various bugfixes in new compiler

This commit is contained in:
Joel Dice 2008-02-17 15:29:04 -07:00
parent d654c943f3
commit e8ed2a4749
4 changed files with 112 additions and 28 deletions

View File

@ -13,16 +13,17 @@ enum Operation {
const unsigned OperationCount = Return + 1; const unsigned OperationCount = Return + 1;
enum UnaryOperation { enum UnaryOperation {
Call,
Push, Push,
Pop, Pop,
Call,
AlignedCall,
Jump,
JumpIfLess, JumpIfLess,
JumpIfGreater, JumpIfGreater,
JumpIfLessOrEqual, JumpIfLessOrEqual,
JumpIfGreaterOrEqual, JumpIfGreaterOrEqual,
JumpIfEqual, JumpIfEqual,
JumpIfNotEqual, JumpIfNotEqual,
Jump,
Negate Negate
}; };

View File

@ -3510,7 +3510,7 @@ finish(MyThread* t, Context* context)
} }
// for debugging: // for debugging:
if (//false and if (true or//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)),
@ -3966,7 +3966,7 @@ saveStackAndBase(MyThread* t, Assembler* a)
a->apply(Move, BytesPerWord, Register, &base, Memory, &baseDst); a->apply(Move, BytesPerWord, Register, &base, Memory, &baseDst);
Assembler::Register stack(a->stack()); Assembler::Register stack(a->stack());
Assembler::Memory stackDst(a->thread(), difference(&(t->base), t)); Assembler::Memory stackDst(a->thread(), difference(&(t->stack), t));
a->apply(Move, BytesPerWord, Register, &stack, Memory, &stackDst); a->apply(Move, BytesPerWord, Register, &stack, Memory, &stackDst);
} }
@ -3983,16 +3983,29 @@ pushThread(MyThread*, Assembler* a)
} }
} }
void
popThread(MyThread*, Assembler* a)
{
if (a->argumentRegisterCount() == 0) {
ResolvedPromise bpwPromise(BytesPerWord);
Assembler::Constant bpw(&bpwPromise);
Assembler::Register stack(a->stack());
a->apply(Add, BytesPerWord, Constant, &bpw, Register, &stack);
}
}
object object
compileDefault(MyThread* t, Assembler* a) compileDefault(MyThread* t, Assembler* a)
{ {
saveStackAndBase(t, a); saveStackAndBase(t, a);
pushThread(t, a); pushThread(t, a);
ResolvedPromise promise(reinterpret_cast<intptr_t>(compileMethod)); ResolvedPromise procPromise(reinterpret_cast<intptr_t>(compileMethod));
Assembler::Constant proc(&promise); Assembler::Constant proc(&procPromise);
a->apply(Call, BytesPerWord, Constant, &proc); a->apply(Call, BytesPerWord, Constant, &proc);
popThread(t, a);
Assembler::Register result(a->returnLow()); Assembler::Register result(a->returnLow());
a->apply(Jump, BytesPerWord, Register, &result); a->apply(Jump, BytesPerWord, Register, &result);
@ -4009,6 +4022,8 @@ compileNative(MyThread* t, Assembler* a)
Assembler::Constant proc(&promise); Assembler::Constant proc(&promise);
a->apply(Call, BytesPerWord, Constant, &proc); a->apply(Call, BytesPerWord, Constant, &proc);
popThread(t, a);
a->apply(Return); a->apply(Return);
return finish(t, a, "native"); return finish(t, a, "native");

View File

@ -513,7 +513,7 @@ class ArgumentEvent: public Event {
return register_(c, c->assembler->argumentRegister(index)); return register_(c, c->assembler->argumentRegister(index));
} else { } else {
return memory(c, c->assembler->base(), return memory(c, c->assembler->base(),
index + (c->stackOffset * BytesPerWord), -(index + ((c->stackOffset + 1) * BytesPerWord)),
NoRegister, 0, 0); NoRegister, 0, 0);
} }
} }
@ -617,7 +617,7 @@ class SyncForCallEvent: public Event {
assert(c, v == src); assert(c, v == src);
return memory(c, c->assembler->base(), return memory(c, c->assembler->base(),
index + (c->stackOffset * BytesPerWord), -(index + ((c->stackOffset + 1) * BytesPerWord)),
NoRegister, 0, 0); NoRegister, 0, 0);
} }
@ -749,8 +749,7 @@ class CallEvent: public Event {
assert(c, v == address); assert(c, v == address);
if (indirection) { if (indirection) {
return register_ return register_(c, c->assembler->returnLow(), NoRegister);
(c, c->assembler->returnLow(), c->assembler->returnHigh());
} else { } else {
return 0; return 0;
} }
@ -777,19 +776,23 @@ class CallEvent: public Event {
} }
if (stackOffset != c->stackOffset) { if (stackOffset != c->stackOffset) {
apply(c, LoadAddress, BytesPerWord, register_(c, c->assembler->stack()), apply(c, LoadAddress, BytesPerWord,
memory(c, c->assembler->base(), stackOffset * BytesPerWord, memory(c, c->assembler->base(),
NoRegister, 0, 0)); -((stackOffset + 1) * BytesPerWord),
NoRegister, 0, 0),
register_(c, c->assembler->stack()));
} }
UnaryOperation type = ((flags & Compiler::Aligned) ? AlignedCall : Call);
if (indirection) { if (indirection) {
if (address->target->equals(address->value)) { if (not address->target->equals(address->value)) {
apply(c, Move, BytesPerWord, address->value, address->target); apply(c, Move, BytesPerWord, address->value, address->target);
} }
apply(c, Call, BytesPerWord, apply(c, type, BytesPerWord,
constant(c, reinterpret_cast<intptr_t>(indirection))); constant(c, reinterpret_cast<intptr_t>(indirection)));
} else { } else {
apply(c, Call, BytesPerWord, address->value); apply(c, type, BytesPerWord, address->value);
} }
if (traceHandler) { if (traceHandler) {
@ -1303,17 +1306,19 @@ stack(Context* c, MyOperand* operand, unsigned size, unsigned index,
Stack(operand, size, index, next); Stack(operand, size, index, next);
} }
Stack*
stack(Context* c, MyOperand* operand, unsigned size, Stack* next)
{
return stack(c, operand, size, (next ? next->index + size : 0), next);
}
void void
push(Context* c, unsigned size, MyOperand* o) push(Context* c, unsigned size, MyOperand* o)
{ {
assert(c, ceiling(size, BytesPerWord)); assert(c, ceiling(size, BytesPerWord));
assert(c, o->event == 0); assert(c, o->event == 0);
c->state->stack = stack c->state->stack = stack(c, o, ceiling(size, BytesPerWord), c->state->stack);
(c, o, ceiling(size, BytesPerWord),
ceiling(size, BytesPerWord)
+ (c->state->stack ? c->state->stack->index : 0),
c->state->stack);
} }
MyOperand* MyOperand*
@ -1571,9 +1576,9 @@ class MyCompiler: public Compiler {
syncStack(&c, SyncForCall); syncStack(&c, SyncForCall);
unsigned stackOffset = c.stackOffset unsigned stackOffset = c.stackOffset
+ (c.state->stack ? c.state->stack->index + (c.state->stack ? c.state->stack->index + c.state->stack->size : 0)
+ (footprint > c.assembler->argumentRegisterCount() ? + (footprint > c.assembler->argumentRegisterCount() ?
footprint - c.assembler->argumentRegisterCount() : 0) : 0); footprint - c.assembler->argumentRegisterCount() : 0);
MyOperand* result = operand(&c); MyOperand* result = operand(&c);
appendCall(&c, static_cast<MyOperand*>(address), indirection, flags, appendCall(&c, static_cast<MyOperand*>(address), indirection, flags,

View File

@ -297,7 +297,16 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
} }
void void
jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a) alignedCallC(Context* c, unsigned size, Assembler::Constant* a)
{
while ((c->code.length() + 1) % 4) {
c->code.append(0x90);
}
callC(c, size, a);
}
void
callR(Context* c, unsigned size UNUSED, Assembler::Register* a)
{ {
assert(c, size == BytesPerWord); assert(c, size == BytesPerWord);
@ -305,6 +314,15 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a)
c->code.append(0xd0 | a->low); c->code.append(0xd0 | a->low);
} }
void
jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a)
{
assert(c, size == BytesPerWord);
c->code.append(0xff);
c->code.append(0xe0 | a->low);
}
void void
pushR(Context* c, unsigned size, Assembler::Register* a) pushR(Context* c, unsigned size, Assembler::Register* a)
{ {
@ -318,6 +336,10 @@ pushR(Context* c, unsigned size, Assembler::Register* a)
} }
} }
void
move4To8RR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b);
void void
popR(Context* c, unsigned size, Assembler::Register* a) popR(Context* c, unsigned size, Assembler::Register* a)
{ {
@ -327,12 +349,15 @@ popR(Context* c, unsigned size, Assembler::Register* a)
popR(c, 4, a); popR(c, 4, a);
popR(c, 4, &ah); popR(c, 4, &ah);
} else { } else {
c->code.append(0x50 | a->low); c->code.append(0x58 | a->low);
if (BytesPerWord == 8 and size == 4) {
move4To8RR(c, 0, a, a);
}
} }
} }
void void
leaRM(Context* c, unsigned size, Assembler::Register* a, Assembler::Memory* b) leaMR(Context* c, unsigned size, Assembler::Memory* b, Assembler::Register* a)
{ {
if (BytesPerWord == 8 and size == 4) { if (BytesPerWord == 8 and size == 4) {
encode(c, 0x8d, a->low, b, false); encode(c, 0x8d, a->low, b, false);
@ -403,6 +428,17 @@ moveRR(Context* c, unsigned size, Assembler::Register* a,
} }
} }
void
move4To8RR(Context* c, unsigned size UNUSED, Assembler::Register* a,
Assembler::Register* b)
{
assert(c, BytesPerWord == 8);
rex(c);
c->code.append(0x63);
c->code.append(0xc0 | (a->low << 3) | b->low);
}
void void
moveMR(Context* c, unsigned size, Assembler::Memory* a, Assembler::Register* b) moveMR(Context* c, unsigned size, Assembler::Memory* a, Assembler::Register* b)
{ {
@ -455,6 +491,29 @@ move4To8MR(Context* c, unsigned, Assembler::Memory* a, Assembler::Register* b)
encode(c, 0x63, b->low, a, true); encode(c, 0x63, b->low, a, true);
} }
void
addCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b)
{
assert(c, BytesPerWord == 8 or size == 4); // todo
int64_t v = a->value->value();
if (v) {
rex(c);
if (isInt8(v)) {
c->code.append(0x83);
c->code.append(0xc0 | b->low);
c->code.append(v);
} else if (isInt32(v)) {
c->code.append(0x81);
c->code.append(0xc0 | b->low);
c->code.append4(v);
} else {
abort(c);
}
}
}
void void
addRR(Context* c, unsigned size, Assembler::Register* a, addRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b) Assembler::Register* b)
@ -481,18 +540,22 @@ populateTables()
Operations[Return] = return_; Operations[Return] = return_;
UnaryOperations[INDEX1(Call, Constant)] = CAST1(callC); UnaryOperations[INDEX1(Call, Constant)] = CAST1(callC);
UnaryOperations[INDEX1(AlignedCall, Constant)] = CAST1(alignedCallC);
UnaryOperations[INDEX1(Call, Register)] = CAST1(callR);
UnaryOperations[INDEX1(Jump, Register)] = CAST1(jumpR); UnaryOperations[INDEX1(Jump, Register)] = CAST1(jumpR);
UnaryOperations[INDEX1(Push, Register)] = CAST1(pushR); UnaryOperations[INDEX1(Push, Register)] = CAST1(pushR);
UnaryOperations[INDEX1(Pop, Register)] = CAST1(popR); UnaryOperations[INDEX1(Pop, Register)] = CAST1(popR);
BinaryOperations[INDEX2(LoadAddress, Register, Memory)] = CAST2(leaRM); BinaryOperations[INDEX2(LoadAddress, Memory, Register)] = CAST2(leaMR);
BinaryOperations[INDEX2(Move, Constant, Register)] = CAST2(moveCR); BinaryOperations[INDEX2(Move, Constant, Register)] = CAST2(moveCR);
BinaryOperations[INDEX2(Move, Constant, Memory)] = CAST2(moveCM); BinaryOperations[INDEX2(Move, Constant, Memory)] = CAST2(moveCM);
BinaryOperations[INDEX2(Move, Register, Memory)] = CAST2(moveRM); BinaryOperations[INDEX2(Move, Register, Memory)] = CAST2(moveRM);
BinaryOperations[INDEX2(Move, Register, Register)] = CAST2(moveRR); BinaryOperations[INDEX2(Move, Register, Register)] = CAST2(moveRR);
BinaryOperations[INDEX2(Move4To8, Register, Register)] = CAST2(move4To8RR);
BinaryOperations[INDEX2(Move, Memory, Register)] = CAST2(moveMR); BinaryOperations[INDEX2(Move, Memory, Register)] = CAST2(moveMR);
BinaryOperations[INDEX2(Move, Address, Register)] = CAST2(moveAR); BinaryOperations[INDEX2(Move, Address, Register)] = CAST2(moveAR);
BinaryOperations[INDEX2(Move4To8, Memory, Register)] = CAST2(move4To8MR); BinaryOperations[INDEX2(Move4To8, Memory, Register)] = CAST2(move4To8MR);
BinaryOperations[INDEX2(Add, Constant, Register)] = CAST2(addCR);
BinaryOperations[INDEX2(Add, Register, Register)] = CAST2(addRR); BinaryOperations[INDEX2(Add, Register, Register)] = CAST2(addRR);
BinaryOperations[INDEX2(Add, Register, Memory)] = CAST2(addRM); BinaryOperations[INDEX2(Add, Register, Memory)] = CAST2(addRM);
} }