From 125e7278c6699de6a0941d1ad95f9b9b34826335 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Thu, 2 Jan 2014 00:00:14 -0800 Subject: [PATCH] Ugh. Replacing the fancy templates with hand coded sequences for now. --- src/alloy/backend/x64/lir/lir_builder.cc | 73 +- src/alloy/backend/x64/lir/lir_builder.h | 28 +- src/alloy/backend/x64/lir/lir_instr.h | 28 +- src/alloy/backend/x64/lir/lir_label.h | 1 + src/alloy/backend/x64/lir/lir_opcodes.cc | 14 +- src/alloy/backend/x64/lir/lir_opcodes.h | 43 +- src/alloy/backend/x64/lir/lir_opcodes.inl | 65 +- .../x64/lowering/lowering_hir_opcodes.inl | 112 -- .../x64/lowering/lowering_lir_opcodes.inl | 16 - .../x64/lowering/lowering_sequences.cc | 1059 +++++++++-------- .../backend/x64/lowering/lowering_table.cc | 28 +- .../backend/x64/lowering/lowering_table.h | 28 +- src/alloy/backend/x64/lowering/sources.gypi | 2 - src/alloy/backend/x64/x64_assembler.cc | 33 +- src/alloy/backend/x64/x64_assembler.h | 5 + src/alloy/backend/x64/x64_backend.cc | 2 + src/alloy/backend/x64/x64_emitter.h | 2 - src/alloy/hir/hir_builder.cc | 3 +- src/alloy/hir/opcodes.h | 1 - src/xenia/debug/protocols/ws/ws_client.cc | 2 +- third_party/beaengine.gypi | 6 +- xenia.gyp | 4 +- 22 files changed, 784 insertions(+), 771 deletions(-) delete mode 100644 src/alloy/backend/x64/lowering/lowering_hir_opcodes.inl delete mode 100644 src/alloy/backend/x64/lowering/lowering_lir_opcodes.inl diff --git a/src/alloy/backend/x64/lir/lir_builder.cc b/src/alloy/backend/x64/lir/lir_builder.cc index a16e3dcb0..5cbecf845 100644 --- a/src/alloy/backend/x64/lir/lir_builder.cc +++ b/src/alloy/backend/x64/lir/lir_builder.cc @@ -49,10 +49,18 @@ void LIRBuilder::Dump(StringBuffer* str) { auto label = block->label_head; while (label) { - if (label->name) { - str->Append("%s:\n", label->name); + if (label->local) { + if (label->name) { + str->Append(".%s:\n", label->name); + } else { + str->Append(".label%d:\n", label->id); + } } else { - str->Append("label%d:\n", label->id); + if (label->name) { + str->Append("%s:\n", label->name); + } else { + str->Append("label%d:\n", label->id); + } } label = label->next; } @@ -63,8 +71,11 @@ void LIRBuilder::Dump(StringBuffer* str) { i = i->next; continue; } - - // TODO(benvanik): handle comment + if (i->opcode == &LIR_OPCODE_COMMENT_info) { + str->Append(" ; %s\n", (char*)i->arg[0].i64); + i = i->next; + continue; + } const LIROpcodeInfo* info = i->opcode; str->Append(" "); @@ -95,12 +106,14 @@ LIRInstr* LIRBuilder::last_instr() const { return NULL; } -LIRLabel* LIRBuilder::NewLabel() { +LIRLabel* LIRBuilder::NewLabel(bool local) { LIRLabel* label = arena_->Alloc(); label->next = label->prev = NULL; label->block = NULL; label->id = next_label_id_++; label->name = NULL; + label->local = local; + label->tag = NULL; return label; } @@ -174,3 +187,51 @@ LIRInstr* LIRBuilder::AppendInstr( instr->flags = flags; return instr; } + +void LIRBuilder::Comment(const char* format, ...) { + auto instr = AppendInstr(LIR_OPCODE_COMMENT_info); +} + +void LIRBuilder::Nop() { + auto instr = AppendInstr(LIR_OPCODE_NOP_info); +} + +void LIRBuilder::SourceOffset(uint64_t offset) { + auto instr = AppendInstr(LIR_OPCODE_SOURCE_OFFSET_info); +} + +void LIRBuilder::DebugBreak() { + auto instr = AppendInstr(LIR_OPCODE_DEBUG_BREAK_info); +} + +void LIRBuilder::Trap() { + auto instr = AppendInstr(LIR_OPCODE_TRAP_info); +} + +void LIRBuilder::Test(int8_t a, int8_t b) { + auto instr = AppendInstr(LIR_OPCODE_TEST_info); +} + +void LIRBuilder::Test(int16_t a, int16_t b) { + auto instr = AppendInstr(LIR_OPCODE_TEST_info); +} + +void LIRBuilder::Test(int32_t a, int32_t b) { + auto instr = AppendInstr(LIR_OPCODE_TEST_info); +} + +void LIRBuilder::Test(int64_t a, int64_t b) { + auto instr = AppendInstr(LIR_OPCODE_TEST_info); +} + +void LIRBuilder::Test(hir::Value* a, hir::Value* b) { + auto instr = AppendInstr(LIR_OPCODE_TEST_info); +} + +void LIRBuilder::JumpEQ(LIRLabel* label) { + auto instr = AppendInstr(LIR_OPCODE_JUMP_EQ_info); +} + +void LIRBuilder::JumpNE(LIRLabel* label) { + auto instr = AppendInstr(LIR_OPCODE_JUMP_NE_info); +} diff --git a/src/alloy/backend/x64/lir/lir_builder.h b/src/alloy/backend/x64/lir/lir_builder.h index 0b1ecd04c..25f643ded 100644 --- a/src/alloy/backend/x64/lir/lir_builder.h +++ b/src/alloy/backend/x64/lir/lir_builder.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace alloy { @@ -40,16 +41,37 @@ public: LIRBlock* current_block() const; LIRInstr* last_instr() const; - LIRLabel* NewLabel(); + LIRLabel* NewLabel(bool local = false); + LIRLabel* NewLocalLabel() { return NewLabel(true); } void MarkLabel(LIRLabel* label, LIRBlock* block = 0); // TODO(benvanik): allocations LIRBlock* AppendBlock(); void EndBlock(); - LIRInstr* AppendInstr(const LIROpcodeInfo& opcode, uint16_t flags); -protected: + void Comment(const char* format, ...); + void Nop(); + void SourceOffset(uint64_t offset); + + void DebugBreak(); + void Trap(); + + void Mov(); + + void Test(int8_t a, int8_t b); + void Test(int16_t a, int16_t b); + void Test(int32_t a, int32_t b); + void Test(int64_t a, int64_t b); + void Test(hir::Value* a, hir::Value* b); + + void JumpEQ(LIRLabel* label); + void JumpNE(LIRLabel* label); + +private: + LIRInstr* AppendInstr(const LIROpcodeInfo& opcode, uint16_t flags = 0); + +private: X64Backend* backend_; Arena* arena_; diff --git a/src/alloy/backend/x64/lir/lir_instr.h b/src/alloy/backend/x64/lir/lir_instr.h index 53ddba3a5..a10c981c3 100644 --- a/src/alloy/backend/x64/lir/lir_instr.h +++ b/src/alloy/backend/x64/lir/lir_instr.h @@ -65,6 +65,19 @@ enum LIRRegister { XMM15, }; +typedef union { + runtime::FunctionInfo* symbol_info; + LIRLabel* label; + LIRRegister reg; + int8_t i8; + int16_t i16; + int32_t i32; + int64_t i64; + float f32; + double f64; + uint64_t offset; +} LIROperand; + class LIRInstr { public: @@ -75,21 +88,8 @@ public: const LIROpcodeInfo* opcode; uint16_t flags; - typedef union { - runtime::FunctionInfo* symbol_info; - LIRLabel* label; - LIRRegister reg; - int8_t i8; - int16_t i16; - int32_t i32; - int64_t i64; - float f32; - double f64; - uint64_t offset; - } Op; - // TODO(benvanik): make this variable width? - Op arg[4]; + LIROperand arg[4]; }; diff --git a/src/alloy/backend/x64/lir/lir_label.h b/src/alloy/backend/x64/lir/lir_label.h index c35e19d7d..50a234972 100644 --- a/src/alloy/backend/x64/lir/lir_label.h +++ b/src/alloy/backend/x64/lir/lir_label.h @@ -29,6 +29,7 @@ public: uint32_t id; char* name; + bool local; void* tag; }; diff --git a/src/alloy/backend/x64/lir/lir_opcodes.cc b/src/alloy/backend/x64/lir/lir_opcodes.cc index 42d1b568d..337bc0904 100644 --- a/src/alloy/backend/x64/lir/lir_opcodes.cc +++ b/src/alloy/backend/x64/lir/lir_opcodes.cc @@ -18,11 +18,21 @@ namespace backend { namespace x64 { namespace lir { -#define DEFINE_OPCODE(num, name, sig, flags) \ - static const LIROpcodeInfo num##_info = { flags, sig, name, num, }; +#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 diff --git a/src/alloy/backend/x64/lir/lir_opcodes.h b/src/alloy/backend/x64/lir/lir_opcodes.h index 564fc8c29..c86ee1a53 100644 --- a/src/alloy/backend/x64/lir/lir_opcodes.h +++ b/src/alloy/backend/x64/lir/lir_opcodes.h @@ -20,13 +20,20 @@ namespace lir { enum LIROpcode { - LIR_OPCODE_MOV_I32, - LIR_OPCODE_XOR_I32, - LIR_OPCODE_DEC_I32, - LIR_OPCODE_SUB_I32, - LIR_OPCODE_IMUL_I32, - LIR_OPCODE_IMUL_I32_AUX, - LIR_OPCODE_DIV_I32, + LIR_OPCODE_COMMENT, + LIR_OPCODE_NOP, + + LIR_OPCODE_SOURCE_OFFSET, + + LIR_OPCODE_DEBUG_BREAK, + LIR_OPCODE_TRAP, + + LIR_OPCODE_MOV, + + LIR_OPCODE_TEST, + + LIR_OPCODE_JUMP_EQ, + LIR_OPCODE_JUMP_NE, __LIR_OPCODE_MAX_VALUE, // Keep at end. }; @@ -40,36 +47,20 @@ enum LIROpcodeFlags { LIR_OPCODE_FLAG_HIDE = (1 << 6), }; -enum LIROpcodeSignatureType { - // 3 bits max (0-7) - LIR_OPCODE_SIG_TYPE_X = 0, -}; - -enum LIROpcodeSignature { - LIR_OPCODE_SIG_X = (LIR_OPCODE_SIG_TYPE_X), - LIR_OPCODE_SIG_R32 = (LIR_OPCODE_SIG_TYPE_X), - LIR_OPCODE_SIG_R32_R32 = (LIR_OPCODE_SIG_TYPE_X), - LIR_OPCODE_SIG_R32_R32_C32 = (LIR_OPCODE_SIG_TYPE_X), -}; - -#define GET_LIR_OPCODE_SIG_TYPE_DEST(sig) (LIROpcodeSignatureType)(sig & 0x7) -#define GET_LIR_OPCODE_SIG_TYPE_SRC1(sig) (LIROpcodeSignatureType)((sig >> 3) & 0x7) -#define GET_LIR_OPCODE_SIG_TYPE_SRC2(sig) (LIROpcodeSignatureType)((sig >> 6) & 0x7) -#define GET_LIR_OPCODE_SIG_TYPE_SRC3(sig) (LIROpcodeSignatureType)((sig >> 9) & 0x7) - typedef struct { uint32_t flags; - uint32_t signature; const char* name; LIROpcode num; } LIROpcodeInfo; -#define DEFINE_OPCODE(num, name, sig, flags) \ +#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 diff --git a/src/alloy/backend/x64/lir/lir_opcodes.inl b/src/alloy/backend/x64/lir/lir_opcodes.inl index fb3544c81..9ce9dfcf2 100644 --- a/src/alloy/backend/x64/lir/lir_opcodes.inl +++ b/src/alloy/backend/x64/lir/lir_opcodes.inl @@ -8,37 +8,46 @@ */ DEFINE_OPCODE( - LIR_OPCODE_MOV_I32, - "mov.i32", - LIR_OPCODE_SIG_R32_R32, - 0); + LIR_OPCODE_COMMENT, + "comment", + LIR_OPCODE_FLAG_IGNORE) + DEFINE_OPCODE( - LIR_OPCODE_XOR_I32, - "xor.i32", - LIR_OPCODE_SIG_R32_R32, - 0); + LIR_OPCODE_NOP, + "nop", + LIR_OPCODE_FLAG_IGNORE) + DEFINE_OPCODE( - LIR_OPCODE_DEC_I32, - "dec.i32", - LIR_OPCODE_SIG_R32, - 0); + LIR_OPCODE_SOURCE_OFFSET, + "source_offset", + LIR_OPCODE_FLAG_IGNORE | LIR_OPCODE_FLAG_HIDE) + DEFINE_OPCODE( - LIR_OPCODE_SUB_I32, - "sub.i32", - LIR_OPCODE_SIG_R32_R32, - 0); + LIR_OPCODE_DEBUG_BREAK, + "debug_break", + 0) + DEFINE_OPCODE( - LIR_OPCODE_IMUL_I32, - "imul.i32", - LIR_OPCODE_SIG_R32_R32, - 0); + LIR_OPCODE_TRAP, + "trap", + 0) + DEFINE_OPCODE( - LIR_OPCODE_IMUL_I32_AUX, - "imul.i32.aux", - LIR_OPCODE_SIG_R32_R32_C32, - 0); + LIR_OPCODE_MOV, + "mov", + 0) + DEFINE_OPCODE( - LIR_OPCODE_DIV_I32, - "div.i32", - LIR_OPCODE_SIG_R32, - 0); + LIR_OPCODE_TEST, + "test", + 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/lowering/lowering_hir_opcodes.inl b/src/alloy/backend/x64/lowering/lowering_hir_opcodes.inl deleted file mode 100644 index 1aeddce41..000000000 --- a/src/alloy/backend/x64/lowering/lowering_hir_opcodes.inl +++ /dev/null @@ -1,112 +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_X(COMMENT); - -DEFINE_OPCODE_X(NOP); - -DEFINE_OPCODE_X_O(SOURCE_OFFSET); - -DEFINE_OPCODE_X(DEBUG_BREAK); -DEFINE_OPCODE_X_V(DEBUG_BREAK_TRUE); - -DEFINE_OPCODE_X(TRAP); -DEFINE_OPCODE_X_V(TRAP_TRUE); - -DEFINE_OPCODE_X_S(CALL); -DEFINE_OPCODE_X_V_S(CALL_TRUE); -DEFINE_OPCODE_X_V(CALL_INDIRECT); -DEFINE_OPCODE_X_V_V(CALL_INDIRECT_TRUE); -DEFINE_OPCODE_X(RETURN); -DEFINE_OPCODE_X_V(SET_RETURN_ADDRESS); - -DEFINE_OPCODE_X_L(BRANCH); -DEFINE_OPCODE_X_V_L(BRANCH_TRUE); -DEFINE_OPCODE_X_V_L(BRANCH_FALSE); - -DEFINE_OPCODE_V_V(ASSIGN); -DEFINE_OPCODE_V_V(CAST); -DEFINE_OPCODE_V_V(ZERO_EXTEND); -DEFINE_OPCODE_V_V(SIGN_EXTEND); -DEFINE_OPCODE_V_V(TRUNCATE); -DEFINE_OPCODE_V_V(CONVERT); -DEFINE_OPCODE_V_V(ROUND); -DEFINE_OPCODE_V_V(VECTOR_CONVERT_I2F); -DEFINE_OPCODE_V_V(VECTOR_CONVERT_F2I); - -DEFINE_OPCODE_V_V(LOAD_VECTOR_SHL); -DEFINE_OPCODE_V_V(LOAD_VECTOR_SHR); - -DEFINE_OPCODE_V_O(LOAD_CONTEXT); -DEFINE_OPCODE_V_O_V(STORE_CONTEXT); - -DEFINE_OPCODE_V_V(LOAD); -DEFINE_OPCODE_V_V(LOAD_ACQUIRE); -DEFINE_OPCODE_X_V_V(STORE); -DEFINE_OPCODE_V_V_V(STORE_RELEASE); -DEFINE_OPCODE_X_V_O(PREFETCH); - -DEFINE_OPCODE_V_V_V(MAX); -DEFINE_OPCODE_V_V_V(MIN); -DEFINE_OPCODE_V_V_V_V(SELECT); -DEFINE_OPCODE_V_V(IS_TRUE); -DEFINE_OPCODE_V_V(IS_FALSE); -DEFINE_OPCODE_V_V_V(COMPARE_EQ); -DEFINE_OPCODE_V_V_V(COMPARE_NE); -DEFINE_OPCODE_V_V_V(COMPARE_SLT); -DEFINE_OPCODE_V_V_V(COMPARE_SLE); -DEFINE_OPCODE_V_V_V(COMPARE_SGT); -DEFINE_OPCODE_V_V_V(COMPARE_SGE); -DEFINE_OPCODE_V_V_V(COMPARE_ULT); -DEFINE_OPCODE_V_V_V(COMPARE_ULE); -DEFINE_OPCODE_V_V_V(COMPARE_UGT); -DEFINE_OPCODE_V_V_V(COMPARE_UGE); -DEFINE_OPCODE_V_V(DID_CARRY); -DEFINE_OPCODE_V_V(DID_OVERFLOW); -DEFINE_OPCODE_V_V_V(VECTOR_COMPARE_EQ); -DEFINE_OPCODE_V_V_V(VECTOR_COMPARE_SGT); -DEFINE_OPCODE_V_V_V(VECTOR_COMPARE_SGE); -DEFINE_OPCODE_V_V_V(VECTOR_COMPARE_UGT); -DEFINE_OPCODE_V_V_V(VECTOR_COMPARE_UGE); - -DEFINE_OPCODE_V_V_V(ADD); -DEFINE_OPCODE_V_V_V_V(ADD_CARRY); -DEFINE_OPCODE_V_V_V(SUB); -DEFINE_OPCODE_V_V_V(MUL); -DEFINE_OPCODE_V_V_V(DIV); -DEFINE_OPCODE_V_V_V(REM); -DEFINE_OPCODE_V_V_V_V(MULADD); -DEFINE_OPCODE_V_V_V_V(MULSUB); -DEFINE_OPCODE_V_V(NEG); -DEFINE_OPCODE_V_V(ABS); -DEFINE_OPCODE_V_V(SQRT); -DEFINE_OPCODE_V_V(RSQRT); -DEFINE_OPCODE_V_V_V(DOT_PRODUCT_3); -DEFINE_OPCODE_V_V_V(DOT_PRODUCT_4); - -DEFINE_OPCODE_V_V_V(AND); -DEFINE_OPCODE_V_V_V(OR); -DEFINE_OPCODE_V_V_V(XOR); -DEFINE_OPCODE_V_V(NOT); -DEFINE_OPCODE_V_V_V(SHL); -DEFINE_OPCODE_V_V_V(VECTOR_SHL); -DEFINE_OPCODE_V_V_V(SHR); -DEFINE_OPCODE_V_V_V(SHA); -DEFINE_OPCODE_V_V_V(ROTATE_LEFT); -DEFINE_OPCODE_V_V(BYTE_SWAP); -DEFINE_OPCODE_V_V(CNTLZ); -DEFINE_OPCODE_V_V_V_V(INSERT); -DEFINE_OPCODE_V_V_V(EXTRACT); -DEFINE_OPCODE_V_V(SPLAT); -DEFINE_OPCODE_V_V_V_V(PERMUTE); -DEFINE_OPCODE_V_V_O(SWIZZLE); - -DEFINE_OPCODE_V_V_V_V(COMPARE_EXCHANGE); -DEFINE_OPCODE_V_V_V(ATOMIC_ADD); -DEFINE_OPCODE_V_V_V(ATOMIC_SUB); diff --git a/src/alloy/backend/x64/lowering/lowering_lir_opcodes.inl b/src/alloy/backend/x64/lowering/lowering_lir_opcodes.inl deleted file mode 100644 index 748d9d221..000000000 --- a/src/alloy/backend/x64/lowering/lowering_lir_opcodes.inl +++ /dev/null @@ -1,16 +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_LIR_OPCODE_R32_R32(MOV_I32); -DEFINE_LIR_OPCODE_R32_R32(XOR_I32); -DEFINE_LIR_OPCODE_R32(DEC_I32); -DEFINE_LIR_OPCODE_R32_R32(SUB_I32); -DEFINE_LIR_OPCODE_R32_R32(IMUL_I32); -DEFINE_LIR_OPCODE_R32_R32_C32(IMUL_I32_AUX); -DEFINE_LIR_OPCODE_R32(DIV_I32); diff --git a/src/alloy/backend/x64/lowering/lowering_sequences.cc b/src/alloy/backend/x64/lowering/lowering_sequences.cc index f9caadca7..0c9e25a5a 100644 --- a/src/alloy/backend/x64/lowering/lowering_sequences.cc +++ b/src/alloy/backend/x64/lowering/lowering_sequences.cc @@ -11,580 +11,601 @@ #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 std; - - -namespace { - - -enum ArgType { - NULL_ARG_TYPE, - VALUE_ARG_TYPE, - CONSTANT_ARG_TYPE, - SYMBOL_ARG_TYPE, - LABEL_ARG_TYPE, - OUT_ARG_TYPE, - IN_ARG_TYPE, - REG_ARG_TYPE, -}; -template -class Arg { -public: - const static ArgType arg_type = ARG_TYPE; -}; - -class NullArg : public Arg {}; - -template -class ValueRef : public Arg { -public: - const static int type = TYPE; -}; -class SymbolRef : public Arg { -public: -}; -class LabelRef : public Arg { -public: -}; -template - // vec -class Constant : public Arg { -public: - const static int type = TYPE; - const static bool has_value = HAS_VALUE; - const static int8_t i8 = INT8_VALUE; - const static int16_t i16 = INT16_VALUE; - const static int32_t i32 = INT32_VALUE; - const static int64_t i64 = INT64_VALUE; - const static intmax_t f32_num = FLOAT32_NUM_VALUE; - const static intmax_t f32_den = FLOAT32_DEN_VALUE; - const static intmax_t f64_num = FLOAT64_NUM_VALUE; - const static intmax_t f64_den = FLOAT64_DEN_VALUE; - // vec -}; -template -class Int8Constant : public Constant {}; -template -class Int16Constant : public Constant {}; -template -class Int32Constant : public Constant {}; -template -class Int64Constant : public Constant {}; -template -class Float32Constant : public Constant {}; -template -class Float64Constant : public Constant {}; -// vec - -template -class Out : public Arg { -public: - const static int slot = SLOT; -}; - -template -class In : public Arg { -public: - const static int slot = SLOT; - const static int arg = ARG; -}; - -template -class Reg : public Arg { -public: - const static int reg_name = REG_NAME; -}; - - -class Matcher { -public: - template struct IntType { static const int value = v; }; - - template - static bool CheckArg(Instr* instr_list[], Instr::Op& op, IntType) { - return true; - } - template - static bool CheckArg(Instr* instr_list[], Instr::Op& op, IntType) { - return op.value->type == T::type; - } - template - static bool CheckArg(Instr* instr_list[], Instr::Op& op, IntType) { - return true; - } - template - static bool CheckArg(Instr* instr_list[], Instr::Op& op, IntType) { - return true; - } - template - static bool CheckArg(Instr* instr_list[], Instr::Op& op, IntType) { - if (op.value->type != T::type) { - return false; - } - if (!T::has_value) { - return true; - } - switch (T::type) { - case INT8_TYPE: - return op.value->constant.i8 == T::i8; - case INT16_TYPE: - return op.value->constant.i16 == T::i16; - case INT32_TYPE: - return op.value->constant.i32 == T::i32; - case INT64_TYPE: - return op.value->constant.i64 == T::i64; - case FLOAT32_TYPE: - return op.value->constant.f32 == (T::f32_num / T::f32_den); - case FLOAT64_TYPE: - return op.value->constant.f64 == (T::f64_num / T::f64_den); - // vec - } - return false; - } - template - static bool CheckArg(Instr* instr_list[], Instr::Op& op, IntType) { - Instr* instr = instr_list[T::slot]; - return op.value == instr->dest; - } - template - static bool CheckArg(Instr* instr_list[], Instr::Op& op, IntType) { - Instr* instr = instr_list[T::slot]; - switch (T::arg) { - case 0: - return op.value == instr->src1.value; - case 1: - return op.value == instr->src2.value; - case 2: - return op.value == instr->src3.value; - } - return false; - } - - template - static bool CheckDest(Instr* instr_list[], Value* value, IntType) { - return true; - } - template - static bool CheckDest(Instr* instr_list[], Value* value, IntType) { - return value->type == T::type; - } - template - static bool CheckDest(Instr* instr_list[], Value* value, IntType) { - Instr* instr = instr_list[T::slot]; - return value == instr->dest; - } - template - static bool CheckDest(Instr* instr_list[], Value* value, IntType) { - Instr* instr = instr_list[T::slot]; - switch (T::arg) { - case 0: - return value == instr->src1.value; - case 1: - return value == instr->src2.value; - case 2: - return value == instr->src3.value; - } - return false; - } - - template - static typename std::enable_if::value, void>::type - Match(Instr* instr_list[], int& instr_offset, Instr*&, bool&) { - } - template - static typename std::enable_if::value, void>::type - Match(Instr* instr_list[], int& instr_offset, Instr*& instr, bool& matched) { - instr_list[instr_offset++] = instr; - typedef std::tuple_element::type T; - if (instr->opcode->num != T::opcode) { - matched = false; - return; - } - // Matches opcode, check args. - if (!std::is_same::value) { - if (!CheckDest(instr_list, instr->dest, IntType())) { - matched = false; - return; - } - } - if (!std::is_same::value) { - if (!CheckArg(instr_list, instr->src1, IntType())) { - matched = false; - return; - } - } - if (!std::is_same::value) { - if (!CheckArg(instr_list, instr->src2, IntType())) { - matched = false; - return; - } - } - if (!std::is_same::value) { - if (!CheckArg(instr_list, instr->src3, IntType())) { - matched = false; - return; - } - } - instr = instr->next; - Match(instr_list, instr_offset, instr, matched); - } - - template - static bool Matches(Instr* instr_list[], int& instr_offset, Instr*& instr) { - bool matched = true; - Instr* orig_instr = instr; - Match<0, HIRS>(instr_list, instr_offset, instr, matched); - if (!matched) { - instr = orig_instr; - } - return matched; - } -}; - - -class Emitter { -public: - template - static typename std::enable_if::value, void>::type - EmitInstr(LIRBuilder* builder, Instr*[]) { - } - template - static typename std::enable_if::value, void>::type - EmitInstr(LIRBuilder* builder, Instr* instr_list[]) { - typedef std::tuple_element::type T; - //LIRInstr* lir_instr = builder->AppendInstr(T::opcode); - if (!std::is_same::value) { - // lir_instr->dest = ... - } - if (!std::is_same::value) { - // - } - if (!std::is_same::value) { - // - } - if (!std::is_same::value) { - // - } - EmitInstr(builder, instr_list); - } - - template - static void Emit(LIRBuilder* builder, Instr* instr_list[]) { - EmitInstr<0, LIRS>(builder, instr_list); - } -}; - - -template -void Translate(LoweringTable* table) { - auto exec = [](LIRBuilder* builder, Instr*& instr) { - Instr* instr_list[32] = { 0 }; - int instr_offset = 0; - if (Matcher::Matches(instr_list, instr_offset, instr)) { - Emitter::Emit(builder, instr_list); - return true; - } - return false; - }; - auto new_fn = new LoweringTable::TypedFnWrapper(exec); - table->AddSequence(std::tuple_element<0, MATCH>::type::opcode, new_fn); -} - - -} // namespace - - -namespace { -template -class HIR_OPCODE { -public: - static const Opcode opcode = OPCODE; - static const OpcodeSignature signature = SIGNATURE; - static const int flags = FLAGS; - - typedef DEST dest; - typedef ARG0 arg0; - typedef ARG1 arg1; - typedef ARG2 arg2; -}; -#define DEFINE_OPCODE(num, name, sig, flags) \ - template \ -class BASE_HIR_##num : public HIR_OPCODE{}; -#include -#undef DEFINE_OPCODE -#define DEFINE_OPCODE_V_O(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_V_O_V(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_V_V(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_V_V_O(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_V_V_V(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_V_V_V_V(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_X(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name<> {} -#define DEFINE_OPCODE_X_L(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_X_O(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_X_S(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_X_V(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_X_V_L(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_X_V_O(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_X_V_S(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#define DEFINE_OPCODE_X_V_V(name) \ - template \ - class HIR_##name : public BASE_HIR_OPCODE_##name {} -#include -} - -namespace { -template -class LIR_OPCODE { -public: - static const LIROpcode opcode = OPCODE; - static const LIROpcodeSignature signature = SIGNATURE; - static const int flags = FLAGS; - - typedef DEST dest; - typedef ARG0 arg0; - typedef ARG1 arg1; - typedef ARG2 arg2; -}; -#define DEFINE_OPCODE(num, name, sig, flags) \ - template \ - class BASE_##num : public LIR_OPCODE {}; -#include -#undef DEFINE_OPCODE -#define DEFINE_LIR_OPCODE_X(name) \ - template \ - class LIR_##name : public BASE_LIR_OPCODE_##name<> {} -#define DEFINE_LIR_OPCODE_R32(name) \ - template \ - class LIR_##name : public BASE_LIR_OPCODE_##name {} -#define DEFINE_LIR_OPCODE_R32_R32(name) \ - template \ - class LIR_##name : public BASE_LIR_OPCODE_##name {} -#define DEFINE_LIR_OPCODE_R32_R32_C32(name) \ - template \ - class LIR_##name : public BASE_LIR_OPCODE_##name {} -#include -} - - void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) { - // TODO(benvanik): translate comments somehow - special type? - Translate - >, tuple< - >> (table); + // -------------------------------------------------------------------------- + // General + // -------------------------------------------------------------------------- - Translate - >, tuple< - >> (table); + table->AddSequence(OPCODE_COMMENT, [](LIRBuilder& lb, Instr*& instr) { + char* str = (char*)instr->src1.offset; + lb.Comment(str); + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_NOP, [](LIRBuilder& lb, Instr*& instr) { + lb.Nop(); + instr = instr->next; + return true; + }); // -------------------------------------------------------------------------- // Debugging // -------------------------------------------------------------------------- - // TODO(benvanik): translate source offsets for mapping - Translate> - >, tuple< - >> (table); + table->AddSequence(OPCODE_SOURCE_OFFSET, [](LIRBuilder& lb, 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); + instr = instr->next; + return true; + }); - Translate - >, tuple< - // int3 - >> (table); - Translate> - >, tuple< - // test if 0 - // jz label - // int3 - // label: - >> (table); + table->AddSequence(OPCODE_DEBUG_BREAK, [](LIRBuilder& lb, Instr*& instr) { + lb.DebugBreak(); + instr = instr->next; + return true; + }); - Translate - >, tuple< - // int3 - >> (table); - Translate> - >, tuple< - // test if 0 - // jz label - // int3 - // label: - >> (table); + 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); + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_TRAP, [](LIRBuilder& lb, Instr*& instr) { + lb.Trap(); + 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); + instr = instr->next; + return true; + }); // -------------------------------------------------------------------------- // Calls // -------------------------------------------------------------------------- - Translate - >, tuple< - // call - >> (table); - Translate, SymbolRef> - >, tuple< - // call - >> (table); - Translate> - >, tuple< - // call - >> (table); - Translate, ValueRef> - >, tuple< - // call - >> (table); - // return / set return address + table->AddSequence(OPCODE_CALL, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_CALL_TRUE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_CALL_INDIRECT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_CALL_INDIRECT_TRUE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_RETURN, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SET_RETURN_ADDRESS, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); // -------------------------------------------------------------------------- // Branches // -------------------------------------------------------------------------- - Translate - >, tuple< - // branch - >> (table); - Translate, LabelRef> - >, tuple< - // branch - >> (table); - Translate, LabelRef> - >, tuple< - // branch - >> (table); + table->AddSequence(OPCODE_BRANCH, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_BRANCH_TRUE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_BRANCH_FALSE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); // -------------------------------------------------------------------------- // Types // -------------------------------------------------------------------------- - // int 8/etc - Translate, ValueRef> - >, tuple< - LIR_MOV_I32, In<0, 0>> - >> (table); + table->AddSequence(OPCODE_ASSIGN, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_CAST, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_ZERO_EXTEND, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SIGN_EXTEND, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_TRUNCATE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_CONVERT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_ROUND, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_CONVERT_I2F, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_CONVERT_F2I, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); // -------------------------------------------------------------------------- // Constants // -------------------------------------------------------------------------- + // specials for zeroing/etc (xor/etc) + + table->AddSequence(OPCODE_LOAD_VECTOR_SHL, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_LOAD_VECTOR_SHR, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + // -------------------------------------------------------------------------- // Context // -------------------------------------------------------------------------- + table->AddSequence(OPCODE_LOAD_CONTEXT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_STORE_CONTEXT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + // -------------------------------------------------------------------------- // Memory // -------------------------------------------------------------------------- + table->AddSequence(OPCODE_LOAD, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_LOAD_ACQUIRE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_STORE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_STORE_RELEASE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_PREFETCH, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + // -------------------------------------------------------------------------- // Comparisons // -------------------------------------------------------------------------- + table->AddSequence(OPCODE_MAX, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_MIN, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SELECT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_IS_TRUE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_IS_FALSE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_EQ, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_NE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_SLT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_SLE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_SGT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_SGE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_ULT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_ULE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_UGT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_COMPARE_UGE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_DID_CARRY, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_DID_OVERFLOW, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_COMPARE_EQ, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_COMPARE_SGT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_COMPARE_SGE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_COMPARE_UGT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_COMPARE_UGE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + // -------------------------------------------------------------------------- // Math // -------------------------------------------------------------------------- + table->AddSequence(OPCODE_ADD, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_ADD_CARRY, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SUB, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_MUL, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_DIV, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_REM, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_MULADD, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_MULSUB, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_NEG, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_ABS, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SQRT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_RSQRT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_DOT_PRODUCT_3, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_DOT_PRODUCT_4, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_AND, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_OR, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_XOR, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_NOT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SHL, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_VECTOR_SHL, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SHR, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SHA, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_ROTATE_LEFT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_BYTE_SWAP, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_CNTLZ, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_INSERT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_EXTRACT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SPLAT, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_PERMUTE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + + table->AddSequence(OPCODE_SWIZZLE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); + // -------------------------------------------------------------------------- // Atomic // -------------------------------------------------------------------------- - // Tests: + table->AddSequence(OPCODE_COMPARE_EXCHANGE, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); - Translate, ValueRef, ValueRef> - >, tuple< - LIR_MOV_I32, In<0, 0>>, - LIR_SUB_I32, In<0, 1>> - >> (table); - Translate, ValueRef, Int32Constant<1>> - >, tuple< - LIR_MOV_I32, In<0, 0>>, - LIR_DEC_I32> - >> (table); + table->AddSequence(OPCODE_ATOMIC_ADD, [](LIRBuilder& lb, Instr*& instr) { + // TODO + instr = instr->next; + return true; + }); - Translate, ValueRef, Constant> - >, tuple< - LIR_IMUL_I32_AUX, In<0, 0>, In<0, 1>> - >> (table); - Translate, ValueRef, ValueRef> - >, tuple< - LIR_MOV_I32, In<0, 0>>, - LIR_IMUL_I32, In<0, 1>> - >> (table); - - Translate, ValueRef, ValueRef> - >, tuple< - LIR_MOV_I32, In<0, 0>>, - LIR_XOR_I32, Reg>, - LIR_DIV_I32>, - LIR_MOV_I32, Reg> - >> (table); - - //Translate, ValueRef, ValueRef>, - // HIR_IS_TRUE, Out<0>> - //>, tuple< - // LIR_MOV_I32, In<0, 0>>, - // LIR_SUB_I32, In<0, 1>>, - // LIR_EFLAGS_NOT_ZF> - //>> (table); + table->AddSequence(OPCODE_ATOMIC_SUB, [](LIRBuilder& lb, Instr*& instr) { + // TODO + 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 fa52ac8b0..5c874fa70 100644 --- a/src/alloy/backend/x64/lowering/lowering_table.cc +++ b/src/alloy/backend/x64/lowering/lowering_table.cc @@ -23,11 +23,11 @@ LoweringTable::LoweringTable(X64Backend* backend) : LoweringTable::~LoweringTable() { for (size_t n = 0; n < XECOUNT(lookup_); n++) { - auto fn = lookup_[n]; - while (fn) { - auto next = fn->next; - delete fn; - fn = next; + auto entry = lookup_[n]; + while (entry) { + auto next = entry->next; + delete entry; + entry = next; } } } @@ -37,10 +37,12 @@ int LoweringTable::Initialize() { return 0; } -void LoweringTable::AddSequence(hir::Opcode starting_opcode, FnWrapper* fn) { - auto existing_fn = lookup_[starting_opcode]; - fn->next = existing_fn; - lookup_[starting_opcode] = fn; +void LoweringTable::AddSequence(hir::Opcode starting_opcode, sequence_fn_t fn) { + auto existing_entry = lookup_[starting_opcode]; + auto new_entry = new sequence_fn_entry_t(); + new_entry->fn = fn; + new_entry->next = existing_entry; + lookup_[starting_opcode] = new_entry; } int LoweringTable::Process( @@ -78,13 +80,13 @@ int LoweringTable::Process( auto hir_instr = hir_block->instr_head; while (hir_instr) { bool processed = false; - auto fn = lookup_[hir_instr->opcode->num]; - while (fn) { - if ((*fn)(lir_builder, hir_instr)) { + auto entry = lookup_[hir_instr->opcode->num]; + while (entry) { + if ((*entry->fn)(*lir_builder, hir_instr)) { processed = true; break; } - fn = fn->next; + entry = entry->next; } if (!processed) { // No sequence found! diff --git a/src/alloy/backend/x64/lowering/lowering_table.h b/src/alloy/backend/x64/lowering/lowering_table.h index 821beed1a..33c2ca90e 100644 --- a/src/alloy/backend/x64/lowering/lowering_table.h +++ b/src/alloy/backend/x64/lowering/lowering_table.h @@ -33,28 +33,18 @@ public: int Process(hir::HIRBuilder* hir_builder, lir::LIRBuilder* lir_builder); public: - class FnWrapper { - public: - FnWrapper() : next(0) {} - virtual bool operator()(lir::LIRBuilder* builder, hir::Instr*& instr) const = 0; - FnWrapper* next; - }; - template - class TypedFnWrapper : public FnWrapper { - public: - TypedFnWrapper(T fn) : fn_(fn) {} - virtual bool operator()(lir::LIRBuilder* builder, hir::Instr*& instr) const { - return fn_(builder, instr); - } - private: - T fn_; - }; - - void AddSequence(hir::Opcode starting_opcode, FnWrapper* fn); + typedef bool(*sequence_fn_t)(lir::LIRBuilder& lb, hir::Instr*& instr); + void AddSequence(hir::Opcode starting_opcode, sequence_fn_t fn); private: + class sequence_fn_entry_t { + public: + sequence_fn_t fn; + sequence_fn_entry_t* next; + }; + X64Backend* backend_; - FnWrapper* lookup_[hir::__OPCODE_MAX_VALUE]; + sequence_fn_entry_t* lookup_[hir::__OPCODE_MAX_VALUE]; }; diff --git a/src/alloy/backend/x64/lowering/sources.gypi b/src/alloy/backend/x64/lowering/sources.gypi index f404ccba8..5c710cfcc 100644 --- a/src/alloy/backend/x64/lowering/sources.gypi +++ b/src/alloy/backend/x64/lowering/sources.gypi @@ -1,8 +1,6 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ - 'lowering_hir_opcodes.inl', - 'lowering_lir_opcodes.inl', 'lowering_sequences.cc', 'lowering_sequences.h', 'lowering_table.cc', diff --git a/src/alloy/backend/x64/x64_assembler.cc b/src/alloy/backend/x64/x64_assembler.cc index 6ebdd1abd..aa76dad27 100644 --- a/src/alloy/backend/x64/x64_assembler.cc +++ b/src/alloy/backend/x64/x64_assembler.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,10 @@ #include #include +namespace BE { +#include +} + using namespace alloy; using namespace alloy::backend; using namespace alloy::backend::x64; @@ -31,8 +36,9 @@ using namespace alloy::runtime; X64Assembler::X64Assembler(X64Backend* backend) : x64_backend_(backend), - optimizer_(0), builder_(0), + optimizer_(0), + emitter_(0), Assembler(backend) { } @@ -40,6 +46,7 @@ X64Assembler::~X64Assembler() { alloy::tracing::WriteEvent(EventType::AssemblerDeinit({ })); + delete emitter_; delete optimizer_; delete builder_; } @@ -50,10 +57,12 @@ int X64Assembler::Initialize() { return result; } + builder_ = new LIRBuilder(x64_backend_); + optimizer_ = new Optimizer(backend_->runtime()); optimizer_->AddPass(new passes::RedundantMovPass()); - builder_ = new LIRBuilder(x64_backend_); + emitter_ = new X64Emitter(x64_backend_); alloy::tracing::WriteEvent(EventType::AssemblerInit({ })); @@ -64,6 +73,7 @@ int X64Assembler::Initialize() { void X64Assembler::Reset() { builder_->Reset(); optimizer_->Reset(); + emitter_->Reset(); string_buffer_.Reset(); Assembler::Reset(); } @@ -103,7 +113,7 @@ int X64Assembler::Assemble( // Stash generated machine code. if (debug_info) { - //emitter_->Dump(&string_buffer_); + DumpMachineCode(&string_buffer_); debug_info->set_machine_code_disasm(string_buffer_.ToString()); string_buffer_.Reset(); } @@ -121,3 +131,20 @@ XECLEANUP: Reset(); return result; } + +void X64Assembler::DumpMachineCode(StringBuffer* str) { + BE::DISASM disasm; + xe_zero_struct(&disasm, sizeof(disasm)); + disasm.Archi = 64; + disasm.Options = BE::Tabulation + BE::MasmSyntax + BE::PrefixedNumeral; + disasm.EIP = 0;// (BE::UIntPtr)assembler_.getCode(); + BE::UIntPtr eip_end = 0;// assembler_.getCode() + assembler_.getCodeSize(); + while (disasm.EIP < eip_end) { + size_t len = BE::Disasm(&disasm); + if (len == BE::UNKNOWN_OPCODE) { + break; + } + str->Append("%p %s", disasm.EIP, disasm.CompleteInstr); + disasm.EIP += len; + } +} diff --git a/src/alloy/backend/x64/x64_assembler.h b/src/alloy/backend/x64/x64_assembler.h index 7a19dc438..456caa5d9 100644 --- a/src/alloy/backend/x64/x64_assembler.h +++ b/src/alloy/backend/x64/x64_assembler.h @@ -20,6 +20,7 @@ namespace backend { namespace x64 { class X64Backend; +class X64Emitter; namespace lir { class LIRBuilder; } namespace optimizer { class Optimizer; } @@ -37,10 +38,14 @@ public: runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, runtime::DebugInfo* debug_info, runtime::Function** out_function); +private: + void DumpMachineCode(StringBuffer* str); + private: X64Backend* x64_backend_; lir::LIRBuilder* builder_; optimizer::Optimizer* optimizer_; + X64Emitter* emitter_; StringBuffer string_buffer_; }; diff --git a/src/alloy/backend/x64/x64_backend.cc b/src/alloy/backend/x64/x64_backend.cc index 0b2b10879..947626497 100644 --- a/src/alloy/backend/x64/x64_backend.cc +++ b/src/alloy/backend/x64/x64_backend.cc @@ -12,6 +12,7 @@ #include #include #include +#include using namespace alloy; using namespace alloy::backend; @@ -38,6 +39,7 @@ int X64Backend::Initialize() { } lowering_table_ = new LoweringTable(this); + RegisterSequences(lowering_table_); alloy::tracing::WriteEvent(EventType::Init({ })); diff --git a/src/alloy/backend/x64/x64_emitter.h b/src/alloy/backend/x64/x64_emitter.h index ea38efaf3..ea082513f 100644 --- a/src/alloy/backend/x64/x64_emitter.h +++ b/src/alloy/backend/x64/x64_emitter.h @@ -29,8 +29,6 @@ public: void Reset(); - // - private: X64Backend* backend_; }; diff --git a/src/alloy/hir/hir_builder.cc b/src/alloy/hir/hir_builder.cc index 5b2032012..04a02eb04 100644 --- a/src/alloy/hir/hir_builder.cc +++ b/src/alloy/hir/hir_builder.cc @@ -162,7 +162,7 @@ void HIRBuilder::Dump(StringBuffer* str) { i = i->next; continue; } - if (i->opcode->num == OPCODE_COMMENT) { + if (i->opcode == &OPCODE_COMMENT_info) { str->Append(" ; %s\n", (char*)i->src1.offset); i = i->next; continue; @@ -222,6 +222,7 @@ Label* HIRBuilder::NewLabel() { label->block = NULL; label->id = next_label_id_++; label->name = NULL; + label->tag = NULL; return label; } diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index 365514c7f..65fa531b9 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -66,7 +66,6 @@ enum Swizzles { enum Opcode { OPCODE_COMMENT, - OPCODE_NOP, OPCODE_SOURCE_OFFSET, diff --git a/src/xenia/debug/protocols/ws/ws_client.cc b/src/xenia/debug/protocols/ws/ws_client.cc index e4fe21e16..80ce8be00 100644 --- a/src/xenia/debug/protocols/ws/ws_client.cc +++ b/src/xenia/debug/protocols/ws/ws_client.cc @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include diff --git a/third_party/beaengine.gypi b/third_party/beaengine.gypi index e612fe8a0..4b310fc5c 100644 --- a/third_party/beaengine.gypi +++ b/third_party/beaengine.gypi @@ -16,11 +16,15 @@ 'sources': [ 'beaengine/beaengineSources/BeaEngine.c', + 'beaengine/include/beaengine/basic_types.h', + 'beaengine/include/beaengine/BeaEngine.h', + 'beaengine/include/beaengine/export.h', + 'beaengine/include/beaengine/macros.h', ], 'include_dirs': [ - 'beaengine/include/', 'beaengine/beaengineSources/', + 'beaengine/include/', ], 'defines': [ diff --git a/xenia.gyp b/xenia.gyp index 742035032..d87135257 100644 --- a/xenia.gyp +++ b/xenia.gyp @@ -185,9 +185,11 @@ 'type': 'static_library', 'dependencies': [ + 'beaengine', 'gflags', ], 'export_dependent_settings': [ + 'beaengine', 'gflags', ], @@ -246,14 +248,12 @@ 'type': 'static_library', 'dependencies': [ - 'beaengine', 'gflags', 'jansson', 'wslay', 'alloy', ], 'export_dependent_settings': [ - 'beaengine', 'gflags', 'jansson', 'wslay',