Running clang-format on alloy.

All except x64_sequences, which needs work.
This commit is contained in:
Ben Vanik 2014-07-10 20:20:00 -07:00
parent 0158380cfc
commit 7daa85179c
139 changed files with 6925 additions and 6998 deletions

View File

@ -14,7 +14,6 @@
#include <gflags/gflags.h> #include <gflags/gflags.h>
DECLARE_bool(debug); DECLARE_bool(debug);
DECLARE_bool(always_disasm); DECLARE_bool(always_disasm);
@ -23,10 +22,4 @@ DECLARE_bool(validate_hir);
DECLARE_uint64(break_on_instruction); DECLARE_uint64(break_on_instruction);
DECLARE_uint64(break_on_memory); DECLARE_uint64(break_on_memory);
namespace alloy {
} // namespace alloy
#endif // ALLOY_ALLOY_PRIVATE_H_ #endif // ALLOY_ALLOY_PRIVATE_H_

View File

@ -12,7 +12,6 @@
using namespace alloy; using namespace alloy;
#if 0 && DEBUG #if 0 && DEBUG
#define DEFAULT_DEBUG_FLAG true #define DEFAULT_DEBUG_FLAG true
#else #else
@ -21,7 +20,8 @@ using namespace alloy;
DEFINE_bool(debug, DEFAULT_DEBUG_FLAG, DEFINE_bool(debug, DEFAULT_DEBUG_FLAG,
"Allow debugging and retain debug information."); "Allow debugging and retain debug information.");
DEFINE_bool(always_disasm, false, DEFINE_bool(
always_disasm, false,
"Always add debug info to functions, even when no debugger is attached."); "Always add debug info to functions, even when no debugger is attached.");
DEFINE_bool(validate_hir, false, DEFINE_bool(validate_hir, false,

View File

@ -18,10 +18,4 @@
#include <alloy/runtime/thread_state.h> #include <alloy/runtime/thread_state.h>
#include <alloy/tracing/tracing.h> #include <alloy/tracing/tracing.h>
namespace alloy {
} // namespace alloy
#endif // ALLOY_ALLOY_H_ #endif // ALLOY_ALLOY_H_

View File

@ -9,13 +9,10 @@
#include <alloy/arena.h> #include <alloy/arena.h>
using namespace alloy; namespace alloy {
Arena::Arena(size_t chunk_size)
Arena::Arena(size_t chunk_size) : : chunk_size_(chunk_size), head_chunk_(NULL), active_chunk_(NULL) {}
chunk_size_(chunk_size),
head_chunk_(NULL), active_chunk_(NULL) {
}
Arena::~Arena() { Arena::~Arena() {
Reset(); Reset();
@ -88,9 +85,8 @@ void* Arena::CloneContents() {
return result; return result;
} }
Arena::Chunk::Chunk(size_t chunk_size) : Arena::Chunk::Chunk(size_t chunk_size)
next(NULL), : next(NULL), capacity(chunk_size), buffer(0), offset(0) {
capacity(chunk_size), buffer(0), offset(0) {
buffer = (uint8_t*)xe_malloc(capacity); buffer = (uint8_t*)xe_malloc(capacity);
} }
@ -99,3 +95,5 @@ Arena::Chunk::~Chunk() {
xe_free(buffer); xe_free(buffer);
} }
} }
} // namespace alloy

View File

@ -12,10 +12,8 @@
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
class Arena { class Arena {
public: public:
Arena(size_t chunk_size = 4 * 1024 * 1024); Arena(size_t chunk_size = 4 * 1024 * 1024);
@ -25,7 +23,8 @@ public:
void DebugFill(); void DebugFill();
void* Alloc(size_t size); void* Alloc(size_t size);
template<typename T> T* Alloc() { template <typename T>
T* Alloc() {
return (T*)Alloc(sizeof(T)); return (T*)Alloc(sizeof(T));
} }
@ -50,8 +49,6 @@ private:
Chunk* active_chunk_; Chunk* active_chunk_;
}; };
} // namespace alloy } // namespace alloy
#endif // ALLOY_ARENA_H_ #endif // ALLOY_ARENA_H_

View File

@ -11,22 +11,16 @@
#include <alloy/backend/tracing.h> #include <alloy/backend/tracing.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::runtime;
Assembler::Assembler(Backend* backend) : backend_(backend) {}
Assembler::Assembler(Backend* backend) : Assembler::~Assembler() { Reset(); }
backend_(backend) {
}
Assembler::~Assembler() { int Assembler::Initialize() { return 0; }
Reset();
}
int Assembler::Initialize() { void Assembler::Reset() {}
return 0;
}
void Assembler::Reset() { } // namespace backend
} } // namespace alloy

View File

@ -12,25 +12,23 @@
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
namespace hir { namespace hir {
class HIRBuilder; class HIRBuilder;
} } // namespace hir
namespace runtime { namespace runtime {
class DebugInfo; class DebugInfo;
class Function; class Function;
class FunctionInfo; class FunctionInfo;
class Runtime; class Runtime;
} } // namespace runtime
} } // namespace alloy
namespace alloy { namespace alloy {
namespace backend { namespace backend {
class Backend; class Backend;
class Assembler { class Assembler {
public: public:
Assembler(Backend* backend); Assembler(Backend* backend);
@ -40,18 +38,16 @@ public:
virtual void Reset(); virtual void Reset();
virtual int Assemble( virtual int Assemble(runtime::FunctionInfo* symbol_info,
runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, hir::HIRBuilder* builder, uint32_t debug_info_flags,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info, runtime::DebugInfo* debug_info,
runtime::Function** out_function) = 0; runtime::Function** out_function) = 0;
protected: protected:
Backend* backend_; Backend* backend_;
}; };
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_ASSEMBLER_H_ #endif // ALLOY_BACKEND_ASSEMBLER_H_

View File

@ -11,26 +11,22 @@
#include <alloy/backend/tracing.h> #include <alloy/backend/tracing.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::runtime;
using alloy::runtime::Runtime;
Backend::Backend(Runtime* runtime) : Backend::Backend(Runtime* runtime) : runtime_(runtime) {
runtime_(runtime) {
xe_zero_struct(&machine_info_, sizeof(machine_info_)); xe_zero_struct(&machine_info_, sizeof(machine_info_));
} }
Backend::~Backend() { Backend::~Backend() {}
}
int Backend::Initialize() { int Backend::Initialize() { return 0; }
return 0;
}
void* Backend::AllocThreadData() { void* Backend::AllocThreadData() { return NULL; }
return NULL;
}
void Backend::FreeThreadData(void* thread_data) { void Backend::FreeThreadData(void* thread_data) {}
}
} // namespace backend
} // namespace alloy

View File

@ -13,15 +13,17 @@
#include <alloy/core.h> #include <alloy/core.h>
#include <alloy/backend/machine_info.h> #include <alloy/backend/machine_info.h>
namespace alloy {
namespace alloy { namespace runtime { class Runtime; } } namespace runtime {
class Runtime;
} // namespace runtime
} // namespace alloy
namespace alloy { namespace alloy {
namespace backend { namespace backend {
class Assembler; class Assembler;
class Backend { class Backend {
public: public:
Backend(runtime::Runtime* runtime); Backend(runtime::Runtime* runtime);
@ -42,9 +44,7 @@ protected:
MachineInfo machine_info_; MachineInfo machine_info_;
}; };
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_BACKEND_H_ #endif // ALLOY_BACKEND_BACKEND_H_

View File

@ -17,21 +17,19 @@
#include <alloy/hir/label.h> #include <alloy/hir/label.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::backend::ivm; namespace ivm {
using namespace alloy::hir;
using namespace alloy::runtime;
using alloy::hir::HIRBuilder;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
IVMAssembler::IVMAssembler(Backend* backend) : IVMAssembler::IVMAssembler(Backend* backend)
source_map_arena_(128 * 1024), : source_map_arena_(128 * 1024), Assembler(backend) {}
Assembler(backend) {
}
IVMAssembler::~IVMAssembler() { IVMAssembler::~IVMAssembler() {
alloy::tracing::WriteEvent(EventType::AssemblerDeinit({ alloy::tracing::WriteEvent(EventType::AssemblerDeinit({}));
}));
} }
int IVMAssembler::Initialize() { int IVMAssembler::Initialize() {
@ -40,8 +38,7 @@ int IVMAssembler::Initialize() {
return result; return result;
} }
alloy::tracing::WriteEvent(EventType::AssemblerInit({ alloy::tracing::WriteEvent(EventType::AssemblerInit({}));
}));
return result; return result;
} }
@ -53,9 +50,9 @@ void IVMAssembler::Reset() {
Assembler::Reset(); Assembler::Reset();
} }
int IVMAssembler::Assemble( int IVMAssembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
FunctionInfo* symbol_info, HIRBuilder* builder, uint32_t debug_info_flags,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info, runtime::DebugInfo* debug_info,
Function** out_function) { Function** out_function) {
IVMFunction* fn = new IVMFunction(symbol_info); IVMFunction* fn = new IVMFunction(symbol_info);
fn->set_debug_info(debug_info); fn->set_debug_info(debug_info);
@ -89,13 +86,13 @@ int IVMAssembler::Assemble(
auto block = builder->first_block(); auto block = builder->first_block();
while (block) { while (block) {
Label* label = block->label_head; auto label = block->label_head;
while (label) { while (label) {
label->tag = (void*)(0x80000000 | ctx.intcode_count); label->tag = (void*)(0x80000000 | ctx.intcode_count);
label = label->next; label = label->next;
} }
Instr* i = block->instr_head; auto i = block->instr_head;
while (i) { while (i) {
int result = TranslateIntCodes(ctx, i); int result = TranslateIntCodes(ctx, i);
i = i->next; i = i->next;
@ -108,7 +105,8 @@ int IVMAssembler::Assemble(
// Fixup label references. // Fixup label references.
LabelRef* label_ref = ctx.label_ref_head; LabelRef* label_ref = ctx.label_ref_head;
while (label_ref) { while (label_ref) {
label_ref->instr->src1_reg = (uint32_t)(intptr_t)label_ref->label->tag & ~0x80000000; label_ref->instr->src1_reg =
(uint32_t)(intptr_t)label_ref->label->tag & ~0x80000000;
label_ref = label_ref->next; label_ref = label_ref->next;
} }
@ -117,3 +115,7 @@ int IVMAssembler::Assemble(
*out_function = fn; *out_function = fn;
return 0; return 0;
} }
} // namespace ivm
} // namespace backend
} // namespace alloy

View File

@ -14,12 +14,10 @@
#include <alloy/backend/assembler.h> #include <alloy/backend/assembler.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace ivm { namespace ivm {
class IVMAssembler : public Assembler { class IVMAssembler : public Assembler {
public: public:
IVMAssembler(Backend* backend); IVMAssembler(Backend* backend);
@ -29,9 +27,9 @@ public:
virtual void Reset(); virtual void Reset();
virtual int Assemble( virtual int Assemble(runtime::FunctionInfo* symbol_info,
runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, hir::HIRBuilder* builder, uint32_t debug_info_flags,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info, runtime::DebugInfo* debug_info,
runtime::Function** out_function); runtime::Function** out_function);
private: private:
@ -40,10 +38,8 @@ private:
Arena scratch_arena_; Arena scratch_arena_;
}; };
} // namespace ivm } // namespace ivm
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_ #endif // ALLOY_BACKEND_IVM_IVM_ASSEMBLER_H_

View File

@ -13,20 +13,15 @@
#include <alloy/backend/ivm/ivm_stack.h> #include <alloy/backend/ivm/ivm_stack.h>
#include <alloy/backend/ivm/tracing.h> #include <alloy/backend/ivm/tracing.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::backend::ivm; namespace ivm {
using namespace alloy::runtime;
using alloy::runtime::Runtime;
IVMBackend::IVMBackend(Runtime* runtime) : IVMBackend::IVMBackend(Runtime* runtime) : Backend(runtime) {}
Backend(runtime) {
}
IVMBackend::~IVMBackend() { IVMBackend::~IVMBackend() { alloy::tracing::WriteEvent(EventType::Deinit({})); }
alloy::tracing::WriteEvent(EventType::Deinit({
}));
}
int IVMBackend::Initialize() { int IVMBackend::Initialize() {
int result = Backend::Initialize(); int result = Backend::Initialize();
@ -35,34 +30,28 @@ int IVMBackend::Initialize() {
} }
machine_info_.register_sets[0] = { machine_info_.register_sets[0] = {
0, 0, "gpr", MachineInfo::RegisterSet::INT_TYPES, 16,
"gpr",
MachineInfo::RegisterSet::INT_TYPES,
16,
}; };
machine_info_.register_sets[1] = { machine_info_.register_sets[1] = {
1, 1, "vec", MachineInfo::RegisterSet::FLOAT_TYPES |
"vec",
MachineInfo::RegisterSet::FLOAT_TYPES |
MachineInfo::RegisterSet::VEC_TYPES, MachineInfo::RegisterSet::VEC_TYPES,
16, 16,
}; };
alloy::tracing::WriteEvent(EventType::Init({ alloy::tracing::WriteEvent(EventType::Init({}));
}));
return result; return result;
} }
void* IVMBackend::AllocThreadData() { void* IVMBackend::AllocThreadData() { return new IVMStack(); }
return new IVMStack();
}
void IVMBackend::FreeThreadData(void* thread_data) { void IVMBackend::FreeThreadData(void* thread_data) {
auto stack = (IVMStack*)thread_data; auto stack = (IVMStack*)thread_data;
delete stack; delete stack;
} }
Assembler* IVMBackend::CreateAssembler() { Assembler* IVMBackend::CreateAssembler() { return new IVMAssembler(this); }
return new IVMAssembler(this);
} } // namespace ivm
} // namespace backend
} // namespace alloy

View File

@ -14,15 +14,12 @@
#include <alloy/backend/backend.h> #include <alloy/backend/backend.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace ivm { namespace ivm {
#define ALLOY_HAS_IVM_BACKEND 1 #define ALLOY_HAS_IVM_BACKEND 1
class IVMBackend : public Backend { class IVMBackend : public Backend {
public: public:
IVMBackend(runtime::Runtime* runtime); IVMBackend(runtime::Runtime* runtime);
@ -36,10 +33,8 @@ public:
virtual Assembler* CreateAssembler(); virtual Assembler* CreateAssembler();
}; };
} // namespace ivm } // namespace ivm
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_IVM_IVM_BACKEND_H_ #endif // ALLOY_BACKEND_IVM_IVM_BACKEND_H_

View File

@ -14,17 +14,21 @@
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
#include <alloy/runtime/thread_state.h> #include <alloy/runtime/thread_state.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::backend::ivm; namespace ivm {
using namespace alloy::runtime;
using alloy::runtime::Breakpoint;
using alloy::runtime::FunctionInfo;
using alloy::runtime::ThreadState;
IVMFunction::IVMFunction(FunctionInfo* symbol_info) : IVMFunction::IVMFunction(FunctionInfo* symbol_info)
register_count_(0), intcode_count_(0), intcodes_(0), : register_count_(0),
source_map_count_(0), source_map_(0), intcode_count_(0),
Function(symbol_info) { intcodes_(0),
} source_map_count_(0),
source_map_(0),
Function(symbol_info) {}
IVMFunction::~IVMFunction() { IVMFunction::~IVMFunction() {
xe_free(intcodes_); xe_free(intcodes_);
@ -57,8 +61,7 @@ int IVMFunction::AddBreakpointImpl(Breakpoint* breakpoint) {
} }
// TEMP breakpoints always overwrite normal ones. // TEMP breakpoints always overwrite normal ones.
if (!i->debug_flags || if (!i->debug_flags || breakpoint->type() == Breakpoint::TEMP_TYPE) {
breakpoint->type() == Breakpoint::TEMP_TYPE) {
uint64_t breakpoint_ptr = (uint64_t)breakpoint; uint64_t breakpoint_ptr = (uint64_t)breakpoint;
i->src2_reg = (uint32_t)breakpoint_ptr; i->src2_reg = (uint32_t)breakpoint_ptr;
i->src3_reg = (uint32_t)(breakpoint_ptr >> 32); i->src3_reg = (uint32_t)(breakpoint_ptr >> 32);
@ -177,3 +180,7 @@ int IVMFunction::CallImpl(ThreadState* thread_state, uint64_t return_address) {
return 0; return 0;
} }
} // namespace ivm
} // namespace backend
} // namespace alloy

File diff suppressed because it is too large Load Diff

View File

@ -15,14 +15,16 @@
#include <alloy/hir/instr.h> #include <alloy/hir/instr.h>
#include <alloy/hir/opcodes.h> #include <alloy/hir/opcodes.h>
namespace alloy { namespace runtime { class ThreadState; } } namespace alloy {
namespace runtime {
class ThreadState;
}
}
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace ivm { namespace ivm {
typedef union { typedef union {
int8_t i8; int8_t i8;
uint8_t u8; uint8_t u8;
@ -37,7 +39,6 @@ typedef union {
vec128_t v128; vec128_t v128;
} Register; } Register;
typedef struct { typedef struct {
Register* rf; Register* rf;
uint8_t* locals; uint8_t* locals;
@ -51,15 +52,12 @@ typedef struct {
uint64_t call_return_address; uint64_t call_return_address;
} IntCodeState; } IntCodeState;
struct IntCode_s; struct IntCode_s;
typedef uint32_t (*IntCodeFn)( typedef uint32_t (*IntCodeFn)(IntCodeState& ics, const struct IntCode_s* i);
IntCodeState& ics, const struct IntCode_s* i);
#define IA_RETURN 0xA0000000 #define IA_RETURN 0xA0000000
#define IA_NEXT 0xB0000000 #define IA_NEXT 0xB0000000
typedef struct IntCode_s { typedef struct IntCode_s {
IntCodeFn intcode_fn; IntCodeFn intcode_fn;
uint16_t flags; uint16_t flags;
@ -81,20 +79,17 @@ typedef struct IntCode_s {
// debugging info/etc // debugging info/etc
} IntCode; } IntCode;
typedef struct LabelRef_s { typedef struct LabelRef_s {
hir::Label* label; hir::Label* label;
IntCode* instr; IntCode* instr;
LabelRef_s* next; LabelRef_s* next;
} LabelRef; } LabelRef;
typedef struct SourceMapEntry_s { typedef struct SourceMapEntry_s {
uint64_t source_offset; uint64_t source_offset;
uint64_t intcode_index; uint64_t intcode_index;
} SourceMapEntry; } SourceMapEntry;
typedef struct { typedef struct {
uint32_t register_count; uint32_t register_count;
size_t intcode_count; size_t intcode_count;
@ -106,13 +101,10 @@ typedef struct {
size_t stack_size; size_t stack_size;
} TranslationContext; } TranslationContext;
int TranslateIntCodes(TranslationContext& ctx, hir::Instr* i); int TranslateIntCodes(TranslationContext& ctx, hir::Instr* i);
} // namespace ivm } // namespace ivm
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_IVM_INTCODE_H_ #endif // ALLOY_BACKEND_IVM_INTCODE_H_

View File

@ -9,15 +9,12 @@
#include <alloy/backend/ivm/ivm_stack.h> #include <alloy/backend/ivm/ivm_stack.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::backend::ivm; namespace ivm {
IVMStack::IVMStack()
IVMStack::IVMStack() : : chunk_size_(2 * 1024 * 1024), head_chunk_(NULL), active_chunk_(NULL) {}
chunk_size_(2 * 1024 * 1024),
head_chunk_(NULL), active_chunk_(NULL) {
}
IVMStack::~IVMStack() { IVMStack::~IVMStack() {
Chunk* chunk = head_chunk_; Chunk* chunk = head_chunk_;
@ -66,9 +63,8 @@ void IVMStack::Free(size_t register_count) {
} }
} }
IVMStack::Chunk::Chunk(size_t chunk_size) : IVMStack::Chunk::Chunk(size_t chunk_size)
prev(NULL), next(NULL), : prev(NULL), next(NULL), capacity(chunk_size), buffer(0), offset(0) {
capacity(chunk_size), buffer(0), offset(0) {
buffer = (uint8_t*)xe_malloc(capacity); buffer = (uint8_t*)xe_malloc(capacity);
} }
@ -77,3 +73,7 @@ IVMStack::Chunk::~Chunk() {
xe_free(buffer); xe_free(buffer);
} }
} }
} // namespace ivm
} // namespace backend
} // namespace alloy

View File

@ -14,12 +14,10 @@
#include <alloy/backend/ivm/ivm_intcode.h> #include <alloy/backend/ivm/ivm_intcode.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace ivm { namespace ivm {
class IVMStack { class IVMStack {
public: public:
IVMStack(); IVMStack();
@ -48,10 +46,8 @@ private:
Chunk* active_chunk_; Chunk* active_chunk_;
}; };
} // namespace ivm } // namespace ivm
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_IVM_IVM_STACK_H_ #endif // ALLOY_BACKEND_IVM_IVM_STACK_H_

View File

@ -12,21 +12,17 @@
#include <alloy/backend/tracing.h> #include <alloy/backend/tracing.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace ivm { namespace ivm {
const uint32_t ALLOY_BACKEND_IVM = const uint32_t ALLOY_BACKEND_IVM = alloy::backend::EventType::ALLOY_BACKEND_IVM;
alloy::backend::EventType::ALLOY_BACKEND_IVM;
class EventType { class EventType {
public: public:
enum { enum {
ALLOY_BACKEND_IVM_INIT = ALLOY_BACKEND_IVM | (1), ALLOY_BACKEND_IVM_INIT = ALLOY_BACKEND_IVM | (1),
ALLOY_BACKEND_IVM_DEINIT = ALLOY_BACKEND_IVM | (2), ALLOY_BACKEND_IVM_DEINIT = ALLOY_BACKEND_IVM | (2),
ALLOY_BACKEND_IVM_ASSEMBLER = ALLOY_BACKEND_IVM | (1 << 20), ALLOY_BACKEND_IVM_ASSEMBLER = ALLOY_BACKEND_IVM | (1 << 20),
ALLOY_BACKEND_IVM_ASSEMBLER_INIT = ALLOY_BACKEND_IVM_ASSEMBLER | (1), ALLOY_BACKEND_IVM_ASSEMBLER_INIT = ALLOY_BACKEND_IVM_ASSEMBLER | (1),
ALLOY_BACKEND_IVM_ASSEMBLER_DEINIT = ALLOY_BACKEND_IVM_ASSEMBLER | (2), ALLOY_BACKEND_IVM_ASSEMBLER_DEINIT = ALLOY_BACKEND_IVM_ASSEMBLER | (2),
@ -47,10 +43,8 @@ public:
} AssemblerDeinit; } AssemblerDeinit;
}; };
} // namespace ivm } // namespace ivm
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_IVM_TRACING_H_ #endif // ALLOY_BACKEND_IVM_TRACING_H_

View File

@ -12,11 +12,9 @@
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
struct MachineInfo { struct MachineInfo {
struct RegisterSet { struct RegisterSet {
enum Types { enum Types {
@ -31,9 +29,7 @@ struct MachineInfo {
} register_sets[8]; } register_sets[8];
}; };
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_MACHINE_INFO_H_ #endif // ALLOY_BACKEND_MACHINE_INFO_H_

View File

@ -13,13 +13,11 @@
#include <alloy/tracing/tracing.h> #include <alloy/tracing/tracing.h>
#include <alloy/tracing/event_type.h> #include <alloy/tracing/event_type.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
const uint32_t ALLOY_BACKEND = alloy::tracing::EventType::ALLOY_BACKEND; const uint32_t ALLOY_BACKEND = alloy::tracing::EventType::ALLOY_BACKEND;
class EventType { class EventType {
public: public:
enum { enum {
@ -28,9 +26,7 @@ public:
}; };
}; };
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_TRACING_H_ #endif // ALLOY_BACKEND_TRACING_H_

View File

@ -12,21 +12,17 @@
#include <alloy/backend/tracing.h> #include <alloy/backend/tracing.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
const uint32_t ALLOY_BACKEND_X64 = const uint32_t ALLOY_BACKEND_X64 = alloy::backend::EventType::ALLOY_BACKEND_X64;
alloy::backend::EventType::ALLOY_BACKEND_X64;
class EventType { class EventType {
public: public:
enum { enum {
ALLOY_BACKEND_X64_INIT = ALLOY_BACKEND_X64 | (1), ALLOY_BACKEND_X64_INIT = ALLOY_BACKEND_X64 | (1),
ALLOY_BACKEND_X64_DEINIT = ALLOY_BACKEND_X64 | (2), ALLOY_BACKEND_X64_DEINIT = ALLOY_BACKEND_X64 | (2),
ALLOY_BACKEND_X64_ASSEMBLER = ALLOY_BACKEND_X64 | (1 << 20), ALLOY_BACKEND_X64_ASSEMBLER = ALLOY_BACKEND_X64 | (1 << 20),
ALLOY_BACKEND_X64_ASSEMBLER_INIT = ALLOY_BACKEND_X64_ASSEMBLER | (1), ALLOY_BACKEND_X64_ASSEMBLER_INIT = ALLOY_BACKEND_X64_ASSEMBLER | (1),
ALLOY_BACKEND_X64_ASSEMBLER_DEINIT = ALLOY_BACKEND_X64_ASSEMBLER | (2), ALLOY_BACKEND_X64_ASSEMBLER_DEINIT = ALLOY_BACKEND_X64_ASSEMBLER | (2),
@ -47,10 +43,8 @@ public:
} AssemblerDeinit; } AssemblerDeinit;
}; };
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_TRACING_H_ #endif // ALLOY_BACKEND_X64_TRACING_H_

View File

@ -21,22 +21,23 @@ namespace BE {
#include <beaengine/BeaEngine.h> #include <beaengine/BeaEngine.h>
} }
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::backend::x64; namespace x64 {
using namespace alloy::hir;
// TODO(benvanik): remove when enums redefined.
using namespace alloy::runtime; using namespace alloy::runtime;
using alloy::hir::HIRBuilder;
using alloy::runtime::DebugInfo;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
X64Assembler::X64Assembler(X64Backend* backend) : X64Assembler::X64Assembler(X64Backend* backend)
x64_backend_(backend), : x64_backend_(backend), emitter_(0), allocator_(0), Assembler(backend) {}
emitter_(0), allocator_(0),
Assembler(backend) {
}
X64Assembler::~X64Assembler() { X64Assembler::~X64Assembler() {
alloy::tracing::WriteEvent(EventType::AssemblerDeinit({ alloy::tracing::WriteEvent(EventType::AssemblerDeinit({}));
}));
delete emitter_; delete emitter_;
delete allocator_; delete allocator_;
@ -51,8 +52,7 @@ int X64Assembler::Initialize() {
allocator_ = new XbyakAllocator(); allocator_ = new XbyakAllocator();
emitter_ = new X64Emitter(x64_backend_, allocator_); emitter_ = new X64Emitter(x64_backend_, allocator_);
alloy::tracing::WriteEvent(EventType::AssemblerInit({ alloy::tracing::WriteEvent(EventType::AssemblerInit({}));
}));
return result; return result;
} }
@ -62,8 +62,7 @@ void X64Assembler::Reset() {
Assembler::Reset(); Assembler::Reset();
} }
int X64Assembler::Assemble( int X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
FunctionInfo* symbol_info, HIRBuilder* builder,
uint32_t debug_info_flags, DebugInfo* debug_info, uint32_t debug_info_flags, DebugInfo* debug_info,
Function** out_function) { Function** out_function) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -73,13 +72,12 @@ int X64Assembler::Assemble(
// Lower HIR -> x64. // Lower HIR -> x64.
void* machine_code = 0; void* machine_code = 0;
size_t code_size = 0; size_t code_size = 0;
result = emitter_->Emit(builder, result = emitter_->Emit(builder, debug_info_flags, debug_info, machine_code,
debug_info_flags, debug_info, code_size);
machine_code, code_size);
XEEXPECTZERO(result); XEEXPECTZERO(result);
// Stash generated machine code. // Stash generated machine code.
if (debug_info_flags & DEBUG_INFO_MACHINE_CODE_DISASM) { if (debug_info_flags & DebugInfoFlags::DEBUG_INFO_MACHINE_CODE_DISASM) {
DumpMachineCode(debug_info, machine_code, code_size, &string_buffer_); DumpMachineCode(debug_info, machine_code, code_size, &string_buffer_);
debug_info->set_machine_code_disasm(string_buffer_.ToString()); debug_info->set_machine_code_disasm(string_buffer_.ToString());
string_buffer_.Reset(); string_buffer_.Reset();
@ -100,10 +98,8 @@ XECLEANUP:
return result; return result;
} }
void X64Assembler::DumpMachineCode( void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
DebugInfo* debug_info, size_t code_size, StringBuffer* str) {
void* machine_code, size_t code_size,
StringBuffer* str) {
BE::DISASM disasm; BE::DISASM disasm;
xe_zero_struct(&disasm, sizeof(disasm)); xe_zero_struct(&disasm, sizeof(disasm));
disasm.Archi = 64; disasm.Archi = 64;
@ -113,8 +109,8 @@ void X64Assembler::DumpMachineCode(
uint64_t prev_source_offset = 0; uint64_t prev_source_offset = 0;
while (disasm.EIP < eip_end) { while (disasm.EIP < eip_end) {
// Look up source offset. // Look up source offset.
auto map_entry = debug_info->LookupCodeOffset( auto map_entry =
disasm.EIP - (BE::UIntPtr)machine_code); debug_info->LookupCodeOffset(disasm.EIP - (BE::UIntPtr)machine_code);
if (map_entry) { if (map_entry) {
if (map_entry->source_offset == prev_source_offset) { if (map_entry->source_offset == prev_source_offset) {
str->Append(" "); str->Append(" ");
@ -134,3 +130,7 @@ void X64Assembler::DumpMachineCode(
disasm.EIP += len; disasm.EIP += len;
} }
} }
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@ -14,7 +14,6 @@
#include <alloy/backend/assembler.h> #include <alloy/backend/assembler.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
@ -23,7 +22,6 @@ class X64Backend;
class X64Emitter; class X64Emitter;
class XbyakAllocator; class XbyakAllocator;
class X64Assembler : public Assembler { class X64Assembler : public Assembler {
public: public:
X64Assembler(X64Backend* backend); X64Assembler(X64Backend* backend);
@ -33,15 +31,14 @@ public:
virtual void Reset(); virtual void Reset();
virtual int Assemble( virtual int Assemble(runtime::FunctionInfo* symbol_info,
runtime::FunctionInfo* symbol_info, hir::HIRBuilder* builder, hir::HIRBuilder* builder, uint32_t debug_info_flags,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info, runtime::DebugInfo* debug_info,
runtime::Function** out_function); runtime::Function** out_function);
private: private:
void DumpMachineCode(runtime::DebugInfo* debug_info, void DumpMachineCode(runtime::DebugInfo* debug_info, void* machine_code,
void* machine_code, size_t code_size, size_t code_size, StringBuffer* str);
StringBuffer* str);
private: private:
X64Backend* x64_backend_; X64Backend* x64_backend_;
@ -51,10 +48,8 @@ private:
StringBuffer string_buffer_; StringBuffer string_buffer_;
}; };
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_ASSEMBLER_H_ #endif // ALLOY_BACKEND_X64_X64_ASSEMBLER_H_

View File

@ -15,20 +15,16 @@
#include <alloy/backend/x64/x64_sequences.h> #include <alloy/backend/x64/x64_sequences.h>
#include <alloy/backend/x64/x64_thunk_emitter.h> #include <alloy/backend/x64/x64_thunk_emitter.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::backend::x64; namespace x64 {
using namespace alloy::runtime;
using alloy::runtime::Runtime;
X64Backend::X64Backend(Runtime* runtime) : X64Backend::X64Backend(Runtime* runtime) : code_cache_(0), Backend(runtime) {}
code_cache_(0),
Backend(runtime) {
}
X64Backend::~X64Backend() { X64Backend::~X64Backend() {
alloy::tracing::WriteEvent(EventType::Deinit({ alloy::tracing::WriteEvent(EventType::Deinit({}));
}));
delete code_cache_; delete code_cache_;
} }
@ -41,15 +37,10 @@ int X64Backend::Initialize() {
RegisterSequences(); RegisterSequences();
machine_info_.register_sets[0] = { machine_info_.register_sets[0] = {
0, 0, "gpr", MachineInfo::RegisterSet::INT_TYPES, X64Emitter::GPR_COUNT,
"gpr",
MachineInfo::RegisterSet::INT_TYPES,
X64Emitter::GPR_COUNT,
}; };
machine_info_.register_sets[1] = { machine_info_.register_sets[1] = {
1, 1, "xmm", MachineInfo::RegisterSet::FLOAT_TYPES |
"xmm",
MachineInfo::RegisterSet::FLOAT_TYPES |
MachineInfo::RegisterSet::VEC_TYPES, MachineInfo::RegisterSet::VEC_TYPES,
X64Emitter::XMM_COUNT, X64Emitter::XMM_COUNT,
}; };
@ -67,12 +58,13 @@ int X64Backend::Initialize() {
delete thunk_emitter; delete thunk_emitter;
delete allocator; delete allocator;
alloy::tracing::WriteEvent(EventType::Init({ alloy::tracing::WriteEvent(EventType::Init({}));
}));
return result; return result;
} }
Assembler* X64Backend::CreateAssembler() { Assembler* X64Backend::CreateAssembler() { return new X64Assembler(this); }
return new X64Assembler(this);
} } // namespace x64
} // namespace backend
} // namespace alloy

View File

@ -14,17 +14,14 @@
#include <alloy/backend/backend.h> #include <alloy/backend/backend.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
class X64CodeCache; class X64CodeCache;
#define ALLOY_HAS_X64_BACKEND 1 #define ALLOY_HAS_X64_BACKEND 1
typedef void* (*HostToGuestThunk)(void* target, void* arg0, void* arg1); typedef void* (*HostToGuestThunk)(void* target, void* arg0, void* arg1);
typedef void* (*GuestToHostThunk)(void* target, void* arg0, void* arg1); typedef void* (*GuestToHostThunk)(void* target, void* arg0, void* arg1);
@ -47,10 +44,8 @@ private:
GuestToHostThunk guest_to_host_thunk_; GuestToHostThunk guest_to_host_thunk_;
}; };
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_BACKEND_H_ #endif // ALLOY_BACKEND_X64_X64_BACKEND_H_

View File

@ -11,11 +11,6 @@
#include <alloy/backend/x64/tracing.h> #include <alloy/backend/x64/tracing.h>
using namespace alloy;
using namespace alloy::backend;
using namespace alloy::backend::x64;
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
@ -24,6 +19,7 @@ class X64CodeChunk {
public: public:
X64CodeChunk(size_t chunk_size); X64CodeChunk(size_t chunk_size);
~X64CodeChunk(); ~X64CodeChunk();
public: public:
X64CodeChunk* next; X64CodeChunk* next;
size_t capacity; size_t capacity;
@ -44,16 +40,8 @@ public:
void AddTableEntry(uint8_t* code, size_t code_size, size_t stack_size); void AddTableEntry(uint8_t* code, size_t code_size, size_t stack_size);
}; };
X64CodeCache::X64CodeCache(size_t chunk_size)
} // namespace x64 : chunk_size_(chunk_size), head_chunk_(NULL), active_chunk_(NULL) {}
} // namespace backend
} // namespace alloy
X64CodeCache::X64CodeCache(size_t chunk_size) :
chunk_size_(chunk_size),
head_chunk_(NULL), active_chunk_(NULL) {
}
X64CodeCache::~X64CodeCache() { X64CodeCache::~X64CodeCache() {
std::lock_guard<std::mutex> guard(lock_); std::lock_guard<std::mutex> guard(lock_);
@ -66,9 +54,7 @@ X64CodeCache::~X64CodeCache() {
head_chunk_ = NULL; head_chunk_ = NULL;
} }
int X64CodeCache::Initialize() { int X64CodeCache::Initialize() { return 0; }
return 0;
}
void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size, void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
size_t stack_size) { size_t stack_size) {
@ -113,12 +99,9 @@ void* X64CodeCache::PlaceCode(void* machine_code, size_t code_size,
return final_address; return final_address;
} }
X64CodeChunk::X64CodeChunk(size_t chunk_size) : X64CodeChunk::X64CodeChunk(size_t chunk_size)
next(NULL), : next(NULL), capacity(chunk_size), buffer(0), offset(0) {
capacity(chunk_size), buffer(0), offset(0) { buffer = (uint8_t*)VirtualAlloc(NULL, capacity, MEM_RESERVE | MEM_COMMIT,
buffer = (uint8_t*)VirtualAlloc(
NULL, capacity,
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE); PAGE_EXECUTE_READWRITE);
fn_table_capacity = (uint32_t)XEROUNDUP(capacity / ESTIMATED_FN_SIZE, 16); fn_table_capacity = (uint32_t)XEROUNDUP(capacity / ESTIMATED_FN_SIZE, 16);
@ -126,12 +109,9 @@ X64CodeChunk::X64CodeChunk(size_t chunk_size) :
fn_table = (RUNTIME_FUNCTION*)xe_malloc(table_size); fn_table = (RUNTIME_FUNCTION*)xe_malloc(table_size);
fn_table_count = 0; fn_table_count = 0;
fn_table_handle = 0; fn_table_handle = 0;
RtlAddGrowableFunctionTable( RtlAddGrowableFunctionTable(&fn_table_handle, fn_table, fn_table_count,
&fn_table_handle, fn_table_capacity, (ULONG_PTR)buffer,
fn_table, (ULONG_PTR)buffer + capacity);
fn_table_count,
fn_table_capacity,
(ULONG_PTR)buffer, (ULONG_PTR)buffer + capacity);
} }
X64CodeChunk::~X64CodeChunk() { X64CodeChunk::~X64CodeChunk() {
@ -215,19 +195,17 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
RtlDeleteGrowableFunctionTable(fn_table_handle); RtlDeleteGrowableFunctionTable(fn_table_handle);
size_t old_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION); size_t old_size = fn_table_capacity * sizeof(RUNTIME_FUNCTION);
size_t new_size = old_size * 2; size_t new_size = old_size * 2;
auto new_table = (RUNTIME_FUNCTION*)xe_realloc(fn_table, old_size, new_size); auto new_table =
(RUNTIME_FUNCTION*)xe_realloc(fn_table, old_size, new_size);
XEASSERTNOTNULL(new_table); XEASSERTNOTNULL(new_table);
if (!new_table) { if (!new_table) {
return; return;
} }
fn_table = new_table; fn_table = new_table;
fn_table_capacity *= 2; fn_table_capacity *= 2;
RtlAddGrowableFunctionTable( RtlAddGrowableFunctionTable(&fn_table_handle, fn_table, fn_table_count,
&fn_table_handle, fn_table_capacity, (ULONG_PTR)buffer,
fn_table, (ULONG_PTR)buffer + capacity);
fn_table_count,
fn_table_capacity,
(ULONG_PTR)buffer, (ULONG_PTR)buffer + capacity);
} }
// Allocate unwind data. We know we have space because we overallocated. // Allocate unwind data. We know we have space because we overallocated.
@ -261,7 +239,8 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx // http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
size_t co = 0; size_t co = 0;
auto& unwind_code = unwind_info->UnwindCode[co++]; auto& unwind_code = unwind_info->UnwindCode[co++];
unwind_code.CodeOffset = 14; // end of instruction + 1 == offset of next instruction unwind_code.CodeOffset =
14; // end of instruction + 1 == offset of next instruction
unwind_code.UnwindOp = UWOP_ALLOC_SMALL; unwind_code.UnwindOp = UWOP_ALLOC_SMALL;
unwind_code.OpInfo = stack_size / 8 - 1; unwind_code.OpInfo = stack_size / 8 - 1;
} else { } else {
@ -280,7 +259,8 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx // http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
size_t co = 0; size_t co = 0;
auto& unwind_code = unwind_info->UnwindCode[co++]; auto& unwind_code = unwind_info->UnwindCode[co++];
unwind_code.CodeOffset = 7; // end of instruction + 1 == offset of next instruction unwind_code.CodeOffset =
7; // end of instruction + 1 == offset of next instruction
unwind_code.UnwindOp = UWOP_ALLOC_LARGE; unwind_code.UnwindOp = UWOP_ALLOC_LARGE;
unwind_code.OpInfo = 0; unwind_code.OpInfo = 0;
unwind_code = unwind_info->UnwindCode[co++]; unwind_code = unwind_info->UnwindCode[co++];
@ -296,3 +276,7 @@ void X64CodeChunk::AddTableEntry(uint8_t* code, size_t code_size,
// Notify the function table that it has new entries. // Notify the function table that it has new entries.
RtlGrowFunctionTable(fn_table_handle, fn_table_count); RtlGrowFunctionTable(fn_table_handle, fn_table_count);
} }
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@ -14,7 +14,6 @@
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
@ -42,10 +41,8 @@ private:
X64CodeChunk* active_chunk_; X64CodeChunk* active_chunk_;
}; };
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_CODE_CACHE_H_ #endif // ALLOY_BACKEND_X64_X64_CODE_CACHE_H_

View File

@ -20,18 +20,21 @@
#include <alloy/runtime/symbol_info.h> #include <alloy/runtime/symbol_info.h>
#include <alloy/runtime/thread_state.h> #include <alloy/runtime/thread_state.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::backend::x64; namespace x64 {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using namespace alloy::runtime; using namespace alloy::runtime;
using namespace Xbyak; using namespace Xbyak;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
namespace alloy { using alloy::runtime::Function;
namespace backend { using alloy::runtime::FunctionInfo;
namespace x64 { using alloy::runtime::SourceMapEntry;
using alloy::runtime::ThreadState;
static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024; static const size_t MAX_CODE_SIZE = 1 * 1024 * 1024;
@ -42,41 +45,29 @@ static const size_t STASH_OFFSET = 32;
// can get the value. // can get the value.
#define STORE_EFLAGS 1 #define STORE_EFLAGS 1
} // namespace x64
} // namespace backend
} // namespace alloy
const uint32_t X64Emitter::gpr_reg_map_[X64Emitter::GPR_COUNT] = { const uint32_t X64Emitter::gpr_reg_map_[X64Emitter::GPR_COUNT] = {
Operand::RBX, Operand::RBX, Operand::R12, Operand::R13, Operand::R14, Operand::R15,
Operand::R12, Operand::R13, Operand::R14, Operand::R15,
}; };
const uint32_t X64Emitter::xmm_reg_map_[X64Emitter::XMM_COUNT] = { const uint32_t X64Emitter::xmm_reg_map_[X64Emitter::XMM_COUNT] = {
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
}; };
X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator) : : runtime_(backend->runtime()),
runtime_(backend->runtime()),
backend_(backend), backend_(backend),
code_cache_(backend->code_cache()), code_cache_(backend->code_cache()),
allocator_(allocator), allocator_(allocator),
current_instr_(0), current_instr_(0),
CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator) { CodeGenerator(MAX_CODE_SIZE, AutoGrow, allocator) {}
}
X64Emitter::~X64Emitter() { X64Emitter::~X64Emitter() {}
}
int X64Emitter::Initialize() { int X64Emitter::Initialize() { return 0; }
return 0;
}
int X64Emitter::Emit( int X64Emitter::Emit(HIRBuilder* builder, uint32_t debug_info_flags,
HIRBuilder* builder, runtime::DebugInfo* debug_info, void*& out_code_address,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info, size_t& out_code_size) {
void*& out_code_address, size_t& out_code_size) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
// Reset. // Reset.
@ -99,8 +90,7 @@ int X64Emitter::Emit(
// Stash source map. // Stash source map.
if (debug_info_flags & DEBUG_INFO_SOURCE_MAP) { if (debug_info_flags & DEBUG_INFO_SOURCE_MAP) {
debug_info->InitializeSourceMap( debug_info->InitializeSourceMap(
source_map_count_, source_map_count_, (SourceMapEntry*)source_map_arena_.CloneContents());
(SourceMapEntry*)source_map_arena_.CloneContents());
} }
return 0; return 0;
@ -258,7 +248,8 @@ const size_t ASM_OFFSET = 2 + 2 + 8 + 2 + 8;
// 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
// 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
// 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
// 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 00H // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00
// 00H
uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) { uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) {
// TODO(benvanik): generate this thunk at runtime? or a shim? // TODO(benvanik): generate this thunk at runtime? or a shim?
@ -293,7 +284,8 @@ uint64_t ResolveFunctionSymbol(void* raw_context, uint64_t symbol_info_ptr) {
return addr; return addr;
} }
void X64Emitter::Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info) { void X64Emitter::Call(const hir::Instr* instr,
runtime::FunctionInfo* symbol_info) {
auto fn = reinterpret_cast<X64Function*>(symbol_info->function()); auto fn = reinterpret_cast<X64Function*>(symbol_info->function());
// Resolve address to the function to call and store in rax. // Resolve address to the function to call and store in rax.
// TODO(benvanik): caching/etc. For now this makes debugging easier. // TODO(benvanik): caching/etc. For now this makes debugging easier.
@ -372,12 +364,12 @@ void X64Emitter::CallIndirect(const hir::Instr* instr, const Reg64& reg) {
uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) { uint64_t UndefinedCallExtern(void* raw_context, uint64_t symbol_info_ptr) {
auto symbol_info = reinterpret_cast<FunctionInfo*>(symbol_info_ptr); auto symbol_info = reinterpret_cast<FunctionInfo*>(symbol_info_ptr);
XELOGW("undefined extern call to %.8X %s", XELOGW("undefined extern call to %.8X %s", symbol_info->address(),
symbol_info->address(),
symbol_info->name()); symbol_info->name());
return 0; return 0;
} }
void X64Emitter::CallExtern(const hir::Instr* instr, const FunctionInfo* symbol_info) { void X64Emitter::CallExtern(const hir::Instr* instr,
const FunctionInfo* symbol_info) {
XEASSERT(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN); XEASSERT(symbol_info->behavior() == FunctionInfo::BEHAVIOR_EXTERN);
if (!symbol_info->extern_handler()) { if (!symbol_info->extern_handler()) {
CallNative(UndefinedCallExtern, reinterpret_cast<uint64_t>(symbol_info)); CallNative(UndefinedCallExtern, reinterpret_cast<uint64_t>(symbol_info));
@ -419,7 +411,8 @@ void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0)) {
ReloadEDX(); ReloadEDX();
} }
void X64Emitter::CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0), uint64_t arg0) { void X64Emitter::CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0),
uint64_t arg0) {
mov(rdx, arg0); mov(rdx, arg0);
mov(rax, reinterpret_cast<uint64_t>(fn)); mov(rax, reinterpret_cast<uint64_t>(fn));
call(rax); call(rax);
@ -514,29 +507,48 @@ Address X64Emitter::GetXmmConstPtr(XmmConst id) {
/* XMMZero */ vec128f(0.0f, 0.0f, 0.0f, 0.0f), /* XMMZero */ vec128f(0.0f, 0.0f, 0.0f, 0.0f),
/* XMMOne */ vec128f(1.0f, 1.0f, 1.0f, 1.0f), /* XMMOne */ vec128f(1.0f, 1.0f, 1.0f, 1.0f),
/* XMMNegativeOne */ vec128f(-1.0f, -1.0f, -1.0f, -1.0f), /* XMMNegativeOne */ vec128f(-1.0f, -1.0f, -1.0f, -1.0f),
/* XMMMaskX16Y16 */ vec128i(0x0000FFFFu, 0xFFFF0000u, 0x00000000u, 0x00000000u), /* XMMMaskX16Y16 */ vec128i(0x0000FFFFu, 0xFFFF0000u,
/* XMMFlipX16Y16 */ vec128i(0x00008000u, 0x00000000u, 0x00000000u, 0x00000000u), 0x00000000u, 0x00000000u),
/* XMMFlipX16Y16 */ vec128i(0x00008000u, 0x00000000u,
0x00000000u, 0x00000000u),
/* XMMFixX16Y16 */ vec128f(-32768.0f, 0.0f, 0.0f, 0.0f), /* XMMFixX16Y16 */ vec128f(-32768.0f, 0.0f, 0.0f, 0.0f),
/* XMMNormalizeX16Y16 */ vec128f(1.0f / 32767.0f, 1.0f / (32767.0f * 65536.0f), 0.0f, 0.0f), /* XMMNormalizeX16Y16 */ vec128f(
1.0f / 32767.0f, 1.0f / (32767.0f * 65536.0f), 0.0f, 0.0f),
/* XMM0001 */ vec128f(0.0f, 0.0f, 0.0f, 1.0f), /* XMM0001 */ vec128f(0.0f, 0.0f, 0.0f, 1.0f),
/* XMM3301 */ vec128f(3.0f, 3.0f, 0.0f, 1.0f), /* XMM3301 */ vec128f(3.0f, 3.0f, 0.0f, 1.0f),
/* XMMSignMaskPS */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u), /* XMMSignMaskPS */ vec128i(0x80000000u, 0x80000000u,
/* XMMSignMaskPD */ vec128i(0x00000000u, 0x80000000u, 0x00000000u, 0x80000000u), 0x80000000u, 0x80000000u),
/* XMMAbsMaskPS */ vec128i(0x7FFFFFFFu, 0x7FFFFFFFu, 0x7FFFFFFFu, 0x7FFFFFFFu), /* XMMSignMaskPD */ vec128i(0x00000000u, 0x80000000u,
/* XMMAbsMaskPD */ vec128i(0xFFFFFFFFu, 0x7FFFFFFFu, 0xFFFFFFFFu, 0x7FFFFFFFu), 0x00000000u, 0x80000000u),
/* XMMByteSwapMask */ vec128i(0x00010203u, 0x04050607u, 0x08090A0Bu, 0x0C0D0E0Fu), /* XMMAbsMaskPS */ vec128i(0x7FFFFFFFu, 0x7FFFFFFFu,
/* XMMPermuteControl15 */ vec128b(15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15), 0x7FFFFFFFu, 0x7FFFFFFFu),
/* XMMPackD3DCOLOR */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0C000408u), /* XMMAbsMaskPD */ vec128i(0xFFFFFFFFu, 0x7FFFFFFFu,
/* XMMUnpackD3DCOLOR */ vec128i(0xFFFFFF0Eu, 0xFFFFFF0Du, 0xFFFFFF0Cu, 0xFFFFFF0Fu), 0xFFFFFFFFu, 0x7FFFFFFFu),
/* XMMOneOver255 */ vec128f(1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f, 1.0f / 255.0f), /* XMMByteSwapMask */ vec128i(0x00010203u, 0x04050607u,
/* XMMShiftMaskPS */ vec128i(0x0000001Fu, 0x0000001Fu, 0x0000001Fu, 0x0000001Fu), 0x08090A0Bu, 0x0C0D0E0Fu),
/* XMMShiftByteMask */ vec128i(0x000000FFu, 0x000000FFu, 0x000000FFu, 0x000000FFu), /* XMMPermuteControl15 */ vec128b(15, 15, 15, 15, 15, 15, 15, 15, 15,
/* XMMUnsignedDwordMax */ vec128i(0xFFFFFFFFu, 0x00000000u, 0xFFFFFFFFu, 0x00000000u), 15, 15, 15, 15, 15, 15, 15),
/* XMMPackD3DCOLOR */ vec128i(0xFFFFFFFFu, 0xFFFFFFFFu,
0xFFFFFFFFu, 0x0C000408u),
/* XMMUnpackD3DCOLOR */ vec128i(0xFFFFFF0Eu, 0xFFFFFF0Du,
0xFFFFFF0Cu, 0xFFFFFF0Fu),
/* XMMOneOver255 */ vec128f(1.0f / 255.0f, 1.0f / 255.0f,
1.0f / 255.0f, 1.0f / 255.0f),
/* XMMShiftMaskPS */ vec128i(0x0000001Fu, 0x0000001Fu,
0x0000001Fu, 0x0000001Fu),
/* XMMShiftByteMask */ vec128i(0x000000FFu, 0x000000FFu,
0x000000FFu, 0x000000FFu),
/* XMMUnsignedDwordMax */ vec128i(0xFFFFFFFFu, 0x00000000u,
0xFFFFFFFFu, 0x00000000u),
/* XMM255 */ vec128f(255.0f, 255.0f, 255.0f, 255.0f), /* XMM255 */ vec128f(255.0f, 255.0f, 255.0f, 255.0f),
/* XMMSignMaskI8 */ vec128i(0x80808080u, 0x80808080u, 0x80808080u, 0x80808080u), /* XMMSignMaskI8 */ vec128i(0x80808080u, 0x80808080u,
/* XMMSignMaskI16 */ vec128i(0x80008000u, 0x80008000u, 0x80008000u, 0x80008000u), 0x80808080u, 0x80808080u),
/* XMMSignMaskI32 */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u), /* XMMSignMaskI16 */ vec128i(0x80008000u, 0x80008000u,
/* XMMSignMaskF32 */ vec128i(0x80000000u, 0x80000000u, 0x80000000u, 0x80000000u), 0x80008000u, 0x80008000u),
/* XMMSignMaskI32 */ vec128i(0x80000000u, 0x80000000u,
0x80000000u, 0x80000000u),
/* XMMSignMaskF32 */ vec128i(0x80000000u, 0x80000000u,
0x80000000u, 0x80000000u),
}; };
// TODO(benvanik): cache base pointer somewhere? stack? It'd be nice to // TODO(benvanik): cache base pointer somewhere? stack? It'd be nice to
// prevent this move. // prevent this move.
@ -614,3 +626,7 @@ Address X64Emitter::StashXmm(const vec128_t& v) {
vmovups(addr, xmm0); vmovups(addr, xmm0);
return addr; return addr;
} }
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@ -80,9 +80,9 @@ public:
int Initialize(); int Initialize();
int Emit(hir::HIRBuilder* builder, int Emit(hir::HIRBuilder* builder, uint32_t debug_info_flags,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info, runtime::DebugInfo* debug_info, void*& out_code_address,
void*& out_code_address, size_t& out_code_size); size_t& out_code_size);
public: public:
// Reserved: rsp // Reserved: rsp
@ -123,11 +123,13 @@ public:
void Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info); void Call(const hir::Instr* instr, runtime::FunctionInfo* symbol_info);
void CallIndirect(const hir::Instr* instr, const Xbyak::Reg64& reg); void CallIndirect(const hir::Instr* instr, const Xbyak::Reg64& reg);
void CallExtern(const hir::Instr* instr, const runtime::FunctionInfo* symbol_info); void CallExtern(const hir::Instr* instr,
const runtime::FunctionInfo* symbol_info);
void CallNative(void* fn); void CallNative(void* fn);
void CallNative(uint64_t (*fn)(void* raw_context)); void CallNative(uint64_t (*fn)(void* raw_context));
void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0)); void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0));
void CallNative(uint64_t(*fn)(void* raw_context, uint64_t arg0), uint64_t arg0); void CallNative(uint64_t (*fn)(void* raw_context, uint64_t arg0),
uint64_t arg0);
void CallNativeSafe(void* fn); void CallNativeSafe(void* fn);
void SetReturnAddress(uint64_t value); void SetReturnAddress(uint64_t value);
void ReloadECX(); void ReloadECX();
@ -174,10 +176,8 @@ protected:
static const uint32_t xmm_reg_map_[XMM_COUNT]; static const uint32_t xmm_reg_map_[XMM_COUNT];
}; };
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_EMITTER_H_ #endif // ALLOY_BACKEND_X64_X64_EMITTER_H_

View File

@ -14,16 +14,17 @@
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
#include <alloy/runtime/thread_state.h> #include <alloy/runtime/thread_state.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace backend {
using namespace alloy::backend::x64; namespace x64 {
using namespace alloy::runtime;
using alloy::runtime::Breakpoint;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
using alloy::runtime::ThreadState;
X64Function::X64Function(FunctionInfo* symbol_info) : X64Function::X64Function(FunctionInfo* symbol_info)
machine_code_(NULL), code_size_(0), : machine_code_(NULL), code_size_(0), Function(symbol_info) {}
Function(symbol_info) {
}
X64Function::~X64Function() { X64Function::~X64Function() {
// machine_code_ is freed by code cache. // machine_code_ is freed by code cache.
@ -34,20 +35,17 @@ void X64Function::Setup(void* machine_code, size_t code_size) {
code_size_ = code_size; code_size_ = code_size;
} }
int X64Function::AddBreakpointImpl(Breakpoint* breakpoint) { int X64Function::AddBreakpointImpl(Breakpoint* breakpoint) { return 0; }
return 0;
}
int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) { int X64Function::RemoveBreakpointImpl(Breakpoint* breakpoint) { return 0; }
return 0;
}
int X64Function::CallImpl(ThreadState* thread_state, uint64_t return_address) { int X64Function::CallImpl(ThreadState* thread_state, uint64_t return_address) {
auto backend = (X64Backend*)thread_state->runtime()->backend(); auto backend = (X64Backend*)thread_state->runtime()->backend();
auto thunk = backend->host_to_guest_thunk(); auto thunk = backend->host_to_guest_thunk();
thunk( thunk(machine_code_, thread_state->raw_context(), (void*)return_address);
machine_code_,
thread_state->raw_context(),
(void*)return_address);
return 0; return 0;
} }
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@ -14,12 +14,10 @@
#include <alloy/runtime/function.h> #include <alloy/runtime/function.h>
#include <alloy/runtime/symbol_info.h> #include <alloy/runtime/symbol_info.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
class X64Function : public runtime::Function { class X64Function : public runtime::Function {
public: public:
X64Function(runtime::FunctionInfo* symbol_info); X64Function(runtime::FunctionInfo* symbol_info);
@ -41,10 +39,8 @@ private:
size_t code_size_; size_t code_size_;
}; };
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_FUNCTION_H_ #endif // ALLOY_BACKEND_X64_X64_FUNCTION_H_

View File

@ -20,14 +20,12 @@ namespace x64 {
class X64Emitter; class X64Emitter;
void RegisterSequences(); void RegisterSequences();
bool SelectSequence(X64Emitter& e, const hir::Instr* i, const hir::Instr** new_tail); bool SelectSequence(X64Emitter& e, const hir::Instr* i,
const hir::Instr** new_tail);
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_SEQUENCES_H_ #endif // ALLOY_BACKEND_X64_X64_SEQUENCES_H_

View File

@ -11,21 +11,16 @@
#include <third_party/xbyak/xbyak/xbyak.h> #include <third_party/xbyak/xbyak/xbyak.h>
namespace alloy {
using namespace alloy; namespace backend {
using namespace alloy::backend; namespace x64 {
using namespace alloy::backend::x64;
using namespace Xbyak; using namespace Xbyak;
X64ThunkEmitter::X64ThunkEmitter(X64Backend* backend, XbyakAllocator* allocator)
: X64Emitter(backend, allocator) {}
X64ThunkEmitter::X64ThunkEmitter( X64ThunkEmitter::~X64ThunkEmitter() {}
X64Backend* backend, XbyakAllocator* allocator) :
X64Emitter(backend, allocator) {
}
X64ThunkEmitter::~X64ThunkEmitter() {
}
HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() { HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
// rcx = target // rcx = target
@ -143,3 +138,7 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
void* fn = Emplace(stack_size); void* fn = Emplace(stack_size);
return (HostToGuestThunk)fn; return (HostToGuestThunk)fn;
} }
} // namespace x64
} // namespace backend
} // namespace alloy

View File

@ -14,12 +14,10 @@
#include <alloy/backend/x64/x64_backend.h> #include <alloy/backend/x64/x64_backend.h>
#include <alloy/backend/x64/x64_emitter.h> #include <alloy/backend/x64/x64_emitter.h>
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
/** /**
* Stack Layout * Stack Layout
* ---------------------------- * ----------------------------
@ -125,7 +123,6 @@ public:
const static size_t GUEST_CALL_RET_ADDR = 80; const static size_t GUEST_CALL_RET_ADDR = 80;
}; };
class X64ThunkEmitter : public X64Emitter { class X64ThunkEmitter : public X64Emitter {
public: public:
X64ThunkEmitter(X64Backend* backend, XbyakAllocator* allocator); X64ThunkEmitter(X64Backend* backend, XbyakAllocator* allocator);
@ -138,10 +135,8 @@ public:
GuestToHostThunk EmitGuestToHostThunk(); GuestToHostThunk EmitGuestToHostThunk();
}; };
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_ #endif // ALLOY_BACKEND_X64_X64_THUNK_EMITTER_H_

View File

@ -27,9 +27,12 @@ namespace x64 {
#define TARGET_THREAD 1 #define TARGET_THREAD 1
#define IFLUSH() fflush(stdout) #define IFLUSH() fflush(stdout)
#define IPRINT if (thread_state->thread_id() == TARGET_THREAD) printf #define IPRINT \
if (thread_state->thread_id() == TARGET_THREAD) printf
#define DFLUSH() fflush(stdout) #define DFLUSH() fflush(stdout)
#define DPRINT DFLUSH(); if (thread_state->thread_id() == TARGET_THREAD) printf #define DPRINT \
DFLUSH(); \
if (thread_state->thread_id() == TARGET_THREAD) printf
uint32_t GetTracingMode() { uint32_t GetTracingMode() {
uint32_t mode = 0; uint32_t mode = 0;
@ -66,7 +69,8 @@ void TraceContextLoadI64(void* raw_context, uint64_t offset, uint64_t value) {
} }
void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) { void TraceContextLoadF32(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
DPRINT("%e (%X) = ctx f32 +%d\n", value.m128_f32[0], value.m128_i32[0], offset); DPRINT("%e (%X) = ctx f32 +%d\n", value.m128_f32[0], value.m128_i32[0],
offset);
} }
void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) { void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
@ -80,9 +84,9 @@ void TraceContextLoadF64(void* raw_context, uint64_t offset, __m128 value) {
void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) { void TraceContextLoadV128(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%d\n", DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = ctx v128 +%d\n",
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3], value.m128_f32[0], value.m128_f32[1], value.m128_f32[2],
value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3], value.m128_f32[3], value.m128_i32[0], value.m128_i32[1],
offset); value.m128_i32[2], value.m128_i32[3], offset);
} }
void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) { void TraceContextStoreI8(void* raw_context, uint64_t offset, uint8_t value) {
@ -103,7 +107,8 @@ void TraceContextStoreI64(void* raw_context, uint64_t offset, uint64_t value) {
} }
void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) { void TraceContextStoreF32(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
DPRINT("ctx f32 +%d = %e (%X)\n", offset, value.m128_i32[0], value.m128_f32[0]); DPRINT("ctx f32 +%d = %e (%X)\n", offset, value.m128_i32[0],
value.m128_f32[0]);
} }
void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) { void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
@ -117,8 +122,9 @@ void TraceContextStoreF64(void* raw_context, uint64_t offset, __m128 value) {
void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) { void TraceContextStoreV128(void* raw_context, uint64_t offset, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", offset, DPRINT("ctx v128 +%d = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", offset,
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3], value.m128_f32[0], value.m128_f32[1], value.m128_f32[2],
value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3]); value.m128_f32[3], value.m128_i32[0], value.m128_i32[1],
value.m128_i32[2], value.m128_i32[3]);
} }
void TraceMemoryLoadI8(void* raw_context, uint64_t address, uint8_t value) { void TraceMemoryLoadI8(void* raw_context, uint64_t address, uint8_t value) {
@ -139,7 +145,8 @@ void TraceMemoryLoadI64(void* raw_context, uint64_t address, uint64_t value) {
} }
void TraceMemoryLoadF32(void* raw_context, uint64_t address, __m128 value) { void TraceMemoryLoadF32(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
DPRINT("%e (%X) = load.f32 %.8X\n", value.m128_f32[0], value.m128_i32[0], address); DPRINT("%e (%X) = load.f32 %.8X\n", value.m128_f32[0], value.m128_i32[0],
address);
} }
void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) { void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
@ -153,9 +160,9 @@ void TraceMemoryLoadF64(void* raw_context, uint64_t address, __m128 value) {
void TraceMemoryLoadV128(void* raw_context, uint64_t address, __m128 value) { void TraceMemoryLoadV128(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n", DPRINT("[%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X] = load.v128 %.8X\n",
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3], value.m128_f32[0], value.m128_f32[1], value.m128_f32[2],
value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3], value.m128_f32[3], value.m128_i32[0], value.m128_i32[1],
address); value.m128_i32[2], value.m128_i32[3], address);
} }
void TraceMemoryStoreI8(void* raw_context, uint64_t address, uint8_t value) { void TraceMemoryStoreI8(void* raw_context, uint64_t address, uint8_t value) {
@ -176,7 +183,8 @@ void TraceMemoryStoreI64(void* raw_context, uint64_t address, uint64_t value) {
} }
void TraceMemoryStoreF32(void* raw_context, uint64_t address, __m128 value) { void TraceMemoryStoreF32(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
DPRINT("store.f32 %.8X = %e (%X)\n", address, value.m128_f32[0], value.m128_i32[0]); DPRINT("store.f32 %.8X = %e (%X)\n", address, value.m128_f32[0],
value.m128_i32[0]);
} }
void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) { void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
@ -189,12 +197,12 @@ void TraceMemoryStoreF64(void* raw_context, uint64_t address, __m128 value) {
} }
void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value) { void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value) {
auto thread_state = *((ThreadState**)raw_context); auto thread_state = *((ThreadState**)raw_context);
DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n", address, DPRINT("store.v128 %.8X = [%e, %e, %e, %e] [%.8X, %.8X, %.8X, %.8X]\n",
value.m128_f32[0], value.m128_f32[1], value.m128_f32[2], value.m128_f32[3], address, value.m128_f32[0], value.m128_f32[1], value.m128_f32[2],
value.m128_i32[0], value.m128_i32[1], value.m128_i32[2], value.m128_i32[3]); value.m128_f32[3], value.m128_i32[0], value.m128_i32[1],
value.m128_i32[2], value.m128_i32[3]);
} }
} // namespace x64 } // namespace x64
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy

View File

@ -28,7 +28,6 @@ typedef union __declspec(align(16)) __m128 {
} __m128; } __m128;
#endif #endif
namespace alloy { namespace alloy {
namespace backend { namespace backend {
namespace x64 { namespace x64 {
@ -81,5 +80,4 @@ void TraceMemoryStoreV128(void* raw_context, uint64_t address, __m128 value);
} // namespace backend } // namespace backend
} // namespace alloy } // namespace alloy
#endif // ALLOY_BACKEND_X64_X64_TRACERS_H_ #endif // ALLOY_BACKEND_X64_X64_TRACERS_H_

View File

@ -12,18 +12,16 @@
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
#include <alloy/compiler/tracing.h> #include <alloy/compiler/tracing.h>
using namespace alloy; namespace alloy {
using namespace alloy::compiler; namespace compiler {
using namespace alloy::hir;
using namespace alloy::runtime;
using alloy::hir::HIRBuilder;
using alloy::runtime::Runtime;
Compiler::Compiler(Runtime* runtime) : Compiler::Compiler(Runtime* runtime) : runtime_(runtime) {
runtime_(runtime) {
scratch_arena_ = new Arena(); scratch_arena_ = new Arena();
alloy::tracing::WriteEvent(EventType::Init({ alloy::tracing::WriteEvent(EventType::Init({}));
}));
} }
Compiler::~Compiler() { Compiler::~Compiler() {
@ -36,8 +34,7 @@ Compiler::~Compiler() {
delete scratch_arena_; delete scratch_arena_;
alloy::tracing::WriteEvent(EventType::Deinit({ alloy::tracing::WriteEvent(EventType::Deinit({}));
}));
} }
void Compiler::AddPass(CompilerPass* pass) { void Compiler::AddPass(CompilerPass* pass) {
@ -45,8 +42,7 @@ void Compiler::AddPass(CompilerPass* pass) {
passes_.push_back(pass); passes_.push_back(pass);
} }
void Compiler::Reset() { void Compiler::Reset() {}
}
int Compiler::Compile(HIRBuilder* builder) { int Compiler::Compile(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -63,3 +59,6 @@ int Compiler::Compile(HIRBuilder* builder) {
return 0; return 0;
} }
} // namespace compiler
} // namespace alloy

View File

@ -13,15 +13,17 @@
#include <alloy/core.h> #include <alloy/core.h>
#include <alloy/hir/hir_builder.h> #include <alloy/hir/hir_builder.h>
namespace alloy { namespace runtime { class Runtime; } } namespace alloy {
namespace runtime {
class Runtime;
} // namespace runtime
} // namespace alloy
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
class CompilerPass; class CompilerPass;
class Compiler { class Compiler {
public: public:
Compiler(runtime::Runtime* runtime); Compiler(runtime::Runtime* runtime);
@ -44,9 +46,7 @@ private:
PassList passes_; PassList passes_;
}; };
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_COMPILER_H_ #endif // ALLOY_COMPILER_COMPILER_H_

View File

@ -11,16 +11,12 @@
#include <alloy/compiler/compiler.h> #include <alloy/compiler/compiler.h>
using namespace alloy; namespace alloy {
using namespace alloy::compiler; namespace compiler {
CompilerPass::CompilerPass() : runtime_(0), compiler_(0) {}
CompilerPass::CompilerPass() : CompilerPass::~CompilerPass() {}
runtime_(0), compiler_(0) {
}
CompilerPass::~CompilerPass() {
}
int CompilerPass::Initialize(Compiler* compiler) { int CompilerPass::Initialize(Compiler* compiler) {
runtime_ = compiler->runtime(); runtime_ = compiler->runtime();
@ -31,3 +27,6 @@ int CompilerPass::Initialize(Compiler* compiler) {
Arena* CompilerPass::scratch_arena() const { Arena* CompilerPass::scratch_arena() const {
return compiler_->scratch_arena(); return compiler_->scratch_arena();
} }
} // namespace compiler
} // namespace alloy

View File

@ -14,15 +14,17 @@
#include <alloy/hir/hir_builder.h> #include <alloy/hir/hir_builder.h>
namespace alloy { namespace runtime { class Runtime; } } namespace alloy {
namespace runtime {
class Runtime;
} // namespace runtime
} // namespace alloy
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
class Compiler; class Compiler;
class CompilerPass { class CompilerPass {
public: public:
CompilerPass(); CompilerPass();
@ -40,9 +42,7 @@ protected:
Compiler* compiler_; Compiler* compiler_;
}; };
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_COMPILER_PASS_H_ #endif // ALLOY_COMPILER_COMPILER_PASS_H_

View File

@ -49,7 +49,6 @@
// Block gets: // Block gets:
// AddIncomingValue(Value* value, Block* src_block) ?? // AddIncomingValue(Value* value, Block* src_block) ??
// Potentially interesting passes: // Potentially interesting passes:
// //
// Run order: // Run order:

View File

@ -12,18 +12,20 @@
#include <alloy/runtime/function.h> #include <alloy/runtime/function.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::compiler; namespace compiler {
using namespace alloy::compiler::passes; namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using alloy::hir::HIRBuilder;
using alloy::hir::TypeName;
using alloy::hir::Value;
ConstantPropagationPass::ConstantPropagationPass() : ConstantPropagationPass::ConstantPropagationPass() : CompilerPass() {}
CompilerPass() {
}
ConstantPropagationPass::~ConstantPropagationPass() { ConstantPropagationPass::~ConstantPropagationPass() {}
}
int ConstantPropagationPass::Run(HIRBuilder* builder) { int ConstantPropagationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -55,11 +57,11 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) {
// v1 = 19 // v1 = 19
// v2 = 0 // v2 = 0
Block* block = builder->first_block(); auto block = builder->first_block();
while (block) { while (block) {
Instr* i = block->instr_head; auto i = block->instr_head;
while (i) { while (i) {
Value* v = i->dest; auto v = i->dest;
switch (i->opcode->num) { switch (i->opcode->num) {
case OPCODE_DEBUG_BREAK_TRUE: case OPCODE_DEBUG_BREAK_TRUE:
if (i->src1.value->IsConstant()) { if (i->src1.value->IsConstant()) {
@ -438,7 +440,7 @@ int ConstantPropagationPass::Run(HIRBuilder* builder) {
return 0; return 0;
} }
void ConstantPropagationPass::PropagateCarry(hir::Value* v, bool did_carry) { void ConstantPropagationPass::PropagateCarry(Value* v, bool did_carry) {
auto next = v->use_head; auto next = v->use_head;
while (next) { while (next) {
auto use = next; auto use = next;
@ -450,3 +452,7 @@ void ConstantPropagationPass::PropagateCarry(hir::Value* v, bool did_carry) {
} }
} }
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -12,12 +12,10 @@
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
namespace passes { namespace passes {
class ConstantPropagationPass : public CompilerPass { class ConstantPropagationPass : public CompilerPass {
public: public:
ConstantPropagationPass(); ConstantPropagationPass();
@ -29,10 +27,8 @@ private:
void PropagateCarry(hir::Value* v, bool did_carry); void PropagateCarry(hir::Value* v, bool did_carry);
}; };
} // namespace passes } // namespace passes
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_ #endif // ALLOY_COMPILER_PASSES_CONSTANT_PROPAGATION_PASS_H_

View File

@ -14,22 +14,24 @@
#include <alloy/compiler/compiler.h> #include <alloy/compiler/compiler.h>
#include <alloy/runtime/runtime.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;
DEFINE_bool(store_all_context_values, false, DEFINE_bool(store_all_context_values, false,
"Don't strip dead context stores to aid in debugging."); "Don't strip dead context stores to aid in debugging.");
namespace alloy {
namespace compiler {
namespace passes {
ContextPromotionPass::ContextPromotionPass() : // TODO(benvanik): remove when enums redefined.
context_values_size_(0), context_values_(0), using namespace alloy::hir;
CompilerPass() {
} using alloy::frontend::ContextInfo;
using alloy::hir::Block;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::Value;
ContextPromotionPass::ContextPromotionPass()
: context_values_size_(0), context_values_(0), CompilerPass() {}
ContextPromotionPass::~ContextPromotionPass() { ContextPromotionPass::~ContextPromotionPass() {
if (context_values_) { if (context_values_) {
@ -70,7 +72,7 @@ int ContextPromotionPass::Run(HIRBuilder* builder) {
// Promote loads to values. // Promote loads to values.
// Process each block independently, for now. // Process each block independently, for now.
Block* block = builder->first_block(); auto block = builder->first_block();
while (block) { while (block) {
PromoteBlock(block); PromoteBlock(block);
block = block->next; block = block->next;
@ -121,7 +123,7 @@ void ContextPromotionPass::PromoteBlock(Block* block) {
void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) { void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) {
// TODO(benvanik): use a bitvector. // TODO(benvanik): use a bitvector.
// To avoid clearing the structure, we use a token. // To avoid clearing the structure, we use a token.
Value* token = (Value*)block; auto token = (Value*)block;
// Walk backwards and mark offsets that are written to. // Walk backwards and mark offsets that are written to.
// If the offset was written to earlier, ignore the store. // If the offset was written to earlier, ignore the store.
@ -141,3 +143,7 @@ void ContextPromotionPass::RemoveDeadStoresBlock(Block* block) {
i = prev; i = prev;
} }
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -12,12 +12,10 @@
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
namespace passes { namespace passes {
class ContextPromotionPass : public CompilerPass { class ContextPromotionPass : public CompilerPass {
public: public:
ContextPromotionPass(); ContextPromotionPass();
@ -36,10 +34,8 @@ private:
hir::Value** context_values_; hir::Value** context_values_;
}; };
} // namespace passes } // namespace passes
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_ #endif // ALLOY_COMPILER_PASSES_CONTEXT_PROMOTION_PASS_H_

View File

@ -13,21 +13,19 @@
#include <alloy/compiler/compiler.h> #include <alloy/compiler/compiler.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace compiler {
using namespace alloy::compiler; namespace passes {
using namespace alloy::compiler::passes;
using namespace alloy::frontend; // TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using namespace alloy::runtime;
using alloy::hir::Edge;
using alloy::hir::HIRBuilder;
ControlFlowAnalysisPass::ControlFlowAnalysisPass() : ControlFlowAnalysisPass::ControlFlowAnalysisPass() : CompilerPass() {}
CompilerPass() {
}
ControlFlowAnalysisPass::~ControlFlowAnalysisPass() { ControlFlowAnalysisPass::~ControlFlowAnalysisPass() {}
}
int ControlFlowAnalysisPass::Run(HIRBuilder* builder) { int ControlFlowAnalysisPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -67,3 +65,7 @@ int ControlFlowAnalysisPass::Run(HIRBuilder* builder) {
return 0; return 0;
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -12,12 +12,10 @@
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
namespace passes { namespace passes {
class ControlFlowAnalysisPass : public CompilerPass { class ControlFlowAnalysisPass : public CompilerPass {
public: public:
ControlFlowAnalysisPass(); ControlFlowAnalysisPass();
@ -28,10 +26,8 @@ public:
private: private:
}; };
} // namespace passes } // namespace passes
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_ #endif // ALLOY_COMPILER_PASSES_CONTROL_FLOW_ANALYSIS_PASS_H_

View File

@ -19,21 +19,20 @@
#include <llvm/ADT/BitVector.h> #include <llvm/ADT/BitVector.h>
#pragma warning(pop) #pragma warning(pop)
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace compiler {
using namespace alloy::compiler; namespace passes {
using namespace alloy::compiler::passes;
using namespace alloy::frontend; // TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using namespace alloy::runtime;
using alloy::hir::HIRBuilder;
using alloy::hir::OpcodeSignatureType;
using alloy::hir::Value;
DataFlowAnalysisPass::DataFlowAnalysisPass() : DataFlowAnalysisPass::DataFlowAnalysisPass() : CompilerPass() {}
CompilerPass() {
}
DataFlowAnalysisPass::~DataFlowAnalysisPass() { DataFlowAnalysisPass::~DataFlowAnalysisPass() {}
}
int DataFlowAnalysisPass::Run(HIRBuilder* builder) { int DataFlowAnalysisPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -66,15 +65,15 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder,
// Stash for value map. We may want to maintain this during building. // Stash for value map. We may want to maintain this during building.
auto arena = builder->arena(); auto arena = builder->arena();
Value** value_map = (Value**)arena->Alloc( Value** value_map =
sizeof(Value*) * max_value_estimate); (Value**)arena->Alloc(sizeof(Value*) * max_value_estimate);
// Allocate incoming bitvectors for use by blocks. We don't need outgoing // Allocate incoming bitvectors for use by blocks. We don't need outgoing
// because they are only used during the block iteration. // because they are only used during the block iteration.
// Mapped by block ordinal. // Mapped by block ordinal.
// TODO(benvanik): cache this list, grow as needed, etc. // TODO(benvanik): cache this list, grow as needed, etc.
auto incoming_bitvectors = (llvm::BitVector**)arena->Alloc( auto incoming_bitvectors =
sizeof(llvm::BitVector*) * block_count); (llvm::BitVector**)arena->Alloc(sizeof(llvm::BitVector*) * block_count);
for (auto n = 0u; n < block_count; n++) { for (auto n = 0u; n < block_count; n++) {
incoming_bitvectors[n] = new llvm::BitVector(max_value_estimate); incoming_bitvectors[n] = new llvm::BitVector(max_value_estimate);
} }
@ -201,3 +200,7 @@ void DataFlowAnalysisPass::AnalyzeFlow(HIRBuilder* builder,
delete incoming_bitvectors[n]; delete incoming_bitvectors[n];
} }
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -9,18 +9,20 @@
#include <alloy/compiler/passes/dead_code_elimination_pass.h> #include <alloy/compiler/passes/dead_code_elimination_pass.h>
using namespace alloy; namespace alloy {
using namespace alloy::compiler; namespace compiler {
using namespace alloy::compiler::passes; namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::Value;
DeadCodeEliminationPass::DeadCodeEliminationPass() : DeadCodeEliminationPass::DeadCodeEliminationPass() : CompilerPass() {}
CompilerPass() {
}
DeadCodeEliminationPass::~DeadCodeEliminationPass() { DeadCodeEliminationPass::~DeadCodeEliminationPass() {}
}
int DeadCodeEliminationPass::Run(HIRBuilder* builder) { int DeadCodeEliminationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -63,7 +65,7 @@ int DeadCodeEliminationPass::Run(HIRBuilder* builder) {
bool any_instr_removed = false; bool any_instr_removed = false;
bool any_locals_removed = false; bool any_locals_removed = false;
Block* block = builder->first_block(); auto block = builder->first_block();
while (block) { while (block) {
// Walk instructions in reverse. // Walk instructions in reverse.
Instr* i = block->instr_tail; Instr* i = block->instr_tail;
@ -71,8 +73,8 @@ int DeadCodeEliminationPass::Run(HIRBuilder* builder) {
auto prev = i->prev; auto prev = i->prev;
auto opcode = i->opcode; auto opcode = i->opcode;
if (!(opcode->flags & OPCODE_FLAG_VOLATILE) && if (!(opcode->flags & OPCODE_FLAG_VOLATILE) && i->dest &&
i->dest && !i->dest->use_head) { !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(i); MakeNopRecursive(i);
any_instr_removed = true; any_instr_removed = true;
@ -110,7 +112,7 @@ int DeadCodeEliminationPass::Run(HIRBuilder* builder) {
// Remove all nops. // Remove all nops.
if (any_instr_removed) { if (any_instr_removed) {
Block* block = builder->first_block(); auto block = builder->first_block();
while (block) { while (block) {
Instr* i = block->instr_head; Instr* i = block->instr_head;
while (i) { while (i) {
@ -209,3 +211,7 @@ bool DeadCodeEliminationPass::CheckLocalUse(Instr* i) {
return false; return false;
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -13,21 +13,18 @@
#include <alloy/compiler/compiler.h> #include <alloy/compiler/compiler.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace compiler {
using namespace alloy::compiler; namespace passes {
using namespace alloy::compiler::passes;
using namespace alloy::frontend; // TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using namespace alloy::runtime;
using alloy::hir::HIRBuilder;
FinalizationPass::FinalizationPass() : FinalizationPass::FinalizationPass() : CompilerPass() {}
CompilerPass() {
}
FinalizationPass::~FinalizationPass() { FinalizationPass::~FinalizationPass() {}
}
int FinalizationPass::Run(HIRBuilder* builder) { int FinalizationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -70,3 +67,7 @@ int FinalizationPass::Run(HIRBuilder* builder) {
return 0; return 0;
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -12,12 +12,10 @@
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
namespace passes { namespace passes {
class FinalizationPass : public CompilerPass { class FinalizationPass : public CompilerPass {
public: public:
FinalizationPass(); FinalizationPass();
@ -28,10 +26,8 @@ public:
private: private:
}; };
} // namespace passes } // namespace passes
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_ #endif // ALLOY_COMPILER_PASSES_FINALIZATION_PASS_H_

View File

@ -11,20 +11,25 @@
#include <algorithm> #include <algorithm>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace compiler {
using namespace alloy::compiler; namespace passes {
using namespace alloy::compiler::passes;
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using alloy::backend::MachineInfo;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::OpcodeSignatureType;
using alloy::hir::RegAssignment;
using alloy::hir::TypeName;
using alloy::hir::Value;
#define ASSERT_NO_CYCLES 0 #define ASSERT_NO_CYCLES 0
RegisterAllocationPass::RegisterAllocationPass(const MachineInfo* machine_info)
RegisterAllocationPass::RegisterAllocationPass( : machine_info_(machine_info), CompilerPass() {
const MachineInfo* machine_info) :
machine_info_(machine_info),
CompilerPass() {
// Initialize register sets. // Initialize register sets.
// TODO(benvanik): rewrite in a way that makes sense - this is terrible. // TODO(benvanik): rewrite in a way that makes sense - this is terrible.
auto mi_sets = machine_info->register_sets; auto mi_sets = machine_info->register_sets;
@ -88,7 +93,7 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
instr = block->instr_head; instr = block->instr_head;
while (instr) { while (instr) {
const OpcodeInfo* info = instr->opcode; const auto info = instr->opcode;
uint32_t signature = info->signature; uint32_t signature = info->signature;
// Update the register use heaps. // Update the register use heaps.
@ -117,7 +122,8 @@ int RegisterAllocationPass::Run(HIRBuilder* builder) {
// Must not have been set already. // Must not have been set already.
XEASSERTNULL(instr->dest->reg.set); XEASSERTNULL(instr->dest->reg.set);
// Sort the usage list. We depend on this in future uses of this variable. // Sort the usage list. We depend on this in future uses of this
// variable.
SortUsageList(instr->dest); SortUsageList(instr->dest);
// If we have a preferred register, use that. // If we have a preferred register, use that.
@ -181,7 +187,6 @@ void RegisterAllocationPass::DumpUsage(const char* name) {
#endif #endif
} }
void RegisterAllocationPass::PrepareBlockState() { void RegisterAllocationPass::PrepareBlockState() {
for (size_t i = 0; i < XECOUNT(usage_sets_.all_sets); ++i) { for (size_t i = 0; i < XECOUNT(usage_sets_.all_sets); ++i) {
auto usage_set = usage_sets_.all_sets[i]; auto usage_set = usage_sets_.all_sets[i];
@ -249,9 +254,8 @@ bool RegisterAllocationPass::IsRegInUse(const RegAssignment& reg) {
return !usage_set->availability.test(reg.index); return !usage_set->availability.test(reg.index);
} }
RegisterAllocationPass::RegisterSetUsage* RegisterAllocationPass::RegisterSetUsage* RegisterAllocationPass::MarkRegUsed(
RegisterAllocationPass::MarkRegUsed(const RegAssignment& reg, const RegAssignment& reg, Value* value, Value::Use* use) {
Value* value, Value::Use* use) {
auto usage_set = RegisterSetForValue(value); auto usage_set = RegisterSetForValue(value);
usage_set->availability.set(reg.index, false); usage_set->availability.set(reg.index, false);
usage_set->upcoming_uses.emplace_back(value, use); usage_set->upcoming_uses.emplace_back(value, use);
@ -298,7 +302,8 @@ bool RegisterAllocationPass::TryAllocateRegister(Value* value) {
// Find the first free register, if any. // Find the first free register, if any.
// We have to ensure it's a valid one (in our count). // We have to ensure it's a valid one (in our count).
unsigned long first_unused = 0; unsigned long first_unused = 0;
bool all_used = _BitScanForward(&first_unused, usage_set->availability.to_ulong()) == 0; bool all_used =
_BitScanForward(&first_unused, usage_set->availability.to_ulong()) == 0;
if (!all_used && first_unused < usage_set->count) { if (!all_used && first_unused < usage_set->count) {
// Available! Use it!. // Available! Use it!.
value->reg.set = usage_set->set; value->reg.set = usage_set->set;
@ -311,8 +316,8 @@ bool RegisterAllocationPass::TryAllocateRegister(Value* value) {
return false; return false;
} }
bool RegisterAllocationPass::SpillOneRegister( bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder,
HIRBuilder* builder, TypeName required_type) { TypeName required_type) {
// Get the set that we will be picking from. // Get the set that we will be picking from.
RegisterSetUsage* usage_set; RegisterSetUsage* usage_set;
if (required_type <= INT64_TYPE) { if (required_type <= INT64_TYPE) {
@ -326,10 +331,10 @@ bool RegisterAllocationPass::SpillOneRegister(
DumpUsage("SpillOneRegister (pre)"); DumpUsage("SpillOneRegister (pre)");
// Pick the one with the furthest next use. // Pick the one with the furthest next use.
XEASSERT(!usage_set->upcoming_uses.empty()); XEASSERT(!usage_set->upcoming_uses.empty());
auto furthest_usage = std::max_element( auto furthest_usage = std::max_element(usage_set->upcoming_uses.begin(),
usage_set->upcoming_uses.begin(), usage_set->upcoming_uses.end(), usage_set->upcoming_uses.end(),
RegisterUsage::Comparer()); RegisterUsage::Comparer());
Value* spill_value = furthest_usage->value; auto spill_value = furthest_usage->value;
Value::Use* prev_use = furthest_usage->use->prev; Value::Use* prev_use = furthest_usage->use->prev;
Value::Use* next_use = furthest_usage->use; Value::Use* next_use = furthest_usage->use;
XEASSERTNOTNULL(next_use); XEASSERTNOTNULL(next_use);
@ -367,7 +372,8 @@ bool RegisterAllocationPass::SpillOneRegister(
spill_value->last_use = spill_store; spill_value->last_use = spill_store;
} else if (prev_use) { } else if (prev_use) {
// We insert the store immediately before the previous use. // We insert the store immediately before the previous use.
// If we were smarter we could then re-run allocation and reuse the register // If we were smarter we could then re-run allocation and reuse the
// register
// once dropped. // once dropped.
spill_store->MoveBefore(prev_use->instr); spill_store->MoveBefore(prev_use->instr);
@ -448,8 +454,7 @@ bool RegisterAllocationPass::SpillOneRegister(
} }
RegisterAllocationPass::RegisterSetUsage* RegisterAllocationPass::RegisterSetUsage*
RegisterAllocationPass::RegisterSetForValue( RegisterAllocationPass::RegisterSetForValue(const Value* value) {
const Value* value) {
if (value->type <= INT64_TYPE) { if (value->type <= INT64_TYPE) {
return usage_sets_.int_set; return usage_sets_.int_set;
} else if (value->type <= FLOAT64_TYPE) { } else if (value->type <= FLOAT64_TYPE) {
@ -498,16 +503,24 @@ void RegisterAllocationPass::SortUsageList(Value* value) {
Value::Use* e = nullptr; Value::Use* e = nullptr;
if (psize == 0) { if (psize == 0) {
// p is empty; e must come from q // p is empty; e must come from q
e = q; q = q->next; qsize--; e = q;
q = q->next;
qsize--;
} else if (qsize == 0 || !q) { } else if (qsize == 0 || !q) {
// q is empty; e must come from p // q is empty; e must come from p
e = p; p = p->next; psize--; e = p;
p = p->next;
psize--;
} else if (CompareValueUse(p, q) <= 0) { } else if (CompareValueUse(p, q) <= 0) {
// First element of p is lower (or same); e must come from p // First element of p is lower (or same); e must come from p
e = p; p = p->next; psize--; e = p;
p = p->next;
psize--;
} else { } else {
// First element of q is lower; e must come from q // First element of q is lower; e must come from q
e = q; q = q->next; qsize--; e = q;
q = q->next;
qsize--;
} }
// add the next element to the merged list // add the next element to the merged list
if (tail) { if (tail) {
@ -537,3 +550,7 @@ void RegisterAllocationPass::SortUsageList(Value* value) {
value->use_head = head; value->use_head = head;
value->last_use = tail->instr; value->last_use = tail->instr;
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -17,12 +17,10 @@
#include <alloy/backend/machine_info.h> #include <alloy/backend/machine_info.h>
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
namespace passes { namespace passes {
class RegisterAllocationPass : public CompilerPass { class RegisterAllocationPass : public CompilerPass {
public: public:
RegisterAllocationPass(const backend::MachineInfo* machine_info); RegisterAllocationPass(const backend::MachineInfo* machine_info);
@ -80,10 +78,8 @@ private:
} usage_sets_; } usage_sets_;
}; };
} // namespace passes } // namespace passes
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_ #endif // ALLOY_COMPILER_PASSES_REGISTER_ALLOCATION_PASS_H_

View File

@ -9,18 +9,20 @@
#include <alloy/compiler/passes/simplification_pass.h> #include <alloy/compiler/passes/simplification_pass.h>
using namespace alloy; namespace alloy {
using namespace alloy::compiler; namespace compiler {
using namespace alloy::compiler::passes; namespace passes {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::Value;
SimplificationPass::SimplificationPass() : SimplificationPass::SimplificationPass() : CompilerPass() {}
CompilerPass() {
}
SimplificationPass::~SimplificationPass() { SimplificationPass::~SimplificationPass() {}
}
int SimplificationPass::Run(HIRBuilder* builder) { int SimplificationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -65,7 +67,7 @@ void SimplificationPass::CheckTruncate(Instr* i) {
// Walk backward up src's chain looking for an extend. We may have // Walk backward up src's chain looking for an extend. We may have
// assigns, so skip those. // assigns, so skip those.
auto src = i->src1.value; auto src = i->src1.value;
Instr* def = src->def; auto def = src->def;
while (def && def->opcode == &OPCODE_ASSIGN_info) { while (def && def->opcode == &OPCODE_ASSIGN_info) {
// Skip asignments. // Skip asignments.
def = def->src1.value->def; def = def->src1.value->def;
@ -93,7 +95,7 @@ void SimplificationPass::CheckByteSwap(Instr* i) {
// Walk backward up src's chain looking for a byte swap. We may have // Walk backward up src's chain looking for a byte swap. We may have
// assigns, so skip those. // assigns, so skip those.
auto src = i->src1.value; auto src = i->src1.value;
Instr* def = src->def; auto def = src->def;
while (def && def->opcode == &OPCODE_ASSIGN_info) { while (def && def->opcode == &OPCODE_ASSIGN_info) {
// Skip asignments. // Skip asignments.
def = def->src1.value->def; def = def->src1.value->def;
@ -147,11 +149,11 @@ void SimplificationPass::SimplifyAssignments(HIRBuilder* builder) {
} }
Value* SimplificationPass::CheckValue(Value* value) { Value* SimplificationPass::CheckValue(Value* value) {
Instr* def = value->def; auto def = value->def;
if (def && def->opcode == &OPCODE_ASSIGN_info) { 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; auto replacement = def->src1.value;
while (true) { while (true) {
def = replacement->def; def = replacement->def;
if (!def || def->opcode != &OPCODE_ASSIGN_info) { if (!def || def->opcode != &OPCODE_ASSIGN_info) {
@ -163,3 +165,7 @@ Value* SimplificationPass::CheckValue(Value* value) {
} }
return value; return value;
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -12,12 +12,10 @@
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
namespace passes { namespace passes {
class SimplificationPass : public CompilerPass { class SimplificationPass : public CompilerPass {
public: public:
SimplificationPass(); SimplificationPass();
@ -34,10 +32,8 @@ private:
hir::Value* CheckValue(hir::Value* value); hir::Value* CheckValue(hir::Value* value);
}; };
} // namespace passes } // namespace passes
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_PASSES_SIMPLIFICATION_PASS_H_ #endif // ALLOY_COMPILER_PASSES_SIMPLIFICATION_PASS_H_

View File

@ -13,21 +13,22 @@
#include <alloy/compiler/compiler.h> #include <alloy/compiler/compiler.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace compiler {
using namespace alloy::compiler; namespace passes {
using namespace alloy::compiler::passes;
using namespace alloy::frontend; // TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using namespace alloy::runtime;
using alloy::hir::Block;
using alloy::hir::HIRBuilder;
using alloy::hir::Instr;
using alloy::hir::OpcodeSignatureType;
using alloy::hir::Value;
ValidationPass::ValidationPass() : ValidationPass::ValidationPass() : CompilerPass() {}
CompilerPass() {
}
ValidationPass::~ValidationPass() { ValidationPass::~ValidationPass() {}
}
int ValidationPass::Run(HIRBuilder* builder) { int ValidationPass::Run(HIRBuilder* builder) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -99,3 +100,7 @@ int ValidationPass::ValidateValue(Block* block, Instr* instr, Value* value) {
//} //}
return 0; return 0;
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -12,12 +12,10 @@
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
namespace passes { namespace passes {
class ValidationPass : public CompilerPass { class ValidationPass : public CompilerPass {
public: public:
ValidationPass(); ValidationPass();
@ -30,10 +28,8 @@ private:
int ValidateValue(hir::Block* block, hir::Instr* instr, hir::Value* value); int ValidateValue(hir::Block* block, hir::Instr* instr, hir::Value* value);
}; };
} // namespace passes } // namespace passes
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_PASSES_VALIDATION_PASS_H_ #endif // ALLOY_COMPILER_PASSES_VALIDATION_PASS_H_

View File

@ -19,21 +19,20 @@
#include <llvm/ADT/BitVector.h> #include <llvm/ADT/BitVector.h>
#pragma warning(pop) #pragma warning(pop)
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace compiler {
using namespace alloy::compiler; namespace passes {
using namespace alloy::compiler::passes;
using namespace alloy::frontend; // TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using namespace alloy::runtime;
using alloy::hir::HIRBuilder;
using alloy::hir::OpcodeInfo;
using alloy::hir::Value;
ValueReductionPass::ValueReductionPass() : ValueReductionPass::ValueReductionPass() : CompilerPass() {}
CompilerPass() {
}
ValueReductionPass::~ValueReductionPass() { ValueReductionPass::~ValueReductionPass() {}
}
void ValueReductionPass::ComputeLastUse(Value* value) { void ValueReductionPass::ComputeLastUse(Value* value) {
// TODO(benvanik): compute during construction? // TODO(benvanik): compute during construction?
@ -137,3 +136,7 @@ int ValueReductionPass::Run(HIRBuilder* builder) {
return 0; return 0;
} }
} // namespace passes
} // namespace compiler
} // namespace alloy

View File

@ -12,12 +12,10 @@
#include <alloy/compiler/compiler_pass.h> #include <alloy/compiler/compiler_pass.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
namespace passes { namespace passes {
class ValueReductionPass : public CompilerPass { class ValueReductionPass : public CompilerPass {
public: public:
ValueReductionPass(); ValueReductionPass();
@ -29,10 +27,8 @@ private:
void ComputeLastUse(hir::Value* value); void ComputeLastUse(hir::Value* value);
}; };
} // namespace passes } // namespace passes
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_ #endif // ALLOY_COMPILER_PASSES_VALUE_REDUCTION_PASS_H_

View File

@ -13,13 +13,11 @@
#include <alloy/tracing/tracing.h> #include <alloy/tracing/tracing.h>
#include <alloy/tracing/event_type.h> #include <alloy/tracing/event_type.h>
namespace alloy { namespace alloy {
namespace compiler { namespace compiler {
const uint32_t ALLOY_COMPILER = alloy::tracing::EventType::ALLOY_COMPILER; const uint32_t ALLOY_COMPILER = alloy::tracing::EventType::ALLOY_COMPILER;
class EventType { class EventType {
public: public:
enum { enum {
@ -35,9 +33,7 @@ public:
} Deinit; } Deinit;
}; };
} // namespace compiler } // namespace compiler
} // namespace alloy } // namespace alloy
#endif // ALLOY_COMPILER_TRACING_H_ #endif // ALLOY_COMPILER_TRACING_H_

View File

@ -17,7 +17,6 @@
#include <alloy/delegate.h> #include <alloy/delegate.h>
#include <alloy/string_buffer.h> #include <alloy/string_buffer.h>
namespace alloy { namespace alloy {
typedef struct XECACHEALIGN vec128_s { typedef struct XECACHEALIGN vec128_s {
@ -50,28 +49,44 @@ typedef struct XECACHEALIGN vec128_s {
} vec128_t; } vec128_t;
XEFORCEINLINE vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { XEFORCEINLINE vec128_t vec128i(uint32_t x, uint32_t y, uint32_t z, uint32_t w) {
vec128_t v; vec128_t v;
v.i4[0] = x; v.i4[1] = y; v.i4[2] = z; v.i4[3] = w; v.i4[0] = x;
v.i4[1] = y;
v.i4[2] = z;
v.i4[3] = w;
return v; return v;
} }
XEFORCEINLINE vec128_t vec128f(float x, float y, float z, float w) { XEFORCEINLINE vec128_t vec128f(float x, float y, float z, float w) {
vec128_t v; vec128_t v;
v.f4[0] = x; v.f4[1] = y; v.f4[2] = z; v.f4[3] = w; v.f4[0] = x;
v.f4[1] = y;
v.f4[2] = z;
v.f4[3] = w;
return v; return v;
} }
XEFORCEINLINE vec128_t vec128b( XEFORCEINLINE vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3,
uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3,
uint8_t y0, uint8_t y1, uint8_t y2, uint8_t y3, uint8_t y0, uint8_t y1, uint8_t y2, uint8_t y3,
uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3, uint8_t z0, uint8_t z1, uint8_t z2, uint8_t z3,
uint8_t w0, uint8_t w1, uint8_t w2, uint8_t w3) { uint8_t w0, uint8_t w1, uint8_t w2, uint8_t w3) {
vec128_t v; vec128_t v;
v.b16[0] = x3; v.b16[1] = x2; v.b16[2] = x1; v.b16[3] = x0; v.b16[0] = x3;
v.b16[4] = y3; v.b16[5] = y2; v.b16[6] = y1; v.b16[7] = y0; v.b16[1] = x2;
v.b16[8] = z3; v.b16[9] = z2; v.b16[10] = z1; v.b16[11] = z0; v.b16[2] = x1;
v.b16[12] = w3; v.b16[13] = w2; v.b16[14] = w1; v.b16[15] = w0; v.b16[3] = x0;
v.b16[4] = y3;
v.b16[5] = y2;
v.b16[6] = y1;
v.b16[7] = y0;
v.b16[8] = z3;
v.b16[9] = z2;
v.b16[10] = z1;
v.b16[11] = z0;
v.b16[12] = w3;
v.b16[13] = w2;
v.b16[14] = w1;
v.b16[15] = w0;
return v; return v;
} }
} // namespace alloy } // namespace alloy
#endif // ALLOY_CORE_H_ #endif // ALLOY_CORE_H_

View File

@ -16,10 +16,8 @@
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
// TODO(benvanik): go lockfree, and don't hold the lock while emitting. // TODO(benvanik): go lockfree, and don't hold the lock while emitting.
template <typename T> template <typename T>
@ -59,8 +57,6 @@ private:
std::vector<listener_t> listeners_; std::vector<listener_t> listeners_;
}; };
} // namespace alloy } // namespace alloy
#endif // ALLOY_DELEGATE_H_ #endif // ALLOY_DELEGATE_H_

View File

@ -9,14 +9,13 @@
#include <alloy/frontend/context_info.h> #include <alloy/frontend/context_info.h>
using namespace alloy; namespace alloy {
using namespace alloy::frontend; namespace frontend {
ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset)
: size_(size), thread_state_offset_(thread_state_offset) {}
ContextInfo::ContextInfo(size_t size, uintptr_t thread_state_offset) : ContextInfo::~ContextInfo() {}
size_(size),
thread_state_offset_(thread_state_offset) {
}
ContextInfo::~ContextInfo() { } // namespace frontend
} } // namespace alloy

View File

@ -12,11 +12,9 @@
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
class ContextInfo { class ContextInfo {
public: public:
ContextInfo(size_t size, uintptr_t thread_state_offset); ContextInfo(size_t size, uintptr_t thread_state_offset);
@ -31,9 +29,7 @@ private:
uintptr_t thread_state_offset_; uintptr_t thread_state_offset_;
}; };
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_CONTEXT_INFO_H_ #endif // ALLOY_FRONTEND_CONTEXT_INFO_H_

View File

@ -12,23 +12,17 @@
#include <alloy/frontend/tracing.h> #include <alloy/frontend/tracing.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::frontend; namespace frontend {
using namespace alloy::runtime;
Frontend::Frontend(runtime::Runtime* runtime)
: runtime_(runtime), context_info_(0) {}
Frontend::Frontend(Runtime* runtime) : Frontend::~Frontend() { delete context_info_; }
runtime_(runtime), context_info_(0) {
}
Frontend::~Frontend() { Memory* Frontend::memory() const { return runtime_->memory(); }
delete context_info_;
}
Memory* Frontend::memory() const { int Frontend::Initialize() { return 0; }
return runtime_->memory();
}
int Frontend::Initialize() { } // namespace frontend
return 0; } // namespace alloy
}

View File

@ -16,15 +16,15 @@
#include <alloy/runtime/function.h> #include <alloy/runtime/function.h>
#include <alloy/runtime/symbol_info.h> #include <alloy/runtime/symbol_info.h>
namespace alloy {
namespace alloy { namespace runtime { namespace runtime {
class Runtime; class Runtime;
} } } // namespace runtime
} // namespace alloy
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
class Frontend { class Frontend {
public: public:
Frontend(runtime::Runtime* runtime); Frontend(runtime::Runtime* runtime);
@ -36,10 +36,9 @@ public:
virtual int Initialize(); virtual int Initialize();
virtual int DeclareFunction( virtual int DeclareFunction(runtime::FunctionInfo* symbol_info) = 0;
runtime::FunctionInfo* symbol_info) = 0; virtual int DefineFunction(runtime::FunctionInfo* symbol_info,
virtual int DefineFunction( uint32_t debug_info_flags,
runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags,
runtime::Function** out_function) = 0; runtime::Function** out_function) = 0;
protected: protected:
@ -47,9 +46,7 @@ protected:
ContextInfo* context_info_; ContextInfo* context_info_;
}; };
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_FRONTEND_H_ #endif // ALLOY_FRONTEND_FRONTEND_H_

View File

@ -9,19 +9,11 @@
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
using namespace alloy; namespace alloy {
using namespace alloy::frontend; namespace frontend {
using namespace alloy::frontend::ppc; namespace ppc {
namespace {
uint64_t ParseInt64(const char* value) {
return xestrtoulla(value, NULL, 0);
}
}
uint64_t ParseInt64(const char* value) { return xestrtoulla(value, NULL, 0); }
void PPCContext::SetRegFromString(const char* name, const char* value) { void PPCContext::SetRegFromString(const char* name, const char* value) {
int n; int n;
@ -32,8 +24,7 @@ void PPCContext::SetRegFromString(const char* name, const char* value) {
} }
} }
bool PPCContext::CompareRegWithString( bool PPCContext::CompareRegWithString(const char* name, const char* value,
const char* name, const char* value,
char* out_value, size_t out_value_size) { char* out_value, size_t out_value_size) {
int n; int n;
if (sscanf(name, "r%d", &n) == 1) { if (sscanf(name, "r%d", &n) == 1) {
@ -48,3 +39,7 @@ bool PPCContext::CompareRegWithString(
return false; return false;
} }
} }
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -9,10 +9,6 @@
#include <alloy/frontend/ppc/ppc_disasm.h> #include <alloy/frontend/ppc/ppc_disasm.h>
using namespace alloy::frontend::ppc;
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
@ -26,115 +22,105 @@ void Disasm__(InstrData& i, StringBuffer* str) {
} }
void Disasm_X_FRT_FRB(InstrData& i, StringBuffer* str) { void Disasm_X_FRT_FRB(InstrData& i, StringBuffer* str) {
str->Append("%*s%s f%d, f%d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", str->Append("%*s%s f%d, f%d", i.X.Rc ? -7 : -8, i.type->name,
i.X.RT, i.X.RB); i.X.Rc ? "." : "", i.X.RT, i.X.RB);
} }
void Disasm_A_FRT_FRB(InstrData& i, StringBuffer* str) { void Disasm_A_FRT_FRB(InstrData& i, StringBuffer* str) {
str->Append("%*s%s f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, i.A.Rc ? "." : "", str->Append("%*s%s f%d, f%d", i.A.Rc ? -7 : -8, i.type->name,
i.A.FRT, i.A.FRB); i.A.Rc ? "." : "", i.A.FRT, i.A.FRB);
} }
void Disasm_A_FRT_FRA_FRB(InstrData& i, StringBuffer* str) { void Disasm_A_FRT_FRA_FRB(InstrData& i, StringBuffer* str) {
str->Append("%*s%s f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, i.A.Rc ? "." : "", str->Append("%*s%s f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name,
i.A.FRT, i.A.FRA, i.A.FRB); i.A.Rc ? "." : "", i.A.FRT, i.A.FRA, i.A.FRB);
} }
void Disasm_A_FRT_FRA_FRB_FRC(InstrData& i, StringBuffer* str) { void Disasm_A_FRT_FRA_FRB_FRC(InstrData& i, StringBuffer* str) {
str->Append("%*s%s f%d, f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name, i.A.Rc ? "." : "", str->Append("%*s%s f%d, f%d, f%d, f%d", i.A.Rc ? -7 : -8, i.type->name,
i.A.FRT, i.A.FRA, i.A.FRB, i.A.FRC); i.A.Rc ? "." : "", i.A.FRT, i.A.FRA, i.A.FRB, i.A.FRC);
} }
void Disasm_X_RT_RA_RB(InstrData& i, StringBuffer* str) { void Disasm_X_RT_RA_RB(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, r%d, %d", i.type->name, str->Append("%-8s r%d, r%d, %d", i.type->name, i.X.RT, i.X.RA, i.X.RB);
i.X.RT, i.X.RA, i.X.RB);
} }
void Disasm_X_RT_RA0_RB(InstrData& i, StringBuffer* str) { void Disasm_X_RT_RA0_RB(InstrData& i, StringBuffer* str) {
if (i.X.RA) { if (i.X.RA) {
str->Append("%-8s r%d, r%d, %d", i.type->name, str->Append("%-8s r%d, r%d, %d", i.type->name, i.X.RT, i.X.RA, i.X.RB);
i.X.RT, i.X.RA, i.X.RB);
} else { } else {
str->Append("%-8s r%d, 0, %d", i.type->name, str->Append("%-8s r%d, 0, %d", i.type->name, i.X.RT, i.X.RB);
i.X.RT, i.X.RB);
} }
} }
void Disasm_X_FRT_RA_RB(InstrData& i, StringBuffer* str) { void Disasm_X_FRT_RA_RB(InstrData& i, StringBuffer* str) {
str->Append("%-8s f%d, r%d, %d", i.type->name, str->Append("%-8s f%d, r%d, %d", i.type->name, i.X.RT, i.X.RA, i.X.RB);
i.X.RT, i.X.RA, i.X.RB);
} }
void Disasm_X_FRT_RA0_RB(InstrData& i, StringBuffer* str) { void Disasm_X_FRT_RA0_RB(InstrData& i, StringBuffer* str) {
if (i.X.RA) { if (i.X.RA) {
str->Append("%-8s f%d, r%d, %d", i.type->name, str->Append("%-8s f%d, r%d, %d", i.type->name, i.X.RT, i.X.RA, i.X.RB);
i.X.RT, i.X.RA, i.X.RB);
} else { } else {
str->Append("%-8s f%d, 0, %d", i.type->name, str->Append("%-8s f%d, 0, %d", i.type->name, i.X.RT, i.X.RB);
i.X.RT, i.X.RB);
} }
} }
void Disasm_D_RT_RA_I(InstrData& i, StringBuffer* str) { void Disasm_D_RT_RA_I(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, r%d, %d", i.type->name, str->Append("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA,
i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS)); (int32_t)(int16_t)XEEXTS16(i.D.DS));
} }
void Disasm_D_RT_RA0_I(InstrData& i, StringBuffer* str) { void Disasm_D_RT_RA0_I(InstrData& i, StringBuffer* str) {
if (i.D.RA) { if (i.D.RA) {
str->Append("%-8s r%d, r%d, %d", i.type->name, str->Append("%-8s r%d, r%d, %d", i.type->name, i.D.RT, i.D.RA,
i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS)); (int32_t)(int16_t)XEEXTS16(i.D.DS));
} else { } else {
str->Append("%-8s r%d, 0, %d", i.type->name, str->Append("%-8s r%d, 0, %d", i.type->name, i.D.RT,
i.D.RT, (int32_t)(int16_t)XEEXTS16(i.D.DS)); (int32_t)(int16_t)XEEXTS16(i.D.DS));
} }
} }
void Disasm_D_FRT_RA_I(InstrData& i, StringBuffer* str) { void Disasm_D_FRT_RA_I(InstrData& i, StringBuffer* str) {
str->Append("%-8s f%d, r%d, %d", i.type->name, str->Append("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA,
i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS)); (int32_t)(int16_t)XEEXTS16(i.D.DS));
} }
void Disasm_D_FRT_RA0_I(InstrData& i, StringBuffer* str) { void Disasm_D_FRT_RA0_I(InstrData& i, StringBuffer* str) {
if (i.D.RA) { if (i.D.RA) {
str->Append("%-8s f%d, r%d, %d", i.type->name, str->Append("%-8s f%d, r%d, %d", i.type->name, i.D.RT, i.D.RA,
i.D.RT, i.D.RA, (int32_t)(int16_t)XEEXTS16(i.D.DS)); (int32_t)(int16_t)XEEXTS16(i.D.DS));
} else { } else {
str->Append("%-8s f%d, 0, %d", i.type->name, str->Append("%-8s f%d, 0, %d", i.type->name, i.D.RT,
i.D.RT, (int32_t)(int16_t)XEEXTS16(i.D.DS)); (int32_t)(int16_t)XEEXTS16(i.D.DS));
} }
} }
void Disasm_DS_RT_RA_I(InstrData& i, StringBuffer* str) { void Disasm_DS_RT_RA_I(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, r%d, %d", i.type->name, str->Append("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA,
i.DS.RT, i.DS.RA, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
} }
void Disasm_DS_RT_RA0_I(InstrData& i, StringBuffer* str) { void Disasm_DS_RT_RA0_I(InstrData& i, StringBuffer* str) {
if (i.DS.RA) { if (i.DS.RA) {
str->Append("%-8s r%d, r%d, %d", i.type->name, str->Append("%-8s r%d, r%d, %d", i.type->name, i.DS.RT, i.DS.RA,
i.DS.RT, i.DS.RA, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
} else { } else {
str->Append("%-8s r%d, 0, %d", i.type->name, str->Append("%-8s r%d, 0, %d", i.type->name, i.DS.RT,
i.DS.RT, (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2)); (int32_t)(int16_t)XEEXTS16(i.DS.DS << 2));
} }
} }
void Disasm_D_RA(InstrData& i, StringBuffer* str) { void Disasm_D_RA(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d", i.type->name, str->Append("%-8s r%d", i.type->name, i.D.RA);
i.D.RA);
} }
void Disasm_X_RA_RB(InstrData& i, StringBuffer* str) { void Disasm_X_RA_RB(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, r%d", i.type->name, str->Append("%-8s r%d, r%d", i.type->name, i.X.RA, i.X.RB);
i.X.RA, i.X.RB);
} }
void Disasm_XO_RT_RA_RB(InstrData& i, StringBuffer* str) { void Disasm_XO_RT_RA_RB(InstrData& i, StringBuffer* str) {
str->Append("%*s%s%s r%d, r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name, str->Append("%*s%s%s r%d, r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name,
i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA,
i.XO.RT, i.XO.RA, i.XO.RB); i.XO.RB);
} }
void Disasm_XO_RT_RA(InstrData& i, StringBuffer* str) { void Disasm_XO_RT_RA(InstrData& i, StringBuffer* str) {
str->Append("%*s%s%s r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name, str->Append("%*s%s%s r%d, r%d", i.XO.Rc ? -7 : -8, i.type->name,
i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.OE ? "o" : "", i.XO.Rc ? "." : "", i.XO.RT, i.XO.RA);
i.XO.RT, i.XO.RA);
} }
void Disasm_X_RA_RT_RB(InstrData& i, StringBuffer* str) { void Disasm_X_RA_RT_RB(InstrData& i, StringBuffer* str) {
str->Append("%*s%s r%d, r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", str->Append("%*s%s r%d, r%d, r%d", i.X.Rc ? -7 : -8, i.type->name,
i.X.RA, i.X.RT, i.X.RB); i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB);
} }
void Disasm_D_RA_RT_I(InstrData& i, StringBuffer* str) { void Disasm_D_RA_RT_I(InstrData& i, StringBuffer* str) {
str->Append("%-7s. r%d, r%d, %.4Xh", i.type->name, str->Append("%-7s. r%d, r%d, %.4Xh", i.type->name, i.D.RA, i.D.RT, i.D.DS);
i.D.RA, i.D.RT, i.D.DS);
} }
void Disasm_X_RA_RT(InstrData& i, StringBuffer* str) { void Disasm_X_RA_RT(InstrData& i, StringBuffer* str) {
str->Append("%*s%s r%d, r%d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", str->Append("%*s%s r%d, r%d", i.X.Rc ? -7 : -8, i.type->name,
i.X.RA, i.X.RT); i.X.Rc ? "." : "", i.X.RA, i.X.RT);
} }
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) #define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
@ -147,11 +133,13 @@ void Disasm_X_RA_RT(InstrData& i, StringBuffer* str) {
#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) #define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630))
#define VX128_VD128 (i.VX128.VD128l | (i.VX128.VD128h << 5)) #define VX128_VD128 (i.VX128.VD128l | (i.VX128.VD128h << 5))
#define VX128_VA128 (i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6)) #define VX128_VA128 \
(i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6))
#define VX128_VB128 (i.VX128.VB128l | (i.VX128.VB128h << 5)) #define VX128_VB128 (i.VX128.VB128l | (i.VX128.VB128h << 5))
#define VX128_1_VD128 (i.VX128_1.VD128l | (i.VX128_1.VD128h << 5)) #define VX128_1_VD128 (i.VX128_1.VD128l | (i.VX128_1.VD128h << 5))
#define VX128_2_VD128 (i.VX128_2.VD128l | (i.VX128_2.VD128h << 5)) #define VX128_2_VD128 (i.VX128_2.VD128l | (i.VX128_2.VD128h << 5))
#define VX128_2_VA128 (i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6)) #define VX128_2_VA128 \
(i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6))
#define VX128_2_VB128 (i.VX128_2.VB128l | (i.VX128_2.VD128h << 5)) #define VX128_2_VB128 (i.VX128_2.VB128l | (i.VX128_2.VD128h << 5))
#define VX128_2_VC (i.VX128_2.VC) #define VX128_2_VC (i.VX128_2.VC)
#define VX128_3_VD128 (i.VX128_3.VD128l | (i.VX128_3.VD128h << 5)) #define VX128_3_VD128 (i.VX128_3.VD128l | (i.VX128_3.VD128h << 5))
@ -160,82 +148,79 @@ void Disasm_X_RA_RT(InstrData& i, StringBuffer* str) {
#define VX128_4_VD128 (i.VX128_4.VD128l | (i.VX128_4.VD128h << 5)) #define VX128_4_VD128 (i.VX128_4.VD128l | (i.VX128_4.VD128h << 5))
#define VX128_4_VB128 (i.VX128_4.VB128l | (i.VX128_4.VB128h << 5)) #define VX128_4_VB128 (i.VX128_4.VB128l | (i.VX128_4.VB128h << 5))
#define VX128_5_VD128 (i.VX128_5.VD128l | (i.VX128_5.VD128h << 5)) #define VX128_5_VD128 (i.VX128_5.VD128l | (i.VX128_5.VD128h << 5))
#define VX128_5_VA128 (i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6) #define VX128_5_VA128 \
(i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6)
#define VX128_5_VB128 (i.VX128_5.VB128l | (i.VX128_5.VB128h << 5)) #define VX128_5_VB128 (i.VX128_5.VB128l | (i.VX128_5.VB128h << 5))
#define VX128_5_SH (i.VX128_5.SH) #define VX128_5_SH (i.VX128_5.SH)
#define VX128_R_VD128 (i.VX128_R.VD128l | (i.VX128_R.VD128h << 5)) #define VX128_R_VD128 (i.VX128_R.VD128l | (i.VX128_R.VD128h << 5))
#define VX128_R_VA128 (i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6)) #define VX128_R_VA128 \
(i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6))
#define VX128_R_VB128 (i.VX128_R.VB128l | (i.VX128_R.VB128h << 5)) #define VX128_R_VB128 (i.VX128_R.VB128l | (i.VX128_R.VB128h << 5))
void Disasm_X_VX_RA0_RB(InstrData& i, StringBuffer* str) { void Disasm_X_VX_RA0_RB(InstrData& i, StringBuffer* str) {
if (i.X.RA) { if (i.X.RA) {
str->Append("%-8s v%d, r%d, r%d", i.type->name, str->Append("%-8s v%d, r%d, r%d", i.type->name, i.X.RT, i.X.RA, i.X.RB);
i.X.RT, i.X.RA, i.X.RB);
} else { } else {
str->Append("%-8s v%d, 0, r%d", i.type->name, str->Append("%-8s v%d, 0, r%d", i.type->name, i.X.RT, i.X.RB);
i.X.RT, i.X.RB);
} }
} }
void Disasm_VX1281_VD_RA0_RB(InstrData& i, StringBuffer* str) { void Disasm_VX1281_VD_RA0_RB(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_1_VD128; const uint32_t vd = VX128_1_VD128;
if (i.VX128_1.RA) { if (i.VX128_1.RA) {
str->Append("%-8s v%d, r%d, r%d", i.type->name, str->Append("%-8s v%d, r%d, r%d", i.type->name, vd, i.VX128_1.RA,
vd, i.VX128_1.RA, i.VX128_1.RB); i.VX128_1.RB);
} else { } else {
str->Append("%-8s v%d, 0, r%d", i.type->name, str->Append("%-8s v%d, 0, r%d", i.type->name, vd, i.VX128_1.RB);
vd, i.VX128_1.RB);
} }
} }
void Disasm_VX1283_VD_VB(InstrData& i, StringBuffer* str) { void Disasm_VX1283_VD_VB(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_3_VD128; const uint32_t vd = VX128_3_VD128;
const uint32_t vb = VX128_3_VB128; const uint32_t vb = VX128_3_VB128;
str->Append("%-8s v%d, v%d", i.type->name, str->Append("%-8s v%d, v%d", i.type->name, vd, vb);
vd, vb);
} }
void Disasm_VX1283_VD_VB_I(InstrData& i, StringBuffer* str) { void Disasm_VX1283_VD_VB_I(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_VD128; const uint32_t vd = VX128_VD128;
const uint32_t va = VX128_VA128; const uint32_t va = VX128_VA128;
const uint32_t uimm = i.VX128_3.IMM; const uint32_t uimm = i.VX128_3.IMM;
str->Append("%-8s v%d, v%d, %.2Xh", i.type->name, str->Append("%-8s v%d, v%d, %.2Xh", i.type->name, vd, va, uimm);
vd, va, uimm);
} }
void Disasm_VX_VD_VA_VB(InstrData& i, StringBuffer* str) { void Disasm_VX_VD_VA_VB(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, v%d", i.type->name, str->Append("%-8s v%d, v%d, v%d", i.type->name, i.VX.VD, i.VX.VA, i.VX.VB);
i.VX.VD, i.VX.VA, i.VX.VB);
} }
void Disasm_VX128_VD_VA_VB(InstrData& i, StringBuffer* str) { void Disasm_VX128_VD_VA_VB(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_VD128; const uint32_t vd = VX128_VD128;
const uint32_t va = VX128_VA128; const uint32_t va = VX128_VA128;
const uint32_t vb = VX128_VB128; const uint32_t vb = VX128_VB128;
str->Append("%-8s v%d, v%d, v%d", i.type->name, str->Append("%-8s v%d, v%d, v%d", i.type->name, vd, va, vb);
vd, va, vb);
} }
void Disasm_VX128_VD_VA_VD_VB(InstrData& i, StringBuffer* str) { void Disasm_VX128_VD_VA_VD_VB(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_VD128; const uint32_t vd = VX128_VD128;
const uint32_t va = VX128_VA128; const uint32_t va = VX128_VA128;
const uint32_t vb = VX128_VB128; const uint32_t vb = VX128_VB128;
str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, vd, va, vd, vb);
vd, va, vd, vb);
} }
void Disasm_VX1282_VD_VA_VB_VC(InstrData& i, StringBuffer* str) { void Disasm_VX1282_VD_VA_VB_VC(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_2_VD128; const uint32_t vd = VX128_2_VD128;
const uint32_t va = VX128_2_VA128; const uint32_t va = VX128_2_VA128;
const uint32_t vb = VX128_2_VB128; const uint32_t vb = VX128_2_VB128;
const uint32_t vc = i.VX128_2.VC; const uint32_t vc = i.VX128_2.VC;
str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, vd, va, vb, vc);
vd, va, vb, vc);
} }
void Disasm_VXA_VD_VA_VB_VC(InstrData& i, StringBuffer* str) { void Disasm_VXA_VD_VA_VB_VC(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, str->Append("%-8s v%d, v%d, v%d, v%d", i.type->name, i.VXA.VD, i.VXA.VA,
i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC); i.VXA.VB, i.VXA.VC);
} }
void Disasm_sync(InstrData& i, StringBuffer* str) { void Disasm_sync(InstrData& i, StringBuffer* str) {
const char* name; const char* name;
int L = i.X.RT & 3; int L = i.X.RT & 3;
switch (L) { switch (L) {
case 0: name = "hwsync"; break; case 0:
case 1: name = "lwsync"; break; name = "hwsync";
break;
case 1:
name = "lwsync";
break;
default: default:
case 2: case 2:
case 3: case 3:
@ -248,10 +233,18 @@ void Disasm_sync(InstrData& i, StringBuffer* str) {
void Disasm_dcbf(InstrData& i, StringBuffer* str) { void Disasm_dcbf(InstrData& i, StringBuffer* str) {
const char* name; const char* name;
switch (i.X.RT & 3) { switch (i.X.RT & 3) {
case 0: name = "dcbf"; break; case 0:
case 1: name = "dcbfl"; break; name = "dcbf";
case 2: name = "dcbf.RESERVED"; break; break;
case 3: name = "dcbflp"; break; case 1:
name = "dcbfl";
break;
case 2:
name = "dcbf.RESERVED";
break;
case 3:
name = "dcbflp";
break;
} }
str->Append("%-8s r%d, r%d", name, i.X.RA, i.X.RB); str->Append("%-8s r%d, r%d", name, i.X.RA, i.X.RB);
} }
@ -266,13 +259,12 @@ void Disasm_dcbz(InstrData& i, StringBuffer* str) {
} }
void Disasm_fcmp(InstrData& i, StringBuffer* str) { void Disasm_fcmp(InstrData& i, StringBuffer* str) {
str->Append("%-8s cr%d, f%d, f%d", i.type->name, str->Append("%-8s cr%d, f%d, f%d", i.type->name, i.X.RT >> 2, i.X.RA, i.X.RB);
i.X.RT >> 2, i.X.RA, i.X.RB);
} }
void Disasm_mffsx(InstrData& i, StringBuffer* str) { void Disasm_mffsx(InstrData& i, StringBuffer* str) {
str->Append("%*s%s f%d, FPSCR", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", str->Append("%*s%s f%d, FPSCR", i.X.Rc ? -7 : -8, i.type->name,
i.X.RT); i.X.Rc ? "." : "", i.X.RT);
} }
void Disasm_bx(InstrData& i, StringBuffer* str) { void Disasm_bx(InstrData& i, StringBuffer* str) {
@ -283,8 +275,7 @@ void Disasm_bx(InstrData& i, StringBuffer* str) {
} else { } else {
nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2)); nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2));
} }
str->Append("%-8s %.8X", name, str->Append("%-8s %.8X", name, nia);
nia);
// TODO(benvanik): resolve target name? // TODO(benvanik): resolve target name?
} }
void Disasm_bcx(InstrData& i, StringBuffer* str) { void Disasm_bcx(InstrData& i, StringBuffer* str) {
@ -295,7 +286,9 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) {
} else { } else {
s1 = ""; s1 = "";
} }
char s2[8] = { 'c', 'r', 0, }; char s2[8] = {
'c', 'r', 0,
};
if (!XESELECTBITS(i.B.BO, 4, 4)) { if (!XESELECTBITS(i.B.BO, 4, 4)) {
char* s2a = _itoa(i.B.BI >> 2, s2 + 2, 10); char* s2a = _itoa(i.B.BI >> 2, s2 + 2, 10);
s2a += xestrlena(s2a); s2a += xestrlena(s2a);
@ -310,14 +303,15 @@ void Disasm_bcx(InstrData& i, StringBuffer* str) {
} else { } else {
nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2)); nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2));
} }
str->Append("%-8s %s%s%s%.8X", i.type->name, str->Append("%-8s %s%s%s%.8X", i.type->name, s0, s1, s2, nia);
s0, s1, s2, nia);
// TODO(benvanik): resolve target name? // TODO(benvanik): resolve target name?
} }
void Disasm_bcctrx(InstrData& i, StringBuffer* str) { void Disasm_bcctrx(InstrData& i, StringBuffer* str) {
// TODO(benvanik): mnemonics // TODO(benvanik): mnemonics
const char* s0 = i.XL.LK ? "lr, " : ""; const char* s0 = i.XL.LK ? "lr, " : "";
char s2[8] = { 'c', 'r', 0, }; char s2[8] = {
'c', 'r', 0,
};
if (!XESELECTBITS(i.XL.BO, 4, 4)) { if (!XESELECTBITS(i.XL.BO, 4, 4)) {
char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10); char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10);
s2a += xestrlena(s2a); s2a += xestrlena(s2a);
@ -326,8 +320,7 @@ void Disasm_bcctrx(InstrData& i, StringBuffer* str) {
} else { } else {
s2[0] = 0; s2[0] = 0;
} }
str->Append("%-8s %s%sctr", i.type->name, str->Append("%-8s %s%sctr", i.type->name, s0, s2);
s0, s2);
// TODO(benvanik): resolve target name? // TODO(benvanik): resolve target name?
} }
void Disasm_bclrx(InstrData& i, StringBuffer* str) { void Disasm_bclrx(InstrData& i, StringBuffer* str) {
@ -341,7 +334,9 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) {
} else { } else {
s1 = ""; s1 = "";
} }
char s2[8] = { 'c', 'r', 0, }; char s2[8] = {
'c', 'r', 0,
};
if (!XESELECTBITS(i.XL.BO, 4, 4)) { if (!XESELECTBITS(i.XL.BO, 4, 4)) {
char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10); char* s2a = _itoa(i.XL.BI >> 2, s2 + 2, 10);
s2a += xestrlena(s2a); s2a += xestrlena(s2a);
@ -350,13 +345,11 @@ void Disasm_bclrx(InstrData& i, StringBuffer* str) {
} else { } else {
s2[0] = 0; s2[0] = 0;
} }
str->Append("%-8s %s%s", name, str->Append("%-8s %s%s", name, s1, s2);
s1, s2);
} }
void Disasm_mfcr(InstrData& i, StringBuffer* str) { void Disasm_mfcr(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, cr", i.type->name, str->Append("%-8s r%d, cr", i.type->name, i.X.RT);
i.X.RT);
} }
const char* Disasm_spr_name(uint32_t n) { const char* Disasm_spr_name(uint32_t n) {
const char* reg = "???"; const char* reg = "???";
@ -376,153 +369,142 @@ const char* Disasm_spr_name(uint32_t n) {
void Disasm_mfspr(InstrData& i, StringBuffer* str) { void Disasm_mfspr(InstrData& i, StringBuffer* str) {
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
const char* reg = Disasm_spr_name(n); const char* reg = Disasm_spr_name(n);
str->Append("%-8s r%d, %s", i.type->name, str->Append("%-8s r%d, %s", i.type->name, i.XFX.RT, reg);
i.XFX.RT, reg);
} }
void Disasm_mtspr(InstrData& i, StringBuffer* str) { void Disasm_mtspr(InstrData& i, StringBuffer* str) {
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F); const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
const char* reg = Disasm_spr_name(n); const char* reg = Disasm_spr_name(n);
str->Append("%-8s %s, r%d", i.type->name, str->Append("%-8s %s, r%d", i.type->name, reg, i.XFX.RT);
reg, i.XFX.RT);
} }
void Disasm_mftb(InstrData& i, StringBuffer* str) { void Disasm_mftb(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, tb", i.type->name, str->Append("%-8s r%d, tb", i.type->name, i.XFX.RT);
i.XFX.RT);
} }
void Disasm_mfmsr(InstrData& i, StringBuffer* str) { void Disasm_mfmsr(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d", i.type->name, str->Append("%-8s r%d", i.type->name, i.X.RT);
i.X.RT);
} }
void Disasm_mtmsr(InstrData& i, StringBuffer* str) { void Disasm_mtmsr(InstrData& i, StringBuffer* str) {
str->Append("%-8s r%d, %d", i.type->name, str->Append("%-8s r%d, %d", i.type->name, i.X.RT, (i.X.RA & 16) ? 1 : 0);
i.X.RT, (i.X.RA & 16) ? 1 : 0);
} }
void Disasm_cmp(InstrData& i, StringBuffer* str) { void Disasm_cmp(InstrData& i, StringBuffer* str) {
str->Append("%-8s cr%d, %.2X, r%d, r%d", i.type->name, str->Append("%-8s cr%d, %.2X, r%d, r%d", i.type->name, i.X.RT >> 2,
i.X.RT >> 2, i.X.RT & 1, i.X.RA, i.X.RB); i.X.RT & 1, i.X.RA, i.X.RB);
} }
void Disasm_cmpi(InstrData& i, StringBuffer* str) { void Disasm_cmpi(InstrData& i, StringBuffer* str) {
str->Append("%-8s cr%d, %.2X, r%d, %d", i.type->name, str->Append("%-8s cr%d, %.2X, r%d, %d", i.type->name, i.D.RT >> 2, i.D.RT & 1,
i.D.RT >> 2, i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS)); i.D.RA, XEEXTS16(i.D.DS));
} }
void Disasm_cmpli(InstrData& i, StringBuffer* str) { void Disasm_cmpli(InstrData& i, StringBuffer* str) {
str->Append("%-8s cr%d, %.2X, r%d, %.2X", i.type->name, str->Append("%-8s cr%d, %.2X, r%d, %.2X", i.type->name, i.D.RT >> 2,
i.D.RT >> 2, i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS)); i.D.RT & 1, i.D.RA, XEEXTS16(i.D.DS));
} }
void Disasm_rld(InstrData& i, StringBuffer* str) { void Disasm_rld(InstrData& i, StringBuffer* str) {
if (i.MD.idx == 0) { if (i.MD.idx == 0) {
// XEDISASMR(rldiclx, 0x78000000, MD ) // XEDISASMR(rldiclx, 0x78000000, MD )
str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicl", i.MD.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicl",
i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH,
(i.MD.MB5 << 5) | i.MD.MB);
} else if (i.MD.idx == 1) { } else if (i.MD.idx == 1) {
// XEDISASMR(rldicrx, 0x78000004, MD ) // XEDISASMR(rldicrx, 0x78000004, MD )
str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicr", i.MD.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldicr",
i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH,
(i.MD.MB5 << 5) | i.MD.MB);
} else if (i.MD.idx == 2) { } else if (i.MD.idx == 2) {
// XEDISASMR(rldicx, 0x78000008, MD ) // XEDISASMR(rldicx, 0x78000008, MD )
uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH; uint32_t sh = (i.MD.SH5 << 5) | i.MD.SH;
uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB; uint32_t mb = (i.MD.MB5 << 5) | i.MD.MB;
const char* name = (mb == 0x3E) ? "sldi" : "rldic"; const char* name = (mb == 0x3E) ? "sldi" : "rldic";
str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, name, i.MD.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, name,
i.MD.RA, i.MD.RT, sh, mb); i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, sh, mb);
} else if (i.MDS.idx == 8) { } else if (i.MDS.idx == 8) {
// XEDISASMR(rldclx, 0x78000010, MDS) // XEDISASMR(rldclx, 0x78000010, MDS)
str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcl", i.MDS.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcl",
i.MDS.RA, i.MDS.RT, i.MDS.RB, (i.MDS.MB5 << 5) | i.MDS.MB); i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB,
(i.MDS.MB5 << 5) | i.MDS.MB);
} else if (i.MDS.idx == 9) { } else if (i.MDS.idx == 9) {
// XEDISASMR(rldcrx, 0x78000012, MDS) // XEDISASMR(rldcrx, 0x78000012, MDS)
str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcr", i.MDS.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d, %d", i.MDS.Rc ? -7 : -8, "rldcr",
i.MDS.RA, i.MDS.RT, i.MDS.RB, (i.MDS.MB5 << 5) | i.MDS.MB); i.MDS.Rc ? "." : "", i.MDS.RA, i.MDS.RT, i.MDS.RB,
(i.MDS.MB5 << 5) | i.MDS.MB);
} else if (i.MD.idx == 3) { } else if (i.MD.idx == 3) {
// XEDISASMR(rldimix, 0x7800000C, MD ) // XEDISASMR(rldimix, 0x7800000C, MD )
str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldimi", i.MD.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d, %d", i.MD.Rc ? -7 : -8, "rldimi",
i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH, (i.MD.MB5 << 5) | i.MD.MB); i.MD.Rc ? "." : "", i.MD.RA, i.MD.RT, (i.MD.SH5 << 5) | i.MD.SH,
(i.MD.MB5 << 5) | i.MD.MB);
} else { } else {
XEASSERTALWAYS(); XEASSERTALWAYS();
} }
} }
void Disasm_rlwim(InstrData& i, StringBuffer* str) { void Disasm_rlwim(InstrData& i, StringBuffer* str) {
str->Append("%*s%s r%d, r%d, %d, %d, %d", i.M.Rc ? -7 : -8, i.type->name, i.M.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d, %d, %d", i.M.Rc ? -7 : -8, i.type->name,
i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME); i.M.Rc ? "." : "", i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME);
} }
void Disasm_rlwnmx(InstrData& i, StringBuffer* str) { void Disasm_rlwnmx(InstrData& i, StringBuffer* str) {
str->Append("%*s%s r%d, r%d, r%d, %d, %d", i.M.Rc ? -7 : -8, i.type->name, i.M.Rc ? "." : "", str->Append("%*s%s r%d, r%d, r%d, %d, %d", i.M.Rc ? -7 : -8, i.type->name,
i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME); i.M.Rc ? "." : "", i.M.RA, i.M.RT, i.M.SH, i.M.MB, i.M.ME);
} }
void Disasm_srawix(InstrData& i, StringBuffer* str) { void Disasm_srawix(InstrData& i, StringBuffer* str) {
str->Append("%*s%s r%d, r%d, %d", i.X.Rc ? -7 : -8, i.type->name, i.X.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d", i.X.Rc ? -7 : -8, i.type->name,
i.X.RA, i.X.RT, i.X.RB); i.X.Rc ? "." : "", i.X.RA, i.X.RT, i.X.RB);
} }
void Disasm_sradix(InstrData& i, StringBuffer* str) { void Disasm_sradix(InstrData& i, StringBuffer* str) {
str->Append("%*s%s r%d, r%d, %d", i.XS.Rc ? -7 : -8, i.type->name, i.XS.Rc ? "." : "", str->Append("%*s%s r%d, r%d, %d", i.XS.Rc ? -7 : -8, i.type->name,
i.XS.RA, i.XS.RT, (i.XS.SH5 << 5) | i.XS.SH); i.XS.Rc ? "." : "", i.XS.RA, i.XS.RT, (i.XS.SH5 << 5) | i.XS.SH);
} }
void Disasm_vpermwi128(InstrData& i, StringBuffer* str) { void Disasm_vpermwi128(InstrData& i, StringBuffer* str) {
const uint32_t vd = i.VX128_P.VD128l | (i.VX128_P.VD128h << 5); const uint32_t vd = i.VX128_P.VD128l | (i.VX128_P.VD128h << 5);
const uint32_t vb = i.VX128_P.VB128l | (i.VX128_P.VB128h << 5); const uint32_t vb = i.VX128_P.VB128l | (i.VX128_P.VB128h << 5);
str->Append("%-8s v%d, v%d, %.2X", i.type->name, str->Append("%-8s v%d, v%d, %.2X", i.type->name, vd, vb,
vd, vb, i.VX128_P.PERMl | (i.VX128_P.PERMh << 5)); i.VX128_P.PERMl | (i.VX128_P.PERMh << 5));
} }
void Disasm_vrfin128(InstrData& i, StringBuffer* str) { void Disasm_vrfin128(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_3_VD128; const uint32_t vd = VX128_3_VD128;
const uint32_t vb = VX128_3_VB128; const uint32_t vb = VX128_3_VB128;
str->Append("%-8s v%d, v%d", i.type->name, str->Append("%-8s v%d, v%d", i.type->name, vd, vb);
vd, vb);
} }
void Disasm_vrlimi128(InstrData& i, StringBuffer* str) { void Disasm_vrlimi128(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_4_VD128; const uint32_t vd = VX128_4_VD128;
const uint32_t vb = VX128_4_VB128; const uint32_t vb = VX128_4_VB128;
str->Append("%-8s v%d, v%d, %.2X, %.2X", i.type->name, str->Append("%-8s v%d, v%d, %.2X, %.2X", i.type->name, vd, vb, i.VX128_4.IMM,
vd, vb, i.VX128_4.IMM, i.VX128_4.z); i.VX128_4.z);
} }
void Disasm_vsldoi128(InstrData& i, StringBuffer* str) { void Disasm_vsldoi128(InstrData& i, StringBuffer* str) {
const uint32_t vd = VX128_5_VD128; const uint32_t vd = VX128_5_VD128;
const uint32_t va = VX128_5_VA128; const uint32_t va = VX128_5_VA128;
const uint32_t vb = VX128_5_VB128; const uint32_t vb = VX128_5_VB128;
const uint32_t sh = i.VX128_5.SH; const uint32_t sh = i.VX128_5.SH;
str->Append("%-8s v%d, v%d, v%d, %.2X", i.type->name, str->Append("%-8s v%d, v%d, v%d, %.2X", i.type->name, vd, va, vb, sh);
vd, va, vb, sh);
} }
void Disasm_vspltb(InstrData& i, StringBuffer* str) { void Disasm_vspltb(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, %.2X", i.type->name, str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB,
i.VX.VD, i.VX.VB, i.VX.VA & 0xF); i.VX.VA & 0xF);
} }
void Disasm_vsplth(InstrData& i, StringBuffer* str) { void Disasm_vsplth(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, %.2X", i.type->name, str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB,
i.VX.VD, i.VX.VB, i.VX.VA & 0x7); i.VX.VA & 0x7);
} }
void Disasm_vspltw(InstrData& i, StringBuffer* str) { void Disasm_vspltw(InstrData& i, StringBuffer* str) {
str->Append("%-8s v%d, v%d, %.2X", i.type->name, str->Append("%-8s v%d, v%d, %.2X", i.type->name, i.VX.VD, i.VX.VB, i.VX.VA);
i.VX.VD, i.VX.VB, i.VX.VA);
} }
void Disasm_vspltisb(InstrData& i, StringBuffer* str) { void Disasm_vspltisb(InstrData& i, StringBuffer* str) {
// 5bit -> 8bit sign extend // 5bit -> 8bit sign extend
int8_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xF0) : i.VX.VA; int8_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xF0) : i.VX.VA;
str->Append("%-8s v%d, %.2X", i.type->name, str->Append("%-8s v%d, %.2X", i.type->name, i.VX.VD, simm);
i.VX.VD, simm);
} }
void Disasm_vspltish(InstrData& i, StringBuffer* str) { void Disasm_vspltish(InstrData& i, StringBuffer* str) {
// 5bit -> 16bit sign extend // 5bit -> 16bit sign extend
int16_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFF0) : i.VX.VA; int16_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFF0) : i.VX.VA;
str->Append("%-8s v%d, %.4X", i.type->name, str->Append("%-8s v%d, %.4X", i.type->name, i.VX.VD, simm);
i.VX.VD, simm);
} }
void Disasm_vspltisw(InstrData& i, StringBuffer* str) { void Disasm_vspltisw(InstrData& i, StringBuffer* str) {
// 5bit -> 32bit sign extend // 5bit -> 32bit sign extend
int32_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFF0) : i.VX.VA; int32_t simm = (i.VX.VA & 0x10) ? (i.VX.VA | 0xFFFFFFF0) : i.VX.VA;
str->Append("%-8s v%d, %.8X", i.type->name, str->Append("%-8s v%d, %.8X", i.type->name, i.VX.VD, simm);
i.VX.VD, simm);
} }
} // namespace ppc int DisasmPPC(InstrData& i, StringBuffer* str) {
} // namespace frontend
} // namespace alloy
int alloy::frontend::ppc::DisasmPPC(InstrData& i, StringBuffer* str) {
if (!i.type) { if (!i.type) {
str->Append("???"); str->Append("???");
} else { } else {
@ -531,3 +513,6 @@ int alloy::frontend::ppc::DisasmPPC(InstrData& i, StringBuffer* str) {
return 0; return 0;
} }
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -12,18 +12,14 @@
#include <alloy/frontend/ppc/ppc_instr.h> #include <alloy/frontend/ppc/ppc_instr.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
int DisasmPPC(InstrData& i, StringBuffer* str); int DisasmPPC(InstrData& i, StringBuffer* str);
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_DISASM_H_ #endif // ALLOY_FRONTEND_PPC_PPC_DISASM_H_

View File

@ -13,12 +13,10 @@
#include <alloy/frontend/ppc/ppc_emit.h> #include <alloy/frontend/ppc/ppc_emit.h>
#include <alloy/frontend/ppc/ppc_instr.h> #include <alloy/frontend/ppc/ppc_instr.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
#define XEEMITTER(name, opcode, format) int InstrEmit_##name #define XEEMITTER(name, opcode, format) int InstrEmit_##name
#define XEREGISTERINSTR(name, opcode) \ #define XEREGISTERINSTR(name, opcode) \
@ -28,10 +26,8 @@ namespace ppc {
//#define XEINSTRNOTIMPLEMENTED XEASSERTALWAYS //#define XEINSTRNOTIMPLEMENTED XEASSERTALWAYS
//#define XEINSTRNOTIMPLEMENTED() __debugbreak() //#define XEINSTRNOTIMPLEMENTED() __debugbreak()
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_ #endif // ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_

View File

@ -12,22 +12,18 @@
#include <alloy/frontend/ppc/ppc_instr.h> #include <alloy/frontend/ppc/ppc_instr.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
void RegisterEmitCategoryAltivec(); void RegisterEmitCategoryAltivec();
void RegisterEmitCategoryALU(); void RegisterEmitCategoryALU();
void RegisterEmitCategoryControl(); void RegisterEmitCategoryControl();
void RegisterEmitCategoryFPU(); void RegisterEmitCategoryFPU();
void RegisterEmitCategoryMemory(); void RegisterEmitCategoryMemory();
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_EMIT_H_ #endif // ALLOY_FRONTEND_PPC_PPC_EMIT_H_

View File

@ -12,28 +12,23 @@
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_hir_builder.h> #include <alloy/frontend/ppc/ppc_hir_builder.h>
using namespace alloy::frontend::ppc;
using namespace alloy::hir;
using namespace alloy::runtime;
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using alloy::hir::Value;
Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb); Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb);
#define SHUFPS_SWAP_DWORDS 0x1B #define SHUFPS_SWAP_DWORDS 0x1B
// Most of this file comes from: // Most of this file comes from:
// http://biallas.net/doc/vmx128/vmx128.txt // http://biallas.net/doc/vmx128/vmx128.txt
// https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp // https://github.com/kakaroto/ps3ida/blob/master/plugins/PPCAltivec/src/main.cpp
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26) #define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0)) #define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))
#define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3)) #define VX128_1(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x7f3))
@ -44,67 +39,28 @@ Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb);
#define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630)) #define VX128_P(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x630))
#define VX128_VD128 (i.VX128.VD128l | (i.VX128.VD128h << 5)) #define VX128_VD128 (i.VX128.VD128l | (i.VX128.VD128h << 5))
#define VX128_VA128 (i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6)) #define VX128_VA128 \
(i.VX128.VA128l | (i.VX128.VA128h << 5) | (i.VX128.VA128H << 6))
#define VX128_VB128 (i.VX128.VB128l | (i.VX128.VB128h << 5)) #define VX128_VB128 (i.VX128.VB128l | (i.VX128.VB128h << 5))
#define VX128_1_VD128 (i.VX128_1.VD128l | (i.VX128_1.VD128h << 5)) #define VX128_1_VD128 (i.VX128_1.VD128l | (i.VX128_1.VD128h << 5))
#define VX128_2_VD128 (i.VX128_2.VD128l | (i.VX128_2.VD128h << 5)) #define VX128_2_VD128 (i.VX128_2.VD128l | (i.VX128_2.VD128h << 5))
#define VX128_2_VA128 (i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6)) #define VX128_2_VA128 \
(i.VX128_2.VA128l | (i.VX128_2.VA128h << 5) | (i.VX128_2.VA128H << 6))
#define VX128_2_VB128 (i.VX128_2.VB128l | (i.VX128_2.VD128h << 5)) #define VX128_2_VB128 (i.VX128_2.VB128l | (i.VX128_2.VD128h << 5))
#define VX128_2_VC (i.VX128_2.VC) #define VX128_2_VC (i.VX128_2.VC)
#define VX128_3_VD128 (i.VX128_3.VD128l | (i.VX128_3.VD128h << 5)) #define VX128_3_VD128 (i.VX128_3.VD128l | (i.VX128_3.VD128h << 5))
#define VX128_3_VB128 (i.VX128_3.VB128l | (i.VX128_3.VB128h << 5)) #define VX128_3_VB128 (i.VX128_3.VB128l | (i.VX128_3.VB128h << 5))
#define VX128_3_IMM (i.VX128_3.IMM) #define VX128_3_IMM (i.VX128_3.IMM)
#define VX128_5_VD128 (i.VX128_5.VD128l | (i.VX128_5.VD128h << 5)) #define VX128_5_VD128 (i.VX128_5.VD128l | (i.VX128_5.VD128h << 5))
#define VX128_5_VA128 (i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6) #define VX128_5_VA128 \
(i.VX128_5.VA128l | (i.VX128_5.VA128h << 5)) | (i.VX128_5.VA128H << 6)
#define VX128_5_VB128 (i.VX128_5.VB128l | (i.VX128_5.VB128h << 5)) #define VX128_5_VB128 (i.VX128_5.VB128l | (i.VX128_5.VB128h << 5))
#define VX128_5_SH (i.VX128_5.SH) #define VX128_5_SH (i.VX128_5.SH)
#define VX128_R_VD128 (i.VX128_R.VD128l | (i.VX128_R.VD128h << 5)) #define VX128_R_VD128 (i.VX128_R.VD128l | (i.VX128_R.VD128h << 5))
#define VX128_R_VA128 (i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6)) #define VX128_R_VA128 \
(i.VX128_R.VA128l | (i.VX128_R.VA128h << 5) | (i.VX128_R.VA128H << 6))
#define VX128_R_VB128 (i.VX128_R.VB128l | (i.VX128_R.VB128h << 5)) #define VX128_R_VB128 (i.VX128_R.VB128l | (i.VX128_R.VB128h << 5))
// namespace {
// // Shuffle masks to shift the values over and insert zeros from the low bits.
// static __m128i __shift_table_left[16] = {
// _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0), // unused
// _mm_set_epi8(14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15),
// _mm_set_epi8(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15),
// _mm_set_epi8(12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15),
// _mm_set_epi8(11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15),
// _mm_set_epi8(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15),
// _mm_set_epi8( 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 7, 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 6, 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 5, 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 4, 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 3, 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 2, 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 1, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15),
// _mm_set_epi8( 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15),
// };
// static __m128i __shift_table_right[16] = {
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), // unused
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7),
// _mm_set_epi8( 0, 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6),
// _mm_set_epi8( 0, 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5),
// _mm_set_epi8( 0, 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4),
// _mm_set_epi8( 0, 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3),
// _mm_set_epi8( 0, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2),
// _mm_set_epi8( 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1),
// };
// }
unsigned int xerotl(unsigned int value, unsigned int shift) { unsigned int xerotl(unsigned int value, unsigned int shift) {
XEASSERT(shift < 32); XEASSERT(shift < 32);
return shift == 0 ? value : ((value << shift) | (value >> (32 - shift))); return shift == 0 ? value : ((value << shift) | (value >> (32 - shift)));
@ -135,7 +91,8 @@ XEEMITTER(lvehx, 0x7C00004E, X )(PPCHIRBuilder& f, InstrData& i) {
return 1; return 1;
} }
int InstrEmit_lvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_lvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
XEINSTRNOTIMPLEMENTED(); XEINSTRNOTIMPLEMENTED();
return 1; return 1;
} }
@ -146,7 +103,8 @@ XEEMITTER(lvewx128, VX128_1(4, 131), VX128_1)(PPCHIRBuilder& f, InstrData
return InstrEmit_lvewx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); return InstrEmit_lvewx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB);
} }
int InstrEmit_lvsl_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_lvsl_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
Value* ea = CalculateEA_0(f, ra, rb); Value* ea = CalculateEA_0(f, ra, rb);
Value* sh = f.Truncate(f.And(ea, f.LoadConstant((int64_t)0xF)), INT8_TYPE); Value* sh = f.Truncate(f.And(ea, f.LoadConstant((int64_t)0xF)), INT8_TYPE);
Value* v = f.LoadVectorShl(sh); Value* v = f.LoadVectorShl(sh);
@ -160,7 +118,8 @@ XEEMITTER(lvsl128, VX128_1(4, 3), VX128_1)(PPCHIRBuilder& f, InstrData
return InstrEmit_lvsl_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); return InstrEmit_lvsl_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB);
} }
int InstrEmit_lvsr_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_lvsr_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
Value* ea = CalculateEA_0(f, ra, rb); Value* ea = CalculateEA_0(f, ra, rb);
Value* sh = f.Truncate(f.And(ea, f.LoadConstant((int64_t)0xF)), INT8_TYPE); Value* sh = f.Truncate(f.And(ea, f.LoadConstant((int64_t)0xF)), INT8_TYPE);
Value* v = f.LoadVectorShr(sh); Value* v = f.LoadVectorShr(sh);
@ -174,7 +133,8 @@ XEEMITTER(lvsr128, VX128_1(4, 67), VX128_1)(PPCHIRBuilder& f, InstrData
return InstrEmit_lvsr_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); return InstrEmit_lvsr_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB);
} }
int InstrEmit_lvx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_lvx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
Value* ea = f.And(CalculateEA_0(f, ra, rb), f.LoadConstant(~0xFull)); Value* ea = f.And(CalculateEA_0(f, ra, rb), f.LoadConstant(~0xFull));
f.StoreVR(vd, f.ByteSwap(f.Load(ea, VEC128_TYPE))); f.StoreVR(vd, f.ByteSwap(f.Load(ea, VEC128_TYPE)));
return 0; return 0;
@ -209,7 +169,8 @@ XEEMITTER(stvehx, 0x7C00014E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
int InstrEmit_stvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_stvewx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
Value* ea = CalculateEA_0(f, ra, rb); Value* ea = CalculateEA_0(f, ra, rb);
ea = f.And(ea, f.LoadConstant(~0x3ull)); ea = f.And(ea, f.LoadConstant(~0x3ull));
Value* el = f.Shr(f.And(ea, f.LoadConstant(0xFull)), 2); Value* el = f.Shr(f.And(ea, f.LoadConstant(0xFull)), 2);
@ -224,7 +185,8 @@ XEEMITTER(stvewx128, VX128_1(4, 387), VX128_1)(PPCHIRBuilder& f, InstrData
return InstrEmit_stvewx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB); return InstrEmit_stvewx_(f, i, VX128_1_VD128, i.VX128_1.RA, i.VX128_1.RB);
} }
int InstrEmit_stvx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_stvx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
Value* ea = f.And(CalculateEA_0(f, ra, rb), f.LoadConstant(~0xFull)); Value* ea = f.And(CalculateEA_0(f, ra, rb), f.LoadConstant(~0xFull));
f.Store(ea, f.ByteSwap(f.LoadVR(vd))); f.Store(ea, f.ByteSwap(f.LoadVR(vd)));
return 0; return 0;
@ -244,17 +206,15 @@ XEEMITTER(stvxl128, VX128_1(4, 963), VX128_1)(PPCHIRBuilder& f, InstrData
// The lvlx/lvrx/etc instructions are in Cell docs only: // The lvlx/lvrx/etc instructions are in Cell docs only:
// https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/C40E4C6133B31EE8872570B500791108/$file/vector_simd_pem_v_2.07c_26Oct2006_cell.pdf // https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/C40E4C6133B31EE8872570B500791108/$file/vector_simd_pem_v_2.07c_26Oct2006_cell.pdf
int InstrEmit_lvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_lvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
Value* ea = CalculateEA_0(f, ra, rb); Value* ea = CalculateEA_0(f, ra, rb);
Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant((int8_t)0xF)); Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant((int8_t)0xF));
// ea &= ~0xF // ea &= ~0xF
ea = f.And(ea, f.LoadConstant(~0xFull)); ea = f.And(ea, f.LoadConstant(~0xFull));
// v = (new << eb) // v = (new << eb)
Value* v = f.Permute( Value* v = f.Permute(f.LoadVectorShl(eb), f.ByteSwap(f.Load(ea, VEC128_TYPE)),
f.LoadVectorShl(eb), f.LoadZero(VEC128_TYPE), INT8_TYPE);
f.ByteSwap(f.Load(ea, VEC128_TYPE)),
f.LoadZero(VEC128_TYPE),
INT8_TYPE);
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
} }
@ -271,17 +231,16 @@ XEEMITTER(lvlxl128, VX128_1(4, 1539), VX128_1)(PPCHIRBuilder& f, InstrData
return InstrEmit_lvlx128(f, i); return InstrEmit_lvlx128(f, i);
} }
int InstrEmit_lvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_lvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
Value* ea = CalculateEA_0(f, ra, rb); Value* ea = CalculateEA_0(f, ra, rb);
Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant((int8_t)0xF)); Value* eb = f.And(f.Truncate(ea, INT8_TYPE), f.LoadConstant((int8_t)0xF));
// ea &= ~0xF // ea &= ~0xF
ea = f.And(ea, f.LoadConstant(~0xFull)); ea = f.And(ea, f.LoadConstant(~0xFull));
// v = (new >> (16 - eb)) // v = (new >> (16 - eb))
Value* v = f.Permute( Value* v = f.Permute(f.LoadVectorShr(f.Sub(f.LoadConstant((int8_t)16), eb)),
f.LoadVectorShr(f.Sub(f.LoadConstant((int8_t)16), eb)),
f.LoadZero(VEC128_TYPE), f.LoadZero(VEC128_TYPE),
f.ByteSwap(f.Load(ea, VEC128_TYPE)), f.ByteSwap(f.Load(ea, VEC128_TYPE)), INT8_TYPE);
INT8_TYPE);
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
} }
@ -298,7 +257,8 @@ XEEMITTER(lvrxl128, VX128_1(4, 1603), VX128_1)(PPCHIRBuilder& f, InstrData
return InstrEmit_lvrx128(f, i); return InstrEmit_lvrx128(f, i);
} }
int InstrEmit_stvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_stvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
// NOTE: if eb == 0 (so 16b aligned) this equals new_value // NOTE: if eb == 0 (so 16b aligned) this equals new_value
// we could optimize this to prevent the other load/mask, in that case. // we could optimize this to prevent the other load/mask, in that case.
Value* ea = CalculateEA_0(f, ra, rb); Value* ea = CalculateEA_0(f, ra, rb);
@ -308,20 +268,13 @@ int InstrEmit_stvlx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, u
ea = f.And(ea, f.LoadConstant(~0xFull)); ea = f.And(ea, f.LoadConstant(~0xFull));
Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE)); Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE));
// v = (new >> eb) | (old & (ONE << (16 - eb))) // v = (new >> eb) | (old & (ONE << (16 - eb)))
Value* v = f.Permute( Value* v = f.Permute(f.LoadVectorShr(eb), f.LoadZero(VEC128_TYPE), new_value,
f.LoadVectorShr(eb),
f.LoadZero(VEC128_TYPE),
new_value,
INT8_TYPE); INT8_TYPE);
v = f.Or( v = f.Or(
v, v, f.And(old_value,
f.And( f.Permute(f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)),
old_value,
f.Permute(
f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)),
f.Not(f.LoadZero(VEC128_TYPE)), f.Not(f.LoadZero(VEC128_TYPE)),
f.LoadZero(VEC128_TYPE), f.LoadZero(VEC128_TYPE), INT8_TYPE)));
INT8_TYPE)));
// ea &= ~0xF (handled above) // ea &= ~0xF (handled above)
f.Store(ea, f.ByteSwap(v)); f.Store(ea, f.ByteSwap(v));
return 0; return 0;
@ -335,11 +288,13 @@ XEEMITTER(stvlx128, VX128_1(4, 1283), VX128_1)(PPCHIRBuilder& f, InstrData
XEEMITTER(stvlxl, 0x7C00070E, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(stvlxl, 0x7C00070E, X)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_stvlx(f, i); return InstrEmit_stvlx(f, i);
} }
XEEMITTER(stvlxl128, VX128_1(4, 1795), VX128_1)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(stvlxl128, VX128_1(4, 1795), VX128_1)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_stvlx128(f, i); return InstrEmit_stvlx128(f, i);
} }
int InstrEmit_stvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, uint32_t rb) { int InstrEmit_stvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra,
uint32_t rb) {
// NOTE: if eb == 0 (so 16b aligned) this equals new_value // NOTE: if eb == 0 (so 16b aligned) this equals new_value
// we could optimize this to prevent the other load/mask, in that case. // we could optimize this to prevent the other load/mask, in that case.
Value* ea = CalculateEA_0(f, ra, rb); Value* ea = CalculateEA_0(f, ra, rb);
@ -349,20 +304,11 @@ int InstrEmit_stvrx_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t ra, u
ea = f.And(ea, f.LoadConstant(~0xFull)); ea = f.And(ea, f.LoadConstant(~0xFull));
Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE)); Value* old_value = f.ByteSwap(f.Load(ea, VEC128_TYPE));
// v = (new << (16 - eb)) | (old & (ONE >> eb)) // v = (new << (16 - eb)) | (old & (ONE >> eb))
Value* v = f.Permute( Value* v = f.Permute(f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)),
f.LoadVectorShl(f.Sub(f.LoadConstant((int8_t)16), eb)), new_value, f.LoadZero(VEC128_TYPE), INT8_TYPE);
new_value, v = f.Or(v, f.And(old_value,
f.LoadZero(VEC128_TYPE), f.Permute(f.LoadVectorShr(eb), f.LoadZero(VEC128_TYPE),
INT8_TYPE); f.Not(f.LoadZero(VEC128_TYPE)), INT8_TYPE)));
v = f.Or(
v,
f.And(
old_value,
f.Permute(
f.LoadVectorShr(eb),
f.LoadZero(VEC128_TYPE),
f.Not(f.LoadZero(VEC128_TYPE)),
INT8_TYPE)));
// ea &= ~0xF (handled above) // ea &= ~0xF (handled above)
f.Store(ea, f.ByteSwap(v)); f.Store(ea, f.ByteSwap(v));
return 0; return 0;
@ -376,7 +322,8 @@ XEEMITTER(stvrx128, VX128_1(4, 1347), VX128_1)(PPCHIRBuilder& f, InstrData
XEEMITTER(stvrxl, 0x7C00074E, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(stvrxl, 0x7C00074E, X)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_stvrx(f, i); return InstrEmit_stvrx(f, i);
} }
XEEMITTER(stvrxl128, VX128_1(4, 1859), VX128_1)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(stvrxl128, VX128_1(4, 1859), VX128_1)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_stvrx128(f, i); return InstrEmit_stvrx128(f, i);
} }
@ -409,72 +356,72 @@ XEEMITTER(vaddfp128, VX128(5, 16), VX128 )(PPCHIRBuilder& f, InstrData
} }
XEEMITTER(vaddsbs, 0x10000300, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vaddsbs, 0x10000300, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE,
INT8_TYPE, ARITHMETIC_SATURATE); ARITHMETIC_SATURATE);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
} }
XEEMITTER(vaddshs, 0x10000340, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vaddshs, 0x10000340, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE,
INT16_TYPE, ARITHMETIC_SATURATE); ARITHMETIC_SATURATE);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
} }
XEEMITTER(vaddsws, 0x10000380, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vaddsws, 0x10000380, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE,
INT32_TYPE, ARITHMETIC_SATURATE); ARITHMETIC_SATURATE);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
} }
XEEMITTER(vaddubm, 0x10000000, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vaddubm, 0x10000000, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE,
INT8_TYPE, ARITHMETIC_UNSIGNED); ARITHMETIC_UNSIGNED);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
} }
XEEMITTER(vaddubs, 0x10000200, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vaddubs, 0x10000200, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT8_TYPE,
INT8_TYPE, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
} }
XEEMITTER(vadduhm, 0x10000040, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vadduhm, 0x10000040, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE,
INT16_TYPE, ARITHMETIC_UNSIGNED); ARITHMETIC_UNSIGNED);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
} }
XEEMITTER(vadduhs, 0x10000240, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vadduhs, 0x10000240, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT16_TYPE,
INT16_TYPE, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
} }
XEEMITTER(vadduwm, 0x10000080, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vadduwm, 0x10000080, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE,
INT32_TYPE, ARITHMETIC_UNSIGNED); ARITHMETIC_UNSIGNED);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
} }
XEEMITTER(vadduws, 0x10000280, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vadduws, 0x10000280, VX)(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), Value* v = f.VectorAdd(f.LoadVR(i.VX.VA), f.LoadVR(i.VX.VB), INT32_TYPE,
INT32_TYPE, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE);
f.StoreSAT(f.DidSaturate(v)); f.StoreSAT(f.DidSaturate(v));
f.StoreVR(i.VX.VD, v); f.StoreVR(i.VX.VD, v);
return 0; return 0;
@ -536,11 +483,11 @@ XEEMITTER(vavguw, 0x10000482, VX )(PPCHIRBuilder& f, InstrData& i) {
return 1; return 1;
} }
int InstrEmit_vcfsx_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { int InstrEmit_vcfsx_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb,
uint32_t uimm) {
// (VD) <- float(VB as signed) / 2^uimm // (VD) <- float(VB as signed) / 2^uimm
uimm = uimm ? (2 << (uimm - 1)) : 1; uimm = uimm ? (2 << (uimm - 1)) : 1;
Value* v = f.Div( Value* v = f.Div(f.VectorConvertI2F(f.LoadVR(vb)),
f.VectorConvertI2F(f.LoadVR(vb)),
f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE));
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
@ -548,15 +495,16 @@ int InstrEmit_vcfsx_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm)
XEEMITTER(vcfsx, 0x1000034A, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcfsx, 0x1000034A, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcfsx_(f, i.VX.VD, i.VX.VB, i.VX.VA); return InstrEmit_vcfsx_(f, i.VX.VD, i.VX.VB, i.VX.VA);
} }
XEEMITTER(vcsxwfp128, VX128_3(6, 688), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcsxwfp128, VX128_3(6, 688), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vcfsx_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); return InstrEmit_vcfsx_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM);
} }
int InstrEmit_vcfux_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { int InstrEmit_vcfux_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb,
uint32_t uimm) {
// (VD) <- float(VB as unsigned) / 2^uimm // (VD) <- float(VB as unsigned) / 2^uimm
uimm = uimm ? (2 << (uimm - 1)) : 1; uimm = uimm ? (2 << (uimm - 1)) : 1;
Value* v = f.Div( Value* v = f.Div(f.VectorConvertI2F(f.LoadVR(vb), ARITHMETIC_UNSIGNED),
f.VectorConvertI2F(f.LoadVR(vb), ARITHMETIC_UNSIGNED),
f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE)); f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE));
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
@ -564,16 +512,17 @@ int InstrEmit_vcfux_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm)
XEEMITTER(vcfux, 0x1000030A, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcfux, 0x1000030A, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcfux_(f, i.VX.VD, i.VX.VB, i.VX.VA); return InstrEmit_vcfux_(f, i.VX.VD, i.VX.VB, i.VX.VA);
} }
XEEMITTER(vcuxwfp128, VX128_3(6, 752), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcuxwfp128, VX128_3(6, 752), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vcfux_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); return InstrEmit_vcfux_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM);
} }
int InstrEmit_vctsxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { int InstrEmit_vctsxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb,
uint32_t uimm) {
// (VD) <- int_sat(VB as signed * 2^uimm) // (VD) <- int_sat(VB as signed * 2^uimm)
uimm = uimm ? (2 << (uimm - 1)) : 1; uimm = uimm ? (2 << (uimm - 1)) : 1;
Value* v = f.Mul( Value* v =
f.LoadVR(vb), f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE));
f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE));
v = f.VectorConvertF2I(v, ARITHMETIC_SATURATE); v = f.VectorConvertF2I(v, ARITHMETIC_SATURATE);
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
@ -581,16 +530,17 @@ int InstrEmit_vctsxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm)
XEEMITTER(vctsxs, 0x100003CA, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vctsxs, 0x100003CA, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vctsxs_(f, i.VX.VD, i.VX.VB, i.VX.VA); return InstrEmit_vctsxs_(f, i.VX.VD, i.VX.VB, i.VX.VA);
} }
XEEMITTER(vcfpsxws128, VX128_3(6, 560), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcfpsxws128, VX128_3(6, 560), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vctsxs_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); return InstrEmit_vctsxs_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM);
} }
int InstrEmit_vctuxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { int InstrEmit_vctuxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb,
uint32_t uimm) {
// (VD) <- int_sat(VB as unsigned * 2^uimm) // (VD) <- int_sat(VB as unsigned * 2^uimm)
uimm = uimm ? (2 << (uimm - 1)) : 1; uimm = uimm ? (2 << (uimm - 1)) : 1;
Value* v = f.Mul( Value* v =
f.LoadVR(vb), f.Mul(f.LoadVR(vb), f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE));
f.Splat(f.LoadConstant((float)uimm), VEC128_TYPE));
v = f.VectorConvertF2I(v, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE); v = f.VectorConvertF2I(v, ARITHMETIC_UNSIGNED | ARITHMETIC_SATURATE);
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
@ -598,11 +548,13 @@ int InstrEmit_vctuxs_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm)
XEEMITTER(vctuxs, 0x1000038A, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vctuxs, 0x1000038A, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vctuxs_(f, i.VX.VD, i.VX.VB, i.VX.VA); return InstrEmit_vctuxs_(f, i.VX.VD, i.VX.VB, i.VX.VA);
} }
XEEMITTER(vcfpuxws128, VX128_3(6, 624), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcfpuxws128, VX128_3(6, 624), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vctuxs_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); return InstrEmit_vctuxs_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM);
} }
int InstrEmit_vcmpbfp_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { int InstrEmit_vcmpbfp_(PPCHIRBuilder& f, InstrData& i, uint32_t vd, uint32_t va,
uint32_t vb, uint32_t rc) {
XEINSTRNOTIMPLEMENTED(); XEINSTRNOTIMPLEMENTED();
return 1; return 1;
} }
@ -610,7 +562,8 @@ XEEMITTER(vcmpbfp, 0x100003C6, VXR )(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpbfp_(f, i, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpbfp_(f, i, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc);
} }
XEEMITTER(vcmpbfp128, VX128(6, 384), VX128_R)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpbfp128, VX128(6, 384), VX128_R)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpbfp_(f, i, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); return InstrEmit_vcmpbfp_(f, i, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128,
i.VX128_R.Rc);
} }
enum vcmpxxfp_op { enum vcmpxxfp_op {
@ -618,7 +571,8 @@ enum vcmpxxfp_op {
vcmpxxfp_gt, vcmpxxfp_gt,
vcmpxxfp_ge, vcmpxxfp_ge,
}; };
int InstrEmit_vcmpxxfp_(PPCHIRBuilder& f, InstrData& i, vcmpxxfp_op cmpop, uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { int InstrEmit_vcmpxxfp_(PPCHIRBuilder& f, InstrData& i, vcmpxxfp_op cmpop,
uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) {
// (VD.xyzw) = (VA.xyzw) OP (VB.xyzw) ? 0xFFFFFFFF : 0x00000000 // (VD.xyzw) = (VA.xyzw) OP (VB.xyzw) ? 0xFFFFFFFF : 0x00000000
// if (Rc) CR6 = all_equal | 0 | none_equal | 0 // if (Rc) CR6 = all_equal | 0 | none_equal | 0
// If an element in either VA or VB is NaN the result will be 0x00000000 // If an element in either VA or VB is NaN the result will be 0x00000000
@ -645,22 +599,28 @@ int InstrEmit_vcmpxxfp_(PPCHIRBuilder& f, InstrData& i, vcmpxxfp_op cmpop, uint3
} }
XEEMITTER(vcmpeqfp, 0x100000C6, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpeqfp, 0x100000C6, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_eq, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_eq, i.VXR.VD, i.VXR.VA, i.VXR.VB,
i.VXR.Rc);
} }
XEEMITTER(vcmpeqfp128, VX128(6, 0), VX128_R)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpeqfp128, VX128(6, 0), VX128_R)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_eq, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_eq, VX128_R_VD128, VX128_R_VA128,
VX128_R_VB128, i.VX128_R.Rc);
} }
XEEMITTER(vcmpgefp, 0x100001C6, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgefp, 0x100001C6, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_ge, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_ge, i.VXR.VD, i.VXR.VA, i.VXR.VB,
i.VXR.Rc);
} }
XEEMITTER(vcmpgefp128, VX128(6, 128), VX128_R)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgefp128, VX128(6, 128), VX128_R)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_ge, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_ge, VX128_R_VD128, VX128_R_VA128,
VX128_R_VB128, i.VX128_R.Rc);
} }
XEEMITTER(vcmpgtfp, 0x100002C6, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgtfp, 0x100002C6, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_gt, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_gt, i.VXR.VD, i.VXR.VA, i.VXR.VB,
i.VXR.Rc);
} }
XEEMITTER(vcmpgtfp128, VX128(6, 256), VX128_R)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgtfp128, VX128(6, 256), VX128_R)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_gt, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); return InstrEmit_vcmpxxfp_(f, i, vcmpxxfp_gt, VX128_R_VD128, VX128_R_VA128,
VX128_R_VB128, i.VX128_R.Rc);
} }
enum vcmpxxi_op { enum vcmpxxi_op {
@ -668,7 +628,9 @@ enum vcmpxxi_op {
vcmpxxi_gt_signed, vcmpxxi_gt_signed,
vcmpxxi_gt_unsigned, vcmpxxi_gt_unsigned,
}; };
int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, uint32_t width, uint32_t vd, uint32_t va, uint32_t vb, uint32_t rc) { int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop,
uint32_t width, uint32_t vd, uint32_t va, uint32_t vb,
uint32_t rc) {
// (VD.xyzw) = (VA.xyzw) OP (VB.xyzw) ? 0xFFFFFFFF : 0x00000000 // (VD.xyzw) = (VA.xyzw) OP (VB.xyzw) ? 0xFFFFFFFF : 0x00000000
// if (Rc) CR6 = all_equal | 0 | none_equal | 0 // if (Rc) CR6 = all_equal | 0 | none_equal | 0
// If an element in either VA or VB is NaN the result will be 0x00000000 // If an element in either VA or VB is NaN the result will be 0x00000000
@ -685,7 +647,9 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, uint32_
case 4: case 4:
v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); v = f.VectorCompareEQ(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE);
break; break;
default: XEASSERTALWAYS(); return 1; default:
XEASSERTALWAYS();
return 1;
} }
break; break;
case vcmpxxi_gt_signed: case vcmpxxi_gt_signed:
@ -699,7 +663,9 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, uint32_
case 4: case 4:
v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); v = f.VectorCompareSGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE);
break; break;
default: XEASSERTALWAYS(); return 1; default:
XEASSERTALWAYS();
return 1;
} }
break; break;
case vcmpxxi_gt_unsigned: case vcmpxxi_gt_unsigned:
@ -713,10 +679,14 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, uint32_
case 4: case 4:
v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE); v = f.VectorCompareUGT(f.LoadVR(va), f.LoadVR(vb), INT32_TYPE);
break; break;
default: XEASSERTALWAYS(); return 1; default:
XEASSERTALWAYS();
return 1;
} }
break; break;
default: XEASSERTALWAYS(); return 1; default:
XEASSERTALWAYS();
return 1;
} }
if (rc) { if (rc) {
f.UpdateCR6(v); f.UpdateCR6(v);
@ -725,34 +695,44 @@ int InstrEmit_vcmpxxi_(PPCHIRBuilder& f, InstrData& i, vcmpxxi_op cmpop, uint32_
return 0; return 0;
} }
XEEMITTER(vcmpequb, 0x10000006, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpequb, 0x10000006, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 1, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 1, i.VXR.VD, i.VXR.VA, i.VXR.VB,
i.VXR.Rc);
} }
XEEMITTER(vcmpequh, 0x10000046, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpequh, 0x10000046, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 2, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 2, i.VXR.VD, i.VXR.VA, i.VXR.VB,
i.VXR.Rc);
} }
XEEMITTER(vcmpequw, 0x10000086, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpequw, 0x10000086, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 4, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 4, i.VXR.VD, i.VXR.VA, i.VXR.VB,
i.VXR.Rc);
} }
XEEMITTER(vcmpequw128, VX128(6, 512), VX128_R)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpequw128, VX128(6, 512), VX128_R)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 4, VX128_R_VD128, VX128_R_VA128, VX128_R_VB128, i.VX128_R.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_eq, 4, VX128_R_VD128, VX128_R_VA128,
VX128_R_VB128, i.VX128_R.Rc);
} }
XEEMITTER(vcmpgtsb, 0x10000306, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgtsb, 0x10000306, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 1, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 1, i.VXR.VD, i.VXR.VA,
i.VXR.VB, i.VXR.Rc);
} }
XEEMITTER(vcmpgtsh, 0x10000346, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgtsh, 0x10000346, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 2, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 2, i.VXR.VD, i.VXR.VA,
i.VXR.VB, i.VXR.Rc);
} }
XEEMITTER(vcmpgtsw, 0x10000386, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgtsw, 0x10000386, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 4, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_signed, 4, i.VXR.VD, i.VXR.VA,
i.VXR.VB, i.VXR.Rc);
} }
XEEMITTER(vcmpgtub, 0x10000206, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgtub, 0x10000206, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 1, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 1, i.VXR.VD, i.VXR.VA,
i.VXR.VB, i.VXR.Rc);
} }
XEEMITTER(vcmpgtuh, 0x10000246, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgtuh, 0x10000246, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 2, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 2, i.VXR.VD, i.VXR.VA,
i.VXR.VB, i.VXR.Rc);
} }
XEEMITTER(vcmpgtuw, 0x10000286, VXR)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vcmpgtuw, 0x10000286, VXR)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 4, i.VXR.VD, i.VXR.VA, i.VXR.VB, i.VXR.Rc); return InstrEmit_vcmpxxi_(f, i, vcmpxxi_gt_unsigned, 4, i.VXR.VD, i.VXR.VA,
i.VXR.VB, i.VXR.Rc);
} }
int InstrEmit_vexptefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) { int InstrEmit_vexptefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) {
@ -764,7 +744,8 @@ int InstrEmit_vexptefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) {
XEEMITTER(vexptefp, 0x1000018A, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vexptefp, 0x1000018A, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vexptefp_(f, i.VX.VD, i.VX.VB); return InstrEmit_vexptefp_(f, i.VX.VD, i.VX.VB);
} }
XEEMITTER(vexptefp128, VX128_3(6, 1712), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vexptefp128, VX128_3(6, 1712), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vexptefp_(f, VX128_3_VD128, VX128_3_VB128); return InstrEmit_vexptefp_(f, VX128_3_VD128, VX128_3_VB128);
} }
@ -777,14 +758,15 @@ int InstrEmit_vlogefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) {
XEEMITTER(vlogefp, 0x100001CA, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vlogefp, 0x100001CA, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vlogefp_(f, i.VX.VD, i.VX.VB); return InstrEmit_vlogefp_(f, i.VX.VD, i.VX.VB);
} }
XEEMITTER(vlogefp128, VX128_3(6, 1776), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vlogefp128, VX128_3(6, 1776), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vlogefp_(f, VX128_3_VD128, VX128_3_VB128); return InstrEmit_vlogefp_(f, VX128_3_VD128, VX128_3_VB128);
} }
int InstrEmit_vmaddfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { int InstrEmit_vmaddfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb,
uint32_t vc) {
// (VD) <- ((VA) * (VC)) + (VB) // (VD) <- ((VA) * (VC)) + (VB)
Value* v = f.MulAdd( Value* v = f.MulAdd(f.LoadVR(va), f.LoadVR(vc), f.LoadVR(vb));
f.LoadVR(va), f.LoadVR(vc), f.LoadVR(vb));
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
} }
@ -795,13 +777,14 @@ XEEMITTER(vmaddfp, 0x1000002E, VXA )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(vmaddfp128, VX128(5, 208), VX128)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vmaddfp128, VX128(5, 208), VX128)(PPCHIRBuilder& f, InstrData& i) {
// (VD) <- ((VA) * (VB)) + (VD) // (VD) <- ((VA) * (VB)) + (VD)
// NOTE: this resuses VD and swaps the arg order! // NOTE: this resuses VD and swaps the arg order!
return InstrEmit_vmaddfp_(f, VX128_VD128, VX128_VA128, VX128_VD128, VX128_VB128); return InstrEmit_vmaddfp_(f, VX128_VD128, VX128_VA128, VX128_VD128,
VX128_VB128);
} }
XEEMITTER(vmaddcfp128, VX128(5, 272), VX128)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vmaddcfp128, VX128(5, 272), VX128)(PPCHIRBuilder& f, InstrData& i) {
// (VD) <- ((VA) * (VD)) + (VB) // (VD) <- ((VA) * (VD)) + (VB)
Value* v = f.MulAdd( Value* v = f.MulAdd(f.LoadVR(VX128_VA128), f.LoadVR(VX128_VD128),
f.LoadVR(VX128_VA128), f.LoadVR(VX128_VD128), f.LoadVR(VX128_VB128)); f.LoadVR(VX128_VB128));
f.StoreVR(VX128_VD128, v); f.StoreVR(VX128_VD128, v);
return 0; return 0;
} }
@ -922,10 +905,7 @@ int InstrEmit_vmrghw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
// (VD.y) = (VB.x) // (VD.y) = (VB.x)
// (VD.z) = (VA.y) // (VD.z) = (VA.y)
// (VD.w) = (VB.y) // (VD.w) = (VB.y)
Value* v = f.Permute( Value* v = f.Permute(f.LoadConstant(0x00040105), f.LoadVR(va), f.LoadVR(vb),
f.LoadConstant(0x00040105),
f.LoadVR(va),
f.LoadVR(vb),
INT32_TYPE); INT32_TYPE);
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
@ -952,10 +932,7 @@ int InstrEmit_vmrglw_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
// (VD.y) = (VB.z) // (VD.y) = (VB.z)
// (VD.z) = (VA.w) // (VD.z) = (VA.w)
// (VD.w) = (VB.w) // (VD.w) = (VB.w)
Value* v = f.Permute( Value* v = f.Permute(f.LoadConstant(0x02060307), f.LoadVR(va), f.LoadVR(vb),
f.LoadConstant(0x02060307),
f.LoadVR(va),
f.LoadVR(vb),
INT32_TYPE); INT32_TYPE);
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
@ -1062,7 +1039,8 @@ XEEMITTER(vmulfp128, VX128(5, 144), VX128 )(PPCHIRBuilder& f, InstrData
return 0; return 0;
} }
int InstrEmit_vnmsubfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { int InstrEmit_vnmsubfp_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb,
uint32_t vc) {
// (VD) <- -(((VA) * (VC)) - (VB)) // (VD) <- -(((VA) * (VC)) - (VB))
// NOTE: only one rounding should take place, but that's hard... // NOTE: only one rounding should take place, but that's hard...
// This really needs VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS but that's AVX. // This really needs VFNMSUB132PS/VFNMSUB213PS/VFNMSUB231PS but that's AVX.
@ -1074,7 +1052,8 @@ XEEMITTER(vnmsubfp, 0x1000002F, VXA )(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vnmsubfp_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC); return InstrEmit_vnmsubfp_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC);
} }
XEEMITTER(vnmsubfp128, VX128(5, 336), VX128)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vnmsubfp128, VX128(5, 336), VX128)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vnmsubfp_(f, VX128_VD128, VX128_VA128, VX128_VB128, VX128_VD128); return InstrEmit_vnmsubfp_(f, VX128_VD128, VX128_VA128, VX128_VB128,
VX128_VD128);
} }
int InstrEmit_vnor_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) { int InstrEmit_vnor_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb) {
@ -1108,7 +1087,8 @@ XEEMITTER(vor128, VX128(5, 720), VX128 )(PPCHIRBuilder& f, InstrData
return InstrEmit_vor_(f, VX128_VD128, VX128_VA128, VX128_VB128); return InstrEmit_vor_(f, VX128_VD128, VX128_VA128, VX128_VB128);
} }
int InstrEmit_vperm_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { int InstrEmit_vperm_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb,
uint32_t vc) {
Value* v = f.Permute(f.LoadVR(vc), f.LoadVR(va), f.LoadVR(vb), INT8_TYPE); Value* v = f.Permute(f.LoadVR(vc), f.LoadVR(va), f.LoadVR(vb), INT8_TYPE);
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
@ -1117,10 +1097,12 @@ XEEMITTER(vperm, 0x1000002B, VXA )(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vperm_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC); return InstrEmit_vperm_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC);
} }
XEEMITTER(vperm128, VX128_2(5, 0), VX128_2)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vperm128, VX128_2(5, 0), VX128_2)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vperm_(f, VX128_2_VD128, VX128_2_VA128, VX128_2_VB128, VX128_2_VC); return InstrEmit_vperm_(f, VX128_2_VD128, VX128_2_VA128, VX128_2_VB128,
VX128_2_VC);
} }
XEEMITTER(vpermwi128, VX128_P(6, 528), VX128_P)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vpermwi128, VX128_P(6, 528), VX128_P)(PPCHIRBuilder& f,
InstrData& i) {
// (VD.x) = (VB.uimm[6-7]) // (VD.x) = (VB.uimm[6-7])
// (VD.y) = (VB.uimm[4-5]) // (VD.y) = (VB.uimm[4-5])
// (VD.z) = (VB.uimm[2-3]) // (VD.z) = (VB.uimm[2-3])
@ -1218,7 +1200,8 @@ XEEMITTER(vrlw128, VX128(6, 80), VX128 )(PPCHIRBuilder& f, InstrData
return 1; return 1;
} }
XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f,
InstrData& i) {
const uint32_t vd = i.VX128_4.VD128l | (i.VX128_4.VD128h << 5); const uint32_t vd = i.VX128_4.VD128l | (i.VX128_4.VD128h << 5);
const uint32_t vb = i.VX128_4.VB128l | (i.VX128_4.VB128h << 5); const uint32_t vb = i.VX128_4.VB128l | (i.VX128_4.VB128h << 5);
uint32_t blend_mask_src = i.VX128_4.IMM; uint32_t blend_mask_src = i.VX128_4.IMM;
@ -1249,15 +1232,16 @@ XEEMITTER(vrlimi128, VX128_4(6, 1808), VX128_4)(PPCHIRBuilder& f, InstrData
// X Y Z W -> W X Y Z // X Y Z W -> W X Y Z
swizzle_mask = SWIZZLE_XYZW_TO_WXYZ; swizzle_mask = SWIZZLE_XYZW_TO_WXYZ;
break; break;
default: XEASSERTALWAYS(); return 1; default:
XEASSERTALWAYS();
return 1;
} }
v = f.Swizzle(f.LoadVR(vb), FLOAT32_TYPE, swizzle_mask); v = f.Swizzle(f.LoadVR(vb), FLOAT32_TYPE, swizzle_mask);
} else { } else {
v = f.LoadVR(vb); v = f.LoadVR(vb);
} }
if (blend_mask != 0x00010203) { if (blend_mask != 0x00010203) {
v = f.Permute( v = f.Permute(f.LoadConstant(blend_mask), v, f.LoadVR(vd), INT32_TYPE);
f.LoadConstant(blend_mask), v, f.LoadVR(vd), INT32_TYPE);
} }
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
@ -1275,11 +1259,13 @@ int InstrEmit_vrsqrtefp_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb) {
XEEMITTER(vrsqrtefp, 0x1000014A, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vrsqrtefp, 0x1000014A, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vrsqrtefp_(f, i.VX.VD, i.VX.VB); return InstrEmit_vrsqrtefp_(f, i.VX.VD, i.VX.VB);
} }
XEEMITTER(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vrsqrtefp128, VX128_3(6, 1648), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vrsqrtefp_(f, VX128_3_VD128, VX128_3_VB128); return InstrEmit_vrsqrtefp_(f, VX128_3_VD128, VX128_3_VB128);
} }
int InstrEmit_vsel_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t vc) { int InstrEmit_vsel_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb,
uint32_t vc) {
Value* a = f.LoadVR(va); Value* a = f.LoadVR(va);
Value* v = f.Xor(f.And(f.Xor(a, f.LoadVR(vb)), f.LoadVR(vc)), a); Value* v = f.Xor(f.And(f.Xor(a, f.LoadVR(vb)), f.LoadVR(vc)), a);
f.StoreVR(vd, v); f.StoreVR(vd, v);
@ -1342,7 +1328,8 @@ static uint8_t __vsldoi_table[16][16] = {
{14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, {14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
{15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}, {15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
}; };
int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, uint32_t sh) { int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb,
uint32_t sh) {
// (VD) <- ((VA) || (VB)) << (SH << 3) // (VD) <- ((VA) || (VB)) << (SH << 3)
if (!sh) { if (!sh) {
f.StoreVR(vd, f.LoadVR(va)); f.StoreVR(vd, f.LoadVR(va));
@ -1358,10 +1345,7 @@ int InstrEmit_vsldoi_(PPCHIRBuilder& f, uint32_t vd, uint32_t va, uint32_t vb, u
vec128_t shift = *((vec128_t*)(__vsldoi_table[sh])); vec128_t shift = *((vec128_t*)(__vsldoi_table[sh]));
for (int i = 0; i < 4; ++i) shift.i4[i] = XESWAP32BE(shift.i4[i]); for (int i = 0; i < 4; ++i) shift.i4[i] = XESWAP32BE(shift.i4[i]);
Value* control = f.LoadConstant(shift); Value* control = f.LoadConstant(shift);
Value* v = f.Permute( Value* v = f.Permute(control, f.LoadVR(va), f.LoadVR(vb), INT8_TYPE);
control,
f.LoadVR(va),
f.LoadVR(vb), INT8_TYPE);
f.StoreVR(vd, v); f.StoreVR(vd, v);
return 0; return 0;
} }
@ -1369,7 +1353,8 @@ XEEMITTER(vsldoi, 0x1000002C, VXA )(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vsldoi_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC & 0xF); return InstrEmit_vsldoi_(f, i.VXA.VD, i.VXA.VA, i.VXA.VB, i.VXA.VC & 0xF);
} }
XEEMITTER(vsldoi128, VX128_5(4, 16), VX128_5)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vsldoi128, VX128_5(4, 16), VX128_5)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vsldoi_(f, VX128_5_VD128, VX128_5_VA128, VX128_5_VB128, VX128_5_SH); return InstrEmit_vsldoi_(f, VX128_5_VD128, VX128_5_VA128, VX128_5_VB128,
VX128_5_SH);
} }
XEEMITTER(vslo, 0x1000040C, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vslo, 0x1000040C, VX)(PPCHIRBuilder& f, InstrData& i) {
@ -1399,7 +1384,8 @@ XEEMITTER(vsplth, 0x1000024C, VX )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
int InstrEmit_vspltw_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm) { int InstrEmit_vspltw_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb,
uint32_t uimm) {
// (VD.xyzw) <- (VB.uimm) // (VD.xyzw) <- (VB.uimm)
Value* w = f.Extract(f.LoadVR(vb), (uimm & 0x3), INT32_TYPE); Value* w = f.Extract(f.LoadVR(vb), (uimm & 0x3), INT32_TYPE);
Value* v = f.Splat(w, VEC128_TYPE); Value* v = f.Splat(w, VEC128_TYPE);
@ -1409,7 +1395,8 @@ int InstrEmit_vspltw_(PPCHIRBuilder& f, uint32_t vd, uint32_t vb, uint32_t uimm)
XEEMITTER(vspltw, 0x1000028C, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vspltw, 0x1000028C, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vspltw_(f, i.VX.VD, i.VX.VB, i.VX.VA); return InstrEmit_vspltw_(f, i.VX.VD, i.VX.VB, i.VX.VA);
} }
XEEMITTER(vspltw128, VX128_3(6, 1840), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vspltw128, VX128_3(6, 1840), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vspltw_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM); return InstrEmit_vspltw_(f, VX128_3_VD128, VX128_3_VB128, VX128_3_IMM);
} }
@ -1460,7 +1447,8 @@ int InstrEmit_vspltisw_(PPCHIRBuilder& f, uint32_t vd, uint32_t uimm) {
XEEMITTER(vspltisw, 0x1000038C, VX)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vspltisw, 0x1000038C, VX)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_vspltisw_(f, i.VX.VD, i.VX.VA); return InstrEmit_vspltisw_(f, i.VX.VD, i.VX.VA);
} }
XEEMITTER(vspltisw128, VX128_3(6, 1904), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vspltisw128, VX128_3(6, 1904), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
return InstrEmit_vspltisw_(f, VX128_3_VD128, VX128_3_IMM); return InstrEmit_vspltisw_(f, VX128_3_VD128, VX128_3_IMM);
} }
@ -1774,7 +1762,8 @@ XEEMITTER(vupklsb128, VX128(6, 960), VX128 )(PPCHIRBuilder& f, InstrData
return InstrEmit_vupklsb_(f, VX128_VD128, VX128_VB128); return InstrEmit_vupklsb_(f, VX128_VD128, VX128_VB128);
} }
XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f,
InstrData& i) {
const uint32_t vd = i.VX128_4.VD128l | (i.VX128_4.VD128h << 5); const uint32_t vd = i.VX128_4.VD128l | (i.VX128_4.VD128h << 5);
const uint32_t vb = i.VX128_4.VB128l | (i.VX128_4.VB128h << 5); const uint32_t vb = i.VX128_4.VB128l | (i.VX128_4.VB128h << 5);
uint32_t type = i.VX128_4.IMM >> 2; uint32_t type = i.VX128_4.IMM >> 2;
@ -1838,7 +1827,8 @@ XEEMITTER(vpkd3d128, VX128_4(6, 1552), VX128_4)(PPCHIRBuilder& f, InstrData
return 0; return 0;
} }
XEEMITTER(vupkd3d128, VX128_3(6, 2032), VX128_3)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(vupkd3d128, VX128_3(6, 2032), VX128_3)(PPCHIRBuilder& f,
InstrData& i) {
// Can't find many docs on this. Best reference is // Can't find many docs on this. Best reference is
// http://worldcraft.googlecode.com/svn/trunk/src/qylib/math/xmmatrix.inl, // http://worldcraft.googlecode.com/svn/trunk/src/qylib/math/xmmatrix.inl,
// which shows how it's used in some cases. Since it's all intrinsics, // which shows how it's used in some cases. Since it's all intrinsics,
@ -1887,7 +1877,6 @@ XEEMITTER(vxor128, VX128(5, 784), VX128 )(PPCHIRBuilder& f, InstrData
return InstrEmit_vxor_(f, VX128_VD128, VX128_VA128, VX128_VB128); return InstrEmit_vxor_(f, VX128_VD128, VX128_VA128, VX128_VB128);
} }
void RegisterEmitCategoryAltivec() { void RegisterEmitCategoryAltivec() {
XEREGISTERINSTR(dst, 0x7C0002AC); XEREGISTERINSTR(dst, 0x7C0002AC);
XEREGISTERINSTR(dstst, 0x7C0002EC); XEREGISTERINSTR(dstst, 0x7C0002EC);
@ -2134,7 +2123,6 @@ void RegisterEmitCategoryAltivec() {
XEREGISTERINSTR(vxor128, VX128(5, 784)); XEREGISTERINSTR(vxor128, VX128(5, 784));
} }
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy

View File

@ -12,24 +12,20 @@
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_hir_builder.h> #include <alloy/frontend/ppc/ppc_hir_builder.h>
using namespace alloy::frontend::ppc;
using namespace alloy::hir;
using namespace alloy::runtime;
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using alloy::hir::Value;
// Integer arithmetic (A-3) // Integer arithmetic (A-3)
XEEMITTER(addx, 0x7C000214, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(addx, 0x7C000214, XO)(PPCHIRBuilder& f, InstrData& i) {
// RD <- (RA) + (RB) // RD <- (RA) + (RB)
Value* v = f.Add( Value* v = f.Add(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB));
f.LoadGPR(i.XO.RA),
f.LoadGPR(i.XO.RB));
f.StoreGPR(i.XO.RT, v); f.StoreGPR(i.XO.RT, v);
if (i.XO.OE) { if (i.XO.OE) {
XEASSERTALWAYS(); XEASSERTALWAYS();
@ -44,10 +40,8 @@ XEEMITTER(addx, 0x7C000214, XO )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(addcx, 0x7C000014, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(addcx, 0x7C000014, XO)(PPCHIRBuilder& f, InstrData& i) {
// RD <- (RA) + (RB) // RD <- (RA) + (RB)
// CA <- carry bit // CA <- carry bit
Value* v = f.Add( Value* v =
f.LoadGPR(i.XO.RA), f.Add(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB), ARITHMETIC_SET_CARRY);
f.LoadGPR(i.XO.RB),
ARITHMETIC_SET_CARRY);
f.StoreCA(f.DidCarry(v)); f.StoreCA(f.DidCarry(v));
f.StoreGPR(i.XO.RT, v); f.StoreGPR(i.XO.RT, v);
if (i.XO.OE) { if (i.XO.OE) {
@ -62,10 +56,7 @@ XEEMITTER(addcx, 0x7C000014, XO )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(addex, 0x7C000114, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(addex, 0x7C000114, XO)(PPCHIRBuilder& f, InstrData& i) {
// RD <- (RA) + (RB) + XER[CA] // RD <- (RA) + (RB) + XER[CA]
Value* v = f.AddWithCarry( Value* v = f.AddWithCarry(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB), f.LoadCA(),
f.LoadGPR(i.XO.RA),
f.LoadGPR(i.XO.RB),
f.LoadCA(),
ARITHMETIC_SET_CARRY); ARITHMETIC_SET_CARRY);
f.StoreCA(f.DidCarry(v)); f.StoreCA(f.DidCarry(v));
f.StoreGPR(i.XO.RT, v); f.StoreGPR(i.XO.RT, v);
@ -95,9 +86,7 @@ XEEMITTER(addi, 0x38000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(addic, 0x30000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(addic, 0x30000000, D)(PPCHIRBuilder& f, InstrData& i) {
// RT <- (RA) + EXTS(SI) // RT <- (RA) + EXTS(SI)
Value* v = f.Add( Value* v = f.Add(f.LoadGPR(i.D.RA), f.LoadConstant(XEEXTS16(i.D.DS)),
f.LoadGPR(i.D.RA),
f.LoadConstant(XEEXTS16(i.D.DS)),
ARITHMETIC_SET_CARRY); ARITHMETIC_SET_CARRY);
f.StoreCA(f.DidCarry(v)); f.StoreCA(f.DidCarry(v));
f.StoreGPR(i.D.RT, v); f.StoreGPR(i.D.RT, v);
@ -106,9 +95,7 @@ XEEMITTER(addic, 0x30000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(addicx, 0x34000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(addicx, 0x34000000, D)(PPCHIRBuilder& f, InstrData& i) {
// RT <- (RA) + EXTS(SI) // RT <- (RA) + EXTS(SI)
Value* v = f.Add( Value* v = f.Add(f.LoadGPR(i.D.RA), f.LoadConstant(XEEXTS16(i.D.DS)),
f.LoadGPR(i.D.RA),
f.LoadConstant(XEEXTS16(i.D.DS)),
ARITHMETIC_SET_CARRY); ARITHMETIC_SET_CARRY);
f.StoreCA(f.DidCarry(v)); f.StoreCA(f.DidCarry(v));
f.StoreGPR(i.D.RT, v); f.StoreGPR(i.D.RT, v);
@ -132,11 +119,8 @@ XEEMITTER(addis, 0x3C000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(addmex, 0x7C0001D4, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(addmex, 0x7C0001D4, XO)(PPCHIRBuilder& f, InstrData& i) {
// RT <- (RA) + CA - 1 // RT <- (RA) + CA - 1
Value* v = f.AddWithCarry( Value* v = f.AddWithCarry(f.LoadGPR(i.XO.RA), f.LoadConstant((int64_t)-1),
f.LoadGPR(i.XO.RA), f.LoadCA(), ARITHMETIC_SET_CARRY);
f.LoadConstant((int64_t)-1),
f.LoadCA(),
ARITHMETIC_SET_CARRY);
if (i.XO.OE) { if (i.XO.OE) {
// With XER[SO] update too. // With XER[SO] update too.
// e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1));
@ -154,11 +138,8 @@ XEEMITTER(addmex, 0x7C0001D4, XO )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(addzex, 0x7C000194, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(addzex, 0x7C000194, XO)(PPCHIRBuilder& f, InstrData& i) {
// RT <- (RA) + CA // RT <- (RA) + CA
Value* v = f.AddWithCarry( Value* v = f.AddWithCarry(f.LoadGPR(i.XO.RA), f.LoadZero(INT64_TYPE),
f.LoadGPR(i.XO.RA), f.LoadCA(), ARITHMETIC_SET_CARRY);
f.LoadZero(INT64_TYPE),
f.LoadCA(),
ARITHMETIC_SET_CARRY);
if (i.XO.OE) { if (i.XO.OE) {
// With XER[SO] update too. // With XER[SO] update too.
// e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1));
@ -305,8 +286,8 @@ XEEMITTER(mulhdux, 0x7C000012, XO )(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED(); XEINSTRNOTIMPLEMENTED();
return 1; return 1;
} }
Value* v = f.MulHi( Value* v =
f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB), ARITHMETIC_UNSIGNED); f.MulHi(f.LoadGPR(i.XO.RA), f.LoadGPR(i.XO.RB), ARITHMETIC_UNSIGNED);
f.StoreGPR(i.XO.RT, v); f.StoreGPR(i.XO.RT, v);
if (i.XO.Rc) { if (i.XO.Rc) {
f.UpdateCR(0, v); f.UpdateCR(0, v);
@ -321,9 +302,9 @@ XEEMITTER(mulhwx, 0x7C000096, XO )(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED(); XEINSTRNOTIMPLEMENTED();
return 1; return 1;
} }
Value* v = f.SignExtend(f.MulHi( Value* v = f.SignExtend(f.MulHi(f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE),
f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE), f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE)),
f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE)), INT64_TYPE); INT64_TYPE);
f.StoreGPR(i.XO.RT, v); f.StoreGPR(i.XO.RT, v);
if (i.XO.Rc) { if (i.XO.Rc) {
f.UpdateCR(0, v); f.UpdateCR(0, v);
@ -338,10 +319,10 @@ XEEMITTER(mulhwux, 0x7C000016, XO )(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED(); XEINSTRNOTIMPLEMENTED();
return 1; return 1;
} }
Value* v = f.ZeroExtend(f.MulHi( Value* v = f.ZeroExtend(
f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE), f.MulHi(f.Truncate(f.LoadGPR(i.XO.RA), INT32_TYPE),
f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE), f.Truncate(f.LoadGPR(i.XO.RB), INT32_TYPE), ARITHMETIC_UNSIGNED),
ARITHMETIC_UNSIGNED), INT64_TYPE); INT64_TYPE);
f.StoreGPR(i.XO.RT, v); f.StoreGPR(i.XO.RT, v);
if (i.XO.Rc) { if (i.XO.Rc) {
f.UpdateCR(0, v, false); f.UpdateCR(0, v, false);
@ -438,10 +419,8 @@ XEEMITTER(subfx, 0x7C000050, XO )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(subfcx, 0x7C000010, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(subfcx, 0x7C000010, XO)(PPCHIRBuilder& f, InstrData& i) {
// RT <- ¬(RA) + (RB) + 1 // RT <- ¬(RA) + (RB) + 1
Value* v = f.Sub( Value* v =
f.LoadGPR(i.XO.RB), f.Sub(f.LoadGPR(i.XO.RB), f.LoadGPR(i.XO.RA), ARITHMETIC_SET_CARRY);
f.LoadGPR(i.XO.RA),
ARITHMETIC_SET_CARRY);
f.StoreCA(f.DidCarry(v)); f.StoreCA(f.DidCarry(v));
f.StoreGPR(i.XO.RT, v); f.StoreGPR(i.XO.RT, v);
if (i.XO.OE) { if (i.XO.OE) {
@ -456,9 +435,7 @@ XEEMITTER(subfcx, 0x7C000010, XO )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(subficx, 0x20000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(subficx, 0x20000000, D)(PPCHIRBuilder& f, InstrData& i) {
// RT <- ¬(RA) + EXTS(SI) + 1 // RT <- ¬(RA) + EXTS(SI) + 1
Value* v = f.Sub( Value* v = f.Sub(f.LoadConstant(XEEXTS16(i.D.DS)), f.LoadGPR(i.D.RA),
f.LoadConstant(XEEXTS16(i.D.DS)),
f.LoadGPR(i.D.RA),
ARITHMETIC_SET_CARRY); ARITHMETIC_SET_CARRY);
f.StoreCA(f.DidCarry(v)); f.StoreCA(f.DidCarry(v));
f.StoreGPR(i.D.RT, v); f.StoreGPR(i.D.RT, v);
@ -467,11 +444,8 @@ XEEMITTER(subficx, 0x20000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(subfex, 0x7C000110, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(subfex, 0x7C000110, XO)(PPCHIRBuilder& f, InstrData& i) {
// RT <- ¬(RA) + (RB) + CA // RT <- ¬(RA) + (RB) + CA
Value* v = f.AddWithCarry( Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)), f.LoadGPR(i.XO.RB),
f.Not(f.LoadGPR(i.XO.RA)), f.LoadCA(), ARITHMETIC_SET_CARRY);
f.LoadGPR(i.XO.RB),
f.LoadCA(),
ARITHMETIC_SET_CARRY);
f.StoreCA(f.DidCarry(v)); f.StoreCA(f.DidCarry(v));
f.StoreGPR(i.XO.RT, v); f.StoreGPR(i.XO.RT, v);
if (i.XO.OE) { if (i.XO.OE) {
@ -486,10 +460,8 @@ XEEMITTER(subfex, 0x7C000110, XO )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(subfmex, 0x7C0001D0, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(subfmex, 0x7C0001D0, XO)(PPCHIRBuilder& f, InstrData& i) {
// RT <- ¬(RA) + CA - 1 // RT <- ¬(RA) + CA - 1
Value* v = f.AddWithCarry( Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)),
f.Not(f.LoadGPR(i.XO.RA)), f.LoadConstant((int64_t)-1), f.LoadCA());
f.LoadConstant((int64_t)-1),
f.LoadCA());
if (i.XO.OE) { if (i.XO.OE) {
XEASSERTALWAYS(); XEASSERTALWAYS();
// e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1)); // e.update_xer_with_overflow_and_carry(b.CreateExtractValue(v, 1));
@ -505,9 +477,7 @@ XEEMITTER(subfmex, 0x7C0001D0, XO )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(subfzex, 0x7C000190, XO)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(subfzex, 0x7C000190, XO)(PPCHIRBuilder& f, InstrData& i) {
// RT <- ¬(RA) + CA // RT <- ¬(RA) + CA
Value* v = f.AddWithCarry( Value* v = f.AddWithCarry(f.Not(f.LoadGPR(i.XO.RA)), f.LoadZero(INT64_TYPE),
f.Not(f.LoadGPR(i.XO.RA)),
f.LoadZero(INT64_TYPE),
f.LoadCA()); f.LoadCA());
if (i.XO.OE) { if (i.XO.OE) {
XEASSERTALWAYS(); XEASSERTALWAYS();
@ -522,7 +492,6 @@ XEEMITTER(subfzex, 0x7C000190, XO )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Integer compare (A-4) // Integer compare (A-4)
XEEMITTER(cmp, 0x7C000000, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(cmp, 0x7C000000, X)(PPCHIRBuilder& f, InstrData& i) {
@ -637,7 +606,6 @@ XEEMITTER(cmpli, 0x28000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Integer logical (A-5) // Integer logical (A-5)
XEEMITTER(andx, 0x7C000038, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(andx, 0x7C000038, X)(PPCHIRBuilder& f, InstrData& i) {
@ -662,9 +630,7 @@ XEEMITTER(andcx, 0x7C000078, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(andix, 0x70000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(andix, 0x70000000, D)(PPCHIRBuilder& f, InstrData& i) {
// RA <- (RS) & (i48.0 || UI) // RA <- (RS) & (i48.0 || UI)
Value* ra = f.And( Value* ra = f.And(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t)i.D.DS));
f.LoadGPR(i.D.RT),
f.LoadConstant((uint64_t)i.D.DS));
f.StoreGPR(i.D.RA, ra); f.StoreGPR(i.D.RA, ra);
f.UpdateCR(0, ra); f.UpdateCR(0, ra);
return 0; return 0;
@ -672,9 +638,8 @@ XEEMITTER(andix, 0x70000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(andisx, 0x74000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(andisx, 0x74000000, D)(PPCHIRBuilder& f, InstrData& i) {
// RA <- (RS) & (i32.0 || UI || i16.0) // RA <- (RS) & (i32.0 || UI || i16.0)
Value* ra = f.And( Value* ra =
f.LoadGPR(i.D.RT), f.And(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t(i.D.DS) << 16)));
f.LoadConstant((uint64_t(i.D.DS) << 16)));
f.StoreGPR(i.D.RA, ra); f.StoreGPR(i.D.RA, ra);
f.UpdateCR(0, ra); f.UpdateCR(0, ra);
return 0; return 0;
@ -701,8 +666,7 @@ XEEMITTER(cntlzwx, 0x7C000034, X )(PPCHIRBuilder& f, InstrData& i) {
// if (RS)[n] = 1 then leave n // if (RS)[n] = 1 then leave n
// n <- n + 1 // n <- n + 1
// RA <- n - 32 // RA <- n - 32
Value* v = f.CountLeadingZeros( Value* v = f.CountLeadingZeros(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE));
f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE));
v = f.ZeroExtend(v, INT64_TYPE); v = f.ZeroExtend(v, INT64_TYPE);
f.StoreGPR(i.X.RA, v); f.StoreGPR(i.X.RA, v);
if (i.X.Rc) { if (i.X.Rc) {
@ -763,9 +727,7 @@ XEEMITTER(extswx, 0x7C0007B4, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(nandx, 0x7C0003B8, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(nandx, 0x7C0003B8, X)(PPCHIRBuilder& f, InstrData& i) {
// RA <- ¬((RS) & (RB)) // RA <- ¬((RS) & (RB))
Value* ra = f.And( Value* ra = f.And(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB));
f.LoadGPR(i.X.RT),
f.LoadGPR(i.X.RB));
ra = f.Not(ra); ra = f.Not(ra);
f.StoreGPR(i.X.RA, ra); f.StoreGPR(i.X.RA, ra);
if (i.X.Rc) { if (i.X.Rc) {
@ -776,9 +738,7 @@ XEEMITTER(nandx, 0x7C0003B8, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(norx, 0x7C0000F8, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(norx, 0x7C0000F8, X)(PPCHIRBuilder& f, InstrData& i) {
// RA <- ¬((RS) | (RB)) // RA <- ¬((RS) | (RB))
Value* ra = f.Or( Value* ra = f.Or(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB));
f.LoadGPR(i.X.RT),
f.LoadGPR(i.X.RB));
ra = f.Not(ra); ra = f.Not(ra);
f.StoreGPR(i.X.RA, ra); f.StoreGPR(i.X.RA, ra);
if (i.X.Rc) { if (i.X.Rc) {
@ -789,8 +749,7 @@ XEEMITTER(norx, 0x7C0000F8, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(orx, 0x7C000378, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(orx, 0x7C000378, X)(PPCHIRBuilder& f, InstrData& i) {
// RA <- (RS) | (RB) // RA <- (RS) | (RB)
if (i.X.RT == i.X.RB && i.X.RT == i.X.RA && if (i.X.RT == i.X.RB && i.X.RT == i.X.RA && !i.X.Rc) {
!i.X.Rc) {
// Sometimes used as no-op. // Sometimes used as no-op.
f.Nop(); f.Nop();
return 0; return 0;
@ -799,9 +758,7 @@ XEEMITTER(orx, 0x7C000378, X )(PPCHIRBuilder& f, InstrData& i) {
if (i.X.RT == i.X.RB) { if (i.X.RT == i.X.RB) {
ra = f.LoadGPR(i.X.RT); ra = f.LoadGPR(i.X.RT);
} else { } else {
ra = f.Or( ra = f.Or(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB));
f.LoadGPR(i.X.RT),
f.LoadGPR(i.X.RB));
} }
f.StoreGPR(i.X.RA, ra); f.StoreGPR(i.X.RA, ra);
if (i.X.Rc) { if (i.X.Rc) {
@ -812,9 +769,7 @@ XEEMITTER(orx, 0x7C000378, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(orcx, 0x7C000338, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(orcx, 0x7C000338, X)(PPCHIRBuilder& f, InstrData& i) {
// RA <- (RS) | ¬(RB) // RA <- (RS) | ¬(RB)
Value* ra = f.Or( Value* ra = f.Or(f.LoadGPR(i.X.RT), f.Not(f.LoadGPR(i.X.RB)));
f.LoadGPR(i.X.RT),
f.Not(f.LoadGPR(i.X.RB)));
f.StoreGPR(i.X.RA, ra); f.StoreGPR(i.X.RA, ra);
if (i.X.Rc) { if (i.X.Rc) {
f.UpdateCR(0, ra); f.UpdateCR(0, ra);
@ -828,27 +783,21 @@ XEEMITTER(ori, 0x60000000, D )(PPCHIRBuilder& f, InstrData& i) {
f.Nop(); f.Nop();
return 0; return 0;
} }
Value* ra = f.Or( Value* ra = f.Or(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t)i.D.DS));
f.LoadGPR(i.D.RT),
f.LoadConstant((uint64_t)i.D.DS));
f.StoreGPR(i.D.RA, ra); f.StoreGPR(i.D.RA, ra);
return 0; return 0;
} }
XEEMITTER(oris, 0x64000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(oris, 0x64000000, D)(PPCHIRBuilder& f, InstrData& i) {
// RA <- (RS) | (i32.0 || UI || i16.0) // RA <- (RS) | (i32.0 || UI || i16.0)
Value* ra = f.Or( Value* ra = f.Or(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t(i.D.DS) << 16)));
f.LoadGPR(i.D.RT),
f.LoadConstant((uint64_t(i.D.DS) << 16)));
f.StoreGPR(i.D.RA, ra); f.StoreGPR(i.D.RA, ra);
return 0; return 0;
} }
XEEMITTER(xorx, 0x7C000278, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(xorx, 0x7C000278, X)(PPCHIRBuilder& f, InstrData& i) {
// RA <- (RS) XOR (RB) // RA <- (RS) XOR (RB)
Value* ra = f.Xor( Value* ra = f.Xor(f.LoadGPR(i.X.RT), f.LoadGPR(i.X.RB));
f.LoadGPR(i.X.RT),
f.LoadGPR(i.X.RB));
f.StoreGPR(i.X.RA, ra); f.StoreGPR(i.X.RA, ra);
if (i.X.Rc) { if (i.X.Rc) {
f.UpdateCR(0, ra); f.UpdateCR(0, ra);
@ -858,23 +807,19 @@ XEEMITTER(xorx, 0x7C000278, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(xori, 0x68000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(xori, 0x68000000, D)(PPCHIRBuilder& f, InstrData& i) {
// RA <- (RS) XOR (i48.0 || UI) // RA <- (RS) XOR (i48.0 || UI)
Value* ra = f.Xor( Value* ra = f.Xor(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t)i.D.DS));
f.LoadGPR(i.D.RT),
f.LoadConstant((uint64_t)i.D.DS));
f.StoreGPR(i.D.RA, ra); f.StoreGPR(i.D.RA, ra);
return 0; return 0;
} }
XEEMITTER(xoris, 0x6C000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(xoris, 0x6C000000, D)(PPCHIRBuilder& f, InstrData& i) {
// RA <- (RS) XOR (i32.0 || UI || i16.0) // RA <- (RS) XOR (i32.0 || UI || i16.0)
Value* ra = f.Xor( Value* ra =
f.LoadGPR(i.D.RT), f.Xor(f.LoadGPR(i.D.RT), f.LoadConstant((uint64_t(i.D.DS) << 16)));
f.LoadConstant((uint64_t(i.D.DS) << 16)));
f.StoreGPR(i.D.RA, ra); f.StoreGPR(i.D.RA, ra);
return 0; return 0;
} }
// Integer rotate (A-6) // Integer rotate (A-6)
XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) {
@ -955,9 +900,7 @@ XEEMITTER(rld, 0x78000000, MDS)(PPCHIRBuilder& f, InstrData& i) {
} }
if (m != 0xFFFFFFFFFFFFFFFF) { if (m != 0xFFFFFFFFFFFFFFFF) {
Value* ra = f.LoadGPR(i.MD.RA); Value* ra = f.LoadGPR(i.MD.RA);
v = f.Or( v = f.Or(f.And(v, f.LoadConstant(m)), f.And(ra, f.LoadConstant(~m)));
f.And(v, f.LoadConstant(m)),
f.And(ra, f.LoadConstant(~m)));
} }
f.StoreGPR(i.MD.RA, v); f.StoreGPR(i.MD.RA, v);
if (i.MD.Rc) { if (i.MD.Rc) {
@ -1027,8 +970,8 @@ XEEMITTER(rlwnmx, 0x5C000000, M )(PPCHIRBuilder& f, InstrData& i) {
// m <- MASK(MB+32, ME+32) // m <- MASK(MB+32, ME+32)
// RA <- r & m // RA <- r & m
Value* v = f.Truncate(f.LoadGPR(i.M.RT), INT32_TYPE); Value* v = f.Truncate(f.LoadGPR(i.M.RT), INT32_TYPE);
Value* sh = f.And(f.Truncate(f.LoadGPR(i.M.SH), INT32_TYPE), Value* sh =
f.LoadConstant(0x1F)); f.And(f.Truncate(f.LoadGPR(i.M.SH), INT32_TYPE), f.LoadConstant(0x1F));
v = f.RotateLeft(v, sh); v = f.RotateLeft(v, sh);
// Compiler sometimes masks with 0xFFFFFFFF (identity) - avoid the work here // Compiler sometimes masks with 0xFFFFFFFF (identity) - avoid the work here
// as our truncation/zero-extend does it for us. // as our truncation/zero-extend does it for us.
@ -1043,7 +986,6 @@ XEEMITTER(rlwnmx, 0x5C000000, M )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Integer shift (A-7) // Integer shift (A-7)
XEEMITTER(sldx, 0x7C000036, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(sldx, 0x7C000036, X)(PPCHIRBuilder& f, InstrData& i) {
@ -1070,8 +1012,8 @@ XEEMITTER(slwx, 0x7C000030, X )(PPCHIRBuilder& f, InstrData& i) {
// else // else
// m <- i64.0 // m <- i64.0
// RA <- r & m // RA <- r & m
Value* v = f.Shl(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE), Value* v =
f.LoadGPR(i.X.RB)); f.Shl(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE), f.LoadGPR(i.X.RB));
v = f.ZeroExtend(v, INT64_TYPE); v = f.ZeroExtend(v, INT64_TYPE);
f.StoreGPR(i.X.RA, v); f.StoreGPR(i.X.RA, v);
if (i.X.Rc) { if (i.X.Rc) {
@ -1106,8 +1048,8 @@ XEEMITTER(srwx, 0x7C000430, X )(PPCHIRBuilder& f, InstrData& i) {
// m <- i64.0 // m <- i64.0
// RA <- r & m // RA <- r & m
// TODO(benvanik): if >1F, zero out the result. // TODO(benvanik): if >1F, zero out the result.
Value* v = f.Shr(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE), Value* v =
f.LoadGPR(i.X.RB)); f.Shr(f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE), f.LoadGPR(i.X.RB));
v = f.ZeroExtend(v, INT64_TYPE); v = f.ZeroExtend(v, INT64_TYPE);
f.StoreGPR(i.X.RA, v); f.StoreGPR(i.X.RA, v);
if (i.X.Rc) { if (i.X.Rc) {
@ -1136,8 +1078,7 @@ XEEMITTER(sradx, 0x7C000634, X )(PPCHIRBuilder& f, InstrData& i) {
// is negative. Start tracking that here. // is negative. Start tracking that here.
// TODO(benvanik): dynamically generate mask better than this. // TODO(benvanik): dynamically generate mask better than this.
Value* ca_sh = f.Sub(f.LoadConstant((int8_t)63), sh); Value* ca_sh = f.Sub(f.LoadConstant((int8_t)63), sh);
Value* ca = Value* ca = f.Shr(f.Shl(f.LoadConstant(0xFFFFFFFFFFFFFFFFull), ca_sh), ca_sh);
f.Shr(f.Shl(f.LoadConstant(0xFFFFFFFFFFFFFFFFull), ca_sh), ca_sh);
ca = f.CompareNE(f.And(ca, v), f.LoadZero(INT64_TYPE)); ca = f.CompareNE(f.And(ca, v), f.LoadZero(INT64_TYPE));
// Shift right. // Shift right.
@ -1173,8 +1114,7 @@ XEEMITTER(sradix, 0x7C000674, XS )(PPCHIRBuilder& f, InstrData& i) {
// is negative. // is negative.
XEASSERT(sh); XEASSERT(sh);
uint64_t mask = XEMASK(64 - sh, 63); uint64_t mask = XEMASK(64 - sh, 63);
Value* ca = f.And( Value* ca = f.And(f.Truncate(f.Shr(v, 63), INT8_TYPE),
f.Truncate(f.Shr(v, 63), INT8_TYPE),
f.IsTrue(f.And(v, f.LoadConstant(mask)))); f.IsTrue(f.And(v, f.LoadConstant(mask))));
f.StoreCA(ca); f.StoreCA(ca);
@ -1196,18 +1136,15 @@ XEEMITTER(srawx, 0x7C000630, X )(PPCHIRBuilder& f, InstrData& i) {
// if n == 0: rA <- sign_extend(rS), XER[CA] = 0 // if n == 0: rA <- sign_extend(rS), XER[CA] = 0
// if n >= 32: rA <- 64 sign bits of rS, XER[CA] = sign bit of lo_32(rS) // if n >= 32: rA <- 64 sign bits of rS, XER[CA] = sign bit of lo_32(rS)
Value* v = f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE); Value* v = f.Truncate(f.LoadGPR(i.X.RT), INT32_TYPE);
Value* sh = f.And( Value* sh =
f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), f.And(f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), f.LoadConstant(0x7F));
f.LoadConstant(0x7F));
// CA is set if any bits are shifted out of the right and if the result // CA is set if any bits are shifted out of the right and if the result
// is negative. // is negative.
Value* mask = f.Not(f.Shl(f.LoadConstant(-1), sh)); Value* mask = f.Not(f.Shl(f.LoadConstant(-1), sh));
Value* ca = f.And( Value* ca =
f.Truncate(f.Shr(v, 31), INT8_TYPE), f.And(f.Truncate(f.Shr(v, 31), INT8_TYPE), f.IsTrue(f.And(v, mask)));
f.IsTrue(f.And(v, mask)));
f.StoreCA(ca); f.StoreCA(ca);
v = f.Sha(v, sh), v = f.Sha(v, sh), v = f.SignExtend(v, INT64_TYPE);
v = f.SignExtend(v, INT64_TYPE);
f.StoreGPR(i.X.RA, v); f.StoreGPR(i.X.RA, v);
if (i.X.Rc) { if (i.X.Rc) {
f.UpdateCR(0, v); f.UpdateCR(0, v);
@ -1234,12 +1171,10 @@ XEEMITTER(srawix, 0x7C000670, X )(PPCHIRBuilder& f, InstrData& i) {
// CA is set if any bits are shifted out of the right and if the result // CA is set if any bits are shifted out of the right and if the result
// is negative. // is negative.
uint32_t mask = (uint32_t)XEMASK(64 - i.X.RB, 63); uint32_t mask = (uint32_t)XEMASK(64 - i.X.RB, 63);
ca = f.And( ca = f.And(f.Truncate(f.Shr(v, 31), INT8_TYPE),
f.Truncate(f.Shr(v, 31), INT8_TYPE),
f.IsTrue(f.And(v, f.LoadConstant(mask)))); f.IsTrue(f.And(v, f.LoadConstant(mask))));
v = f.Sha(v, (int8_t)i.X.RB), v = f.Sha(v, (int8_t)i.X.RB), v = f.SignExtend(v, INT64_TYPE);
v = f.SignExtend(v, INT64_TYPE);
} }
f.StoreCA(ca); f.StoreCA(ca);
f.StoreGPR(i.X.RA, v); f.StoreGPR(i.X.RA, v);
@ -1249,7 +1184,6 @@ XEEMITTER(srawix, 0x7C000670, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
void RegisterEmitCategoryALU() { void RegisterEmitCategoryALU() {
XEREGISTERINSTR(addx, 0x7C000214); XEREGISTERINSTR(addx, 0x7C000214);
XEREGISTERINSTR(addcx, 0X7C000014); XEREGISTERINSTR(addcx, 0X7C000014);
@ -1321,7 +1255,6 @@ void RegisterEmitCategoryALU() {
XEREGISTERINSTR(srawix, 0x7C000670); XEREGISTERINSTR(srawix, 0x7C000670);
} }
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy

View File

@ -12,21 +12,19 @@
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_hir_builder.h> #include <alloy/frontend/ppc/ppc_hir_builder.h>
using namespace alloy::frontend::ppc;
using namespace alloy::hir;
using namespace alloy::runtime;
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
int InstrEmit_branch( using alloy::hir::Label;
PPCHIRBuilder& f, const char* src, uint64_t cia, using alloy::hir::Value;
Value* nia, bool lk, Value* cond = NULL, bool expect_true = true,
bool nia_is_lr = false) { int InstrEmit_branch(PPCHIRBuilder& f, const char* src, uint64_t cia,
Value* nia, bool lk, Value* cond = NULL,
bool expect_true = true, bool nia_is_lr = false) {
uint32_t call_flags = 0; uint32_t call_flags = 0;
// TODO(benvanik): this may be wrong and overwrite LRs when not desired! // TODO(benvanik): this may be wrong and overwrite LRs when not desired!
@ -54,8 +52,7 @@ int InstrEmit_branch(
// recursion. // recursion.
uint64_t nia_value = nia->AsUint64() & 0xFFFFFFFF; uint64_t nia_value = nia->AsUint64() & 0xFFFFFFFF;
bool is_recursion = false; bool is_recursion = false;
if (nia_value == f.symbol_info()->address() && if (nia_value == f.symbol_info()->address() && lk) {
lk) {
is_recursion = true; is_recursion = true;
} }
Label* label = is_recursion ? NULL : f.LookupLabel(nia_value); Label* label = is_recursion ? NULL : f.LookupLabel(nia_value);
@ -73,7 +70,7 @@ int InstrEmit_branch(
} }
} else { } else {
// Call function. // Call function.
FunctionInfo* symbol_info = f.LookupFunction(nia_value); auto symbol_info = f.LookupFunction(nia_value);
if (cond) { if (cond) {
if (!expect_true) { if (!expect_true) {
cond = f.IsFalse(cond); cond = f.IsFalse(cond);
@ -143,7 +140,6 @@ int InstrEmit_branch(
return 0; return 0;
} }
XEEMITTER(bx, 0x48000000, I)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(bx, 0x48000000, I)(PPCHIRBuilder& f, InstrData& i) {
// if AA then // if AA then
// NIA <- EXTS(LI || 0b00) // NIA <- EXTS(LI || 0b00)
@ -159,8 +155,7 @@ XEEMITTER(bx, 0x48000000, I )(PPCHIRBuilder& f, InstrData& i) {
nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2)); nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2));
} }
return InstrEmit_branch( return InstrEmit_branch(f, "bx", i.address, f.LoadConstant(nia), i.I.LK);
f, "bx", i.address, f.LoadConstant(nia), i.I.LK);
} }
XEEMITTER(bcx, 0x40000000, B)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(bcx, 0x40000000, B)(PPCHIRBuilder& f, InstrData& i) {
@ -236,8 +231,8 @@ XEEMITTER(bcx, 0x40000000, B )(PPCHIRBuilder& f, InstrData& i) {
} else { } else {
nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2)); nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2));
} }
return InstrEmit_branch( return InstrEmit_branch(f, "bcx", i.address, f.LoadConstant(nia), i.B.LK, ok,
f, "bcx", i.address, f.LoadConstant(nia), i.B.LK, ok, expect_true); expect_true);
} }
XEEMITTER(bcctrx, 0x4C000420, XL)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(bcctrx, 0x4C000420, XL)(PPCHIRBuilder& f, InstrData& i) {
@ -268,8 +263,8 @@ XEEMITTER(bcctrx, 0x4C000420, XL )(PPCHIRBuilder& f, InstrData& i) {
} }
bool expect_true = !not_cond_ok; bool expect_true = !not_cond_ok;
return InstrEmit_branch( return InstrEmit_branch(f, "bcctrx", i.address, f.LoadCTR(), i.XL.LK, cond_ok,
f, "bcctrx", i.address, f.LoadCTR(), i.XL.LK, cond_ok, expect_true); expect_true);
} }
XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) {
@ -336,11 +331,10 @@ XEEMITTER(bclrx, 0x4C000020, XL )(PPCHIRBuilder& f, InstrData& i) {
expect_true = !not_cond_ok; expect_true = !not_cond_ok;
} }
return InstrEmit_branch( return InstrEmit_branch(f, "bclrx", i.address, f.LoadLR(), i.XL.LK, ok,
f, "bclrx", i.address, f.LoadLR(), i.XL.LK, ok, expect_true, true); expect_true, true);
} }
// Condition register logical (A-23) // Condition register logical (A-23)
XEEMITTER(crand, 0x4C000202, XL)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(crand, 0x4C000202, XL)(PPCHIRBuilder& f, InstrData& i) {
@ -388,7 +382,6 @@ XEEMITTER(mcrf, 0x4C000000, XL )(PPCHIRBuilder& f, InstrData& i) {
return 1; return 1;
} }
// System linkage (A-24) // System linkage (A-24)
XEEMITTER(sc, 0x44000002, SC)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(sc, 0x44000002, SC)(PPCHIRBuilder& f, InstrData& i) {
@ -396,11 +389,10 @@ XEEMITTER(sc, 0x44000002, SC )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Trap (A-25) // Trap (A-25)
int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, Value* va, Value* vb,
Value* va, Value* vb, uint32_t TO) { uint32_t TO) {
// if (a < b) & TO[0] then TRAP // if (a < b) & TO[0] then TRAP
// if (a > b) & TO[1] then TRAP // if (a > b) & TO[1] then TRAP
// if (a = b) & TO[2] then TRAP // if (a = b) & TO[2] then TRAP
@ -468,10 +460,10 @@ XEEMITTER(tw, 0x7C000008, X )(PPCHIRBuilder& f, InstrData& i) {
// if (a = b) & TO[2] then TRAP // if (a = b) & TO[2] then TRAP
// if (a <u b) & TO[3] then TRAP // if (a <u b) & TO[3] then TRAP
// if (a >u b) & TO[4] then TRAP // if (a >u b) & TO[4] then TRAP
Value* ra = f.SignExtend(f.Truncate( Value* ra =
f.LoadGPR(i.X.RA), INT32_TYPE), INT64_TYPE); f.SignExtend(f.Truncate(f.LoadGPR(i.X.RA), INT32_TYPE), INT64_TYPE);
Value* rb = f.SignExtend(f.Truncate( Value* rb =
f.LoadGPR(i.X.RB), INT32_TYPE), INT64_TYPE); f.SignExtend(f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), INT64_TYPE);
return InstrEmit_trap(f, i, ra, rb, i.X.RT); return InstrEmit_trap(f, i, ra, rb, i.X.RT);
} }
@ -488,13 +480,12 @@ XEEMITTER(twi, 0x0C000000, D )(PPCHIRBuilder& f, InstrData& i) {
f.Trap(type); f.Trap(type);
return 0; return 0;
} }
Value* ra = f.SignExtend(f.Truncate( Value* ra =
f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE); f.SignExtend(f.Truncate(f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE);
Value* rb = f.LoadConstant(XEEXTS16(i.D.DS)); Value* rb = f.LoadConstant(XEEXTS16(i.D.DS));
return InstrEmit_trap(f, i, ra, rb, i.D.RT); return InstrEmit_trap(f, i, ra, rb, i.D.RT);
} }
// Processor control (A-26) // Processor control (A-26)
XEEMITTER(mfcr, 0x7C000026, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(mfcr, 0x7C000026, X)(PPCHIRBuilder& f, InstrData& i) {
@ -593,7 +584,6 @@ XEEMITTER(mtmsrd, 0x7C000164, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
void RegisterEmitCategoryControl() { void RegisterEmitCategoryControl() {
XEREGISTERINSTR(bx, 0x48000000); XEREGISTERINSTR(bx, 0x48000000);
XEREGISTERINSTR(bcx, 0x40000000); XEREGISTERINSTR(bcx, 0x40000000);
@ -623,7 +613,6 @@ void RegisterEmitCategoryControl() {
XEREGISTERINSTR(mtmsrd, 0x7C000164); XEREGISTERINSTR(mtmsrd, 0x7C000164);
} }
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy

View File

@ -12,27 +12,24 @@
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_hir_builder.h> #include <alloy/frontend/ppc/ppc_hir_builder.h>
using namespace alloy::frontend::ppc;
using namespace alloy::hir;
using namespace alloy::runtime;
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using alloy::hir::RoundMode;
using alloy::hir::Value;
// Good source of information: // Good source of information:
// http://mamedev.org/source/src/emu/cpu/powerpc/ppc_ops.c // http://mamedev.org/source/src/emu/cpu/powerpc/ppc_ops.c
// The correctness of that code is not reflected here yet -_- // The correctness of that code is not reflected here yet -_-
// Enable rounding numbers to single precision as required. // Enable rounding numbers to single precision as required.
// This adds a bunch of work per operation and I'm not sure it's required. // This adds a bunch of work per operation and I'm not sure it's required.
#define ROUND_TO_SINGLE #define ROUND_TO_SINGLE
// Floating-point arithmetic (A-8) // Floating-point arithmetic (A-8)
XEEMITTER(faddx, 0xFC00002A, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(faddx, 0xFC00002A, A)(PPCHIRBuilder& f, InstrData& i) {
@ -197,15 +194,12 @@ XEEMITTER(fsqrtsx, 0xEC00002C, A )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Floating-point multiply-add (A-9) // Floating-point multiply-add (A-9)
XEEMITTER(fmaddx, 0xFC00003A, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fmaddx, 0xFC00003A, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA x frC) + frB // frD <- (frA x frC) + frB
Value* v = f.MulAdd( Value* v =
f.LoadFPR(i.A.FRA), f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v); f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v); // f.UpdateFPRF(v);
if (i.A.Rc) { if (i.A.Rc) {
@ -218,10 +212,8 @@ XEEMITTER(fmaddx, 0xFC00003A, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmaddsx, 0xEC00003A, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fmaddsx, 0xEC00003A, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA x frC) + frB // frD <- (frA x frC) + frB
Value* v = f.MulAdd( Value* v =
f.LoadFPR(i.A.FRA), f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v); f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v); // f.UpdateFPRF(v);
@ -235,10 +227,8 @@ XEEMITTER(fmaddsx, 0xEC00003A, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmsubx, 0xFC000038, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fmsubx, 0xFC000038, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA x frC) - frB // frD <- (frA x frC) - frB
Value* v = f.MulSub( Value* v =
f.LoadFPR(i.A.FRA), f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v); f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v); // f.UpdateFPRF(v);
if (i.A.Rc) { if (i.A.Rc) {
@ -251,10 +241,8 @@ XEEMITTER(fmsubx, 0xFC000038, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmsubsx, 0xEC000038, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fmsubsx, 0xEC000038, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA x frC) - frB // frD <- (frA x frC) - frB
Value* v = f.MulSub( Value* v =
f.LoadFPR(i.A.FRA), f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v); f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v); // f.UpdateFPRF(v);
@ -278,10 +266,8 @@ XEEMITTER(fnmaddsx, 0xEC00003E, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnmsubx, 0xFC00003C, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fnmsubx, 0xFC00003C, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- -([frA x frC] - frB) // frD <- -([frA x frC] - frB)
Value* v = f.Neg(f.MulSub( Value* v = f.Neg(
f.LoadFPR(i.A.FRA), f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB)));
f.StoreFPR(i.A.FRT, v); f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v); // f.UpdateFPRF(v);
if (i.A.Rc) { if (i.A.Rc) {
@ -294,10 +280,8 @@ XEEMITTER(fnmsubx, 0xFC00003C, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnmsubsx, 0xEC00003C, A)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fnmsubsx, 0xEC00003C, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- -([frA x frC] - frB) // frD <- -([frA x frC] - frB)
Value* v = f.Neg(f.MulSub( Value* v = f.Neg(
f.LoadFPR(i.A.FRA), f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB)));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE); v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v); f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v); // f.UpdateFPRF(v);
@ -309,14 +293,11 @@ XEEMITTER(fnmsubsx, 0xEC00003C, A )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Floating-point rounding and conversion (A-10) // Floating-point rounding and conversion (A-10)
XEEMITTER(fcfidx, 0xFC00069C, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fcfidx, 0xFC00069C, X)(PPCHIRBuilder& f, InstrData& i) {
// frD <- signed_int64_to_double( frB ) // frD <- signed_int64_to_double( frB )
Value* v = f.Convert( Value* v = f.Convert(f.Cast(f.LoadFPR(i.A.FRB), INT64_TYPE), FLOAT64_TYPE);
f.Cast(f.LoadFPR(i.A.FRB), INT64_TYPE),
FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v); f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v); // f.UpdateFPRF(v);
if (i.A.Rc) { if (i.A.Rc) {
@ -385,7 +366,6 @@ XEEMITTER(frspx, 0xFC000018, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Floating-point compare (A-11) // Floating-point compare (A-11)
int InstrEmit_fcmpx_(PPCHIRBuilder& f, InstrData& i, bool ordered) { int InstrEmit_fcmpx_(PPCHIRBuilder& f, InstrData& i, bool ordered) {
@ -417,7 +397,6 @@ XEEMITTER(fcmpu, 0xFC000000, X )(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_fcmpx_(f, i, false); return InstrEmit_fcmpx_(f, i, false);
} }
// Floating-point status and control register (A // Floating-point status and control register (A
XEEMITTER(mcrfs, 0xFC000080, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(mcrfs, 0xFC000080, X)(PPCHIRBuilder& f, InstrData& i) {
@ -465,7 +444,6 @@ XEEMITTER(mtfsfix, 0xFC00010C, X )(PPCHIRBuilder& f, InstrData& i) {
return 1; return 1;
} }
// Floating-point move (A-21) // Floating-point move (A-21)
XEEMITTER(fabsx, 0xFC000210, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(fabsx, 0xFC000210, X)(PPCHIRBuilder& f, InstrData& i) {
@ -509,7 +487,6 @@ XEEMITTER(fnegx, 0xFC000050, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
void RegisterEmitCategoryFPU() { void RegisterEmitCategoryFPU() {
XEREGISTERINSTR(faddx, 0xFC00002A); XEREGISTERINSTR(faddx, 0xFC00002A);
XEREGISTERINSTR(faddsx, 0xEC00002A); XEREGISTERINSTR(faddsx, 0xEC00002A);
@ -552,7 +529,6 @@ void RegisterEmitCategoryFPU() {
XEREGISTERINSTR(fnegx, 0xFC000050); XEREGISTERINSTR(fnegx, 0xFC000050);
} }
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy

View File

@ -12,23 +12,22 @@
#include <alloy/frontend/ppc/ppc_context.h> #include <alloy/frontend/ppc/ppc_context.h>
#include <alloy/frontend/ppc/ppc_hir_builder.h> #include <alloy/frontend/ppc/ppc_hir_builder.h>
using namespace alloy::frontend::ppc;
using namespace alloy::hir;
using namespace alloy::runtime;
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using alloy::hir::Value;
#define TRUNCATE_ADDRESSES 0 #define TRUNCATE_ADDRESSES 0
Value* CalculateEA(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) { Value* CalculateEA(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) {
#if TRUNCATE_ADDRESSES #if TRUNCATE_ADDRESSES
return f.ZeroExtend(f.Add( return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.Truncate(f.LoadGPR(ra), INT32_TYPE), f.Truncate(f.LoadGPR(rb), INT32_TYPE)),
f.Truncate(f.LoadGPR(rb), INT32_TYPE)), INT64_TYPE); INT64_TYPE);
#else #else
return f.Add(f.LoadGPR(ra), f.LoadGPR(rb)); return f.Add(f.LoadGPR(ra), f.LoadGPR(rb));
#endif // TRUNCATE_ADDRESSES #endif // TRUNCATE_ADDRESSES
@ -37,9 +36,9 @@ Value* CalculateEA(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) {
Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) { Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) {
#if TRUNCATE_ADDRESSES #if TRUNCATE_ADDRESSES
if (ra) { if (ra) {
return f.ZeroExtend(f.Add( return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.Truncate(f.LoadGPR(ra), INT32_TYPE), f.Truncate(f.LoadGPR(rb), INT32_TYPE)),
f.Truncate(f.LoadGPR(rb), INT32_TYPE)), INT64_TYPE); INT64_TYPE);
} else { } else {
return f.ZeroExtend(f.Truncate(f.LoadGPR(rb), INT32_TYPE), INT64_TYPE); return f.ZeroExtend(f.Truncate(f.LoadGPR(rb), INT32_TYPE), INT64_TYPE);
} }
@ -54,9 +53,9 @@ Value* CalculateEA_0(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) {
Value* CalculateEA_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) { Value* CalculateEA_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) {
#if TRUNCATE_ADDRESSES #if TRUNCATE_ADDRESSES
return f.ZeroExtend(f.Add( return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.Truncate(f.LoadGPR(ra), INT32_TYPE), f.LoadConstant((int32_t)imm)),
f.LoadConstant((int32_t)imm)), INT64_TYPE); INT64_TYPE);
#else #else
return f.Add(f.LoadGPR(ra), f.LoadConstant(imm)); return f.Add(f.LoadGPR(ra), f.LoadConstant(imm));
#endif // TRUNCATE_ADDRESSES #endif // TRUNCATE_ADDRESSES
@ -65,9 +64,9 @@ Value* CalculateEA_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) {
Value* CalculateEA_0_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) { Value* CalculateEA_0_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) {
#if TRUNCATE_ADDRESSES #if TRUNCATE_ADDRESSES
if (ra) { if (ra) {
return f.ZeroExtend(f.Add( return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.Truncate(f.LoadGPR(ra), INT32_TYPE), f.LoadConstant((int32_t)imm)),
f.LoadConstant((int32_t)imm)), INT64_TYPE); INT64_TYPE);
} else { } else {
return f.ZeroExtend(f.LoadConstant((int32_t)imm), INT64_TYPE); return f.ZeroExtend(f.LoadConstant((int32_t)imm), INT64_TYPE);
} }
@ -80,7 +79,6 @@ Value* CalculateEA_0_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) {
#endif // TRUNCATE_ADDRESSES #endif // TRUNCATE_ADDRESSES
} }
// Integer load (A-13) // Integer load (A-13)
XEEMITTER(lbz, 0x88000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(lbz, 0x88000000, D)(PPCHIRBuilder& f, InstrData& i) {
@ -300,7 +298,6 @@ XEEMITTER(lwzx, 0x7C00002E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
XEEMITTER(ld, 0xE8000000, DS)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(ld, 0xE8000000, DS)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then // if RA = 0 then
// b <- 0 // b <- 0
@ -349,7 +346,6 @@ XEEMITTER(ldx, 0x7C00002A, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Integer store (A-14) // Integer store (A-14)
XEEMITTER(stb, 0x98000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(stb, 0x98000000, D)(PPCHIRBuilder& f, InstrData& i) {
@ -528,7 +524,6 @@ XEEMITTER(stdx, 0x7C00012A, X)(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Integer load and store with byte reverse (A-1 // Integer load and store with byte reverse (A-1
XEEMITTER(lhbrx, 0x7C00062C, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(lhbrx, 0x7C00062C, X)(PPCHIRBuilder& f, InstrData& i) {
@ -606,7 +601,6 @@ XEEMITTER(stdbrx, 0x7C000528, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Integer load and store multiple (A-16) // Integer load and store multiple (A-16)
XEEMITTER(lmw, 0xB8000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(lmw, 0xB8000000, D)(PPCHIRBuilder& f, InstrData& i) {
@ -619,7 +613,6 @@ XEEMITTER(stmw, 0xBC000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 1; return 1;
} }
// Integer load and store string (A-17) // Integer load and store string (A-17)
XEEMITTER(lswi, 0x7C0004AA, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(lswi, 0x7C0004AA, X)(PPCHIRBuilder& f, InstrData& i) {
@ -642,7 +635,6 @@ XEEMITTER(stswx, 0x7C00052A, X )(PPCHIRBuilder& f, InstrData& i) {
return 1; return 1;
} }
// Memory synchronization (A-18) // Memory synchronization (A-18)
XEEMITTER(eieio, 0x7C0006AC, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(eieio, 0x7C0006AC, X)(PPCHIRBuilder& f, InstrData& i) {
@ -690,7 +682,8 @@ XEEMITTER(lwarx, 0x7C000028, X )(PPCHIRBuilder& f, InstrData& i) {
// RESERVE_ADDR <- real_addr(EA) // RESERVE_ADDR <- real_addr(EA)
// RT <- i32.0 || MEM(EA, 4) // RT <- i32.0 || MEM(EA, 4)
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
Value* rt = f.ZeroExtend(f.ByteSwap(f.LoadAcquire(ea, INT32_TYPE)), INT64_TYPE); Value* rt =
f.ZeroExtend(f.ByteSwap(f.LoadAcquire(ea, INT32_TYPE)), INT64_TYPE);
f.StoreGPR(i.X.RT, rt); f.StoreGPR(i.X.RT, rt);
return 0; return 0;
} }
@ -729,7 +722,6 @@ XEEMITTER(stwcx, 0x7C00012D, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
// Floating-point load (A-19) // Floating-point load (A-19)
XEEMITTER(lfd, 0xC8000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(lfd, 0xC8000000, D)(PPCHIRBuilder& f, InstrData& i) {
@ -789,8 +781,7 @@ XEEMITTER(lfs, 0xC0000000, D )(PPCHIRBuilder& f, InstrData& i) {
// FRT <- DOUBLE(MEM(EA, 4)) // FRT <- DOUBLE(MEM(EA, 4))
Value* ea = CalculateEA_0_i(f, i.D.RA, XEEXTS16(i.D.DS)); Value* ea = CalculateEA_0_i(f, i.D.RA, XEEXTS16(i.D.DS));
Value* rt = f.Convert( Value* rt = f.Convert(
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE);
FLOAT64_TYPE);
f.StoreFPR(i.D.RT, rt); f.StoreFPR(i.D.RT, rt);
return 0; return 0;
} }
@ -801,8 +792,7 @@ XEEMITTER(lfsu, 0xC4000000, D )(PPCHIRBuilder& f, InstrData& i) {
// RA <- EA // RA <- EA
Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS)); Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS));
Value* rt = f.Convert( Value* rt = f.Convert(
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE);
FLOAT64_TYPE);
f.StoreFPR(i.D.RT, rt); f.StoreFPR(i.D.RT, rt);
f.StoreGPR(i.D.RA, ea); f.StoreGPR(i.D.RA, ea);
return 0; return 0;
@ -814,8 +804,7 @@ XEEMITTER(lfsux, 0x7C00046E, X )(PPCHIRBuilder& f, InstrData& i) {
// RA <- EA // RA <- EA
Value* ea = CalculateEA(f, i.X.RA, i.X.RB); Value* ea = CalculateEA(f, i.X.RA, i.X.RB);
Value* rt = f.Convert( Value* rt = f.Convert(
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE);
FLOAT64_TYPE);
f.StoreFPR(i.X.RT, rt); f.StoreFPR(i.X.RT, rt);
f.StoreGPR(i.X.RA, ea); f.StoreGPR(i.X.RA, ea);
return 0; return 0;
@ -830,13 +819,11 @@ XEEMITTER(lfsx, 0x7C00042E, X )(PPCHIRBuilder& f, InstrData& i) {
// FRT <- DOUBLE(MEM(EA, 4)) // FRT <- DOUBLE(MEM(EA, 4))
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
Value* rt = f.Convert( Value* rt = f.Convert(
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE);
FLOAT64_TYPE);
f.StoreFPR(i.X.RT, rt); f.StoreFPR(i.X.RT, rt);
return 0; return 0;
} }
// Floating-point store (A-20) // Floating-point store (A-20)
XEEMITTER(stfd, 0xD8000000, D)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(stfd, 0xD8000000, D)(PPCHIRBuilder& f, InstrData& i) {
@ -891,8 +878,8 @@ XEEMITTER(stfiwx, 0x7C0007AE, X )(PPCHIRBuilder& f, InstrData& i) {
// EA <- b + (RB) // EA <- b + (RB)
// MEM(EA, 4) <- (FRS)[32:63] // MEM(EA, 4) <- (FRS)[32:63]
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
f.Store(ea, f.ByteSwap( f.Store(ea, f.ByteSwap(f.Truncate(f.Cast(f.LoadFPR(i.X.RT), INT64_TYPE),
f.Truncate(f.Cast(f.LoadFPR(i.X.RT), INT64_TYPE), INT32_TYPE))); INT32_TYPE)));
return 0; return 0;
} }
@ -904,8 +891,8 @@ XEEMITTER(stfs, 0xD0000000, D )(PPCHIRBuilder& f, InstrData& i) {
// EA <- b + EXTS(D) // EA <- b + EXTS(D)
// MEM(EA, 4) <- SINGLE(FRS) // MEM(EA, 4) <- SINGLE(FRS)
Value* ea = CalculateEA_0_i(f, i.D.RA, XEEXTS16(i.D.DS)); Value* ea = CalculateEA_0_i(f, i.D.RA, XEEXTS16(i.D.DS));
f.Store(ea, f.ByteSwap(f.Cast( f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE),
f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE), INT32_TYPE))); INT32_TYPE)));
return 0; return 0;
} }
@ -914,8 +901,8 @@ XEEMITTER(stfsu, 0xD4000000, D )(PPCHIRBuilder& f, InstrData& i) {
// MEM(EA, 4) <- SINGLE(FRS) // MEM(EA, 4) <- SINGLE(FRS)
// RA <- EA // RA <- EA
Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS)); Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS));
f.Store(ea, f.ByteSwap(f.Cast( f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE),
f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE), INT32_TYPE))); INT32_TYPE)));
f.StoreGPR(i.D.RA, ea); f.StoreGPR(i.D.RA, ea);
return 0; return 0;
} }
@ -925,8 +912,8 @@ XEEMITTER(stfsux, 0x7C00056E, X )(PPCHIRBuilder& f, InstrData& i) {
// MEM(EA, 4) <- SINGLE(FRS) // MEM(EA, 4) <- SINGLE(FRS)
// RA <- EA // RA <- EA
Value* ea = CalculateEA(f, i.X.RA, i.X.RB); Value* ea = CalculateEA(f, i.X.RA, i.X.RB);
f.Store(ea, f.ByteSwap(f.Cast( f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE),
f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE), INT32_TYPE))); INT32_TYPE)));
f.StoreGPR(i.X.RA, ea); f.StoreGPR(i.X.RA, ea);
return 0; return 0;
} }
@ -939,12 +926,11 @@ XEEMITTER(stfsx, 0x7C00052E, X )(PPCHIRBuilder& f, InstrData& i) {
// EA <- b + (RB) // EA <- b + (RB)
// MEM(EA, 4) <- SINGLE(FRS) // MEM(EA, 4) <- SINGLE(FRS)
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB); Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
f.Store(ea, f.ByteSwap(f.Cast( f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE),
f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE), INT32_TYPE))); INT32_TYPE)));
return 0; return 0;
} }
// Cache management (A-27) // Cache management (A-27)
XEEMITTER(dcbf, 0x7C0000AC, X)(PPCHIRBuilder& f, InstrData& i) { XEEMITTER(dcbf, 0x7C0000AC, X)(PPCHIRBuilder& f, InstrData& i) {
@ -994,7 +980,6 @@ XEEMITTER(icbi, 0x7C0007AC, X )(PPCHIRBuilder& f, InstrData& i) {
return 0; return 0;
} }
void RegisterEmitCategoryMemory() { void RegisterEmitCategoryMemory() {
XEREGISTERINSTR(lbz, 0x88000000); XEREGISTERINSTR(lbz, 0x88000000);
XEREGISTERINSTR(lbzu, 0x8C000000); XEREGISTERINSTR(lbzu, 0x8C000000);
@ -1079,7 +1064,6 @@ void RegisterEmitCategoryMemory() {
XEREGISTERINSTR(icbi, 0x7C0007AC); XEREGISTERINSTR(icbi, 0x7C0007AC);
} }
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy

View File

@ -15,13 +15,14 @@
#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>
using namespace alloy; namespace alloy {
using namespace alloy::frontend; namespace frontend {
using namespace alloy::frontend::ppc; namespace ppc {
using namespace alloy::runtime;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
using alloy::runtime::Runtime;
namespace {
void InitializeIfNeeded(); void InitializeIfNeeded();
void CleanupOnShutdown(); void CleanupOnShutdown();
@ -41,18 +42,13 @@ namespace {
atexit(CleanupOnShutdown); atexit(CleanupOnShutdown);
} }
void CleanupOnShutdown() { void CleanupOnShutdown() {}
}
}
PPCFrontend::PPCFrontend(Runtime* runtime) : Frontend(runtime) {
PPCFrontend::PPCFrontend(Runtime* runtime) :
Frontend(runtime) {
InitializeIfNeeded(); InitializeIfNeeded();
ContextInfo* info = new ContextInfo( ContextInfo* info =
sizeof(PPCContext), new ContextInfo(sizeof(PPCContext), offsetof(PPCContext, thread_state));
offsetof(PPCContext, thread_state));
// Add fields/etc. // Add fields/etc.
context_info_ = info; context_info_ = info;
} }
@ -61,8 +57,7 @@ PPCFrontend::~PPCFrontend() {
// Force cleanup now before we deinit. // Force cleanup now before we deinit.
translator_pool_.Reset(); translator_pool_.Reset();
alloy::tracing::WriteEvent(EventType::Deinit({ alloy::tracing::WriteEvent(EventType::Deinit({}));
}));
} }
int PPCFrontend::Initialize() { int PPCFrontend::Initialize() {
@ -71,14 +66,12 @@ int PPCFrontend::Initialize() {
return result; return result;
} }
alloy::tracing::WriteEvent(EventType::Init({ alloy::tracing::WriteEvent(EventType::Init({}));
}));
return result; return result;
} }
int PPCFrontend::DeclareFunction( int PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) {
FunctionInfo* symbol_info) {
// Could scan or something here. // Could scan or something here.
// Could also check to see if it's a well-known function type and classify // Could also check to see if it's a well-known function type and classify
// for later. // for later.
@ -87,12 +80,16 @@ int PPCFrontend::DeclareFunction(
return 0; return 0;
} }
int PPCFrontend::DefineFunction( int PPCFrontend::DefineFunction(FunctionInfo* symbol_info,
FunctionInfo* symbol_info, uint32_t debug_info_flags, uint32_t debug_info_flags,
Function** out_function) { Function** out_function) {
PPCTranslator* translator = translator_pool_.Allocate(this); PPCTranslator* translator = translator_pool_.Allocate(this);
int result = translator->Translate( int result =
symbol_info, debug_info_flags, out_function); translator->Translate(symbol_info, debug_info_flags, out_function);
translator_pool_.Release(translator); translator_pool_.Release(translator);
return result; return result;
} }
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -15,7 +15,6 @@
#include <alloy/frontend/frontend.h> #include <alloy/frontend/frontend.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
@ -29,20 +28,17 @@ public:
virtual int Initialize(); virtual int Initialize();
virtual int DeclareFunction( virtual int DeclareFunction(runtime::FunctionInfo* symbol_info);
runtime::FunctionInfo* symbol_info); virtual int DefineFunction(runtime::FunctionInfo* symbol_info,
virtual int DefineFunction( uint32_t debug_info_flags,
runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags,
runtime::Function** out_function); runtime::Function** out_function);
private: private:
TypePool<PPCTranslator, PPCFrontend*> translator_pool_; TypePool<PPCTranslator, PPCFrontend*> translator_pool_;
}; };
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_FRONTEND_H_ #endif // ALLOY_FRONTEND_PPC_PPC_FRONTEND_H_

View File

@ -18,22 +18,25 @@
#include <alloy/hir/label.h> #include <alloy/hir/label.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::frontend; namespace frontend {
using namespace alloy::frontend::ppc; namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir; using namespace alloy::hir;
using namespace alloy::runtime;
using alloy::hir::Label;
using alloy::hir::TypeName;
using alloy::hir::Value;
using alloy::runtime::Runtime;
using alloy::runtime::FunctionInfo;
PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend) : PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend)
frontend_(frontend), : frontend_(frontend), HIRBuilder() {
HIRBuilder() {
comment_buffer_ = new StringBuffer(4096); comment_buffer_ = new StringBuffer(4096);
} }
PPCHIRBuilder::~PPCHIRBuilder() { PPCHIRBuilder::~PPCHIRBuilder() { delete comment_buffer_; }
delete comment_buffer_;
}
void PPCHIRBuilder::Reset() { void PPCHIRBuilder::Reset() {
start_address_ = 0; start_address_ = 0;
@ -51,13 +54,11 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) {
symbol_info_ = symbol_info; symbol_info_ = symbol_info;
start_address_ = symbol_info->address(); start_address_ = symbol_info->address();
instr_count_ = instr_count_ = (symbol_info->end_address() - symbol_info->address()) / 4 + 1;
(symbol_info->end_address() - symbol_info->address()) / 4 + 1;
with_debug_info_ = with_debug_info; with_debug_info_ = with_debug_info;
if (with_debug_info_) { if (with_debug_info_) {
Comment("%s fn %.8X-%.8X %s", Comment("%s fn %.8X-%.8X %s", symbol_info->module()->name(),
symbol_info->module()->name(),
symbol_info->address(), symbol_info->end_address(), symbol_info->address(), symbol_info->end_address(),
symbol_info->name()); symbol_info->name());
} }
@ -134,8 +135,8 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) {
} }
if (!i.type->emit || emit(*this, i)) { if (!i.type->emit || emit(*this, i)) {
XELOGCPU("Unimplemented instr %.8X %.8X %s", XELOGCPU("Unimplemented instr %.8X %.8X %s", i.address, i.code,
i.address, i.code, i.type->name); i.type->name);
Comment("UNIMPLEMENTED!"); Comment("UNIMPLEMENTED!");
// DebugBreak(); // DebugBreak();
// TraceInvalidInstruction(i); // TraceInvalidInstruction(i);
@ -147,8 +148,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, bool with_debug_info) {
void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) { void PPCHIRBuilder::AnnotateLabel(uint64_t address, Label* label) {
char name_buffer[13]; char name_buffer[13];
xesnprintfa(name_buffer, XECOUNT(name_buffer), xesnprintfa(name_buffer, XECOUNT(name_buffer), "loc_%.8X", (uint32_t)address);
"loc_%.8X", (uint32_t)address);
label->name = (char*)arena_->Alloc(sizeof(name_buffer)); label->name = (char*)arena_->Alloc(sizeof(name_buffer));
xe_copy_struct(label->name, name_buffer, sizeof(name_buffer)); xe_copy_struct(label->name, name_buffer, sizeof(name_buffer));
} }
@ -235,13 +235,12 @@ void PPCHIRBuilder::StoreCR(uint32_t n, Value* value) {
XEASSERTALWAYS(); XEASSERTALWAYS();
} }
void PPCHIRBuilder::UpdateCR( void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, bool is_signed) {
uint32_t n, Value* lhs, bool is_signed) {
UpdateCR(n, lhs, LoadZero(lhs->type), is_signed); UpdateCR(n, lhs, LoadZero(lhs->type), is_signed);
} }
void PPCHIRBuilder::UpdateCR( void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, Value* rhs,
uint32_t n, Value* lhs, Value* rhs, bool is_signed) { bool is_signed) {
if (is_signed) { if (is_signed) {
Value* lt = CompareSLT(lhs, rhs); Value* lt = CompareSLT(lhs, rhs);
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 0, lt); StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 0, lt);
@ -264,7 +263,8 @@ void PPCHIRBuilder::UpdateCR6(Value* src_value) {
// Testing for all 1's and all 0's. // Testing for all 1's and all 0's.
// if (Rc) CR6 = all_equal | 0 | none_equal | 0 // if (Rc) CR6 = all_equal | 0 | none_equal | 0
// TODO(benvanik): efficient instruction? // TODO(benvanik): efficient instruction?
StoreContext(offsetof(PPCContext, cr6.cr6_all_equal), IsFalse(Not(src_value))); StoreContext(offsetof(PPCContext, cr6.cr6_all_equal),
IsFalse(Not(src_value)));
StoreContext(offsetof(PPCContext, cr6.cr6_none_equal), IsFalse(src_value)); StoreContext(offsetof(PPCContext, cr6.cr6_none_equal), IsFalse(src_value));
} }
@ -282,9 +282,7 @@ Value* PPCHIRBuilder::LoadXER() {
return NULL; return NULL;
} }
void PPCHIRBuilder::StoreXER(Value* value) { void PPCHIRBuilder::StoreXER(Value* value) { XEASSERTALWAYS(); }
XEASSERTALWAYS();
}
Value* PPCHIRBuilder::LoadCA() { Value* PPCHIRBuilder::LoadCA() {
return LoadContext(offsetof(PPCContext, xer_ca), INT8_TYPE); return LoadContext(offsetof(PPCContext, xer_ca), INT8_TYPE);
@ -305,48 +303,41 @@ void PPCHIRBuilder::StoreSAT(Value* value) {
} }
Value* PPCHIRBuilder::LoadGPR(uint32_t reg) { Value* PPCHIRBuilder::LoadGPR(uint32_t reg) {
return LoadContext( return LoadContext(offsetof(PPCContext, r) + reg * 8, INT64_TYPE);
offsetof(PPCContext, r) + reg * 8, INT64_TYPE);
} }
void PPCHIRBuilder::StoreGPR(uint32_t reg, Value* value) { void PPCHIRBuilder::StoreGPR(uint32_t reg, Value* value) {
XEASSERT(value->type == INT64_TYPE); XEASSERT(value->type == INT64_TYPE);
StoreContext( StoreContext(offsetof(PPCContext, r) + reg * 8, value);
offsetof(PPCContext, r) + reg * 8, value);
} }
Value* PPCHIRBuilder::LoadFPR(uint32_t reg) { Value* PPCHIRBuilder::LoadFPR(uint32_t reg) {
return LoadContext( return LoadContext(offsetof(PPCContext, f) + reg * 8, FLOAT64_TYPE);
offsetof(PPCContext, f) + reg * 8, FLOAT64_TYPE);
} }
void PPCHIRBuilder::StoreFPR(uint32_t reg, Value* value) { void PPCHIRBuilder::StoreFPR(uint32_t reg, Value* value) {
XEASSERT(value->type == FLOAT64_TYPE); XEASSERT(value->type == FLOAT64_TYPE);
StoreContext( StoreContext(offsetof(PPCContext, f) + reg * 8, value);
offsetof(PPCContext, f) + reg * 8, value);
} }
Value* PPCHIRBuilder::LoadVR(uint32_t reg) { Value* PPCHIRBuilder::LoadVR(uint32_t reg) {
return LoadContext( return LoadContext(offsetof(PPCContext, v) + reg * 16, VEC128_TYPE);
offsetof(PPCContext, v) + reg * 16, VEC128_TYPE);
} }
void PPCHIRBuilder::StoreVR(uint32_t reg, Value* value) { void PPCHIRBuilder::StoreVR(uint32_t reg, Value* value) {
XEASSERT(value->type == VEC128_TYPE); XEASSERT(value->type == VEC128_TYPE);
StoreContext( StoreContext(offsetof(PPCContext, v) + reg * 16, value);
offsetof(PPCContext, v) + reg * 16, value);
} }
Value* PPCHIRBuilder::LoadAcquire( Value* PPCHIRBuilder::LoadAcquire(Value* address, TypeName type,
Value* address, TypeName type, uint32_t load_flags) { uint32_t load_flags) {
AtomicExchange( AtomicExchange(LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE),
LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE),
Truncate(address, INT32_TYPE)); Truncate(address, INT32_TYPE));
return Load(address, type, load_flags); return Load(address, type, load_flags);
} }
Value* PPCHIRBuilder::StoreRelease( Value* PPCHIRBuilder::StoreRelease(Value* address, Value* value,
Value* address, Value* value, uint32_t store_flags) { uint32_t store_flags) {
Value* old_address = AtomicExchange( Value* old_address = AtomicExchange(
LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE), LoadContext(offsetof(PPCContext, reserve_address), INT64_TYPE),
LoadZero(INT32_TYPE)); LoadZero(INT32_TYPE));
@ -357,3 +348,7 @@ Value* PPCHIRBuilder::StoreRelease(
MarkLabel(skip_label); MarkLabel(skip_label);
return eq; return eq;
} }
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -15,18 +15,17 @@
#include <alloy/runtime/function.h> #include <alloy/runtime/function.h>
#include <alloy/runtime/symbol_info.h> #include <alloy/runtime/symbol_info.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
class PPCFrontend; class PPCFrontend;
class PPCHIRBuilder : public hir::HIRBuilder { class PPCHIRBuilder : public hir::HIRBuilder {
using Instr = alloy::hir::Instr; using Instr = alloy::hir::Instr;
using Label = alloy::hir::Label; using Label = alloy::hir::Label;
using Value = alloy::hir::Value; using Value = alloy::hir::Value;
public: public:
PPCHIRBuilder(PPCFrontend* frontend); PPCHIRBuilder(PPCFrontend* frontend);
virtual ~PPCHIRBuilder(); virtual ~PPCHIRBuilder();
@ -68,7 +67,8 @@ public:
Value* LoadVR(uint32_t reg); Value* LoadVR(uint32_t reg);
void StoreVR(uint32_t reg, Value* value); void StoreVR(uint32_t reg, Value* value);
Value* LoadAcquire(Value* address, hir::TypeName type, uint32_t load_flags = 0); Value* LoadAcquire(Value* address, hir::TypeName type,
uint32_t load_flags = 0);
Value* StoreRelease(Value* address, Value* value, uint32_t store_flags = 0); Value* StoreRelease(Value* address, Value* value, uint32_t store_flags = 0);
private: private:
@ -89,10 +89,8 @@ private:
Label** label_list_; Label** label_list_;
}; };
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_ #endif // ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_

View File

@ -13,11 +13,9 @@
#include <alloy/frontend/ppc/ppc_instr_tables.h> #include <alloy/frontend/ppc/ppc_instr_tables.h>
namespace alloy {
using namespace alloy; namespace frontend {
using namespace alloy::frontend; namespace ppc {
using namespace alloy::frontend::ppc;
void InstrOperand::Dump(std::string& out_str) { void InstrOperand::Dump(std::string& out_str) {
if (display) { if (display) {
@ -92,10 +90,7 @@ void InstrOperand::Dump(std::string& out_str) {
out_str += buffer; out_str += buffer;
} }
void InstrAccessBits::Clear() { spr = cr = gpr = fpr = 0; }
void InstrAccessBits::Clear() {
spr = cr = gpr = fpr = 0;
}
void InstrAccessBits::Extend(InstrAccessBits& other) { void InstrAccessBits::Extend(InstrAccessBits& other) {
spr |= other.spr; spr |= other.spr;
@ -281,41 +276,31 @@ void InstrAccessBits::Dump(std::string& out_str) {
out_str = str.str(); out_str = str.str();
} }
void InstrDisasm::Init(const char* name, const char* info, uint32_t flags) { void InstrDisasm::Init(const char* name, const char* info, uint32_t flags) {
this->name = name; this->name = name;
this->info = info; this->info = info;
this->flags = flags; this->flags = flags;
} }
void InstrDisasm::AddLR(InstrRegister::Access access) { void InstrDisasm::AddLR(InstrRegister::Access access) {}
}
void InstrDisasm::AddCTR(InstrRegister::Access access) { void InstrDisasm::AddCTR(InstrRegister::Access access) {}
}
void InstrDisasm::AddCR(uint32_t bf, InstrRegister::Access access) { void InstrDisasm::AddCR(uint32_t bf, InstrRegister::Access access) {}
}
void InstrDisasm::AddFPSCR(InstrRegister::Access access) { void InstrDisasm::AddFPSCR(InstrRegister::Access access) {}
}
void InstrDisasm::AddRegOperand( void InstrDisasm::AddRegOperand(InstrRegister::RegisterSet set,
InstrRegister::RegisterSet set, uint32_t ordinal, uint32_t ordinal, InstrRegister::Access access,
InstrRegister::Access access, const char* display) { const char* display) {}
}
void InstrDisasm::AddSImmOperand(uint64_t value, size_t width, void InstrDisasm::AddSImmOperand(uint64_t value, size_t width,
const char* display) { const char* display) {}
}
void InstrDisasm::AddUImmOperand(uint64_t value, size_t width, void InstrDisasm::AddUImmOperand(uint64_t value, size_t width,
const char* display) { const char* display) {}
}
int InstrDisasm::Finish() { int InstrDisasm::Finish() { return 0; }
return 0;
}
void InstrDisasm::Dump(std::string& out_str, size_t pad) { void InstrDisasm::Dump(std::string& out_str, size_t pad) {
out_str = name; out_str = name;
@ -330,46 +315,54 @@ void InstrDisasm::Dump(std::string& out_str, size_t pad) {
} }
} }
InstrType* GetInstrType(uint32_t code) {
InstrType* alloy::frontend::ppc::GetInstrType(uint32_t code) {
// Fast lookup via tables. // Fast lookup via tables.
InstrType* slot = NULL; InstrType* slot = NULL;
switch (code >> 26) { switch (code >> 26) {
case 4: case 4:
// Opcode = 4, index = bits 10-0 (10) // Opcode = 4, index = bits 10-0 (10)
slot = alloy::frontend::ppc::tables::instr_table_4[XESELECTBITS(code, 0, 10)]; slot = alloy::frontend::ppc::tables::instr_table_4[XESELECTBITS(code, 0,
10)];
break; break;
case 19: case 19:
// Opcode = 19, index = bits 10-1 (10) // Opcode = 19, index = bits 10-1 (10)
slot = alloy::frontend::ppc::tables::instr_table_19[XESELECTBITS(code, 1, 10)]; slot = alloy::frontend::ppc::tables::instr_table_19[XESELECTBITS(code, 1,
10)];
break; break;
case 30: case 30:
// Opcode = 30, index = bits 4-1 (4) // Opcode = 30, index = bits 4-1 (4)
// Special cased to an uber instruction. // Special cased to an uber instruction.
slot = alloy::frontend::ppc::tables::instr_table_30[XESELECTBITS(code, 0, 0)]; slot = alloy::frontend::ppc::tables::instr_table_30[XESELECTBITS(code, 0,
0)];
break; break;
case 31: case 31:
// Opcode = 31, index = bits 10-1 (10) // Opcode = 31, index = bits 10-1 (10)
slot = alloy::frontend::ppc::tables::instr_table_31[XESELECTBITS(code, 1, 10)]; slot = alloy::frontend::ppc::tables::instr_table_31[XESELECTBITS(code, 1,
10)];
break; break;
case 58: case 58:
// Opcode = 58, index = bits 1-0 (2) // Opcode = 58, index = bits 1-0 (2)
slot = alloy::frontend::ppc::tables::instr_table_58[XESELECTBITS(code, 0, 1)]; slot = alloy::frontend::ppc::tables::instr_table_58[XESELECTBITS(code, 0,
1)];
break; break;
case 59: case 59:
// Opcode = 59, index = bits 5-1 (5) // Opcode = 59, index = bits 5-1 (5)
slot = alloy::frontend::ppc::tables::instr_table_59[XESELECTBITS(code, 1, 5)]; slot = alloy::frontend::ppc::tables::instr_table_59[XESELECTBITS(code, 1,
5)];
break; break;
case 62: case 62:
// Opcode = 62, index = bits 1-0 (2) // Opcode = 62, index = bits 1-0 (2)
slot = alloy::frontend::ppc::tables::instr_table_62[XESELECTBITS(code, 0, 1)]; slot = alloy::frontend::ppc::tables::instr_table_62[XESELECTBITS(code, 0,
1)];
break; break;
case 63: case 63:
// Opcode = 63, index = bits 10-1 (10) // Opcode = 63, index = bits 10-1 (10)
slot = alloy::frontend::ppc::tables::instr_table_63[XESELECTBITS(code, 1, 10)]; slot = alloy::frontend::ppc::tables::instr_table_63[XESELECTBITS(code, 1,
10)];
break; break;
default: default:
slot = alloy::frontend::ppc::tables::instr_table[XESELECTBITS(code, 26, 31)]; slot =
alloy::frontend::ppc::tables::instr_table[XESELECTBITS(code, 26, 31)];
break; break;
} }
if (slot && slot->opcode) { if (slot && slot->opcode) {
@ -379,8 +372,7 @@ InstrType* alloy::frontend::ppc::GetInstrType(uint32_t code) {
// Slow lookup via linear scan. // Slow lookup via linear scan.
// This is primarily due to laziness. It could be made fast like the others. // This is primarily due to laziness. It could be made fast like the others.
for (size_t n = 0; for (size_t n = 0;
n < XECOUNT(alloy::frontend::ppc::tables::instr_table_scan); n < XECOUNT(alloy::frontend::ppc::tables::instr_table_scan); n++) {
n++) {
slot = &(alloy::frontend::ppc::tables::instr_table_scan[n]); slot = &(alloy::frontend::ppc::tables::instr_table_scan[n]);
if (slot->opcode == (code & slot->opcode_mask)) { if (slot->opcode == (code & slot->opcode_mask)) {
return slot; return slot;
@ -390,7 +382,7 @@ InstrType* alloy::frontend::ppc::GetInstrType(uint32_t code) {
return NULL; return NULL;
} }
int alloy::frontend::ppc::RegisterInstrEmit(uint32_t code, InstrEmitFn emit) { int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
InstrType* instr_type = GetInstrType(code); InstrType* instr_type = GetInstrType(code);
XEASSERTNOTNULL(instr_type); XEASSERTNOTNULL(instr_type);
if (!instr_type) { if (!instr_type) {
@ -400,3 +392,7 @@ int alloy::frontend::ppc::RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
instr_type->emit = emit; instr_type->emit = emit;
return 0; return 0;
} }
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -15,12 +15,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
// TODO(benvanik): rename these // TODO(benvanik): rename these
typedef enum { typedef enum {
kXEPPCInstrFormatI = 0, kXEPPCInstrFormatI = 0,
@ -77,19 +75,13 @@ typedef enum {
kXEPPCInstrFlagReserved = 0, kXEPPCInstrFlagReserved = 0,
} xe_ppc_instr_flag_e; } xe_ppc_instr_flag_e;
class InstrType; class InstrType;
static inline int64_t XEEXTS16(uint32_t v) { return (int64_t)((int16_t)v); }
static inline int64_t XEEXTS16(uint32_t v) {
return (int64_t)((int16_t)v);
}
static inline int64_t XEEXTS26(uint32_t v) { static inline int64_t XEEXTS26(uint32_t v) {
return (int64_t)(v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v)); return (int64_t)(v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v));
} }
static inline uint64_t XEEXTZ16(uint32_t v) { static inline uint64_t XEEXTZ16(uint32_t v) { return (uint64_t)((uint16_t)v); }
return (uint64_t)((uint16_t)v);
}
static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) { static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
// if mstart ≤ mstop then // if mstart ≤ mstop then
// mask[mstart:mstop] = ones // mask[mstart:mstop] = ones
@ -105,7 +97,6 @@ static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
return mstart <= mstop ? value : ~value; return mstart <= mstop ? value : ~value;
} }
typedef struct { typedef struct {
InstrType* type; InstrType* type;
uint64_t address; uint64_t address;
@ -118,7 +109,8 @@ typedef struct {
uint32_t LK : 1; uint32_t LK : 1;
uint32_t AA : 1; uint32_t AA : 1;
uint32_t LI : 24; uint32_t LI : 24;
uint32_t : 6; uint32_t:
6;
} I; } I;
// kXEPPCInstrFormatB // kXEPPCInstrFormatB
struct { struct {
@ -127,7 +119,8 @@ typedef struct {
uint32_t BD : 14; uint32_t BD : 14;
uint32_t BI : 5; uint32_t BI : 5;
uint32_t BO : 5; uint32_t BO : 5;
uint32_t : 6; uint32_t:
6;
} B; } B;
// kXEPPCInstrFormatSC // kXEPPCInstrFormatSC
@ -136,71 +129,87 @@ typedef struct {
uint32_t DS : 16; uint32_t DS : 16;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} D; } D;
// kXEPPCInstrFormatDS // kXEPPCInstrFormatDS
struct { struct {
uint32_t : 2; uint32_t:
2;
uint32_t DS : 14; uint32_t DS : 14;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} DS; } DS;
// kXEPPCInstrFormatX // kXEPPCInstrFormatX
struct { struct {
uint32_t Rc : 1; uint32_t Rc : 1;
uint32_t : 10; uint32_t:
10;
uint32_t RB : 5; uint32_t RB : 5;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} X; } X;
// kXEPPCInstrFormatXL // kXEPPCInstrFormatXL
struct { struct {
uint32_t LK : 1; uint32_t LK : 1;
uint32_t : 10; uint32_t:
10;
uint32_t BB : 5; uint32_t BB : 5;
uint32_t BI : 5; uint32_t BI : 5;
uint32_t BO : 5; uint32_t BO : 5;
uint32_t : 6; uint32_t:
6;
} XL; } XL;
// kXEPPCInstrFormatXFX // kXEPPCInstrFormatXFX
struct { struct {
uint32_t : 1; uint32_t:
uint32_t : 10; 1;
uint32_t:
10;
uint32_t spr : 10; uint32_t spr : 10;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} XFX; } XFX;
// kXEPPCInstrFormatXFL // kXEPPCInstrFormatXFL
struct { struct {
uint32_t Rc : 1; uint32_t Rc : 1;
uint32_t : 10; uint32_t:
10;
uint32_t RB : 5; uint32_t RB : 5;
uint32_t W : 1; uint32_t W : 1;
uint32_t FM : 8; uint32_t FM : 8;
uint32_t L : 1; uint32_t L : 1;
uint32_t : 6; uint32_t:
6;
} XFL; } XFL;
// kXEPPCInstrFormatXS // kXEPPCInstrFormatXS
struct { struct {
uint32_t Rc : 1; uint32_t Rc : 1;
uint32_t SH5 : 1; uint32_t SH5 : 1;
uint32_t : 9; uint32_t:
9;
uint32_t SH : 5; uint32_t SH : 5;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} XS; } XS;
// kXEPPCInstrFormatXO // kXEPPCInstrFormatXO
struct { struct {
uint32_t Rc : 1; uint32_t Rc : 1;
uint32_t : 9; uint32_t:
9;
uint32_t OE : 1; uint32_t OE : 1;
uint32_t RB : 5; uint32_t RB : 5;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} XO; } XO;
// kXEPPCInstrFormatA // kXEPPCInstrFormatA
struct { struct {
@ -210,7 +219,8 @@ typedef struct {
uint32_t FRB : 5; uint32_t FRB : 5;
uint32_t FRA : 5; uint32_t FRA : 5;
uint32_t FRT : 5; uint32_t FRT : 5;
uint32_t : 6; uint32_t:
6;
} A; } A;
// kXEPPCInstrFormatM // kXEPPCInstrFormatM
struct { struct {
@ -220,7 +230,8 @@ typedef struct {
uint32_t SH : 5; uint32_t SH : 5;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} M; } M;
// kXEPPCInstrFormatMD // kXEPPCInstrFormatMD
struct { struct {
@ -232,7 +243,8 @@ typedef struct {
uint32_t SH : 5; uint32_t SH : 5;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} MD; } MD;
// kXEPPCInstrFormatMDS // kXEPPCInstrFormatMDS
struct { struct {
@ -243,33 +255,40 @@ typedef struct {
uint32_t RB : 5; uint32_t RB : 5;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t RT : 5; uint32_t RT : 5;
uint32_t : 6; uint32_t:
6;
} MDS; } MDS;
// kXEPPCInstrFormatVXA // kXEPPCInstrFormatVXA
struct { struct {
uint32_t : 6; uint32_t:
6;
uint32_t VC : 5; uint32_t VC : 5;
uint32_t VB : 5; uint32_t VB : 5;
uint32_t VA : 5; uint32_t VA : 5;
uint32_t VD : 5; uint32_t VD : 5;
uint32_t : 6; uint32_t:
6;
} VXA; } VXA;
// kXEPPCInstrFormatVX // kXEPPCInstrFormatVX
struct { struct {
uint32_t : 11; uint32_t:
11;
uint32_t VB : 5; uint32_t VB : 5;
uint32_t VA : 5; uint32_t VA : 5;
uint32_t VD : 5; uint32_t VD : 5;
uint32_t : 6; uint32_t:
6;
} VX; } VX;
// kXEPPCInstrFormatVXR // kXEPPCInstrFormatVXR
struct { struct {
uint32_t : 10; uint32_t:
10;
uint32_t Rc : 1; uint32_t Rc : 1;
uint32_t VB : 5; uint32_t VB : 5;
uint32_t VA : 5; uint32_t VA : 5;
uint32_t VD : 5; uint32_t VD : 5;
uint32_t : 6; uint32_t:
6;
} VXR; } VXR;
// kXEPPCInstrFormatVX128 // kXEPPCInstrFormatVX128
struct { struct {
@ -278,25 +297,31 @@ typedef struct {
// VB128 = VB128l | (VB128h << 5) // VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2; uint32_t VB128h : 2;
uint32_t VD128h : 2; uint32_t VD128h : 2;
uint32_t : 1; uint32_t:
1;
uint32_t VA128h : 1; uint32_t VA128h : 1;
uint32_t : 4; uint32_t:
4;
uint32_t VA128H : 1; uint32_t VA128H : 1;
uint32_t VB128l : 5; uint32_t VB128l : 5;
uint32_t VA128l : 5; uint32_t VA128l : 5;
uint32_t VD128l : 5; uint32_t VD128l : 5;
uint32_t : 6; uint32_t:
6;
} VX128; } VX128;
// kXEPPCInstrFormatVX128_1 // kXEPPCInstrFormatVX128_1
struct { struct {
// VD128 = VD128l | (VD128h << 5) // VD128 = VD128l | (VD128h << 5)
uint32_t : 2; uint32_t:
2;
uint32_t VD128h : 2; uint32_t VD128h : 2;
uint32_t : 7; uint32_t:
7;
uint32_t RB : 5; uint32_t RB : 5;
uint32_t RA : 5; uint32_t RA : 5;
uint32_t VD128l : 5; uint32_t VD128l : 5;
uint32_t : 6; uint32_t:
6;
} VX128_1; } VX128_1;
// kXEPPCInstrFormatVX128_2 // kXEPPCInstrFormatVX128_2
struct { struct {
@ -305,15 +330,18 @@ typedef struct {
// VB128 = VB128l | (VB128h << 5) // VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2; uint32_t VB128h : 2;
uint32_t VD128h : 2; uint32_t VD128h : 2;
uint32_t : 1; uint32_t:
1;
uint32_t VA128h : 1; uint32_t VA128h : 1;
uint32_t VC : 3; uint32_t VC : 3;
uint32_t : 1; uint32_t:
1;
uint32_t VA128H : 1; uint32_t VA128H : 1;
uint32_t VB128l : 5; uint32_t VB128l : 5;
uint32_t VA128l : 5; uint32_t VA128l : 5;
uint32_t VD128l : 5; uint32_t VD128l : 5;
uint32_t : 6; uint32_t:
6;
} VX128_2; } VX128_2;
// kXEPPCInstrFormatVX128_3 // kXEPPCInstrFormatVX128_3
struct { struct {
@ -321,11 +349,13 @@ typedef struct {
// VB128 = VB128l | (VB128h << 5) // VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2; uint32_t VB128h : 2;
uint32_t VD128h : 2; uint32_t VD128h : 2;
uint32_t : 7; uint32_t:
7;
uint32_t VB128l : 5; uint32_t VB128l : 5;
uint32_t IMM : 5; uint32_t IMM : 5;
uint32_t VD128l : 5; uint32_t VD128l : 5;
uint32_t : 6; uint32_t:
6;
} VX128_3; } VX128_3;
// kXEPPCInstrFormatVX128_4 // kXEPPCInstrFormatVX128_4
struct { struct {
@ -333,13 +363,16 @@ typedef struct {
// VB128 = VB128l | (VB128h << 5) // VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2; uint32_t VB128h : 2;
uint32_t VD128h : 2; uint32_t VD128h : 2;
uint32_t : 2; uint32_t:
2;
uint32_t z : 2; uint32_t z : 2;
uint32_t : 3; uint32_t:
3;
uint32_t VB128l : 5; uint32_t VB128l : 5;
uint32_t IMM : 5; uint32_t IMM : 5;
uint32_t VD128l : 5; uint32_t VD128l : 5;
uint32_t : 6; uint32_t:
6;
} VX128_4; } VX128_4;
// kXEPPCInstrFormatVX128_5 // kXEPPCInstrFormatVX128_5
struct { struct {
@ -348,14 +381,16 @@ typedef struct {
// VB128 = VB128l | (VB128h << 5) // VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2; uint32_t VB128h : 2;
uint32_t VD128h : 2; uint32_t VD128h : 2;
uint32_t : 1; uint32_t:
1;
uint32_t VA128h : 1; uint32_t VA128h : 1;
uint32_t SH : 4; uint32_t SH : 4;
uint32_t VA128H : 1; uint32_t VA128H : 1;
uint32_t VB128l : 5; uint32_t VB128l : 5;
uint32_t VA128l : 5; uint32_t VA128l : 5;
uint32_t VD128l : 5; uint32_t VD128l : 5;
uint32_t : 6; uint32_t:
6;
} VX128_5; } VX128_5;
// kXEPPCInstrFormatVX128_P // kXEPPCInstrFormatVX128_P
struct { struct {
@ -364,13 +399,16 @@ typedef struct {
// PERM = PERMl | (PERMh << 5) // PERM = PERMl | (PERMh << 5)
uint32_t VB128h : 2; uint32_t VB128h : 2;
uint32_t VD128h : 2; uint32_t VD128h : 2;
uint32_t : 2; uint32_t:
2;
uint32_t PERMh : 3; uint32_t PERMh : 3;
uint32_t : 2; uint32_t:
2;
uint32_t VB128l : 5; uint32_t VB128l : 5;
uint32_t PERMl : 5; uint32_t PERMl : 5;
uint32_t VD128l : 5; uint32_t VD128l : 5;
uint32_t : 6; uint32_t:
6;
} VX128_P; } VX128_P;
// kXEPPCInstrFormatVX128_R // kXEPPCInstrFormatVX128_R
struct { struct {
@ -379,15 +417,18 @@ typedef struct {
// VB128 = VB128l | (VB128h << 5) // VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2; uint32_t VB128h : 2;
uint32_t VD128h : 2; uint32_t VD128h : 2;
uint32_t : 1; uint32_t:
1;
uint32_t VA128h : 1; uint32_t VA128h : 1;
uint32_t Rc : 1; uint32_t Rc : 1;
uint32_t : 3; uint32_t:
3;
uint32_t VA128H : 1; uint32_t VA128H : 1;
uint32_t VB128l : 5; uint32_t VB128l : 5;
uint32_t VA128l : 5; uint32_t VA128l : 5;
uint32_t VD128l : 5; uint32_t VD128l : 5;
uint32_t : 6; uint32_t:
6;
} VX128_R; } VX128_R;
// kXEPPCInstrFormatXDSS // kXEPPCInstrFormatXDSS
struct { struct {
@ -395,7 +436,6 @@ typedef struct {
}; };
} InstrData; } InstrData;
typedef struct { typedef struct {
enum RegisterSet { enum RegisterSet {
kXER, kXER,
@ -419,7 +459,6 @@ typedef struct {
Access access; Access access;
} InstrRegister; } InstrRegister;
typedef struct { typedef struct {
enum OperandType { enum OperandType {
kRegister, kRegister,
@ -440,13 +479,17 @@ typedef struct {
void Dump(std::string& out_str); void Dump(std::string& out_str);
} InstrOperand; } InstrOperand;
class InstrAccessBits { class InstrAccessBits {
public: public:
InstrAccessBits() : InstrAccessBits()
spr(0), cr(0), gpr(0), fpr(0), : spr(0),
vr31_0(0), vr63_32(0), vr95_64(0), vr127_96(0) { cr(0),
} gpr(0),
fpr(0),
vr31_0(0),
vr63_32(0),
vr95_64(0),
vr127_96(0) {}
// Bitmasks derived from the accesses to registers. // Bitmasks derived from the accesses to registers.
// Format is 2 bits for each register, even bits indicating reads and odds // Format is 2 bits for each register, even bits indicating reads and odds
@ -466,7 +509,6 @@ public:
void Dump(std::string& out_str); void Dump(std::string& out_str);
}; };
class InstrDisasm { class InstrDisasm {
public: public:
enum Flags { enum Flags {
@ -496,11 +538,9 @@ public:
void Dump(std::string& out_str, size_t pad = 13); void Dump(std::string& out_str, size_t pad = 13);
}; };
typedef void (*InstrDisasmFn)(InstrData& i, StringBuffer* str); typedef void (*InstrDisasmFn)(InstrData& i, StringBuffer* str);
typedef void* InstrEmitFn; typedef void* InstrEmitFn;
class InstrType { class InstrType {
public: public:
uint32_t opcode; uint32_t opcode;
@ -517,11 +557,8 @@ public:
InstrType* GetInstrType(uint32_t code); InstrType* GetInstrType(uint32_t code);
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit); int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_INSTR_H_ #endif // ALLOY_FRONTEND_PPC_PPC_INSTR_H_

File diff suppressed because it is too large Load Diff

View File

@ -16,18 +16,15 @@
#include <alloy/frontend/ppc/ppc_instr.h> #include <alloy/frontend/ppc/ppc_instr.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::frontend; namespace frontend {
using namespace alloy::frontend::ppc; namespace ppc {
using namespace alloy::runtime;
using alloy::runtime::FunctionInfo;
PPCScanner::PPCScanner(PPCFrontend* frontend) : PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {}
frontend_(frontend) {
}
PPCScanner::~PPCScanner() { PPCScanner::~PPCScanner() {}
}
bool PPCScanner::IsRestGprLr(uint64_t address) { bool PPCScanner::IsRestGprLr(uint64_t address) {
FunctionInfo* symbol_info; FunctionInfo* symbol_info;
@ -80,9 +77,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// Check if the function starts with a mfspr lr, as that's a good indication // Check if the function starts with a mfspr lr, as that's a good indication
// of whether or not this is a normal function with a prolog/epilog. // of whether or not this is a normal function with a prolog/epilog.
// Some valid leaf functions won't have this, but most will. // Some valid leaf functions won't have this, but most will.
if (address == start_address && if (address == start_address && i.type && i.type->opcode == 0x7C0002A6 &&
i.type &&
i.type->opcode == 0x7C0002A6 &&
(((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F)) == 8) { (((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F)) == 8) {
starts_with_mfspr_lr = true; starts_with_mfspr_lr = true;
} }
@ -104,8 +99,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// This is generally a return. // This is generally a return.
if (furthest_target > address) { if (furthest_target > address) {
// Remaining targets within function, not end. // Remaining targets within function, not end.
XELOGSDB("ignoring blr %.8X (branch to %.8X)", XELOGSDB("ignoring blr %.8X (branch to %.8X)", address,
address, furthest_target); furthest_target);
} else { } else {
// Function end point. // Function end point.
XELOGSDB("function end %.8X", address); XELOGSDB("function end %.8X", address);
@ -142,16 +137,15 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// If the target is back into the function and there's no further target // If the target is back into the function and there's no further target
// we are at the end of a function. // we are at the end of a function.
// (Indirect branches may still go beyond, but no way of knowing). // (Indirect branches may still go beyond, but no way of knowing).
if (target >= start_address && if (target >= start_address && target < address &&
target < address && furthest_target <= address) { furthest_target <= address) {
XELOGSDB("function end %.8X (back b)", address); XELOGSDB("function end %.8X (back b)", address);
ends_fn = true; ends_fn = true;
} }
// If the target is not a branch and it goes to before the current // If the target is not a branch and it goes to before the current
// address it's definitely a tail call. // address it's definitely a tail call.
if (!ends_fn && if (!ends_fn && target < start_address && furthest_target <= address) {
target < start_address && furthest_target <= address) {
XELOGSDB("function end %.8X (back b before addr)", address); XELOGSDB("function end %.8X (back b before addr)", address);
ends_fn = true; ends_fn = true;
} }
@ -160,9 +154,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// Note that sometimes functions stick this in a basic block *inside* // Note that sometimes functions stick this in a basic block *inside*
// of the function somewhere, so ensure we don't have any branches over // of the function somewhere, so ensure we don't have any branches over
// it. // it.
if (!ends_fn && if (!ends_fn && furthest_target <= address && IsRestGprLr(target)) {
furthest_target <= address &&
IsRestGprLr(target)) {
XELOGSDB("function end %.8X (__restgprlr_*)", address); XELOGSDB("function end %.8X (__restgprlr_*)", address);
ends_fn = true; ends_fn = true;
} }
@ -174,9 +166,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// b KeBugCheck // b KeBugCheck
// This check may hit on functions that jump over data code, so only // This check may hit on functions that jump over data code, so only
// trigger this check in leaf functions (no mfspr lr/prolog). // trigger this check in leaf functions (no mfspr lr/prolog).
if (!ends_fn && if (!ends_fn && !starts_with_mfspr_lr && blocks_found == 1) {
!starts_with_mfspr_lr &&
blocks_found == 1) {
XELOGSDB("HEURISTIC: ending at simple leaf thunk %.8X", address); XELOGSDB("HEURISTIC: ending at simple leaf thunk %.8X", address);
ends_fn = true; ends_fn = true;
} }
@ -259,8 +249,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
address += 4; address += 4;
if (end_address && address > end_address) { if (end_address && address > end_address) {
// Hmm.... // Hmm....
XELOGSDB("Ran over function bounds! %.8X-%.8X", XELOGSDB("Ran over function bounds! %.8X-%.8X", start_address,
start_address, end_address); end_address);
break; break;
} }
} }
@ -270,8 +260,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// from someplace valid (like method hints) this may indicate an error. // from someplace valid (like method hints) this may indicate an error.
// It's also possible that we guessed in hole-filling and there's another // It's also possible that we guessed in hole-filling and there's another
// function below this one. // function below this one.
XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X", XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X", start_address,
start_address, end_address, address + 4); end_address, address + 4);
} }
symbol_info->set_end_address(address); symbol_info->set_end_address(address);
@ -300,8 +290,7 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
bool in_block = false; bool in_block = false;
uint64_t block_start = 0; uint64_t block_start = 0;
InstrData i; InstrData i;
for (uint64_t address = start_address; for (uint64_t address = start_address; address <= end_address; address += 4) {
address <= end_address; address += 4) {
i.address = address; i.address = address;
i.code = XEGETUINT32BE(p + address); i.code = XEGETUINT32BE(p + address);
if (!i.code) { if (!i.code) {
@ -349,16 +338,14 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
if (ends_block) { if (ends_block) {
in_block = false; in_block = false;
block_map[block_start] = { block_map[block_start] = {
block_start, block_start, address,
address,
}; };
} }
} }
if (in_block) { if (in_block) {
block_map[block_start] = { block_map[block_start] = {
block_start, block_start, end_address,
end_address,
}; };
} }
@ -368,3 +355,7 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
} }
return blocks; return blocks;
} }
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -13,7 +13,6 @@
#include <alloy/core.h> #include <alloy/core.h>
#include <alloy/runtime/symbol_info.h> #include <alloy/runtime/symbol_info.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
@ -25,7 +24,6 @@ typedef struct BlockInfo_t {
uint64_t end_address; uint64_t end_address;
} BlockInfo; } BlockInfo;
class PPCScanner { class PPCScanner {
public: public:
PPCScanner(PPCFrontend* frontend); PPCScanner(PPCFrontend* frontend);
@ -42,10 +40,8 @@ private:
PPCFrontend* frontend_; PPCFrontend* frontend_;
}; };
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_SCANNER_H_ #endif // ALLOY_FRONTEND_PPC_PPC_SCANNER_H_

View File

@ -19,17 +19,20 @@
#include <alloy/frontend/ppc/ppc_scanner.h> #include <alloy/frontend/ppc/ppc_scanner.h>
#include <alloy/runtime/runtime.h> #include <alloy/runtime/runtime.h>
using namespace alloy; namespace alloy {
using namespace alloy::backend; namespace frontend {
using namespace alloy::compiler; namespace ppc {
using namespace alloy::frontend;
using namespace alloy::frontend::ppc; // TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using namespace alloy::runtime; using namespace alloy::runtime;
using alloy::backend::Backend;
using alloy::compiler::Compiler;
using alloy::runtime::Function;
using alloy::runtime::FunctionInfo;
namespace passes = alloy::compiler::passes;
PPCTranslator::PPCTranslator(PPCFrontend* frontend) : PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
frontend_(frontend) {
Backend* backend = frontend->runtime()->backend(); Backend* backend = frontend->runtime()->backend();
scanner_ = new PPCScanner(frontend); scanner_ = new PPCScanner(frontend);
@ -67,8 +70,8 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) :
// Will modify the HIR to add loads/stores. // Will modify the HIR to add loads/stores.
// This should be the last pass before finalization, as after this all // This should be the last pass before finalization, as after this all
// registers are assigned and ready to be emitted. // registers are assigned and ready to be emitted.
compiler_->AddPass(new passes::RegisterAllocationPass( compiler_->AddPass(
backend->machine_info())); new passes::RegisterAllocationPass(backend->machine_info()));
if (validate) compiler_->AddPass(new passes::ValidationPass()); if (validate) compiler_->AddPass(new passes::ValidationPass());
// Must come last. The HIR is not really HIR after this. // Must come last. The HIR is not really HIR after this.
@ -82,8 +85,7 @@ PPCTranslator::~PPCTranslator() {
delete scanner_; delete scanner_;
} }
int PPCTranslator::Translate( int PPCTranslator::Translate(FunctionInfo* symbol_info,
FunctionInfo* symbol_info,
uint32_t debug_info_flags, uint32_t debug_info_flags,
Function** out_function) { Function** out_function) {
SCOPE_profile_cpu_f("alloy"); SCOPE_profile_cpu_f("alloy");
@ -139,10 +141,8 @@ int PPCTranslator::Translate(
} }
// Assemble to backend machine code. // Assemble to backend machine code.
result = assembler_->Assemble( result = assembler_->Assemble(symbol_info, builder_, debug_info_flags,
symbol_info, builder_, debug_info, out_function);
debug_info_flags, debug_info,
out_function);
XEEXPECTZERO(result); XEEXPECTZERO(result);
result = 0; result = 0;
@ -158,13 +158,12 @@ XECLEANUP:
return result; return result;
}; };
void PPCTranslator::DumpSource( void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info,
runtime::FunctionInfo* symbol_info, StringBuffer* string_buffer) { StringBuffer* string_buffer) {
Memory* memory = frontend_->memory(); Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase(); const uint8_t* p = memory->membase();
string_buffer->Append("%s fn %.8X-%.8X %s\n", string_buffer->Append("%s fn %.8X-%.8X %s\n", symbol_info->module()->name(),
symbol_info->module()->name(),
symbol_info->address(), symbol_info->end_address(), symbol_info->address(), symbol_info->end_address(),
symbol_info->name()); symbol_info->name());
@ -182,10 +181,8 @@ void PPCTranslator::DumpSource(
i.type = GetInstrType(i.code); i.type = GetInstrType(i.code);
// Check labels. // Check labels.
if (block_it != blocks.end() && if (block_it != blocks.end() && block_it->start_address == address) {
block_it->start_address == address) { string_buffer->Append("%.8X loc_%.8X:\n", address, address);
string_buffer->Append(
"%.8X loc_%.8X:\n", address, address);
++block_it; ++block_it;
} }
@ -194,3 +191,7 @@ void PPCTranslator::DumpSource(
string_buffer->Append("\n"); string_buffer->Append("\n");
} }
} }
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@ -15,7 +15,6 @@
#include <alloy/compiler/compiler.h> #include <alloy/compiler/compiler.h>
#include <alloy/runtime/symbol_info.h> #include <alloy/runtime/symbol_info.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
namespace ppc { namespace ppc {
@ -24,14 +23,12 @@ class PPCFrontend;
class PPCHIRBuilder; class PPCHIRBuilder;
class PPCScanner; class PPCScanner;
class PPCTranslator { class PPCTranslator {
public: public:
PPCTranslator(PPCFrontend* frontend); PPCTranslator(PPCFrontend* frontend);
~PPCTranslator(); ~PPCTranslator();
int Translate(runtime::FunctionInfo* symbol_info, int Translate(runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags,
uint32_t debug_info_flags,
runtime::Function** out_function); runtime::Function** out_function);
private: private:
@ -48,10 +45,8 @@ private:
StringBuffer string_buffer_; StringBuffer string_buffer_;
}; };
} // namespace ppc } // namespace ppc
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_ #endif // ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_

View File

@ -13,13 +13,11 @@
#include <alloy/tracing/tracing.h> #include <alloy/tracing/tracing.h>
#include <alloy/tracing/event_type.h> #include <alloy/tracing/event_type.h>
namespace alloy { namespace alloy {
namespace frontend { namespace frontend {
const uint32_t ALLOY_FRONTEND = alloy::tracing::EventType::ALLOY_FRONTEND; const uint32_t ALLOY_FRONTEND = alloy::tracing::EventType::ALLOY_FRONTEND;
class EventType { class EventType {
public: public:
enum { enum {
@ -35,9 +33,7 @@ public:
} Deinit; } Deinit;
}; };
} // namespace frontend } // namespace frontend
} // namespace alloy } // namespace alloy
#endif // ALLOY_FRONTEND_TRACING_H_ #endif // ALLOY_FRONTEND_TRACING_H_

View File

@ -11,9 +11,8 @@
#include <alloy/hir/instr.h> #include <alloy/hir/instr.h>
using namespace alloy; namespace alloy {
using namespace alloy::hir; namespace hir {
void Block::AssertNoCycles() { void Block::AssertNoCycles() {
Instr* hare = instr_head; Instr* hare = instr_head;
@ -37,3 +36,6 @@ void Block::AssertNoCycles() {
} }
} }
} }
} // namespace hir
} // namespace alloy

View File

@ -14,7 +14,6 @@
XEDECLARECLASS1(llvm, BitVector); XEDECLARECLASS1(llvm, BitVector);
namespace alloy { namespace alloy {
namespace hir { namespace hir {
@ -23,13 +22,13 @@ class HIRBuilder;
class Instr; class Instr;
class Label; class Label;
class Edge { class Edge {
public: public:
enum EdgeFlags { enum EdgeFlags {
UNCONDITIONAL = (1 << 0), UNCONDITIONAL = (1 << 0),
DOMINATES = (1 << 1), DOMINATES = (1 << 1),
}; };
public: public:
Edge* outgoing_next; Edge* outgoing_next;
Edge* outgoing_prev; Edge* outgoing_prev;
@ -42,7 +41,6 @@ public:
uint32_t flags; uint32_t flags;
}; };
class Block { class Block {
public: public:
Arena* arena; Arena* arena;
@ -65,9 +63,7 @@ public:
void AssertNoCycles(); void AssertNoCycles();
}; };
} // namespace hir } // namespace hir
} // namespace alloy } // namespace alloy
#endif // ALLOY_HIR_BLOCK_H_ #endif // ALLOY_HIR_BLOCK_H_

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,6 @@
#include <alloy/hir/opcodes.h> #include <alloy/hir/opcodes.h>
#include <alloy/hir/value.h> #include <alloy/hir/value.h>
namespace alloy { namespace alloy {
namespace hir { namespace hir {
@ -25,7 +24,6 @@ enum FunctionAttributes {
FUNCTION_ATTRIB_INLINE = (1 << 1), FUNCTION_ATTRIB_INLINE = (1 << 1),
}; };
class HIRBuilder { class HIRBuilder {
public: public:
HIRBuilder(); HIRBuilder();
@ -86,10 +84,8 @@ public:
void Branch(Label* label, uint32_t branch_flags = 0); void Branch(Label* label, uint32_t branch_flags = 0);
void Branch(Block* block, uint32_t branch_flags = 0); void Branch(Block* block, uint32_t branch_flags = 0);
void BranchTrue(Value* cond, Label* label, void BranchTrue(Value* cond, Label* label, uint32_t branch_flags = 0);
uint32_t branch_flags = 0); void BranchFalse(Value* cond, Label* label, uint32_t branch_flags = 0);
void BranchFalse(Value* cond, Label* label,
uint32_t branch_flags = 0);
// phi type_name, Block* b1, Value* v1, Block* b2, Value* v2, etc // phi type_name, Block* b1, Value* v1, Block* b2, Value* v2, etc
@ -162,8 +158,7 @@ public:
uint32_t arithmetic_flags = 0); uint32_t arithmetic_flags = 0);
Value* VectorAdd(Value* value1, Value* value2, TypeName part_type, Value* VectorAdd(Value* value1, Value* value2, TypeName part_type,
uint32_t arithmetic_flags = 0); uint32_t arithmetic_flags = 0);
Value* Sub(Value* value1, Value* value2, Value* Sub(Value* value1, Value* value2, uint32_t arithmetic_flags = 0);
uint32_t arithmetic_flags = 0);
Value* Mul(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); Value* Mul(Value* value1, Value* value2, uint32_t arithmetic_flags = 0);
Value* MulHi(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); Value* MulHi(Value* value1, Value* value2, uint32_t arithmetic_flags = 0);
Value* Div(Value* value1, Value* value2, uint32_t arithmetic_flags = 0); Value* Div(Value* value1, Value* value2, uint32_t arithmetic_flags = 0);
@ -208,16 +203,15 @@ public:
Value* Pack(Value* value, uint32_t pack_flags = 0); Value* Pack(Value* value, uint32_t pack_flags = 0);
Value* Unpack(Value* value, uint32_t pack_flags = 0); Value* Unpack(Value* value, uint32_t pack_flags = 0);
Value* CompareExchange(Value* address, Value* CompareExchange(Value* address, Value* compare_value,
Value* compare_value, Value* exchange_value); Value* exchange_value);
Value* AtomicExchange(Value* address, Value* new_value); Value* AtomicExchange(Value* address, Value* new_value);
Value* AtomicAdd(Value* address, Value* value); Value* AtomicAdd(Value* address, Value* value);
Value* AtomicSub(Value* address, Value* value); Value* AtomicSub(Value* address, Value* value);
protected: protected:
void DumpValue(StringBuffer* str, Value* value); void DumpValue(StringBuffer* str, Value* value);
void DumpOp( void DumpOp(StringBuffer* str, OpcodeSignatureType sig_type, Instr::Op* op);
StringBuffer* str, OpcodeSignatureType sig_type, Instr::Op* op);
Value* AllocValue(TypeName type = INT64_TYPE); Value* AllocValue(TypeName type = INT64_TYPE);
Value* CloneValue(Value* source); Value* CloneValue(Value* source);
@ -226,11 +220,10 @@ private:
Block* AppendBlock(); Block* AppendBlock();
void EndBlock(); void EndBlock();
bool IsUnconditionalJump(Instr* instr); bool IsUnconditionalJump(Instr* instr);
Instr* AppendInstr(const OpcodeInfo& opcode, uint16_t flags, Instr* AppendInstr(const OpcodeInfo& opcode, uint16_t flags, Value* dest = 0);
Value* dest = 0);
Value* CompareXX(const OpcodeInfo& opcode, Value* value1, Value* value2); Value* CompareXX(const OpcodeInfo& opcode, Value* value1, Value* value2);
Value* VectorCompareXX( Value* VectorCompareXX(const OpcodeInfo& opcode, Value* value1, Value* value2,
const OpcodeInfo& opcode, Value* value1, Value* value2, TypeName part_type); TypeName part_type);
protected: protected:
Arena* arena_; Arena* arena_;
@ -247,9 +240,7 @@ protected:
Block* current_block_; Block* current_block_;
}; };
} // namespace hir } // namespace hir
} // namespace alloy } // namespace alloy
#endif // ALLOY_HIR_HIR_BUILDER_H_ #endif // ALLOY_HIR_HIR_BUILDER_H_

View File

@ -11,9 +11,8 @@
#include <alloy/hir/block.h> #include <alloy/hir/block.h>
using namespace alloy; namespace alloy {
using namespace alloy::hir; namespace hir {
void Instr::set_src1(Value* value) { void Instr::set_src1(Value* value) {
if (src1.value == value) { if (src1.value == value) {
@ -114,3 +113,6 @@ void Instr::Remove() {
block->instr_tail = prev; block->instr_tail = prev;
} }
} }
} // namespace hir
} // namespace alloy

View File

@ -14,9 +14,11 @@
#include <alloy/hir/opcodes.h> #include <alloy/hir/opcodes.h>
#include <alloy/hir/value.h> #include <alloy/hir/value.h>
namespace alloy {
namespace alloy { namespace runtime { class FunctionInfo; } } namespace runtime {
class FunctionInfo;
} // namespace runtime
} // namespace alloy
namespace alloy { namespace alloy {
namespace hir { namespace hir {
@ -59,9 +61,7 @@ public:
void Remove(); void Remove();
}; };
} // namespace hir } // namespace hir
} // namespace alloy } // namespace alloy
#endif // ALLOY_HIR_INSTR_H_ #endif // ALLOY_HIR_INSTR_H_

View File

@ -12,13 +12,11 @@
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
namespace hir { namespace hir {
class Block; class Block;
class Label { class Label {
public: public:
Block* block; Block* block;
@ -31,9 +29,7 @@ public:
void* tag; void* tag;
}; };
} // namespace hir } // namespace hir
} // namespace alloy } // namespace alloy
#endif // ALLOY_HIR_LABEL_H_ #endif // ALLOY_HIR_LABEL_H_

View File

@ -9,15 +9,13 @@
#include <alloy/hir/opcodes.h> #include <alloy/hir/opcodes.h>
using namespace alloy;
using namespace alloy::hir;
namespace alloy { namespace alloy {
namespace hir { namespace hir {
#define DEFINE_OPCODE(num, name, sig, flags) \ #define DEFINE_OPCODE(num, name, sig, flags) \
static const OpcodeInfo num##_info = { flags, sig, name, num, }; static const OpcodeInfo num##_info = { \
flags, sig, name, num, \
};
#include <alloy/hir/opcodes.inl> #include <alloy/hir/opcodes.inl>
#undef DEFINE_OPCODE #undef DEFINE_OPCODE

View File

@ -12,11 +12,9 @@
#include <alloy/core.h> #include <alloy/core.h>
namespace alloy { namespace alloy {
namespace hir { namespace hir {
enum CallFlags { enum CallFlags {
CALL_TAIL = (1 << 1), CALL_TAIL = (1 << 1),
CALL_POSSIBLE_RETURN = (1 << 2), CALL_POSSIBLE_RETURN = (1 << 2),
@ -56,11 +54,8 @@ enum ArithmeticFlags {
enum Permutes { enum Permutes {
PERMUTE_XY_ZW = 0x00010405, PERMUTE_XY_ZW = 0x00010405,
}; };
#define SWIZZLE_MASK(x, y, z, w) ( \ #define SWIZZLE_MASK(x, y, z, w) \
(((x) & 0x3) << 6) | \ ((((x)&0x3) << 6) | (((y)&0x3) << 4) | (((z)&0x3) << 2) | (((w)&0x3)))
(((y) & 0x3) << 4) | \
(((z) & 0x3) << 2) | \
(((w) & 0x3)))
enum Swizzles { enum Swizzles {
SWIZZLE_XYZW_TO_XYZW = SWIZZLE_MASK(0, 1, 2, 3), SWIZZLE_XYZW_TO_XYZW = SWIZZLE_MASK(0, 1, 2, 3),
SWIZZLE_XYZW_TO_YZWX = SWIZZLE_MASK(1, 2, 3, 0), SWIZZLE_XYZW_TO_YZWX = SWIZZLE_MASK(1, 2, 3, 0),
@ -78,19 +73,14 @@ enum PackType {
PACK_TYPE_S16_IN_32_HI = 7, PACK_TYPE_S16_IN_32_HI = 7,
}; };
enum Opcode { enum Opcode {
OPCODE_COMMENT, OPCODE_COMMENT,
OPCODE_NOP, OPCODE_NOP,
OPCODE_SOURCE_OFFSET, OPCODE_SOURCE_OFFSET,
OPCODE_DEBUG_BREAK, OPCODE_DEBUG_BREAK,
OPCODE_DEBUG_BREAK_TRUE, OPCODE_DEBUG_BREAK_TRUE,
OPCODE_TRAP, OPCODE_TRAP,
OPCODE_TRAP_TRUE, OPCODE_TRAP_TRUE,
OPCODE_CALL, OPCODE_CALL,
OPCODE_CALL_TRUE, OPCODE_CALL_TRUE,
OPCODE_CALL_INDIRECT, OPCODE_CALL_INDIRECT,
@ -99,11 +89,9 @@ enum Opcode {
OPCODE_RETURN, OPCODE_RETURN,
OPCODE_RETURN_TRUE, OPCODE_RETURN_TRUE,
OPCODE_SET_RETURN_ADDRESS, OPCODE_SET_RETURN_ADDRESS,
OPCODE_BRANCH, OPCODE_BRANCH,
OPCODE_BRANCH_TRUE, OPCODE_BRANCH_TRUE,
OPCODE_BRANCH_FALSE, OPCODE_BRANCH_FALSE,
OPCODE_ASSIGN, OPCODE_ASSIGN,
OPCODE_CAST, OPCODE_CAST,
OPCODE_ZERO_EXTEND, OPCODE_ZERO_EXTEND,
@ -113,22 +101,16 @@ enum Opcode {
OPCODE_ROUND, OPCODE_ROUND,
OPCODE_VECTOR_CONVERT_I2F, OPCODE_VECTOR_CONVERT_I2F,
OPCODE_VECTOR_CONVERT_F2I, OPCODE_VECTOR_CONVERT_F2I,
OPCODE_LOAD_VECTOR_SHL, OPCODE_LOAD_VECTOR_SHL,
OPCODE_LOAD_VECTOR_SHR, OPCODE_LOAD_VECTOR_SHR,
OPCODE_LOAD_CLOCK, OPCODE_LOAD_CLOCK,
OPCODE_LOAD_LOCAL, OPCODE_LOAD_LOCAL,
OPCODE_STORE_LOCAL, OPCODE_STORE_LOCAL,
OPCODE_LOAD_CONTEXT, OPCODE_LOAD_CONTEXT,
OPCODE_STORE_CONTEXT, OPCODE_STORE_CONTEXT,
OPCODE_LOAD, OPCODE_LOAD,
OPCODE_STORE, OPCODE_STORE,
OPCODE_PREFETCH, OPCODE_PREFETCH,
OPCODE_MAX, OPCODE_MAX,
OPCODE_MIN, OPCODE_MIN,
OPCODE_SELECT, OPCODE_SELECT,
@ -152,7 +134,6 @@ enum Opcode {
OPCODE_VECTOR_COMPARE_SGE, OPCODE_VECTOR_COMPARE_SGE,
OPCODE_VECTOR_COMPARE_UGT, OPCODE_VECTOR_COMPARE_UGT,
OPCODE_VECTOR_COMPARE_UGE, OPCODE_VECTOR_COMPARE_UGE,
OPCODE_ADD, OPCODE_ADD,
OPCODE_ADD_CARRY, OPCODE_ADD_CARRY,
OPCODE_VECTOR_ADD, OPCODE_VECTOR_ADD,
@ -170,7 +151,6 @@ enum Opcode {
OPCODE_LOG2, OPCODE_LOG2,
OPCODE_DOT_PRODUCT_3, OPCODE_DOT_PRODUCT_3,
OPCODE_DOT_PRODUCT_4, OPCODE_DOT_PRODUCT_4,
OPCODE_AND, OPCODE_AND,
OPCODE_OR, OPCODE_OR,
OPCODE_XOR, OPCODE_XOR,
@ -191,12 +171,10 @@ enum Opcode {
OPCODE_SWIZZLE, OPCODE_SWIZZLE,
OPCODE_PACK, OPCODE_PACK,
OPCODE_UNPACK, OPCODE_UNPACK,
OPCODE_COMPARE_EXCHANGE, OPCODE_COMPARE_EXCHANGE,
OPCODE_ATOMIC_EXCHANGE, OPCODE_ATOMIC_EXCHANGE,
OPCODE_ATOMIC_ADD, OPCODE_ATOMIC_ADD,
OPCODE_ATOMIC_SUB, OPCODE_ATOMIC_SUB,
__OPCODE_MAX_VALUE, // Keep at end. __OPCODE_MAX_VALUE, // Keep at end.
}; };
@ -223,23 +201,35 @@ enum OpcodeSignature {
OPCODE_SIG_X = (OPCODE_SIG_TYPE_X), OPCODE_SIG_X = (OPCODE_SIG_TYPE_X),
OPCODE_SIG_X_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_L << 3), OPCODE_SIG_X_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_L << 3),
OPCODE_SIG_X_O = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3), OPCODE_SIG_X_O = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3),
OPCODE_SIG_X_O_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3) | (OPCODE_SIG_TYPE_V << 6), OPCODE_SIG_X_O_V =
(OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_O << 3) | (OPCODE_SIG_TYPE_V << 6),
OPCODE_SIG_X_S = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_S << 3), OPCODE_SIG_X_S = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_S << 3),
OPCODE_SIG_X_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3), OPCODE_SIG_X_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3),
OPCODE_SIG_X_V_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_L << 6), OPCODE_SIG_X_V_L =
OPCODE_SIG_X_V_L_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_L << 6) | (OPCODE_SIG_TYPE_L << 9), (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_L << 6),
OPCODE_SIG_X_V_O = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6), OPCODE_SIG_X_V_L_L = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) |
OPCODE_SIG_X_V_S = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_S << 6), (OPCODE_SIG_TYPE_L << 6) | (OPCODE_SIG_TYPE_L << 9),
OPCODE_SIG_X_V_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6), OPCODE_SIG_X_V_O =
OPCODE_SIG_X_V_V_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9), (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6),
OPCODE_SIG_X_V_S =
(OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_S << 6),
OPCODE_SIG_X_V_V =
(OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6),
OPCODE_SIG_X_V_V_V = (OPCODE_SIG_TYPE_X) | (OPCODE_SIG_TYPE_V << 3) |
(OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9),
OPCODE_SIG_V = (OPCODE_SIG_TYPE_V), OPCODE_SIG_V = (OPCODE_SIG_TYPE_V),
OPCODE_SIG_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_O << 3), OPCODE_SIG_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_O << 3),
OPCODE_SIG_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3), OPCODE_SIG_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3),
OPCODE_SIG_V_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6), OPCODE_SIG_V_V_O =
OPCODE_SIG_V_V_O_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6) | (OPCODE_SIG_TYPE_V << 9), (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_O << 6),
OPCODE_SIG_V_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6), OPCODE_SIG_V_V_O_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) |
OPCODE_SIG_V_V_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_O << 9), (OPCODE_SIG_TYPE_O << 6) | (OPCODE_SIG_TYPE_V << 9),
OPCODE_SIG_V_V_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9), OPCODE_SIG_V_V_V =
(OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) | (OPCODE_SIG_TYPE_V << 6),
OPCODE_SIG_V_V_V_O = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) |
(OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_O << 9),
OPCODE_SIG_V_V_V_V = (OPCODE_SIG_TYPE_V) | (OPCODE_SIG_TYPE_V << 3) |
(OPCODE_SIG_TYPE_V << 6) | (OPCODE_SIG_TYPE_V << 9),
}; };
#define GET_OPCODE_SIG_TYPE_DEST(sig) (OpcodeSignatureType)(sig & 0x7) #define GET_OPCODE_SIG_TYPE_DEST(sig) (OpcodeSignatureType)(sig & 0x7)
@ -254,15 +244,11 @@ typedef struct {
Opcode num; Opcode num;
} OpcodeInfo; } OpcodeInfo;
#define DEFINE_OPCODE(num, name, sig, flags) extern const OpcodeInfo num##_info;
#define DEFINE_OPCODE(num, name, sig, flags) \
extern const OpcodeInfo num##_info;
#include <alloy/hir/opcodes.inl> #include <alloy/hir/opcodes.inl>
#undef DEFINE_OPCODE #undef DEFINE_OPCODE
} // namespace hir } // namespace hir
} // namespace alloy } // namespace alloy
#endif // ALLOY_HIR_OPCODES_H_ #endif // ALLOY_HIR_OPCODES_H_

View File

@ -13,13 +13,11 @@
#include <alloy/tracing/tracing.h> #include <alloy/tracing/tracing.h>
#include <alloy/tracing/event_type.h> #include <alloy/tracing/event_type.h>
namespace alloy { namespace alloy {
namespace hir { namespace hir {
const uint32_t ALLOY_HIR = alloy::tracing::EventType::ALLOY_HIR; const uint32_t ALLOY_HIR = alloy::tracing::EventType::ALLOY_HIR;
class EventType { class EventType {
public: public:
enum { enum {
@ -27,9 +25,7 @@ public:
}; };
}; };
} // namespace hir } // namespace hir
} // namespace alloy } // namespace alloy
#endif // ALLOY_HIR_TRACING_H_ #endif // ALLOY_HIR_TRACING_H_

View File

@ -9,9 +9,8 @@
#include <alloy/hir/value.h> #include <alloy/hir/value.h>
using namespace alloy; namespace alloy {
using namespace alloy::hir; namespace hir {
Value::Use* Value::AddUse(Arena* arena, Instr* instr) { Value::Use* Value::AddUse(Arena* arena, Instr* instr) {
Use* use = arena->Alloc<Use>(); Use* use = arena->Alloc<Use>();
@ -600,3 +599,6 @@ bool Value::Compare(Opcode opcode, Value* other) {
XEASSERTALWAYS(); XEASSERTALWAYS();
return false; return false;
} }
} // namespace hir
} // namespace alloy

Some files were not shown because too many files have changed in this diff Show More