mirror of
https://github.com/corda/corda.git
synced 2025-03-17 17:45:17 +00:00
got a simple arithmetic test working
This commit is contained in:
parent
9971eaa92a
commit
af9758a6d3
@ -168,6 +168,13 @@ class Assembler {
|
||||
virtual unsigned value() = 0;
|
||||
};
|
||||
|
||||
class Block {
|
||||
public:
|
||||
virtual ~Block() { }
|
||||
|
||||
virtual unsigned resolve(unsigned start, Block* next) = 0;
|
||||
};
|
||||
|
||||
class Architecture {
|
||||
public:
|
||||
virtual ~Architecture() { }
|
||||
@ -179,6 +186,8 @@ class Assembler {
|
||||
virtual int returnLow() = 0;
|
||||
virtual int returnHigh() = 0;
|
||||
|
||||
virtual bool condensedAddressing() = 0;
|
||||
|
||||
virtual bool reserved(int register_) = 0;
|
||||
|
||||
virtual unsigned argumentRegisterCount() = 0;
|
||||
@ -245,7 +254,7 @@ class Assembler {
|
||||
|
||||
virtual Offset* offset() = 0;
|
||||
|
||||
virtual void endBlock() = 0;
|
||||
virtual Block* endBlock() = 0;
|
||||
|
||||
virtual unsigned length() = 0;
|
||||
|
||||
|
@ -27,7 +27,7 @@ vmCall();
|
||||
|
||||
namespace {
|
||||
|
||||
const bool Verbose = false;
|
||||
const bool Verbose = true;
|
||||
const bool DebugNatives = false;
|
||||
const bool DebugCallTable = false;
|
||||
const bool DebugMethodTree = false;
|
||||
@ -3832,11 +3832,11 @@ finish(MyThread* t, Context* context)
|
||||
strcmp
|
||||
(reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
|
||||
"java/lang/String") == 0 and
|
||||
"Simple") == 0 and
|
||||
strcmp
|
||||
(reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, methodName(t, context->method), 0)),
|
||||
"compareTo") == 0)
|
||||
"main") == 0)
|
||||
{
|
||||
asm("int3");
|
||||
}
|
||||
@ -4959,6 +4959,8 @@ compileThunks(MyThread* t, MyProcessor* p)
|
||||
|
||||
Assembler::Register result(t->arch->returnLow());
|
||||
a->apply(Jump, BytesPerWord, RegisterOperand, &result);
|
||||
|
||||
a->endBlock()->resolve(0, 0);
|
||||
}
|
||||
|
||||
ThunkContext nativeContext(t);
|
||||
@ -4979,6 +4981,8 @@ compileThunks(MyThread* t, MyProcessor* p)
|
||||
a->popFrame();
|
||||
|
||||
a->apply(Return);
|
||||
|
||||
a->endBlock()->resolve(0, 0);
|
||||
}
|
||||
|
||||
ThunkContext aioobContext(t);
|
||||
@ -4996,6 +5000,8 @@ compileThunks(MyThread* t, MyProcessor* p)
|
||||
|
||||
Assembler::Constant proc(&(aioobContext.promise));
|
||||
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
|
||||
|
||||
a->endBlock()->resolve(0, 0);
|
||||
}
|
||||
|
||||
ThunkContext tableContext(t);
|
||||
@ -5006,6 +5012,8 @@ compileThunks(MyThread* t, MyProcessor* p)
|
||||
|
||||
Assembler::Constant proc(&(tableContext.promise));
|
||||
a->apply(LongJump, BytesPerWord, ConstantOperand, &proc);
|
||||
|
||||
a->endBlock()->resolve(0, 0);
|
||||
}
|
||||
|
||||
p->thunkSize = pad(tableContext.context.assembler->length());
|
||||
|
107
src/compiler.cpp
107
src/compiler.cpp
@ -15,8 +15,8 @@ using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
const bool DebugAppend = false;
|
||||
const bool DebugCompile = false;
|
||||
const bool DebugAppend = true;
|
||||
const bool DebugCompile = true;
|
||||
const bool DebugStack = false;
|
||||
const bool DebugRegisters = false;
|
||||
|
||||
@ -120,9 +120,10 @@ class State {
|
||||
|
||||
class LogicalInstruction {
|
||||
public:
|
||||
LogicalInstruction() {
|
||||
memset(this, 0, sizeof(LogicalInstruction));
|
||||
}
|
||||
LogicalInstruction(int index):
|
||||
firstEvent(0), lastEvent(0), immediatePredecessor(0), stack(0), locals(0),
|
||||
machineOffset(0), index(index), stackSaved(false)
|
||||
{ }
|
||||
|
||||
Event* firstEvent;
|
||||
Event* lastEvent;
|
||||
@ -321,6 +322,17 @@ class CodePromise: public Promise {
|
||||
CodePromise* next;
|
||||
};
|
||||
|
||||
unsigned
|
||||
machineOffset(Context* c, int logicalIp)
|
||||
{
|
||||
for (unsigned n = logicalIp; n < c->logicalCodeLength; ++n) {
|
||||
LogicalInstruction* i = c->logicalCode[n];
|
||||
if (i and i->machineOffset) return i->machineOffset->value();
|
||||
}
|
||||
|
||||
abort(c);
|
||||
}
|
||||
|
||||
class IpPromise: public Promise {
|
||||
public:
|
||||
IpPromise(Context* c, int logicalIp):
|
||||
@ -331,7 +343,7 @@ class IpPromise: public Promise {
|
||||
virtual int64_t value() {
|
||||
if (resolved()) {
|
||||
return reinterpret_cast<intptr_t>
|
||||
(c->machineCode + c->logicalCode[logicalIp]->machineOffset->value());
|
||||
(c->machineCode + machineOffset(c, logicalIp));
|
||||
}
|
||||
|
||||
abort(c);
|
||||
@ -365,6 +377,12 @@ expect(Context* c, bool v)
|
||||
expect(c->system, v);
|
||||
}
|
||||
|
||||
Cell*
|
||||
cons(Context* c, void* value, Cell* next)
|
||||
{
|
||||
return new (c->zone->allocate(sizeof(Cell))) Cell(next, value);
|
||||
}
|
||||
|
||||
class Event {
|
||||
public:
|
||||
Event(Context* c):
|
||||
@ -377,6 +395,8 @@ class Event {
|
||||
|
||||
if (c->lastEvent) {
|
||||
c->lastEvent->next = this;
|
||||
predecessors = cons(c, c->lastEvent, 0);
|
||||
c->lastEvent->successors = cons(c, this, c->lastEvent->successors);
|
||||
} else {
|
||||
c->firstEvent = this;
|
||||
}
|
||||
@ -1367,6 +1387,7 @@ insertRead(Context*, Event* event, int sequence, Value* v, Read* r)
|
||||
{
|
||||
r->value = v;
|
||||
r->event = event;
|
||||
r->eventNext = event->reads;
|
||||
event->reads = r;
|
||||
++ event->readCount;
|
||||
|
||||
@ -1791,10 +1812,12 @@ class CombineEvent: public Event {
|
||||
unsigned firstSize, Value* first,
|
||||
unsigned secondSize, Value* second,
|
||||
unsigned resultSize, Value* result,
|
||||
Read* firstRead, Read* secondRead):
|
||||
Read* firstRead,
|
||||
Read* secondRead,
|
||||
Read* resultRead):
|
||||
Event(c), type(type), firstSize(firstSize), first(first),
|
||||
secondSize(secondSize), second(second), resultSize(resultSize),
|
||||
result(result)
|
||||
result(result), resultRead(resultRead)
|
||||
{
|
||||
addRead(c, first, firstRead);
|
||||
addRead(c, second, secondRead);
|
||||
@ -1805,18 +1828,20 @@ class CombineEvent: public Event {
|
||||
fprintf(stderr, "CombineEvent.compile\n");
|
||||
}
|
||||
|
||||
maybePreserve(c, stack, locals, secondSize, second, second->source);
|
||||
Site* target;
|
||||
if (c->arch->condensedAddressing()) {
|
||||
maybePreserve(c, stack, locals, secondSize, second, second->source);
|
||||
target = second->source;
|
||||
} else {
|
||||
target = resultRead->allocateSite(c);
|
||||
addSite(c, stack, locals, resultSize, result, target);
|
||||
}
|
||||
|
||||
Site* target = targetOrRegister(c, result);
|
||||
apply(c, type, firstSize, first->source, secondSize, second->source,
|
||||
resultSize, target);
|
||||
|
||||
nextRead(c, first);
|
||||
nextRead(c, second);
|
||||
|
||||
if (live(result)) {
|
||||
addSite(c, 0, 0, resultSize, result, target);
|
||||
}
|
||||
}
|
||||
|
||||
TernaryOperation type;
|
||||
@ -1826,6 +1851,7 @@ class CombineEvent: public Event {
|
||||
Value* second;
|
||||
unsigned resultSize;
|
||||
Value* result;
|
||||
Read* resultRead;
|
||||
};
|
||||
|
||||
Value*
|
||||
@ -1902,7 +1928,15 @@ appendCombine(Context* c, TernaryOperation type,
|
||||
fprintf(stderr, "appendCombine\n");
|
||||
}
|
||||
|
||||
// todo: respect resultTypeMask and resultRegisterMask
|
||||
Read* resultRead = read
|
||||
(c, resultSize, resultTypeMask, resultRegisterMask, AnyFrameIndex);
|
||||
Read* secondRead;
|
||||
if (c->arch->condensedAddressing()) {
|
||||
secondRead = resultRead;
|
||||
} else {
|
||||
secondRead = read
|
||||
(c, secondSize, secondTypeMask, secondRegisterMask, AnyFrameIndex);
|
||||
}
|
||||
|
||||
new (c->zone->allocate(sizeof(CombineEvent)))
|
||||
CombineEvent
|
||||
@ -1911,7 +1945,8 @@ appendCombine(Context* c, TernaryOperation type,
|
||||
secondSize, second,
|
||||
resultSize, result,
|
||||
read(c, firstSize, firstTypeMask, firstRegisterMask, AnyFrameIndex),
|
||||
read(c, secondSize, secondTypeMask, secondRegisterMask, AnyFrameIndex));
|
||||
secondRead,
|
||||
resultRead);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2331,7 +2366,7 @@ propagateJunctionSites(Context* c, Event* e, Site** sites)
|
||||
unsigned
|
||||
frameFootprint(Context* c, Stack* s)
|
||||
{
|
||||
return c->localFootprint + s->index + s->size;
|
||||
return c->localFootprint + (s ? (s->index + s->size) : 0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2448,7 +2483,7 @@ next(Context* c, LogicalInstruction* i)
|
||||
{
|
||||
for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) {
|
||||
i = c->logicalCode[n];
|
||||
if (i) return i;
|
||||
if (i and i->firstEvent) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2456,12 +2491,12 @@ next(Context* c, LogicalInstruction* i)
|
||||
class Block {
|
||||
public:
|
||||
Block(Event* head):
|
||||
head(head), nextInstruction(0), offset(0), start(0)
|
||||
head(head), nextInstruction(0), assemblerBlock(0), start(0)
|
||||
{ }
|
||||
|
||||
Event* head;
|
||||
LogicalInstruction* nextInstruction;
|
||||
Assembler::Offset* offset;
|
||||
Assembler::Block* assemblerBlock;
|
||||
unsigned start;
|
||||
};
|
||||
|
||||
@ -2490,11 +2525,13 @@ compile(Context* c)
|
||||
e->logicalInstruction->machineOffset = a->offset();
|
||||
}
|
||||
|
||||
Event* predecessor = static_cast<Event*>(e->predecessors->value);
|
||||
if (e->predecessors->next) {
|
||||
setSites(c, e, predecessor->junctionSites);
|
||||
} else if (predecessor->successors->next) {
|
||||
setSites(c, e, predecessor->savedSites);
|
||||
if (e->predecessors) {
|
||||
Event* predecessor = static_cast<Event*>(e->predecessors->value);
|
||||
if (e->predecessors->next) {
|
||||
setSites(c, e, predecessor->junctionSites);
|
||||
} else if (predecessor->successors->next) {
|
||||
setSites(c, e, predecessor->savedSites);
|
||||
}
|
||||
}
|
||||
|
||||
populateSources(c, e);
|
||||
@ -2514,28 +2551,25 @@ compile(Context* c)
|
||||
if (e->next and e->logicalInstruction->lastEvent == e) {
|
||||
LogicalInstruction* nextInstruction = next(c, e->logicalInstruction);
|
||||
if (nextInstruction != e->next->logicalInstruction) {
|
||||
a->endBlock();
|
||||
|
||||
block->nextInstruction = nextInstruction;
|
||||
block->offset = a->offset();
|
||||
block->assemblerBlock = a->endBlock();
|
||||
block = ::block(c, e->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a->endBlock();
|
||||
|
||||
block->nextInstruction = 0;
|
||||
block->offset = a->offset();
|
||||
block->assemblerBlock = a->endBlock();
|
||||
|
||||
block = firstBlock;
|
||||
while (block->nextInstruction) {
|
||||
Block* next = block->nextInstruction->firstEvent->block;
|
||||
next->start = block->offset->resolve(block->start);
|
||||
next->start = block->assemblerBlock->resolve
|
||||
(block->start, next->assemblerBlock);
|
||||
block = next;
|
||||
}
|
||||
|
||||
return block->offset->resolve(block->start);
|
||||
return block->assemblerBlock->resolve(block->start, 0);
|
||||
}
|
||||
|
||||
unsigned
|
||||
@ -2599,8 +2633,11 @@ visit(Context* c, unsigned logicalIp)
|
||||
{
|
||||
assert(c, logicalIp < c->logicalCodeLength);
|
||||
|
||||
c->logicalCode[logicalIp] = new
|
||||
(c->zone->allocate(sizeof(LogicalInstruction))) LogicalInstruction;
|
||||
if (c->logicalCode[logicalIp] == 0) {
|
||||
c->logicalCode[logicalIp] = new
|
||||
(c->zone->allocate(sizeof(LogicalInstruction)))
|
||||
LogicalInstruction(logicalIp);
|
||||
}
|
||||
}
|
||||
|
||||
class Client: public Assembler::Client {
|
||||
|
164
src/x86.cpp
164
src/x86.cpp
@ -34,6 +34,8 @@ enum {
|
||||
r15 = 15,
|
||||
};
|
||||
|
||||
const unsigned FrameHeaderSize = 2;
|
||||
|
||||
inline bool
|
||||
isInt8(intptr_t v)
|
||||
{
|
||||
@ -48,19 +50,28 @@ isInt32(intptr_t v)
|
||||
|
||||
class Task;
|
||||
|
||||
class Block {
|
||||
class MyBlock: public Assembler::Block {
|
||||
public:
|
||||
Block(unsigned offset): offset(offset), start(~0) { }
|
||||
MyBlock(unsigned offset): offset(offset), start(~0), size(0), next(0) { }
|
||||
|
||||
virtual unsigned resolve(unsigned start, Assembler::Block* next) {
|
||||
this->start = start;
|
||||
this->next = static_cast<MyBlock*>(next);
|
||||
return start + size;
|
||||
}
|
||||
|
||||
unsigned offset;
|
||||
unsigned start;
|
||||
unsigned size;
|
||||
MyBlock* next;
|
||||
};
|
||||
|
||||
class Context {
|
||||
public:
|
||||
Context(System* s, Allocator* a, Zone* zone):
|
||||
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
|
||||
block(0)
|
||||
firstBlock(new (zone->allocate(sizeof(MyBlock))) MyBlock(0)),
|
||||
lastBlock(firstBlock)
|
||||
{ }
|
||||
|
||||
System* s;
|
||||
@ -69,7 +80,8 @@ class Context {
|
||||
Vector code;
|
||||
Task* tasks;
|
||||
uint8_t* result;
|
||||
Block* block;
|
||||
MyBlock* firstBlock;
|
||||
MyBlock* lastBlock;
|
||||
};
|
||||
|
||||
typedef void (*OperationType)(Context*);
|
||||
@ -623,11 +635,95 @@ moveCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
}
|
||||
|
||||
void
|
||||
subtractBorrowCR(Context* c, unsigned aSize UNUSED, Assembler::Constant* a,
|
||||
unsigned bSize UNUSED, Assembler::Register* b)
|
||||
addCarryRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
assert(c, BytesPerWord == 8 or size == 4);
|
||||
|
||||
if (size == 8) rex(c);
|
||||
c->code.append(0x11);
|
||||
c->code.append(0xc0 | (a->low << 3) | b->low);
|
||||
}
|
||||
|
||||
void
|
||||
addRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
unsigned bSize UNUSED, Assembler::Register* b)
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
assert(c, BytesPerWord == 8 or aSize == 4);
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
addRR(c, 4, a, 4, b);
|
||||
addCarryRR(c, 4, &ah, &bh);
|
||||
} else {
|
||||
if (aSize == 8) rex(c);
|
||||
c->code.append(0x01);
|
||||
c->code.append(0xc0 | (a->low << 3) | b->low);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
addCarryCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
assert(c, BytesPerWord == 8 or size == 4);
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (isInt8(v)) {
|
||||
c->code.append(0x83);
|
||||
c->code.append(0xd0 | b->low);
|
||||
c->code.append(v);
|
||||
} else {
|
||||
abort(c);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
addCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
unsigned bSize, Assembler::Register* b)
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (v) {
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
ResolvedPromise low(v & 0xFFFFFFFF);
|
||||
Assembler::Constant al(&low);
|
||||
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
addCR(c, 4, &al, 4, b);
|
||||
addCarryCR(c, 4, &ah, &bh);
|
||||
} else {
|
||||
if (aSize == 8) rex(c);
|
||||
if (isInt8(v)) {
|
||||
c->code.append(0x83);
|
||||
c->code.append(0xc0 | b->low);
|
||||
c->code.append(v);
|
||||
} else if (isInt32(v)) {
|
||||
c->code.append(0x81);
|
||||
c->code.append(0xc0 | b->low);
|
||||
c->code.append4(v);
|
||||
} else {
|
||||
Assembler::Register tmp(c->client->acquireTemporary());
|
||||
moveCR(c, aSize, a, aSize, &tmp);
|
||||
addRR(c, aSize, &tmp, bSize, b);
|
||||
c->client->releaseTemporary(tmp.low);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
assert(c, BytesPerWord == 8 or size == 4);
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (isInt8(v)) {
|
||||
@ -661,7 +757,7 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
subtractCR(c, 4, &al, 4, b);
|
||||
subtractBorrowCR(c, 4, &ah, 4, &bh);
|
||||
subtractBorrowCR(c, 4, &ah, &bh);
|
||||
} else {
|
||||
if (aSize == 8) rex(c);
|
||||
if (isInt8(v)) {
|
||||
@ -683,13 +779,12 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
}
|
||||
|
||||
void
|
||||
subtractBorrowRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
||||
unsigned bSize UNUSED, Assembler::Register* b)
|
||||
subtractBorrowRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
assert(c, BytesPerWord == 8 or aSize == 4);
|
||||
assert(c, BytesPerWord == 8 or size == 4);
|
||||
|
||||
if (aSize == 8) rex(c);
|
||||
if (size == 8) rex(c);
|
||||
c->code.append(0x19);
|
||||
c->code.append(0xc0 | (a->low << 3) | b->low);
|
||||
}
|
||||
@ -705,7 +800,7 @@ subtractRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
subtractRR(c, 4, a, 4, b);
|
||||
subtractBorrowRR(c, 4, &ah, 4, &bh);
|
||||
subtractBorrowRR(c, 4, &ah, &bh);
|
||||
} else {
|
||||
if (aSize == 8) rex(c);
|
||||
c->code.append(0x29);
|
||||
@ -741,9 +836,12 @@ populateTables(ArchitectureContext* c)
|
||||
uo[index(LongJump, C)] = CAST1(longJumpC);
|
||||
|
||||
bo[index(Move, R, R)] = CAST2(moveRR);
|
||||
bo[index(Move, C, R)] = CAST2(moveCR);
|
||||
bo[index(Move, M, R)] = CAST2(moveMR);
|
||||
bo[index(Move, R, M)] = CAST2(moveRM);
|
||||
|
||||
bo[index(Add, C, R)] = CAST2(addCR);
|
||||
|
||||
bo[index(Subtract, C, R)] = CAST2(subtractCR);
|
||||
}
|
||||
|
||||
@ -769,6 +867,10 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
return rax;
|
||||
}
|
||||
|
||||
virtual bool condensedAddressing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool reserved(int register_) {
|
||||
switch (register_) {
|
||||
case rbp:
|
||||
@ -822,7 +924,8 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
|
||||
virtual unsigned alignFrameSize(unsigned sizeInWords) {
|
||||
const unsigned alignment = 16 / BytesPerWord;
|
||||
return (ceiling(sizeInWords + 2, alignment) * alignment);
|
||||
return (ceiling(sizeInWords + FrameHeaderSize, alignment) * alignment)
|
||||
- FrameHeaderSize;
|
||||
}
|
||||
|
||||
virtual void* frameIp(void* stack) {
|
||||
@ -830,7 +933,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
|
||||
virtual unsigned frameHeaderSize() {
|
||||
return 2;
|
||||
return FrameHeaderSize;
|
||||
}
|
||||
|
||||
virtual unsigned frameFooterSize() {
|
||||
@ -936,7 +1039,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
|
||||
class MyOffset: public Assembler::Offset {
|
||||
public:
|
||||
MyOffset(Context* c, Block* block, unsigned offset):
|
||||
MyOffset(Context* c, MyBlock* block, unsigned offset):
|
||||
c(c), block(block), offset(offset)
|
||||
{ }
|
||||
|
||||
@ -955,7 +1058,7 @@ class MyOffset: public Assembler::Offset {
|
||||
}
|
||||
|
||||
Context* c;
|
||||
Block* block;
|
||||
MyBlock* block;
|
||||
unsigned offset;
|
||||
};
|
||||
|
||||
@ -1002,14 +1105,15 @@ class MyAssembler: public Assembler {
|
||||
}
|
||||
va_end(a);
|
||||
|
||||
allocateFrame(footprint);
|
||||
allocateFrame(arch_->alignFrameSize(footprint));
|
||||
|
||||
unsigned offset = 0;
|
||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||
Memory dst(rsp, footprint);
|
||||
Memory dst(rsp, offset * BytesPerWord);
|
||||
apply(Move,
|
||||
arguments[i].size, arguments[i].type, arguments[i].operand,
|
||||
pad(arguments[i].size), MemoryOperand, &dst);
|
||||
footprint -= ceiling(arguments[i].size, BytesPerWord);
|
||||
offset += ceiling(arguments[i].size, BytesPerWord);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1021,8 +1125,7 @@ class MyAssembler: public Assembler {
|
||||
apply(Move, BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &base);
|
||||
|
||||
Constant footprintConstant
|
||||
(resolved(&c, arch_->alignFrameSize(footprint) * BytesPerWord));
|
||||
Constant footprintConstant(resolved(&c, footprint * BytesPerWord));
|
||||
apply(Subtract, BytesPerWord, ConstantOperand, &footprintConstant,
|
||||
BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
@ -1070,7 +1173,10 @@ class MyAssembler: public Assembler {
|
||||
|
||||
virtual void writeTo(uint8_t* dst) {
|
||||
c.result = dst;
|
||||
memcpy(dst, c.code.data, c.code.length());
|
||||
|
||||
for (MyBlock* b = c.firstBlock; b; b = b->next) {
|
||||
memcpy(dst + b->start, c.code.data + b->offset, b->size);
|
||||
}
|
||||
|
||||
for (Task* t = c.tasks; t; t = t->next) {
|
||||
t->run(&c);
|
||||
@ -1079,11 +1185,15 @@ class MyAssembler: public Assembler {
|
||||
|
||||
virtual Offset* offset() {
|
||||
return new (c.zone->allocate(sizeof(MyOffset)))
|
||||
MyOffset(&c, c.block, c.code.length());
|
||||
MyOffset(&c, c.lastBlock, c.code.length());
|
||||
}
|
||||
|
||||
virtual void endBlock() {
|
||||
c.block = new (c.zone->allocate(sizeof(Block))) Block(c.code.length());
|
||||
virtual Block* endBlock() {
|
||||
MyBlock* b = c.lastBlock;
|
||||
b->size = c.code.length() - b->offset;
|
||||
c.lastBlock = new (c.zone->allocate(sizeof(MyBlock)))
|
||||
MyBlock(c.code.length());
|
||||
return b;
|
||||
}
|
||||
|
||||
virtual unsigned length() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user