From d654c943f346b71d75ee489a24fcbb465205a92e Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Sun, 17 Feb 2008 13:57:40 -0700 Subject: [PATCH] various bugfixes and tweaks in new compiler, primarily related to duplicating stack operands --- src/compile.cpp | 50 +++-- src/compiler.cpp | 472 +++++++++++++++++++++++++++++++++++------------ src/compiler.h | 3 +- src/x86.cpp | 74 +++++++- test/Misc.java | 94 +++++----- 5 files changed, 492 insertions(+), 201 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 753fd663c8..3106bb73d0 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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(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(&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) { diff --git a/src/compiler.cpp b/src/compiler.cpp index ad54cf58d7..7e40a4655c 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -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 - (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(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(o)->register_.low == register_.low + and static_cast(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(o)->value.base == value.base + and static_cast(o)->value.offset == value.offset + and static_cast(o)->value.index == value.index + and static_cast(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(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(src), dst); + return dst; + } + virtual void cmp(unsigned size, Operand* a, Operand* b) { appendCompare(&c, size, static_cast(a), static_cast(b)); @@ -1530,7 +1760,7 @@ class MyCompiler: public Compiler { int i = 0; for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) { - *reinterpret_cast(dst + c.assembler->length() + (i++)) + *reinterpret_cast(dst + pad(c.assembler->length()) + (i++)) = n->promise->value(); } } diff --git a/src/compiler.h b/src/compiler.h index aa8a35d381..5eb2593e29 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -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; diff --git a/src/x86.cpp b/src/x86.cpp index 63f0f65671..b58944785c 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -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(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() { diff --git a/test/Misc.java b/test/Misc.java index 3565bd4871..76d62c04d6 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -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);