mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
rework compiler interface to explicitly accept a size parameter for each operation where relevant
This commit is contained in:
parent
b9fa7179d9
commit
fa513beb2f
@ -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 {
|
||||
|
406
src/compile.cpp
406
src/compile.cpp
@ -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(8, o);
|
||||
}
|
||||
c->push(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)),
|
||||
|
382
src/compiler.cpp
382
src/compiler.cpp
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
44
src/x86.cpp
44
src/x86.cpp
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user