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 {
|
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 {
|
||||||
|
406
src/compile.cpp
406
src/compile.cpp
@ -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)),
|
||||||
|
382
src/compiler.cpp
382
src/compiler.cpp
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
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
|
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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user