Ugh. Replacing the fancy templates with hand coded sequences for now.
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user