Basic ContextPromotionPass and some opcode info rearranging.
This commit is contained in:
parent
51d0be0f0a
commit
329b554c7a
|
@ -15,9 +15,11 @@
|
||||||
using namespace alloy;
|
using namespace alloy;
|
||||||
using namespace alloy::compiler;
|
using namespace alloy::compiler;
|
||||||
using namespace alloy::hir;
|
using namespace alloy::hir;
|
||||||
|
using namespace alloy::runtime;
|
||||||
|
|
||||||
|
|
||||||
Compiler::Compiler() {
|
Compiler::Compiler(Runtime* runtime) :
|
||||||
|
runtime_(runtime) {
|
||||||
alloy::tracing::WriteEvent(EventType::Init({
|
alloy::tracing::WriteEvent(EventType::Init({
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -35,6 +37,7 @@ Compiler::~Compiler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::AddPass(Pass* pass) {
|
void Compiler::AddPass(Pass* pass) {
|
||||||
|
pass->Initialize(this);
|
||||||
passes_.push_back(pass);
|
passes_.push_back(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include <alloy/core.h>
|
#include <alloy/core.h>
|
||||||
#include <alloy/hir/function_builder.h>
|
#include <alloy/hir/function_builder.h>
|
||||||
|
|
||||||
|
namespace alloy { namespace runtime { class Runtime; } }
|
||||||
|
|
||||||
|
|
||||||
namespace alloy {
|
namespace alloy {
|
||||||
namespace compiler {
|
namespace compiler {
|
||||||
|
@ -22,8 +24,10 @@ class Pass;
|
||||||
|
|
||||||
class Compiler {
|
class Compiler {
|
||||||
public:
|
public:
|
||||||
Compiler();
|
Compiler(runtime::Runtime* runtime);
|
||||||
~Compiler();
|
~Compiler();
|
||||||
|
|
||||||
|
runtime::Runtime* runtime() const { return runtime_; }
|
||||||
|
|
||||||
void AddPass(Pass* pass);
|
void AddPass(Pass* pass);
|
||||||
|
|
||||||
|
@ -32,6 +36,8 @@ public:
|
||||||
int Compile(hir::FunctionBuilder* builder);
|
int Compile(hir::FunctionBuilder* builder);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
runtime::Runtime* runtime_;
|
||||||
|
|
||||||
typedef std::vector<Pass*> PassList;
|
typedef std::vector<Pass*> PassList;
|
||||||
PassList passes_;
|
PassList passes_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,12 +9,21 @@
|
||||||
|
|
||||||
#include <alloy/compiler/pass.h>
|
#include <alloy/compiler/pass.h>
|
||||||
|
|
||||||
|
#include <alloy/compiler/compiler.h>
|
||||||
|
|
||||||
using namespace alloy;
|
using namespace alloy;
|
||||||
using namespace alloy::compiler;
|
using namespace alloy::compiler;
|
||||||
|
|
||||||
|
|
||||||
Pass::Pass() {
|
Pass::Pass() :
|
||||||
|
runtime_(0), compiler_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Pass::~Pass() {
|
Pass::~Pass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Pass::Initialize(Compiler* compiler) {
|
||||||
|
runtime_ = compiler->runtime();
|
||||||
|
compiler_ = compiler;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -14,17 +14,27 @@
|
||||||
|
|
||||||
#include <alloy/hir/function_builder.h>
|
#include <alloy/hir/function_builder.h>
|
||||||
|
|
||||||
|
namespace alloy { namespace runtime { class Runtime; } }
|
||||||
|
|
||||||
|
|
||||||
namespace alloy {
|
namespace alloy {
|
||||||
namespace compiler {
|
namespace compiler {
|
||||||
|
|
||||||
|
class Compiler;
|
||||||
|
|
||||||
|
|
||||||
class Pass {
|
class Pass {
|
||||||
public:
|
public:
|
||||||
Pass();
|
Pass();
|
||||||
virtual ~Pass();
|
virtual ~Pass();
|
||||||
|
|
||||||
|
virtual int Initialize(Compiler* compiler);
|
||||||
|
|
||||||
virtual int Run(hir::FunctionBuilder* builder) = 0;
|
virtual int Run(hir::FunctionBuilder* builder) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
runtime::Runtime* runtime_;
|
||||||
|
Compiler* compiler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#define ALLOY_COMPILER_PASSES_H_
|
#define ALLOY_COMPILER_PASSES_H_
|
||||||
|
|
||||||
//#include <alloy/compiler/passes/constant_propagation_pass.h>
|
//#include <alloy/compiler/passes/constant_propagation_pass.h>
|
||||||
//#include <alloy/compiler/passes/context_promotion_pass.h>
|
#include <alloy/compiler/passes/context_promotion_pass.h>
|
||||||
#include <alloy/compiler/passes/dead_code_elimination_pass.h>
|
#include <alloy/compiler/passes/dead_code_elimination_pass.h>
|
||||||
//#include <alloy/compiler/passes/dead_store_elimination_pass.h>
|
//#include <alloy/compiler/passes/dead_store_elimination_pass.h>
|
||||||
#include <alloy/compiler/passes/simplification_pass.h>
|
#include <alloy/compiler/passes/simplification_pass.h>
|
||||||
|
|
|
@ -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 <alloy/compiler/passes/context_promotion_pass.h>
|
||||||
|
|
||||||
|
#include <alloy/compiler/compiler.h>
|
||||||
|
#include <alloy/runtime/runtime.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <alloy/compiler/pass.h>
|
||||||
|
|
||||||
|
|
||||||
|
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_
|
|
@ -53,8 +53,6 @@ int DeadCodeEliminationPass::Run(FunctionBuilder* builder) {
|
||||||
// all removed ops with NOP and then do a single pass that removes them
|
// all removed ops with NOP and then do a single pass that removes them
|
||||||
// all.
|
// all.
|
||||||
|
|
||||||
const OpcodeInfo* nop = builder->GetNopOpcode();
|
|
||||||
|
|
||||||
bool any_removed = false;
|
bool any_removed = false;
|
||||||
Block* block = builder->first_block();
|
Block* block = builder->first_block();
|
||||||
while (block) {
|
while (block) {
|
||||||
|
@ -67,7 +65,7 @@ int DeadCodeEliminationPass::Run(FunctionBuilder* builder) {
|
||||||
if (!(opcode->flags & OPCODE_FLAG_VOLATILE) &&
|
if (!(opcode->flags & OPCODE_FLAG_VOLATILE) &&
|
||||||
i->dest && !i->dest->use_head) {
|
i->dest && !i->dest->use_head) {
|
||||||
// Has no uses and is not volatile. This instruction can die!
|
// Has no uses and is not volatile. This instruction can die!
|
||||||
MakeNopRecursive(nop, i);
|
MakeNopRecursive(i);
|
||||||
any_removed = true;
|
any_removed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +82,7 @@ int DeadCodeEliminationPass::Run(FunctionBuilder* builder) {
|
||||||
Instr* i = block->instr_head;
|
Instr* i = block->instr_head;
|
||||||
while (i) {
|
while (i) {
|
||||||
Instr* next = i->next;
|
Instr* next = i->next;
|
||||||
if (i->opcode->num == OPCODE_NOP) {
|
if (i->opcode == &OPCODE_NOP_info) {
|
||||||
// Nop - remove!
|
// Nop - remove!
|
||||||
i->Remove();
|
i->Remove();
|
||||||
}
|
}
|
||||||
|
@ -97,9 +95,8 @@ int DeadCodeEliminationPass::Run(FunctionBuilder* builder) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeadCodeEliminationPass::MakeNopRecursive(
|
void DeadCodeEliminationPass::MakeNopRecursive(Instr* i) {
|
||||||
const OpcodeInfo* nop, Instr* i) {
|
i->opcode = &hir::OPCODE_NOP_info;
|
||||||
i->opcode = nop;
|
|
||||||
i->dest->def = NULL;
|
i->dest->def = NULL;
|
||||||
i->dest = NULL;
|
i->dest = NULL;
|
||||||
|
|
||||||
|
@ -113,7 +110,7 @@ void DeadCodeEliminationPass::MakeNopRecursive(
|
||||||
if (!value->use_head) { \
|
if (!value->use_head) { \
|
||||||
/* Value is now unused, so recursively kill it. */ \
|
/* Value is now unused, so recursively kill it. */ \
|
||||||
if (value->def && value->def != i) { \
|
if (value->def && value->def != i) { \
|
||||||
MakeNopRecursive(nop, value->def); \
|
MakeNopRecursive(value->def); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual int Run(hir::FunctionBuilder* builder);
|
virtual int Run(hir::FunctionBuilder* builder);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MakeNopRecursive(const hir::OpcodeInfo* nop, hir::Instr* i);
|
void MakeNopRecursive(hir::Instr* i);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,13 +65,13 @@ int SimplificationPass::Run(FunctionBuilder* builder) {
|
||||||
|
|
||||||
Value* SimplificationPass::CheckValue(Value* value) {
|
Value* SimplificationPass::CheckValue(Value* value) {
|
||||||
Instr* def = value->def;
|
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
|
// Value comes from an assignment - recursively find if it comes from
|
||||||
// another assignment. It probably doesn't, if we already replaced it.
|
// another assignment. It probably doesn't, if we already replaced it.
|
||||||
Value* replacement = def->src1.value;
|
Value* replacement = def->src1.value;
|
||||||
while (true) {
|
while (true) {
|
||||||
def = replacement->def;
|
def = replacement->def;
|
||||||
if (!def || def->opcode->num != OPCODE_ASSIGN) {
|
if (!def || def->opcode != &OPCODE_ASSIGN_info) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
replacement = def->src1.value;
|
replacement = def->src1.value;
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
'sources': [
|
'sources': [
|
||||||
#'constant_propagation_pass.cc',
|
#'constant_propagation_pass.cc',
|
||||||
#'constant_propagation_pass.h',
|
#'constant_propagation_pass.h',
|
||||||
#'context_promotion_pass.cc',
|
'context_promotion_pass.cc',
|
||||||
#'context_promotion_pass.h',
|
'context_promotion_pass.h',
|
||||||
'dead_code_elimination_pass.cc',
|
'dead_code_elimination_pass.cc',
|
||||||
'dead_code_elimination_pass.h',
|
'dead_code_elimination_pass.h',
|
||||||
#'dead_store_elimination_pass.cc',
|
#'dead_store_elimination_pass.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 <alloy/frontend/context_info.h>
|
||||||
|
|
||||||
|
using namespace alloy;
|
||||||
|
using namespace alloy::frontend;
|
||||||
|
|
||||||
|
|
||||||
|
ContextInfo::ContextInfo(size_t size) :
|
||||||
|
size_(size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextInfo::~ContextInfo() {
|
||||||
|
}
|
|
@ -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 <alloy/core.h>
|
||||||
|
|
||||||
|
|
||||||
|
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_
|
|
@ -18,10 +18,11 @@ using namespace alloy::runtime;
|
||||||
|
|
||||||
|
|
||||||
Frontend::Frontend(Runtime* runtime) :
|
Frontend::Frontend(Runtime* runtime) :
|
||||||
runtime_(runtime) {
|
runtime_(runtime), context_info_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Frontend::~Frontend() {
|
Frontend::~Frontend() {
|
||||||
|
delete context_info_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory* Frontend::memory() const {
|
Memory* Frontend::memory() const {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <alloy/core.h>
|
#include <alloy/core.h>
|
||||||
#include <alloy/memory.h>
|
#include <alloy/memory.h>
|
||||||
|
#include <alloy/frontend/context_info.h>
|
||||||
#include <alloy/runtime/function.h>
|
#include <alloy/runtime/function.h>
|
||||||
#include <alloy/runtime/symbol_info.h>
|
#include <alloy/runtime/symbol_info.h>
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ public:
|
||||||
|
|
||||||
runtime::Runtime* runtime() const { return runtime_; }
|
runtime::Runtime* runtime() const { return runtime_; }
|
||||||
Memory* memory() const;
|
Memory* memory() const;
|
||||||
|
ContextInfo* context_info() const { return context_info_; }
|
||||||
|
|
||||||
virtual int Initialize();
|
virtual int Initialize();
|
||||||
|
|
||||||
|
@ -42,6 +44,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
runtime::Runtime* runtime_;
|
runtime::Runtime* runtime_;
|
||||||
|
ContextInfo* context_info_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <alloy/frontend/ppc/ppc_frontend.h>
|
#include <alloy/frontend/ppc/ppc_frontend.h>
|
||||||
|
|
||||||
#include <alloy/frontend/tracing.h>
|
#include <alloy/frontend/tracing.h>
|
||||||
|
#include <alloy/frontend/ppc/ppc_context.h>
|
||||||
#include <alloy/frontend/ppc/ppc_disasm.h>
|
#include <alloy/frontend/ppc/ppc_disasm.h>
|
||||||
#include <alloy/frontend/ppc/ppc_emit.h>
|
#include <alloy/frontend/ppc/ppc_emit.h>
|
||||||
#include <alloy/frontend/ppc/ppc_translator.h>
|
#include <alloy/frontend/ppc/ppc_translator.h>
|
||||||
|
@ -54,6 +55,10 @@ namespace {
|
||||||
PPCFrontend::PPCFrontend(Runtime* runtime) :
|
PPCFrontend::PPCFrontend(Runtime* runtime) :
|
||||||
Frontend(runtime) {
|
Frontend(runtime) {
|
||||||
InitializeIfNeeded();
|
InitializeIfNeeded();
|
||||||
|
|
||||||
|
ContextInfo* info = new ContextInfo(sizeof(PPCContext));
|
||||||
|
// Add fields/etc.
|
||||||
|
context_info_ = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPCFrontend::~PPCFrontend() {
|
PPCFrontend::~PPCFrontend() {
|
||||||
|
|
|
@ -30,9 +30,9 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) :
|
||||||
scanner_ = new PPCScanner(frontend);
|
scanner_ = new PPCScanner(frontend);
|
||||||
builder_ = new PPCFunctionBuilder(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::ConstantPropagationPass());
|
||||||
//compiler_->AddPass(new passes::TypePropagationPass());
|
//compiler_->AddPass(new passes::TypePropagationPass());
|
||||||
//compiler_->AddPass(new passes::ByteSwapEliminationPass());
|
//compiler_->AddPass(new passes::ByteSwapEliminationPass());
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||||
{
|
{
|
||||||
'sources': [
|
'sources': [
|
||||||
|
'context_info.cc',
|
||||||
|
'context_info.h',
|
||||||
'frontend.cc',
|
'frontend.cc',
|
||||||
'frontend.h',
|
'frontend.h',
|
||||||
'tracing.h',
|
'tracing.h',
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -55,7 +55,6 @@ public:
|
||||||
|
|
||||||
void Comment(const char* format, ...);
|
void Comment(const char* format, ...);
|
||||||
|
|
||||||
const OpcodeInfo* GetNopOpcode() const;
|
|
||||||
void Nop();
|
void Nop();
|
||||||
|
|
||||||
// trace info/etc
|
// trace info/etc
|
||||||
|
|
|
@ -19,7 +19,7 @@ void Instr::set_src1(Value* value) {
|
||||||
if (src1.value == value) {
|
if (src1.value == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (src1.value) {
|
if (src1_use) {
|
||||||
src1.value->RemoveUse(src1_use);
|
src1.value->RemoveUse(src1_use);
|
||||||
}
|
}
|
||||||
src1.value = value;
|
src1.value = value;
|
||||||
|
@ -30,7 +30,7 @@ void Instr::set_src2(Value* value) {
|
||||||
if (src2.value == value) {
|
if (src2.value == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (src2.value) {
|
if (src2_use) {
|
||||||
src2.value->RemoveUse(src2_use);
|
src2.value->RemoveUse(src2_use);
|
||||||
}
|
}
|
||||||
src2.value = value;
|
src2.value = value;
|
||||||
|
@ -41,7 +41,7 @@ void Instr::set_src3(Value* value) {
|
||||||
if (src3.value == value) {
|
if (src3.value == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (src3.value) {
|
if (src3_use) {
|
||||||
src3.value->RemoveUse(src3_use);
|
src3.value->RemoveUse(src3_use);
|
||||||
}
|
}
|
||||||
src3.value = value;
|
src3.value = value;
|
||||||
|
|
|
@ -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 <alloy/hir/opcodes.h>
|
||||||
|
|
||||||
|
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 <alloy/hir/opcodes.inl>
|
||||||
|
#undef DEFINE_OPCODE
|
||||||
|
|
||||||
|
} // namespace hir
|
||||||
|
} // namespace alloy
|
|
@ -212,6 +212,12 @@ typedef struct {
|
||||||
} OpcodeInfo;
|
} OpcodeInfo;
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFINE_OPCODE(num, name, sig, flags) \
|
||||||
|
extern const OpcodeInfo num##_info;
|
||||||
|
#include <alloy/hir/opcodes.inl>
|
||||||
|
#undef DEFINE_OPCODE
|
||||||
|
|
||||||
|
|
||||||
} // namespace hir
|
} // namespace hir
|
||||||
} // namespace alloy
|
} // namespace alloy
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
@ -9,7 +9,9 @@
|
||||||
'instr.h',
|
'instr.h',
|
||||||
'label.cc',
|
'label.cc',
|
||||||
'label.h',
|
'label.h',
|
||||||
|
'opcodes.cc',
|
||||||
'opcodes.h',
|
'opcodes.h',
|
||||||
|
'opcodes.inl',
|
||||||
'tracing.h',
|
'tracing.h',
|
||||||
'value.cc',
|
'value.cc',
|
||||||
'value.h',
|
'value.h',
|
||||||
|
|
Loading…
Reference in New Issue