Ugh. Replacing the fancy templates with hand coded sequences for now.
This commit is contained in:
parent
3e4f93a6a9
commit
125e7278c6
|
@ -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<LIRLabel>();
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <alloy/backend/x64/lir/lir_instr.h>
|
||||
#include <alloy/backend/x64/lir/lir_label.h>
|
||||
#include <alloy/backend/x64/lir/lir_opcodes.h>
|
||||
#include <alloy/hir/value.h>
|
||||
|
||||
|
||||
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_;
|
||||
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
|
||||
uint32_t id;
|
||||
char* name;
|
||||
bool local;
|
||||
|
||||
void* tag;
|
||||
};
|
||||
|
|
|
@ -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 <alloy/backend/x64/lir/lir_opcodes.inl>
|
||||
#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 <alloy/backend/x64/lir/lir_opcodes.inl>
|
||||
#undef DEFINE_OPCODE
|
||||
};
|
||||
return *lookup[opcode];
|
||||
}
|
||||
|
||||
} // namespace lir
|
||||
} // namespace x64
|
||||
} // namespace backend
|
||||
|
|
|
@ -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 <alloy/backend/x64/lir/lir_opcodes.inl>
|
||||
#undef DEFINE_OPCODE
|
||||
|
||||
extern const LIROpcodeInfo& GetOpcodeInfo(LIROpcode opcode);
|
||||
|
||||
|
||||
} // namespace lir
|
||||
} // namespace x64
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
|
@ -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);
|
File diff suppressed because it is too large
Load Diff
|
@ -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!
|
||||
|
|
|
@ -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<typename T>
|
||||
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];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <alloy/backend/x64/tracing.h>
|
||||
#include <alloy/backend/x64/x64_backend.h>
|
||||
#include <alloy/backend/x64/x64_emitter.h>
|
||||
#include <alloy/backend/x64/x64_function.h>
|
||||
#include <alloy/backend/x64/lir/lir_builder.h>
|
||||
#include <alloy/backend/x64/lowering/lowering_table.h>
|
||||
|
@ -20,6 +21,10 @@
|
|||
#include <alloy/hir/label.h>
|
||||
#include <alloy/runtime/runtime.h>
|
||||
|
||||
namespace BE {
|
||||
#include <beaengine/BeaEngine.h>
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <alloy/backend/x64/tracing.h>
|
||||
#include <alloy/backend/x64/x64_assembler.h>
|
||||
#include <alloy/backend/x64/lowering/lowering_table.h>
|
||||
#include <alloy/backend/x64/lowering/lowering_sequences.h>
|
||||
|
||||
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({
|
||||
}));
|
||||
|
|
|
@ -29,8 +29,6 @@ public:
|
|||
|
||||
void Reset();
|
||||
|
||||
//
|
||||
|
||||
private:
|
||||
X64Backend* backend_;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ enum Swizzles {
|
|||
|
||||
enum Opcode {
|
||||
OPCODE_COMMENT,
|
||||
|
||||
OPCODE_NOP,
|
||||
|
||||
OPCODE_SOURCE_OFFSET,
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <third_party/jansson/src/jansson.h>
|
||||
#include <jansson.h>
|
||||
|
||||
#include <xenia/emulator.h>
|
||||
#include <xenia/debug/debug_server.h>
|
||||
|
|
|
@ -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': [
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue