various bugfixes and tweaks in new compiler, primarily related to duplicating stack operands

This commit is contained in:
Joel Dice 2008-02-17 13:57:40 -07:00
parent 6271f878e8
commit d654c943f3
5 changed files with 492 additions and 201 deletions

View File

@ -733,6 +733,10 @@ class Frame {
return r;
}
Compiler::Operand* peekLong(unsigned index) {
return c->peek(8, index);
}
Compiler::Operand* popLong() {
poppedLong();
return popLongQuiet();
@ -803,10 +807,7 @@ class Frame {
}
void dup() {
Compiler::Operand* s0 = c->pop(BytesPerWord);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, c->dup(BytesPerWord, c->peek(BytesPerWord, 0)));
dupped();
}
@ -817,7 +818,7 @@ class Frame {
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
duppedX1();
}
@ -830,7 +831,7 @@ class Frame {
c->push(BytesPerWord, s0);
pushLongQuiet(s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
} else {
Compiler::Operand* s1 = c->pop(BytesPerWord);
Compiler::Operand* s2 = c->pop(BytesPerWord);
@ -838,7 +839,7 @@ class Frame {
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s2);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
}
duppedX2();
@ -846,18 +847,15 @@ class Frame {
void dup2() {
if (get(sp - 1) == Long) {
Compiler::Operand* s0 = popLongQuiet();
pushLongQuiet(s0);
pushLongQuiet(s0);
pushLongQuiet(c->dup(8, peekLong(0)));
} else {
Compiler::Operand* s0 = c->pop(BytesPerWord);
Compiler::Operand* s1 = c->pop(BytesPerWord);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, c->dup(BytesPerWord, s1));
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
}
dupped2();
@ -870,7 +868,7 @@ class Frame {
pushLongQuiet(s0);
c->push(BytesPerWord, s1);
pushLongQuiet(s0);
pushLongQuiet(c->dup(8, s0));
} else {
Compiler::Operand* s0 = c->pop(BytesPerWord);
Compiler::Operand* s1 = c->pop(BytesPerWord);
@ -879,8 +877,8 @@ class Frame {
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s2);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, c->dup(BytesPerWord, s1));
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
}
dupped2X1();
@ -895,7 +893,7 @@ class Frame {
pushLongQuiet(s0);
pushLongQuiet(s1);
pushLongQuiet(s0);
pushLongQuiet(c->dup(8, s0));
} else {
Compiler::Operand* s1 = c->pop(BytesPerWord);
Compiler::Operand* s2 = c->pop(BytesPerWord);
@ -903,7 +901,7 @@ class Frame {
pushLongQuiet(s0);
c->push(BytesPerWord, s2);
c->push(BytesPerWord, s1);
pushLongQuiet(s0);
pushLongQuiet(c->dup(8, s0));
}
} else {
Compiler::Operand* s0 = c->pop(BytesPerWord);
@ -915,8 +913,8 @@ class Frame {
c->push(BytesPerWord, s0);
c->push(BytesPerWord, s3);
c->push(BytesPerWord, s2);
c->push(BytesPerWord, s1);
c->push(BytesPerWord, s0);
c->push(BytesPerWord, c->dup(BytesPerWord, s1));
c->push(BytesPerWord, c->dup(BytesPerWord, s0));
}
dupped2X2();
@ -1788,7 +1786,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
object class_ = resolveClassInPool(t, codePool(t, code), index - 1);
if (UNLIKELY(t->exception)) return;
Compiler::Operand* instance = c->peek(0);
Compiler::Operand* instance = c->peek(BytesPerWord, 0);
c->call
(c->constant(reinterpret_cast<intptr_t>(checkCast)),
@ -2396,7 +2394,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
frame->trace(0, false),
BytesPerWord,
3, c->thread(), frame->append(target),
c->peek(instance)),
c->peek(BytesPerWord, instance)),
0,
0,
frame->trace(target, true),
@ -2443,7 +2441,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
unsigned offset = ClassVtable + (methodOffset(t, target) * BytesPerWord);
Compiler::Operand* instance = c->peek(parameterFootprint - 1);
Compiler::Operand* instance = c->peek
(BytesPerWord, parameterFootprint - 1);
unsigned rSize = resultSize(t, methodReturnCode(t, target));
@ -3463,14 +3462,13 @@ finish(MyThread* t, Context* context)
Compiler* c = context->compiler;
unsigned codeSize = c->compile();
object result = allocateCode(t, codeSize + c->poolSize());
object result = allocateCode(t, pad(codeSize) + c->poolSize());
PROTECT(t, result);
uint8_t* start = reinterpret_cast<uint8_t*>(&singletonValue(t, result, 0));
c->writeTo(start);
PROTECT(t, result);
unsigned mapSize = frameMapSizeInWords(t, context->method);
for (TraceElement* p = context->traceLog; p; p = p->next) {

View File

@ -22,10 +22,11 @@ class Value {
public:
virtual ~Value() { }
virtual bool equals(Value*) { return false; }
virtual bool equals(RegisterValue*) { return false; }
virtual OperandType type() = 0;
virtual void preserve(Context*) { }
virtual bool equals(Value*) { return false; }
virtual void preserve(Context*, MyOperand*) { }
virtual void acquire(Context*, MyOperand*) { }
virtual void release(Context*, MyOperand*) { }
@ -39,15 +40,24 @@ class Value {
class MyOperand: public Compiler::Operand {
public:
MyOperand(Value* value):
event(0), value(value), target(0), size(0), index(0), next(0)
event(0), value(value), target(0)
{ }
Event* event;
Value* value;
Value* target;
};
class Stack {
public:
Stack(MyOperand* operand, unsigned size, unsigned index, Stack* next):
operand(operand), size(size), index(index), next(next)
{ }
MyOperand* operand;
unsigned size;
unsigned index;
MyOperand* next;
Stack* next;
};
class State {
@ -57,7 +67,7 @@ class State {
next(s)
{ }
MyOperand* stack;
Stack* stack;
State* next;
};
@ -191,7 +201,7 @@ class PoolPromise: public Promise {
virtual int64_t value() {
if (resolved()) {
return reinterpret_cast<intptr_t>
(c->machineCode + c->assembler->length() + key);
(c->machineCode + pad(c->assembler->length()) + key);
}
abort(c);
@ -209,6 +219,8 @@ class CodePromise: public Promise {
public:
CodePromise(Context* c, CodePromise* next): c(c), offset(-1), next(next) { }
CodePromise(Context* c, int offset): c(c), offset(offset), next(0) { }
virtual int64_t value() {
if (resolved()) {
return reinterpret_cast<intptr_t>(c->machineCode + offset);
@ -257,6 +269,8 @@ class ConstantValue: public Value {
public:
ConstantValue(Promise* value): value(value) { }
virtual OperandType type() { return Constant; }
virtual RegisterValue* toRegister(Context* c);
virtual void asAssemblerOperand(Context*,
@ -287,6 +301,8 @@ class AddressValue: public Value {
public:
AddressValue(Promise* address): address(address) { }
virtual OperandType type() { return Address; }
virtual RegisterValue* toRegister(Context* c);
virtual void asAssemblerOperand(Context*,
@ -306,35 +322,43 @@ address(Context* c, Promise* address)
return new (c->zone->allocate(sizeof(AddressValue))) AddressValue(address);
}
void preserve(Context* c, int reg);
void preserve(Context* c, int reg, MyOperand* a);
class RegisterValue: public Value {
public:
RegisterValue(int low, int high): register_(low, high) { }
virtual bool equals(Value* o) { return o->equals(this); }
virtual OperandType type() { return Register; }
virtual bool equals(RegisterValue* o) {
return o->register_.low == register_.low
and o->register_.high == register_.high;
virtual bool equals(Value* o) {
return this == o or
(o->type() == Register
and static_cast<RegisterValue*>(o)->register_.low == register_.low
and static_cast<RegisterValue*>(o)->register_.high == register_.high);
}
virtual void preserve(Context* c) {
::preserve(c, register_.low);
if (register_.high >= 0) ::preserve(c, register_.high);
virtual void preserve(Context* c, MyOperand* a) {
::preserve(c, register_.low, a);
if (register_.high >= 0) ::preserve(c, register_.high, a);
}
virtual void acquire(Context* c, MyOperand* a) {
preserve(c);
c->registers[register_.low].operand = a;
if (register_.high >= 0) c->registers[register_.high].operand = a;
if (a != c->registers[register_.low].operand) {
fprintf(stderr, "%p acquire %d\n", a, register_.low);
preserve(c, a);
c->registers[register_.low].operand = a;
if (register_.high >= 0) c->registers[register_.high].operand = a;
}
}
virtual void release(Context* c, MyOperand* a UNUSED) {
assert(c, a == c->registers[register_.low].operand);
if (a == c->registers[register_.low].operand) {
fprintf(stderr, "%p release %d\n", a, register_.low);
c->registers[register_.low].operand = 0;
if (register_.high >= 0) c->registers[register_.high].operand = 0;
c->registers[register_.low].operand = 0;
if (register_.high >= 0) c->registers[register_.high].operand = 0;
}
}
virtual RegisterValue* toRegister(Context*) {
@ -366,6 +390,17 @@ class MemoryValue: public Value {
value(base, offset, index, scale, traceHandler)
{ }
virtual OperandType type() { return Memory; }
virtual bool equals(Value* o) {
return this == o or
(o->type() == Memory
and static_cast<MemoryValue*>(o)->value.base == value.base
and static_cast<MemoryValue*>(o)->value.offset == value.offset
and static_cast<MemoryValue*>(o)->value.index == value.index
and static_cast<MemoryValue*>(o)->value.scale == value.scale);
}
virtual RegisterValue* toRegister(Context* c) {
RegisterValue* v = freeRegister(c, BytesPerWord);
apply(c, Move, BytesPerWord, this, v);
@ -458,7 +493,7 @@ class Event {
virtual void compile(Context* c) = 0;
Event* next;
MyOperand* stack;
Stack* stack;
CodePromise* promises;
};
@ -466,7 +501,10 @@ class ArgumentEvent: public Event {
public:
ArgumentEvent(Context* c, unsigned size, MyOperand* a, unsigned index):
Event(c), size(size), a(a), index(index)
{ }
{
assert(c, a->event == 0);
a->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == a);
@ -475,7 +513,7 @@ class ArgumentEvent: public Event {
return register_(c, c->assembler->argumentRegister(index));
} else {
return memory(c, c->assembler->base(),
(v->index + c->stackOffset) * BytesPerWord,
index + (c->stackOffset * BytesPerWord),
NoRegister, 0, 0);
}
}
@ -487,8 +525,12 @@ class ArgumentEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "ArgumentEvent.compile\n");
if (a->target == 0) a->target = target(c, a);
a->value->release(c, a);
a->target->preserve(c);
a->target->preserve(c, a);
if (not a->target->equals(a->value)) {
apply(c, Move, size, a->value, a->target);
@ -511,7 +553,12 @@ class ReturnEvent: public Event {
public:
ReturnEvent(Context* c, unsigned size, MyOperand* a):
Event(c), size(size), a(a)
{ }
{
if (a) {
assert(c, a->event == 0);
a->event = this;
}
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == a);
@ -526,7 +573,11 @@ class ReturnEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "ReturnEvent.compile\n");
if (a) {
if (a->target == 0) a->target = target(c, a);
a->value->release(c, a);
if (not a->target->equals(a->value)) {
@ -536,6 +587,7 @@ class ReturnEvent: public Event {
Assembler::Register base(c->assembler->base());
Assembler::Register stack(c->assembler->stack());
c->assembler->apply(Move, BytesPerWord, Register, &base, Register, &stack);
c->assembler->apply(Pop, BytesPerWord, Register, &base);
c->assembler->apply(Return);
@ -553,15 +605,19 @@ appendReturn(Context* c, unsigned size, MyOperand* value)
class SyncForCallEvent: public Event {
public:
SyncForCallEvent(Context* c, unsigned size, MyOperand* src, MyOperand* dst):
Event(c), size(size), src(src), dst(dst)
{ }
SyncForCallEvent(Context* c, unsigned size, unsigned index, MyOperand* src,
MyOperand* dst):
Event(c), size(size), index(index), src(src), dst(dst)
{
assert(c, src->event == 0);
src->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == src);
return memory(c, c->assembler->base(),
(v->index + c->stackOffset) * BytesPerWord,
index + (c->stackOffset * BytesPerWord),
NoRegister, 0, 0);
}
@ -572,43 +628,68 @@ class SyncForCallEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "SyncForCallEvent.compile\n");
if (src->target == 0) src->target = target(c, src);
src->value->release(c, src);
if (not src->target->equals(src->value)) {
if (src->value->type() == Memory and src->target->type() == Memory) {
RegisterValue* tmp = freeRegister(c, size);
tmp->preserve(c, 0);
apply(c, Move, size, src->value, tmp);
src->value = tmp;
}
apply(c, Move, size, src->value, src->target);
}
dst->value = src->target;
}
unsigned size;
unsigned index;
MyOperand* src;
MyOperand* dst;
};
void
appendSyncForCall(Context* c, unsigned size, MyOperand* src, MyOperand* dst)
appendSyncForCall(Context* c, unsigned size, unsigned index, MyOperand* src,
MyOperand* dst)
{
new (c->zone->allocate(sizeof(SyncForCallEvent)))
SyncForCallEvent(c, size, src, dst);
SyncForCallEvent(c, size, index, src, dst);
}
class SyncForJumpEvent: public Event {
public:
SyncForJumpEvent(Context* c, unsigned size, MyOperand* src, MyOperand* dst):
Event(c), size(size), src(src), dst(dst)
{ }
SyncForJumpEvent(Context* c, unsigned size, unsigned index, MyOperand* src,
MyOperand* dst):
Event(c), size(size), index(index), src(src), dst(dst)
{
assert(c, src->event == 0);
src->event = this;
}
SyncForJumpEvent(Event* next, unsigned size, MyOperand* src, MyOperand* dst):
Event(next), size(size), src(src), dst(dst)
{ }
SyncForJumpEvent(Context* c, Event* next, unsigned size, unsigned index,
MyOperand* src, MyOperand* dst):
Event(next), size(size), index(index), src(src), dst(dst)
{
assert(c, src->event == 0);
src->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == src);
if (BytesPerWord == 4 and v->size == 8) {
return register_(c, c->assembler->stackSyncRegister(v->index),
c->assembler->stackSyncRegister(v->index + 4));
if (BytesPerWord == 4 and size == 8) {
return register_
(c, c->assembler->stackSyncRegister(index / BytesPerWord),
c->assembler->stackSyncRegister((index / BytesPerWord) + 1));
} else {
return register_(c, c->assembler->stackSyncRegister(v->index));
return register_
(c, c->assembler->stackSyncRegister(index / BytesPerWord));
}
}
@ -619,6 +700,10 @@ class SyncForJumpEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "SyncForJumpEvent.compile\n");
if (src->target == 0) src->target = target(c, src);
src->value->release(c, src);
src->target->acquire(c, dst);
@ -630,15 +715,17 @@ class SyncForJumpEvent: public Event {
}
unsigned size;
unsigned index;
MyOperand* src;
MyOperand* dst;
};
void
appendSyncForJump(Context* c, unsigned size, MyOperand* src, MyOperand* dst)
appendSyncForJump(Context* c, unsigned size, unsigned index, MyOperand* src,
MyOperand* dst)
{
new (c->zone->allocate(sizeof(SyncForJumpEvent)))
SyncForJumpEvent(c, size, src, dst);
SyncForJumpEvent(c, size, index, src, dst);
}
class CallEvent: public Event {
@ -653,7 +740,10 @@ class CallEvent: public Event {
traceHandler(traceHandler),
result(result),
stackOffset(stackOffset)
{ }
{
assert(c, address->event == 0);
address->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == address);
@ -672,6 +762,12 @@ class CallEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "CallEvent.compile\n");
if (indirection and address->target == 0) {
address->target = target(c, address);
}
address->value->release(c, address);
if (result->event) {
@ -680,12 +776,14 @@ class CallEvent: public Event {
result->value->acquire(c, result);
}
apply(c, LoadAddress, BytesPerWord, register_(c, c->assembler->stack()),
memory(c, c->assembler->base(), stackOffset * BytesPerWord,
NoRegister, 0, 0));
if (stackOffset != c->stackOffset) {
apply(c, LoadAddress, BytesPerWord, register_(c, c->assembler->stack()),
memory(c, c->assembler->base(), stackOffset * BytesPerWord,
NoRegister, 0, 0));
}
if (indirection) {
if (not address->target->equals(address->value)) {
if (address->target->equals(address->value)) {
apply(c, Move, BytesPerWord, address->value, address->target);
}
apply(c, Call, BytesPerWord,
@ -693,6 +791,12 @@ class CallEvent: public Event {
} else {
apply(c, Call, BytesPerWord, address->value);
}
if (traceHandler) {
traceHandler->handleTrace
(new (c->zone->allocate(sizeof(CodePromise)))
CodePromise(c, c->assembler->length()));
}
}
MyOperand* address;
@ -716,7 +820,7 @@ appendCall(Context* c, MyOperand* address, void* indirection, unsigned flags,
int
freeRegister(Context* c)
{
for (unsigned i = 0; i < c->assembler->registerCount(); ++i) {
for (int i = c->assembler->registerCount(); i >= 0; --i) {
if ((not c->registers[i].reserved)
and c->registers[i].operand == 0)
{
@ -724,7 +828,7 @@ freeRegister(Context* c)
}
}
for (unsigned i = 0; i < c->assembler->registerCount(); ++i) {
for (int i = c->assembler->registerCount(); i >= 0; --i) {
if (not c->registers[i].reserved) {
return i;
}
@ -748,15 +852,20 @@ class MoveEvent: public Event {
MoveEvent(Context* c, BinaryOperation type, unsigned size, MyOperand* src,
MyOperand* dst):
Event(c), type(type), size(size), src(src), dst(dst)
{ }
{
assert(c, src->event == 0);
src->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == src);
if (dst->value) {
return dst->value;
} else if (dst->event) {
return dst->event->target(c, dst);
} else {
return v->event->target(c, dst);
return 0;
}
}
@ -767,12 +876,18 @@ class MoveEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "MoveEvent.compile\n");
if (src->target == 0) src->target = target(c, src);
if (src->target == 0) {
if (dst->value) {
src->target = dst->value;
} else {
src->target = freeRegister(c, size);
}
src->target = freeRegister(c, size);
} else if (src->value->type() == Memory and src->target->type() == Memory)
{
RegisterValue* tmp = freeRegister(c, size);
tmp->preserve(c, 0);
apply(c, Move, size, src->value, tmp);
src->value = tmp;
}
src->value->release(c, src);
@ -797,11 +912,67 @@ appendMove(Context* c, BinaryOperation type, unsigned size, MyOperand* src,
MoveEvent(c, type, size, src, dst);
}
class DupEvent: public Event {
public:
DupEvent(Context* c, unsigned size, MyOperand* src, MyOperand* dst):
Event(c), size(size), src(src), dst(dst)
{ }
virtual Value* target(Context* c, MyOperand*) {
abort(c);
}
virtual void replace(Context* c, MyOperand*, MyOperand*) {
abort(c);
}
virtual void compile(Context* c) {
fprintf(stderr, "DupEvent.compile\n");
Value* value = src->value;
Value* target = dst->value;
if (target == 0) {
if (dst->event) {
target = dst->event->target(c, dst);
} else {
target = freeRegister(c, size);
}
} else if (value->type() == Memory and target->type() == Memory) {
RegisterValue* tmp = freeRegister(c, size);
tmp->preserve(c, 0);
apply(c, Move, size, value, tmp);
value = tmp;
}
target->acquire(c, dst);
apply(c, Move, size, value, target);
dst->value = target;
}
unsigned size;
MyOperand* src;
MyOperand* dst;
};
void
appendDup(Context* c, unsigned size, MyOperand* src, MyOperand* dst)
{
new (c->zone->allocate(sizeof(DupEvent))) DupEvent(c, size, src, dst);
}
class CompareEvent: public Event {
public:
CompareEvent(Context* c, unsigned size, MyOperand* a, MyOperand* b):
Event(c), size(size), a(a), b(b)
{ }
{
assert(c, a->event == 0);
a->event = this;
assert(c, b->event == 0);
b->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == a or v == b);
@ -821,6 +992,8 @@ class CompareEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "CompareEvent.compile\n");
a->value->release(c, a);
b->value->release(c, b);
@ -842,7 +1015,10 @@ class BranchEvent: public Event {
public:
BranchEvent(Context* c, UnaryOperation type, MyOperand* address):
Event(c), type(type), address(address)
{ }
{
assert(c, address->event == 0);
address->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == address);
@ -857,6 +1033,8 @@ class BranchEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "BranchEvent.compile\n");
address->value->release(c, address);
apply(c, type, BytesPerWord, address->value);
@ -877,7 +1055,10 @@ class JumpEvent: public Event {
JumpEvent(Context* c, MyOperand* address):
Event(c),
address(address)
{ }
{
assert(c, address->event == 0);
address->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == address);
@ -891,6 +1072,8 @@ class JumpEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "JumpEvent.compile\n");
address->value->release(c, address);
apply(c, Jump, BytesPerWord, address->value);
@ -913,12 +1096,17 @@ class CombineEvent: public Event {
CombineEvent(Context* c, BinaryOperation type, unsigned size, MyOperand* a,
MyOperand* b, MyOperand* result):
Event(c), type(type), size(size), a(a), b(b), result(result)
{ }
{
assert(c, a->event == 0);
a->event = this;
assert(c, b->event == 0);
b->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
Assembler::Register ar(NoRegister);
Assembler::Register br(NoRegister);
c->assembler->getTargets(type, v->size, &ar, &br);
c->assembler->getTargets(type, size, &ar, &br);
if (v == a) {
if (ar.low == NoRegister) {
@ -930,7 +1118,16 @@ class CombineEvent: public Event {
assert(c, v == b);
if (br.low == NoRegister) {
return result->event->target(c, result);
if (result->event) {
Value* v = result->event->target(c, result);
if (v->type() == Register) {
return v;
} else {
return 0;
}
} else {
return 0;
}
} else {
return register_(c, br.low, br.high);
}
@ -949,6 +1146,11 @@ class CombineEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "CombineEvent.compile\n");
if (a->target == 0) a->target = target(c, a);
if (b->target == 0) b->target = target(c, b);
a->value->release(c, a);
b->value->release(c, b);
b->value->acquire(c, result);
@ -985,13 +1187,16 @@ class TranslateEvent: public Event {
TranslateEvent(Context* c, UnaryOperation type, unsigned size, MyOperand* a,
MyOperand* result):
Event(c), type(type), size(size), a(a), result(result)
{ }
{
assert(c, a->event == 0);
a->event = this;
}
virtual Value* target(Context* c, MyOperand* v) {
assert(c, v == a);
Assembler::Register r(NoRegister);
c->assembler->getTargets(type, v->size, &r);
c->assembler->getTargets(type, size, &r);
if (r.low == NoRegister) {
return result->event->target(c, result);
@ -1007,9 +1212,16 @@ class TranslateEvent: public Event {
}
virtual void compile(Context* c) {
fprintf(stderr, "TranslateEvent.compile\n");
if (a->target == 0) a->target = target(c, a);
result->value->acquire(c, result);
apply(c, type, a->size, a->value);
if (a->target and not a->target->equals(a->value)) {
apply(c, Move, size, a->value, a->target);
}
apply(c, type, size, a->value);
result->value = a->value;
}
@ -1045,18 +1257,21 @@ AddressValue::toRegister(Context* c)
}
void
preserve(Context* c, int reg)
preserve(Context* c, int reg, MyOperand* a)
{
MyOperand* a = c->registers[reg].operand;
if (a) {
MemoryValue* dst = memory
(c, c->assembler->base(), (a->index + c->stackOffset) * BytesPerWord,
-1, 0, 0);
MyOperand* b = c->registers[reg].operand;
if (b and a != b) {
fprintf(stderr, "%p preserve %d for %p\n", a, reg, b);
apply(c, Move, a->size, a->value, dst);
abort(c);
// MemoryValue* dst = memory
// (c, c->assembler->base(), (b->index + c->stackOffset) * BytesPerWord,
// -1, 0, 0);
a->value = dst;
c->registers[reg].operand = 0;
// apply(c, Move, b->size, b->value, dst);
// b->value = dst;
// c->registers[reg].operand = 0;
}
}
@ -1080,52 +1295,59 @@ popState(Context* c)
State(c->state->next);
}
Stack*
stack(Context* c, MyOperand* operand, unsigned size, unsigned index,
Stack* next)
{
return new (c->zone->allocate(sizeof(Stack)))
Stack(operand, size, index, next);
}
void
push(Context* c, unsigned size, MyOperand* o)
{
assert(c, o->size == 0 and o->index == 0);
assert(c, ceiling(size, BytesPerWord));
assert(c, o->event == 0);
o->next = c->state->stack;
o->size = ceiling(size, BytesPerWord);
o->index = ceiling(size, BytesPerWord)
+ (c->state->stack ? c->state->stack->index : 0);
c->state->stack = o;
c->state->stack = stack
(c, o, ceiling(size, BytesPerWord),
ceiling(size, BytesPerWord)
+ (c->state->stack ? c->state->stack->index : 0),
c->state->stack);
}
MyOperand*
pop(Context* c, unsigned size UNUSED)
{
MyOperand* o = c->state->stack;
assert(c, ceiling(size, BytesPerWord) == o->size);
Stack* s = c->state->stack;
assert(c, ceiling(size, BytesPerWord) == s->size);
c->state->stack = o->next;
return o;
c->state->stack = s->next;
return s->operand;
}
void
syncStack(Context* c, SyncType type)
{
MyOperand* top = 0;
MyOperand* new_ = 0;
for (MyOperand* old = c->state->stack; old; old = old->next) {
MyOperand* n = operand(c);
if (new_) {
new_->next = n;
Stack* newStack = 0;
for (Stack* s = c->state->stack; s; s = s->next) {
MyOperand* old = s->operand;
MyOperand* new_ = operand(c);
Stack* ns = stack(c, new_, s->size, s->index, 0);
if (newStack) {
newStack->next = ns;
} else {
top = n;
newStack = c->state->stack = ns;
}
new_ = n;
new_->size = old->size;
new_->index = old->index;
if (type == SyncForCall) {
appendSyncForCall(c, old->size * BytesPerWord, old, new_);
appendSyncForCall
(c, s->size * BytesPerWord, s->index * BytesPerWord, old, new_);
} else {
appendSyncForJump(c, old->size * BytesPerWord, old, new_);
appendSyncForJump
(c, s->size * BytesPerWord, s->index * BytesPerWord, old, new_);
}
}
c->state->stack = top;
}
void
@ -1137,13 +1359,9 @@ updateJunctions(Context* c)
if (i->predecessor >= 0) {
LogicalInstruction* p = c->logicalCode + i->predecessor;
MyOperand* new_ = 0;
for (MyOperand* old = i->firstEvent->stack; old; old = old->next) {
MyOperand* n = operand(c);
if (new_) new_->next = n;
new_ = n;
new_->size = old->size;
new_->index = old->index;
for (Stack* s = c->state->stack; s; s = s->next) {
MyOperand* old = s->operand;
MyOperand* new_ = operand(c);
if (old->event) {
old->event->replace(c, old, new_);
@ -1151,7 +1369,9 @@ updateJunctions(Context* c)
p->lastEvent = p->lastEvent->next = new
(c->zone->allocate(sizeof(SyncForJumpEvent)))
SyncForJumpEvent(p->lastEvent->next, old->size, old, new_);
SyncForJumpEvent
(c, p->lastEvent->next, s->size * BytesPerWord,
s->index * BytesPerWord, old, new_);
}
}
}
@ -1170,7 +1390,6 @@ compile(Context* c)
for (unsigned i = 0; i < c->logicalCodeLength; ++ i) {
fprintf(stderr, "compile ip %d\n", i);
for (Event* e = c->logicalCode[i].firstEvent; e; e = e->next) {
fprintf(stderr, "compile ip %d event\n", i);
e->compile(c);
if (e == c->logicalCode[i].lastEvent) break;
@ -1307,17 +1526,21 @@ class MyCompiler: public Compiler {
}
virtual void popped(unsigned count) {
for (int i = count; i >= 0;) {
MyOperand* o = c.state->stack;
c.state->stack = o->next;
count -= o->size;
for (unsigned i = count; i > 0;) {
Stack* s = c.state->stack;
c.state->stack = s->next;
i -= s->size;
}
}
virtual Operand* peek(unsigned index) {
MyOperand* a = c.state->stack;
for (; index; --index) a = a->next;
return a;
virtual Operand* peek(unsigned size, unsigned index) {
Stack* s = c.state->stack;
for (unsigned i = index; i > 0;) {
s = s->next;
i -= s->size;
}
assert(&c, s->size == ceiling(size, BytesPerWord));
return s->operand;
}
virtual Operand* call(Operand* address,
@ -1347,9 +1570,10 @@ class MyCompiler: public Compiler {
syncStack(&c, SyncForCall);
unsigned stackOffset = c.stackOffset + c.state->stack->index
+ (footprint > c.assembler->argumentRegisterCount() ?
footprint - c.assembler->argumentRegisterCount() : 0);
unsigned stackOffset = c.stackOffset
+ (c.state->stack ? c.state->stack->index
+ (footprint > c.assembler->argumentRegisterCount() ?
footprint - c.assembler->argumentRegisterCount() : 0) : 0);
MyOperand* result = operand(&c);
appendCall(&c, static_cast<MyOperand*>(address), indirection, flags,
@ -1384,6 +1608,12 @@ class MyCompiler: public Compiler {
return dst;
}
virtual Operand* dup(unsigned size, Operand* src) {
MyOperand* dst = operand(&c);
appendDup(&c, size, static_cast<MyOperand*>(src), dst);
return dst;
}
virtual void cmp(unsigned size, Operand* a, Operand* b) {
appendCompare(&c, size, static_cast<MyOperand*>(a),
static_cast<MyOperand*>(b));
@ -1530,7 +1760,7 @@ class MyCompiler: public Compiler {
int i = 0;
for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) {
*reinterpret_cast<intptr_t*>(dst + c.assembler->length() + (i++))
*reinterpret_cast<intptr_t*>(dst + pad(c.assembler->length()) + (i++))
= n->promise->value();
}
}

View File

@ -48,7 +48,7 @@ class Compiler {
virtual Operand* pop(unsigned size) = 0;
virtual void pushed(unsigned count) = 0;
virtual void popped(unsigned count) = 0;
virtual Operand* peek(unsigned index) = 0;
virtual Operand* peek(unsigned size, unsigned index) = 0;
virtual Operand* call(Operand* address,
void* indirection,
@ -64,6 +64,7 @@ class Compiler {
virtual Operand* load(unsigned size, Operand* src) = 0;
virtual Operand* loadz(unsigned size, Operand* src) = 0;
virtual Operand* load4To8(Operand* src) = 0;
virtual Operand* dup(unsigned size, Operand* src) = 0;
virtual void cmp(unsigned size, Operand* a, Operand* b) = 0;
virtual void jl(Operand* address) = 0;
virtual void jg(Operand* address) = 0;

View File

@ -121,7 +121,7 @@ class Task {
class OffsetTask: public Task {
public:
OffsetTask(Task* next, Promise* promise, int instructionOffset,
OffsetTask(Task* next, Promise* promise, unsigned instructionOffset,
unsigned instructionSize):
Task(next),
promise(promise),
@ -141,7 +141,7 @@ class OffsetTask: public Task {
}
Promise* promise;
int instructionOffset;
unsigned instructionOffset;
unsigned instructionSize;
};
@ -153,6 +153,30 @@ appendOffsetTask(Context* c, Promise* promise, int instructionOffset,
(c->tasks, promise, instructionOffset, instructionSize);
}
class ImmediateTask: public Task {
public:
ImmediateTask(Task* next, Promise* promise, unsigned offset):
Task(next),
promise(promise),
offset(offset)
{ }
virtual void run(Context* c) {
intptr_t v = promise->value();
memcpy(c->result + offset, &v, BytesPerWord);
}
Promise* promise;
unsigned offset;
};
void
appendImmediateTask(Context* c, Promise* promise, unsigned offset)
{
c->tasks = new (c->zone->allocate(sizeof(ImmediateTask))) ImmediateTask
(c->tasks, promise, offset);
}
void
encode(Context* c, uint8_t* instruction, unsigned length, int a, int b,
int32_t displacement, int index, unsigned scale)
@ -307,6 +331,18 @@ popR(Context* c, unsigned size, Assembler::Register* a)
}
}
void
leaRM(Context* c, unsigned size, Assembler::Register* a, Assembler::Memory* b)
{
if (BytesPerWord == 8 and size == 4) {
encode(c, 0x8d, a->low, b, false);
} else {
assert(c, BytesPerWord == 8 or size == 4);
encode(c, 0x8d, a->low, b, true);
}
}
void
moveCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
Assembler::Register* b)
@ -315,7 +351,12 @@ moveCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
rex(c);
c->code.append(0xb8 | b->low);
c->code.appendAddress(a->value->value());
if (a->value->resolved()) {
c->code.appendAddress(a->value->value());
} else {
appendImmediateTask(c, a->value, c->code.length());
c->code.appendAddress(static_cast<uintptr_t>(0));
}
}
void
@ -393,6 +434,19 @@ moveMR(Context* c, unsigned size, Assembler::Memory* a, Assembler::Register* b)
}
}
void
moveAR(Context* c, unsigned size, Assembler::Address* a,
Assembler::Register* b)
{
assert(c, BytesPerWord == 8 or size == 4); // todo
Assembler::Constant constant(a->address);
Assembler::Memory memory(b->low, 0, -1, 0);
moveCR(c, size, &constant, b);
moveMR(c, size, &memory, b);
}
void
move4To8MR(Context* c, unsigned, Assembler::Memory* a, Assembler::Register* b)
{
@ -412,6 +466,15 @@ addRR(Context* c, unsigned size, Assembler::Register* a,
c->code.append(0xc0 | (a->low << 3) | b->low);
}
void
addRM(Context* c, unsigned size, Assembler::Register* a,
Assembler::Memory* b)
{
assert(c, BytesPerWord == 8 or size == 4);
encode(c, 0x01, a->low, b, true);
}
void
populateTables()
{
@ -422,13 +485,16 @@ populateTables()
UnaryOperations[INDEX1(Push, Register)] = CAST1(pushR);
UnaryOperations[INDEX1(Pop, Register)] = CAST1(popR);
BinaryOperations[INDEX2(LoadAddress, Register, Memory)] = CAST2(leaRM);
BinaryOperations[INDEX2(Move, Constant, Register)] = CAST2(moveCR);
BinaryOperations[INDEX2(Move, Constant, Memory)] = CAST2(moveCM);
BinaryOperations[INDEX2(Move, Register, Memory)] = CAST2(moveRM);
BinaryOperations[INDEX2(Move, Register, Register)] = CAST2(moveRR);
BinaryOperations[INDEX2(Move, Memory, Register)] = CAST2(moveMR);
BinaryOperations[INDEX2(Move, Address, Register)] = CAST2(moveAR);
BinaryOperations[INDEX2(Move4To8, Memory, Register)] = CAST2(move4To8MR);
BinaryOperations[INDEX2(Add, Register, Register)] = CAST2(addRR);
BinaryOperations[INDEX2(Add, Register, Memory)] = CAST2(addRM);
}
class MyAssembler: public Assembler {
@ -442,7 +508,7 @@ class MyAssembler: public Assembler {
}
virtual unsigned registerCount() {
return BytesPerWord == 4 ? 8 : 16;
return 8;//BytesPerWord == 4 ? 8 : 16;
}
virtual int base() {

View File

@ -1,67 +1,60 @@
public class Misc {
// private static int alpha;
// private static int beta;
// private static byte byte1, byte2, byte3;
// private int gamma;
private static int alpha;
private static int beta;
private static byte byte1, byte2, byte3;
private int gamma;
// private String foo(String s) {
// return s;
// }
private String foo(String s) {
return s;
}
// public String bar(String s) {
// return s;
// }
public String bar(String s) {
return s;
}
// private static String baz(String s) {
// return s;
// }
private static String baz(String s) {
return s;
}
// private static void expect(boolean v) {
// if (! v) throw new RuntimeException();
// }
private static void expect(boolean v) {
if (! v) throw new RuntimeException();
}
// private synchronized byte sync() {
// byte[] array = new byte[123];
// return array[42];
// }
private synchronized byte sync() {
byte[] array = new byte[123];
return array[42];
}
// private static synchronized byte syncStatic(boolean throw_) {
// byte[] array = new byte[123];
// if (throw_) {
// throw new RuntimeException();
// } else {
// return array[42];
// }
// }
private static synchronized byte syncStatic(boolean throw_) {
byte[] array = new byte[123];
if (throw_) {
throw new RuntimeException();
} else {
return array[42];
}
}
// public static void putInt(int val, byte[] dst, int offset) {
// System.out.println("put " + val);
// dst[offset] = (byte)((val >> 24) & 0xff);
// dst[offset+1] = (byte)((val >> 16) & 0xff);
// dst[offset+2] = (byte)((val >> 8) & 0xff);
// dst[offset+3] = (byte)((val ) & 0xff);
// }
public static void putInt(int val, byte[] dst, int offset) {
System.out.println("put " + val);
dst[offset] = (byte)((val >> 24) & 0xff);
dst[offset+1] = (byte)((val >> 16) & 0xff);
dst[offset+2] = (byte)((val >> 8) & 0xff);
dst[offset+3] = (byte)((val ) & 0xff);
}
// public static void putLong(long val, byte[] dst, int offset) {
// putInt((int)(val >> 32), dst, offset);
// putInt((int)val, dst, offset + 4);
// }
public static void putLong(long val, byte[] dst, int offset) {
putInt((int)(val >> 32), dst, offset);
putInt((int)val, dst, offset + 4);
}
// public String toString() {
// return super.toString();
// }
public String toString() {
return super.toString();
}
public static void main(String[] args) {
int a = 2;
int b = 2;
int c = a + b;
// byte2 = 0;
// expect(byte2 == 0);
// Misc m = new Misc();
// m.toString();
// expect(Long.valueOf(231L) == 231L);
// long x = 231;
@ -97,6 +90,9 @@ public class Misc {
// int b = 2;
// int c = a + b;
Misc m = new Misc();
// m.toString();
// String s = "hello";
// m.foo(s);
// m.bar(s);