diff --git a/src/alloy/compiler/compiler.cc b/src/alloy/compiler/compiler.cc index da1a2e76e..062f0150e 100644 --- a/src/alloy/compiler/compiler.cc +++ b/src/alloy/compiler/compiler.cc @@ -15,9 +15,11 @@ using namespace alloy; using namespace alloy::compiler; using namespace alloy::hir; +using namespace alloy::runtime; -Compiler::Compiler() { +Compiler::Compiler(Runtime* runtime) : + runtime_(runtime) { alloy::tracing::WriteEvent(EventType::Init({ })); } @@ -35,6 +37,7 @@ Compiler::~Compiler() { } void Compiler::AddPass(Pass* pass) { + pass->Initialize(this); passes_.push_back(pass); } diff --git a/src/alloy/compiler/compiler.h b/src/alloy/compiler/compiler.h index d4f45c86d..f1c9733f8 100644 --- a/src/alloy/compiler/compiler.h +++ b/src/alloy/compiler/compiler.h @@ -13,6 +13,8 @@ #include #include +namespace alloy { namespace runtime { class Runtime; } } + namespace alloy { namespace compiler { @@ -22,8 +24,10 @@ class Pass; class Compiler { public: - Compiler(); + Compiler(runtime::Runtime* runtime); ~Compiler(); + + runtime::Runtime* runtime() const { return runtime_; } void AddPass(Pass* pass); @@ -32,6 +36,8 @@ public: int Compile(hir::FunctionBuilder* builder); private: + runtime::Runtime* runtime_; + typedef std::vector PassList; PassList passes_; }; diff --git a/src/alloy/compiler/pass.cc b/src/alloy/compiler/pass.cc index 2920bf002..5e671c49d 100644 --- a/src/alloy/compiler/pass.cc +++ b/src/alloy/compiler/pass.cc @@ -9,12 +9,21 @@ #include +#include + using namespace alloy; using namespace alloy::compiler; -Pass::Pass() { +Pass::Pass() : + runtime_(0), compiler_(0) { } Pass::~Pass() { } + +int Pass::Initialize(Compiler* compiler) { + runtime_ = compiler->runtime(); + compiler_ = compiler; + return 0; +} diff --git a/src/alloy/compiler/pass.h b/src/alloy/compiler/pass.h index 5d020e93c..a326ec79b 100644 --- a/src/alloy/compiler/pass.h +++ b/src/alloy/compiler/pass.h @@ -14,17 +14,27 @@ #include +namespace alloy { namespace runtime { class Runtime; } } + namespace alloy { namespace compiler { +class Compiler; + class Pass { public: Pass(); virtual ~Pass(); + virtual int Initialize(Compiler* compiler); + virtual int Run(hir::FunctionBuilder* builder) = 0; + +protected: + runtime::Runtime* runtime_; + Compiler* compiler_; }; diff --git a/src/alloy/compiler/passes.h b/src/alloy/compiler/passes.h index bb35604ef..2dd1672d5 100644 --- a/src/alloy/compiler/passes.h +++ b/src/alloy/compiler/passes.h @@ -11,7 +11,7 @@ #define ALLOY_COMPILER_PASSES_H_ //#include -//#include +#include #include //#include #include diff --git a/src/alloy/compiler/passes/context_promotion_pass.cc b/src/alloy/compiler/passes/context_promotion_pass.cc new file mode 100644 index 000000000..dffe465f1 --- /dev/null +++ b/src/alloy/compiler/passes/context_promotion_pass.cc @@ -0,0 +1,109 @@ +/** + ****************************************************************************** + * 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::compiler; +using namespace alloy::compiler::passes; +using namespace alloy::frontend; +using namespace alloy::hir; +using namespace alloy::runtime; + + +ContextPromotionPass::ContextPromotionPass() : + context_values_size_(0), context_values_(0), + Pass() { +} + +ContextPromotionPass::~ContextPromotionPass() { + if (context_values_) { + xe_free(context_values_); + } +} + +int ContextPromotionPass::Initialize(Compiler* compiler) { + if (Pass::Initialize(compiler)) { + return 1; + } + + // This is a terrible implementation. + ContextInfo* context_info = runtime_->frontend()->context_info(); + context_values_size_ = context_info->size() * sizeof(Value*); + context_values_ = (Value**)xe_calloc(context_values_size_); + + return 0; +} + +int ContextPromotionPass::Run(FunctionBuilder* builder) { + // Like mem2reg, but because context memory is unaliasable it's easier to + // check and convert LoadContext/StoreContext into value operations. + // Example of load->value promotion: + // v0 = load_context +100 + // store_context +200, v0 + // v1 = load_context +100 <-- replace with v1 = v0 + // store_context +200, v1 + // + // It'd be possible in this stage to also remove redundant context stores: + // Example of dead store elimination: + // store_context +100, v0 <-- removed due to following store + // store_context +100, v1 + // This is more generally done by DSE, however if it could be done here + // instead as it may be faster (at least on the block-level). + + // Process each block independently, for now. + Block* block = builder->first_block(); + while (block) { + PromoteBlock(block); + block = block->next; + } + + return 0; +} + +void ContextPromotionPass::PromoteBlock(Block* block) { + // Clear the context values list. + // TODO(benvanik): new data structure that isn't so stupid. + // Bitvector of validity, perhaps? + xe_zero_struct(context_values_, context_values_size_); + + Instr* i = block->instr_head; + while (i) { + if (i->opcode == &OPCODE_LOAD_CONTEXT_info) { + size_t offset = i->src1.offset; + Value* previous_value = context_values_[offset]; + if (previous_value) { + // Legit previous value, reuse. + i->opcode = &hir::OPCODE_ASSIGN_info; + i->set_src1(previous_value); + } else { + // Store the loaded value into the table. + context_values_[offset] = i->dest; + } + } else if (i->opcode == &OPCODE_STORE_CONTEXT_info) { + size_t offset = i->src1.offset; + Value* value = i->src2.value; + Value* previous_value = context_values_[offset]; + if (previous_value && + previous_value->def && + previous_value->def->opcode == &OPCODE_STORE_CONTEXT_info) { + // Legit previous value from a useless store. + // Remove the store entirely. + previous_value->def->Remove(); + } + // Store value into the table for later. + context_values_[offset] = value; + } + + i = i->next; + } +} diff --git a/src/alloy/compiler/passes/context_promotion_pass.h b/src/alloy/compiler/passes/context_promotion_pass.h new file mode 100644 index 000000000..4a8211246 --- /dev/null +++ b/src/alloy/compiler/passes/context_promotion_pass.h @@ -0,0 +1,44 @@ +/** + ****************************************************************************** + * 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_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_ +#define ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_ + +#include + + +namespace alloy { +namespace compiler { +namespace passes { + + +class ContextPromotionPass : public Pass { +public: + ContextPromotionPass(); + virtual ~ContextPromotionPass(); + + virtual int Initialize(Compiler* compiler); + + virtual int Run(hir::FunctionBuilder* builder); + +private: + void PromoteBlock(hir::Block* block); + +private: + size_t context_values_size_; + hir::Value** context_values_; +}; + + +} // namespace passes +} // namespace compiler +} // namespace alloy + + +#endif // ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_ diff --git a/src/alloy/compiler/passes/dead_code_elimination_pass.cc b/src/alloy/compiler/passes/dead_code_elimination_pass.cc index 674234bce..cc76b7f41 100644 --- a/src/alloy/compiler/passes/dead_code_elimination_pass.cc +++ b/src/alloy/compiler/passes/dead_code_elimination_pass.cc @@ -53,8 +53,6 @@ int DeadCodeEliminationPass::Run(FunctionBuilder* builder) { // all removed ops with NOP and then do a single pass that removes them // all. - const OpcodeInfo* nop = builder->GetNopOpcode(); - bool any_removed = false; Block* block = builder->first_block(); while (block) { @@ -67,7 +65,7 @@ int DeadCodeEliminationPass::Run(FunctionBuilder* builder) { if (!(opcode->flags & OPCODE_FLAG_VOLATILE) && i->dest && !i->dest->use_head) { // Has no uses and is not volatile. This instruction can die! - MakeNopRecursive(nop, i); + MakeNopRecursive(i); any_removed = true; } @@ -84,7 +82,7 @@ int DeadCodeEliminationPass::Run(FunctionBuilder* builder) { Instr* i = block->instr_head; while (i) { Instr* next = i->next; - if (i->opcode->num == OPCODE_NOP) { + if (i->opcode == &OPCODE_NOP_info) { // Nop - remove! i->Remove(); } @@ -97,9 +95,8 @@ int DeadCodeEliminationPass::Run(FunctionBuilder* builder) { return 0; } -void DeadCodeEliminationPass::MakeNopRecursive( - const OpcodeInfo* nop, Instr* i) { - i->opcode = nop; +void DeadCodeEliminationPass::MakeNopRecursive(Instr* i) { + i->opcode = &hir::OPCODE_NOP_info; i->dest->def = NULL; i->dest = NULL; @@ -113,7 +110,7 @@ void DeadCodeEliminationPass::MakeNopRecursive( if (!value->use_head) { \ /* Value is now unused, so recursively kill it. */ \ if (value->def && value->def != i) { \ - MakeNopRecursive(nop, value->def); \ + MakeNopRecursive(value->def); \ } \ } \ } diff --git a/src/alloy/compiler/passes/dead_code_elimination_pass.h b/src/alloy/compiler/passes/dead_code_elimination_pass.h index 5ce5156bd..7b363bf2e 100644 --- a/src/alloy/compiler/passes/dead_code_elimination_pass.h +++ b/src/alloy/compiler/passes/dead_code_elimination_pass.h @@ -26,7 +26,7 @@ public: virtual int Run(hir::FunctionBuilder* builder); private: - void MakeNopRecursive(const hir::OpcodeInfo* nop, hir::Instr* i); + void MakeNopRecursive(hir::Instr* i); }; diff --git a/src/alloy/compiler/passes/simplification_pass.cc b/src/alloy/compiler/passes/simplification_pass.cc index 3b8fe2e7c..9cce48476 100644 --- a/src/alloy/compiler/passes/simplification_pass.cc +++ b/src/alloy/compiler/passes/simplification_pass.cc @@ -65,13 +65,13 @@ int SimplificationPass::Run(FunctionBuilder* builder) { Value* SimplificationPass::CheckValue(Value* value) { Instr* def = value->def; - if (def && def->opcode->num == OPCODE_ASSIGN) { + if (def && def->opcode == &OPCODE_ASSIGN_info) { // Value comes from an assignment - recursively find if it comes from // another assignment. It probably doesn't, if we already replaced it. Value* replacement = def->src1.value; while (true) { def = replacement->def; - if (!def || def->opcode->num != OPCODE_ASSIGN) { + if (!def || def->opcode != &OPCODE_ASSIGN_info) { break; } replacement = def->src1.value; diff --git a/src/alloy/compiler/passes/sources.gypi b/src/alloy/compiler/passes/sources.gypi index 3fa9e27a9..516c90b28 100644 --- a/src/alloy/compiler/passes/sources.gypi +++ b/src/alloy/compiler/passes/sources.gypi @@ -3,8 +3,8 @@ 'sources': [ #'constant_propagation_pass.cc', #'constant_propagation_pass.h', - #'context_promotion_pass.cc', - #'context_promotion_pass.h', + 'context_promotion_pass.cc', + 'context_promotion_pass.h', 'dead_code_elimination_pass.cc', 'dead_code_elimination_pass.h', #'dead_store_elimination_pass.cc', diff --git a/src/alloy/frontend/context_info.cc b/src/alloy/frontend/context_info.cc new file mode 100644 index 000000000..a90888d17 --- /dev/null +++ b/src/alloy/frontend/context_info.cc @@ -0,0 +1,21 @@ +/** + ****************************************************************************** + * 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::frontend; + + +ContextInfo::ContextInfo(size_t size) : + size_(size) { +} + +ContextInfo::~ContextInfo() { +} diff --git a/src/alloy/frontend/context_info.h b/src/alloy/frontend/context_info.h new file mode 100644 index 000000000..04b00b012 --- /dev/null +++ b/src/alloy/frontend/context_info.h @@ -0,0 +1,36 @@ +/** + ****************************************************************************** + * 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_FRONTEND_CONTEXT_INFO_H_ +#define ALLOY_FRONTEND_CONTEXT_INFO_H_ + +#include + + +namespace alloy { +namespace frontend { + + +class ContextInfo { +public: + ContextInfo(size_t size); + ~ContextInfo(); + + size_t size() const { return size_; } + +private: + size_t size_; +}; + + +} // namespace frontend +} // namespace alloy + + +#endif // ALLOY_FRONTEND_CONTEXT_INFO_H_ diff --git a/src/alloy/frontend/frontend.cc b/src/alloy/frontend/frontend.cc index 30c480a0a..68ad147ef 100644 --- a/src/alloy/frontend/frontend.cc +++ b/src/alloy/frontend/frontend.cc @@ -18,10 +18,11 @@ using namespace alloy::runtime; Frontend::Frontend(Runtime* runtime) : - runtime_(runtime) { + runtime_(runtime), context_info_(0) { } Frontend::~Frontend() { + delete context_info_; } Memory* Frontend::memory() const { diff --git a/src/alloy/frontend/frontend.h b/src/alloy/frontend/frontend.h index 8e5cd1e5a..4de31e222 100644 --- a/src/alloy/frontend/frontend.h +++ b/src/alloy/frontend/frontend.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -31,6 +32,7 @@ public: runtime::Runtime* runtime() const { return runtime_; } Memory* memory() const; + ContextInfo* context_info() const { return context_info_; } virtual int Initialize(); @@ -42,6 +44,7 @@ public: protected: runtime::Runtime* runtime_; + ContextInfo* context_info_; }; diff --git a/src/alloy/frontend/ppc/ppc_frontend.cc b/src/alloy/frontend/ppc/ppc_frontend.cc index 2e587865f..2a01e82a2 100644 --- a/src/alloy/frontend/ppc/ppc_frontend.cc +++ b/src/alloy/frontend/ppc/ppc_frontend.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,10 @@ namespace { PPCFrontend::PPCFrontend(Runtime* runtime) : Frontend(runtime) { InitializeIfNeeded(); + + ContextInfo* info = new ContextInfo(sizeof(PPCContext)); + // Add fields/etc. + context_info_ = info; } PPCFrontend::~PPCFrontend() { diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index 94de30a69..f109b9bda 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -30,9 +30,9 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : scanner_ = new PPCScanner(frontend); builder_ = new PPCFunctionBuilder(frontend); - compiler_ = new Compiler(); + compiler_ = new Compiler(frontend->runtime()); - //compiler_->AddPass(new passes::ContextPromotionPass()); + compiler_->AddPass(new passes::ContextPromotionPass()); //compiler_->AddPass(new passes::ConstantPropagationPass()); //compiler_->AddPass(new passes::TypePropagationPass()); //compiler_->AddPass(new passes::ByteSwapEliminationPass()); diff --git a/src/alloy/frontend/sources.gypi b/src/alloy/frontend/sources.gypi index bfd855ad1..d0d63ab49 100644 --- a/src/alloy/frontend/sources.gypi +++ b/src/alloy/frontend/sources.gypi @@ -1,6 +1,8 @@ # Copyright 2013 Ben Vanik. All Rights Reserved. { 'sources': [ + 'context_info.cc', + 'context_info.h', 'frontend.cc', 'frontend.h', 'tracing.h', diff --git a/src/alloy/hir/function_builder.cc b/src/alloy/hir/function_builder.cc index 98fd23ad5..118c42e41 100644 --- a/src/alloy/hir/function_builder.cc +++ b/src/alloy/hir/function_builder.cc @@ -348,15 +348,7 @@ Value* FunctionBuilder::CloneValue(Value* source) { return value; } -#define STATIC_OPCODE(num, name, sig, flags) \ - static const OpcodeInfo opcode = { flags, sig, name, num, }; - void FunctionBuilder::Comment(const char* format, ...) { - STATIC_OPCODE( - OPCODE_COMMENT, - "comment", - OPCODE_SIG_X, - OPCODE_FLAG_IGNORE); char buffer[1024]; va_list args; @@ -369,80 +361,47 @@ void FunctionBuilder::Comment(const char* format, ...) { } void* p = arena_->Alloc(len + 1); xe_copy_struct(p, buffer, len + 1); - Instr* i = AppendInstr(opcode, 0); + Instr* i = AppendInstr(OPCODE_COMMENT_info, 0); i->src1.offset = (uint64_t)p; i->src2.value = i->src3.value = NULL; } -const OpcodeInfo* FunctionBuilder::GetNopOpcode() const { - STATIC_OPCODE( - OPCODE_NOP, - "nop", - OPCODE_SIG_X, - OPCODE_FLAG_IGNORE); - return &opcode; -} - void FunctionBuilder::Nop() { - Instr* i = AppendInstr(*GetNopOpcode(), 0); + Instr* i = AppendInstr(OPCODE_NOP_info, 0); i->src1.value = i->src2.value = i->src3.value = NULL; } void FunctionBuilder::DebugBreak() { - STATIC_OPCODE( - OPCODE_DEBUG_BREAK, - "debug_break", - OPCODE_SIG_X, - OPCODE_FLAG_VOLATILE); - - Instr* i = AppendInstr(opcode, 0); + Instr* i = AppendInstr(OPCODE_DEBUG_BREAK_info, 0); i->src1.value = i->src2.value = i->src3.value = NULL; EndBlock(); } void FunctionBuilder::DebugBreakTrue(Value* cond) { - STATIC_OPCODE( - OPCODE_DEBUG_BREAK_TRUE, - "debug_break_true", - OPCODE_SIG_X_V, - OPCODE_FLAG_VOLATILE); - if (cond->IsConstantTrue()) { DebugBreak(); return; } - Instr* i = AppendInstr(opcode, 0); + Instr* i = AppendInstr(OPCODE_DEBUG_BREAK_TRUE_info, 0); i->set_src1(cond); i->src2.value = i->src3.value = NULL; EndBlock(); } void FunctionBuilder::Trap() { - STATIC_OPCODE( - OPCODE_TRAP, - "trap", - OPCODE_SIG_X, - OPCODE_FLAG_VOLATILE); - - Instr* i = AppendInstr(opcode, 0); + Instr* i = AppendInstr(OPCODE_TRAP_info, 0); i->src1.value = i->src2.value = i->src3.value = NULL; EndBlock(); } void FunctionBuilder::TrapTrue(Value* cond) { - STATIC_OPCODE( - OPCODE_TRAP_TRUE, - "trap_true", - OPCODE_SIG_X_V, - OPCODE_FLAG_VOLATILE); - if (cond->IsConstantTrue()) { Trap(); return; } - Instr* i = AppendInstr(opcode, 0); + Instr* i = AppendInstr(OPCODE_TRAP_TRUE_info, 0); i->set_src1(cond); i->src2.value = i->src3.value = NULL; EndBlock(); @@ -450,13 +409,7 @@ void FunctionBuilder::TrapTrue(Value* cond) { void FunctionBuilder::Call( FunctionInfo* symbol_info, uint32_t call_flags) { - STATIC_OPCODE( - OPCODE_CALL, - "call", - OPCODE_SIG_X_S, - OPCODE_FLAG_BRANCH); - - Instr* i = AppendInstr(opcode, call_flags); + Instr* i = AppendInstr(OPCODE_CALL_info, call_flags); i->src1.symbol_info = symbol_info; i->src2.value = i->src3.value = NULL; EndBlock(); @@ -464,18 +417,12 @@ void FunctionBuilder::Call( void FunctionBuilder::CallTrue( Value* cond, FunctionInfo* symbol_info, uint32_t call_flags) { - STATIC_OPCODE( - OPCODE_CALL_TRUE, - "call_true", - OPCODE_SIG_X_V_S, - OPCODE_FLAG_BRANCH); - if (cond->IsConstantTrue()) { Call(symbol_info, call_flags); return; } - Instr* i = AppendInstr(opcode, call_flags); + Instr* i = AppendInstr(OPCODE_CALL_TRUE_info, call_flags); i->set_src1(cond); i->src2.symbol_info = symbol_info; i->src3.value = NULL; @@ -484,14 +431,8 @@ void FunctionBuilder::CallTrue( void FunctionBuilder::CallIndirect( Value* value, uint32_t call_flags) { - STATIC_OPCODE( - OPCODE_CALL_INDIRECT, - "call_indirect", - OPCODE_SIG_X_V, - OPCODE_FLAG_BRANCH); - ASSERT_ADDRESS_TYPE(value); - Instr* i = AppendInstr(opcode, call_flags); + Instr* i = AppendInstr(OPCODE_CALL_INDIRECT_info, call_flags); i->set_src1(value); i->src2.value = i->src3.value = NULL; EndBlock(); @@ -499,19 +440,13 @@ void FunctionBuilder::CallIndirect( void FunctionBuilder::CallIndirectTrue( Value* cond, Value* value, uint32_t call_flags) { - STATIC_OPCODE( - OPCODE_CALL_INDIRECT_TRUE, - "call_indirect_true", - OPCODE_SIG_X_V_V, - OPCODE_FLAG_BRANCH); - if (cond->IsConstantTrue()) { CallIndirect(value, call_flags); return; } ASSERT_ADDRESS_TYPE(value); - Instr* i = AppendInstr(opcode, call_flags); + Instr* i = AppendInstr(OPCODE_CALL_INDIRECT_TRUE_info, call_flags); i->set_src1(cond); i->set_src2(value); i->src3.value = NULL; @@ -519,38 +454,21 @@ void FunctionBuilder::CallIndirectTrue( } void FunctionBuilder::Return() { - STATIC_OPCODE( - OPCODE_RETURN, - "return", - OPCODE_SIG_X, - OPCODE_FLAG_BRANCH); - - Instr* i = AppendInstr(opcode, 0); + Instr* i = AppendInstr(OPCODE_RETURN_info, 0); i->src1.value = i->src2.value = i->src3.value = NULL; EndBlock(); } void FunctionBuilder::Branch(Label* label, uint32_t branch_flags) { - STATIC_OPCODE( - OPCODE_BRANCH, - "branch", - OPCODE_SIG_X_L, - OPCODE_FLAG_BRANCH); - - Instr* i = AppendInstr(opcode, branch_flags); + Instr* i = AppendInstr(OPCODE_BRANCH_info, branch_flags); i->src1.label = label; i->src2.value = i->src3.value = NULL; EndBlock(); } void FunctionBuilder::BranchIf( - Value* cond, Label* true_label, Label* false_label, uint32_t branch_flags) { - STATIC_OPCODE( - OPCODE_BRANCH_IF, - "branch_if", - OPCODE_SIG_X_V_L_L, - OPCODE_FLAG_BRANCH); - + Value* cond, Label* true_label, Label* false_label, + uint32_t branch_flags) { if (cond->IsConstantTrue()) { Branch(true_label, branch_flags); return; @@ -559,7 +477,7 @@ void FunctionBuilder::BranchIf( return; } - Instr* i = AppendInstr(opcode, branch_flags); + Instr* i = AppendInstr(OPCODE_BRANCH_IF_info, branch_flags); i->set_src1(cond); i->src2.label = true_label; i->src3.label = false_label; @@ -568,18 +486,12 @@ void FunctionBuilder::BranchIf( void FunctionBuilder::BranchTrue( Value* cond, Label* label, uint32_t branch_flags) { - STATIC_OPCODE( - OPCODE_BRANCH_TRUE, - "branch_true", - OPCODE_SIG_X_V_L, - OPCODE_FLAG_BRANCH); - if (cond->IsConstantTrue()) { Branch(label, branch_flags); return; } - Instr* i = AppendInstr(opcode, branch_flags); + Instr* i = AppendInstr(OPCODE_BRANCH_TRUE_info, branch_flags); i->set_src1(cond); i->src2.label = label; i->src3.value = NULL; @@ -588,18 +500,12 @@ void FunctionBuilder::BranchTrue( void FunctionBuilder::BranchFalse( Value* cond, Label* label, uint32_t branch_flags) { - STATIC_OPCODE( - OPCODE_BRANCH_FALSE, - "branch_false", - OPCODE_SIG_X_V_L, - OPCODE_FLAG_BRANCH); - if (cond->IsConstantFalse()) { Branch(label, branch_flags); return; } - Instr* i = AppendInstr(opcode, branch_flags); + Instr* i = AppendInstr(OPCODE_BRANCH_FALSE_info, branch_flags); i->set_src1(cond); i->src2.label = label; i->src3.value = NULL; @@ -609,18 +515,12 @@ void FunctionBuilder::BranchFalse( // phi type_name, Block* b1, Value* v1, Block* b2, Value* v2, etc Value* FunctionBuilder::Assign(Value* value) { - STATIC_OPCODE( - OPCODE_ASSIGN, - "assign", - OPCODE_SIG_V_V, - 0); - if (value->IsConstant()) { return value; } Instr* i = AppendInstr( - opcode, 0, + OPCODE_ASSIGN_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -628,12 +528,6 @@ Value* FunctionBuilder::Assign(Value* value) { } Value* FunctionBuilder::Cast(Value* value, TypeName target_type) { - STATIC_OPCODE( - OPCODE_CAST, - "cast", - OPCODE_SIG_V_V, - 0); - if (value->type == target_type) { return value; } else if (value->IsConstant()) { @@ -643,7 +537,7 @@ Value* FunctionBuilder::Cast(Value* value, TypeName target_type) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_CAST_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -651,12 +545,6 @@ Value* FunctionBuilder::Cast(Value* value, TypeName target_type) { } Value* FunctionBuilder::ZeroExtend(Value* value, TypeName target_type) { - STATIC_OPCODE( - OPCODE_ZERO_EXTEND, - "zero_extend", - OPCODE_SIG_V_V, - 0); - if (value->type == target_type) { return value; } else if (value->IsConstant()) { @@ -666,7 +554,7 @@ Value* FunctionBuilder::ZeroExtend(Value* value, TypeName target_type) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_ZERO_EXTEND_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -674,12 +562,6 @@ Value* FunctionBuilder::ZeroExtend(Value* value, TypeName target_type) { } Value* FunctionBuilder::SignExtend(Value* value, TypeName target_type) { - STATIC_OPCODE( - OPCODE_SIGN_EXTEND, - "sign_extend", - OPCODE_SIG_V_V, - 0); - if (value->type == target_type) { return value; } else if (value->IsConstant()) { @@ -689,7 +571,7 @@ Value* FunctionBuilder::SignExtend(Value* value, TypeName target_type) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_SIGN_EXTEND_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -697,12 +579,6 @@ Value* FunctionBuilder::SignExtend(Value* value, TypeName target_type) { } Value* FunctionBuilder::Truncate(Value* value, TypeName target_type) { - STATIC_OPCODE( - OPCODE_TRUNCATE, - "truncate", - OPCODE_SIG_V_V, - 0); - ASSERT_INTEGER_TYPE(value->type); ASSERT_INTEGER_TYPE(target_type); @@ -715,7 +591,7 @@ Value* FunctionBuilder::Truncate(Value* value, TypeName target_type) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_TRUNCATE_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -724,12 +600,6 @@ Value* FunctionBuilder::Truncate(Value* value, TypeName target_type) { Value* FunctionBuilder::Convert(Value* value, TypeName target_type, RoundMode round_mode) { - STATIC_OPCODE( - OPCODE_CONVERT, - "convert", - OPCODE_SIG_V_V, - 0); - if (value->type == target_type) { return value; } else if (value->IsConstant()) { @@ -739,7 +609,7 @@ Value* FunctionBuilder::Convert(Value* value, TypeName target_type, } Instr* i = AppendInstr( - opcode, round_mode, + OPCODE_CONVERT_info, round_mode, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -747,12 +617,6 @@ Value* FunctionBuilder::Convert(Value* value, TypeName target_type, } Value* FunctionBuilder::Round(Value* value, RoundMode round_mode) { - STATIC_OPCODE( - OPCODE_ROUND, - "round", - OPCODE_SIG_V_V, - 0); - ASSERT_FLOAT_TYPE(value); if (value->IsConstant()) { @@ -762,7 +626,7 @@ Value* FunctionBuilder::Round(Value* value, RoundMode round_mode) { } Instr* i = AppendInstr( - opcode, round_mode, + OPCODE_ROUND_info, round_mode, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -770,16 +634,10 @@ Value* FunctionBuilder::Round(Value* value, RoundMode round_mode) { } Value* FunctionBuilder::VectorConvertI2F(Value* value) { - STATIC_OPCODE( - OPCODE_VECTOR_CONVERT_I2F, - "vector_convert_i2f", - OPCODE_SIG_V_V, - 0); - ASSERT_VECTOR_TYPE(value); Instr* i = AppendInstr( - opcode, 0, + OPCODE_VECTOR_CONVERT_I2F_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -787,16 +645,10 @@ Value* FunctionBuilder::VectorConvertI2F(Value* value) { } Value* FunctionBuilder::VectorConvertF2I(Value* value, RoundMode round_mode) { - STATIC_OPCODE( - OPCODE_VECTOR_CONVERT_F2I, - "vector_convert_f2i", - OPCODE_SIG_V_V, - 0); - ASSERT_VECTOR_TYPE(value); Instr* i = AppendInstr( - opcode, round_mode, + OPCODE_VECTOR_CONVERT_F2I_info, round_mode, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -877,14 +729,8 @@ Value* FunctionBuilder::LoadConstant(const vec128_t& value) { } Value* FunctionBuilder::LoadContext(size_t offset, TypeName type) { - STATIC_OPCODE( - OPCODE_LOAD_CONTEXT, - "load_context", - OPCODE_SIG_V_O, - 0); - Instr* i = AppendInstr( - opcode, 0, + OPCODE_LOAD_CONTEXT_info, 0, AllocValue(type)); i->src1.offset = offset; i->src2.value = i->src3.value = NULL; @@ -892,13 +738,7 @@ Value* FunctionBuilder::LoadContext(size_t offset, TypeName type) { } void FunctionBuilder::StoreContext(size_t offset, Value* value) { - STATIC_OPCODE( - OPCODE_STORE_CONTEXT, - "store_context", - OPCODE_SIG_X_O_V, - 0); - - Instr* i = AppendInstr(opcode, 0); + Instr* i = AppendInstr(OPCODE_STORE_CONTEXT_info, 0); i->src1.offset = offset; i->set_src2(value); i->src3.value = NULL; @@ -906,15 +746,9 @@ void FunctionBuilder::StoreContext(size_t offset, Value* value) { Value* FunctionBuilder::Load( Value* address, TypeName type, uint32_t load_flags) { - STATIC_OPCODE( - OPCODE_LOAD, - "load", - OPCODE_SIG_V_V, - OPCODE_FLAG_MEMORY); - ASSERT_ADDRESS_TYPE(address); Instr* i = AppendInstr( - opcode, load_flags, + OPCODE_LOAD_info, load_flags, AllocValue(type)); i->set_src1(address); i->src2.value = i->src3.value = NULL; @@ -923,15 +757,9 @@ Value* FunctionBuilder::Load( Value* FunctionBuilder::LoadAcquire( Value* address, TypeName type, uint32_t load_flags) { - STATIC_OPCODE( - OPCODE_LOAD_ACQUIRE, - "load_acquire", - OPCODE_SIG_V_V, - OPCODE_FLAG_MEMORY | OPCODE_FLAG_VOLATILE); - ASSERT_ADDRESS_TYPE(address); Instr* i = AppendInstr( - opcode, load_flags, + OPCODE_LOAD_ACQUIRE_info, load_flags, AllocValue(type)); i->set_src1(address); i->src2.value = i->src3.value = NULL; @@ -940,14 +768,8 @@ Value* FunctionBuilder::LoadAcquire( void FunctionBuilder::Store( Value* address, Value* value, uint32_t store_flags) { - STATIC_OPCODE( - OPCODE_STORE, - "store", - OPCODE_SIG_X_V_V, - OPCODE_FLAG_MEMORY); - ASSERT_ADDRESS_TYPE(address); - Instr* i = AppendInstr(opcode, store_flags); + Instr* i = AppendInstr(OPCODE_STORE_info, store_flags); i->set_src1(address); i->set_src2(value); i->src3.value = NULL; @@ -955,14 +777,8 @@ void FunctionBuilder::Store( Value* FunctionBuilder::StoreRelease( Value* address, Value* value, uint32_t store_flags) { - STATIC_OPCODE( - OPCODE_STORE_RELEASE, - "store_release", - OPCODE_SIG_V_V_V, - OPCODE_FLAG_MEMORY | OPCODE_FLAG_VOLATILE); - ASSERT_ADDRESS_TYPE(address); - Instr* i = AppendInstr(opcode, store_flags, + Instr* i = AppendInstr(OPCODE_STORE_RELEASE_info, store_flags, AllocValue(INT8_TYPE)); i->set_src1(address); i->set_src2(value); @@ -972,26 +788,14 @@ Value* FunctionBuilder::StoreRelease( void FunctionBuilder::Prefetch( Value* address, size_t length, uint32_t prefetch_flags) { - STATIC_OPCODE( - OPCODE_PREFETCH, - "prefetch", - OPCODE_SIG_X_V_O, - 0); - ASSERT_ADDRESS_TYPE(address); - Instr* i = AppendInstr(opcode, prefetch_flags); + Instr* i = AppendInstr(OPCODE_PREFETCH_info, prefetch_flags); i->set_src1(address); i->src2.offset = length; i->src3.value = NULL; } Value* FunctionBuilder::Max(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_MAX, - "max", - OPCODE_SIG_V_V_V, - 0); - ASSERT_TYPES_EQUAL(value1, value2); if (value1->type != VEC128_TYPE && @@ -1000,7 +804,7 @@ Value* FunctionBuilder::Max(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_MAX_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1009,12 +813,6 @@ Value* FunctionBuilder::Max(Value* value1, Value* value2) { } Value* FunctionBuilder::Min(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_MIN, - "min", - OPCODE_SIG_V_V_V, - 0); - ASSERT_TYPES_EQUAL(value1, value2); if (value1->type != VEC128_TYPE && @@ -1023,7 +821,7 @@ Value* FunctionBuilder::Min(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_MIN_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1032,12 +830,6 @@ Value* FunctionBuilder::Min(Value* value1, Value* value2) { } Value* FunctionBuilder::Select(Value* cond, Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_SELECT, - "select", - OPCODE_SIG_V_V_V_V, - 0); - XEASSERT(cond->type == INT8_TYPE); // for now ASSERT_TYPES_EQUAL(value1, value2); @@ -1046,7 +838,7 @@ Value* FunctionBuilder::Select(Value* cond, Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_SELECT_info, 0, AllocValue(value1->type)); i->set_src1(cond); i->set_src2(value1); @@ -1055,18 +847,12 @@ Value* FunctionBuilder::Select(Value* cond, Value* value1, Value* value2) { } Value* FunctionBuilder::IsTrue(Value* value) { - STATIC_OPCODE( - OPCODE_IS_TRUE, - "is_true", - OPCODE_SIG_V_V, - 0); - if (value->IsConstant()) { return LoadConstant(value->IsConstantTrue() ? 1 : 0); } Instr* i = AppendInstr( - opcode, 0, + OPCODE_IS_TRUE_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1074,18 +860,12 @@ Value* FunctionBuilder::IsTrue(Value* value) { } Value* FunctionBuilder::IsFalse(Value* value) { - STATIC_OPCODE( - OPCODE_IS_FALSE, - "is_false", - OPCODE_SIG_V_V, - 0); - if (value->IsConstant()) { return LoadConstant(value->IsConstantFalse() ? 1 : 0); } Instr* i = AppendInstr( - opcode, 0, + OPCODE_IS_FALSE_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1109,104 +889,48 @@ Value* FunctionBuilder::CompareXX( } Value* FunctionBuilder::CompareEQ(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_EQ, - "compare_eq", - OPCODE_SIG_V_V_V, - OPCODE_FLAG_COMMUNATIVE); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_EQ_info, value1, value2); } Value* FunctionBuilder::CompareNE(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_NE, - "compare_ne", - OPCODE_SIG_V_V_V, - OPCODE_FLAG_COMMUNATIVE); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_NE_info, value1, value2); } Value* FunctionBuilder::CompareSLT(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_SLT, - "compare_slt", - OPCODE_SIG_V_V_V, - 0); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_SLT_info, value1, value2); } Value* FunctionBuilder::CompareSLE(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_SLE, - "compare_sle", - OPCODE_SIG_V_V_V, - 0); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_SLE_info, value1, value2); } Value* FunctionBuilder::CompareSGT(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_SGT, - "compare_sgt", - OPCODE_SIG_V_V_V, - 0); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_SGT_info, value1, value2); } Value* FunctionBuilder::CompareSGE(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_SGE, - "compare_sge", - OPCODE_SIG_V_V_V, - 0); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_SGE_info, value1, value2); } Value* FunctionBuilder::CompareULT(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_ULT, - "compare_ult", - OPCODE_SIG_V_V_V, - 0); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_ULT_info, value1, value2); } Value* FunctionBuilder::CompareULE(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_ULE, - "compare_ule", - OPCODE_SIG_V_V_V, - 0); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_ULE_info, value1, value2); } Value* FunctionBuilder::CompareUGT(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_UGT, - "compare_ugt", - OPCODE_SIG_V_V_V, - 0); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_UGT_info, value1, value2); } Value* FunctionBuilder::CompareUGE(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_COMPARE_UGE, - "compare_uge", - OPCODE_SIG_V_V_V, - 0); - return CompareXX(opcode, value1, value2); + return CompareXX(OPCODE_COMPARE_UGE_info, value1, value2); } Value* FunctionBuilder::DidCarry(Value* value) { - STATIC_OPCODE( - OPCODE_DID_CARRY, - "did_carry", - OPCODE_SIG_V_V, - 0); - Instr* i = AppendInstr( - opcode, 0, + OPCODE_DID_CARRY_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1214,14 +938,8 @@ Value* FunctionBuilder::DidCarry(Value* value) { } Value* FunctionBuilder::DidOverflow(Value* value) { - STATIC_OPCODE( - OPCODE_DID_OVERFLOW, - "did_overflow", - OPCODE_SIG_V_V, - 0); - Instr* i = AppendInstr( - opcode, 0, + OPCODE_DID_OVERFLOW_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1247,62 +965,36 @@ Value* FunctionBuilder::VectorCompareXX( Value* FunctionBuilder::VectorCompareEQ( Value* value1, Value* value2, TypeName part_type) { - STATIC_OPCODE( - OPCODE_VECTOR_COMPARE_EQ, - "vector_compare_eq", - OPCODE_SIG_V_V_V, - 0); - return VectorCompareXX(opcode, value1, value2, part_type); + return VectorCompareXX( + OPCODE_VECTOR_COMPARE_EQ_info, value1, value2, part_type); } Value* FunctionBuilder::VectorCompareSGT( Value* value1, Value* value2, TypeName part_type) { - STATIC_OPCODE( - OPCODE_VECTOR_COMPARE_SGT, - "vector_compare_sgt", - OPCODE_SIG_V_V_V, - 0); - return VectorCompareXX(opcode, value1, value2, part_type); + return VectorCompareXX( + OPCODE_VECTOR_COMPARE_SGT_info, value1, value2, part_type); } Value* FunctionBuilder::VectorCompareSGE( Value* value1, Value* value2, TypeName part_type) { - STATIC_OPCODE( - OPCODE_VECTOR_COMPARE_SGE, - "vector_compare_sge", - OPCODE_SIG_V_V_V, - 0); - return VectorCompareXX(opcode, value1, value2, part_type); + return VectorCompareXX( + OPCODE_VECTOR_COMPARE_SGE_info, value1, value2, part_type); } Value* FunctionBuilder::VectorCompareUGT( Value* value1, Value* value2, TypeName part_type) { - STATIC_OPCODE( - OPCODE_VECTOR_COMPARE_UGT, - "vector_compare_ugt", - OPCODE_SIG_V_V_V, - 0); - return VectorCompareXX(opcode, value1, value2, part_type); + return VectorCompareXX( + OPCODE_VECTOR_COMPARE_UGT_info, value1, value2, part_type); } Value* FunctionBuilder::VectorCompareUGE( Value* value1, Value* value2, TypeName part_type) { - STATIC_OPCODE( - OPCODE_VECTOR_COMPARE_UGE, - "vector_compare_uge", - OPCODE_SIG_V_V_V, - 0); - return VectorCompareXX(opcode, value1, value2, part_type); + return VectorCompareXX( + OPCODE_VECTOR_COMPARE_UGE_info, value1, value2, part_type); } Value* FunctionBuilder::Add( Value* value1, Value* value2, uint32_t arithmetic_flags) { - STATIC_OPCODE( - OPCODE_ADD, - "add", - OPCODE_SIG_V_V_V, - OPCODE_FLAG_COMMUNATIVE); - ASSERT_TYPES_EQUAL(value1, value2); // TODO(benvanik): optimize when flags set. @@ -1319,7 +1011,7 @@ Value* FunctionBuilder::Add( } Instr* i = AppendInstr( - opcode, arithmetic_flags, + OPCODE_ADD_info, arithmetic_flags, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1330,12 +1022,6 @@ Value* FunctionBuilder::Add( Value* FunctionBuilder::AddWithCarry( Value* value1, Value* value2, Value* value3, uint32_t arithmetic_flags) { - STATIC_OPCODE( - OPCODE_ADD_CARRY, - "add_carry", - OPCODE_SIG_V_V_V_V, - OPCODE_FLAG_COMMUNATIVE); - ASSERT_TYPES_EQUAL(value1, value2); XEASSERT(value3->type == INT8_TYPE); @@ -1355,7 +1041,7 @@ Value* FunctionBuilder::AddWithCarry( } Instr* i = AppendInstr( - opcode, arithmetic_flags, + OPCODE_ADD_CARRY_info, arithmetic_flags, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1365,12 +1051,6 @@ Value* FunctionBuilder::AddWithCarry( Value* FunctionBuilder::Sub( Value* value1, Value* value2, uint32_t arithmetic_flags) { - STATIC_OPCODE( - OPCODE_SUB, - "sub", - OPCODE_SIG_V_V_V, - 0); - ASSERT_TYPES_EQUAL(value1, value2); // TODO(benvanik): optimize when flags set. @@ -1387,7 +1067,7 @@ Value* FunctionBuilder::Sub( } Instr* i = AppendInstr( - opcode, arithmetic_flags, + OPCODE_SUB_info, arithmetic_flags, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1396,12 +1076,6 @@ Value* FunctionBuilder::Sub( } Value* FunctionBuilder::Mul(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_MUL, - "mul", - OPCODE_SIG_V_V_V, - OPCODE_FLAG_COMMUNATIVE); - ASSERT_TYPES_EQUAL(value1, value2); if (value1->IsConstant() && value2->IsConstant()) { @@ -1411,7 +1085,7 @@ Value* FunctionBuilder::Mul(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_MUL_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1420,12 +1094,6 @@ Value* FunctionBuilder::Mul(Value* value1, Value* value2) { } Value* FunctionBuilder::Div(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_DIV, - "div", - OPCODE_SIG_V_V_V, - 0); - ASSERT_TYPES_EQUAL(value1, value2); if (value1->IsConstant() && value2->IsConstant()) { @@ -1435,7 +1103,7 @@ Value* FunctionBuilder::Div(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_DIV_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1444,12 +1112,6 @@ Value* FunctionBuilder::Div(Value* value1, Value* value2) { } Value* FunctionBuilder::Rem(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_REM, - "rem", - OPCODE_SIG_V_V_V, - 0); - ASSERT_TYPES_EQUAL(value1, value2); if (value1->IsConstant() && value2->IsConstant()) { @@ -1459,7 +1121,7 @@ Value* FunctionBuilder::Rem(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_REM_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1468,12 +1130,6 @@ Value* FunctionBuilder::Rem(Value* value1, Value* value2) { } Value* FunctionBuilder::MulAdd(Value* value1, Value* value2, Value* value3) { - STATIC_OPCODE( - OPCODE_MULADD, - "mul_add", - OPCODE_SIG_V_V_V_V, - 0); - ASSERT_TYPES_EQUAL(value1, value2); ASSERT_TYPES_EQUAL(value1, value3); @@ -1491,7 +1147,7 @@ Value* FunctionBuilder::MulAdd(Value* value1, Value* value2, Value* value3) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_MULADD_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1500,12 +1156,6 @@ Value* FunctionBuilder::MulAdd(Value* value1, Value* value2, Value* value3) { } Value* FunctionBuilder::MulSub(Value* value1, Value* value2, Value* value3) { - STATIC_OPCODE( - OPCODE_MULSUB, - "mul_sub", - OPCODE_SIG_V_V_V_V, - 0); - ASSERT_TYPES_EQUAL(value1, value2); ASSERT_TYPES_EQUAL(value1, value3); @@ -1523,7 +1173,7 @@ Value* FunctionBuilder::MulSub(Value* value1, Value* value2, Value* value3) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_MULSUB_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1532,12 +1182,6 @@ Value* FunctionBuilder::MulSub(Value* value1, Value* value2, Value* value3) { } Value* FunctionBuilder::Neg(Value* value) { - STATIC_OPCODE( - OPCODE_NEG, - "neg", - OPCODE_SIG_V_V, - 0); - ASSERT_NON_VECTOR_TYPE(value); if (value->IsConstant()) { @@ -1547,7 +1191,7 @@ Value* FunctionBuilder::Neg(Value* value) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_NEG_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1555,12 +1199,6 @@ Value* FunctionBuilder::Neg(Value* value) { } Value* FunctionBuilder::Abs(Value* value) { - STATIC_OPCODE( - OPCODE_ABS, - "abs", - OPCODE_SIG_V_V, - 0); - ASSERT_NON_VECTOR_TYPE(value); if (value->IsConstant()) { @@ -1570,7 +1208,7 @@ Value* FunctionBuilder::Abs(Value* value) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_ABS_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1578,12 +1216,6 @@ Value* FunctionBuilder::Abs(Value* value) { } Value* FunctionBuilder::Sqrt(Value* value) { - STATIC_OPCODE( - OPCODE_SQRT, - "sqrt", - OPCODE_SIG_V_V, - 0); - ASSERT_FLOAT_TYPE(value); if (value->IsConstant()) { @@ -1593,7 +1225,7 @@ Value* FunctionBuilder::Sqrt(Value* value) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_SQRT_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1601,16 +1233,10 @@ Value* FunctionBuilder::Sqrt(Value* value) { } Value* FunctionBuilder::RSqrt(Value* value) { - STATIC_OPCODE( - OPCODE_RSQRT, - "rsqrt", - OPCODE_SIG_V_V, - 0); - ASSERT_FLOAT_TYPE(value); Instr* i = AppendInstr( - opcode, 0, + OPCODE_RSQRT_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1618,18 +1244,12 @@ Value* FunctionBuilder::RSqrt(Value* value) { } Value* FunctionBuilder::DotProduct3(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_DOT_PRODUCT_3, - "dot_product_3", - OPCODE_SIG_V_V_V, - 0); - ASSERT_VECTOR_TYPE(value1); ASSERT_VECTOR_TYPE(value2); ASSERT_TYPES_EQUAL(value1, value2); Instr* i = AppendInstr( - opcode, 0, + OPCODE_DOT_PRODUCT_3_info, 0, AllocValue(FLOAT32_TYPE)); i->set_src1(value1); i->set_src2(value2); @@ -1638,18 +1258,12 @@ Value* FunctionBuilder::DotProduct3(Value* value1, Value* value2) { } Value* FunctionBuilder::DotProduct4(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_DOT_PRODUCT_4, - "dot_product_4", - OPCODE_SIG_V_V_V, - 0); - ASSERT_VECTOR_TYPE(value1); ASSERT_VECTOR_TYPE(value2); ASSERT_TYPES_EQUAL(value1, value2); Instr* i = AppendInstr( - opcode, 0, + OPCODE_DOT_PRODUCT_4_info, 0, AllocValue(FLOAT32_TYPE)); i->set_src1(value1); i->set_src2(value2); @@ -1658,12 +1272,6 @@ Value* FunctionBuilder::DotProduct4(Value* value1, Value* value2) { } Value* FunctionBuilder::And(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_AND, - "and", - OPCODE_SIG_V_V_V, - OPCODE_FLAG_COMMUNATIVE); - ASSERT_INTEGER_TYPE(value1); ASSERT_INTEGER_TYPE(value2); ASSERT_TYPES_EQUAL(value1, value2); @@ -1679,7 +1287,7 @@ Value* FunctionBuilder::And(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_AND_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1688,12 +1296,6 @@ Value* FunctionBuilder::And(Value* value1, Value* value2) { } Value* FunctionBuilder::Or(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_OR, - "or", - OPCODE_SIG_V_V_V, - OPCODE_FLAG_COMMUNATIVE); - ASSERT_INTEGER_TYPE(value1); ASSERT_INTEGER_TYPE(value2); ASSERT_TYPES_EQUAL(value1, value2); @@ -1709,7 +1311,7 @@ Value* FunctionBuilder::Or(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_OR_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1718,12 +1320,6 @@ Value* FunctionBuilder::Or(Value* value1, Value* value2) { } Value* FunctionBuilder::Xor(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_XOR, - "xor", - OPCODE_SIG_V_V_V, - OPCODE_FLAG_COMMUNATIVE); - ASSERT_INTEGER_TYPE(value1); ASSERT_INTEGER_TYPE(value2); ASSERT_TYPES_EQUAL(value1, value2); @@ -1735,7 +1331,7 @@ Value* FunctionBuilder::Xor(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_XOR_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1744,12 +1340,6 @@ Value* FunctionBuilder::Xor(Value* value1, Value* value2) { } Value* FunctionBuilder::Not(Value* value) { - STATIC_OPCODE( - OPCODE_NOT, - "not", - OPCODE_SIG_V_V, - 0); - ASSERT_INTEGER_TYPE(value); if (value->IsConstant()) { @@ -1759,7 +1349,7 @@ Value* FunctionBuilder::Not(Value* value) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_NOT_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1767,12 +1357,6 @@ Value* FunctionBuilder::Not(Value* value) { } Value* FunctionBuilder::Shl(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_SHL, - "shl", - OPCODE_SIG_V_V_V, - 0); - ASSERT_INTEGER_TYPE(value1); ASSERT_INTEGER_TYPE(value2); @@ -1791,7 +1375,7 @@ Value* FunctionBuilder::Shl(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_SHL_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1804,17 +1388,11 @@ Value* FunctionBuilder::Shl(Value* value1, int8_t value2) { Value* FunctionBuilder::VectorShl(Value* value1, Value* value2, TypeName part_type) { - STATIC_OPCODE( - OPCODE_VECTOR_SHL, - "vector_shl", - OPCODE_SIG_V_V_V, - 0); - ASSERT_VECTOR_TYPE(value1); ASSERT_VECTOR_TYPE(value2); Instr* i = AppendInstr( - opcode, part_type, + OPCODE_VECTOR_SHL_info, part_type, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1823,12 +1401,6 @@ Value* FunctionBuilder::VectorShl(Value* value1, Value* value2, } Value* FunctionBuilder::Shr(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_SHR, - "shr", - OPCODE_SIG_V_V_V, - 0); - ASSERT_INTEGER_TYPE(value1); ASSERT_INTEGER_TYPE(value2); @@ -1845,7 +1417,7 @@ Value* FunctionBuilder::Shr(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_SHR_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1857,12 +1429,6 @@ Value* FunctionBuilder::Shr(Value* value1, int8_t value2) { } Value* FunctionBuilder::Sha(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_SHA, - "sha", - OPCODE_SIG_V_V_V, - 0); - ASSERT_INTEGER_TYPE(value1); ASSERT_INTEGER_TYPE(value2); @@ -1879,7 +1445,7 @@ Value* FunctionBuilder::Sha(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_SHA_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1891,12 +1457,6 @@ Value* FunctionBuilder::Sha(Value* value1, int8_t value2) { } Value* FunctionBuilder::RotateLeft(Value* value1, Value* value2) { - STATIC_OPCODE( - OPCODE_ROTATE_LEFT, - "rotate_left", - OPCODE_SIG_V_V_V, - 0); - ASSERT_INTEGER_TYPE(value1); ASSERT_INTEGER_TYPE(value2); @@ -1909,7 +1469,7 @@ Value* FunctionBuilder::RotateLeft(Value* value1, Value* value2) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_ROTATE_LEFT_info, 0, AllocValue(value1->type)); i->set_src1(value1); i->set_src2(value2); @@ -1918,12 +1478,6 @@ Value* FunctionBuilder::RotateLeft(Value* value1, Value* value2) { } Value* FunctionBuilder::ByteSwap(Value* value) { - STATIC_OPCODE( - OPCODE_BYTE_SWAP, - "byte_swap", - OPCODE_SIG_V_V, - 0); - if (value->type == INT8_TYPE) { return value; } @@ -1934,7 +1488,7 @@ Value* FunctionBuilder::ByteSwap(Value* value) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_BYTE_SWAP_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1942,12 +1496,6 @@ Value* FunctionBuilder::ByteSwap(Value* value) { } Value* FunctionBuilder::CountLeadingZeros(Value* value) { - STATIC_OPCODE( - OPCODE_CNTLZ, - "cntlz", - OPCODE_SIG_V_V, - 0); - ASSERT_INTEGER_TYPE(value); if (value->IsConstantZero()) { @@ -1956,7 +1504,7 @@ Value* FunctionBuilder::CountLeadingZeros(Value* value) { } Instr* i = AppendInstr( - opcode, 0, + OPCODE_CNTLZ_info, 0, AllocValue(INT8_TYPE)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -1964,16 +1512,10 @@ Value* FunctionBuilder::CountLeadingZeros(Value* value) { } Value* FunctionBuilder::Insert(Value* value, uint32_t index, Value* part) { - STATIC_OPCODE( - OPCODE_INSERT, - "insert", - OPCODE_SIG_V_V_O_V, - 0); - // TODO(benvanik): could do some of this as constants. Instr* i = AppendInstr( - opcode, 0, + OPCODE_INSERT_info, 0, AllocValue(value->type)); i->set_src1(value); i->src2.offset = index; @@ -1982,16 +1524,10 @@ Value* FunctionBuilder::Insert(Value* value, uint32_t index, Value* part) { } Value* FunctionBuilder::Extract(Value* value, uint32_t index, TypeName target_type) { - STATIC_OPCODE( - OPCODE_EXTRACT, - "extract", - OPCODE_SIG_V_V_O, - 0); - // TODO(benvanik): could do some of this as constants. Instr* i = AppendInstr( - opcode, 0, + OPCODE_EXTRACT_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.offset = index; @@ -2000,16 +1536,10 @@ Value* FunctionBuilder::Extract(Value* value, uint32_t index, TypeName target_ty } Value* FunctionBuilder::Splat(Value* value, TypeName target_type) { - STATIC_OPCODE( - OPCODE_SPLAT, - "splat", - OPCODE_SIG_V_V, - 0); - // TODO(benvanik): could do some of this as constants. Instr* i = AppendInstr( - opcode, 0, + OPCODE_SPLAT_info, 0, AllocValue(target_type)); i->set_src1(value); i->src2.value = i->src3.value = NULL; @@ -2018,12 +1548,6 @@ Value* FunctionBuilder::Splat(Value* value, TypeName target_type) { Value* FunctionBuilder::Permute( Value* control, Value* value1, Value* value2, TypeName part_type) { - STATIC_OPCODE( - OPCODE_PERMUTE, - "permute", - OPCODE_SIG_V_V_V_V, - part_type); - ASSERT_TYPES_EQUAL(value1, value2); // For now. XEASSERT(part_type == INT32_TYPE || part_type == FLOAT32_TYPE); @@ -2031,7 +1555,7 @@ Value* FunctionBuilder::Permute( // TODO(benvanik): could do some of this as constants. Instr* i = AppendInstr( - opcode, 0, + OPCODE_PERMUTE_info, part_type, AllocValue(value1->type)); i->set_src1(control); i->set_src2(value1); @@ -2041,12 +1565,6 @@ Value* FunctionBuilder::Permute( Value* FunctionBuilder::Swizzle( Value* value, TypeName part_type, uint32_t swizzle_mask) { - STATIC_OPCODE( - OPCODE_PERMUTE, - "permute", - OPCODE_SIG_V_V_O, - part_type); - // For now. XEASSERT(part_type == INT32_TYPE || part_type == FLOAT32_TYPE); @@ -2057,7 +1575,7 @@ Value* FunctionBuilder::Swizzle( // TODO(benvanik): could do some of this as constants. Instr* i = AppendInstr( - opcode, 0, + OPCODE_SWIZZLE_info, part_type, AllocValue(value->type)); i->set_src1(value); i->src2.offset = swizzle_mask; @@ -2067,18 +1585,12 @@ Value* FunctionBuilder::Swizzle( Value* FunctionBuilder::CompareExchange( Value* address, Value* compare_value, Value* exchange_value) { - STATIC_OPCODE( - OPCODE_COMPARE_EXCHANGE, - "compare_exchange", - OPCODE_SIG_V_V_V_V, - OPCODE_FLAG_VOLATILE); - ASSERT_ADDRESS_TYPE(address); ASSERT_INTEGER_TYPE(compare_value); ASSERT_INTEGER_TYPE(exchange_value); ASSERT_TYPES_EQUAL(compare_value, exchange_value); Instr* i = AppendInstr( - opcode, 0, + OPCODE_COMPARE_EXCHANGE_info, 0, AllocValue(exchange_value->type)); i->set_src1(address); i->set_src2(compare_value); @@ -2087,16 +1599,10 @@ Value* FunctionBuilder::CompareExchange( } Value* FunctionBuilder::AtomicAdd(Value* address, Value* value) { - STATIC_OPCODE( - OPCODE_ATOMIC_ADD, - "atomic_add", - OPCODE_SIG_V_V_V, - 0); - ASSERT_ADDRESS_TYPE(address); ASSERT_INTEGER_TYPE(value); Instr* i = AppendInstr( - opcode, 0, + OPCODE_ATOMIC_ADD_info, 0, AllocValue(value->type)); i->set_src1(address); i->set_src2(value); @@ -2105,16 +1611,10 @@ Value* FunctionBuilder::AtomicAdd(Value* address, Value* value) { } Value* FunctionBuilder::AtomicSub(Value* address, Value* value) { - STATIC_OPCODE( - OPCODE_ATOMIC_SUB, - "atomic_sub", - OPCODE_SIG_V_V_V, - 0); - ASSERT_ADDRESS_TYPE(address); ASSERT_INTEGER_TYPE(value); Instr* i = AppendInstr( - opcode, 0, + OPCODE_ATOMIC_SUB_info, 0, AllocValue(value->type)); i->set_src1(address); i->set_src2(value); diff --git a/src/alloy/hir/function_builder.h b/src/alloy/hir/function_builder.h index dca09d72a..931c8c2c1 100644 --- a/src/alloy/hir/function_builder.h +++ b/src/alloy/hir/function_builder.h @@ -55,7 +55,6 @@ public: void Comment(const char* format, ...); - const OpcodeInfo* GetNopOpcode() const; void Nop(); // trace info/etc diff --git a/src/alloy/hir/instr.cc b/src/alloy/hir/instr.cc index 3ff9610e9..005f36dd7 100644 --- a/src/alloy/hir/instr.cc +++ b/src/alloy/hir/instr.cc @@ -19,7 +19,7 @@ void Instr::set_src1(Value* value) { if (src1.value == value) { return; } - if (src1.value) { + if (src1_use) { src1.value->RemoveUse(src1_use); } src1.value = value; @@ -30,7 +30,7 @@ void Instr::set_src2(Value* value) { if (src2.value == value) { return; } - if (src2.value) { + if (src2_use) { src2.value->RemoveUse(src2_use); } src2.value = value; @@ -41,7 +41,7 @@ void Instr::set_src3(Value* value) { if (src3.value == value) { return; } - if (src3.value) { + if (src3_use) { src3.value->RemoveUse(src3_use); } src3.value = value; diff --git a/src/alloy/hir/opcodes.cc b/src/alloy/hir/opcodes.cc new file mode 100644 index 000000000..24880d5be --- /dev/null +++ b/src/alloy/hir/opcodes.cc @@ -0,0 +1,25 @@ +/** + ****************************************************************************** + * 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::hir; + + +namespace alloy { +namespace hir { + +#define DEFINE_OPCODE(num, name, sig, flags) \ + static const OpcodeInfo num##_info = { flags, sig, name, num, }; +#include +#undef DEFINE_OPCODE + +} // namespace hir +} // namespace alloy diff --git a/src/alloy/hir/opcodes.h b/src/alloy/hir/opcodes.h index e6ab8411d..071a5f356 100644 --- a/src/alloy/hir/opcodes.h +++ b/src/alloy/hir/opcodes.h @@ -212,6 +212,12 @@ typedef struct { } OpcodeInfo; +#define DEFINE_OPCODE(num, name, sig, flags) \ + extern const OpcodeInfo num##_info; +#include +#undef DEFINE_OPCODE + + } // namespace hir } // namespace alloy diff --git a/src/alloy/hir/opcodes.inl b/src/alloy/hir/opcodes.inl new file mode 100644 index 000000000..0e150f19e --- /dev/null +++ b/src/alloy/hir/opcodes.inl @@ -0,0 +1,512 @@ +/** + ****************************************************************************** + * 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( + OPCODE_COMMENT, + "comment", + OPCODE_SIG_X, + OPCODE_FLAG_IGNORE); + +DEFINE_OPCODE( + OPCODE_NOP, + "nop", + OPCODE_SIG_X, + OPCODE_FLAG_IGNORE); + +DEFINE_OPCODE( + OPCODE_DEBUG_BREAK, + "debug_break", + OPCODE_SIG_X, + OPCODE_FLAG_VOLATILE); + +DEFINE_OPCODE( + OPCODE_DEBUG_BREAK_TRUE, + "debug_break_true", + OPCODE_SIG_X_V, + OPCODE_FLAG_VOLATILE); + +DEFINE_OPCODE( + OPCODE_TRAP, + "trap", + OPCODE_SIG_X, + OPCODE_FLAG_VOLATILE); + +DEFINE_OPCODE( + OPCODE_TRAP_TRUE, + "trap_true", + OPCODE_SIG_X_V, + OPCODE_FLAG_VOLATILE); + +DEFINE_OPCODE( + OPCODE_CALL, + "call", + OPCODE_SIG_X_S, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_CALL_TRUE, + "call_true", + OPCODE_SIG_X_V_S, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_CALL_INDIRECT, + "call_indirect", + OPCODE_SIG_X_V, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_CALL_INDIRECT_TRUE, + "call_indirect_true", + OPCODE_SIG_X_V_V, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_RETURN, + "return", + OPCODE_SIG_X, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_BRANCH, + "branch", + OPCODE_SIG_X_L, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_BRANCH_IF, + "branch_if", + OPCODE_SIG_X_V_L_L, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_BRANCH_TRUE, + "branch_true", + OPCODE_SIG_X_V_L, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_BRANCH_FALSE, + "branch_false", + OPCODE_SIG_X_V_L, + OPCODE_FLAG_BRANCH); + +DEFINE_OPCODE( + OPCODE_ASSIGN, + "assign", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_CAST, + "cast", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_ZERO_EXTEND, + "zero_extend", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_SIGN_EXTEND, + "sign_extend", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_TRUNCATE, + "truncate", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_CONVERT, + "convert", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_ROUND, + "round", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_VECTOR_CONVERT_I2F, + "vector_convert_i2f", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_VECTOR_CONVERT_F2I, + "vector_convert_f2i", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_LOAD_CONTEXT, + "load_context", + OPCODE_SIG_V_O, + 0); + +DEFINE_OPCODE( + OPCODE_STORE_CONTEXT, + "store_context", + OPCODE_SIG_X_O_V, + 0); + +DEFINE_OPCODE( + OPCODE_LOAD, + "load", + OPCODE_SIG_V_V, + OPCODE_FLAG_MEMORY); + +DEFINE_OPCODE( + OPCODE_LOAD_ACQUIRE, + "load_acquire", + OPCODE_SIG_V_V, + OPCODE_FLAG_MEMORY | OPCODE_FLAG_VOLATILE); + +DEFINE_OPCODE( + OPCODE_STORE, + "store", + OPCODE_SIG_X_V_V, + OPCODE_FLAG_MEMORY); + +DEFINE_OPCODE( + OPCODE_STORE_RELEASE, + "store_release", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_MEMORY | OPCODE_FLAG_VOLATILE); + +DEFINE_OPCODE( + OPCODE_PREFETCH, + "prefetch", + OPCODE_SIG_X_V_O, + 0); + +DEFINE_OPCODE( + OPCODE_MAX, + "max", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_MIN, + "min", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_SELECT, + "select", + OPCODE_SIG_V_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_IS_TRUE, + "is_true", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_IS_FALSE, + "is_false", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_COMPARE_EQ, + "compare_eq", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_COMMUNATIVE); +DEFINE_OPCODE( + OPCODE_COMPARE_NE, + "compare_ne", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_COMMUNATIVE); +DEFINE_OPCODE( + OPCODE_COMPARE_SLT, + "compare_slt", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_COMPARE_SLE, + "compare_sle", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_COMPARE_SGT, + "compare_sgt", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_COMPARE_SGE, + "compare_sge", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_COMPARE_ULT, + "compare_ult", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_COMPARE_ULE, + "compare_ule", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_COMPARE_UGT, + "compare_ugt", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_COMPARE_UGE, + "compare_uge", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_DID_CARRY, + "did_carry", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_DID_OVERFLOW, + "did_overflow", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_VECTOR_COMPARE_EQ, + "vector_compare_eq", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_COMMUNATIVE); +DEFINE_OPCODE( + OPCODE_VECTOR_COMPARE_SGT, + "vector_compare_sgt", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_VECTOR_COMPARE_SGE, + "vector_compare_sge", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_VECTOR_COMPARE_UGT, + "vector_compare_ugt", + OPCODE_SIG_V_V_V, + 0); +DEFINE_OPCODE( + OPCODE_VECTOR_COMPARE_UGE, + "vector_compare_uge", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_ADD, + "add", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_COMMUNATIVE); + +DEFINE_OPCODE( + OPCODE_ADD_CARRY, + "add_carry", + OPCODE_SIG_V_V_V_V, + OPCODE_FLAG_COMMUNATIVE); + +DEFINE_OPCODE( + OPCODE_SUB, + "sub", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_MUL, + "mul", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_COMMUNATIVE); + +DEFINE_OPCODE( + OPCODE_DIV, + "div", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_REM, + "rem", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_MULADD, + "mul_add", + OPCODE_SIG_V_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_MULSUB, + "mul_sub", + OPCODE_SIG_V_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_NEG, + "neg", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_ABS, + "abs", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_SQRT, + "sqrt", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_RSQRT, + "rsqrt", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_DOT_PRODUCT_3, + "dot_product_3", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_DOT_PRODUCT_4, + "dot_product_4", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_AND, + "and", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_COMMUNATIVE); + +DEFINE_OPCODE( + OPCODE_OR, + "or", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_COMMUNATIVE); + +DEFINE_OPCODE( + OPCODE_XOR, + "xor", + OPCODE_SIG_V_V_V, + OPCODE_FLAG_COMMUNATIVE); + +DEFINE_OPCODE( + OPCODE_NOT, + "not", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_SHL, + "shl", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_VECTOR_SHL, + "vector_shl", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_SHR, + "shr", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_SHA, + "sha", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_ROTATE_LEFT, + "rotate_left", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_BYTE_SWAP, + "byte_swap", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_CNTLZ, + "cntlz", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_INSERT, + "insert", + OPCODE_SIG_V_V_O_V, + 0); + +DEFINE_OPCODE( + OPCODE_EXTRACT, + "extract", + OPCODE_SIG_V_V_O, + 0); + +DEFINE_OPCODE( + OPCODE_SPLAT, + "splat", + OPCODE_SIG_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_PERMUTE, + "permute", + OPCODE_SIG_V_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_SWIZZLE, + "swizzle", + OPCODE_SIG_V_V_O, + 0); + +DEFINE_OPCODE( + OPCODE_COMPARE_EXCHANGE, + "compare_exchange", + OPCODE_SIG_V_V_V_V, + OPCODE_FLAG_VOLATILE); + +DEFINE_OPCODE( + OPCODE_ATOMIC_ADD, + "atomic_add", + OPCODE_SIG_V_V_V, + 0); + +DEFINE_OPCODE( + OPCODE_ATOMIC_SUB, + "atomic_sub", + OPCODE_SIG_V_V_V, + 0); diff --git a/src/alloy/hir/sources.gypi b/src/alloy/hir/sources.gypi index d0410cf01..ed47de651 100644 --- a/src/alloy/hir/sources.gypi +++ b/src/alloy/hir/sources.gypi @@ -9,7 +9,9 @@ 'instr.h', 'label.cc', 'label.h', + 'opcodes.cc', 'opcodes.h', + 'opcodes.inl', 'tracing.h', 'value.cc', 'value.h',