mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
remove virtual stack code due to problems with jumps, to be revisited along with other optimizations when everything is working; various bugfixes
This commit is contained in:
parent
fab77e4d96
commit
fe24005ff0
@ -77,7 +77,7 @@ vmInvoke:
|
|||||||
// 20(%ebp): stackSize
|
// 20(%ebp): stackSize
|
||||||
// 24(%ebp): returnType
|
// 24(%ebp): returnType
|
||||||
|
|
||||||
mov 8(%ebp),%rbx
|
mov 8(%ebp),%ebx
|
||||||
|
|
||||||
// reserve space for arguments
|
// reserve space for arguments
|
||||||
subl 20(%ebp),%esp
|
subl 20(%ebp),%esp
|
||||||
|
@ -1403,7 +1403,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case areturn:
|
case areturn:
|
||||||
c->epilogue();
|
|
||||||
c->return_(frame->popObject());
|
c->return_(frame->popObject());
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2130,7 +2129,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
|
|
||||||
case ireturn:
|
case ireturn:
|
||||||
case freturn:
|
case freturn:
|
||||||
c->epilogue();
|
|
||||||
c->return_(frame->popInt());
|
c->return_(frame->popInt());
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2367,7 +2365,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
|
|||||||
|
|
||||||
case lreturn:
|
case lreturn:
|
||||||
case dreturn:
|
case dreturn:
|
||||||
c->epilogue();
|
|
||||||
c->return_(frame->popLong());
|
c->return_(frame->popLong());
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2866,7 +2863,7 @@ compile(MyThread* t, Compiler* c, object method)
|
|||||||
|
|
||||||
unsigned footprint = methodParameterFootprint(t, method);
|
unsigned footprint = methodParameterFootprint(t, method);
|
||||||
unsigned locals = codeMaxLocals(t, code);
|
unsigned locals = codeMaxLocals(t, code);
|
||||||
c->sub(c->constant((locals - footprint) * BytesPerWord), c->stack());
|
c->reserve(locals - footprint);
|
||||||
|
|
||||||
Vector objectPool(t->m->system, 256);
|
Vector objectPool(t->m->system, 256);
|
||||||
Vector traceLog(t->m->system, 1024);
|
Vector traceLog(t->m->system, 1024);
|
||||||
|
254
src/compiler.cpp
254
src/compiler.cpp
@ -178,10 +178,6 @@ class MyOperand: public Operand {
|
|||||||
return BytesPerWord;
|
return BytesPerWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual StackOperand* logicalPush(Context* c) { abort(c); }
|
|
||||||
|
|
||||||
virtual void logicalFlush(Context*, StackOperand*) { /* ignore */ }
|
|
||||||
|
|
||||||
virtual Register asRegister(Context* c) { abort(c); }
|
virtual Register asRegister(Context* c) { abort(c); }
|
||||||
|
|
||||||
virtual void release(Context*) { /* ignore */ }
|
virtual void release(Context*) { /* ignore */ }
|
||||||
@ -204,16 +200,9 @@ class MyOperand: public Operand {
|
|||||||
class RegisterOperand: public MyOperand {
|
class RegisterOperand: public MyOperand {
|
||||||
public:
|
public:
|
||||||
RegisterOperand(Register value):
|
RegisterOperand(Register value):
|
||||||
value(value), reserved(false), stack(0)
|
value(value), reserved(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual StackOperand* logicalPush(Context* c);
|
|
||||||
|
|
||||||
virtual void logicalFlush(Context* c UNUSED, StackOperand* s UNUSED) {
|
|
||||||
assert(c, stack == s);
|
|
||||||
stack = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Register asRegister(Context*) {
|
virtual Register asRegister(Context*) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -236,7 +225,6 @@ class RegisterOperand: public MyOperand {
|
|||||||
|
|
||||||
Register value;
|
Register value;
|
||||||
bool reserved;
|
bool reserved;
|
||||||
StackOperand* stack;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImmediateOperand: public MyOperand {
|
class ImmediateOperand: public MyOperand {
|
||||||
@ -245,8 +233,6 @@ class ImmediateOperand: public MyOperand {
|
|||||||
value(value)
|
value(value)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual StackOperand* logicalPush(Context* c);
|
|
||||||
|
|
||||||
virtual void apply(Context* c, Operation operation);
|
virtual void apply(Context* c, Operation operation);
|
||||||
|
|
||||||
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
||||||
@ -262,8 +248,6 @@ class AbsoluteOperand: public MyOperand {
|
|||||||
value(value)
|
value(value)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual StackOperand* logicalPush(Context* c);
|
|
||||||
|
|
||||||
virtual void apply(Context* c, Operation operation);
|
virtual void apply(Context* c, Operation operation);
|
||||||
|
|
||||||
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
||||||
@ -290,7 +274,7 @@ class MemoryOperand: public MyOperand {
|
|||||||
assert(static_cast<System*>(0), scale == 1); // todo
|
assert(static_cast<System*>(0), scale == 1); // todo
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual StackOperand* logicalPush(Context* c);
|
virtual Register asRegister(Context*);
|
||||||
|
|
||||||
virtual void apply(Context* c, Operation operation);
|
virtual void apply(Context* c, Operation operation);
|
||||||
|
|
||||||
@ -336,24 +320,22 @@ class SelectionOperand: public MyOperand {
|
|||||||
|
|
||||||
class StackOperand: public MyOperand {
|
class StackOperand: public MyOperand {
|
||||||
public:
|
public:
|
||||||
StackOperand(MyOperand* base, StackOperand* next):
|
StackOperand(MyOperand* base, int index, StackOperand* next):
|
||||||
base(base), next(next), flushed(false)
|
base(base), index(index), next(next)
|
||||||
{
|
{ }
|
||||||
if (next) {
|
|
||||||
index = next->index + (next->footprint() / BytesPerWord);
|
|
||||||
} else {
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual StackOperand* logicalPush(Context* c) {
|
virtual unsigned footprint() {
|
||||||
return base->logicalPush(c);
|
return base->footprint();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Register asRegister(Context* c) {
|
virtual Register asRegister(Context* c) {
|
||||||
return base->asRegister(c);
|
return base->asRegister(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void apply(Context* c, Operation operation) {
|
||||||
|
base->apply(c, operation);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void accept(Context* c, Operation operation,
|
virtual void accept(Context* c, Operation operation,
|
||||||
RegisterOperand* operand)
|
RegisterOperand* operand)
|
||||||
{
|
{
|
||||||
@ -361,9 +343,8 @@ class StackOperand: public MyOperand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MyOperand* base;
|
MyOperand* base;
|
||||||
StackOperand* next;
|
|
||||||
int index;
|
int index;
|
||||||
bool flushed;
|
StackOperand* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
@ -376,7 +357,8 @@ class Context {
|
|||||||
zone(s, 8 * 1024),
|
zone(s, 8 * 1024),
|
||||||
indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)),
|
indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)),
|
||||||
stack(0),
|
stack(0),
|
||||||
ipTable(0)
|
ipTable(0),
|
||||||
|
reserved(0)
|
||||||
{
|
{
|
||||||
ipMappings.appendAddress
|
ipMappings.appendAddress
|
||||||
(new (zone.allocate(sizeof(IpMapping))) IpMapping(-1, 0));
|
(new (zone.allocate(sizeof(IpMapping))) IpMapping(-1, 0));
|
||||||
@ -407,6 +389,7 @@ class Context {
|
|||||||
intptr_t indirectCaller;
|
intptr_t indirectCaller;
|
||||||
StackOperand* stack;
|
StackOperand* stack;
|
||||||
IpMapping** ipTable;
|
IpMapping** ipTable;
|
||||||
|
unsigned reserved;
|
||||||
RegisterOperand* registers[RegisterCount];
|
RegisterOperand* registers[RegisterCount];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -465,72 +448,49 @@ currentMapping(Context* c)
|
|||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
flush(Context* c, StackOperand* s)
|
|
||||||
{
|
|
||||||
s->base->apply(c, MyOperand::push);
|
|
||||||
|
|
||||||
s->base->logicalFlush(c, s);
|
|
||||||
|
|
||||||
s->base = memory
|
|
||||||
(c, register_(c, rbp), - (s->index + 1) * BytesPerWord, 0, 1);
|
|
||||||
s->flushed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RegisterOperand*
|
RegisterOperand*
|
||||||
temporary(Context* c, bool reserve)
|
temporary(Context* c)
|
||||||
{
|
{
|
||||||
RegisterOperand* r = 0;
|
|
||||||
// we don't yet support using r9-r15
|
// we don't yet support using r9-r15
|
||||||
for (unsigned i = 0; i < 8/*RegisterCount*/; ++i) {
|
for (unsigned i = 0; i < 8/*RegisterCount*/; ++i) {
|
||||||
if (not c->registers[i]->reserved) {
|
if (not c->registers[i]->reserved) {
|
||||||
if (c->registers[i]->stack == 0) {
|
c->registers[i]->reserved = true;
|
||||||
if (reserve) c->registers[i]->reserved = true;
|
return c->registers[i];
|
||||||
return c->registers[i];
|
|
||||||
} else if (r == 0 or r->stack->index > c->registers[i]->stack->index) {
|
|
||||||
r = c->registers[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r) {
|
abort(c);
|
||||||
flush(c, r->stack);
|
|
||||||
return r;
|
|
||||||
} else {
|
|
||||||
abort(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StackOperand*
|
StackOperand*
|
||||||
push(Context* c, MyOperand* base)
|
push(Context* c, MyOperand* v)
|
||||||
{
|
{
|
||||||
return base->logicalPush(c);
|
v->apply(c, MyOperand::push);
|
||||||
|
|
||||||
|
int index = (c->stack ?
|
||||||
|
c->stack->index + (c->stack->footprint() / BytesPerWord) :
|
||||||
|
0);
|
||||||
|
|
||||||
|
MyOperand* base = memory
|
||||||
|
(c, register_(c, rbp), - (c->reserved + index + 1) * BytesPerWord, 0, 1);
|
||||||
|
|
||||||
|
return c->stack = new (c->zone.allocate(sizeof(StackOperand)))
|
||||||
|
StackOperand(base, index, c->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pop(Context* c, MyOperand* dst)
|
pop(Context* c, MyOperand* dst)
|
||||||
{
|
{
|
||||||
if (c->stack->flushed) {
|
dst->apply(c, MyOperand::pop);
|
||||||
dst->apply(c, MyOperand::pop);
|
|
||||||
} else {
|
|
||||||
c->stack->base->apply(c, MyOperand::mov, dst);
|
|
||||||
c->stack->base->logicalFlush(c, c->stack);
|
|
||||||
}
|
|
||||||
c->stack = c->stack->next;
|
c->stack = c->stack->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
MyOperand*
|
MyOperand*
|
||||||
pop(Context* c)
|
pop(Context* c)
|
||||||
{
|
{
|
||||||
MyOperand* r;
|
RegisterOperand* tmp = temporary(c);
|
||||||
if (c->stack->flushed) {
|
tmp->apply(c, MyOperand::pop);
|
||||||
RegisterOperand* tmp = temporary(c, true);
|
MyOperand* r = tmp;
|
||||||
tmp->apply(c, MyOperand::pop);
|
|
||||||
r = tmp;
|
|
||||||
} else {
|
|
||||||
r = c->stack->base;
|
|
||||||
c->stack->base->logicalFlush(c, c->stack);
|
|
||||||
}
|
|
||||||
c->stack = c->stack->next;
|
c->stack = c->stack->next;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -548,22 +508,6 @@ selection(Context* c, SelectionOperand::SelectionType type, MyOperand* base)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
flushStack(Context* c)
|
|
||||||
{
|
|
||||||
if (c->stack) {
|
|
||||||
StackOperand* stack[c->stack->index + 1];
|
|
||||||
int index = c->stack->index + 1;
|
|
||||||
for (StackOperand* s = c->stack; s and not s->flushed; s = s->next) {
|
|
||||||
stack[-- index] = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; index < c->stack->index + 1; ++ index) {
|
|
||||||
flush(c, stack[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Register
|
Register
|
||||||
gpRegister(Context* c, unsigned index)
|
gpRegister(Context* c, unsigned index)
|
||||||
{
|
{
|
||||||
@ -588,8 +532,6 @@ gpRegister(Context* c, unsigned index)
|
|||||||
unsigned
|
unsigned
|
||||||
pushArguments(Context* c, unsigned count, va_list list)
|
pushArguments(Context* c, unsigned count, va_list list)
|
||||||
{
|
{
|
||||||
flushStack(c);
|
|
||||||
|
|
||||||
MyOperand* arguments[count];
|
MyOperand* arguments[count];
|
||||||
unsigned footprint = 0;
|
unsigned footprint = 0;
|
||||||
for (unsigned i = 0; i < count; ++i) {
|
for (unsigned i = 0; i < count; ++i) {
|
||||||
@ -662,24 +604,6 @@ encode(Context* c, uint8_t instruction, uint8_t zeroPrefix,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackOperand*
|
|
||||||
RegisterOperand::logicalPush(Context* c)
|
|
||||||
{
|
|
||||||
if (reserved or stack) {
|
|
||||||
RegisterOperand* tmp = temporary(c, false);
|
|
||||||
tmp->accept(c, mov, this);
|
|
||||||
c->stack = new (c->zone.allocate(sizeof(StackOperand)))
|
|
||||||
StackOperand(tmp, c->stack);
|
|
||||||
tmp->stack = c->stack;
|
|
||||||
} else {
|
|
||||||
c->stack = new (c->zone.allocate(sizeof(StackOperand)))
|
|
||||||
StackOperand(this, c->stack);
|
|
||||||
stack = c->stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c->stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RegisterOperand::apply(Context* c, Operation operation)
|
RegisterOperand::apply(Context* c, Operation operation)
|
||||||
{
|
{
|
||||||
@ -734,6 +658,17 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
ImmediateOperand* operand)
|
ImmediateOperand* operand)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
|
case add:
|
||||||
|
if (operand->value) {
|
||||||
|
assert(c, isInt8(operand->value)); // todo
|
||||||
|
|
||||||
|
rex(c);
|
||||||
|
c->code.append(0x83);
|
||||||
|
c->code.append(0xc0 | value);
|
||||||
|
c->code.append(operand->value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case and_:
|
case and_:
|
||||||
if (operand->value) {
|
if (operand->value) {
|
||||||
rex(c);
|
rex(c);
|
||||||
@ -805,15 +740,21 @@ class AbsoluteMovTask: public IpTask {
|
|||||||
MyPromise* promise;
|
MyPromise* promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
addAbsoluteMovTask(Context* c, MyPromise* p)
|
||||||
|
{
|
||||||
|
IpMapping* mapping = currentMapping(c);
|
||||||
|
mapping->task = new (c->zone.allocate(sizeof(AbsoluteMovTask)))
|
||||||
|
AbsoluteMovTask(c->code.length(), p, mapping->task);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RegisterOperand::accept(Context* c, Operation operation,
|
RegisterOperand::accept(Context* c, Operation operation,
|
||||||
AbsoluteOperand* operand)
|
AbsoluteOperand* operand)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case mov: {
|
case mov: {
|
||||||
IpMapping* mapping = currentMapping(c);
|
addAbsoluteMovTask(c, operand->value);
|
||||||
mapping->task = new (c->zone.allocate(sizeof(AbsoluteMovTask)))
|
|
||||||
AbsoluteMovTask(c->code.length(), operand->value, mapping->task);
|
|
||||||
|
|
||||||
accept(c, mov, immediate(c, 0));
|
accept(c, mov, immediate(c, 0));
|
||||||
accept(c, mov, memory(c, this, 0, 0, 1));
|
accept(c, mov, memory(c, this, 0, 0, 1));
|
||||||
@ -846,11 +787,13 @@ class DirectCallTask: public IpTask {
|
|||||||
uint8_t* address;
|
uint8_t* address;
|
||||||
};
|
};
|
||||||
|
|
||||||
StackOperand*
|
void
|
||||||
ImmediateOperand::logicalPush(Context* c)
|
addDirectCallTask(Context* c, intptr_t v)
|
||||||
{
|
{
|
||||||
return c->stack = new (c->zone.allocate(sizeof(StackOperand)))
|
IpMapping* mapping = currentMapping(c);
|
||||||
StackOperand(this, c->stack);
|
mapping->task = new (c->zone.allocate(sizeof(DirectCallTask)))
|
||||||
|
DirectCallTask
|
||||||
|
(c->code.length(), reinterpret_cast<uint8_t*>(v), mapping->task);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -865,43 +808,55 @@ ImmediateOperand::apply(Context* c, Operation operation)
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case call: {
|
case call: {
|
||||||
IpMapping* mapping = currentMapping(c);
|
addDirectCallTask(c, value);
|
||||||
mapping->task = new (c->zone.allocate(sizeof(DirectCallTask)))
|
|
||||||
DirectCallTask
|
|
||||||
(c->code.length(), reinterpret_cast<uint8_t*>(value), mapping->task);
|
|
||||||
|
|
||||||
c->code.append(0xE8);
|
c->code.append(0xE8);
|
||||||
c->code.append4(0);
|
c->code.append4(0);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case push:
|
||||||
|
if (isInt8(value)) {
|
||||||
|
c->code.append(0x6a);
|
||||||
|
c->code.append(value);
|
||||||
|
} else if (isInt32(value)) {
|
||||||
|
c->code.append(0x68);
|
||||||
|
c->code.append4(value);
|
||||||
|
} else {
|
||||||
|
RegisterOperand* tmp = temporary(c);
|
||||||
|
tmp->accept(c, mov, this);
|
||||||
|
tmp->apply(c, push);
|
||||||
|
tmp->release(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackOperand*
|
|
||||||
AbsoluteOperand::logicalPush(Context* c)
|
|
||||||
{
|
|
||||||
return c->stack = new (c->zone.allocate(sizeof(StackOperand)))
|
|
||||||
StackOperand(this, c->stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AbsoluteOperand::apply(Context* c, Operation operation)
|
AbsoluteOperand::apply(Context* c, Operation operation)
|
||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
|
case push: {
|
||||||
|
addAbsoluteMovTask(c, value);
|
||||||
|
|
||||||
|
RegisterOperand* tmp = temporary(c);
|
||||||
|
tmp->accept(c, mov, immediate(c, 0));
|
||||||
|
memory(c, tmp, 0, 0, 1)->apply(c, push);
|
||||||
|
tmp->release(c);
|
||||||
|
} break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackOperand*
|
Register
|
||||||
MemoryOperand::logicalPush(Context* c)
|
MemoryOperand::asRegister(Context* c)
|
||||||
{
|
{
|
||||||
RegisterOperand* tmp = temporary(c, false);
|
RegisterOperand* tmp = temporary(c);
|
||||||
tmp->accept(c, mov, this);
|
tmp->accept(c, mov, this);
|
||||||
c->stack = new (c->zone.allocate(sizeof(StackOperand)))
|
tmp->release(c);
|
||||||
StackOperand(tmp, c->stack);
|
return tmp->value;
|
||||||
tmp->stack = c->stack;
|
|
||||||
return c->stack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -916,6 +871,10 @@ MemoryOperand::apply(Context* c, Operation operation)
|
|||||||
encode(c, 0x8f, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
|
encode(c, 0x8f, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case push:
|
||||||
|
encode(c, 0xff, 0x30, 0x70, 0xb0, rax, base->asRegister(c), displacement);
|
||||||
|
break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -931,6 +890,12 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
displacement);
|
displacement);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case add:
|
||||||
|
rex(c);
|
||||||
|
encode(c, 0x01, 0, 0x40, 0x80, operand->value, base->asRegister(c),
|
||||||
|
displacement);
|
||||||
|
break;
|
||||||
|
|
||||||
default: abort(c);
|
default: abort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -958,7 +923,7 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
{
|
{
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case mov: {
|
case mov: {
|
||||||
RegisterOperand* tmp = temporary(c, true);
|
RegisterOperand* tmp = temporary(c);
|
||||||
|
|
||||||
tmp->accept(c, mov, operand);
|
tmp->accept(c, mov, operand);
|
||||||
accept(c, mov, tmp);
|
accept(c, mov, tmp);
|
||||||
@ -1108,7 +1073,6 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* stack() {
|
virtual Operand* stack() {
|
||||||
flushStack(&c);
|
|
||||||
return register_(&c, rsp);
|
return register_(&c, rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1125,7 +1089,7 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* temporary() {
|
virtual Operand* temporary() {
|
||||||
return ::temporary(&c, true);
|
return ::temporary(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void release(Operand* v) {
|
virtual void release(Operand* v) {
|
||||||
@ -1153,7 +1117,7 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
immediate(&c, c.indirectCaller)->apply(&c, MyOperand::call);
|
immediate(&c, c.indirectCaller)->apply(&c, MyOperand::call);
|
||||||
|
|
||||||
immediate(&c, footprint)->apply(&c, MyOperand::sub, register_(&c, rsp));
|
immediate(&c, footprint)->apply(&c, MyOperand::add, register_(&c, rsp));
|
||||||
|
|
||||||
return register_(&c, rax);
|
return register_(&c, rax);
|
||||||
}
|
}
|
||||||
@ -1180,24 +1144,23 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
static_cast<MyOperand*>(address)->apply(&c, MyOperand::call);
|
static_cast<MyOperand*>(address)->apply(&c, MyOperand::call);
|
||||||
|
|
||||||
immediate(&c, footprint)->apply(&c, MyOperand::sub, register_(&c, rsp));
|
immediate(&c, footprint)->apply(&c, MyOperand::add, register_(&c, rsp));
|
||||||
|
|
||||||
return register_(&c, rax);
|
return register_(&c, rax);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void return_(Operand* v) {
|
virtual void return_(Operand* v) {
|
||||||
static_cast<MyOperand*>(v)->apply(&c, MyOperand::mov, register_(&c, rax));
|
static_cast<MyOperand*>(v)->apply(&c, MyOperand::mov, register_(&c, rax));
|
||||||
|
epilogue();
|
||||||
ret();
|
ret();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* call(Operand* v) {
|
virtual Operand* call(Operand* v) {
|
||||||
flushStack(&c);
|
|
||||||
static_cast<MyOperand*>(v)->apply(&c, MyOperand::call);
|
static_cast<MyOperand*>(v)->apply(&c, MyOperand::call);
|
||||||
return register_(&c, rax);
|
return register_(&c, rax);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Operand* alignedCall(Operand* v) {
|
virtual Operand* alignedCall(Operand* v) {
|
||||||
flushStack(&c);
|
|
||||||
static_cast<MyOperand*>(v)->apply(&c, MyOperand::alignedCall);
|
static_cast<MyOperand*>(v)->apply(&c, MyOperand::alignedCall);
|
||||||
return register_(&c, rax);
|
return register_(&c, rax);
|
||||||
}
|
}
|
||||||
@ -1340,6 +1303,11 @@ class MyCompiler: public Compiler {
|
|||||||
register_(&c, rsp)->apply(&c, MyOperand::mov, register_(&c, rbp));
|
register_(&c, rsp)->apply(&c, MyOperand::mov, register_(&c, rbp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void reserve(unsigned size) {
|
||||||
|
sub(constant(size * BytesPerWord), stack());
|
||||||
|
c.reserved = size;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void epilogue() {
|
virtual void epilogue() {
|
||||||
register_(&c, rbp)->apply(&c, MyOperand::mov, register_(&c, rsp));
|
register_(&c, rbp)->apply(&c, MyOperand::mov, register_(&c, rsp));
|
||||||
register_(&c, rbp)->apply(&c, MyOperand::pop);
|
register_(&c, rbp)->apply(&c, MyOperand::pop);
|
||||||
|
@ -89,6 +89,7 @@ class Compiler {
|
|||||||
virtual Operand* select8(Operand*) = 0;
|
virtual Operand* select8(Operand*) = 0;
|
||||||
|
|
||||||
virtual void prologue() = 0;
|
virtual void prologue() = 0;
|
||||||
|
virtual void reserve(unsigned size) = 0;
|
||||||
virtual void epilogue() = 0;
|
virtual void epilogue() = 0;
|
||||||
|
|
||||||
virtual void startLogicalIp(unsigned) = 0;
|
virtual void startLogicalIp(unsigned) = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user