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 { enum BinaryOperation {
LoadAddress, LoadAddress,
Move1, Move,
Move2, MoveZ,
Move4,
Move8,
Move1ToW,
Move2ToW,
Move2zToW,
Move4To8, Move4To8,
Compare, Compare,
Add, Add,
@ -51,8 +46,6 @@ enum BinaryOperation {
Xor Xor
}; };
const BinaryOperation Move = (BytesPerWord == 8 ? Move8 : Move4);
const unsigned BinaryOperationCount = Xor + 1; const unsigned BinaryOperationCount = Xor + 1;
enum OperandType { enum OperandType {

View File

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

View File

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

View File

@ -29,10 +29,8 @@ class Compiler {
virtual Promise* poolAppend(intptr_t value) = 0; virtual Promise* poolAppend(intptr_t value) = 0;
virtual Promise* poolAppendPromise(Promise* value) = 0; virtual Promise* poolAppendPromise(Promise* value) = 0;
virtual Operand* constant(intptr_t value) = 0; virtual Operand* constant(int64_t value) = 0;
virtual Operand* constant8(int64_t value) = 0;
virtual Operand* promiseConstant(Promise* value) = 0; virtual Operand* promiseConstant(Promise* value) = 0;
virtual Operand* promiseConstant8(Promise* value) = 0;
virtual Operand* address(Promise* address) = 0; virtual Operand* address(Promise* address) = 0;
virtual Operand* memory(Operand* base, virtual Operand* memory(Operand* base,
int displacement = 0, int displacement = 0,
@ -46,10 +44,10 @@ class Compiler {
virtual Operand* label() = 0; virtual Operand* label() = 0;
virtual void mark(Operand* label) = 0; virtual void mark(Operand* label) = 0;
virtual void push(Operand* value) = 0; virtual void push(unsigned size, Operand* value) = 0;
virtual Operand* pop() = 0; virtual Operand* pop(unsigned size) = 0;
virtual void push(unsigned count) = 0; virtual void pushed(unsigned count) = 0;
virtual void pop(unsigned count) = 0; virtual void popped(unsigned count) = 0;
virtual Operand* peek(unsigned index) = 0; virtual Operand* peek(unsigned index) = 0;
virtual Operand* call(Operand* address, virtual Operand* call(Operand* address,
@ -59,21 +57,14 @@ class Compiler {
unsigned resultSize, unsigned resultSize,
unsigned argumentCount, unsigned argumentCount,
...) = 0; ...) = 0;
virtual void return_(Operand* value) = 0;
virtual void store(Operand* src, Operand* dst) = 0; virtual void return_(unsigned size, Operand* value) = 0;
virtual void store1(Operand* src, Operand* dst) = 0;
virtual void store2(Operand* src, Operand* dst) = 0; virtual void store(unsigned size, Operand* src, Operand* dst) = 0;
virtual void store4(Operand* src, Operand* dst) = 0; virtual Operand* load(unsigned size, Operand* src) = 0;
virtual void store8(Operand* src, Operand* dst) = 0; virtual Operand* loadz(unsigned size, Operand* src) = 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 Operand* load4To8(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 jl(Operand* address) = 0;
virtual void jg(Operand* address) = 0; virtual void jg(Operand* address) = 0;
virtual void jle(Operand* address) = 0; virtual void jle(Operand* address) = 0;
@ -81,18 +72,18 @@ class Compiler {
virtual void je(Operand* address) = 0; virtual void je(Operand* address) = 0;
virtual void jne(Operand* address) = 0; virtual void jne(Operand* address) = 0;
virtual void jmp(Operand* address) = 0; virtual void jmp(Operand* address) = 0;
virtual Operand* add(Operand* a, Operand* b) = 0; virtual Operand* add(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* sub(Operand* a, Operand* b) = 0; virtual Operand* sub(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* mul(Operand* a, Operand* b) = 0; virtual Operand* mul(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* div(Operand* a, Operand* b) = 0; virtual Operand* div(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* rem(Operand* a, Operand* b) = 0; virtual Operand* rem(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* shl(Operand* a, Operand* b) = 0; virtual Operand* shl(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* shr(Operand* a, Operand* b) = 0; virtual Operand* shr(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* ushr(Operand* a, Operand* b) = 0; virtual Operand* ushr(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* and_(Operand* a, Operand* b) = 0; virtual Operand* and_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* or_(Operand* a, Operand* b) = 0; virtual Operand* or_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* xor_(Operand* a, Operand* b) = 0; virtual Operand* xor_(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* neg(Operand* a) = 0; virtual Operand* neg(unsigned size, Operand* a) = 0;
virtual unsigned compile() = 0; virtual unsigned compile() = 0;
virtual unsigned poolSize() = 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 void
move4To8MR(Context* c, unsigned, Assembler::Memory* a, Assembler::Register* b) move4To8MR(Context* c, unsigned, Assembler::Memory* a, Assembler::Register* b)
{ {
@ -363,14 +394,11 @@ populateTables()
UnaryOperations[INDEX1(Call, Constant)] = CAST1(callC); UnaryOperations[INDEX1(Call, Constant)] = CAST1(callC);
UnaryOperations[INDEX1(Jump, Register)] = CAST1(jumpR); UnaryOperations[INDEX1(Jump, Register)] = CAST1(jumpR);
BinaryOperations[INDEX2(Move4, Constant, Register)] = CAST2(moveCR); BinaryOperations[INDEX2(Move, Constant, Register)] = CAST2(moveCR);
BinaryOperations[INDEX2(Move8, Constant, Register)] = CAST2(moveCR); BinaryOperations[INDEX2(Move, Constant, Memory)] = CAST2(moveCM);
BinaryOperations[INDEX2(Move4, Constant, Memory)] = CAST2(moveCM); BinaryOperations[INDEX2(Move, Register, Memory)] = CAST2(moveRM);
BinaryOperations[INDEX2(Move8, Constant, Memory)] = CAST2(moveCM); BinaryOperations[INDEX2(Move, Register, Register)] = CAST2(moveRR);
BinaryOperations[INDEX2(Move4, Register, Memory)] = CAST2(moveRM); BinaryOperations[INDEX2(Move, Memory, Register)] = CAST2(moveMR);
BinaryOperations[INDEX2(Move8, Register, Memory)] = CAST2(moveRM);
BinaryOperations[INDEX2(Move4, Register, Register)] = CAST2(moveRR);
BinaryOperations[INDEX2(Move8, Register, Register)] = CAST2(moveRR);
BinaryOperations[INDEX2(Move4To8, Memory, Register)] = CAST2(move4To8MR); BinaryOperations[INDEX2(Move4To8, Memory, Register)] = CAST2(move4To8MR);
BinaryOperations[INDEX2(Add, Register, Register)] = CAST2(addRR); BinaryOperations[INDEX2(Add, Register, Register)] = CAST2(addRR);
} }