From e13b755048e3ae11b88309102d99077e82a68524 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 5 Sep 2008 09:00:38 -0600 Subject: [PATCH] more progress towards new JIT code - this compiles but won't run properly --- src/assembler.h | 8 +-- src/compiler.cpp | 154 +++++++++++++++++++++++++---------------------- src/compiler.h | 2 +- src/x86.cpp | 154 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 240 insertions(+), 78 deletions(-) diff --git a/src/assembler.h b/src/assembler.h index a8a5194757..87bf9110df 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -222,10 +222,10 @@ class Assembler { virtual Architecture* arch() = 0; - virtual void saveFrame(unsigned stackOffset, unsigned baseOffset); - virtual void pushFrame(unsigned argumentCount, ...); - virtual void allocateFrame(unsigned footprint); - virtual void popFrame(); + virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) = 0; + virtual void pushFrame(unsigned argumentCount, ...) = 0; + virtual void allocateFrame(unsigned footprint) = 0; + virtual void popFrame() = 0; virtual void apply(Operation op) = 0; diff --git a/src/compiler.cpp b/src/compiler.cpp index 3593cd2d63..1241d3783f 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -2203,6 +2203,42 @@ appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, (c, object, lengthOffset, index, handler); } +// class ClobberLocalEvent: public Event { +// public: +// ClobberLocalEvent(Context* c, unsigned size, int index): +// Event(c), size(size), index(index) +// { } + +// virtual void compile(Context* c) { +// if (DebugCompile) { +// fprintf(stderr, "ClobberLocalEvent.compile\n"); +// } + +// Value* v = locals[index]; +// if (live(v) +// and v->sites->next == 0 +// and v->sites->match(c, 1 << MemoryOperand, 0, index)) +// { +// preserve(c, stack, locals, size, v, v->sites, v->reads); +// removeSite(c, v, v->sites); +// } +// } + +// unsigned size; +// int index; +// }; + +// void +// appendClobberLocal(Context* c, unsigned size, int index) +// { +// if (DebugAppend) { +// fprintf(stderr, "appendClobberLocal\n"); +// } + +// new (c->zone->allocate(sizeof(ClobberLocalEvent))) +// ClobberLocalEvent(c, size, index); +// } + Site* readSource(Context* c, Stack* stack, Value** locals, Read* r) { @@ -2567,19 +2603,13 @@ class Client: public Assembler::Client { } virtual void save(int r) { - if (c->registers[r]->refCount or c->registers[r]->value) { - Assembler::Register operand(r); - c->assembler->apply(Push, BytesPerWord, RegisterOperand, &operand); - c->registers[r]->pushed = true; - } + // todo + expect(c, c->registers[r]->refCount == 0); + expect(c, c->registers[r]->value == 0); } - virtual void restore(int r) { - if (c->registers[r]->pushed) { - Assembler::Register operand(r); - c->assembler->apply(Pop, BytesPerWord, RegisterOperand, &operand); - c->registers[r]->pushed = false; - } + virtual void restore(int) { + // todo } Context* c; @@ -2607,7 +2637,7 @@ class MyCompiler: public Compiler { } virtual void resetStack() { - ::resetStack(&c); + // todo: anything? } virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint, @@ -2622,9 +2652,9 @@ class MyCompiler: public Compiler { (c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength)); memset(c.logicalCode, 0, sizeof(LogicalInstruction*) * logicalCodeLength); - c.localTable = static_cast - (c.zone->allocate(sizeof(Local*) * localFootprint)); - memset(c.localTable, 0, sizeof(Local*) * localFootprint); + c.state->locals = static_cast + (c.zone->allocate(sizeof(Value*) * localFootprint)); + memset(c.state->locals, 0, sizeof(Value*) * localFootprint); } virtual void visitLogicalIp(unsigned logicalIp) { @@ -2696,17 +2726,17 @@ class MyCompiler: public Compiler { } virtual Operand* stack() { - Site* s = registerSite(&c, c.assembler->stack()); - return value(&c, s, s); - } - - virtual Operand* base() { - Site* s = registerSite(&c, c.assembler->base()); + Site* s = registerSite(&c, c.arch->stack()); return value(&c, s, s); } virtual Operand* thread() { - Site* s = registerSite(&c, c.assembler->thread()); + Site* s = registerSite(&c, c.arch->thread()); + return value(&c, s, s); + } + + virtual Operand* stackTop() { + Site* s = frameSite(&c, c.state->stack->index); return value(&c, s, s); } @@ -2719,9 +2749,6 @@ class MyCompiler: public Compiler { } virtual void mark(Operand* label) { - appendStackSync(&c); - ::resetStack(&c); - for (Site* s = static_cast(label)->sites; s; s = s->next) { if (s->type(&c) == ConstantOperand) { static_cast(s)->value.value = machineIp(); @@ -2749,13 +2776,9 @@ class MyCompiler: public Compiler { virtual void pushed() { Value* v = value(&c); c.state->stack = ::stack(&c, v, 1, c.state->stack); - c.state->stack->pushed = true; - appendPushed(&c, c.state->stack); } virtual void popped() { - appendPop(&c, c.state->stack->size, true); - c.state->stack = c.state->stack->next; } @@ -2794,7 +2817,7 @@ class MyCompiler: public Compiler { unsigned size = BytesPerWord; Value* arguments[argumentCount]; unsigned argumentSizes[argumentCount]; - unsigned index = 0; + int index = 0; for (unsigned i = 0; i < argumentCount; ++i) { Value* o = va_arg(a, Value*); if (o) { @@ -2810,13 +2833,6 @@ class MyCompiler: public Compiler { va_end(a); - for (Stack* s = c.state->stack; s; s = s->next) { - if (s->pushEvent == 0) { - appendPush(&c, s); - } - s->pushEvent->active = true; - } - Stack* oldStack = c.state->stack; Stack* bottomArgument = 0; @@ -2829,13 +2845,6 @@ class MyCompiler: public Compiler { Stack* argumentStack = c.state->stack; c.state->stack = oldStack; - unsigned padding = c->assembler->stackPadding - (c.state->stack->index + c.state->stack->size); - - if (bottomArgument) { - bottomArgument->padding = padding; - } - Value* result = value(&c); appendCall(&c, static_cast(address), flags, traceHandler, result, resultSize, argumentStack, index, 0); @@ -2860,20 +2869,20 @@ class MyCompiler: public Compiler { appendReturn(&c, size, static_cast(value)); } - virtual void storeLocal(unsigned size, Operand* src, unsigned index) { + virtual void storeLocal(unsigned, Operand* src, unsigned index) { assert(&c, index < c.localFootprint); - if (c.state->locals[index]) { - appendClobberLocal(&c, size, c.state->locals[index]); - } +// if (c.state->locals[index]) { +// appendClobberLocal(&c, size, index); +// } - Value* v = static_cast(memory(base(), localOffset(&c, index))); - store(size, src, v); +// Value* v = static_cast(memory(base(), localOffset(&c, index))); +// store(size, src, v); - c.state->locals[index] = v; + c.state->locals[index] = static_cast(src); } - virtual Operand* loadLocal(unsigned size, unsigned index) { + virtual Operand* loadLocal(unsigned, unsigned index) { assert(&c, index < c.localFootprint); assert(&c, c.state->locals[index]); @@ -2889,31 +2898,31 @@ class MyCompiler: public Compiler { virtual void store(unsigned size, Operand* src, Operand* dst) { appendMove(&c, Move, size, static_cast(src), - static_cast(dst)); + size, static_cast(dst)); } virtual Operand* load(unsigned size, Operand* src) { Value* dst = value(&c); - appendMove(&c, Move, size, static_cast(src), dst); + appendMove(&c, Move, size, static_cast(src), size, dst); return dst; } virtual Operand* loadz(unsigned size, Operand* src) { Value* dst = value(&c); - appendMove(&c, MoveZ, size, static_cast(src), dst); + appendMove(&c, MoveZ, size, static_cast(src), size, dst); return dst; } virtual Operand* load4To8(Operand* src) { Value* dst = value(&c); - appendMove(&c, Move4To8, 8, static_cast(src), dst); + appendMove(&c, Move, 4, static_cast(src), 8, dst); return dst; } virtual Operand* lcmp(Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, LongCompare, 8, static_cast(a), - static_cast(b), result); + 8, static_cast(b), 8, result); return result; } @@ -2953,77 +2962,77 @@ class MyCompiler: public Compiler { virtual Operand* add(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, Add, size, static_cast(a), - static_cast(b), result); + size, static_cast(b), size, result); return result; } virtual Operand* sub(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, Subtract, size, static_cast(a), - static_cast(b), result); + size, static_cast(b), size, result); return result; } virtual Operand* mul(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, Multiply, size, static_cast(a), - static_cast(b), result); + size, static_cast(b), size, result); return result; } virtual Operand* div(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, Divide, size, static_cast(a), - static_cast(b), result); + size, static_cast(b), size, result); return result; } virtual Operand* rem(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, Remainder, size, static_cast(a), - static_cast(b), result); + size, static_cast(b), size, result); return result; } virtual Operand* shl(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); - appendCombine(&c, ShiftLeft, size, static_cast(a), - static_cast(b), result); + appendCombine(&c, ShiftLeft, BytesPerWord, static_cast(a), + size, static_cast(b), size, result); return result; } virtual Operand* shr(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); - appendCombine(&c, ShiftRight, size, static_cast(a), - static_cast(b), result); + appendCombine(&c, ShiftRight, BytesPerWord, static_cast(a), + size, static_cast(b), size, result); return result; } virtual Operand* ushr(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); - appendCombine(&c, UnsignedShiftRight, size, static_cast(a), - static_cast(b), result); + appendCombine(&c, UnsignedShiftRight, BytesPerWord, static_cast(a), + size, static_cast(b), size, result); return result; } virtual Operand* and_(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, And, size, static_cast(a), - static_cast(b), result); + size, static_cast(b), size, result); return result; } virtual Operand* or_(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, Or, size, static_cast(a), - static_cast(b), result); + size, static_cast(b), size, result); return result; } virtual Operand* xor_(unsigned size, Operand* a, Operand* b) { Value* result = value(&c); appendCombine(&c, Xor, size, static_cast(a), - static_cast(b), result); + size, static_cast(b), size, result); return result; } @@ -3034,7 +3043,6 @@ class MyCompiler: public Compiler { } virtual unsigned compile() { - updateJunctions(&c); return ::compile(&c); } @@ -3044,7 +3052,7 @@ class MyCompiler: public Compiler { virtual void writeTo(uint8_t* dst) { c.machineCode = dst; - c.assembler->writeTo(&c, dst); + c.assembler->writeTo(dst); int i = 0; for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) { diff --git a/src/compiler.h b/src/compiler.h index ae83bfe9de..e4339ecdf0 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -62,7 +62,7 @@ class Compiler { virtual Operand* stack() = 0; virtual Operand* thread() = 0; - virtual Operand* stackTop(); + virtual Operand* stackTop() = 0; virtual Operand* label() = 0; virtual void mark(Operand* label) = 0; diff --git a/src/x86.cpp b/src/x86.cpp index 03f2ba987b..dba2b3ae66 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -348,6 +348,97 @@ index(TernaryOperation operation, + (TernaryOperationCount * OperandTypeCount * OperandTypeCount * operand3); } +void +pushR(Context* c, unsigned size, Assembler::Register* a) +{ + if (BytesPerWord == 4 and size == 8) { + Assembler::Register ah(a->high); + + pushR(c, 4, &ah); + pushR(c, 4, a); + } else { + c->code.append(0x50 | a->low); + } +} + +void +moveRR(Context* c, unsigned aSize, Assembler::Register* a, + unsigned bSize, Assembler::Register* b) +{ + if (BytesPerWord == 4 and aSize == 8 and bSize == 8) { + Assembler::Register ah(a->high); + Assembler::Register bh(b->high); + + moveRR(c, 4, a, 4, b); + moveRR(c, 4, &ah, 4, &bh); + } else { + switch (aSize) { + case 1: + if (BytesPerWord == 4 and a->low > rbx) { + assert(c, b->low <= rbx); + + moveRR(c, BytesPerWord, a, BytesPerWord, b); + moveRR(c, 1, b, BytesPerWord, b); + } else { + rex(c); + c->code.append(0x0f); + c->code.append(0xbe); + c->code.append(0xc0 | (b->low << 3) | a->low); + } + break; + + case 2: + rex(c); + c->code.append(0x0f); + c->code.append(0xbf); + c->code.append(0xc0 | (b->low << 3) | a->low); + break; + + case 8: + case 4: + if (aSize == 4 and bSize == 8) { + if (BytesPerWord == 8) { + rex(c); + c->code.append(0x63); + c->code.append(0xc0 | (b->low << 3) | a->low); + } else { + if (a->low == rax and b->low == rax and b->high == rdx) { + c->code.append(0x99); // cdq + } else { + assert(c, b->low == rax and b->high == rdx); + + moveRR(c, 4, a, 4, b); + moveRR(c, 4, b, 8, b); + } + } + } else { + if (a->low != b->low) { + rex(c); + c->code.append(0x89); + c->code.append(0xc0 | (a->low << 3) | b->low); + } + } + break; + } + } +} + +void +popR(Context* c, unsigned size, Assembler::Register* a) +{ + if (BytesPerWord == 4 and size == 8) { + Assembler::Register ah(a->high); + + popR(c, 4, a); + popR(c, 4, &ah); + } else { + c->code.append(0x58 | a->low); + if (BytesPerWord == 8 and size == 4) { + moveRR(c, 4, a, 8, a); + } + } +} + void populateTables(ArchitectureContext*) { @@ -565,6 +656,69 @@ class MyAssembler: public Assembler { return arch_; } + virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) { + Register stack(rsp); + Memory stackDst(rbx, stackOffset); + apply(Move, BytesPerWord, RegisterOperand, &stack, + BytesPerWord, MemoryOperand, &stackDst); + + Register base(rbp); + Memory baseDst(rbx, baseOffset); + apply(Move, BytesPerWord, RegisterOperand, &base, + BytesPerWord, MemoryOperand, &baseDst); + } + + virtual void pushFrame(unsigned argumentCount, ...) { + struct { + unsigned size; + OperandType type; + Operand* operand; + } arguments[argumentCount]; + va_list a; va_start(a, argumentCount); + unsigned footprint = 0; + for (unsigned i = 0; i < argumentCount; ++i) { + arguments[i].size = va_arg(a, unsigned); + arguments[i].type = static_cast(va_arg(a, int)); + arguments[i].operand = va_arg(a, Operand*); + footprint += ceiling(arguments[i].size, BytesPerWord); + } + va_end(a); + + allocateFrame(footprint); + + for (unsigned i = 0; i < argumentCount; ++i) { + Memory dst(rsp, footprint); + apply(Move, + arguments[i].size, arguments[i].type, arguments[i].operand, + pad(arguments[i].size), MemoryOperand, &dst); + footprint -= ceiling(arguments[i].size, BytesPerWord); + } + } + + virtual void allocateFrame(unsigned footprint) { + Register base(rbp); + pushR(&c, BytesPerWord, &base); + + Register stack(rsp); + apply(Move, BytesPerWord, RegisterOperand, &stack, + BytesPerWord, RegisterOperand, &base); + + Constant footprintConstant + (resolved(&c, arch_->alignFrameSize(footprint) * BytesPerWord)); + apply(Subtract, BytesPerWord, ConstantOperand, &footprintConstant, + BytesPerWord, RegisterOperand, &stack, + BytesPerWord, RegisterOperand, &stack); + } + + virtual void popFrame() { + Register base(rbp); + Register stack(rsp); + apply(Move, BytesPerWord, RegisterOperand, &base, + BytesPerWord, RegisterOperand, &stack); + + popR(&c, BytesPerWord, &base); + } + virtual void apply(Operation op) { arch_->c.operations[op](&c); }