mirror of
https://github.com/corda/corda.git
synced 2025-02-12 05:35:50 +00:00
more progress towards new JIT code - this compiles but won't run properly
This commit is contained in:
parent
5f7d68b404
commit
e13b755048
@ -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;
|
||||
|
||||
|
154
src/compiler.cpp
154
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<Local**>
|
||||
(c.zone->allocate(sizeof(Local*) * localFootprint));
|
||||
memset(c.localTable, 0, sizeof(Local*) * localFootprint);
|
||||
c.state->locals = static_cast<Value**>
|
||||
(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<Value*>(label)->sites; s; s = s->next) {
|
||||
if (s->type(&c) == ConstantOperand) {
|
||||
static_cast<ConstantSite*>(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<Value*>(address), flags, traceHandler, result,
|
||||
resultSize, argumentStack, index, 0);
|
||||
@ -2860,20 +2869,20 @@ class MyCompiler: public Compiler {
|
||||
appendReturn(&c, size, static_cast<Value*>(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<Value*>(memory(base(), localOffset(&c, index)));
|
||||
store(size, src, v);
|
||||
// Value* v = static_cast<Value*>(memory(base(), localOffset(&c, index)));
|
||||
// store(size, src, v);
|
||||
|
||||
c.state->locals[index] = v;
|
||||
c.state->locals[index] = static_cast<Value*>(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<Value*>(src),
|
||||
static_cast<Value*>(dst));
|
||||
size, static_cast<Value*>(dst));
|
||||
}
|
||||
|
||||
virtual Operand* load(unsigned size, Operand* src) {
|
||||
Value* dst = value(&c);
|
||||
appendMove(&c, Move, size, static_cast<Value*>(src), dst);
|
||||
appendMove(&c, Move, size, static_cast<Value*>(src), size, dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
virtual Operand* loadz(unsigned size, Operand* src) {
|
||||
Value* dst = value(&c);
|
||||
appendMove(&c, MoveZ, size, static_cast<Value*>(src), dst);
|
||||
appendMove(&c, MoveZ, size, static_cast<Value*>(src), size, dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
virtual Operand* load4To8(Operand* src) {
|
||||
Value* dst = value(&c);
|
||||
appendMove(&c, Move4To8, 8, static_cast<Value*>(src), dst);
|
||||
appendMove(&c, Move, 4, static_cast<Value*>(src), 8, dst);
|
||||
return dst;
|
||||
}
|
||||
|
||||
virtual Operand* lcmp(Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, LongCompare, 8, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
8, static_cast<Value*>(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<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* sub(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, Subtract, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* mul(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, Multiply, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* div(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, Divide, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* rem(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, Remainder, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* shl(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, ShiftLeft, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
appendCombine(&c, ShiftLeft, BytesPerWord, static_cast<Value*>(a),
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* shr(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, ShiftRight, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
appendCombine(&c, ShiftRight, BytesPerWord, static_cast<Value*>(a),
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* ushr(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, UnsignedShiftRight, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
appendCombine(&c, UnsignedShiftRight, BytesPerWord, static_cast<Value*>(a),
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* and_(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, And, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* or_(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, Or, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* xor_(unsigned size, Operand* a, Operand* b) {
|
||||
Value* result = value(&c);
|
||||
appendCombine(&c, Xor, size, static_cast<Value*>(a),
|
||||
static_cast<Value*>(b), result);
|
||||
size, static_cast<Value*>(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) {
|
||||
|
@ -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;
|
||||
|
154
src/x86.cpp
154
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<OperandType>(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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user