more progress towards new JIT code - this compiles but won't run properly

This commit is contained in:
Joel Dice 2008-09-05 09:00:38 -06:00
parent 5f7d68b404
commit e13b755048
4 changed files with 240 additions and 78 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}