Deleting LIR and such, wiring up for HIR->x64.
This commit is contained in:
@@ -11,14 +11,13 @@
|
||||
|
||||
#include <alloy/backend/x64/x64_backend.h>
|
||||
#include <alloy/backend/x64/x64_code_cache.h>
|
||||
#include <alloy/backend/x64/lir/lir_builder.h>
|
||||
|
||||
#include <third_party/xbyak/xbyak/xbyak.h>
|
||||
#include <alloy/backend/x64/lowering/lowering_table.h>
|
||||
#include <alloy/hir/hir_builder.h>
|
||||
|
||||
using namespace alloy;
|
||||
using namespace alloy::backend;
|
||||
using namespace alloy::backend::x64;
|
||||
using namespace alloy::backend::x64::lir;
|
||||
using namespace alloy::hir;
|
||||
using namespace alloy::runtime;
|
||||
|
||||
using namespace Xbyak;
|
||||
@@ -28,35 +27,21 @@ namespace alloy {
|
||||
namespace backend {
|
||||
namespace x64 {
|
||||
|
||||
class XbyakAllocator : public Allocator {
|
||||
public:
|
||||
virtual bool useProtect() const { return false; }
|
||||
};
|
||||
|
||||
class XbyakGenerator : public CodeGenerator {
|
||||
public:
|
||||
XbyakGenerator(XbyakAllocator* allocator);
|
||||
virtual ~XbyakGenerator();
|
||||
void* Emplace(X64CodeCache* code_cache);
|
||||
int Emit(LIRBuilder* builder);
|
||||
private:
|
||||
int EmitInstruction(LIRInstr* instr);
|
||||
};
|
||||
static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024;
|
||||
|
||||
} // namespace x64
|
||||
} // namespace backend
|
||||
} // namespace alloy
|
||||
|
||||
|
||||
X64Emitter::X64Emitter(X64Backend* backend) :
|
||||
X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator) :
|
||||
backend_(backend),
|
||||
code_cache_(backend->code_cache()) {
|
||||
allocator_ = new XbyakAllocator();
|
||||
generator_ = new XbyakGenerator(allocator_);
|
||||
code_cache_(backend->code_cache()),
|
||||
allocator_(allocator),
|
||||
CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator) {
|
||||
}
|
||||
|
||||
X64Emitter::~X64Emitter() {
|
||||
delete generator_;
|
||||
delete allocator_;
|
||||
}
|
||||
|
||||
@@ -65,28 +50,21 @@ int X64Emitter::Initialize() {
|
||||
}
|
||||
|
||||
int X64Emitter::Emit(
|
||||
LIRBuilder* builder, void*& out_code_address, size_t& out_code_size) {
|
||||
HIRBuilder* builder, void*& out_code_address, size_t& out_code_size) {
|
||||
// Fill the generator with code.
|
||||
int result = generator_->Emit(builder);
|
||||
int result = Emit(builder);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Copy the final code to the cache and relocate it.
|
||||
out_code_size = generator_->getSize();
|
||||
out_code_address = generator_->Emplace(code_cache_);
|
||||
out_code_size = getSize();
|
||||
out_code_address = Emplace(code_cache_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
XbyakGenerator::XbyakGenerator(XbyakAllocator* allocator) :
|
||||
CodeGenerator(1 * 1024 * 1024, AutoGrow, allocator) {
|
||||
}
|
||||
|
||||
XbyakGenerator::~XbyakGenerator() {
|
||||
}
|
||||
|
||||
void* XbyakGenerator::Emplace(X64CodeCache* code_cache) {
|
||||
void* X64Emitter::Emplace(X64CodeCache* code_cache) {
|
||||
// To avoid changing xbyak, we do a switcharoo here.
|
||||
// top_ points to the Xbyak buffer, and since we are in AutoGrow mode
|
||||
// it has pending relocations. We copy the top_ to our buffer, swap the
|
||||
@@ -100,7 +78,7 @@ void* XbyakGenerator::Emplace(X64CodeCache* code_cache) {
|
||||
return new_address;
|
||||
}
|
||||
|
||||
int XbyakGenerator::Emit(LIRBuilder* builder) {
|
||||
int X64Emitter::Emit(HIRBuilder* builder) {
|
||||
// Function prolog.
|
||||
// Must be 16b aligned.
|
||||
// Windows is very strict about the form of this and the epilog:
|
||||
@@ -119,6 +97,8 @@ int XbyakGenerator::Emit(LIRBuilder* builder) {
|
||||
// TODO(benvanik): save registers.
|
||||
}
|
||||
|
||||
auto lowering_table = backend_->lowering_table();
|
||||
|
||||
// Body.
|
||||
auto block = builder->first_block();
|
||||
while (block) {
|
||||
@@ -130,18 +110,10 @@ int XbyakGenerator::Emit(LIRBuilder* builder) {
|
||||
}
|
||||
|
||||
// Add instructions.
|
||||
auto instr = block->instr_head;
|
||||
while (instr) {
|
||||
// Stash offset in debug info.
|
||||
// TODO(benvanik): stash size_ value.
|
||||
|
||||
// Emit.
|
||||
int result = EmitInstruction(instr);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
instr = instr->next;
|
||||
// The table will process sequences of instructions to (try to)
|
||||
// generate optimal code.
|
||||
if (lowering_table->ProcessBlock(*this, block)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
block = block->next;
|
||||
@@ -157,67 +129,3 @@ int XbyakGenerator::Emit(LIRBuilder* builder) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int XbyakGenerator::EmitInstruction(LIRInstr* instr) {
|
||||
switch (instr->opcode->num) {
|
||||
case LIR_OPCODE_NOP:
|
||||
nop();
|
||||
break;
|
||||
|
||||
case LIR_OPCODE_COMMENT:
|
||||
break;
|
||||
|
||||
case LIR_OPCODE_SOURCE_OFFSET:
|
||||
break;
|
||||
case LIR_OPCODE_DEBUG_BREAK:
|
||||
// TODO(benvanik): replace with debugging primitive.
|
||||
db(0xCC);
|
||||
break;
|
||||
case LIR_OPCODE_TRAP:
|
||||
// TODO(benvanik): replace with debugging primitive.
|
||||
db(0xCC);
|
||||
break;
|
||||
|
||||
case LIR_OPCODE_MOV:
|
||||
if (instr->arg1_type() == LIROperandType::OFFSET) {
|
||||
// mov [reg+offset], value
|
||||
mov(ptr[rax + *instr->arg1<intptr_t>()], rbx);
|
||||
} else if (instr->arg2_type() == LIROperandType::OFFSET) {
|
||||
// mov reg, [reg+offset]
|
||||
mov(rbx, ptr[rax + *instr->arg2<intptr_t>()]);
|
||||
} else {
|
||||
// mov reg, reg
|
||||
mov(rax, rbx);
|
||||
}
|
||||
break;
|
||||
case LIR_OPCODE_MOV_ZX:
|
||||
//mov
|
||||
break;
|
||||
case LIR_OPCODE_MOV_SX:
|
||||
//mov
|
||||
break;
|
||||
|
||||
case LIR_OPCODE_TEST:
|
||||
if (instr->arg0_type() == LIROperandType::REGISTER) {
|
||||
if (instr->arg1_type() == LIROperandType::REGISTER) {
|
||||
//test(instr->arg0<LIRRegister>())
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LIR_OPCODE_JUMP_EQ: {
|
||||
auto target = (*instr->arg0<LIRLabel*>());
|
||||
je(target->name, T_NEAR);
|
||||
break;
|
||||
}
|
||||
case LIR_OPCODE_JUMP_NE: {
|
||||
auto target = (*instr->arg0<LIRLabel*>());
|
||||
jne(target->name, T_NEAR);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Unhandled.
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user