diff --git a/src/alloy/backend/x64/lir/lir_block.h b/src/alloy/backend/x64/lir/lir_block.h deleted file mode 100644 index 727171411..000000000 --- a/src/alloy/backend/x64/lir/lir_block.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_LIR_LIR_BLOCK_H_ -#define ALLOY_BACKEND_X64_LIR_LIR_BLOCK_H_ - -#include - - -namespace alloy { -namespace backend { -namespace x64 { -namespace lir { - -class LIRBuilder; -class LIRInstr; -class LIRLabel; - - -class LIRBlock { -public: - Arena* arena; - - LIRBlock* next; - LIRBlock* prev; - - LIRLabel* label_head; - LIRLabel* label_tail; - - LIRInstr* instr_head; - LIRInstr* instr_tail; -}; - - -} // namespace lir -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_LIR_LIR_BLOCK_H_ diff --git a/src/alloy/backend/x64/lir/lir_builder.cc b/src/alloy/backend/x64/lir/lir_builder.cc deleted file mode 100644 index 52e888582..000000000 --- a/src/alloy/backend/x64/lir/lir_builder.cc +++ /dev/null @@ -1,378 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - -using namespace alloy; -using namespace alloy::backend::x64; -using namespace alloy::backend::x64::lir; - - -LIRBuilder::LIRBuilder(X64Backend* backend) : - backend_(backend) { - arena_ = new Arena(); - Reset(); -} - -LIRBuilder::~LIRBuilder() { - Reset(); - delete arena_; -} - -void LIRBuilder::Reset() { - next_label_id_ = 0; - block_head_ = block_tail_ = NULL; - current_block_ = NULL; - arena_->Reset(); -} - -int LIRBuilder::Finalize() { - return 0; -} - -void LIRBuilder::Dump(StringBuffer* str) { - uint32_t block_ordinal = 0; - auto block = block_head_; - while (block) { - if (block == block_head_) { - str->Append(":\n"); - } else if (!block->label_head) { - str->Append(":\n", block_ordinal); - } - block_ordinal++; - - auto label = block->label_head; - while (label) { - if (label->local) { - if (label->name) { - str->Append(".%s:\n", label->name); - } else { - str->Append(".label%d:\n", label->id); - } - } else { - if (label->name) { - str->Append("%s:\n", label->name); - } else { - str->Append("label%d:\n", label->id); - } - } - label = label->next; - } - - auto i = block->instr_head; - while (i) { - if (i->opcode->flags & LIR_OPCODE_FLAG_HIDE) { - i = i->next; - continue; - } - if (i->opcode == &LIR_OPCODE_COMMENT_info) { - str->Append(" ; %s\n", i->arg0()); - i = i->next; - continue; - } - - const LIROpcodeInfo* info = i->opcode; - str->Append(" "); - if (i->flags) { - str->Append("%s.%d", info->name, i->flags); - } else { - str->Append("%s", info->name); - } - if (i->arg0_type() != LIROperandType::NONE) { - str->Append(" "); - DumpArg(str, i->arg0_type(), (intptr_t)i + i->arg_offsets.arg0); - } - if (i->arg1_type() != LIROperandType::NONE) { - str->Append(", "); - DumpArg(str, i->arg1_type(), (intptr_t)i + i->arg_offsets.arg1); - } - if (i->arg2_type() != LIROperandType::NONE) { - str->Append(", "); - DumpArg(str, i->arg2_type(), (intptr_t)i + i->arg_offsets.arg2); - } - if (i->arg3_type() != LIROperandType::NONE) { - str->Append(", "); - DumpArg(str, i->arg3_type(), (intptr_t)i + i->arg_offsets.arg3); - } - str->Append("\n"); - i = i->next; - } - - block = block->next; - } -} - -void LIRBuilder::DumpArg(StringBuffer* str, LIROperandType type, - intptr_t ptr) { - switch (type) { - case LIROperandType::NONE: - break; - case LIROperandType::FUNCTION: - if (true) { - auto target = (*(runtime::FunctionInfo**)ptr); - str->Append(target->name() ? target->name() : ""); - } - break; - case LIROperandType::LABEL: - if (true) { - auto target = (*(LIRLabel**)ptr); - str->Append(target->name); - } - break; - case LIROperandType::OFFSET: - if (true) { - auto offset = (*(intptr_t*)ptr); - str->Append("+%lld", offset); - } - break; - case LIROperandType::STRING: - if (true) { - str->Append((*(char**)ptr)); - } - break; - case LIROperandType::REGISTER: - if (true) { - LIRRegister* reg = (LIRRegister*)ptr; - if (reg->is_virtual()) { - switch (reg->type) { - case LIRRegisterType::REG8: - str->Append("v%d.i8", reg->id & 0x00FFFFFF); - break; - case LIRRegisterType::REG16: - str->Append("v%d.i16", reg->id & 0x00FFFFFF); - break; - case LIRRegisterType::REG32: - str->Append("v%d.i32", reg->id & 0x00FFFFFF); - break; - case LIRRegisterType::REG64: - str->Append("v%d.i64", reg->id & 0x00FFFFFF); - break; - case LIRRegisterType::REGXMM: - str->Append("v%d.xmm", reg->id & 0x00FFFFFF); - break; - } - } else { - str->Append(lir::register_names[(int)reg->name]); - } - } - break; - case LIROperandType::INT8_CONSTANT: - str->Append("%X", *(int8_t*)ptr); - break; - case LIROperandType::INT16_CONSTANT: - str->Append("%X", *(int16_t*)ptr); - break; - case LIROperandType::INT32_CONSTANT: - str->Append("%X", *(int32_t*)ptr); - break; - case LIROperandType::INT64_CONSTANT: - str->Append("%X", *(int64_t*)ptr); - break; - case LIROperandType::FLOAT32_CONSTANT: - str->Append("%F", *(float*)ptr); - break; - case LIROperandType::FLOAT64_CONSTANT: - str->Append("%F", *(double*)ptr); - break; - case LIROperandType::VEC128_CONSTANT: - if (true) { - vec128_t* value = (vec128_t*)ptr; - str->Append("(%F,%F,%F,%F)", - value->x, value->y, value->z, value->w); - } - break; - default: XEASSERTALWAYS(); break; - } -} - -LIRBlock* LIRBuilder::current_block() const { - return current_block_; -} - -LIRInstr* LIRBuilder::last_instr() const { - if (current_block_ && current_block_->instr_tail) { - return current_block_->instr_tail; - } else if (block_tail_) { - return block_tail_->instr_tail; - } - return NULL; -} - -LIRLabel* LIRBuilder::NewLabel(const char* name, bool local) { - LIRLabel* label = arena_->Alloc(); - label->next = label->prev = NULL; - label->block = NULL; - label->id = next_label_id_++; - label->local = local; - label->tag = NULL; - if (!name) { - char label_name[32] = "l"; - _itoa(label->id, label_name + 1, 10); - name = label_name; - } - size_t label_length = xestrlena(name); - label->name = (char*)arena_->Alloc(label_length + 1); - xe_copy_struct(label->name, name, label_length + 1); - return label; -} - -void LIRBuilder::MarkLabel(LIRLabel* label, LIRBlock* block) { - if (!block) { - if (current_block_ && current_block_->instr_tail) { - EndBlock(); - } - if (!current_block_) { - AppendBlock(); - } - block = current_block_; - } - label->block = block; - label->prev = block->label_tail; - label->next = NULL; - if (label->prev) { - label->prev->next = label; - block->label_tail = label; - } else { - block->label_head = block->label_tail = label; - } -} - -LIRBlock* LIRBuilder::AppendBlock() { - LIRBlock* block = arena_->Alloc(); - block->arena = arena_; - block->next = NULL; - block->prev = block_tail_; - if (block_tail_) { - block_tail_->next = block; - } - block_tail_ = block; - if (!block_head_) { - block_head_ = block; - } - current_block_ = block; - block->label_head = block->label_tail = NULL; - block->instr_head = block->instr_tail = NULL; - return block; -} - -void LIRBuilder::EndBlock() { - if (current_block_ && !current_block_->instr_tail) { - // Block never had anything added to it. Since it likely has an - // incoming edge, just keep it around. - return; - } - current_block_ = NULL; -} - -LIRInstr* LIRBuilder::AppendInstr( - const LIROpcodeInfo& opcode_info, uint16_t flags) { - if (!current_block_) { - AppendBlock(); - } - LIRBlock* block = current_block_; - - LIRInstr* instr = arena_->Alloc(); - instr->next = NULL; - instr->prev = block->instr_tail; - if (block->instr_tail) { - block->instr_tail->next = instr; - } - block->instr_tail = instr; - if (!block->instr_head) { - block->instr_head = instr; - } - instr->block = block; - instr->opcode = &opcode_info; - instr->flags = flags; - instr->arg_types = { - LIROperandType::NONE, - LIROperandType::NONE, - LIROperandType::NONE, - LIROperandType::NONE - }; - return instr; -} - -uint8_t LIRBuilder::AppendOperand( - LIRInstr* instr, LIROperandType& type, const char* value) { - type = LIROperandType::STRING; - size_t length = xestrlena(value); - auto ptr = (char*)arena_->Alloc(length + 1); - xe_copy_struct(ptr, value, length + 1); - return (uint8_t)((intptr_t)ptr - (intptr_t)instr); -} - -uint8_t LIRBuilder::AppendOperand( - LIRInstr* instr, LIROperandType& type, hir::Value* value) { - if (value->IsConstant()) { - switch (value->type) { - case hir::INT8_TYPE: - return AppendOperand(instr, type, value->constant.i8); - case hir::INT16_TYPE: - return AppendOperand(instr, type, value->constant.i16); - case hir::INT32_TYPE: - return AppendOperand(instr, type, value->constant.i32); - case hir::INT64_TYPE: - return AppendOperand(instr, type, value->constant.i64); - case hir::FLOAT32_TYPE: - return AppendOperand(instr, type, value->constant.f32); - case hir::FLOAT64_TYPE: - return AppendOperand(instr, type, value->constant.f64); - case hir::VEC128_TYPE: - return AppendOperand(instr, type, value->constant.v128); - default: - XEASSERTALWAYS(); - return 0; - } - } else { - LIRRegisterType reg_type; - switch (value->type) { - case hir::INT8_TYPE: - reg_type = LIRRegisterType::REG8; - break; - case hir::INT16_TYPE: - reg_type = LIRRegisterType::REG16; - break; - case hir::INT32_TYPE: - reg_type = LIRRegisterType::REG32; - break; - case hir::INT64_TYPE: - reg_type = LIRRegisterType::REG64; - break; - case hir::FLOAT32_TYPE: - reg_type = LIRRegisterType::REGXMM; - break; - case hir::FLOAT64_TYPE: - reg_type = LIRRegisterType::REGXMM; - break; - case hir::VEC128_TYPE: - reg_type = LIRRegisterType::REGXMM; - break; - default: - XEASSERTALWAYS(); - return 0; - } - // Make it uniqueish by putting it +20000000 - uint32_t reg_id = 0x20000000 + value->ordinal; - return AppendOperand(instr, type, LIRRegister(reg_type, reg_id)); - } -} - -void LIRBuilder::Comment(const char* format, ...) { - char buffer[1024]; - va_list args; - va_start(args, format); - xevsnprintfa(buffer, 1024, format, args); - va_end(args); - auto instr = AppendInstr(LIR_OPCODE_COMMENT_info); - instr->arg_offsets.arg0 = - AppendOperand(instr, instr->arg_types.arg0, buffer); -} diff --git a/src/alloy/backend/x64/lir/lir_builder.h b/src/alloy/backend/x64/lir/lir_builder.h deleted file mode 100644 index d52a2a611..000000000 --- a/src/alloy/backend/x64/lir/lir_builder.h +++ /dev/null @@ -1,189 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_LIR_LIR_BUILDER_H_ -#define ALLOY_BACKEND_X64_LIR_LIR_BUILDER_H_ - -#include -#include -#include -#include -#include -#include - - -namespace alloy { -namespace backend { -namespace x64 { -class X64Backend; -namespace lir { - - -class LIRBuilder { -public: - LIRBuilder(X64Backend* backend); - ~LIRBuilder(); - - void Reset(); - int Finalize(); - - void Dump(StringBuffer* str); - - Arena* arena() const { return arena_; } - - LIRBlock* first_block() const { return block_head_; } - LIRBlock* current_block() const; - LIRInstr* last_instr() const; - - LIRLabel* NewLabel(const char* name = 0, bool local = false); - LIRLabel* NewLocalLabel() { return NewLabel(0, true); } - void MarkLabel(LIRLabel* label, LIRBlock* block = 0); - - // TODO(benvanik): allocations - - LIRBlock* AppendBlock(); - void EndBlock(); - - void Nop() { AppendInstr(LIR_OPCODE_NOP_info, 0); } - - void Comment(const char* format, ...); - void SourceOffset(uintptr_t offset) { AppendInstr(LIR_OPCODE_SOURCE_OFFSET_info, 0, offset); } - void DebugBreak() { AppendInstr(LIR_OPCODE_DEBUG_BREAK_info, 0); } - void Trap() { AppendInstr(LIR_OPCODE_TRAP_info, 0); } - - template - void Mov(A0& a, A1& b) { AppendInstr(LIR_OPCODE_MOV_info, 0, a, b); } - template - void Mov(A0& a, A1& b, A2& c) { AppendInstr(LIR_OPCODE_MOV_info, 0, a, b, c); } - template - void MovZX(A0& a, A1& b) { AppendInstr(LIR_OPCODE_MOV_ZX_info, 0, a, b); } - template - void MovSX(A0& a, A1& b) { AppendInstr(LIR_OPCODE_MOV_ZX_info, 0, a, b); } - - template - void Test(A0& a, A1& b) { AppendInstr(LIR_OPCODE_TEST_info, 0, a, b); } - - template - void Jump(A0& target) { AppendInstr(LIR_OPCODE_JUMP_info, 0, target); } - void JumpEQ(LIRLabel* target) { AppendInstr(LIR_OPCODE_JUMP_EQ_info, 0, target); } - void JumpNE(LIRLabel* target) { AppendInstr(LIR_OPCODE_JUMP_NE_info, 0, target); } - -private: - void DumpArg(StringBuffer* str, LIROperandType type, intptr_t ptr); - - LIRInstr* AppendInstr(const LIROpcodeInfo& opcode, uint16_t flags = 0); - - XEFORCEINLINE LIROperandType GetOperandType(runtime::FunctionInfo*) { return LIROperandType::FUNCTION; } - XEFORCEINLINE LIROperandType GetOperandType(LIRLabel*) { return LIROperandType::LABEL; } - XEFORCEINLINE LIROperandType GetOperandType(uintptr_t) { return LIROperandType::OFFSET; } - XEFORCEINLINE LIROperandType GetOperandType(const char*) { return LIROperandType::STRING; } - XEFORCEINLINE LIROperandType GetOperandType(LIRRegister&) { return LIROperandType::REGISTER; } - XEFORCEINLINE LIROperandType GetOperandType(int8_t) { return LIROperandType::INT8_CONSTANT; } - XEFORCEINLINE LIROperandType GetOperandType(int16_t) { return LIROperandType::INT16_CONSTANT; } - XEFORCEINLINE LIROperandType GetOperandType(int32_t) { return LIROperandType::INT32_CONSTANT; } - XEFORCEINLINE LIROperandType GetOperandType(int64_t) { return LIROperandType::INT64_CONSTANT; } - XEFORCEINLINE LIROperandType GetOperandType(float) { return LIROperandType::FLOAT32_CONSTANT; } - XEFORCEINLINE LIROperandType GetOperandType(double) { return LIROperandType::FLOAT64_CONSTANT; } - XEFORCEINLINE LIROperandType GetOperandType(vec128_t&) { return LIROperandType::VEC128_CONSTANT; } - LIROperandType GetOperandType(hir::Value* value) { - if (value->IsConstant()) { - switch (value->type) { - case hir::INT8_TYPE: - return LIROperandType::INT8_CONSTANT; - case hir::INT16_TYPE: - return LIROperandType::INT16_CONSTANT; - case hir::INT32_TYPE: - return LIROperandType::INT32_CONSTANT; - case hir::INT64_TYPE: - return LIROperandType::INT64_CONSTANT; - case hir::FLOAT32_TYPE: - return LIROperandType::FLOAT32_CONSTANT; - case hir::FLOAT64_TYPE: - return LIROperandType::FLOAT64_CONSTANT; - case hir::VEC128_TYPE: - return LIROperandType::VEC128_CONSTANT; - default: - XEASSERTALWAYS(); - return LIROperandType::INT8_CONSTANT; - } - } else { - return LIROperandType::REGISTER; - } - } - - template - uint8_t AppendOperand(LIRInstr* instr, LIROperandType& type, T& value) { - type = GetOperandType(value); - auto ptr = arena_->Alloc(); - *ptr = value; - return (uint8_t)((intptr_t)ptr - (intptr_t)instr); - } - uint8_t AppendOperand(LIRInstr* instr, LIROperandType& type, const char* value); - uint8_t AppendOperand(LIRInstr* instr, LIROperandType& type, hir::Value* value); - - template - LIRInstr* AppendInstr(const LIROpcodeInfo& opcode, uint16_t flags, A0& arg0) { - auto instr = AppendInstr(opcode, flags); - instr->arg_offsets.arg0 = - AppendOperand(instr, instr->arg_types.arg0, arg0); - return instr; - } - template - LIRInstr* AppendInstr(const LIROpcodeInfo& opcode, uint16_t flags, A0& arg0, A1& arg1) { - auto instr = AppendInstr(opcode, flags); - instr->arg_offsets.arg0 = - AppendOperand(instr, instr->arg_types.arg0, arg0); - instr->arg_offsets.arg1 = - AppendOperand(instr, instr->arg_types.arg1, arg1); - return instr; - } - template - LIRInstr* AppendInstr(const LIROpcodeInfo& opcode, uint16_t flags, A0& arg0, A1& arg1, A2& arg2) { - auto instr = AppendInstr(opcode, flags); - instr->arg_offsets.arg0 = - AppendOperand(instr, instr->arg_types.arg0, arg0); - instr->arg_offsets.arg1 = - AppendOperand(instr, instr->arg_types.arg1, arg1); - instr->arg_offsets.arg2 = - AppendOperand(instr, instr->arg_types.arg2, arg2); - return instr; - } - template - LIRInstr* AppendInstr(const LIROpcodeInfo& opcode, uint16_t flags, A0& arg0, A1& arg1, A2& arg2, A3& arg3) { - auto instr = AppendInstr(opcode, flags); - instr->arg_offsets.arg0 = - AppendOperand(instr, instr->arg_types.arg0, arg0); - instr->arg_offsets.arg1 = - AppendOperand(instr, instr->arg_types.arg1, arg1); - instr->arg_offsets.arg2 = - AppendOperand(instr, instr->arg_types.arg2, arg2); - instr->arg_offsets.arg3 = - AppendOperand(instr, instr->arg_types.arg3, arg3); - return instr; - } - -private: - X64Backend* backend_; - Arena* arena_; - - uint32_t next_label_id_; - - LIRBlock* block_head_; - LIRBlock* block_tail_; - LIRBlock* current_block_; -}; - - -} // namespace lir -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_LIR_LIR_BUILDER_H_ diff --git a/src/alloy/backend/x64/lir/lir_instr.cc b/src/alloy/backend/x64/lir/lir_instr.cc deleted file mode 100644 index ebed724f7..000000000 --- a/src/alloy/backend/x64/lir/lir_instr.cc +++ /dev/null @@ -1,76 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -using namespace alloy; -using namespace alloy::backend::x64::lir; - - -namespace alloy { -namespace backend { -namespace x64 { -namespace lir { -const char* register_names[] = { - "al", "ax", "eax", "rax", - "bl", "bx", "ebx", "rbx", - "cl", "cx", "ecx", "rcx", - "dl", "dx", "edx", "rdx", - "r8b", "r8w", "r8d", "r8", - "r9b", "r9w", "r9d", "r9", - "r10b", "r10w", "r10d", "r10", - "r11b", "r11w", "r11d", "r11", - "r12b", "r12w", "r12d", "r12", - "r13b", "r13w", "r13d", "r13", - "r14b", "r14w", "r14d", "r14", - "r15b", "r15w", "r15d", "r15", - - "sil", "si", "esi", "rsi", - "dil", "di", "edi", "rdi", - - "rbp", - "rsp", - - "xmm0", - "xmm1", - "xmm2", - "xmm3", - "xmm4", - "xmm5", - "xmm6", - "xmm7", - "xmm8", - "xmm9", - "xmm10", - "xmm11", - "xmm12", - "xmm13", - "xmm14", - "xmm15", -}; -} // namespace lir -} // namespace x64 -} // namespace backend -} // namespace alloy - - -void LIRInstr::Remove() { - if (next) { - next->prev = prev; - } - if (prev) { - prev->next = next; - } - if (block->instr_head == this) { - block->instr_head = next; - } - if (block->instr_tail == this) { - block->instr_tail = prev; - } -} diff --git a/src/alloy/backend/x64/lir/lir_instr.h b/src/alloy/backend/x64/lir/lir_instr.h deleted file mode 100644 index 720257457..000000000 --- a/src/alloy/backend/x64/lir/lir_instr.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_LIR_LIR_INSTR_H_ -#define ALLOY_BACKEND_X64_LIR_LIR_INSTR_H_ - -#include -#include -#include -#include - - -namespace alloy { namespace runtime { class FunctionInfo; } } - - -namespace alloy { -namespace backend { -namespace x64 { -namespace lir { - - -enum class LIRRegisterName : uint32_t { - AL, AX, EAX, RAX, - BL, BX, EBX, RBX, - CL, CX, ECX, RCX, - DL, DX, EDX, RDX, - R8B, R8W, R8D, R8, - R9B, R9W, R9D, R9, - R10B, R10W, R10D, R10, - R11B, R11W, R11D, R11, - R12B, R12W, R12D, R12, - R13B, R13W, R13D, R13, - R14B, R14W, R14D, R14, - R15B, R15W, R15D, R15, - - SIL, SI, ESI, RSI, - DIL, DI, EDI, RDI, - - RBP, - RSP, - - XMM0, - XMM1, - XMM2, - XMM3, - XMM4, - XMM5, - XMM6, - XMM7, - XMM8, - XMM9, - XMM10, - XMM11, - XMM12, - XMM13, - XMM14, - XMM15, - - VREG0 = 0x10000000, -}; -extern const char* register_names[74]; - -enum class LIRRegisterType : uint32_t { - REG8, - REG16, - REG32, - REG64, - REGXMM, -}; - -typedef struct LIRRegister_s { - LIRRegisterType type; - union { - uint32_t id; - LIRRegisterName name; - }; - struct LIRRegister_s(LIRRegisterType _type, uint32_t _id) : - type(_type), id((uint32_t)LIRRegisterName::VREG0 + _id) {} - struct LIRRegister_s(LIRRegisterType _type, LIRRegisterName _name) : - type(_type), name(_name) {} - bool is_virtual() const { return id > (uint32_t)LIRRegisterName::VREG0; } -} LIRRegister; - -enum class LIROperandType : uint8_t { - NONE = 0, - FUNCTION, - LABEL, - OFFSET, - STRING, - REGISTER, - INT8_CONSTANT, - INT16_CONSTANT, - INT32_CONSTANT, - INT64_CONSTANT, - FLOAT32_CONSTANT, - FLOAT64_CONSTANT, - VEC128_CONSTANT, -}; - -class LIRInstr { -public: - LIRBlock* block; - LIRInstr* next; - LIRInstr* prev; - - const LIROpcodeInfo* opcode; - uint16_t flags; - - struct { - LIROperandType arg0; - LIROperandType arg1; - LIROperandType arg2; - LIROperandType arg3; - } arg_types; - struct { - uint8_t arg0; - uint8_t arg1; - uint8_t arg2; - uint8_t arg3; - } arg_offsets; - LIROperandType arg0_type() const { return arg_types.arg0; } - LIROperandType arg1_type() const { return arg_types.arg1; } - LIROperandType arg2_type() const { return arg_types.arg2; } - LIROperandType arg3_type() const { return arg_types.arg3; } - template T* arg0() { return (T*)(((uint8_t*)this) + arg_offsets.arg0); } - template T* arg1() { return (T*)(((uint8_t*)this) + arg_offsets.arg1); } - template T* arg2() { return (T*)(((uint8_t*)this) + arg_offsets.arg2); } - template T* arg3() { return (T*)(((uint8_t*)this) + arg_offsets.arg3); } - - void Remove(); -}; - - -} // namespace lir -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_LIR_LIR_INSTR_H_ diff --git a/src/alloy/backend/x64/lir/lir_label.h b/src/alloy/backend/x64/lir/lir_label.h deleted file mode 100644 index 50a234972..000000000 --- a/src/alloy/backend/x64/lir/lir_label.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_LIR_LIR_LABEL_H_ -#define ALLOY_BACKEND_X64_LIR_LIR_LABEL_H_ - -#include - - -namespace alloy { -namespace backend { -namespace x64 { -namespace lir { - -class LIRBlock; - - -class LIRLabel { -public: - LIRBlock* block; - LIRLabel* next; - LIRLabel* prev; - - uint32_t id; - char* name; - bool local; - - void* tag; -}; - - -} // namespace lir -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_LIR_LIR_LABEL_H_ diff --git a/src/alloy/backend/x64/lir/lir_opcodes.cc b/src/alloy/backend/x64/lir/lir_opcodes.cc deleted file mode 100644 index 337bc0904..000000000 --- a/src/alloy/backend/x64/lir/lir_opcodes.cc +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -using namespace alloy; -using namespace alloy::backend::x64::lir; - - -namespace alloy { -namespace backend { -namespace x64 { -namespace lir { - -#define DEFINE_OPCODE(num, string_name, flags) \ - static const LIROpcodeInfo num##_info = { flags, string_name, num, }; -#include -#undef DEFINE_OPCODE - -const LIROpcodeInfo& GetOpcodeInfo(LIROpcode opcode) { - static const LIROpcodeInfo* lookup[__LIR_OPCODE_MAX_VALUE] = { -#define DEFINE_OPCODE(num, string_name, flags) \ - &num##_info, -#include -#undef DEFINE_OPCODE - }; - return *lookup[opcode]; -} - -} // namespace lir -} // namespace x64 -} // namespace backend -} // namespace alloy diff --git a/src/alloy/backend/x64/lir/lir_opcodes.h b/src/alloy/backend/x64/lir/lir_opcodes.h deleted file mode 100644 index 94d2291a2..000000000 --- a/src/alloy/backend/x64/lir/lir_opcodes.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_LIR_LIR_OPCODES_H_ -#define ALLOY_BACKEND_X64_LIR_LIR_OPCODES_H_ - -#include - - -namespace alloy { -namespace backend { -namespace x64 { -namespace lir { - - -enum LIROpcode { - LIR_OPCODE_NOP, - - LIR_OPCODE_COMMENT, - LIR_OPCODE_SOURCE_OFFSET, - LIR_OPCODE_DEBUG_BREAK, - LIR_OPCODE_TRAP, - - LIR_OPCODE_MOV, - LIR_OPCODE_MOV_ZX, - LIR_OPCODE_MOV_SX, - - LIR_OPCODE_TEST, - - LIR_OPCODE_JUMP, - LIR_OPCODE_JUMP_EQ, - LIR_OPCODE_JUMP_NE, - - __LIR_OPCODE_MAX_VALUE, // Keep at end. -}; - -enum LIROpcodeFlags { - LIR_OPCODE_FLAG_BRANCH = (1 << 1), - LIR_OPCODE_FLAG_MEMORY = (1 << 2), - LIR_OPCODE_FLAG_COMMUNATIVE = (1 << 3), - LIR_OPCODE_FLAG_VOLATILE = (1 << 4), - LIR_OPCODE_FLAG_IGNORE = (1 << 5), - LIR_OPCODE_FLAG_HIDE = (1 << 6), -}; - -typedef struct { - uint32_t flags; - const char* name; - LIROpcode num; -} LIROpcodeInfo; - - -#define DEFINE_OPCODE(num, string_name, flags) \ - extern const LIROpcodeInfo num##_info; -#include -#undef DEFINE_OPCODE - -extern const LIROpcodeInfo& GetOpcodeInfo(LIROpcode opcode); - - -} // namespace lir -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_LIR_LIR_OPCODES_H_ diff --git a/src/alloy/backend/x64/lir/lir_opcodes.inl b/src/alloy/backend/x64/lir/lir_opcodes.inl deleted file mode 100644 index 906bab43d..000000000 --- a/src/alloy/backend/x64/lir/lir_opcodes.inl +++ /dev/null @@ -1,61 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -DEFINE_OPCODE( - LIR_OPCODE_NOP, - "nop", - LIR_OPCODE_FLAG_IGNORE) - -DEFINE_OPCODE( - LIR_OPCODE_COMMENT, - "comment", - LIR_OPCODE_FLAG_IGNORE) -DEFINE_OPCODE( - LIR_OPCODE_SOURCE_OFFSET, - "source_offset", - LIR_OPCODE_FLAG_IGNORE | LIR_OPCODE_FLAG_HIDE) -DEFINE_OPCODE( - LIR_OPCODE_DEBUG_BREAK, - "debug_break", - 0) -DEFINE_OPCODE( - LIR_OPCODE_TRAP, - "trap", - 0) - -DEFINE_OPCODE( - LIR_OPCODE_MOV, - "mov", - 0) -DEFINE_OPCODE( - LIR_OPCODE_MOV_ZX, - "mov_zx", - 0) -DEFINE_OPCODE( - LIR_OPCODE_MOV_SX, - "mov_sx", - 0) - -DEFINE_OPCODE( - LIR_OPCODE_TEST, - "test", - 0) - -DEFINE_OPCODE( - LIR_OPCODE_JUMP, - "jump", - 0) -DEFINE_OPCODE( - LIR_OPCODE_JUMP_EQ, - "jump_eq", - 0) -DEFINE_OPCODE( - LIR_OPCODE_JUMP_NE, - "jump_ne", - 0) diff --git a/src/alloy/backend/x64/lir/sources.gypi b/src/alloy/backend/x64/lir/sources.gypi deleted file mode 100644 index df897c23b..000000000 --- a/src/alloy/backend/x64/lir/sources.gypi +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'lir_block.h', - 'lir_builder.cc', - 'lir_builder.h', - 'lir_instr.cc', - 'lir_instr.h', - 'lir_label.h', - 'lir_opcodes.cc', - 'lir_opcodes.h', - 'lir_opcodes.inl', - 'tracing.h', - ], -} diff --git a/src/alloy/backend/x64/lir/tracing.h b/src/alloy/backend/x64/lir/tracing.h deleted file mode 100644 index 0b6d7382a..000000000 --- a/src/alloy/backend/x64/lir/tracing.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_LIR_TRACING_H_ -#define ALLOY_BACKEND_X64_LIR_TRACING_H_ - -#include - - -namespace alloy { -namespace backend { -namespace x64 { -namespace lir { - -const uint32_t ALLOY_BACKEND_X64_LIR = - alloy::backend::x64::EventType::ALLOY_BACKEND_X64_LIR; - - -class EventType { -public: - enum { - ALLOY_BACKEND_X64_LIR_FOO = ALLOY_BACKEND_X64_LIR | (1), - }; -}; - - -} // namespace lir -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_LIR_TRACING_H_ diff --git a/src/alloy/backend/x64/lowering/lowering_sequences.cc b/src/alloy/backend/x64/lowering/lowering_sequences.cc index d76065b02..0cb940c8f 100644 --- a/src/alloy/backend/x64/lowering/lowering_sequences.cc +++ b/src/alloy/backend/x64/lowering/lowering_sequences.cc @@ -9,28 +9,42 @@ #include +#include #include using namespace alloy; using namespace alloy::backend::x64; -using namespace alloy::backend::x64::lir; using namespace alloy::backend::x64::lowering; using namespace alloy::hir; +using namespace Xbyak; + + +namespace { + +#define UNIMPLEMENTED_SEQ() + +// TODO(benvanik): emit traces/printfs/etc + +} // namespace + + void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // -------------------------------------------------------------------------- // General // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_COMMENT, [](LIRBuilder& lb, Instr*& instr) { - char* str = (char*)instr->src1.offset; - lb.Comment(str); + table->AddSequence(OPCODE_COMMENT, [](X64Emitter& e, Instr*& instr) { + //char* str = (char*)instr->src1.offset; + //lb.Comment(str); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_NOP, [](LIRBuilder& lb, Instr*& instr) { - lb.Nop(); + table->AddSequence(OPCODE_NOP, [](X64Emitter& e, Instr*& instr) { + // If we got this, chances are we want it. + e.nop(); instr = instr->next; return true; }); @@ -39,42 +53,53 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Debugging // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_SOURCE_OFFSET, [](LIRBuilder& lb, Instr*& instr) { + table->AddSequence(OPCODE_SOURCE_OFFSET, [](X64Emitter& e, Instr*& instr) { // TODO(benvanik): translate source offsets for mapping? We're just passing // down the original offset - it may be nice to have two. - lb.SourceOffset(instr->src1.offset); + //lb.SourceOffset(instr->src1.offset); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_DEBUG_BREAK, [](LIRBuilder& lb, Instr*& instr) { - lb.DebugBreak(); + table->AddSequence(OPCODE_DEBUG_BREAK, [](X64Emitter& e, Instr*& instr) { + // TODO(benvanik): insert a call to the debug break function to let the + // debugger know. + e.db(0xCC); instr = instr->next; return true; }); - table->AddSequence(OPCODE_DEBUG_BREAK_TRUE, [](LIRBuilder& lb, Instr*& instr) { - auto skip_label = lb.NewLocalLabel(); - lb.Test(instr->src1.value, instr->src1.value); - lb.JumpNE(skip_label); - lb.DebugBreak(); - lb.MarkLabel(skip_label); + table->AddSequence(OPCODE_DEBUG_BREAK_TRUE, [](X64Emitter& e, Instr*& instr) { + e.inLocalLabel(); + //e.test(e.rax, e.rax); + e.jne(".x"); + // TODO(benvanik): insert a call to the debug break function to let the + // debugger know. + e.db(0xCC); + e.L(".x"); + e.outLocalLabel(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_TRAP, [](LIRBuilder& lb, Instr*& instr) { - lb.Trap(); + table->AddSequence(OPCODE_TRAP, [](X64Emitter& e, Instr*& instr) { + // TODO(benvanik): insert a call to the trap function to let the + // debugger know. + e.db(0xCC); instr = instr->next; return true; }); - table->AddSequence(OPCODE_TRAP_TRUE, [](LIRBuilder& lb, Instr*& instr) { - auto skip_label = lb.NewLocalLabel(); - lb.Test(instr->src1.value, instr->src1.value); - lb.JumpNE(skip_label); - lb.Trap(); - lb.MarkLabel(skip_label); + table->AddSequence(OPCODE_TRAP_TRUE, [](X64Emitter& e, Instr*& instr) { + e.inLocalLabel(); + //e.test(rax, rax); + e.jne(".x"); + // TODO(benvanik): insert a call to the trap function to let the + // debugger know. + e.db(0xCC); + e.L(".x"); + e.outLocalLabel(); instr = instr->next; return true; }); @@ -83,46 +108,48 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Calls // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_CALL, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_CALL, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_CALL_TRUE, [](LIRBuilder& lb, Instr*& instr) { - auto skip_label = lb.NewLocalLabel(); - lb.Test(instr->src1.value, instr->src1.value); - lb.JumpNE(skip_label); - // TODO - lb.MarkLabel(skip_label); + table->AddSequence(OPCODE_CALL_TRUE, [](X64Emitter& e, Instr*& instr) { + //auto skip_label = lb.NewLocalLabel(); + //lb.Test(instr->src1.value, instr->src1.value); + //lb.JumpNE(skip_label); + //// TODO + //lb.MarkLabel(skip_label); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_CALL_INDIRECT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_CALL_INDIRECT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_CALL_INDIRECT_TRUE, [](LIRBuilder& lb, Instr*& instr) { - auto skip_label = lb.NewLocalLabel(); - lb.Test(instr->src1.value, instr->src1.value); - lb.JumpNE(skip_label); - // TODO - lb.MarkLabel(skip_label); + table->AddSequence(OPCODE_CALL_INDIRECT_TRUE, [](X64Emitter& e, Instr*& instr) { + //auto skip_label = lb.NewLocalLabel(); + //lb.Test(instr->src1.value, instr->src1.value); + //lb.JumpNE(skip_label); + //UNIMPLEMENTED_SEQ(); + //lb.MarkLabel(skip_label); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_RETURN, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_RETURN, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SET_RETURN_ADDRESS, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_SET_RETURN_ADDRESS, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); @@ -131,25 +158,28 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Branches // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_BRANCH, [](LIRBuilder& lb, Instr*& instr) { - auto target = (LIRLabel*)instr->src1.label->tag; - lb.Jump(target); + table->AddSequence(OPCODE_BRANCH, [](X64Emitter& e, Instr*& instr) { + /*auto target = (LIRLabel*)instr->src1.label->tag; + lb.Jump(target);*/ + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_BRANCH_TRUE, [](LIRBuilder& lb, Instr*& instr) { - lb.Test(instr->src1.value, instr->src1.value); + table->AddSequence(OPCODE_BRANCH_TRUE, [](X64Emitter& e, Instr*& instr) { + /*lb.Test(instr->src1.value, instr->src1.value); auto target = (LIRLabel*)instr->src2.label->tag; - lb.JumpEQ(target); + lb.JumpEQ(target);*/ + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_BRANCH_FALSE, [](LIRBuilder& lb, Instr*& instr) { - lb.Test(instr->src1.value, instr->src1.value); + table->AddSequence(OPCODE_BRANCH_FALSE, [](X64Emitter& e, Instr*& instr) { + /*lb.Test(instr->src1.value, instr->src1.value); auto target = (LIRLabel*)instr->src2.label->tag; - lb.JumpNE(target); + lb.JumpNE(target);*/ + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); @@ -158,56 +188,61 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Types // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_ASSIGN, [](LIRBuilder& lb, Instr*& instr) { - lb.Mov(instr->dest, instr->src1.value); + table->AddSequence(OPCODE_ASSIGN, [](X64Emitter& e, Instr*& instr) { + //lb.Mov(instr->dest, instr->src1.value); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_CAST, [](LIRBuilder& lb, Instr*& instr) { - lb.Mov(instr->dest, instr->src1.value); + table->AddSequence(OPCODE_CAST, [](X64Emitter& e, Instr*& instr) { + //lb.Mov(instr->dest, instr->src1.value); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_ZERO_EXTEND, [](LIRBuilder& lb, Instr*& instr) { - lb.MovZX(instr->dest, instr->src1.value); + table->AddSequence(OPCODE_ZERO_EXTEND, [](X64Emitter& e, Instr*& instr) { + //lb.MovZX(instr->dest, instr->src1.value); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SIGN_EXTEND, [](LIRBuilder& lb, Instr*& instr) { - lb.MovSX(instr->dest, instr->src1.value); + table->AddSequence(OPCODE_SIGN_EXTEND, [](X64Emitter& e, Instr*& instr) { + //lb.MovSX(instr->dest, instr->src1.value); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_TRUNCATE, [](LIRBuilder& lb, Instr*& instr) { - lb.Mov(instr->dest, instr->src1.value); + table->AddSequence(OPCODE_TRUNCATE, [](X64Emitter& e, Instr*& instr) { + //lb.Mov(instr->dest, instr->src1.value); + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_CONVERT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_CONVERT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_ROUND, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_ROUND, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_CONVERT_I2F, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_CONVERT_I2F, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_CONVERT_F2I, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_CONVERT_F2I, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); @@ -218,20 +253,20 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // specials for zeroing/etc (xor/etc) - table->AddSequence(OPCODE_LOAD_VECTOR_SHL, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_LOAD_VECTOR_SHL, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_LOAD_VECTOR_SHR, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_LOAD_VECTOR_SHR, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_LOAD_CLOCK, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_LOAD_CLOCK, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); @@ -240,20 +275,22 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Context // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_LOAD_CONTEXT, [](LIRBuilder& lb, Instr*& instr) { - lb.Mov( + table->AddSequence(OPCODE_LOAD_CONTEXT, [](X64Emitter& e, Instr*& instr) { + /*lb.Mov( instr->dest, LIRRegister(LIRRegisterType::REG64, LIRRegisterName::RCX), - instr->src1.offset); + instr->src1.offset);*/ + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_STORE_CONTEXT, [](LIRBuilder& lb, Instr*& instr) { - lb.Mov( + table->AddSequence(OPCODE_STORE_CONTEXT, [](X64Emitter& e, Instr*& instr) { + /*lb.Mov( LIRRegister(LIRRegisterType::REG64, LIRRegisterName::RCX), instr->src1.offset, - instr->src2.value); + instr->src2.value);*/ + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); @@ -262,24 +299,26 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Memory // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_LOAD, [](LIRBuilder& lb, Instr*& instr) { + table->AddSequence(OPCODE_LOAD, [](X64Emitter& e, Instr*& instr) { // TODO(benvanik): dynamic register access check // mov reg, [membase + address.32] // TODO(benvanik): special for f32/f64/v128 + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_STORE, [](LIRBuilder& lb, Instr*& instr) { + table->AddSequence(OPCODE_STORE, [](X64Emitter& e, Instr*& instr) { // TODO(benvanik): dynamic register access check // mov [membase + address.32], reg // TODO(benvanik): special for f32/f64/v128 + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_PREFETCH, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_PREFETCH, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); @@ -288,134 +327,140 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Comparisons // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_MAX, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_MAX, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_MIN, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_MIN, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SELECT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_SELECT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_IS_TRUE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_IS_TRUE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_IS_FALSE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_IS_FALSE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_EQ, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_EQ, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_NE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_NE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_SLT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_SLT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_SLE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_SLE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_SGT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_SGT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_SGE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_SGE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_ULT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_ULT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_ULE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_ULE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_UGT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_UGT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_COMPARE_UGE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_UGE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_DID_CARRY, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_DID_CARRY, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_DID_OVERFLOW, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_DID_OVERFLOW, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_COMPARE_EQ, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_DID_SATURATE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_COMPARE_SGT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_COMPARE_EQ, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_COMPARE_SGE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_COMPARE_SGT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_COMPARE_UGT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_COMPARE_SGE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_COMPARE_UGE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_COMPARE_UGT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_COMPARE_UGE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); @@ -424,200 +469,218 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Math // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_ADD, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_ADD, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_ADD_CARRY, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_ADD_CARRY, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SUB, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_SUB, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_MUL, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_MUL, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_DIV, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_MUL_HI, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_MUL_ADD, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_DIV, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_MUL_SUB, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_MUL_ADD, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_NEG, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_MUL_SUB, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_ABS, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_NEG, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SQRT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_ABS, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_RSQRT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_SQRT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_POW2, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_RSQRT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_LOG2, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_POW2, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_DOT_PRODUCT_3, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_LOG2, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_DOT_PRODUCT_4, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_DOT_PRODUCT_3, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_AND, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_DOT_PRODUCT_4, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_OR, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_AND, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_XOR, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_OR, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_NOT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_XOR, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SHL, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_NOT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_SHL, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_SHL, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SHR, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_SHL, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_SHR, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_SHR, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SHA, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_SHR, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_VECTOR_SHA, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_SHA, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_ROTATE_LEFT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_VECTOR_SHA, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_BYTE_SWAP, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_ROTATE_LEFT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_CNTLZ, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_BYTE_SWAP, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_INSERT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_CNTLZ, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_EXTRACT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_INSERT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SPLAT, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_EXTRACT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_PERMUTE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_SPLAT, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_SWIZZLE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_PERMUTE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SWIZZLE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_PACK, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_UNPACK, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); @@ -626,26 +689,26 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { // Atomic // -------------------------------------------------------------------------- - table->AddSequence(OPCODE_COMPARE_EXCHANGE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_COMPARE_EXCHANGE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_ATOMIC_EXCHANGE, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_ATOMIC_EXCHANGE, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_ATOMIC_ADD, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_ATOMIC_ADD, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); - table->AddSequence(OPCODE_ATOMIC_SUB, [](LIRBuilder& lb, Instr*& instr) { - // TODO + table->AddSequence(OPCODE_ATOMIC_SUB, [](X64Emitter& e, Instr*& instr) { + UNIMPLEMENTED_SEQ(); instr = instr->next; return true; }); diff --git a/src/alloy/backend/x64/lowering/lowering_table.cc b/src/alloy/backend/x64/lowering/lowering_table.cc index 412f5b51f..a8df8b7bc 100644 --- a/src/alloy/backend/x64/lowering/lowering_table.cc +++ b/src/alloy/backend/x64/lowering/lowering_table.cc @@ -45,59 +45,25 @@ void LoweringTable::AddSequence(hir::Opcode starting_opcode, sequence_fn_t fn) { lookup_[starting_opcode] = new_entry; } -int LoweringTable::Process( - hir::HIRBuilder* hir_builder, lir::LIRBuilder* lir_builder) { - lir_builder->EndBlock(); - - // Translate all labels ahead of time. - // We stash them on tags to make things easier later on. - auto hir_block = hir_builder->first_block(); - while (hir_block) { - auto hir_label = hir_block->label_head; - while (hir_label) { - auto lir_label = lir_builder->NewLabel(hir_label->name); - hir_label->tag = lir_label; - hir_label = hir_label->next; - } - hir_block = hir_block->next; - } - - // Process each block. - hir_block = hir_builder->first_block(); - while (hir_block) { - // Force a new block. - lir_builder->AppendBlock(); - - // Mark labels. - auto hir_label = hir_block->label_head; - while (hir_label) { - auto lir_label = (lir::LIRLabel*)hir_label->tag; - lir_builder->MarkLabel(lir_label); - hir_label = hir_label->next; - } - - // Process instructions. - auto hir_instr = hir_block->instr_head; - while (hir_instr) { - bool processed = false; - auto entry = lookup_[hir_instr->opcode->num]; - while (entry) { - if ((*entry->fn)(*lir_builder, hir_instr)) { - processed = true; - break; - } - entry = entry->next; - } - if (!processed) { - // No sequence found! - XELOGE("Unable to process HIR opcode %s", hir_instr->opcode->name); - return 1; - hir_instr = hir_instr->next; +int LoweringTable::ProcessBlock(X64Emitter& e, hir::Block* block) { + // Process instructions. + auto instr = block->instr_head; + while (instr) { + bool processed = false; + auto entry = lookup_[instr->opcode->num]; + while (entry) { + if ((*entry->fn)(e, instr)) { + processed = true; + break; } + entry = entry->next; + } + if (!processed) { + // No sequence found! + XELOGE("Unable to process HIR opcode %s", instr->opcode->name); + return 1; + instr = instr->next; } - - lir_builder->EndBlock(); - hir_block = hir_block->next; } return 0; diff --git a/src/alloy/backend/x64/lowering/lowering_table.h b/src/alloy/backend/x64/lowering/lowering_table.h index 33c2ca90e..f62bfd777 100644 --- a/src/alloy/backend/x64/lowering/lowering_table.h +++ b/src/alloy/backend/x64/lowering/lowering_table.h @@ -11,8 +11,6 @@ #define ALLOY_BACKEND_X64_X64_LOWERING_LOWERING_TABLE_H_ #include -#include -#include #include @@ -20,6 +18,7 @@ namespace alloy { namespace backend { namespace x64 { class X64Backend; +class X64Emitter; namespace lowering { @@ -30,10 +29,10 @@ public: int Initialize(); - int Process(hir::HIRBuilder* hir_builder, lir::LIRBuilder* lir_builder); + int ProcessBlock(X64Emitter& e, hir::Block* block); public: - typedef bool(*sequence_fn_t)(lir::LIRBuilder& lb, hir::Instr*& instr); + typedef bool(*sequence_fn_t)(X64Emitter& e, hir::Instr*& instr); void AddSequence(hir::Opcode starting_opcode, sequence_fn_t fn); private: @@ -43,6 +42,8 @@ private: sequence_fn_entry_t* next; }; + // NOTE: this class is shared by multiple threads and is not thread safe. + // Do not modify anything after init. X64Backend* backend_; sequence_fn_entry_t* lookup_[hir::__OPCODE_MAX_VALUE]; }; diff --git a/src/alloy/backend/x64/optimizer/optimizer.cc b/src/alloy/backend/x64/optimizer/optimizer.cc deleted file mode 100644 index 6aa25b00a..000000000 --- a/src/alloy/backend/x64/optimizer/optimizer.cc +++ /dev/null @@ -1,58 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include -#include - -using namespace alloy; -using namespace alloy::backend::x64::lir; -using namespace alloy::backend::x64::optimizer; -using namespace alloy::runtime; - - -Optimizer::Optimizer(Runtime* runtime) : - runtime_(runtime) { - alloy::tracing::WriteEvent(EventType::Init({ - })); -} - -Optimizer::~Optimizer() { - Reset(); - - for (auto it = passes_.begin(); it != passes_.end(); ++it) { - OptimizerPass* pass = *it; - delete pass; - } - - alloy::tracing::WriteEvent(EventType::Deinit({ - })); -} - -void Optimizer::AddPass(OptimizerPass* pass) { - pass->Initialize(this); - passes_.push_back(pass); -} - -void Optimizer::Reset() { -} - -int Optimizer::Optimize(LIRBuilder* builder) { - // TODO(benvanik): sophisticated stuff. Run passes in parallel, run until they - // stop changing things, etc. - for (auto it = passes_.begin(); it != passes_.end(); ++it) { - OptimizerPass* pass = *it; - if (pass->Run(builder)) { - return 1; - } - } - - return 0; -} diff --git a/src/alloy/backend/x64/optimizer/optimizer.h b/src/alloy/backend/x64/optimizer/optimizer.h deleted file mode 100644 index a991fb2a2..000000000 --- a/src/alloy/backend/x64/optimizer/optimizer.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_OPTIMIZER_OPTIMIZER_H_ -#define ALLOY_BACKEND_X64_OPTIMIZER_OPTIMIZER_H_ - -#include -#include - -namespace alloy { namespace runtime { class Runtime; } } - - -namespace alloy { -namespace backend { -namespace x64 { -namespace optimizer { - -class OptimizerPass; - - -class Optimizer { -public: - Optimizer(runtime::Runtime* runtime); - ~Optimizer(); - - runtime::Runtime* runtime() const { return runtime_; } - - void AddPass(OptimizerPass* pass); - - void Reset(); - - int Optimize(lir::LIRBuilder* builder); - -private: - runtime::Runtime* runtime_; - - typedef std::vector PassList; - PassList passes_; -}; - - -} // namespace optimizer -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_OPTIMIZER_OPTIMIZER_H_ diff --git a/src/alloy/backend/x64/optimizer/optimizer_pass.cc b/src/alloy/backend/x64/optimizer/optimizer_pass.cc deleted file mode 100644 index bc00b2705..000000000 --- a/src/alloy/backend/x64/optimizer/optimizer_pass.cc +++ /dev/null @@ -1,29 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -#include - -using namespace alloy; -using namespace alloy::backend::x64::optimizer; - - -OptimizerPass::OptimizerPass() : - runtime_(0), optimizer_(0) { -} - -OptimizerPass::~OptimizerPass() { -} - -int OptimizerPass::Initialize(Optimizer* optimizer) { - runtime_ = optimizer->runtime(); - optimizer_ = optimizer; - return 0; -} diff --git a/src/alloy/backend/x64/optimizer/optimizer_pass.h b/src/alloy/backend/x64/optimizer/optimizer_pass.h deleted file mode 100644 index c5ad80616..000000000 --- a/src/alloy/backend/x64/optimizer/optimizer_pass.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_OPTIMIZER_OPTIMIZER_PASS_H_ -#define ALLOY_BACKEND_X64_OPTIMIZER_OPTIMIZER_PASS_H_ - -#include - -#include - -namespace alloy { namespace runtime { class Runtime; } } - - -namespace alloy { -namespace backend { -namespace x64 { -namespace optimizer { - -class Optimizer; - - -class OptimizerPass { -public: - OptimizerPass(); - virtual ~OptimizerPass(); - - virtual int Initialize(Optimizer* optimizer); - - virtual int Run(lir::LIRBuilder* builder) = 0; - -protected: - runtime::Runtime* runtime_; - Optimizer* optimizer_; -}; - - -} // namespace optimizer -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_OPTIMIZER_OPTIMIZER_PASS_H_ diff --git a/src/alloy/backend/x64/optimizer/optimizer_passes.h b/src/alloy/backend/x64/optimizer/optimizer_passes.h deleted file mode 100644 index 88ad1042a..000000000 --- a/src/alloy/backend/x64/optimizer/optimizer_passes.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_OPTIMIZER_PASSES_H_ -#define ALLOY_BACKEND_X64_OPTIMIZER_PASSES_H_ - -#include -#include -#include - -#endif // ALLOY_BACKEND_X64_OPTIMIZER_PASSES_H_ diff --git a/src/alloy/backend/x64/optimizer/passes/reachability_pass.cc b/src/alloy/backend/x64/optimizer/passes/reachability_pass.cc deleted file mode 100644 index 633600c27..000000000 --- a/src/alloy/backend/x64/optimizer/passes/reachability_pass.cc +++ /dev/null @@ -1,49 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -using namespace alloy; -using namespace alloy::backend::x64::lir; -using namespace alloy::backend::x64::optimizer; -using namespace alloy::backend::x64::optimizer::passes; - - -ReachabilityPass::ReachabilityPass() : - OptimizerPass() { -} - -ReachabilityPass::~ReachabilityPass() { -} - -int ReachabilityPass::Run(LIRBuilder* builder) { - // Run through blocks. If blocks have no incoming edges remove them. - // Afterwards, remove any unneeded jumps (jumping to the next block). - - // TODO(benvanik): dead block removal. - - // Remove unneeded jumps. - auto block = builder->first_block(); - while (block) { - auto tail = block->instr_tail; - if (tail && tail->opcode == &LIR_OPCODE_JUMP_info) { - // Jump. Check target. - if (tail->arg0_type() == LIROperandType::LABEL) { - auto target = *tail->arg0(); - if (target->block == block->next) { - // Jumping to subsequent block. Remove. - tail->Remove(); - } - } - } - block = block->next; - } - - return 0; -} diff --git a/src/alloy/backend/x64/optimizer/passes/reachability_pass.h b/src/alloy/backend/x64/optimizer/passes/reachability_pass.h deleted file mode 100644 index 20f430d3c..000000000 --- a/src/alloy/backend/x64/optimizer/passes/reachability_pass.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REACHABILITY_PASS_H_ -#define ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REACHABILITY_PASS_H_ - -#include - - -namespace alloy { -namespace backend { -namespace x64 { -namespace optimizer { -namespace passes { - - -class ReachabilityPass : public OptimizerPass { -public: - ReachabilityPass(); - virtual ~ReachabilityPass(); - - virtual int Run(lir::LIRBuilder* builder); -}; - - -} // namespace passes -} // namespace optimizer -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REACHABILITY_PASS_H_ diff --git a/src/alloy/backend/x64/optimizer/passes/redundant_mov_pass.cc b/src/alloy/backend/x64/optimizer/passes/redundant_mov_pass.cc deleted file mode 100644 index acbec6089..000000000 --- a/src/alloy/backend/x64/optimizer/passes/redundant_mov_pass.cc +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -using namespace alloy; -using namespace alloy::backend::x64::lir; -using namespace alloy::backend::x64::optimizer; -using namespace alloy::backend::x64::optimizer::passes; - - -RedundantMovPass::RedundantMovPass() : - OptimizerPass() { -} - -RedundantMovPass::~RedundantMovPass() { -} - -int RedundantMovPass::Run(LIRBuilder* builder) { - return 0; -} diff --git a/src/alloy/backend/x64/optimizer/passes/redundant_mov_pass.h b/src/alloy/backend/x64/optimizer/passes/redundant_mov_pass.h deleted file mode 100644 index 7cac00fe4..000000000 --- a/src/alloy/backend/x64/optimizer/passes/redundant_mov_pass.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REDUNDANT_MOV_PASS_H_ -#define ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REDUNDANT_MOV_PASS_H_ - -#include - - -namespace alloy { -namespace backend { -namespace x64 { -namespace optimizer { -namespace passes { - - -class RedundantMovPass : public OptimizerPass { -public: - RedundantMovPass(); - virtual ~RedundantMovPass(); - - virtual int Run(lir::LIRBuilder* builder); -}; - - -} // namespace passes -} // namespace optimizer -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REDUNDANT_MOV_PASS_H_ diff --git a/src/alloy/backend/x64/optimizer/passes/register_allocation_pass.cc b/src/alloy/backend/x64/optimizer/passes/register_allocation_pass.cc deleted file mode 100644 index 298dca4b9..000000000 --- a/src/alloy/backend/x64/optimizer/passes/register_allocation_pass.cc +++ /dev/null @@ -1,27 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#include - -using namespace alloy; -using namespace alloy::backend::x64::lir; -using namespace alloy::backend::x64::optimizer; -using namespace alloy::backend::x64::optimizer::passes; - - -RegisterAllocationPass::RegisterAllocationPass() : - OptimizerPass() { -} - -RegisterAllocationPass::~RegisterAllocationPass() { -} - -int RegisterAllocationPass::Run(LIRBuilder* builder) { - return 0; -} diff --git a/src/alloy/backend/x64/optimizer/passes/register_allocation_pass.h b/src/alloy/backend/x64/optimizer/passes/register_allocation_pass.h deleted file mode 100644 index eb88a6535..000000000 --- a/src/alloy/backend/x64/optimizer/passes/register_allocation_pass.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REGISTER_ALLOCATION_PASS_H_ -#define ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REGISTER_ALLOCATION_PASS_H_ - -#include - - -namespace alloy { -namespace backend { -namespace x64 { -namespace optimizer { -namespace passes { - - -class RegisterAllocationPass : public OptimizerPass { -public: - RegisterAllocationPass(); - virtual ~RegisterAllocationPass(); - - virtual int Run(lir::LIRBuilder* builder); -}; - - -} // namespace passes -} // namespace optimizer -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_OPTIMIZER_PASSES_REGISTER_ALLOCATION_PASS_H_ diff --git a/src/alloy/backend/x64/optimizer/passes/sources.gypi b/src/alloy/backend/x64/optimizer/passes/sources.gypi deleted file mode 100644 index 6d80257ca..000000000 --- a/src/alloy/backend/x64/optimizer/passes/sources.gypi +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'reachability_pass.cc', - 'reachability_pass.h', - 'redundant_mov_pass.cc', - 'redundant_mov_pass.h', - 'register_allocation_pass.cc', - 'register_allocation_pass.h', - ], -} diff --git a/src/alloy/backend/x64/optimizer/sources.gypi b/src/alloy/backend/x64/optimizer/sources.gypi deleted file mode 100644 index 33aae7f33..000000000 --- a/src/alloy/backend/x64/optimizer/sources.gypi +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'optimizer.cc', - 'optimizer.h', - 'optimizer_pass.cc', - 'optimizer_pass.h', - 'optimizer_passes.h', - 'tracing.h', - ], - - 'includes': [ - 'passes/sources.gypi', - ], -} diff --git a/src/alloy/backend/x64/optimizer/tracing.h b/src/alloy/backend/x64/optimizer/tracing.h deleted file mode 100644 index d2a8bad04..000000000 --- a/src/alloy/backend/x64/optimizer/tracing.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - ****************************************************************************** - * Xenia : Xbox 360 Emulator Research Project * - ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * - * Released under the BSD license - see LICENSE in the root for more details. * - ****************************************************************************** - */ - -#ifndef ALLOY_BACKEND_X64_OPTIMIZER_TRACING_H_ -#define ALLOY_BACKEND_X64_OPTIMIZER_TRACING_H_ - -#include - - -namespace alloy { -namespace backend { -namespace x64 { -namespace optimizer { - -const uint32_t ALLOY_BACKEND_X64_OPTIMIZER = - alloy::backend::x64::EventType::ALLOY_BACKEND_X64_OPTIMIZER; - - -class EventType { -public: - enum { - ALLOY_BACKEND_X64_OPTIMIZER_INIT = ALLOY_BACKEND_X64_OPTIMIZER | (1), - ALLOY_BACKEND_X64_OPTIMIZER_DEINIT = ALLOY_BACKEND_X64_OPTIMIZER | (2), - }; - - typedef struct { - static const uint32_t event_type = ALLOY_BACKEND_X64_OPTIMIZER_INIT; - } Init; - typedef struct { - static const uint32_t event_type = ALLOY_BACKEND_X64_OPTIMIZER_DEINIT; - } Deinit; -}; - - -} // namespace optimizer -} // namespace x64 -} // namespace backend -} // namespace alloy - - -#endif // ALLOY_BACKEND_X64_OPTIMIZER_TRACING_H_ diff --git a/src/alloy/backend/x64/sources.gypi b/src/alloy/backend/x64/sources.gypi index 22c367a09..0a3ead5a9 100644 --- a/src/alloy/backend/x64/sources.gypi +++ b/src/alloy/backend/x64/sources.gypi @@ -15,8 +15,6 @@ ], 'includes': [ - 'lir/sources.gypi', 'lowering/sources.gypi', - 'optimizer/sources.gypi', ], } diff --git a/src/alloy/backend/x64/tracing.h b/src/alloy/backend/x64/tracing.h index e24a15f4a..36d814d67 100644 --- a/src/alloy/backend/x64/tracing.h +++ b/src/alloy/backend/x64/tracing.h @@ -30,9 +30,6 @@ public: ALLOY_BACKEND_X64_ASSEMBLER = ALLOY_BACKEND_X64 | (1 << 20), ALLOY_BACKEND_X64_ASSEMBLER_INIT = ALLOY_BACKEND_X64_ASSEMBLER | (1), ALLOY_BACKEND_X64_ASSEMBLER_DEINIT = ALLOY_BACKEND_X64_ASSEMBLER | (2), - - ALLOY_BACKEND_X64_LIR = ALLOY_BACKEND_X64 | (2 << 20), - ALLOY_BACKEND_X64_OPTIMIZER = ALLOY_BACKEND_X64 | (3 << 20), }; typedef struct { diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index 414b1f9d6..9176a60f2 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -13,10 +13,6 @@ #include #include #include -#include -#include -#include -#include #include #include #include @@ -28,16 +24,12 @@ namespace BE { using namespace alloy; using namespace alloy::backend; using namespace alloy::backend::x64; -using namespace alloy::backend::x64::lir; -using namespace alloy::backend::x64::optimizer; using namespace alloy::hir; using namespace alloy::runtime; X64Assembler::X64Assembler(X64Backend* backend) : x64_backend_(backend), - builder_(0), - optimizer_(0), emitter_(0), Assembler(backend) { } @@ -47,8 +39,6 @@ X64Assembler::~X64Assembler() { })); delete emitter_; - delete optimizer_; - delete builder_; } int X64Assembler::Initialize() { @@ -57,14 +47,8 @@ int X64Assembler::Initialize() { return result; } - builder_ = new LIRBuilder(x64_backend_); - - optimizer_ = new Optimizer(backend_->runtime()); - optimizer_->AddPass(new passes::RegisterAllocationPass()); - optimizer_->AddPass(new passes::RedundantMovPass()); - optimizer_->AddPass(new passes::ReachabilityPass()); - - emitter_ = new X64Emitter(x64_backend_); + emitter_ = new X64Emitter(x64_backend_, + new XbyakAllocator()); alloy::tracing::WriteEvent(EventType::AssemblerInit({ })); @@ -73,45 +57,20 @@ int X64Assembler::Initialize() { } void X64Assembler::Reset() { - builder_->Reset(); - optimizer_->Reset(); string_buffer_.Reset(); Assembler::Reset(); } int X64Assembler::Assemble( - FunctionInfo* symbol_info, HIRBuilder* hir_builder, + FunctionInfo* symbol_info, HIRBuilder* builder, uint32_t debug_info_flags, DebugInfo* debug_info, Function** out_function) { int result = 0; - // Lower HIR -> LIR. - auto lowering_table = x64_backend_->lowering_table(); - result = lowering_table->Process(hir_builder, builder_); - XEEXPECTZERO(result); - - // Stash raw LIR. - if (debug_info_flags & DEBUG_INFO_RAW_LIR_DISASM) { - builder_->Dump(&string_buffer_); - debug_info->set_raw_lir_disasm(string_buffer_.ToString()); - string_buffer_.Reset(); - } - - // Optimize LIR. - result = optimizer_->Optimize(builder_); - XEEXPECTZERO(result); - - // Stash optimized LIR. - if (debug_info_flags & DEBUG_INFO_LIR_DISASM) { - builder_->Dump(&string_buffer_); - debug_info->set_lir_disasm(string_buffer_.ToString()); - string_buffer_.Reset(); - } - - // Emit machine code. + // Lower HIR -> x64. void* machine_code = 0; size_t code_size = 0; - result = emitter_->Emit(builder_, machine_code, code_size); + result = emitter_->Emit(builder, machine_code, code_size); XEEXPECTZERO(result); // Stash generated machine code. diff --git a/src/alloy/backend/x64/x64_assembler.h b/src/alloy/backend/x64/x64_assembler.h index db50b6350..6e8855dd8 100644 --- a/src/alloy/backend/x64/x64_assembler.h +++ b/src/alloy/backend/x64/x64_assembler.h @@ -21,8 +21,6 @@ namespace x64 { class X64Backend; class X64Emitter; -namespace lir { class LIRBuilder; } -namespace optimizer { class Optimizer; } class X64Assembler : public Assembler { @@ -44,8 +42,6 @@ private: private: X64Backend* x64_backend_; - lir::LIRBuilder* builder_; - optimizer::Optimizer* optimizer_; X64Emitter* emitter_; StringBuffer string_buffer_; diff --git a/src/alloy/backend/x64/x64_emitter.cc b/src/alloy/backend/x64/x64_emitter.cc index 8f26e5a19..3a6b81b1c 100644 --- a/src/alloy/backend/x64/x64_emitter.cc +++ b/src/alloy/backend/x64/x64_emitter.cc @@ -11,14 +11,13 @@ #include #include -#include - -#include +#include +#include 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()], rbx); - } else if (instr->arg2_type() == LIROperandType::OFFSET) { - // mov reg, [reg+offset] - mov(rbx, ptr[rax + *instr->arg2()]); - } 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()) - } - } - break; - - case LIR_OPCODE_JUMP_EQ: { - auto target = (*instr->arg0()); - je(target->name, T_NEAR); - break; - } - case LIR_OPCODE_JUMP_NE: { - auto target = (*instr->arg0()); - jne(target->name, T_NEAR); - break; - } - default: - // Unhandled. - break; - } - return 0; -} diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index aec1fc0f9..987f28753 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -12,6 +12,9 @@ #include +#include + +XEDECLARECLASS2(alloy, hir, HIRBuilder); namespace alloy { namespace backend { @@ -19,26 +22,31 @@ namespace x64 { class X64Backend; class X64CodeCache; -namespace lir { class LIRBuilder; } -class XbyakAllocator; -class XbyakGenerator; - -class X64Emitter { +// Unfortunately due to the design of xbyak we have to pass this to the ctor. +class XbyakAllocator : public Xbyak::Allocator { public: - X64Emitter(X64Backend* backend); - ~X64Emitter(); + virtual bool useProtect() const { return false; } +}; + +class X64Emitter : public Xbyak::CodeGenerator { +public: + X64Emitter(X64Backend* backend, XbyakAllocator* allocator); + virtual ~X64Emitter(); int Initialize(); - int Emit(lir::LIRBuilder* builder, + int Emit(hir::HIRBuilder* builder, void*& out_code_address, size_t& out_code_size); +private: + void* Emplace(X64CodeCache* code_cache); + int Emit(hir::HIRBuilder* builder); + private: X64Backend* backend_; X64CodeCache* code_cache_; XbyakAllocator* allocator_; - XbyakGenerator* generator_; }; diff --git a/src/alloy/compiler/compiler_passes.h b/src/alloy/compiler/compiler_passes.h index 120dff4e3..69da71b10 100644 --- a/src/alloy/compiler/compiler_passes.h +++ b/src/alloy/compiler/compiler_passes.h @@ -13,6 +13,8 @@ #include #include #include +#include +#include //#include #include diff --git a/src/alloy/compiler/passes/finalization_pass.cc b/src/alloy/compiler/passes/finalization_pass.cc new file mode 100644 index 000000000..d79bf3d2f --- /dev/null +++ b/src/alloy/compiler/passes/finalization_pass.cc @@ -0,0 +1,58 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include + +using namespace alloy; +using namespace alloy::backend; +using namespace alloy::compiler; +using namespace alloy::compiler::passes; +using namespace alloy::frontend; +using namespace alloy::hir; +using namespace alloy::runtime; + + +FinalizationPass::FinalizationPass() : + CompilerPass() { +} + +FinalizationPass::~FinalizationPass() { +} + +int FinalizationPass::Run(HIRBuilder* builder) { + // Process the HIR and prepare it for lowering. + // After this is done the HIR should be ready for emitting. + + auto arena = builder->arena(); + + auto block = builder->first_block(); + while (block) { + // Ensure all labels have names. + auto label = block->label_head; + while (label) { + if (!label->name) { + char* name = (char*)arena->Alloc(6 + 4 + 1); + xestrcpya(name, 6 + 1, "_label"); + char* part = _itoa(label->id, name + 6, 10); + label->name = name; + } + label = label->next; + } + + // ? + + block = block->next; + } + + return 0; +} diff --git a/src/alloy/compiler/passes/finalization_pass.h b/src/alloy/compiler/passes/finalization_pass.h new file mode 100644 index 000000000..a2260003a --- /dev/null +++ b/src/alloy/compiler/passes/finalization_pass.h @@ -0,0 +1,37 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_ +#define ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_ + +#include + + +namespace alloy { +namespace compiler { +namespace passes { + + +class FinalizationPass : public CompilerPass { +public: + FinalizationPass(); + virtual ~FinalizationPass(); + + virtual int Run(hir::HIRBuilder* builder); + +private: +}; + + +} // namespace passes +} // namespace compiler +} // namespace alloy + + +#endif // ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_ diff --git a/src/alloy/compiler/passes/register_allocation_pass.cc b/src/alloy/compiler/passes/register_allocation_pass.cc new file mode 100644 index 000000000..ab0fac30b --- /dev/null +++ b/src/alloy/compiler/passes/register_allocation_pass.cc @@ -0,0 +1,51 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include + +#include +#include +#include + +using namespace alloy; +using namespace alloy::backend; +using namespace alloy::compiler; +using namespace alloy::compiler::passes; +using namespace alloy::frontend; +using namespace alloy::hir; +using namespace alloy::runtime; + + +RegisterAllocationPass::RegisterAllocationPass(Backend* backend) : + CompilerPass() { + // TODO(benvanik): query backend info (register layout, etc). +} + +RegisterAllocationPass::~RegisterAllocationPass() { +} + +int RegisterAllocationPass::Run(HIRBuilder* builder) { + // Run through each block and give each dest value a register. + // This pass is currently really dumb, and will over spill and other badness. + + auto block = builder->first_block(); + while (block) { + if (ProcessBlock(block)) { + return 1; + } + block = block->next; + } + + return 0; +} + +int RegisterAllocationPass::ProcessBlock(Block* block) { + // + return 0; +} diff --git a/src/alloy/compiler/passes/register_allocation_pass.h b/src/alloy/compiler/passes/register_allocation_pass.h new file mode 100644 index 000000000..0f99c25f2 --- /dev/null +++ b/src/alloy/compiler/passes/register_allocation_pass.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2014 Ben Vanik. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_ +#define ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_ + +#include + +XEDECLARECLASS2(alloy, backend, Backend); + + +namespace alloy { +namespace compiler { +namespace passes { + + +class RegisterAllocationPass : public CompilerPass { +public: + RegisterAllocationPass(backend::Backend* backend); + virtual ~RegisterAllocationPass(); + + virtual int Run(hir::HIRBuilder* builder); + +private: + int ProcessBlock(hir::Block* block); +}; + + +} // namespace passes +} // namespace compiler +} // namespace alloy + + +#endif // ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_ diff --git a/src/alloy/compiler/passes/sources.gypi b/src/alloy/compiler/passes/sources.gypi index 7255c5c84..b3b055ad3 100644 --- a/src/alloy/compiler/passes/sources.gypi +++ b/src/alloy/compiler/passes/sources.gypi @@ -7,6 +7,10 @@ 'context_promotion_pass.h', 'dead_code_elimination_pass.cc', 'dead_code_elimination_pass.h', + 'finalization_pass.cc', + 'finalization_pass.h', + 'register_allocation_pass.cc', + 'register_allocation_pass.h', #'dead_store_elimination_pass.cc', #'dead_store_elimination_pass.h', 'simplification_pass.cc', diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index 43662c9fc..bfc8ee365 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -30,11 +30,16 @@ using namespace alloy::runtime; PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) { + Backend* backend = frontend->runtime()->backend(); + scanner_ = new PPCScanner(frontend); builder_ = new PPCHIRBuilder(frontend); - compiler_ = new Compiler(frontend->runtime()); + assembler_ = backend->CreateAssembler(); + assembler_->Initialize(); + // Passes are executed in the order they are added. Multiple of the same + // pass type may be used. compiler_->AddPass(new passes::ContextPromotionPass()); compiler_->AddPass(new passes::SimplificationPass()); // TODO(benvanik): run repeatedly? @@ -45,9 +50,11 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : //compiler_->AddPass(new passes::DeadStoreEliminationPass()); compiler_->AddPass(new passes::DeadCodeEliminationPass()); - Backend* backend = frontend->runtime()->backend(); - assembler_ = backend->CreateAssembler(); - assembler_->Initialize(); + // After register allocation instructions should not be added/removed. + compiler_->AddPass(new passes::RegisterAllocationPass(backend)); + + // Must come last. The HIR is not really HIR after this. + compiler_->AddPass(new passes::FinalizationPass()); } PPCTranslator::~PPCTranslator() { diff --git a/src/alloy/runtime/debug_info.cc b/src/alloy/runtime/debug_info.cc index c38587b78..066ce81da 100644 --- a/src/alloy/runtime/debug_info.cc +++ b/src/alloy/runtime/debug_info.cc @@ -17,8 +17,6 @@ DebugInfo::DebugInfo() : source_disasm_(0), raw_hir_disasm_(0), hir_disasm_(0), - raw_lir_disasm_(0), - lir_disasm_(0), machine_code_disasm_(0) { } @@ -26,7 +24,5 @@ DebugInfo::~DebugInfo() { xe_free(source_disasm_); xe_free(raw_hir_disasm_); xe_free(hir_disasm_); - xe_free(raw_lir_disasm_); - xe_free(lir_disasm_); xe_free(machine_code_disasm_); } diff --git a/src/alloy/runtime/debug_info.h b/src/alloy/runtime/debug_info.h index a95465a7d..3609c5513 100644 --- a/src/alloy/runtime/debug_info.h +++ b/src/alloy/runtime/debug_info.h @@ -23,9 +23,7 @@ enum DebugInfoFlags { DEBUG_INFO_SOURCE_DISASM = (1 << 1), DEBUG_INFO_RAW_HIR_DISASM = (1 << 2), DEBUG_INFO_HIR_DISASM = (1 << 3), - DEBUG_INFO_RAW_LIR_DISASM = (1 << 4), - DEBUG_INFO_LIR_DISASM = (1 << 5), - DEBUG_INFO_MACHINE_CODE_DISASM = (1 << 6), + DEBUG_INFO_MACHINE_CODE_DISASM = (1 << 4), DEBUG_INFO_ALL_DISASM = 0xFFFF, }; @@ -42,10 +40,6 @@ public: void set_raw_hir_disasm(char* value) { raw_hir_disasm_ = value; } const char* hir_disasm() const { return hir_disasm_; } void set_hir_disasm(char* value) { hir_disasm_ = value; } - const char* raw_lir_disasm() const { return raw_lir_disasm_; } - void set_raw_lir_disasm(char* value) { raw_lir_disasm_ = value; } - const char* lir_disasm() const { return lir_disasm_; } - void set_lir_disasm(char* value) { lir_disasm_ = value; } const char* machine_code_disasm() const { return machine_code_disasm_; } void set_machine_code_disasm(char* value) { machine_code_disasm_ = value; } @@ -58,8 +52,6 @@ private: char* source_disasm_; char* raw_hir_disasm_; char* hir_disasm_; - char* raw_lir_disasm_; - char* lir_disasm_; char* machine_code_disasm_; }; diff --git a/src/alloy/runtime/runtime.cc b/src/alloy/runtime/runtime.cc index 95e27a2d2..e10d3ff38 100644 --- a/src/alloy/runtime/runtime.cc +++ b/src/alloy/runtime/runtime.cc @@ -91,10 +91,10 @@ int Runtime::Initialize(Frontend* frontend, Backend* backend) { #endif // ALLOY_HAS_IVM_BACKEND if (FLAGS_runtime_backend == "any") { #if defined(ALLOY_HAS_X64_BACKEND) && ALLOY_HAS_X64_BACKEND - /*if (!backend) { + if (!backend) { backend = new alloy::backend::x64::X64Backend( this); - }*/ + } #endif // ALLOY_HAS_X64_BACKEND #if defined(ALLOY_HAS_IVM_BACKEND) && ALLOY_HAS_IVM_BACKEND if (!backend) { diff --git a/src/xenia/cpu/processor.cc b/src/xenia/cpu/processor.cc index 55a8cb766..678be2190 100644 --- a/src/xenia/cpu/processor.cc +++ b/src/xenia/cpu/processor.cc @@ -704,10 +704,6 @@ json_t* Processor::DumpFunction(uint64_t address, bool& succeeded) { json_object_set_new(disasm_json, "rawHir", disasm_str_json); disasm_str_json = json_string(debug_info->hir_disasm()); json_object_set_new(disasm_json, "hir", disasm_str_json); - disasm_str_json = json_string(debug_info->raw_lir_disasm()); - json_object_set_new(disasm_json, "rawLir", disasm_str_json); - disasm_str_json = json_string(debug_info->lir_disasm()); - json_object_set_new(disasm_json, "lir", disasm_str_json); disasm_str_json = json_string(debug_info->machine_code_disasm()); json_object_set_new(disasm_json, "machineCode", disasm_str_json); json_object_set_new(fn_json, "disasm", disasm_json);