rework compiler interface to explicitly accept a size parameter for each operation where relevant

This commit is contained in:
Joel Dice 2008-02-11 19:06:12 -07:00
parent b9fa7179d9
commit fa513beb2f
5 changed files with 460 additions and 438 deletions

View File

@ -29,13 +29,8 @@ const unsigned UnaryOperationCount = Negate + 1;
enum BinaryOperation {
LoadAddress,
Move1,
Move2,
Move4,
Move8,
Move1ToW,
Move2ToW,
Move2zToW,
Move,
MoveZ,
Move4To8,
Compare,
Add,
@ -51,8 +46,6 @@ enum BinaryOperation {
Xor
};
const BinaryOperation Move = (BytesPerWord == 8 ? Move8 : Move4);
const unsigned BinaryOperationCount = Xor + 1;
enum OperandType {

View File

@ -684,97 +684,111 @@ class Frame {
}
void pushInt(Compiler::Operand* o) {
c->push(o);
c->push(4, o);
pushedInt();
}
void pushAddress(Compiler::Operand* o) {
c->push(o);
c->push(BytesPerWord, o);
pushedInt();
}
void pushObject(Compiler::Operand* o) {
c->push(o);
c->push(BytesPerWord, o);
pushedObject();
}
void pushObject() {
c->push(1);
c->pushed(1);
pushedObject();
}
void pushLong(Compiler::Operand* o) {
void pushLongQuiet(Compiler::Operand* o) {
if (BytesPerWord == 8) {
c->push(1);
c->pushed(1);
}
c->push(o);
c->push(8, o);
}
void pushLong(Compiler::Operand* o) {
pushLongQuiet(o);
pushedLong();
}
void pop(unsigned count) {
popped(count);
c->pop(count);
c->popped(count);
}
Compiler::Operand* popInt() {
poppedInt();
return c->pop();
return c->pop(4);
}
Compiler::Operand* popLongQuiet() {
Compiler::Operand* r = c->pop(8);
if (BytesPerWord == 8) {
c->popped(1);
}
return r;
}
Compiler::Operand* popLong() {
poppedLong();
return c->pop();
return popLongQuiet();
}
Compiler::Operand* popObject() {
poppedObject();
return c->pop();
return c->pop(BytesPerWord);
}
void loadInt(unsigned index) {
assert(t, index < localSize());
pushInt
(c->load4(c->memory(c->base(), localOffset(t, index, context->method))));
(c->load
(4, c->memory(c->base(), localOffset(t, index, context->method))));
}
void loadLong(unsigned index) {
assert(t, index < static_cast<unsigned>(localSize() - 1));
pushLong
(c->load8
(c->memory(c->base(), localOffset(t, index + 1, context->method))));
(c->load
(8, c->memory(c->base(), localOffset(t, index + 1, context->method))));
}
void loadObject(unsigned index) {
assert(t, index < localSize());
pushObject
(c->load
(c->memory(c->base(), localOffset(t, index, context->method))));
(BytesPerWord,
c->memory(c->base(), localOffset(t, index, context->method))));
}
void storeInt(unsigned index) {
c->store4
(popInt(), c->memory(c->base(), localOffset(t, index, context->method)));
c->store
(4, popInt(), c->memory
(c->base(), localOffset(t, index, context->method)));
storedInt(index);
}
void storeLong(unsigned index) {
c->store8
(popLong(), c->memory
c->store
(8, popLong(), c->memory
(c->base(), localOffset(t, index + 1, context->method)));
storedLong(index);
}
void storeObject(unsigned index) {
c->store
(popObject(), c->memory
(BytesPerWord, popObject(), c->memory
(c->base(), localOffset(t, index, context->method)));
storedObject(index);
}
void storeObjectOrAddress(unsigned index) {
c->store
(c->pop(), c->memory
(BytesPerWord, c->pop(BytesPerWord), c->memory
(c->base(), localOffset(t, index, context->method)));
assert(t, sp >= 1);
@ -789,122 +803,131 @@ class Frame {
}
void dup() {
Compiler::Operand* s0 = c->pop();
Compiler::Operand* s0 = c->pop(BytesPerWord);
c->push(s0);
c->push(s0);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s0);
dupped();
}
void dupX1() {
Compiler::Operand* s0 = c->pop();
Compiler::Operand* s1 = c->pop();
Compiler::Operand* s0 = c->pop(BytesPerWord);
Compiler::Operand* s1 = c->pop(BytesPerWord);
c->push(s0);
c->push(s1);
c->push(s0);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
duppedX1();
}
void dupX2() {
Compiler::Operand* s0 = c->pop();
Compiler::Operand* s1 = c->pop();
Compiler::Operand* s0 = c->pop(BytesPerWord);
if (get(sp - 2) == Long) {
c->push(s0);
c->push(s1);
c->push(s0);
} else {
Compiler::Operand* s2 = c->pop();
Compiler::Operand* s1 = popLongQuiet();
c->push(s0);
c->push(s2);
c->push(s1);
c->push(s0);
c->push(BytesPerWord, s0);
pushLongQuiet(s1);
c->push(BytesPerWord, s0);
} else {
Compiler::Operand* s1 = c->pop(BytesPerWord);
Compiler::Operand* s2 = c->pop(BytesPerWord);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s2);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
}
duppedX2();
}
void dup2() {
Compiler::Operand* s0 = c->pop();
if (get(sp - 1) == Long) {
c->push(s0);
c->push(s0);
} else {
Compiler::Operand* s1 = c->pop();
Compiler::Operand* s0 = popLongQuiet();
c->push(s1);
c->push(s0);
c->push(s1);
c->push(s0);
pushLongQuiet(s0);
pushLongQuiet(s0);
} else {
Compiler::Operand* s0 = c->pop(BytesPerWord);
Compiler::Operand* s1 = c->pop(BytesPerWord);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
}
dupped2();
}
void dup2X1() {
Compiler::Operand* s0 = c->pop();
Compiler::Operand* s1 = c->pop();
if (get(sp - 1) == Long) {
c->push(s0);
c->push(s1);
c->push(s0);
} else {
Compiler::Operand* s2 = c->pop();
Compiler::Operand* s0 = popLongQuiet();
Compiler::Operand* s1 = c->pop(BytesPerWord);
c->push(s1);
c->push(s0);
c->push(s2);
c->push(s1);
c->push(s0);
pushLongQuiet(s0);
c->push(BytesPerWord, s1);
pushLongQuiet(s0);
} else {
Compiler::Operand* s0 = c->pop(BytesPerWord);
Compiler::Operand* s1 = c->pop(BytesPerWord);
Compiler::Operand* s2 = c->pop(BytesPerWord);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s2);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
}
dupped2X1();
}
void dup2X2() {
Compiler::Operand* s0 = c->pop();
Compiler::Operand* s1 = c->pop();
if (get(sp - 1) == Long) {
if (get(sp - 3) == Long) {
c->push(s0);
c->push(s1);
c->push(s0);
} else {
Compiler::Operand* s2 = c->pop();
Compiler::Operand* s0 = popLongQuiet();
c->push(s0);
c->push(s2);
c->push(s1);
c->push(s0);
if (get(sp - 3) == Long) {
Compiler::Operand* s1 = popLongQuiet();
pushLongQuiet(s0);
pushLongQuiet(s1);
pushLongQuiet(s0);
} else {
Compiler::Operand* s1 = c->pop(BytesPerWord);
Compiler::Operand* s2 = c->pop(BytesPerWord);
pushLongQuiet(s0);
c->push(BytesPerWord, s2);
c->push(BytesPerWord, s1);
pushLongQuiet(s0);
}
} else {
Compiler::Operand* s2 = c->pop();
Compiler::Operand* s3 = c->pop();
Compiler::Operand* s0 = c->pop(BytesPerWord);
Compiler::Operand* s1 = c->pop(BytesPerWord);
Compiler::Operand* s2 = c->pop(BytesPerWord);
Compiler::Operand* s3 = c->pop(BytesPerWord);
c->push(s1);
c->push(s0);
c->push(s3);
c->push(s2);
c->push(s1);
c->push(s0);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s3);
c->push(BytesPerWord, s2);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
}
dupped2X2();
}
void swap() {
Compiler::Operand* s0 = c->pop();
Compiler::Operand* s1 = c->pop();
Compiler::Operand* s0 = c->pop(BytesPerWord);
Compiler::Operand* s1 = c->pop(BytesPerWord);
c->push(s0);
c->push(s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s1);
swapped();
}
@ -1409,6 +1432,8 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target)
{
Compiler* c = frame->c;
unsigned rSize = resultSize(t, methodReturnCode(t, target));
Compiler::Operand* result = c->call
(c->constant
(reinterpret_cast<intptr_t>
@ -1416,13 +1441,13 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target)
0,
Compiler::Aligned,
frame->trace(target, false),
resultSize(t, methodReturnCode(t, target)),
rSize,
0);
c->pop(methodParameterFootprint(t, target));
c->popped(methodParameterFootprint(t, target));
if (methodReturnCode(t, target) != VoidField) {
c->push(result);
if (rSize) {
c->push(rSize, result);
}
}
@ -1462,7 +1487,8 @@ handleEntrance(MyThread* t, Frame* frame)
// save 'this' pointer in case it is overwritten.
unsigned index = savedTargetIndex(t, method);
c->store(c->memory(c->base(), localOffset(t, 0, method)),
c->store(BytesPerWord,
c->memory(c->base(), localOffset(t, 0, method)),
c->memory(c->base(), localOffset(t, index, method)));
frame->set(index, Frame::Object);
}
@ -1521,10 +1547,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* load = c->label();
Compiler::Operand* throw_ = c->label();
c->cmp(c->constant(0), index);
c->cmp(4, c->constant(0), index);
c->jl(throw_);
c->cmp(c->memory(array, ArrayLength, 0, 1, frame->trace(0, false)),
c->cmp(BytesPerWord,
c->memory(array, ArrayLength, 0, 1, frame->trace(0, false)),
index);
c->jl(load);
@ -1544,29 +1571,30 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
switch (instruction) {
case aaload:
frame->pushObject
(c->load(c->memory(array, ArrayBody, index, BytesPerWord)));
(c->load
(BytesPerWord, c->memory(array, ArrayBody, index, BytesPerWord)));
break;
case faload:
case iaload:
frame->pushInt(c->load4(c->memory(array, ArrayBody, index, 4)));
frame->pushInt(c->load(4, c->memory(array, ArrayBody, index, 4)));
break;
case baload:
frame->pushInt(c->load1(c->memory(array, ArrayBody, index, 1)));
frame->pushInt(c->load(1, c->memory(array, ArrayBody, index, 1)));
break;
case caload:
frame->pushInt(c->load2z(c->memory(array, ArrayBody, index, 2)));
frame->pushInt(c->loadz(2, c->memory(array, ArrayBody, index, 2)));
break;
case daload:
case laload:
frame->pushLong(c->load8(c->memory(array, ArrayBody, index, 8)));
frame->pushLong(c->load(8, c->memory(array, ArrayBody, index, 8)));
break;
case saload:
frame->pushInt(c->load2(c->memory(array, ArrayBody, index, 2)));
frame->pushInt(c->load(2, c->memory(array, ArrayBody, index, 2)));
break;
}
} break;
@ -1595,10 +1623,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* store = c->label();
Compiler::Operand* throw_ = c->label();
c->cmp(c->constant(0), index);
c->cmp(4, c->constant(0), index);
c->jl(throw_);
c->cmp(c->memory(array, ArrayLength, 0, 1, frame->trace(0, false)),
c->cmp(BytesPerWord,
c->memory(array, ArrayLength, 0, 1, frame->trace(0, false)),
index);
c->jl(store);
@ -1624,28 +1653,28 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
frame->trace(0, false),
0,
4, c->thread(), array,
c->add(c->constant(ArrayBody),
c->shl(c->constant(log(BytesPerWord)), index)),
c->add(4, c->constant(ArrayBody),
c->shl(4, c->constant(log(BytesPerWord)), index)),
value);
} break;
case fastore:
case iastore:
c->store4(value, c->memory(array, ArrayBody, index, 4));
c->store(4, value, c->memory(array, ArrayBody, index, 4));
break;
case bastore:
c->store1(value, c->memory(array, ArrayBody, index, 1));
c->store(1, value, c->memory(array, ArrayBody, index, 1));
break;
case castore:
case sastore:
c->store2(value, c->memory(array, ArrayBody, index, 2));
c->store(2, value, c->memory(array, ArrayBody, index, 2));
break;
case dastore:
case lastore:
c->store8(value, c->memory(array, ArrayBody, index, 8));
c->store(8, value, c->memory(array, ArrayBody, index, 8));
break;
}
} break;
@ -1683,12 +1712,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* nonnegative = c->label();
Compiler::Operand* length = frame->popInt();
c->cmp(c->constant(0), length);
c->cmp(4, c->constant(0), length);
c->jge(nonnegative);
c->push(length);
c->push(c->thread());
c->call
(c->constant(reinterpret_cast<intptr_t>(throwNegativeArraySize)),
context->indirection,
@ -1711,13 +1737,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case areturn: {
handleExit(t, frame);
c->return_(frame->popObject());
c->return_(BytesPerWord, frame->popObject());
} return;
case arraylength: {
frame->pushInt
(c->load
(c->memory
(BytesPerWord, c->memory
(frame->popObject(), ArrayLength, 0, 1, frame->trace(0, false))));
} break;
@ -1825,11 +1851,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break;
case dconst_0:
frame->pushLong(c->constant8(doubleToBits(0.0)));
frame->pushLong(c->constant(doubleToBits(0.0)));
break;
case dconst_1:
frame->pushLong(c->constant8(doubleToBits(1.0)));
frame->pushLong(c->constant(doubleToBits(1.0)));
break;
case ddiv: {
@ -2045,34 +2071,36 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case ByteField:
case BooleanField:
frame->pushInt
(c->load1(c->memory(table, fieldOffset(t, field), 0, 1, trace)));
(c->load(1, c->memory(table, fieldOffset(t, field), 0, 1, trace)));
break;
case CharField:
frame->pushInt
(c->load2z(c->memory(table, fieldOffset(t, field), 0, 1, trace)));
(c->loadz(2, c->memory(table, fieldOffset(t, field), 0, 1, trace)));
break;
case ShortField:
frame->pushInt
(c->load2(c->memory(table, fieldOffset(t, field), 0, 1, trace)));
(c->load(2, c->memory(table, fieldOffset(t, field), 0, 1, trace)));
break;
case FloatField:
case IntField:
frame->pushInt
(c->load4(c->memory(table, fieldOffset(t, field), 0, 1, trace)));
(c->load(4, c->memory(table, fieldOffset(t, field), 0, 1, trace)));
break;
case DoubleField:
case LongField:
frame->pushLong
(c->load8(c->memory(table, fieldOffset(t, field), 0, 1, trace)));
(c->load(8, c->memory(table, fieldOffset(t, field), 0, 1, trace)));
break;
case ObjectField:
frame->pushObject
(c->load(c->memory(table, fieldOffset(t, field), 0, 1, trace)));
(c->load
(BytesPerWord, c->memory
(table, fieldOffset(t, field), 0, 1, trace)));
break;
default:
@ -2097,11 +2125,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break;
case i2b: {
frame->pushInt(c->load1(frame->popInt()));
frame->pushInt(c->load(1, frame->popInt()));
} break;
case i2c: {
frame->pushInt(c->load2z(frame->popInt()));
frame->pushInt(c->loadz(2, frame->popInt()));
} break;
case i2d: {
@ -2123,19 +2151,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
break;
case i2s: {
frame->pushInt(c->load2(frame->popInt()));
frame->pushInt(c->load(2, frame->popInt()));
} break;
case iadd: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->add(a, b));
frame->pushInt(c->add(4, a, b));
} break;
case iand: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->and_(a, b));
frame->pushInt(c->and_(4, a, b));
} break;
case iconst_m1:
@ -2169,7 +2197,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case idiv: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->div(a, b));
frame->pushInt(c->div(4, a, b));
} break;
case if_acmpeq:
@ -2181,7 +2209,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* b = frame->popObject();
Compiler::Operand* target = frame->machineIp(newIp);
c->cmp(a, b);
c->cmp(BytesPerWord, a, b);
if (instruction == if_acmpeq) {
c->je(target);
} else {
@ -2205,7 +2233,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* b = frame->popInt();
Compiler::Operand* target = frame->machineIp(newIp);
c->cmp(a, b);
c->cmp(4, a, b);
switch (instruction) {
case if_icmpeq:
c->je(target);
@ -2243,7 +2271,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* a = frame->popInt();
Compiler::Operand* target = frame->machineIp(newIp);
c->cmp(c->constant(0), a);
c->cmp(4, c->constant(0), a);
switch (instruction) {
case ifeq:
c->je(target);
@ -2277,7 +2305,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* a = frame->popObject();
Compiler::Operand* target = frame->machineIp(newIp);
c->cmp(c->constant(0), a);
c->cmp(BytesPerWord, c->constant(0), a);
if (instruction == ifnull) {
c->je(target);
} else {
@ -2295,7 +2323,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* a = c->memory
(c->base(), localOffset(t, index, context->method));
c->store(c->add(c->constant(count), a), a);
c->store(4, c->add(4, c->constant(count), a), a);
} break;
case iload:
@ -2326,11 +2354,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case imul: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->mul(a, b));
frame->pushInt(c->mul(4, a, b));
} break;
case ineg: {
frame->pushInt(c->neg(frame->popInt()));
frame->pushInt(c->neg(4, frame->popInt()));
} break;
case instanceof: {
@ -2357,6 +2385,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
unsigned instance = parameterFootprint - 1;
unsigned rSize = resultSize(t, methodReturnCode(t, target));
Compiler::Operand* result = c->call
(c->call
(c->constant
@ -2370,13 +2400,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
0,
0,
frame->trace(target, true),
resultSize(t, methodReturnCode(t, target)),
rSize,
0);
frame->pop(parameterFootprint);
if (methodReturnCode(t, target) != VoidField) {
c->push(result);
if (rSize) {
c->push(rSize, result);
}
} break;
@ -2415,52 +2445,54 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* instance = c->peek(parameterFootprint - 1);
unsigned rSize = resultSize(t, methodReturnCode(t, target));
Compiler::Operand* result = c->call
(c->memory
(c->and_
(c->constant(PointerMask), c->memory
(4, c->constant(PointerMask), c->memory
(instance, 0, 0, 1, frame->trace(0, false))), offset, 0, 1),
0,
0,
frame->trace(0, true),
resultSize(t, methodReturnCode(t, target)),
rSize,
0);
frame->pop(parameterFootprint);
if (methodReturnCode(t, target) != VoidField) {
c->push(result);
if (rSize) {
c->push(rSize, result);
}
} break;
case ior: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->or_(a, b));
frame->pushInt(c->or_(4, a, b));
} break;
case irem: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->rem(a, b));
frame->pushInt(c->rem(4, a, b));
} break;
case ireturn:
case freturn: {
handleExit(t, frame);
c->return_(frame->popInt());
c->return_(4, frame->popInt());
} return;
case ishl: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->shl(a, b));
frame->pushInt(c->shl(4, a, b));
} break;
case ishr: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->shr(a, b));
frame->pushInt(c->shr(4, a, b));
} break;
case istore:
@ -2491,19 +2523,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case isub: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->sub(a, b));
frame->pushInt(c->sub(4, a, b));
} break;
case iushr: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->ushr(a, b));
frame->pushInt(c->ushr(4, a, b));
} break;
case ixor: {
Compiler::Operand* a = frame->popInt();
Compiler::Operand* b = frame->popInt();
frame->pushInt(c->xor_(a, b));
frame->pushInt(c->xor_(4, a, b));
} break;
case jsr:
@ -2530,19 +2562,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break;
case l2i:
frame->pushInt(c->load4(frame->popLong()));
frame->pushInt(c->load(4, frame->popLong()));
break;
case ladd: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->add(a, b));
frame->pushLong(c->add(8, a, b));
} break;
case land: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->and_(a, b));
frame->pushLong(c->and_(8, a, b));
} break;
case lcmp: {
@ -2553,19 +2585,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
c->cmp(a, b);
c->cmp(8, a, b);
c->jl(less);
c->jg(greater);
c->push(c->constant(0));
c->push(4, c->constant(0));
c->jmp(next);
c->mark(less);
c->push(c->constant(-1));
c->push(4, c->constant(-1));
c->jmp(next);
c->mark(greater);
c->push(c->constant(1));
c->push(4, c->constant(1));
c->mark(next);
@ -2573,11 +2605,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break;
case lconst_0:
frame->pushLong(c->constant8(0));
frame->pushLong(c->constant(0));
break;
case lconst_1:
frame->pushLong(c->constant8(1));
frame->pushLong(c->constant(1));
break;
case ldc:
@ -2616,13 +2648,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
uint64_t v;
memcpy(&v, &singletonValue(t, pool, index - 1), 8);
frame->pushLong(c->constant8(v));
frame->pushLong(c->constant(v));
} break;
case ldiv_: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->div(a, b));
frame->pushLong(c->div(8, a, b));
} break;
case lload:
@ -2653,11 +2685,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case lmul: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->mul(a, b));
frame->pushLong(c->mul(8, a, b));
} break;
case lneg:
frame->pushLong(c->neg(frame->popLong()));
frame->pushLong(c->neg(8, frame->popLong()));
break;
case lookupswitch: {
@ -2710,31 +2742,31 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case lor: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->or_(a, b));
frame->pushLong(c->or_(8, a, b));
} break;
case lrem: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->rem(a, b));
frame->pushLong(c->rem(8, a, b));
} break;
case lreturn:
case dreturn: {
handleExit(t, frame);
c->return_(frame->popLong());
c->return_(8, frame->popLong());
} return;
case lshl: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->shl(a, b));
frame->pushLong(c->shl(8, a, b));
} break;
case lshr: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->shr(a, b));
frame->pushLong(c->shr(8, a, b));
} break;
case lstore:
@ -2765,19 +2797,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case lsub: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->sub(a, b));
frame->pushLong(c->sub(8, a, b));
} break;
case lushr: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->ushr(a, b));
frame->pushLong(c->ushr(8, a, b));
} break;
case lxor: {
Compiler::Operand* a = frame->popLong();
Compiler::Operand* b = frame->popLong();
frame->pushLong(c->xor_(a, b));
frame->pushLong(c->xor_(8, a, b));
} break;
case monitorenter: {
@ -2808,8 +2840,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
0,
frame->trace(0, false),
BytesPerWord,
4, c->thread(), frame->append(class_), c->load(c->stack()),
c->constant(dimensions));
4, c->thread(), frame->append(class_),
c->load(BytesPerWord, c->stack()), c->constant(dimensions));
frame->pop(dimensions);
frame->pushObject(result);
@ -2849,7 +2881,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* length = frame->popInt();
c->cmp(c->constant(0), length);
c->cmp(4, c->constant(0), length);
c->jge(nonnegative);
c->call
@ -2980,22 +3012,26 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
c->store1(value, c->memory(table, fieldOffset(t, field), 0, 1, trace));
c->store
(1, value, c->memory(table, fieldOffset(t, field), 0, 1, trace));
break;
case CharField:
case ShortField:
c->store2(value, c->memory(table, fieldOffset(t, field), 0, 1, trace));
c->store
(2, value, c->memory(table, fieldOffset(t, field), 0, 1, trace));
break;
case FloatField:
case IntField:
c->store4(value, c->memory(table, fieldOffset(t, field), 0, 1, trace));
c->store
(4, value, c->memory(table, fieldOffset(t, field), 0, 1, trace));
break;
case DoubleField:
case LongField:
c->store8(value, c->memory(table, fieldOffset(t, field), 0, 1, trace));
c->store
(8, value, c->memory(table, fieldOffset(t, field), 0, 1, trace));
break;
case ObjectField:
@ -3028,7 +3064,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case return_:
handleExit(t, frame);
c->return_(0);
c->return_(0, 0);
return;
case sipush:
@ -3071,13 +3107,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* defaultCase = c->label();
c->cmp(c->constant(bottom), key);
c->cmp(4, c->constant(bottom), key);
c->jl(defaultCase);
c->cmp(c->constant(top), key);
c->cmp(4, c->constant(top), key);
c->jg(defaultCase);
c->sub(c->constant(bottom), key);
c->sub(4, c->constant(bottom), key);
c->jmp(c->memory(start, 0, key, BytesPerWord));
c->mark(defaultCase);
@ -3108,7 +3144,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
Compiler::Operand* a = c->memory
(c->base(), localOffset(t, index, context->method));
c->store(c->add(c->constant(count), a), a);
c->store(4, c->add(4, c->constant(count), a), a);
} break;
case iload: {
@ -3476,7 +3512,7 @@ finish(MyThread* t, Context* context)
}
// for debugging:
if (false and
if (//false and
strcmp
(reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),

View File

@ -29,7 +29,7 @@ class Value {
virtual void acquire(Context*, MyOperand*) { }
virtual void release(Context*, MyOperand*) { }
virtual RegisterValue* toRegister(Context*, unsigned size) = 0;
virtual RegisterValue* toRegister(Context*) = 0;
virtual void asAssemblerOperand(Context*,
OperandType* type,
@ -38,14 +38,14 @@ class Value {
class MyOperand: public Compiler::Operand {
public:
MyOperand(unsigned size, Value* value):
size(size), event(0), value(value), target(0), index(0), next(0)
MyOperand(Value* value):
event(0), value(value), target(0), size(0), index(0), next(0)
{ }
unsigned size;
Event* event;
Value* value;
Value* target;
unsigned size;
unsigned index;
MyOperand* next;
};
@ -257,7 +257,7 @@ class ConstantValue: public Value {
public:
ConstantValue(Promise* value): value(value) { }
virtual RegisterValue* toRegister(Context* c, unsigned size);
virtual RegisterValue* toRegister(Context* c);
virtual void asAssemblerOperand(Context*,
OperandType* type,
@ -287,7 +287,7 @@ class AddressValue: public Value {
public:
AddressValue(Promise* address): address(address) { }
virtual RegisterValue* toRegister(Context* c, unsigned size);
virtual RegisterValue* toRegister(Context* c);
virtual void asAssemblerOperand(Context*,
OperandType* type,
@ -337,7 +337,7 @@ class RegisterValue: public Value {
if (register_.high >= 0) c->registers[register_.high].operand = 0;
}
virtual RegisterValue* toRegister(Context*, unsigned) {
virtual RegisterValue* toRegister(Context*) {
return this;
}
@ -366,9 +366,9 @@ class MemoryValue: public Value {
value(base, offset, index, scale, traceHandler)
{ }
virtual RegisterValue* toRegister(Context* c, unsigned size) {
RegisterValue* v = freeRegister(c, size);
apply(c, Move, size, this, v);
virtual RegisterValue* toRegister(Context* c) {
RegisterValue* v = freeRegister(c, BytesPerWord);
apply(c, Move, BytesPerWord, this, v);
return v;
}
@ -404,9 +404,7 @@ memory(Context* c, int base, int offset, int index, unsigned scale,
int
toRegister(Context* c, MyOperand* a)
{
assert(c, a->size == BytesPerWord);
return a->value->toRegister(c, a->size)->register_.low;
return a->value->toRegister(c)->register_.low;
}
class AbstractMemoryValue: public MemoryValue {
@ -466,8 +464,8 @@ class Event {
class ArgumentEvent: public Event {
public:
ArgumentEvent(Context* c, MyOperand* a, unsigned index):
Event(c), a(a), index(index)
ArgumentEvent(Context* c, unsigned size, MyOperand* a, unsigned index):
Event(c), size(size), a(a), index(index)
{ }
virtual Value* target(Context* c, MyOperand* v) {
@ -493,25 +491,26 @@ class ArgumentEvent: public Event {
a->target->preserve(c);
if (not a->target->equals(a->value)) {
apply(c, Move, a->size, a->value, a->target);
apply(c, Move, size, a->value, a->target);
}
}
unsigned size;
MyOperand* a;
unsigned index;
};
void
appendArgument(Context* c, MyOperand* value, unsigned index)
appendArgument(Context* c, unsigned size, MyOperand* value, unsigned index)
{
new (c->zone->allocate(sizeof(ArgumentEvent)))
ArgumentEvent(c, value, index);
ArgumentEvent(c, size, value, index);
}
class ReturnEvent: public Event {
public:
ReturnEvent(Context* c, MyOperand* a):
Event(c), a(a)
ReturnEvent(Context* c, unsigned size, MyOperand* a):
Event(c), size(size), a(a)
{ }
virtual Value* target(Context* c, MyOperand* v) {
@ -531,26 +530,27 @@ class ReturnEvent: public Event {
a->value->release(c, a);
if (not a->target->equals(a->value)) {
apply(c, Move, a->size, a->value, a->target);
apply(c, Move, size, a->value, a->target);
}
}
c->assembler->apply(Return);
}
unsigned size;
MyOperand* a;
};
void
appendReturn(Context* c, MyOperand* value)
appendReturn(Context* c, unsigned size, MyOperand* value)
{
new (c->zone->allocate(sizeof(ReturnEvent))) ReturnEvent(c, value);
new (c->zone->allocate(sizeof(ReturnEvent))) ReturnEvent(c, size, value);
}
class SyncForCallEvent: public Event {
public:
SyncForCallEvent(Context* c, MyOperand* src, MyOperand* dst):
Event(c), src(src), dst(dst)
SyncForCallEvent(Context* c, unsigned size, MyOperand* src, MyOperand* dst):
Event(c), size(size), src(src), dst(dst)
{ }
virtual Value* target(Context* c, MyOperand* v) {
@ -571,29 +571,30 @@ class SyncForCallEvent: public Event {
src->value->release(c, src);
if (not src->target->equals(src->value)) {
apply(c, Move, src->size, src->value, src->target);
apply(c, Move, size, src->value, src->target);
}
}
unsigned size;
MyOperand* src;
MyOperand* dst;
};
void
appendSyncForCall(Context* c, MyOperand* src, MyOperand* dst)
appendSyncForCall(Context* c, unsigned size, MyOperand* src, MyOperand* dst)
{
new (c->zone->allocate(sizeof(SyncForCallEvent)))
SyncForCallEvent(c, src, dst);
SyncForCallEvent(c, size, src, dst);
}
class SyncForJumpEvent: public Event {
public:
SyncForJumpEvent(Context* c, MyOperand* src, MyOperand* dst):
Event(c), src(src), dst(dst)
SyncForJumpEvent(Context* c, unsigned size, MyOperand* src, MyOperand* dst):
Event(c), size(size), src(src), dst(dst)
{ }
SyncForJumpEvent(Event* next, MyOperand* src, MyOperand* dst):
Event(next), src(src), dst(dst)
SyncForJumpEvent(Event* next, unsigned size, MyOperand* src, MyOperand* dst):
Event(next), size(size), src(src), dst(dst)
{ }
virtual Value* target(Context* c, MyOperand* v) {
@ -618,21 +619,22 @@ class SyncForJumpEvent: public Event {
src->target->acquire(c, dst);
if (not src->target->equals(src->value)) {
apply(c, Move, src->size, src->value, src->target);
apply(c, Move, size, src->value, src->target);
}
dst->value = src->target;
}
unsigned size;
MyOperand* src;
MyOperand* dst;
};
void
appendSyncForJump(Context* c, MyOperand* src, MyOperand* dst)
appendSyncForJump(Context* c, unsigned size, MyOperand* src, MyOperand* dst)
{
new (c->zone->allocate(sizeof(SyncForJumpEvent)))
SyncForJumpEvent(c, src, dst);
SyncForJumpEvent(c, size, src, dst);
}
class CallEvent: public Event {
@ -680,12 +682,12 @@ class CallEvent: public Event {
if (indirection) {
if (not address->target->equals(address->value)) {
apply(c, Move, address->size, address->value, address->target);
apply(c, Move, BytesPerWord, address->value, address->target);
}
apply(c, Call, BytesPerWord,
constant(c, reinterpret_cast<intptr_t>(indirection)));
} else {
apply(c, Call, address->size, address->value);
apply(c, Call, BytesPerWord, address->value);
}
}
@ -739,8 +741,9 @@ freeRegister(Context* c, unsigned size)
class MoveEvent: public Event {
public:
MoveEvent(Context* c, BinaryOperation type, MyOperand* src, MyOperand* dst):
Event(c), type(type), src(src), dst(dst)
MoveEvent(Context* c, BinaryOperation type, unsigned size, MyOperand* src,
MyOperand* dst):
Event(c), type(type), size(size), src(src), dst(dst)
{ }
virtual Value* target(Context* c, MyOperand* v) {
@ -764,33 +767,36 @@ class MoveEvent: public Event {
if (dst->value) {
src->target = dst->value;
} else {
src->target = freeRegister(c, src->size);
src->target = freeRegister(c, size);
}
}
src->value->release(c, src);
src->target->acquire(c, dst);
apply(c, type, src->size, src->value, src->target);
apply(c, type, size, src->value, src->target);
dst->value = src->target;
}
BinaryOperation type;
unsigned size;
MyOperand* src;
MyOperand* dst;
};
void
appendMove(Context* c, BinaryOperation type, MyOperand* src, MyOperand* dst)
appendMove(Context* c, BinaryOperation type, unsigned size, MyOperand* src,
MyOperand* dst)
{
new (c->zone->allocate(sizeof(MoveEvent))) MoveEvent(c, type, src, dst);
new (c->zone->allocate(sizeof(MoveEvent)))
MoveEvent(c, type, size, src, dst);
}
class CompareEvent: public Event {
public:
CompareEvent(Context* c, MyOperand* a, MyOperand* b):
Event(c), a(a), b(b)
CompareEvent(Context* c, unsigned size, MyOperand* a, MyOperand* b):
Event(c), size(size), a(a), b(b)
{ }
virtual Value* target(Context* c, MyOperand* v) {
@ -814,17 +820,18 @@ class CompareEvent: public Event {
a->value->release(c, a);
b->value->release(c, b);
apply(c, Compare, a->size, a->value, b->value);
apply(c, Compare, size, a->value, b->value);
}
unsigned size;
MyOperand* a;
MyOperand* b;
};
void
appendCompare(Context* c, MyOperand* a, MyOperand* b)
appendCompare(Context* c, unsigned size, MyOperand* a, MyOperand* b)
{
new (c->zone->allocate(sizeof(CompareEvent))) CompareEvent(c, a, b);
new (c->zone->allocate(sizeof(CompareEvent))) CompareEvent(c, size, a, b);
}
class BranchEvent: public Event {
@ -848,7 +855,7 @@ class BranchEvent: public Event {
virtual void compile(Context* c) {
address->value->release(c, address);
apply(c, type, address->size, address->value);
apply(c, type, BytesPerWord, address->value);
}
UnaryOperation type;
@ -882,7 +889,7 @@ class JumpEvent: public Event {
virtual void compile(Context* c) {
address->value->release(c, address);
apply(c, Jump, address->size, address->value);
apply(c, Jump, BytesPerWord, address->value);
}
MyOperand* address;
@ -899,9 +906,9 @@ appendJump(Context* c, MyOperand* address)
class CombineEvent: public Event {
public:
CombineEvent(Context* c, BinaryOperation type, MyOperand* a, MyOperand* b,
MyOperand* result):
Event(c), type(type), a(a), b(b), result(result)
CombineEvent(Context* c, BinaryOperation type, unsigned size, MyOperand* a,
MyOperand* b, MyOperand* result):
Event(c), type(type), size(size), a(a), b(b), result(result)
{ }
virtual Value* target(Context* c, MyOperand* v) {
@ -943,36 +950,37 @@ class CombineEvent: public Event {
b->value->acquire(c, result);
if (a->target and not a->target->equals(a->value)) {
apply(c, Move, a->size, a->value, a->target);
apply(c, Move, size, a->value, a->target);
}
if (b->target and not b->target->equals(b->value)) {
apply(c, Move, b->size, b->value, b->target);
apply(c, Move, size, b->value, b->target);
}
apply(c, type, a->size, a->value, b->value);
apply(c, type, size, a->value, b->value);
result->value = b->value;
}
BinaryOperation type;
unsigned size;
MyOperand* a;
MyOperand* b;
MyOperand* result;
};
void
appendCombine(Context* c, BinaryOperation type, MyOperand* a, MyOperand* b,
MyOperand* result)
appendCombine(Context* c, BinaryOperation type, unsigned size, MyOperand* a,
MyOperand* b, MyOperand* result)
{
new (c->zone->allocate(sizeof(CombineEvent)))
CombineEvent(c, type, a, b, result);
CombineEvent(c, type, size, a, b, result);
}
class TranslateEvent: public Event {
public:
TranslateEvent(Context* c, UnaryOperation type, MyOperand* a,
TranslateEvent(Context* c, UnaryOperation type, unsigned size, MyOperand* a,
MyOperand* result):
Event(c), type(type), a(a), result(result)
Event(c), type(type), size(size), a(a), result(result)
{ }
virtual Value* target(Context* c, MyOperand* v) {
@ -1003,31 +1011,32 @@ class TranslateEvent: public Event {
}
UnaryOperation type;
unsigned size;
MyOperand* a;
MyOperand* result;
};
void
appendTranslate(Context* c, UnaryOperation type, MyOperand* a,
appendTranslate(Context* c, UnaryOperation type, unsigned size, MyOperand* a,
MyOperand* result)
{
new (c->zone->allocate(sizeof(TranslateEvent)))
TranslateEvent(c, type, a, result);
TranslateEvent(c, type, size, a, result);
}
RegisterValue*
ConstantValue::toRegister(Context* c, unsigned size)
ConstantValue::toRegister(Context* c)
{
RegisterValue* v = freeRegister(c, size);
apply(c, Move, size, this, v);
RegisterValue* v = freeRegister(c, BytesPerWord);
apply(c, Move, BytesPerWord, this, v);
return v;
}
RegisterValue*
AddressValue::toRegister(Context* c, unsigned size)
AddressValue::toRegister(Context* c)
{
RegisterValue* v = freeRegister(c, size);
apply(c, Move, size, this, v);
RegisterValue* v = freeRegister(c, BytesPerWord);
apply(c, Move, BytesPerWord, this, v);
return v;
}
@ -1048,9 +1057,9 @@ preserve(Context* c, int reg)
}
MyOperand*
operand(Context* c, unsigned size, Value* value = 0)
operand(Context* c, Value* value = 0)
{
return new (c->zone->allocate(sizeof(MyOperand))) MyOperand(size, value);
return new (c->zone->allocate(sizeof(MyOperand))) MyOperand(value);
}
void
@ -1068,16 +1077,23 @@ popState(Context* c)
}
void
push(Context* c, MyOperand* o)
push(Context* c, unsigned size, MyOperand* o)
{
static_cast<MyOperand*>(o)->next = c->state->stack;
c->state->stack = static_cast<MyOperand*>(o);
assert(c, o->size == 0 and o->index == 0);
o->next = c->state->stack;
o->size = ceiling(size, BytesPerWord);
o->index = ceiling(size, BytesPerWord)
+ (c->state->stack ? c->state->stack->index : 0);
c->state->stack = o;
}
MyOperand*
pop(Context* c)
pop(Context* c, unsigned size UNUSED)
{
MyOperand* o = c->state->stack;
assert(c, ceiling(size, BytesPerWord) == o->size);
c->state->stack = o->next;
return o;
}
@ -1088,19 +1104,20 @@ syncStack(Context* c, SyncType type)
MyOperand* top = 0;
MyOperand* new_ = 0;
for (MyOperand* old = c->state->stack; old; old = old->next) {
MyOperand* n = operand(c, old->size, 0);
MyOperand* n = operand(c);
if (new_) {
new_->next = n;
} else {
top = n;
}
new_ = n;
new_->size = old->size;
new_->index = old->index;
if (type == SyncForCall) {
appendSyncForCall(c, old, new_);
appendSyncForCall(c, old->size * BytesPerWord, old, new_);
} else {
appendSyncForJump(c, old, new_);
appendSyncForJump(c, old->size * BytesPerWord, old, new_);
}
}
@ -1118,9 +1135,10 @@ updateJunctions(Context* c)
MyOperand* new_ = 0;
for (MyOperand* old = i->firstEvent->stack; old; old = old->next) {
MyOperand* n = operand(c, old->size, 0);
MyOperand* n = operand(c);
if (new_) new_->next = n;
new_ = n;
new_->size = old->size;
new_->index = old->index;
if (old->event) {
@ -1129,7 +1147,7 @@ updateJunctions(Context* c)
p->lastEvent = p->lastEvent->next = new
(c->zone->allocate(sizeof(SyncForJumpEvent)))
SyncForJumpEvent(p->lastEvent->next, old, new_);
SyncForJumpEvent(p->lastEvent->next, old->size, old, new_);
}
}
}
@ -1219,21 +1237,12 @@ class MyCompiler: public Compiler {
ResolvedPromise(value));
}
virtual Operand* constant8(int64_t value) {
return promiseConstant8(new (c.zone->allocate(sizeof(ResolvedPromise)))
ResolvedPromise(value));
}
virtual Operand* promiseConstant(Promise* value) {
return operand(&c, BytesPerWord, ::constant(&c, value));
}
virtual Operand* promiseConstant8(Promise* value) {
return operand(&c, 8, ::constant(&c, value));
return operand(&c, ::constant(&c, value));
}
virtual Operand* address(Promise* address) {
return operand(&c, BytesPerWord, ::address(&c, address));
return operand(&c, ::address(&c, address));
}
virtual Operand* memory(Operand* base,
@ -1243,25 +1252,25 @@ class MyCompiler: public Compiler {
TraceHandler* traceHandler = 0)
{
return operand
(&c, BytesPerWord, ::memory
(&c, ::memory
(&c, static_cast<MyOperand*>(base), displacement,
static_cast<MyOperand*>(index), scale, traceHandler));
}
virtual Operand* stack() {
return operand(&c, BytesPerWord, register_(&c, c.assembler->stack()));
return operand(&c, register_(&c, c.assembler->stack()));
}
virtual Operand* base() {
return operand(&c, BytesPerWord, register_(&c, c.assembler->base()));
return operand(&c, register_(&c, c.assembler->base()));
}
virtual Operand* thread() {
return operand(&c, BytesPerWord, register_(&c, c.assembler->thread()));
return operand(&c, register_(&c, c.assembler->thread()));
}
virtual Operand* label() {
return operand(&c, BytesPerWord, ::constant(&c, static_cast<Promise*>(0)));
return operand(&c, ::constant(&c, static_cast<Promise*>(0)));
}
Promise* machineIp() {
@ -1274,20 +1283,24 @@ class MyCompiler: public Compiler {
= machineIp();
}
virtual void push(Operand* value) {
::push(&c, static_cast<MyOperand*>(value));
virtual void push(unsigned size, Operand* value) {
::push(&c, size, static_cast<MyOperand*>(value));
}
virtual Operand* pop() {
return ::pop(&c);
virtual Operand* pop(unsigned size) {
return ::pop(&c, size);
}
virtual void push(unsigned count) {
for (unsigned i = 0; i < count; ++i) ::push(&c, 0);
virtual void pushed(unsigned count) {
for (unsigned i = 0; i < count; ++i) ::push(&c, BytesPerWord, operand(&c));
}
virtual void pop(unsigned count) {
for (unsigned i = 0; i < count; ++i) ::pop(&c);
virtual void popped(unsigned count) {
for (int i = count; i >= 0;) {
MyOperand* o = c.state->stack;
c.state->stack = o->next;
count -= o->size;
}
}
virtual Operand* peek(unsigned index) {
@ -1300,17 +1313,23 @@ class MyCompiler: public Compiler {
void* indirection,
unsigned flags,
TraceHandler* traceHandler,
unsigned resultSize,
unsigned,
unsigned argumentCount,
...)
{
va_list a; va_start(a, argumentCount);
unsigned footprint = 0;
unsigned size = BytesPerWord;
for (unsigned i = 0; i < argumentCount; ++i) {
MyOperand* o = va_arg(a, MyOperand*);
footprint += o->size;
appendArgument(&c, o, i);
if (o) {
appendArgument(&c, size, o, footprint);
size = BytesPerWord;
} else {
size = 8;
}
++ footprint;
}
va_end(a);
@ -1321,87 +1340,42 @@ class MyCompiler: public Compiler {
+ (footprint > c.assembler->argumentRegisterCount() ?
footprint - c.assembler->argumentRegisterCount() : 0);
MyOperand* result = operand(&c, resultSize, 0);
MyOperand* result = operand(&c);
appendCall(&c, static_cast<MyOperand*>(address), indirection, flags,
traceHandler, result, stackOffset);
return result;
}
virtual void return_(Operand* value) {
appendReturn(&c, static_cast<MyOperand*>(value));
virtual void return_(unsigned size, Operand* value) {
appendReturn(&c, size, static_cast<MyOperand*>(value));
}
virtual void store(Operand* src, Operand* dst) {
appendMove(&c, Move, static_cast<MyOperand*>(src),
virtual void store(unsigned size, Operand* src, Operand* dst) {
appendMove(&c, Move, size, static_cast<MyOperand*>(src),
static_cast<MyOperand*>(dst));
}
virtual void store1(Operand* src, Operand* dst) {
appendMove(&c, Move1, static_cast<MyOperand*>(src),
static_cast<MyOperand*>(dst));
}
virtual void store2(Operand* src, Operand* dst) {
appendMove(&c, Move2, static_cast<MyOperand*>(src),
static_cast<MyOperand*>(dst));
}
virtual void store4(Operand* src, Operand* dst) {
appendMove(&c, Move4, static_cast<MyOperand*>(src),
static_cast<MyOperand*>(dst));
}
virtual void store8(Operand* src, Operand* dst) {
appendMove(&c, Move8, static_cast<MyOperand*>(src),
static_cast<MyOperand*>(dst));
}
virtual Operand* load(Operand* src) {
MyOperand* dst = operand(&c, BytesPerWord);
appendMove(&c, Move, static_cast<MyOperand*>(src), dst);
virtual Operand* load(unsigned size, Operand* src) {
MyOperand* dst = operand(&c);
appendMove(&c, Move, size, static_cast<MyOperand*>(src), dst);
return dst;
}
virtual Operand* load1(Operand* src) {
MyOperand* dst = operand(&c, BytesPerWord);
appendMove(&c, Move1ToW, static_cast<MyOperand*>(src), dst);
return dst;
}
virtual Operand* load2(Operand* src) {
MyOperand* dst = operand(&c, BytesPerWord);
appendMove(&c, Move2ToW, static_cast<MyOperand*>(src), dst);
return dst;
}
virtual Operand* load2z(Operand* src) {
MyOperand* dst = operand(&c, BytesPerWord);
appendMove(&c, Move2zToW, static_cast<MyOperand*>(src), dst);
return dst;
}
virtual Operand* load4(Operand* src) {
if (BytesPerWord == 4) {
return load(src);
} else {
return load4To8(src);
}
}
virtual Operand* load8(Operand* src) {
MyOperand* dst = operand(&c, 8);
appendMove(&c, Move8, static_cast<MyOperand*>(src), dst);
virtual Operand* loadz(unsigned size, Operand* src) {
MyOperand* dst = operand(&c);
appendMove(&c, MoveZ, size, static_cast<MyOperand*>(src), dst);
return dst;
}
virtual Operand* load4To8(Operand* src) {
MyOperand* dst = operand(&c, 8);
appendMove(&c, Move4To8, static_cast<MyOperand*>(src), dst);
MyOperand* dst = operand(&c);
appendMove(&c, Move4To8, 0, static_cast<MyOperand*>(src), dst);
return dst;
}
virtual void cmp(Operand* a, Operand* b) {
appendCompare(&c, static_cast<MyOperand*>(a), static_cast<MyOperand*>(b));
virtual void cmp(unsigned size, Operand* a, Operand* b) {
appendCompare(&c, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b));
}
virtual void jl(Operand* address) {
@ -1446,86 +1420,86 @@ class MyCompiler: public Compiler {
appendJump(&c, static_cast<MyOperand*>(address));
}
virtual Operand* add(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, Add, static_cast<MyOperand*>(a),
virtual Operand* add(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, Add, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* sub(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, Subtract, static_cast<MyOperand*>(a),
virtual Operand* sub(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, Subtract, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* mul(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, Multiply, static_cast<MyOperand*>(a),
virtual Operand* mul(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, Multiply, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* div(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, Divide, static_cast<MyOperand*>(a),
virtual Operand* div(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, Divide, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* rem(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, Remainder, static_cast<MyOperand*>(a),
virtual Operand* rem(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, Remainder, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* shl(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, ShiftLeft, static_cast<MyOperand*>(a),
virtual Operand* shl(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, ShiftLeft, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* shr(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, ShiftRight, static_cast<MyOperand*>(a),
virtual Operand* shr(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, ShiftRight, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* ushr(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, UnsignedShiftRight, static_cast<MyOperand*>(a),
virtual Operand* ushr(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, UnsignedShiftRight, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* and_(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, And, static_cast<MyOperand*>(a),
virtual Operand* and_(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, And, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* or_(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, Or, static_cast<MyOperand*>(a),
virtual Operand* or_(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, Or, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* xor_(Operand* a, Operand* b) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendCombine(&c, Xor, static_cast<MyOperand*>(a),
virtual Operand* xor_(unsigned size, Operand* a, Operand* b) {
MyOperand* result = operand(&c);
appendCombine(&c, Xor, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b), result);
return result;
}
virtual Operand* neg(Operand* a) {
MyOperand* result = operand(&c, static_cast<MyOperand*>(a)->size);
appendTranslate(&c, Negate, static_cast<MyOperand*>(a), result);
virtual Operand* neg(unsigned size, Operand* a) {
MyOperand* result = operand(&c);
appendTranslate(&c, Negate, size, static_cast<MyOperand*>(a), result);
return result;
}

View File

@ -29,10 +29,8 @@ class Compiler {
virtual Promise* poolAppend(intptr_t value) = 0;
virtual Promise* poolAppendPromise(Promise* value) = 0;
virtual Operand* constant(intptr_t value) = 0;
virtual Operand* constant8(int64_t value) = 0;
virtual Operand* constant(int64_t value) = 0;
virtual Operand* promiseConstant(Promise* value) = 0;
virtual Operand* promiseConstant8(Promise* value) = 0;
virtual Operand* address(Promise* address) = 0;
virtual Operand* memory(Operand* base,
int displacement = 0,
@ -46,10 +44,10 @@ class Compiler {
virtual Operand* label() = 0;
virtual void mark(Operand* label) = 0;
virtual void push(Operand* value) = 0;
virtual Operand* pop() = 0;
virtual void push(unsigned count) = 0;
virtual void pop(unsigned count) = 0;
virtual void push(unsigned size, Operand* value) = 0;
virtual Operand* pop(unsigned size) = 0;
virtual void pushed(unsigned count) = 0;
virtual void popped(unsigned count) = 0;
virtual Operand* peek(unsigned index) = 0;
virtual Operand* call(Operand* address,
@ -59,21 +57,14 @@ class Compiler {
unsigned resultSize,
unsigned argumentCount,
...) = 0;
virtual void return_(Operand* value) = 0;
virtual void store(Operand* src, Operand* dst) = 0;
virtual void store1(Operand* src, Operand* dst) = 0;
virtual void store2(Operand* src, Operand* dst) = 0;
virtual void store4(Operand* src, Operand* dst) = 0;
virtual void store8(Operand* src, Operand* dst) = 0;
virtual Operand* load(Operand* src) = 0;
virtual Operand* load1(Operand* src) = 0;
virtual Operand* load2(Operand* src) = 0;
virtual Operand* load2z(Operand* src) = 0;
virtual Operand* load4(Operand* src) = 0;
virtual Operand* load8(Operand* src) = 0;
virtual void return_(unsigned size, Operand* value) = 0;
virtual void store(unsigned size, Operand* src, Operand* dst) = 0;
virtual Operand* load(unsigned size, Operand* src) = 0;
virtual Operand* loadz(unsigned size, Operand* src) = 0;
virtual Operand* load4To8(Operand* src) = 0;
virtual void cmp(Operand* a, Operand* b) = 0;
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
virtual void jl(Operand* address) = 0;
virtual void jg(Operand* address) = 0;
virtual void jle(Operand* address) = 0;
@ -81,18 +72,18 @@ class Compiler {
virtual void je(Operand* address) = 0;
virtual void jne(Operand* address) = 0;
virtual void jmp(Operand* address) = 0;
virtual Operand* add(Operand* a, Operand* b) = 0;
virtual Operand* sub(Operand* a, Operand* b) = 0;
virtual Operand* mul(Operand* a, Operand* b) = 0;
virtual Operand* div(Operand* a, Operand* b) = 0;
virtual Operand* rem(Operand* a, Operand* b) = 0;
virtual Operand* shl(Operand* a, Operand* b) = 0;
virtual Operand* shr(Operand* a, Operand* b) = 0;
virtual Operand* ushr(Operand* a, Operand* b) = 0;
virtual Operand* and_(Operand* a, Operand* b) = 0;
virtual Operand* or_(Operand* a, Operand* b) = 0;
virtual Operand* xor_(Operand* a, Operand* b) = 0;
virtual Operand* neg(Operand* a) = 0;
virtual Operand* add(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* sub(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* mul(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* div(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* rem(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* shl(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* shr(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* ushr(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* and_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* or_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* xor_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* neg(unsigned size, Operand* a) = 0;
virtual unsigned compile() = 0;
virtual unsigned poolSize() = 0;

View File

@ -336,6 +336,37 @@ moveRR(Context* c, unsigned size, Assembler::Register* a,
}
}
void
moveMR(Context* c, unsigned size, Assembler::Memory* a, Assembler::Register* b)
{
switch (size) {
case 1:
encode2(c, 0x0fbe, b->low, a, true);
break;
case 2:
encode2(c, 0x0fbf, b->low, a, true);
break;
case 4:
case 8:
if (BytesPerWord == 4 and size == 8) {
moveMR(c, 4, a, b);
Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale);
Assembler::Register bh(b->high);
moveMR(c, 4, &ah, &bh);
} else if (BytesPerWord == 8 and size == 4) {
encode(c, 0x63, b->low, a, true);
} else {
encode(c, 0x8b, b->low, a, true);
}
break;
default: abort(c);
}
}
void
move4To8MR(Context* c, unsigned, Assembler::Memory* a, Assembler::Register* b)
{
@ -363,14 +394,11 @@ populateTables()
UnaryOperations[INDEX1(Call, Constant)] = CAST1(callC);
UnaryOperations[INDEX1(Jump, Register)] = CAST1(jumpR);
BinaryOperations[INDEX2(Move4, Constant, Register)] = CAST2(moveCR);
BinaryOperations[INDEX2(Move8, Constant, Register)] = CAST2(moveCR);
BinaryOperations[INDEX2(Move4, Constant, Memory)] = CAST2(moveCM);
BinaryOperations[INDEX2(Move8, Constant, Memory)] = CAST2(moveCM);
BinaryOperations[INDEX2(Move4, Register, Memory)] = CAST2(moveRM);
BinaryOperations[INDEX2(Move8, Register, Memory)] = CAST2(moveRM);
BinaryOperations[INDEX2(Move4, Register, Register)] = CAST2(moveRR);
BinaryOperations[INDEX2(Move8, Register, Register)] = CAST2(moveRR);
BinaryOperations[INDEX2(Move, Constant, Register)] = CAST2(moveCR);
BinaryOperations[INDEX2(Move, Constant, Memory)] = CAST2(moveCM);
BinaryOperations[INDEX2(Move, Register, Memory)] = CAST2(moveRM);
BinaryOperations[INDEX2(Move, Register, Register)] = CAST2(moveRR);
BinaryOperations[INDEX2(Move, Memory, Register)] = CAST2(moveMR);
BinaryOperations[INDEX2(Move4To8, Memory, Register)] = CAST2(move4To8MR);
BinaryOperations[INDEX2(Add, Register, Register)] = CAST2(addRR);
}