diff --git a/src/compile.cpp b/src/compile.cpp index 0d78e5e5ad..624d7a5938 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -836,26 +836,34 @@ class Frame { } void pushQuiet(unsigned size, Compiler::Operand* o) { - if (size == 8 and BytesPerWord == 8) { - c->push(8); - - context->eventLog.append(PushEvent); - context->eventLog.appendAddress(c->top()); - } - c->push(size, o); context->eventLog.append(PushEvent); context->eventLog.appendAddress(c->top()); } + void pushLongQuiet(Compiler::Operand* o) { + if (BytesPerWord == 8) { + c->push(8); + + context->eventLog.append(PushEvent); + context->eventLog.appendAddress(c->top()); + } + + pushQuiet(8, o); + } + Compiler::Operand* popQuiet(unsigned size) { context->eventLog.append(PopEvent); context->eventLog.appendAddress(c->top()); - Compiler::Operand* r = c->pop(size); + return c->pop(size); + } - if (size == 8 and BytesPerWord == 8) { + Compiler::Operand* popLongQuiet() { + Compiler::Operand* r = popQuiet(8); + + if (BytesPerWord == 8) { context->eventLog.append(PopEvent); context->eventLog.appendAddress(c->top()); @@ -890,7 +898,7 @@ class Frame { } void pushLong(Compiler::Operand* o) { - pushQuiet(8, o); + pushLongQuiet(o); pushedLong(); } @@ -919,7 +927,7 @@ class Frame { Compiler::Operand* popLong() { poppedLong(); - return popQuiet(8); + return popLongQuiet(); } Compiler::Operand* popObject() { @@ -992,10 +1000,10 @@ class Frame { Compiler::Operand* s0 = popQuiet(BytesPerWord); if (get(sp - 2) == Long) { - Compiler::Operand* s1 = popQuiet(8); + Compiler::Operand* s1 = popLongQuiet(); pushQuiet(BytesPerWord, s0); - pushQuiet(8, s1); + pushLongQuiet(s1); pushQuiet(BytesPerWord, s0); } else { Compiler::Operand* s1 = popQuiet(BytesPerWord); @@ -1012,7 +1020,7 @@ class Frame { void dup2() { if (get(sp - 1) == Long) { - pushQuiet(8, peekLong(0)); + pushLongQuiet(peekLong(0)); } else { Compiler::Operand* s0 = popQuiet(BytesPerWord); Compiler::Operand* s1 = popQuiet(BytesPerWord); @@ -1028,12 +1036,12 @@ class Frame { void dup2X1() { if (get(sp - 1) == Long) { - Compiler::Operand* s0 = popQuiet(8); + Compiler::Operand* s0 = popLongQuiet(); Compiler::Operand* s1 = popQuiet(BytesPerWord); - pushQuiet(8, s0); + pushLongQuiet(s0); pushQuiet(BytesPerWord, s1); - pushQuiet(8, s0); + pushLongQuiet(s0); } else { Compiler::Operand* s0 = popQuiet(BytesPerWord); Compiler::Operand* s1 = popQuiet(BytesPerWord); @@ -1051,22 +1059,22 @@ class Frame { void dup2X2() { if (get(sp - 1) == Long) { - Compiler::Operand* s0 = popQuiet(8); + Compiler::Operand* s0 = popLongQuiet(); if (get(sp - 3) == Long) { - Compiler::Operand* s1 = popQuiet(8); + Compiler::Operand* s1 = popLongQuiet(); - pushQuiet(8, s0); - pushQuiet(8, s1); - pushQuiet(8, s0); + pushLongQuiet(s0); + pushLongQuiet(s1); + pushLongQuiet(s0); } else { Compiler::Operand* s1 = popQuiet(BytesPerWord); Compiler::Operand* s2 = popQuiet(BytesPerWord); - pushQuiet(8, s0); + pushLongQuiet(s0); pushQuiet(BytesPerWord, s2); pushQuiet(BytesPerWord, s1); - pushQuiet(8, s0); + pushLongQuiet(s0); } } else { Compiler::Operand* s0 = popQuiet(BytesPerWord); @@ -1847,6 +1855,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, bool exceptionHandler) handleEntrance(t, frame); int index = 0; + if ((methodFlags(t, context->method) & ACC_STATIC) == 0) { + c->initParameter(1, index++); + } + for (MethodSpecIterator it (t, reinterpret_cast (&byteArrayBody(t, methodSpec(t, context->method), 0))); @@ -1860,8 +1872,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, bool exceptionHandler) break; default: - c->initParameter(1, index); - index += 1; + c->initParameter(1, index++); break; } } @@ -3856,15 +3867,15 @@ finish(MyThread* t, Context* context) } // for debugging: - if (//false and + if (false and strcmp (reinterpret_cast (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), - "Simple") == 0 and + "Hello") == 0 and strcmp (reinterpret_cast (&byteArrayBody(t, methodName(t, context->method), 0)), - "pow") == 0) + "main") == 0) { asm("int3"); } diff --git a/src/compiler.cpp b/src/compiler.cpp index 8c7540e352..dc28d08b80 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -264,6 +264,7 @@ class Context { localFootprint(0), maxStackFootprint(0), stackPadding(0), + machineCodeSize(0), constantCompare(CompareNone), pass(ScanPass) { @@ -296,6 +297,7 @@ class Context { unsigned localFootprint; unsigned maxStackFootprint; unsigned stackPadding; + unsigned machineCodeSize; ConstantCompare constantCompare; Pass pass; }; @@ -307,7 +309,7 @@ class PoolPromise: public Promise { virtual int64_t value() { if (resolved()) { return reinterpret_cast - (c->machineCode + pad(c->assembler->length()) + (key * BytesPerWord)); + (c->machineCode + pad(c->machineCodeSize) + (key * BytesPerWord)); } abort(c); @@ -1681,7 +1683,7 @@ class CallEvent: public Event { int footprint = stackArgumentFootprint; for (Stack* s = stack; s; s = s->next) { frameIndex -= s->size; - if (footprint) { + if (footprint > 0) { addRead(c, this, s->value, read(c, s->size * BytesPerWord, 1 << MemoryOperand, 0, frameIndex)); } else { @@ -1690,8 +1692,8 @@ class CallEvent: public Event { assert(c, index <= frameIndex); s->padding = frameIndex - index; } - addRead(c, this, s->value, read(c, s->size * BytesPerWord, - 1 << MemoryOperand, 0, index)); + addRead(c, this, s->value, read + (c, s->size * BytesPerWord, 1 << MemoryOperand, 0, index)); } footprint -= s->size; } @@ -2005,6 +2007,13 @@ class CombineEvent: public Event { nextRead(c, first); nextRead(c, second); + + if (c->arch->condensedAddressing()) { + removeSite(c, second, second->source); + if (result->reads) { + addSite(c, 0, 0, resultSize, result, second->source); + } + } } TernaryOperation type; @@ -2564,9 +2573,11 @@ populateSiteTables(Context* c, Event* e) if (e->junctionSites) { for (unsigned i = 0; i < c->localFootprint; ++i) { - frozenSiteIndex = resolveJunctionSite - (c, e, successor, successor->locals[i], i, frozenSites, - frozenSiteIndex); + if (successor->locals[i]) { + frozenSiteIndex = resolveJunctionSite + (c, e, successor, successor->locals[i], i, frozenSites, + frozenSiteIndex); + } } if (successor->stack) { @@ -2588,9 +2599,12 @@ populateSiteTables(Context* c, Event* e) if (e->successors->next) { unsigned size = sizeof(Site*) * frameFootprint; Site** savedSites = static_cast(c->zone->allocate(size)); + memset(savedSites, 0, size); for (unsigned i = 0; i < c->localFootprint; ++i) { - savedSites[i] = successor->locals[i]->sites; + if (successor->locals[i]) { + savedSites[i] = successor->locals[i]->sites; + } } if (successor->stack) { @@ -2613,9 +2627,11 @@ setSites(Context* c, Event* e, Site** sites) { for (unsigned i = 0; i < c->localFootprint; ++i) { Value* v = e->locals[i]; - clearSites(c, v); - if (live(v)) { - addSite(c, 0, 0, v->reads->size(c), v, sites[i]); + if (v) { + clearSites(c, v); + if (live(v)) { + addSite(c, 0, 0, v->reads->size(c), v, sites[i]); + } } } @@ -2705,7 +2721,9 @@ updateJunctionReads(Context* c, Event* e, Event* successor) StubReadPair* reads = e->junctionReads; for (unsigned i = 0; i < c->localFootprint; ++i) { - updateStubRead(c, reads++, successor->locals[i]->reads); + if (successor->locals[i]) { + updateStubRead(c, reads++, successor->locals[i]->reads); + } } for (Stack* s = successor->stack; s; s = s->next) { @@ -3182,7 +3200,6 @@ class MyCompiler: public Compiler { Value* result = value(&c); appendCall(&c, static_cast(address), flags, traceHandler, result, resultSize, c.stack, 0, argumentFootprint); - return result; } @@ -3193,6 +3210,7 @@ class MyCompiler: public Compiler { virtual void initParameter(unsigned size, unsigned index) { assert(&c, index < c.parameterFootprint); + fprintf(stderr, "init parameter %d size %d\n", index, size); Value* v = value(&c); appendParameter(&c, v, size, index); c.locals[index] = v; @@ -3370,7 +3388,7 @@ class MyCompiler: public Compiler { } virtual unsigned compile() { - return ::compile(&c); + return c.machineCodeSize = ::compile(&c); } virtual unsigned poolSize() { @@ -3383,7 +3401,7 @@ class MyCompiler: public Compiler { int i = 0; for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) { - *reinterpret_cast(dst + pad(c.assembler->length()) + i) + *reinterpret_cast(dst + pad(c.machineCodeSize) + i) = n->promise->value(); i += BytesPerWord; } diff --git a/src/x86.cpp b/src/x86.cpp index 3be8a6ee3d..c678cdf95a 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -744,6 +744,34 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a, } } +void +moveMM(Context* c, unsigned aSize, Assembler::Memory* a, + unsigned bSize, Assembler::Memory* b) +{ + assert(c, aSize == bSize); + + if (BytesPerWord == 8 or aSize <= 4) { + uint32_t mask; + if (BytesPerWord == 4 and aSize == 1) { + mask = (1 << rax) | (1 << rcx) | (1 << rdx) | (1 << rbx); + } else { + mask = ~static_cast(0); + } + + Assembler::Register tmp(c->client->acquireTemporary(mask)); + moveMR(c, aSize, a, aSize, &tmp); + moveRM(c, aSize, &tmp, bSize, b); + c->client->releaseTemporary(tmp.low); + } else { + Assembler::Register tmp(c->client->acquireTemporary(), + c->client->acquireTemporary()); + moveMR(c, aSize, a, aSize, &tmp); + moveRM(c, aSize, &tmp, bSize, b); + c->client->releaseTemporary(tmp.low); + c->client->releaseTemporary(tmp.high); + } +} + void moveAR(Context* c, unsigned aSize, Assembler::Address* a, unsigned bSize, Assembler::Register* b) @@ -851,6 +879,33 @@ compareRR(Context* c, unsigned aSize, Assembler::Register* a, c->code.append(0xc0 | (a->low << 3) | b->low); } +void +compareCR(Context* c, unsigned aSize, Assembler::Constant* a, + unsigned bSize, Assembler::Register* b) +{ + assert(c, aSize == bSize); + assert(c, BytesPerWord == 8 or aSize == 4); + + int64_t v = a->value->value(); + + if (isInt32(v)) { + if (aSize == 8) rex(c); + if (isInt8(v)) { + c->code.append(0x83); + c->code.append(0xf8 | b->low); + c->code.append(v); + } else { + c->code.append(0x81); + c->code.append(0xf8 | b->low); + c->code.append4(v); + } + } else { + Assembler::Register tmp(c->client->acquireTemporary()); + moveCR(c, aSize, a, aSize, &tmp); + compareRR(c, aSize, &tmp, bSize, b); + c->client->releaseTemporary(tmp.low); + } +} void addCarryRR(Context* c, unsigned size, Assembler::Register* a, Assembler::Register* b) @@ -1141,6 +1196,7 @@ populateTables(ArchitectureContext* c) zo[Return] = return_; uo[index(Call, C)] = CAST1(callC); + uo[index(Call, R)] = CAST1(callR); uo[index(AlignedCall, C)] = CAST1(alignedCallC); @@ -1165,8 +1221,11 @@ populateTables(ArchitectureContext* c) bo[index(Move, R, M)] = CAST2(moveRM); bo[index(Move, C, M)] = CAST2(moveCM); bo[index(Move, A, M)] = CAST2(moveAM); + bo[index(Move, A, R)] = CAST2(moveAR); + bo[index(Move, M, M)] = CAST2(moveMM); bo[index(Compare, R, R)] = CAST2(compareRR); + bo[index(Compare, C, R)] = CAST2(compareCR); bo[index(Add, C, R)] = CAST2(addCR); @@ -1454,11 +1513,18 @@ class MyAssembler: public Assembler { unsigned offset = 0; for (unsigned i = 0; i < argumentCount; ++i) { - Memory dst(rsp, offset * BytesPerWord); - apply(Move, - arguments[i].size, arguments[i].type, arguments[i].operand, - pad(arguments[i].size), MemoryOperand, &dst); - offset += ceiling(arguments[i].size, BytesPerWord); + if (i < arch_->argumentRegisterCount()) { + Register dst(arch_->argumentRegister(i)); + apply(Move, + arguments[i].size, arguments[i].type, arguments[i].operand, + pad(arguments[i].size), RegisterOperand, &dst); + } else { + Memory dst(rsp, offset * BytesPerWord); + apply(Move, + arguments[i].size, arguments[i].type, arguments[i].operand, + pad(arguments[i].size), MemoryOperand, &dst); + offset += ceiling(arguments[i].size, BytesPerWord); + } } }