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

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

View File

@@ -12,13 +12,11 @@
#include <alloy/core.h>
namespace alloy {
namespace frontend {
class ContextInfo {
public:
public:
ContextInfo(size_t size, uintptr_t thread_state_offset);
~ContextInfo();
@@ -26,14 +24,12 @@ public:
uintptr_t thread_state_offset() const { return thread_state_offset_; }
private:
private:
size_t size_;
uintptr_t thread_state_offset_;
};
} // namespace frontend
} // namespace alloy
#endif // ALLOY_FRONTEND_CONTEXT_INFO_H_

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,25 +13,21 @@
#include <alloy/frontend/ppc/ppc_emit.h>
#include <alloy/frontend/ppc/ppc_instr.h>
namespace alloy {
namespace frontend {
namespace ppc {
#define XEEMITTER(name, opcode, format) int InstrEmit_##name
#define XEREGISTERINSTR(name, opcode) \
RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name);
RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name);
#define XEINSTRNOTIMPLEMENTED()
//#define XEINSTRNOTIMPLEMENTED XEASSERTALWAYS
//#define XEINSTRNOTIMPLEMENTED() __debugbreak()
} // namespace ppc
} // namespace frontend
} // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_EMIT_PRIVATE_H_

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -12,21 +12,19 @@
#include <alloy/frontend/ppc/ppc_context.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 frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
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) {
using alloy::hir::Label;
using alloy::hir::Value;
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;
// TODO(benvanik): this may be wrong and overwrite LRs when not desired!
@@ -54,8 +52,7 @@ int InstrEmit_branch(
// recursion.
uint64_t nia_value = nia->AsUint64() & 0xFFFFFFFF;
bool is_recursion = false;
if (nia_value == f.symbol_info()->address() &&
lk) {
if (nia_value == f.symbol_info()->address() && lk) {
is_recursion = true;
}
Label* label = is_recursion ? NULL : f.LookupLabel(nia_value);
@@ -73,7 +70,7 @@ int InstrEmit_branch(
}
} else {
// Call function.
FunctionInfo* symbol_info = f.LookupFunction(nia_value);
auto symbol_info = f.LookupFunction(nia_value);
if (cond) {
if (!expect_true) {
cond = f.IsFalse(cond);
@@ -84,27 +81,27 @@ int InstrEmit_branch(
}
}
} else {
// Indirect branch to pointer.
// Indirect branch to pointer.
// TODO(benvanik): runtime recursion detection?
// TODO(benvanik): runtime recursion detection?
// TODO(benvanik): run a DFA pass to see if we can detect whether this is
// a normal function return that is pulling the LR from the stack that
// it set in the prolog. If so, we can omit the dynamic check!
// TODO(benvanik): run a DFA pass to see if we can detect whether this is
// a normal function return that is pulling the LR from the stack that
// it set in the prolog. If so, we can omit the dynamic check!
//// Dynamic test when branching to LR, which is usually used for the return.
//// We only do this if LK=0 as returns wouldn't set LR.
//// Ideally it's a return and we can just do a simple ret and be done.
//// If it's not, we fall through to the full indirection logic.
//if (!lk && reg == kXEPPCRegLR) {
// // The return block will spill registers for us.
// // TODO(benvanik): 'lr_mismatch' debug info.
// // Note: we need to test on *only* the 32-bit target, as the target ptr may
// // have garbage in the upper 32 bits.
// c.cmp(target.r32(), c.getGpArg(1).r32());
// // TODO(benvanik): evaluate hint here.
// c.je(e.GetReturnLabel(), kCondHintLikely);
//}
//// Dynamic test when branching to LR, which is usually used for the return.
//// We only do this if LK=0 as returns wouldn't set LR.
//// Ideally it's a return and we can just do a simple ret and be done.
//// If it's not, we fall through to the full indirection logic.
// if (!lk && reg == kXEPPCRegLR) {
// // The return block will spill registers for us.
// // TODO(benvanik): 'lr_mismatch' debug info.
// // Note: we need to test on *only* the 32-bit target, as the target ptr may
// // have garbage in the upper 32 bits.
// c.cmp(target.r32(), c.getGpArg(1).r32());
// // TODO(benvanik): evaluate hint here.
// c.je(e.GetReturnLabel(), kCondHintLikely);
//}
#if 0
// This breaks longjump, as that uses blr with a non-return lr.
// It'd be nice to move SET_RETURN_ADDRESS semantics up into context
@@ -124,27 +121,26 @@ int InstrEmit_branch(
#else
{
#endif
// Jump to pointer.
bool likely_return = !lk && nia_is_lr;
if (likely_return) {
call_flags |= CALL_POSSIBLE_RETURN;
}
if (cond) {
if (!expect_true) {
cond = f.IsFalse(cond);
}
f.CallIndirectTrue(cond, nia, call_flags);
} else {
f.CallIndirect(nia, call_flags);
// Jump to pointer.
bool likely_return = !lk && nia_is_lr;
if (likely_return) {
call_flags |= CALL_POSSIBLE_RETURN;
}
if (cond) {
if (!expect_true) {
cond = f.IsFalse(cond);
}
f.CallIndirectTrue(cond, nia, call_flags);
} else {
f.CallIndirect(nia, call_flags);
}
}
return 0;
}
return 0;
}
XEEMITTER(bx, 0x48000000, I )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(bx, 0x48000000, I)(PPCHIRBuilder& f, InstrData& i) {
// if AA then
// NIA <- EXTS(LI || 0b00)
// else
@@ -159,11 +155,10 @@ XEEMITTER(bx, 0x48000000, I )(PPCHIRBuilder& f, InstrData& i) {
nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2));
}
return InstrEmit_branch(
f, "bx", i.address, f.LoadConstant(nia), i.I.LK);
return InstrEmit_branch(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) {
// if ¬BO[2] then
// CTR <- CTR - 1
// ctr_ok <- BO[2] | ((CTR[0:63] != 0) XOR BO[3])
@@ -236,11 +231,11 @@ XEEMITTER(bcx, 0x40000000, B )(PPCHIRBuilder& f, InstrData& i) {
} else {
nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2));
}
return InstrEmit_branch(
f, "bcx", i.address, f.LoadConstant(nia), i.B.LK, ok, expect_true);
return InstrEmit_branch(f, "bcx", i.address, f.LoadConstant(nia), i.B.LK, ok,
expect_true);
}
XEEMITTER(bcctrx, 0x4C000420, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(bcctrx, 0x4C000420, XL)(PPCHIRBuilder& f, InstrData& i) {
// cond_ok <- BO[0] | (CR[BI+32] ≡ BO[1])
// if cond_ok then
// NIA <- CTR[0:61] || 0b00
@@ -268,11 +263,11 @@ XEEMITTER(bcctrx, 0x4C000420, XL )(PPCHIRBuilder& f, InstrData& i) {
}
bool expect_true = !not_cond_ok;
return InstrEmit_branch(
f, "bcctrx", i.address, f.LoadCTR(), i.XL.LK, cond_ok, expect_true);
return InstrEmit_branch(f, "bcctrx", i.address, f.LoadCTR(), i.XL.LK, cond_ok,
expect_true);
}
XEEMITTER(bclrx, 0x4C000020, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(bclrx, 0x4C000020, XL)(PPCHIRBuilder& f, InstrData& i) {
// if ¬BO[2] then
// CTR <- CTR - 1
// ctr_ok <- BO[2] | ((CTR[0:63] != 0) XOR BO[3]
@@ -336,71 +331,68 @@ XEEMITTER(bclrx, 0x4C000020, XL )(PPCHIRBuilder& f, InstrData& i) {
expect_true = !not_cond_ok;
}
return InstrEmit_branch(
f, "bclrx", i.address, f.LoadLR(), i.XL.LK, ok, expect_true, true);
return InstrEmit_branch(f, "bclrx", i.address, f.LoadLR(), i.XL.LK, ok,
expect_true, true);
}
// Condition register logical (A-23)
XEEMITTER(crand, 0x4C000202, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(crand, 0x4C000202, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(crandc, 0x4C000102, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(crandc, 0x4C000102, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(creqv, 0x4C000242, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(creqv, 0x4C000242, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(crnand, 0x4C0001C2, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(crnand, 0x4C0001C2, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(crnor, 0x4C000042, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(crnor, 0x4C000042, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(cror, 0x4C000382, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(cror, 0x4C000382, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(crorc, 0x4C000342, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(crorc, 0x4C000342, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(crxor, 0x4C000182, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(crxor, 0x4C000182, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mcrf, 0x4C000000, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mcrf, 0x4C000000, XL)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// System linkage (A-24)
XEEMITTER(sc, 0x44000002, SC )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(sc, 0x44000002, SC)(PPCHIRBuilder& f, InstrData& i) {
f.CallExtern(f.symbol_info());
return 0;
}
// Trap (A-25)
int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i,
Value* va, Value* vb, uint32_t TO) {
int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i, Value* va, Value* vb,
uint32_t TO) {
// if (a < b) & TO[0] then TRAP
// if (a > b) & TO[1] then TRAP
// if (a = b) & TO[2] then TRAP
@@ -435,7 +427,7 @@ int InstrEmit_trap(PPCHIRBuilder& f, InstrData& i,
return 0;
}
XEEMITTER(td, 0x7C000088, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(td, 0x7C000088, X)(PPCHIRBuilder& f, InstrData& i) {
// a <- (RA)
// b <- (RB)
// if (a < b) & TO[0] then TRAP
@@ -448,7 +440,7 @@ XEEMITTER(td, 0x7C000088, X )(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_trap(f, i, ra, rb, i.X.RT);
}
XEEMITTER(tdi, 0x08000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(tdi, 0x08000000, D)(PPCHIRBuilder& f, InstrData& i) {
// a <- (RA)
// if (a < EXTS(SI)) & TO[0] then TRAP
// if (a > EXTS(SI)) & TO[1] then TRAP
@@ -460,7 +452,7 @@ XEEMITTER(tdi, 0x08000000, D )(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_trap(f, i, ra, rb, i.D.RT);
}
XEEMITTER(tw, 0x7C000008, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(tw, 0x7C000008, X)(PPCHIRBuilder& f, InstrData& i) {
// a <- EXTS((RA)[32:63])
// b <- EXTS((RB)[32:63])
// if (a < b) & TO[0] then TRAP
@@ -468,14 +460,14 @@ XEEMITTER(tw, 0x7C000008, X )(PPCHIRBuilder& f, InstrData& i) {
// if (a = b) & TO[2] then TRAP
// if (a <u b) & TO[3] then TRAP
// if (a >u b) & TO[4] then TRAP
Value* ra = f.SignExtend(f.Truncate(
f.LoadGPR(i.X.RA), INT32_TYPE), INT64_TYPE);
Value* rb = f.SignExtend(f.Truncate(
f.LoadGPR(i.X.RB), INT32_TYPE), INT64_TYPE);
Value* ra =
f.SignExtend(f.Truncate(f.LoadGPR(i.X.RA), INT32_TYPE), INT64_TYPE);
Value* rb =
f.SignExtend(f.Truncate(f.LoadGPR(i.X.RB), INT32_TYPE), INT64_TYPE);
return InstrEmit_trap(f, i, ra, rb, i.X.RT);
}
XEEMITTER(twi, 0x0C000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(twi, 0x0C000000, D)(PPCHIRBuilder& f, InstrData& i) {
// a <- EXTS((RA)[32:63])
// if (a < EXTS(SI)) & TO[0] then TRAP
// if (a > EXTS(SI)) & TO[1] then TRAP
@@ -488,21 +480,20 @@ XEEMITTER(twi, 0x0C000000, D )(PPCHIRBuilder& f, InstrData& i) {
f.Trap(type);
return 0;
}
Value* ra = f.SignExtend(f.Truncate(
f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE);
Value* ra =
f.SignExtend(f.Truncate(f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE);
Value* rb = f.LoadConstant(XEEXTS16(i.D.DS));
return InstrEmit_trap(f, i, ra, rb, i.D.RT);
}
// Processor control (A-26)
XEEMITTER(mfcr, 0x7C000026, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mfcr, 0x7C000026, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
// n <- spr[5:9] || spr[0:4]
// if length(SPR(n)) = 64 then
// RT <- SPR(n)
@@ -511,40 +502,40 @@ XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
Value* v;
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
switch (n) {
case 1:
// XER
v = f.LoadXER();
break;
case 8:
// LR
v = f.LoadLR();
break;
case 9:
// CTR
v = f.LoadCTR();
break;
// 268 + 269 = TB + TBU
default:
XEINSTRNOTIMPLEMENTED();
return 1;
case 1:
// XER
v = f.LoadXER();
break;
case 8:
// LR
v = f.LoadLR();
break;
case 9:
// CTR
v = f.LoadCTR();
break;
// 268 + 269 = TB + TBU
default:
XEINSTRNOTIMPLEMENTED();
return 1;
}
f.StoreGPR(i.XFX.RT, v);
return 0;
}
XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) {
Value* time = f.LoadClock();
f.StoreGPR(i.XFX.RT, time);
return 0;
}
XEEMITTER(mtcrf, 0x7C000120, XFX)(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mtcrf, 0x7C000120, XFX)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
// n <- spr[5:9] || spr[0:4]
// if length(SPR(n)) = 64 then
// SPR(n) <- (RS)
@@ -555,21 +546,21 @@ XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
switch (n) {
case 1:
// XER
f.StoreXER(rt);
break;
case 8:
// LR
f.StoreLR(rt);
break;
case 9:
// CTR
f.StoreCTR(rt);
break;
default:
XEINSTRNOTIMPLEMENTED();
return 1;
case 1:
// XER
f.StoreXER(rt);
break;
case 8:
// LR
f.StoreLR(rt);
break;
case 9:
// CTR
f.StoreCTR(rt);
break;
default:
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
@@ -578,52 +569,50 @@ XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
// TODO(benvanik): MSR is used for toggling interrupts, and it'd be nice to
// obey that setting. It's usually guarding atomic stores.
XEEMITTER(mfmsr, 0x7C0000A6, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mfmsr, 0x7C0000A6, X)(PPCHIRBuilder& f, InstrData& i) {
f.Nop();
return 0;
}
XEEMITTER(mtmsr, 0x7C000124, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mtmsr, 0x7C000124, X)(PPCHIRBuilder& f, InstrData& i) {
f.Nop();
return 0;
}
XEEMITTER(mtmsrd, 0x7C000164, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mtmsrd, 0x7C000164, X)(PPCHIRBuilder& f, InstrData& i) {
f.Nop();
return 0;
}
void RegisterEmitCategoryControl() {
XEREGISTERINSTR(bx, 0x48000000);
XEREGISTERINSTR(bcx, 0x40000000);
XEREGISTERINSTR(bcctrx, 0x4C000420);
XEREGISTERINSTR(bclrx, 0x4C000020);
XEREGISTERINSTR(crand, 0x4C000202);
XEREGISTERINSTR(crandc, 0x4C000102);
XEREGISTERINSTR(creqv, 0x4C000242);
XEREGISTERINSTR(crnand, 0x4C0001C2);
XEREGISTERINSTR(crnor, 0x4C000042);
XEREGISTERINSTR(cror, 0x4C000382);
XEREGISTERINSTR(crorc, 0x4C000342);
XEREGISTERINSTR(crxor, 0x4C000182);
XEREGISTERINSTR(mcrf, 0x4C000000);
XEREGISTERINSTR(sc, 0x44000002);
XEREGISTERINSTR(td, 0x7C000088);
XEREGISTERINSTR(tdi, 0x08000000);
XEREGISTERINSTR(tw, 0x7C000008);
XEREGISTERINSTR(twi, 0x0C000000);
XEREGISTERINSTR(mfcr, 0x7C000026);
XEREGISTERINSTR(mfspr, 0x7C0002A6);
XEREGISTERINSTR(mftb, 0x7C0002E6);
XEREGISTERINSTR(mtcrf, 0x7C000120);
XEREGISTERINSTR(mtspr, 0x7C0003A6);
XEREGISTERINSTR(mfmsr, 0x7C0000A6);
XEREGISTERINSTR(mtmsr, 0x7C000124);
XEREGISTERINSTR(mtmsrd, 0x7C000164);
XEREGISTERINSTR(bx, 0x48000000);
XEREGISTERINSTR(bcx, 0x40000000);
XEREGISTERINSTR(bcctrx, 0x4C000420);
XEREGISTERINSTR(bclrx, 0x4C000020);
XEREGISTERINSTR(crand, 0x4C000202);
XEREGISTERINSTR(crandc, 0x4C000102);
XEREGISTERINSTR(creqv, 0x4C000242);
XEREGISTERINSTR(crnand, 0x4C0001C2);
XEREGISTERINSTR(crnor, 0x4C000042);
XEREGISTERINSTR(cror, 0x4C000382);
XEREGISTERINSTR(crorc, 0x4C000342);
XEREGISTERINSTR(crxor, 0x4C000182);
XEREGISTERINSTR(mcrf, 0x4C000000);
XEREGISTERINSTR(sc, 0x44000002);
XEREGISTERINSTR(td, 0x7C000088);
XEREGISTERINSTR(tdi, 0x08000000);
XEREGISTERINSTR(tw, 0x7C000008);
XEREGISTERINSTR(twi, 0x0C000000);
XEREGISTERINSTR(mfcr, 0x7C000026);
XEREGISTERINSTR(mfspr, 0x7C0002A6);
XEREGISTERINSTR(mftb, 0x7C0002E6);
XEREGISTERINSTR(mtcrf, 0x7C000120);
XEREGISTERINSTR(mtspr, 0x7C0003A6);
XEREGISTERINSTR(mfmsr, 0x7C0000A6);
XEREGISTERINSTR(mtmsr, 0x7C000124);
XEREGISTERINSTR(mtmsrd, 0x7C000164);
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@@ -12,148 +12,145 @@
#include <alloy/frontend/ppc/ppc_context.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 frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using alloy::hir::RoundMode;
using alloy::hir::Value;
// Good source of information:
// http://mamedev.org/source/src/emu/cpu/powerpc/ppc_ops.c
// The correctness of that code is not reflected here yet -_-
// Enable rounding numbers to single precision as required.
// This adds a bunch of work per operation and I'm not sure it's required.
#define ROUND_TO_SINGLE
// Floating-point arithmetic (A-8)
XEEMITTER(faddx, 0xFC00002A, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(faddx, 0xFC00002A, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA) + (frB)
Value* v = f.Add(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(faddsx, 0xEC00002A, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(faddsx, 0xEC00002A, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA) + (frB)
Value* v = f.Add(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fdivx, 0xFC000024, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fdivx, 0xFC000024, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- frA / frB
Value* v = f.Div(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fdivsx, 0xEC000024, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fdivsx, 0xEC000024, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- frA / frB
Value* v = f.Div(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fmulx, 0xFC000032, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmulx, 0xFC000032, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA) x (frC)
Value* v = f.Mul(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fmulsx, 0xEC000032, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmulsx, 0xEC000032, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA) x (frC)
Value* v = f.Mul(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fresx, 0xEC000030, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fresx, 0xEC000030, A)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(frsqrtex, 0xFC000034, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(frsqrtex, 0xFC000034, A)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(fsubx, 0xFC000028, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fsubx, 0xFC000028, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA) - (frB)
Value* v = f.Sub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fsubsx, 0xEC000028, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fsubsx, 0xEC000028, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA) - (frB)
Value* v = f.Sub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fselx, 0xFC00002E, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fselx, 0xFC00002E, A)(PPCHIRBuilder& f, InstrData& i) {
// if (frA) >= 0.0
// then frD <- (frC)
// else frD <- (frB)
@@ -161,28 +158,28 @@ XEEMITTER(fselx, 0xFC00002E, A )(PPCHIRBuilder& f, InstrData& i) {
Value* v = f.Select(ge, f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fsqrtx, 0xFC00002C, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fsqrtx, 0xFC00002C, A)(PPCHIRBuilder& f, InstrData& i) {
// Double precision:
// frD <- sqrt(frB)
Value* v = f.Sqrt(f.LoadFPR(i.A.FRA));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fsqrtsx, 0xEC00002C, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fsqrtsx, 0xEC00002C, A)(PPCHIRBuilder& f, InstrData& i) {
// Single precision:
// frD <- sqrt(frB)
Value* v = f.Sqrt(f.LoadFPR(i.A.FRA));
@@ -190,144 +187,128 @@ XEEMITTER(fsqrtsx, 0xEC00002C, A )(PPCHIRBuilder& f, InstrData& i) {
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
// 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
Value* v = f.MulAdd(
f.LoadFPR(i.A.FRA),
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB));
Value* v =
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fmaddsx, 0xEC00003A, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmaddsx, 0xEC00003A, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA x frC) + frB
Value* v = f.MulAdd(
f.LoadFPR(i.A.FRA),
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB));
Value* v =
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fmsubx, 0xFC000038, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmsubx, 0xFC000038, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA x frC) - frB
Value* v = f.MulSub(
f.LoadFPR(i.A.FRA),
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB));
Value* v =
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fmsubsx, 0xEC000038, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmsubsx, 0xEC000038, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frA x frC) - frB
Value* v = f.MulSub(
f.LoadFPR(i.A.FRA),
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB));
Value* v =
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fnmaddx, 0xFC00003E, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnmaddx, 0xFC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(fnmaddsx, 0xEC00003E, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnmaddsx, 0xEC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(fnmsubx, 0xFC00003C, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnmsubx, 0xFC00003C, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- -([frA x frC] - frB)
Value* v = f.Neg(f.MulSub(
f.LoadFPR(i.A.FRA),
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB)));
Value* v = f.Neg(
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fnmsubsx, 0xEC00003C, A )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnmsubsx, 0xEC00003C, A)(PPCHIRBuilder& f, InstrData& i) {
// frD <- -([frA x frC] - frB)
Value* v = f.Neg(f.MulSub(
f.LoadFPR(i.A.FRA),
f.LoadFPR(i.A.FRC),
f.LoadFPR(i.A.FRB)));
Value* v = f.Neg(
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
// 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 )
Value* v = f.Convert(
f.Cast(f.LoadFPR(i.A.FRB), INT64_TYPE),
FLOAT64_TYPE);
Value* v = f.Convert(f.Cast(f.LoadFPR(i.A.FRB), INT64_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.A.FRT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fctidx, 0xFC00065C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fctidx, 0xFC00065C, X)(PPCHIRBuilder& f, InstrData& i) {
// frD <- double_to_signed_int64( frB )
// TODO(benvanik): pull from FPSCR[RN]
RoundMode round_mode = ROUND_TO_ZERO;
@@ -336,19 +317,19 @@ XEEMITTER(fctidx, 0xFC00065C, X )(PPCHIRBuilder& f, InstrData& i) {
f.StoreFPR(i.X.RT, v);
// f.UpdateFPRF(v);
if (i.X.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fctidzx, 0xFC00065E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fctidzx, 0xFC00065E, X)(PPCHIRBuilder& f, InstrData& i) {
// TODO(benvanik): assuming round to zero is always set, is that ok?
return InstrEmit_fctidx(f, i);
}
XEEMITTER(fctiwx, 0xFC00001C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fctiwx, 0xFC00001C, X)(PPCHIRBuilder& f, InstrData& i) {
// frD <- double_to_signed_int32( frB )
// TODO(benvanik): pull from FPSCR[RN]
RoundMode round_mode = ROUND_TO_ZERO;
@@ -357,19 +338,19 @@ XEEMITTER(fctiwx, 0xFC00001C, X )(PPCHIRBuilder& f, InstrData& i) {
f.StoreFPR(i.X.RT, v);
// f.UpdateFPRF(v);
if (i.A.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fctiwzx, 0xFC00001E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fctiwzx, 0xFC00001E, X)(PPCHIRBuilder& f, InstrData& i) {
// TODO(benvanik): assuming round to zero is always set, is that ok?
return InstrEmit_fctiwx(f, i);
}
XEEMITTER(frspx, 0xFC000018, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(frspx, 0xFC000018, X)(PPCHIRBuilder& f, InstrData& i) {
// frD <- Round_single(frB)
// TODO(benvanik): pull from FPSCR[RN]
RoundMode round_mode = ROUND_TO_ZERO;
@@ -378,14 +359,13 @@ XEEMITTER(frspx, 0xFC000018, X )(PPCHIRBuilder& f, InstrData& i) {
f.StoreFPR(i.X.RT, v);
// f.UpdateFPRF(v);
if (i.X.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
// Floating-point compare (A-11)
int InstrEmit_fcmpx_(PPCHIRBuilder& f, InstrData& i, bool ordered) {
@@ -410,22 +390,21 @@ int InstrEmit_fcmpx_(PPCHIRBuilder& f, InstrData& i, bool ordered) {
f.UpdateCR(crf, f.LoadFPR(i.X.RA), f.LoadFPR(i.X.RB), false);
return 0;
}
XEEMITTER(fcmpo, 0xFC000040, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fcmpo, 0xFC000040, X)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_fcmpx_(f, i, true);
}
XEEMITTER(fcmpu, 0xFC000000, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fcmpu, 0xFC000000, X)(PPCHIRBuilder& f, InstrData& i) {
return InstrEmit_fcmpx_(f, i, false);
}
// Floating-point status and control register (A
XEEMITTER(mcrfs, 0xFC000080, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mcrfs, 0xFC000080, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mffsx, 0xFC00048E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mffsx, 0xFC00048E, X)(PPCHIRBuilder& f, InstrData& i) {
if (i.X.Rc) {
XEINSTRNOTIMPLEMENTED();
return 1;
@@ -434,17 +413,17 @@ XEEMITTER(mffsx, 0xFC00048E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mtfsb0x, 0xFC00008C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mtfsb0x, 0xFC00008C, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mtfsb1x, 0xFC00004C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mtfsb1x, 0xFC00004C, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) {
if (i.XFL.Rc) {
XEINSTRNOTIMPLEMENTED();
return 1;
@@ -460,99 +439,96 @@ XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(mtfsfix, 0xFC00010C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(mtfsfix, 0xFC00010C, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Floating-point move (A-21)
XEEMITTER(fabsx, 0xFC000210, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fabsx, 0xFC000210, X)(PPCHIRBuilder& f, InstrData& i) {
// frD <- abs(frB)
Value* v = f.Abs(f.LoadFPR(i.X.RB));
f.StoreFPR(i.X.RT, v);
if (i.X.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fmrx, 0xFC000090, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fmrx, 0xFC000090, X)(PPCHIRBuilder& f, InstrData& i) {
// frD <- (frB)
Value* v = f.LoadFPR(i.X.RB);
f.StoreFPR(i.X.RT, v);
if (i.X.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
XEEMITTER(fnabsx, 0xFC000110, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnabsx, 0xFC000110, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(fnegx, 0xFC000050, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(fnegx, 0xFC000050, X)(PPCHIRBuilder& f, InstrData& i) {
// frD <- ¬ frB[0] || frB[1-63]
Value* v = f.Neg(f.LoadFPR(i.X.RB));
f.StoreFPR(i.X.RT, v);
if (i.X.Rc) {
//e.update_cr_with_cond(1, v);
// e.update_cr_with_cond(1, v);
XEINSTRNOTIMPLEMENTED();
return 1;
}
return 0;
}
void RegisterEmitCategoryFPU() {
XEREGISTERINSTR(faddx, 0xFC00002A);
XEREGISTERINSTR(faddsx, 0xEC00002A);
XEREGISTERINSTR(fdivx, 0xFC000024);
XEREGISTERINSTR(fdivsx, 0xEC000024);
XEREGISTERINSTR(fmulx, 0xFC000032);
XEREGISTERINSTR(fmulsx, 0xEC000032);
XEREGISTERINSTR(fresx, 0xEC000030);
XEREGISTERINSTR(frsqrtex, 0xFC000034);
XEREGISTERINSTR(fsubx, 0xFC000028);
XEREGISTERINSTR(fsubsx, 0xEC000028);
XEREGISTERINSTR(fselx, 0xFC00002E);
XEREGISTERINSTR(fsqrtx, 0xFC00002C);
XEREGISTERINSTR(fsqrtsx, 0xEC00002C);
XEREGISTERINSTR(fmaddx, 0xFC00003A);
XEREGISTERINSTR(fmaddsx, 0xEC00003A);
XEREGISTERINSTR(fmsubx, 0xFC000038);
XEREGISTERINSTR(fmsubsx, 0xEC000038);
XEREGISTERINSTR(fnmaddx, 0xFC00003E);
XEREGISTERINSTR(fnmaddsx, 0xEC00003E);
XEREGISTERINSTR(fnmsubx, 0xFC00003C);
XEREGISTERINSTR(fnmsubsx, 0xEC00003C);
XEREGISTERINSTR(fcfidx, 0xFC00069C);
XEREGISTERINSTR(fctidx, 0xFC00065C);
XEREGISTERINSTR(fctidzx, 0xFC00065E);
XEREGISTERINSTR(fctiwx, 0xFC00001C);
XEREGISTERINSTR(fctiwzx, 0xFC00001E);
XEREGISTERINSTR(frspx, 0xFC000018);
XEREGISTERINSTR(fcmpo, 0xFC000040);
XEREGISTERINSTR(fcmpu, 0xFC000000);
XEREGISTERINSTR(mcrfs, 0xFC000080);
XEREGISTERINSTR(mffsx, 0xFC00048E);
XEREGISTERINSTR(mtfsb0x, 0xFC00008C);
XEREGISTERINSTR(mtfsb1x, 0xFC00004C);
XEREGISTERINSTR(mtfsfx, 0xFC00058E);
XEREGISTERINSTR(mtfsfix, 0xFC00010C);
XEREGISTERINSTR(fabsx, 0xFC000210);
XEREGISTERINSTR(fmrx, 0xFC000090);
XEREGISTERINSTR(fnabsx, 0xFC000110);
XEREGISTERINSTR(fnegx, 0xFC000050);
XEREGISTERINSTR(faddx, 0xFC00002A);
XEREGISTERINSTR(faddsx, 0xEC00002A);
XEREGISTERINSTR(fdivx, 0xFC000024);
XEREGISTERINSTR(fdivsx, 0xEC000024);
XEREGISTERINSTR(fmulx, 0xFC000032);
XEREGISTERINSTR(fmulsx, 0xEC000032);
XEREGISTERINSTR(fresx, 0xEC000030);
XEREGISTERINSTR(frsqrtex, 0xFC000034);
XEREGISTERINSTR(fsubx, 0xFC000028);
XEREGISTERINSTR(fsubsx, 0xEC000028);
XEREGISTERINSTR(fselx, 0xFC00002E);
XEREGISTERINSTR(fsqrtx, 0xFC00002C);
XEREGISTERINSTR(fsqrtsx, 0xEC00002C);
XEREGISTERINSTR(fmaddx, 0xFC00003A);
XEREGISTERINSTR(fmaddsx, 0xEC00003A);
XEREGISTERINSTR(fmsubx, 0xFC000038);
XEREGISTERINSTR(fmsubsx, 0xEC000038);
XEREGISTERINSTR(fnmaddx, 0xFC00003E);
XEREGISTERINSTR(fnmaddsx, 0xEC00003E);
XEREGISTERINSTR(fnmsubx, 0xFC00003C);
XEREGISTERINSTR(fnmsubsx, 0xEC00003C);
XEREGISTERINSTR(fcfidx, 0xFC00069C);
XEREGISTERINSTR(fctidx, 0xFC00065C);
XEREGISTERINSTR(fctidzx, 0xFC00065E);
XEREGISTERINSTR(fctiwx, 0xFC00001C);
XEREGISTERINSTR(fctiwzx, 0xFC00001E);
XEREGISTERINSTR(frspx, 0xFC000018);
XEREGISTERINSTR(fcmpo, 0xFC000040);
XEREGISTERINSTR(fcmpu, 0xFC000000);
XEREGISTERINSTR(mcrfs, 0xFC000080);
XEREGISTERINSTR(mffsx, 0xFC00048E);
XEREGISTERINSTR(mtfsb0x, 0xFC00008C);
XEREGISTERINSTR(mtfsb1x, 0xFC00004C);
XEREGISTERINSTR(mtfsfx, 0xFC00058E);
XEREGISTERINSTR(mtfsfix, 0xFC00010C);
XEREGISTERINSTR(fabsx, 0xFC000210);
XEREGISTERINSTR(fmrx, 0xFC000090);
XEREGISTERINSTR(fnabsx, 0xFC000110);
XEREGISTERINSTR(fnegx, 0xFC000050);
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@@ -12,23 +12,22 @@
#include <alloy/frontend/ppc/ppc_context.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 frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
using namespace alloy::hir;
using alloy::hir::Value;
#define TRUNCATE_ADDRESSES 0
Value* CalculateEA(PPCHIRBuilder& f, uint32_t ra, uint32_t rb) {
#if TRUNCATE_ADDRESSES
return f.ZeroExtend(f.Add(
f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.Truncate(f.LoadGPR(rb), INT32_TYPE)), INT64_TYPE);
return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.Truncate(f.LoadGPR(rb), INT32_TYPE)),
INT64_TYPE);
#else
return f.Add(f.LoadGPR(ra), f.LoadGPR(rb));
#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) {
#if TRUNCATE_ADDRESSES
if (ra) {
return f.ZeroExtend(f.Add(
f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.Truncate(f.LoadGPR(rb), INT32_TYPE)), INT64_TYPE);
return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.Truncate(f.LoadGPR(rb), INT32_TYPE)),
INT64_TYPE);
} else {
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) {
#if TRUNCATE_ADDRESSES
return f.ZeroExtend(f.Add(
f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.LoadConstant((int32_t)imm)), INT64_TYPE);
return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.LoadConstant((int32_t)imm)),
INT64_TYPE);
#else
return f.Add(f.LoadGPR(ra), f.LoadConstant(imm));
#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) {
#if TRUNCATE_ADDRESSES
if (ra) {
return f.ZeroExtend(f.Add(
f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.LoadConstant((int32_t)imm)), INT64_TYPE);
return f.ZeroExtend(f.Add(f.Truncate(f.LoadGPR(ra), INT32_TYPE),
f.LoadConstant((int32_t)imm)),
INT64_TYPE);
} else {
return f.ZeroExtend(f.LoadConstant((int32_t)imm), INT64_TYPE);
}
@@ -80,10 +79,9 @@ Value* CalculateEA_0_i(PPCHIRBuilder& f, uint32_t ra, uint64_t imm) {
#endif // TRUNCATE_ADDRESSES
}
// Integer load (A-13)
XEEMITTER(lbz, 0x88000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lbz, 0x88000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -96,7 +94,7 @@ XEEMITTER(lbz, 0x88000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lbzu, 0x8C000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lbzu, 0x8C000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- i56.0 || MEM(EA, 1)
// RA <- EA
@@ -107,7 +105,7 @@ XEEMITTER(lbzu, 0x8C000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lbzux, 0x7C0000EE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lbzux, 0x7C0000EE, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// RT <- i56.0 || MEM(EA, 1)
// RA <- EA
@@ -118,7 +116,7 @@ XEEMITTER(lbzux, 0x7C0000EE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lbzx, 0x7C0000AE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lbzx, 0x7C0000AE, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -131,7 +129,7 @@ XEEMITTER(lbzx, 0x7C0000AE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lha, 0xA8000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lha, 0xA8000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -144,17 +142,17 @@ XEEMITTER(lha, 0xA8000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhau, 0xAC000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lhau, 0xAC000000, D)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(lhaux, 0x7C0002EE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lhaux, 0x7C0002EE, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(lhax, 0x7C0002AE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lhax, 0x7C0002AE, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -167,7 +165,7 @@ XEEMITTER(lhax, 0x7C0002AE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhz, 0xA0000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lhz, 0xA0000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -180,7 +178,7 @@ XEEMITTER(lhz, 0xA0000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhzu, 0xA4000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lhzu, 0xA4000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- i48.0 || MEM(EA, 2)
// RA <- EA
@@ -191,7 +189,7 @@ XEEMITTER(lhzu, 0xA4000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhzux, 0x7C00026E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lhzux, 0x7C00026E, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// RT <- i48.0 || MEM(EA, 2)
// RA <- EA
@@ -202,7 +200,7 @@ XEEMITTER(lhzux, 0x7C00026E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lhzx, 0x7C00022E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lhzx, 0x7C00022E, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -215,7 +213,7 @@ XEEMITTER(lhzx, 0x7C00022E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwa, 0xE8000002, DS )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwa, 0xE8000002, DS)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -228,7 +226,7 @@ XEEMITTER(lwa, 0xE8000002, DS )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwaux, 0x7C0002EA, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwaux, 0x7C0002EA, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// RT <- EXTS(MEM(EA, 4))
// RA <- EA
@@ -239,7 +237,7 @@ XEEMITTER(lwaux, 0x7C0002EA, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwax, 0x7C0002AA, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwax, 0x7C0002AA, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -252,7 +250,7 @@ XEEMITTER(lwax, 0x7C0002AA, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwz, 0x80000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwz, 0x80000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -265,7 +263,7 @@ XEEMITTER(lwz, 0x80000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwzu, 0x84000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwzu, 0x84000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// RT <- i32.0 || MEM(EA, 4)
// RA <- EA
@@ -276,7 +274,7 @@ XEEMITTER(lwzu, 0x84000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwzux, 0x7C00006E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwzux, 0x7C00006E, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// RT <- i32.0 || MEM(EA, 4)
// RA <- EA
@@ -287,7 +285,7 @@ XEEMITTER(lwzux, 0x7C00006E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwzx, 0x7C00002E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwzx, 0x7C00002E, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -300,8 +298,7 @@ XEEMITTER(lwzx, 0x7C00002E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ld, 0xE8000000, DS )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(ld, 0xE8000000, DS)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -314,7 +311,7 @@ XEEMITTER(ld, 0xE8000000, DS )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ldu, 0xE8000001, DS )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(ldu, 0xE8000001, DS)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(DS || 0b00)
// RT <- MEM(EA, 8)
// RA <- EA
@@ -325,7 +322,7 @@ XEEMITTER(ldu, 0xE8000001, DS )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ldux, 0x7C00006A, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(ldux, 0x7C00006A, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// RT <- MEM(EA, 8)
// RA <- EA
@@ -336,7 +333,7 @@ XEEMITTER(ldux, 0x7C00006A, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ldx, 0x7C00002A, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(ldx, 0x7C00002A, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -349,10 +346,9 @@ XEEMITTER(ldx, 0x7C00002A, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
// Integer store (A-14)
XEEMITTER(stb, 0x98000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stb, 0x98000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -364,7 +360,7 @@ XEEMITTER(stb, 0x98000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stbu, 0x9C000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stbu, 0x9C000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 1) <- (RS)[56:63]
// RA <- EA
@@ -374,7 +370,7 @@ XEEMITTER(stbu, 0x9C000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stbux, 0x7C0001EE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stbux, 0x7C0001EE, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 1) <- (RS)[56:63]
// RA <- EA
@@ -384,7 +380,7 @@ XEEMITTER(stbux, 0x7C0001EE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stbx, 0x7C0001AE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stbx, 0x7C0001AE, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -396,7 +392,7 @@ XEEMITTER(stbx, 0x7C0001AE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sth, 0xB0000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(sth, 0xB0000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -408,7 +404,7 @@ XEEMITTER(sth, 0xB0000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sthu, 0xB4000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(sthu, 0xB4000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 2) <- (RS)[48:63]
// RA <- EA
@@ -418,7 +414,7 @@ XEEMITTER(sthu, 0xB4000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sthux, 0x7C00036E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(sthux, 0x7C00036E, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 2) <- (RS)[48:63]
// RA <- EA
@@ -428,7 +424,7 @@ XEEMITTER(sthux, 0x7C00036E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sthx, 0x7C00032E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(sthx, 0x7C00032E, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -440,7 +436,7 @@ XEEMITTER(sthx, 0x7C00032E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stw, 0x90000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stw, 0x90000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -452,7 +448,7 @@ XEEMITTER(stw, 0x90000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwu, 0x94000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stwu, 0x94000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 4) <- (RS)[32:63]
// RA <- EA
@@ -462,7 +458,7 @@ XEEMITTER(stwu, 0x94000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwux, 0x7C00016E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stwux, 0x7C00016E, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 4) <- (RS)[32:63]
// RA <- EA
@@ -472,7 +468,7 @@ XEEMITTER(stwux, 0x7C00016E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwx, 0x7C00012E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stwx, 0x7C00012E, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -484,7 +480,7 @@ XEEMITTER(stwx, 0x7C00012E, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(std, 0xF8000000, DS )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(std, 0xF8000000, DS)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -496,7 +492,7 @@ XEEMITTER(std, 0xF8000000, DS )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stdu, 0xF8000001, DS )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stdu, 0xF8000001, DS)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(DS || 0b00)
// MEM(EA, 8) <- (RS)
// RA <- EA
@@ -506,7 +502,7 @@ XEEMITTER(stdu, 0xF8000001, DS )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stdux, 0x7C00016A, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stdux, 0x7C00016A, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 8) <- (RS)
// RA <- EA
@@ -528,10 +524,9 @@ XEEMITTER(stdx, 0x7C00012A, X)(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
// 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) {
// if RA = 0 then
// b <- 0
// else
@@ -544,7 +539,7 @@ XEEMITTER(lhbrx, 0x7C00062C, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwbrx, 0x7C00042C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwbrx, 0x7C00042C, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -557,7 +552,7 @@ XEEMITTER(lwbrx, 0x7C00042C, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(ldbrx, 0x7C000428, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(ldbrx, 0x7C000428, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -570,7 +565,7 @@ XEEMITTER(ldbrx, 0x7C000428, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(sthbrx, 0x7C00072C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(sthbrx, 0x7C00072C, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -582,7 +577,7 @@ XEEMITTER(sthbrx, 0x7C00072C, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwbrx, 0x7C00052C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stwbrx, 0x7C00052C, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -594,7 +589,7 @@ XEEMITTER(stwbrx, 0x7C00052C, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stdbrx, 0x7C000528, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stdbrx, 0x7C000528, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -606,64 +601,61 @@ XEEMITTER(stdbrx, 0x7C000528, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
// Integer load and store multiple (A-16)
XEEMITTER(lmw, 0xB8000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lmw, 0xB8000000, D)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(stmw, 0xBC000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stmw, 0xBC000000, D)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Integer load and store string (A-17)
XEEMITTER(lswi, 0x7C0004AA, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lswi, 0x7C0004AA, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(lswx, 0x7C00042A, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lswx, 0x7C00042A, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(stswi, 0x7C0005AA, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stswi, 0x7C0005AA, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
XEEMITTER(stswx, 0x7C00052A, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stswx, 0x7C00052A, X)(PPCHIRBuilder& f, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
// Memory synchronization (A-18)
XEEMITTER(eieio, 0x7C0006AC, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(eieio, 0x7C0006AC, X)(PPCHIRBuilder& f, InstrData& i) {
// XEINSTRNOTIMPLEMENTED();
f.Nop();
return 0;
}
XEEMITTER(sync, 0x7C0004AC, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(sync, 0x7C0004AC, X)(PPCHIRBuilder& f, InstrData& i) {
// XEINSTRNOTIMPLEMENTED();
f.Nop();
return 0;
}
XEEMITTER(isync, 0x4C00012C, XL )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(isync, 0x4C00012C, XL)(PPCHIRBuilder& f, InstrData& i) {
// XEINSTRNOTIMPLEMENTED();
f.Nop();
return 0;
}
XEEMITTER(ldarx, 0x7C0000A8, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(ldarx, 0x7C0000A8, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -679,7 +671,7 @@ XEEMITTER(ldarx, 0x7C0000A8, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lwarx, 0x7C000028, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lwarx, 0x7C000028, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -690,12 +682,13 @@ XEEMITTER(lwarx, 0x7C000028, X )(PPCHIRBuilder& f, InstrData& i) {
// RESERVE_ADDR <- real_addr(EA)
// RT <- i32.0 || MEM(EA, 4)
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);
return 0;
}
XEEMITTER(stdcx, 0x7C0001AD, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stdcx, 0x7C0001AD, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -712,7 +705,7 @@ XEEMITTER(stdcx, 0x7C0001AD, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stwcx, 0x7C00012D, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stwcx, 0x7C00012D, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -729,10 +722,9 @@ XEEMITTER(stwcx, 0x7C00012D, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
// Floating-point load (A-19)
XEEMITTER(lfd, 0xC8000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lfd, 0xC8000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -745,7 +737,7 @@ XEEMITTER(lfd, 0xC8000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfdu, 0xCC000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lfdu, 0xCC000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// FRT <- MEM(EA, 8)
// RA <- EA
@@ -756,7 +748,7 @@ XEEMITTER(lfdu, 0xCC000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfdux, 0x7C0004EE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lfdux, 0x7C0004EE, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// FRT <- MEM(EA, 8)
// RA <- EA
@@ -767,7 +759,7 @@ XEEMITTER(lfdux, 0x7C0004EE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfdx, 0x7C0004AE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lfdx, 0x7C0004AE, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -780,7 +772,7 @@ XEEMITTER(lfdx, 0x7C0004AE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(lfs, 0xC0000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lfs, 0xC0000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -789,39 +781,36 @@ XEEMITTER(lfs, 0xC0000000, D )(PPCHIRBuilder& f, InstrData& i) {
// FRT <- DOUBLE(MEM(EA, 4))
Value* ea = CalculateEA_0_i(f, i.D.RA, XEEXTS16(i.D.DS));
Value* rt = f.Convert(
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE),
FLOAT64_TYPE);
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.D.RT, rt);
return 0;
}
XEEMITTER(lfsu, 0xC4000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lfsu, 0xC4000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// FRT <- DOUBLE(MEM(EA, 4))
// RA <- EA
Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS));
Value* rt = f.Convert(
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE),
FLOAT64_TYPE);
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.D.RT, rt);
f.StoreGPR(i.D.RA, ea);
return 0;
}
XEEMITTER(lfsux, 0x7C00046E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lfsux, 0x7C00046E, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// FRT <- DOUBLE(MEM(EA, 4))
// RA <- EA
Value* ea = CalculateEA(f, i.X.RA, i.X.RB);
Value* rt = f.Convert(
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE),
FLOAT64_TYPE);
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.X.RT, rt);
f.StoreGPR(i.X.RA, ea);
return 0;
}
XEEMITTER(lfsx, 0x7C00042E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(lfsx, 0x7C00042E, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -830,16 +819,14 @@ XEEMITTER(lfsx, 0x7C00042E, X )(PPCHIRBuilder& f, InstrData& i) {
// FRT <- DOUBLE(MEM(EA, 4))
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
Value* rt = f.Convert(
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE),
FLOAT64_TYPE);
f.Cast(f.ByteSwap(f.Load(ea, INT32_TYPE)), FLOAT32_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.X.RT, rt);
return 0;
}
// Floating-point store (A-20)
XEEMITTER(stfd, 0xD8000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfd, 0xD8000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -851,7 +838,7 @@ XEEMITTER(stfd, 0xD8000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfdu, 0xDC000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfdu, 0xDC000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 8) <- (FRS)
// RA <- EA
@@ -861,7 +848,7 @@ XEEMITTER(stfdu, 0xDC000000, D )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfdux, 0x7C0005EE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfdux, 0x7C0005EE, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 8) <- (FRS)
// RA <- EA
@@ -871,7 +858,7 @@ XEEMITTER(stfdux, 0x7C0005EE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfdx, 0x7C0005AE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfdx, 0x7C0005AE, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -883,7 +870,7 @@ XEEMITTER(stfdx, 0x7C0005AE, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(stfiwx, 0x7C0007AE, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfiwx, 0x7C0007AE, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -891,12 +878,12 @@ XEEMITTER(stfiwx, 0x7C0007AE, X )(PPCHIRBuilder& f, InstrData& i) {
// EA <- b + (RB)
// MEM(EA, 4) <- (FRS)[32:63]
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
f.Store(ea, f.ByteSwap(
f.Truncate(f.Cast(f.LoadFPR(i.X.RT), INT64_TYPE), INT32_TYPE)));
f.Store(ea, f.ByteSwap(f.Truncate(f.Cast(f.LoadFPR(i.X.RT), INT64_TYPE),
INT32_TYPE)));
return 0;
}
XEEMITTER(stfs, 0xD0000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfs, 0xD0000000, D)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -904,34 +891,34 @@ XEEMITTER(stfs, 0xD0000000, D )(PPCHIRBuilder& f, InstrData& i) {
// EA <- b + EXTS(D)
// MEM(EA, 4) <- SINGLE(FRS)
Value* ea = CalculateEA_0_i(f, i.D.RA, XEEXTS16(i.D.DS));
f.Store(ea, f.ByteSwap(f.Cast(
f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE), INT32_TYPE)));
f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE),
INT32_TYPE)));
return 0;
}
XEEMITTER(stfsu, 0xD4000000, D )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfsu, 0xD4000000, D)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + EXTS(D)
// MEM(EA, 4) <- SINGLE(FRS)
// RA <- EA
Value* ea = CalculateEA_i(f, i.D.RA, XEEXTS16(i.D.DS));
f.Store(ea, f.ByteSwap(f.Cast(
f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE), INT32_TYPE)));
f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.D.RT), FLOAT32_TYPE),
INT32_TYPE)));
f.StoreGPR(i.D.RA, ea);
return 0;
}
XEEMITTER(stfsux, 0x7C00056E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfsux, 0x7C00056E, X)(PPCHIRBuilder& f, InstrData& i) {
// EA <- (RA) + (RB)
// MEM(EA, 4) <- SINGLE(FRS)
// RA <- EA
Value* ea = CalculateEA(f, i.X.RA, i.X.RB);
f.Store(ea, f.ByteSwap(f.Cast(
f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE), INT32_TYPE)));
f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE),
INT32_TYPE)));
f.StoreGPR(i.X.RA, ea);
return 0;
}
XEEMITTER(stfsx, 0x7C00052E, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(stfsx, 0x7C00052E, X)(PPCHIRBuilder& f, InstrData& i) {
// if RA = 0 then
// b <- 0
// else
@@ -939,15 +926,14 @@ XEEMITTER(stfsx, 0x7C00052E, X )(PPCHIRBuilder& f, InstrData& i) {
// EA <- b + (RB)
// MEM(EA, 4) <- SINGLE(FRS)
Value* ea = CalculateEA_0(f, i.X.RA, i.X.RB);
f.Store(ea, f.ByteSwap(f.Cast(
f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE), INT32_TYPE)));
f.Store(ea, f.ByteSwap(f.Cast(f.Convert(f.LoadFPR(i.X.RT), FLOAT32_TYPE),
INT32_TYPE)));
return 0;
}
// Cache management (A-27)
XEEMITTER(dcbf, 0x7C0000AC, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(dcbf, 0x7C0000AC, X)(PPCHIRBuilder& f, InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// XEINSTRNOTIMPLEMENTED();
@@ -955,7 +941,7 @@ XEEMITTER(dcbf, 0x7C0000AC, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(dcbst, 0x7C00006C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(dcbst, 0x7C00006C, X)(PPCHIRBuilder& f, InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// XEINSTRNOTIMPLEMENTED();
@@ -963,7 +949,7 @@ XEEMITTER(dcbst, 0x7C00006C, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(dcbt, 0x7C00022C, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(dcbt, 0x7C00022C, X)(PPCHIRBuilder& f, InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// XEINSTRNOTIMPLEMENTED();
@@ -971,7 +957,7 @@ XEEMITTER(dcbt, 0x7C00022C, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(dcbtst, 0x7C0001EC, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(dcbtst, 0x7C0001EC, X)(PPCHIRBuilder& f, InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// XEINSTRNOTIMPLEMENTED();
@@ -979,7 +965,7 @@ XEEMITTER(dcbtst, 0x7C0001EC, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(dcbz, 0x7C0007EC, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(dcbz, 0x7C0007EC, X)(PPCHIRBuilder& f, InstrData& i) {
// No-op for now.
// TODO(benvanik): use prefetch
// or dcbz128 0x7C2007EC
@@ -988,98 +974,96 @@ XEEMITTER(dcbz, 0x7C0007EC, X )(PPCHIRBuilder& f, InstrData& i) {
return 0;
}
XEEMITTER(icbi, 0x7C0007AC, X )(PPCHIRBuilder& f, InstrData& i) {
XEEMITTER(icbi, 0x7C0007AC, X)(PPCHIRBuilder& f, InstrData& i) {
// XEINSTRNOTIMPLEMENTED();
f.Nop();
return 0;
}
void RegisterEmitCategoryMemory() {
XEREGISTERINSTR(lbz, 0x88000000);
XEREGISTERINSTR(lbzu, 0x8C000000);
XEREGISTERINSTR(lbzux, 0x7C0000EE);
XEREGISTERINSTR(lbzx, 0x7C0000AE);
XEREGISTERINSTR(lha, 0xA8000000);
XEREGISTERINSTR(lhau, 0xAC000000);
XEREGISTERINSTR(lhaux, 0x7C0002EE);
XEREGISTERINSTR(lhax, 0x7C0002AE);
XEREGISTERINSTR(lhz, 0xA0000000);
XEREGISTERINSTR(lhzu, 0xA4000000);
XEREGISTERINSTR(lhzux, 0x7C00026E);
XEREGISTERINSTR(lhzx, 0x7C00022E);
XEREGISTERINSTR(lwa, 0xE8000002);
XEREGISTERINSTR(lwaux, 0x7C0002EA);
XEREGISTERINSTR(lwax, 0x7C0002AA);
XEREGISTERINSTR(lwz, 0x80000000);
XEREGISTERINSTR(lwzu, 0x84000000);
XEREGISTERINSTR(lwzux, 0x7C00006E);
XEREGISTERINSTR(lwzx, 0x7C00002E);
XEREGISTERINSTR(ld, 0xE8000000);
XEREGISTERINSTR(ldu, 0xE8000001);
XEREGISTERINSTR(ldux, 0x7C00006A);
XEREGISTERINSTR(ldx, 0x7C00002A);
XEREGISTERINSTR(stb, 0x98000000);
XEREGISTERINSTR(stbu, 0x9C000000);
XEREGISTERINSTR(stbux, 0x7C0001EE);
XEREGISTERINSTR(stbx, 0x7C0001AE);
XEREGISTERINSTR(sth, 0xB0000000);
XEREGISTERINSTR(sthu, 0xB4000000);
XEREGISTERINSTR(sthux, 0x7C00036E);
XEREGISTERINSTR(sthx, 0x7C00032E);
XEREGISTERINSTR(stw, 0x90000000);
XEREGISTERINSTR(stwu, 0x94000000);
XEREGISTERINSTR(stwux, 0x7C00016E);
XEREGISTERINSTR(stwx, 0x7C00012E);
XEREGISTERINSTR(std, 0xF8000000);
XEREGISTERINSTR(stdu, 0xF8000001);
XEREGISTERINSTR(stdux, 0x7C00016A);
XEREGISTERINSTR(stdx, 0x7C00012A);
XEREGISTERINSTR(lhbrx, 0x7C00062C);
XEREGISTERINSTR(lwbrx, 0x7C00042C);
XEREGISTERINSTR(ldbrx, 0x7C000428);
XEREGISTERINSTR(sthbrx, 0x7C00072C);
XEREGISTERINSTR(stwbrx, 0x7C00052C);
XEREGISTERINSTR(stdbrx, 0x7C000528);
XEREGISTERINSTR(lmw, 0xB8000000);
XEREGISTERINSTR(stmw, 0xBC000000);
XEREGISTERINSTR(lswi, 0x7C0004AA);
XEREGISTERINSTR(lswx, 0x7C00042A);
XEREGISTERINSTR(stswi, 0x7C0005AA);
XEREGISTERINSTR(stswx, 0x7C00052A);
XEREGISTERINSTR(eieio, 0x7C0006AC);
XEREGISTERINSTR(sync, 0x7C0004AC);
XEREGISTERINSTR(isync, 0x4C00012C);
XEREGISTERINSTR(ldarx, 0x7C0000A8);
XEREGISTERINSTR(lwarx, 0x7C000028);
XEREGISTERINSTR(stdcx, 0x7C0001AD);
XEREGISTERINSTR(stwcx, 0x7C00012D);
XEREGISTERINSTR(lfd, 0xC8000000);
XEREGISTERINSTR(lfdu, 0xCC000000);
XEREGISTERINSTR(lfdux, 0x7C0004EE);
XEREGISTERINSTR(lfdx, 0x7C0004AE);
XEREGISTERINSTR(lfs, 0xC0000000);
XEREGISTERINSTR(lfsu, 0xC4000000);
XEREGISTERINSTR(lfsux, 0x7C00046E);
XEREGISTERINSTR(lfsx, 0x7C00042E);
XEREGISTERINSTR(stfd, 0xD8000000);
XEREGISTERINSTR(stfdu, 0xDC000000);
XEREGISTERINSTR(stfdux, 0x7C0005EE);
XEREGISTERINSTR(stfdx, 0x7C0005AE);
XEREGISTERINSTR(stfiwx, 0x7C0007AE);
XEREGISTERINSTR(stfs, 0xD0000000);
XEREGISTERINSTR(stfsu, 0xD4000000);
XEREGISTERINSTR(stfsux, 0x7C00056E);
XEREGISTERINSTR(stfsx, 0x7C00052E);
XEREGISTERINSTR(dcbf, 0x7C0000AC);
XEREGISTERINSTR(dcbst, 0x7C00006C);
XEREGISTERINSTR(dcbt, 0x7C00022C);
XEREGISTERINSTR(dcbtst, 0x7C0001EC);
XEREGISTERINSTR(dcbz, 0x7C0007EC);
XEREGISTERINSTR(icbi, 0x7C0007AC);
XEREGISTERINSTR(lbz, 0x88000000);
XEREGISTERINSTR(lbzu, 0x8C000000);
XEREGISTERINSTR(lbzux, 0x7C0000EE);
XEREGISTERINSTR(lbzx, 0x7C0000AE);
XEREGISTERINSTR(lha, 0xA8000000);
XEREGISTERINSTR(lhau, 0xAC000000);
XEREGISTERINSTR(lhaux, 0x7C0002EE);
XEREGISTERINSTR(lhax, 0x7C0002AE);
XEREGISTERINSTR(lhz, 0xA0000000);
XEREGISTERINSTR(lhzu, 0xA4000000);
XEREGISTERINSTR(lhzux, 0x7C00026E);
XEREGISTERINSTR(lhzx, 0x7C00022E);
XEREGISTERINSTR(lwa, 0xE8000002);
XEREGISTERINSTR(lwaux, 0x7C0002EA);
XEREGISTERINSTR(lwax, 0x7C0002AA);
XEREGISTERINSTR(lwz, 0x80000000);
XEREGISTERINSTR(lwzu, 0x84000000);
XEREGISTERINSTR(lwzux, 0x7C00006E);
XEREGISTERINSTR(lwzx, 0x7C00002E);
XEREGISTERINSTR(ld, 0xE8000000);
XEREGISTERINSTR(ldu, 0xE8000001);
XEREGISTERINSTR(ldux, 0x7C00006A);
XEREGISTERINSTR(ldx, 0x7C00002A);
XEREGISTERINSTR(stb, 0x98000000);
XEREGISTERINSTR(stbu, 0x9C000000);
XEREGISTERINSTR(stbux, 0x7C0001EE);
XEREGISTERINSTR(stbx, 0x7C0001AE);
XEREGISTERINSTR(sth, 0xB0000000);
XEREGISTERINSTR(sthu, 0xB4000000);
XEREGISTERINSTR(sthux, 0x7C00036E);
XEREGISTERINSTR(sthx, 0x7C00032E);
XEREGISTERINSTR(stw, 0x90000000);
XEREGISTERINSTR(stwu, 0x94000000);
XEREGISTERINSTR(stwux, 0x7C00016E);
XEREGISTERINSTR(stwx, 0x7C00012E);
XEREGISTERINSTR(std, 0xF8000000);
XEREGISTERINSTR(stdu, 0xF8000001);
XEREGISTERINSTR(stdux, 0x7C00016A);
XEREGISTERINSTR(stdx, 0x7C00012A);
XEREGISTERINSTR(lhbrx, 0x7C00062C);
XEREGISTERINSTR(lwbrx, 0x7C00042C);
XEREGISTERINSTR(ldbrx, 0x7C000428);
XEREGISTERINSTR(sthbrx, 0x7C00072C);
XEREGISTERINSTR(stwbrx, 0x7C00052C);
XEREGISTERINSTR(stdbrx, 0x7C000528);
XEREGISTERINSTR(lmw, 0xB8000000);
XEREGISTERINSTR(stmw, 0xBC000000);
XEREGISTERINSTR(lswi, 0x7C0004AA);
XEREGISTERINSTR(lswx, 0x7C00042A);
XEREGISTERINSTR(stswi, 0x7C0005AA);
XEREGISTERINSTR(stswx, 0x7C00052A);
XEREGISTERINSTR(eieio, 0x7C0006AC);
XEREGISTERINSTR(sync, 0x7C0004AC);
XEREGISTERINSTR(isync, 0x4C00012C);
XEREGISTERINSTR(ldarx, 0x7C0000A8);
XEREGISTERINSTR(lwarx, 0x7C000028);
XEREGISTERINSTR(stdcx, 0x7C0001AD);
XEREGISTERINSTR(stwcx, 0x7C00012D);
XEREGISTERINSTR(lfd, 0xC8000000);
XEREGISTERINSTR(lfdu, 0xCC000000);
XEREGISTERINSTR(lfdux, 0x7C0004EE);
XEREGISTERINSTR(lfdx, 0x7C0004AE);
XEREGISTERINSTR(lfs, 0xC0000000);
XEREGISTERINSTR(lfsu, 0xC4000000);
XEREGISTERINSTR(lfsux, 0x7C00046E);
XEREGISTERINSTR(lfsx, 0x7C00042E);
XEREGISTERINSTR(stfd, 0xD8000000);
XEREGISTERINSTR(stfdu, 0xDC000000);
XEREGISTERINSTR(stfdux, 0x7C0005EE);
XEREGISTERINSTR(stfdx, 0x7C0005AE);
XEREGISTERINSTR(stfiwx, 0x7C0007AE);
XEREGISTERINSTR(stfs, 0xD0000000);
XEREGISTERINSTR(stfsu, 0xD4000000);
XEREGISTERINSTR(stfsux, 0x7C00056E);
XEREGISTERINSTR(stfsx, 0x7C00052E);
XEREGISTERINSTR(dcbf, 0x7C0000AC);
XEREGISTERINSTR(dcbst, 0x7C00006C);
XEREGISTERINSTR(dcbt, 0x7C00022C);
XEREGISTERINSTR(dcbtst, 0x7C0001EC);
XEREGISTERINSTR(dcbz, 0x7C0007EC);
XEREGISTERINSTR(icbi, 0x7C0007AC);
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

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

View File

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

View File

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

View File

@@ -15,19 +15,18 @@
#include <alloy/runtime/function.h>
#include <alloy/runtime/symbol_info.h>
namespace alloy {
namespace frontend {
namespace ppc {
class PPCFrontend;
class PPCHIRBuilder : public hir::HIRBuilder {
using Instr = alloy::hir::Instr;
using Label = alloy::hir::Label;
using Value = alloy::hir::Value;
public:
public:
PPCHIRBuilder(PPCFrontend* frontend);
virtual ~PPCHIRBuilder();
@@ -53,9 +52,9 @@ public:
void StoreFPSCR(Value* value);
Value* LoadXER();
void StoreXER(Value* value);
//void UpdateXERWithOverflow();
//void UpdateXERWithOverflowAndCarry();
//void StoreOV(Value* value);
// void UpdateXERWithOverflow();
// void UpdateXERWithOverflowAndCarry();
// void StoreOV(Value* value);
Value* LoadCA();
void StoreCA(Value* value);
Value* LoadSAT();
@@ -68,31 +67,30 @@ public:
Value* LoadVR(uint32_t reg);
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);
private:
private:
void AnnotateLabel(uint64_t address, Label* label);
private:
PPCFrontend* frontend_;
private:
PPCFrontend* frontend_;
// Reset whenever needed:
StringBuffer* comment_buffer_;
// Reset each Emit:
bool with_debug_info_;
bool with_debug_info_;
runtime::FunctionInfo* symbol_info_;
uint64_t start_address_;
uint64_t instr_count_;
Instr** instr_offset_list_;
Label** label_list_;
uint64_t start_address_;
uint64_t instr_count_;
Instr** instr_offset_list_;
Label** label_list_;
};
} // namespace ppc
} // namespace frontend
} // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_HIR_BUILDER_H_

View File

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

View File

@@ -15,81 +15,73 @@
#include <string>
#include <vector>
namespace alloy {
namespace frontend {
namespace ppc {
// TODO(benvanik): rename these
typedef enum {
kXEPPCInstrFormatI = 0,
kXEPPCInstrFormatB = 1,
kXEPPCInstrFormatSC = 2,
kXEPPCInstrFormatD = 3,
kXEPPCInstrFormatDS = 4,
kXEPPCInstrFormatX = 5,
kXEPPCInstrFormatXL = 6,
kXEPPCInstrFormatXFX = 7,
kXEPPCInstrFormatXFL = 8,
kXEPPCInstrFormatXS = 9,
kXEPPCInstrFormatXO = 10,
kXEPPCInstrFormatA = 11,
kXEPPCInstrFormatM = 12,
kXEPPCInstrFormatMD = 13,
kXEPPCInstrFormatMDS = 14,
kXEPPCInstrFormatVXA = 15,
kXEPPCInstrFormatVX = 16,
kXEPPCInstrFormatVXR = 17,
kXEPPCInstrFormatVX128 = 18,
kXEPPCInstrFormatVX128_1 = 19,
kXEPPCInstrFormatVX128_2 = 20,
kXEPPCInstrFormatVX128_3 = 21,
kXEPPCInstrFormatVX128_4 = 22,
kXEPPCInstrFormatVX128_5 = 23,
kXEPPCInstrFormatVX128_P = 24,
kXEPPCInstrFormatVX128_R = 25,
kXEPPCInstrFormatXDSS = 26,
kXEPPCInstrFormatI = 0,
kXEPPCInstrFormatB = 1,
kXEPPCInstrFormatSC = 2,
kXEPPCInstrFormatD = 3,
kXEPPCInstrFormatDS = 4,
kXEPPCInstrFormatX = 5,
kXEPPCInstrFormatXL = 6,
kXEPPCInstrFormatXFX = 7,
kXEPPCInstrFormatXFL = 8,
kXEPPCInstrFormatXS = 9,
kXEPPCInstrFormatXO = 10,
kXEPPCInstrFormatA = 11,
kXEPPCInstrFormatM = 12,
kXEPPCInstrFormatMD = 13,
kXEPPCInstrFormatMDS = 14,
kXEPPCInstrFormatVXA = 15,
kXEPPCInstrFormatVX = 16,
kXEPPCInstrFormatVXR = 17,
kXEPPCInstrFormatVX128 = 18,
kXEPPCInstrFormatVX128_1 = 19,
kXEPPCInstrFormatVX128_2 = 20,
kXEPPCInstrFormatVX128_3 = 21,
kXEPPCInstrFormatVX128_4 = 22,
kXEPPCInstrFormatVX128_5 = 23,
kXEPPCInstrFormatVX128_P = 24,
kXEPPCInstrFormatVX128_R = 25,
kXEPPCInstrFormatXDSS = 26,
} xe_ppc_instr_format_e;
typedef enum {
kXEPPCInstrMaskVXR = 0xFC0003FF,
kXEPPCInstrMaskVXA = 0xFC00003F,
kXEPPCInstrMaskVX128 = 0xFC0003D0,
kXEPPCInstrMaskVX128_1 = 0xFC0007F3,
kXEPPCInstrMaskVX128_2 = 0xFC000210,
kXEPPCInstrMaskVX128_3 = 0xFC0007F0,
kXEPPCInstrMaskVX128_4 = 0xFC000730,
kXEPPCInstrMaskVX128_5 = 0xFC000010,
kXEPPCInstrMaskVX128_P = 0xFC000630,
kXEPPCInstrMaskVX128_R = 0xFC000390,
kXEPPCInstrMaskVXR = 0xFC0003FF,
kXEPPCInstrMaskVXA = 0xFC00003F,
kXEPPCInstrMaskVX128 = 0xFC0003D0,
kXEPPCInstrMaskVX128_1 = 0xFC0007F3,
kXEPPCInstrMaskVX128_2 = 0xFC000210,
kXEPPCInstrMaskVX128_3 = 0xFC0007F0,
kXEPPCInstrMaskVX128_4 = 0xFC000730,
kXEPPCInstrMaskVX128_5 = 0xFC000010,
kXEPPCInstrMaskVX128_P = 0xFC000630,
kXEPPCInstrMaskVX128_R = 0xFC000390,
} xe_ppc_instr_mask_e;
typedef enum {
kXEPPCInstrTypeGeneral = (1 << 0),
kXEPPCInstrTypeBranch = (1 << 1),
kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 2),
kXEPPCInstrTypeGeneral = (1 << 0),
kXEPPCInstrTypeBranch = (1 << 1),
kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 2),
kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 3),
kXEPPCInstrTypeSyscall = (1 << 4),
kXEPPCInstrTypeSyscall = (1 << 4),
} xe_ppc_instr_type_e;
typedef enum {
kXEPPCInstrFlagReserved = 0,
kXEPPCInstrFlagReserved = 0,
} xe_ppc_instr_flag_e;
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) {
return (int64_t)(v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v));
}
static inline uint64_t XEEXTZ16(uint32_t v) {
return (uint64_t)((uint16_t)v);
}
static inline uint64_t XEEXTZ16(uint32_t v) { return (uint64_t)((uint16_t)v); }
static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
// if mstart ≤ mstop then
// mask[mstart:mstop] = ones
@@ -105,289 +97,338 @@ static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
return mstart <= mstop ? value : ~value;
}
typedef struct {
InstrType* type;
uint64_t address;
InstrType* type;
uint64_t address;
union {
uint32_t code;
uint32_t code;
// kXEPPCInstrFormatI
struct {
uint32_t LK : 1;
uint32_t AA : 1;
uint32_t LI : 24;
uint32_t : 6;
uint32_t LK : 1;
uint32_t AA : 1;
uint32_t LI : 24;
uint32_t:
6;
} I;
// kXEPPCInstrFormatB
struct {
uint32_t LK : 1;
uint32_t AA : 1;
uint32_t BD : 14;
uint32_t BI : 5;
uint32_t BO : 5;
uint32_t : 6;
uint32_t LK : 1;
uint32_t AA : 1;
uint32_t BD : 14;
uint32_t BI : 5;
uint32_t BO : 5;
uint32_t:
6;
} B;
// kXEPPCInstrFormatSC
// kXEPPCInstrFormatD
struct {
uint32_t DS : 16;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
uint32_t DS : 16;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t:
6;
} D;
// kXEPPCInstrFormatDS
struct {
uint32_t : 2;
uint32_t DS : 14;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
uint32_t:
2;
uint32_t DS : 14;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t:
6;
} DS;
// kXEPPCInstrFormatX
struct {
uint32_t Rc : 1;
uint32_t : 10;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
uint32_t Rc : 1;
uint32_t:
10;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t:
6;
} X;
// kXEPPCInstrFormatXL
struct {
uint32_t LK : 1;
uint32_t : 10;
uint32_t BB : 5;
uint32_t BI : 5;
uint32_t BO : 5;
uint32_t : 6;
uint32_t LK : 1;
uint32_t:
10;
uint32_t BB : 5;
uint32_t BI : 5;
uint32_t BO : 5;
uint32_t:
6;
} XL;
// kXEPPCInstrFormatXFX
struct {
uint32_t : 1;
uint32_t : 10;
uint32_t spr : 10;
uint32_t RT : 5;
uint32_t : 6;
uint32_t:
1;
uint32_t:
10;
uint32_t spr : 10;
uint32_t RT : 5;
uint32_t:
6;
} XFX;
// kXEPPCInstrFormatXFL
struct {
uint32_t Rc : 1;
uint32_t : 10;
uint32_t RB : 5;
uint32_t W : 1;
uint32_t FM : 8;
uint32_t L : 1;
uint32_t : 6;
uint32_t Rc : 1;
uint32_t:
10;
uint32_t RB : 5;
uint32_t W : 1;
uint32_t FM : 8;
uint32_t L : 1;
uint32_t:
6;
} XFL;
// kXEPPCInstrFormatXS
struct {
uint32_t Rc : 1;
uint32_t SH5 : 1;
uint32_t : 9;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
uint32_t Rc : 1;
uint32_t SH5 : 1;
uint32_t:
9;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t:
6;
} XS;
// kXEPPCInstrFormatXO
struct {
uint32_t Rc : 1;
uint32_t : 9;
uint32_t OE : 1;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
uint32_t Rc : 1;
uint32_t:
9;
uint32_t OE : 1;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t:
6;
} XO;
// kXEPPCInstrFormatA
struct {
uint32_t Rc : 1;
uint32_t XO : 5;
uint32_t FRC : 5;
uint32_t FRB : 5;
uint32_t FRA : 5;
uint32_t FRT : 5;
uint32_t : 6;
uint32_t Rc : 1;
uint32_t XO : 5;
uint32_t FRC : 5;
uint32_t FRB : 5;
uint32_t FRA : 5;
uint32_t FRT : 5;
uint32_t:
6;
} A;
// kXEPPCInstrFormatM
struct {
uint32_t Rc : 1;
uint32_t ME : 5;
uint32_t MB : 5;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
uint32_t Rc : 1;
uint32_t ME : 5;
uint32_t MB : 5;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t:
6;
} M;
// kXEPPCInstrFormatMD
struct {
uint32_t Rc : 1;
uint32_t SH5 : 1;
uint32_t idx : 3;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
uint32_t Rc : 1;
uint32_t SH5 : 1;
uint32_t idx : 3;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t:
6;
} MD;
// kXEPPCInstrFormatMDS
struct {
uint32_t Rc : 1;
uint32_t idx : 4;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
uint32_t Rc : 1;
uint32_t idx : 4;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t:
6;
} MDS;
// kXEPPCInstrFormatVXA
struct {
uint32_t : 6;
uint32_t VC : 5;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t : 6;
uint32_t:
6;
uint32_t VC : 5;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t:
6;
} VXA;
// kXEPPCInstrFormatVX
struct {
uint32_t : 11;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t : 6;
uint32_t:
11;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t:
6;
} VX;
// kXEPPCInstrFormatVXR
struct {
uint32_t : 10;
uint32_t Rc : 1;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t : 6;
uint32_t:
10;
uint32_t Rc : 1;
uint32_t VB : 5;
uint32_t VA : 5;
uint32_t VD : 5;
uint32_t:
6;
} VXR;
// kXEPPCInstrFormatVX128
struct {
// VD128 = VD128l | (VD128h << 5)
// VA128 = VA128l | (VA128h << 5) | (VA128H << 6)
// VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 1;
uint32_t VA128h : 1;
uint32_t : 4;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t : 6;
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t:
1;
uint32_t VA128h : 1;
uint32_t:
4;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t:
6;
} VX128;
// kXEPPCInstrFormatVX128_1
struct {
// VD128 = VD128l | (VD128h << 5)
uint32_t : 2;
uint32_t VD128h : 2;
uint32_t : 7;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t VD128l : 5;
uint32_t : 6;
// VD128 = VD128l | (VD128h << 5)
uint32_t:
2;
uint32_t VD128h : 2;
uint32_t:
7;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t VD128l : 5;
uint32_t:
6;
} VX128_1;
// kXEPPCInstrFormatVX128_2
struct {
// VD128 = VD128l | (VD128h << 5)
// VA128 = VA128l | (VA128h << 5) | (VA128H << 6)
// VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 1;
uint32_t VA128h : 1;
uint32_t VC : 3;
uint32_t : 1;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t : 6;
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t:
1;
uint32_t VA128h : 1;
uint32_t VC : 3;
uint32_t:
1;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t:
6;
} VX128_2;
// kXEPPCInstrFormatVX128_3
struct {
// VD128 = VD128l | (VD128h << 5)
// VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 7;
uint32_t VB128l : 5;
uint32_t IMM : 5;
uint32_t VD128l : 5;
uint32_t : 6;
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t:
7;
uint32_t VB128l : 5;
uint32_t IMM : 5;
uint32_t VD128l : 5;
uint32_t:
6;
} VX128_3;
// kXEPPCInstrFormatVX128_4
struct {
// VD128 = VD128l | (VD128h << 5)
// VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 2;
uint32_t z : 2;
uint32_t : 3;
uint32_t VB128l : 5;
uint32_t IMM : 5;
uint32_t VD128l : 5;
uint32_t : 6;
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t:
2;
uint32_t z : 2;
uint32_t:
3;
uint32_t VB128l : 5;
uint32_t IMM : 5;
uint32_t VD128l : 5;
uint32_t:
6;
} VX128_4;
// kXEPPCInstrFormatVX128_5
struct {
// VD128 = VD128l | (VD128h << 5)
// VA128 = VA128l | (VA128h << 5) | (VA128H << 6)
// VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 1;
uint32_t VA128h : 1;
uint32_t SH : 4;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t : 6;
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t:
1;
uint32_t VA128h : 1;
uint32_t SH : 4;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t:
6;
} VX128_5;
// kXEPPCInstrFormatVX128_P
struct {
// VD128 = VD128l | (VD128h << 5)
// VB128 = VB128l | (VB128h << 5)
// PERM = PERMl | (PERMh << 5)
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 2;
uint32_t PERMh : 3;
uint32_t : 2;
uint32_t VB128l : 5;
uint32_t PERMl : 5;
uint32_t VD128l : 5;
uint32_t : 6;
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t:
2;
uint32_t PERMh : 3;
uint32_t:
2;
uint32_t VB128l : 5;
uint32_t PERMl : 5;
uint32_t VD128l : 5;
uint32_t:
6;
} VX128_P;
// kXEPPCInstrFormatVX128_R
struct {
// VD128 = VD128l | (VD128h << 5)
// VA128 = VA128l | (VA128h << 5) | (VA128H << 6)
// VB128 = VB128l | (VB128h << 5)
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t : 1;
uint32_t VA128h : 1;
uint32_t Rc : 1;
uint32_t : 3;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t : 6;
uint32_t VB128h : 2;
uint32_t VD128h : 2;
uint32_t:
1;
uint32_t VA128h : 1;
uint32_t Rc : 1;
uint32_t:
3;
uint32_t VA128H : 1;
uint32_t VB128l : 5;
uint32_t VA128l : 5;
uint32_t VD128l : 5;
uint32_t:
6;
} VX128_R;
// kXEPPCInstrFormatXDSS
struct {
@@ -395,31 +436,29 @@ typedef struct {
};
} InstrData;
typedef struct {
enum RegisterSet {
kXER,
kLR,
kCTR,
kCR, // 0-7
kCR, // 0-7
kFPSCR,
kGPR, // 0-31
kFPR, // 0-31
kVMX, // 0-127
kGPR, // 0-31
kFPR, // 0-31
kVMX, // 0-127
};
enum Access {
kRead = 1 << 0,
kWrite = 1 << 1,
kReadWrite = kRead | kWrite,
kRead = 1 << 0,
kWrite = 1 << 1,
kReadWrite = kRead | kWrite,
};
RegisterSet set;
uint32_t ordinal;
Access access;
uint32_t ordinal;
Access access;
} InstrRegister;
typedef struct {
enum OperandType {
kRegister,
@@ -431,30 +470,34 @@ typedef struct {
union {
InstrRegister reg;
struct {
bool is_signed;
uint64_t value;
size_t width;
bool is_signed;
uint64_t value;
size_t width;
} imm;
};
void Dump(std::string& out_str);
} InstrOperand;
class InstrAccessBits {
public:
InstrAccessBits() :
spr(0), cr(0), gpr(0), fpr(0),
vr31_0(0), vr63_32(0), vr95_64(0), vr127_96(0) {
}
public:
InstrAccessBits()
: spr(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.
// Format is 2 bits for each register, even bits indicating reads and odds
// indicating writes.
uint64_t spr; // fpcsr/ctr/lr/xer
uint64_t cr; // cr7/6/5/4/3/2/1/0
uint64_t gpr; // r31-0
uint64_t fpr; // f31-0
uint64_t spr; // fpcsr/ctr/lr/xer
uint64_t cr; // cr7/6/5/4/3/2/1/0
uint64_t gpr; // r31-0
uint64_t fpr; // f31-0
uint64_t vr31_0;
uint64_t vr63_32;
uint64_t vr95_64;
@@ -466,21 +509,20 @@ public:
void Dump(std::string& out_str);
};
class InstrDisasm {
public:
public:
enum Flags {
kOE = 1 << 0,
kRc = 1 << 1,
kCA = 1 << 2,
kLR = 1 << 4,
kFP = 1 << 5,
kVMX = 1 << 6,
kOE = 1 << 0,
kRc = 1 << 1,
kCA = 1 << 2,
kLR = 1 << 4,
kFP = 1 << 5,
kVMX = 1 << 6,
};
const char* name;
const char* info;
uint32_t flags;
const char* name;
const char* info;
uint32_t flags;
void Init(const char* name, const char* info, uint32_t flags);
void AddLR(InstrRegister::Access access);
@@ -496,32 +538,27 @@ public:
void Dump(std::string& out_str, size_t pad = 13);
};
typedef void (*InstrDisasmFn)(InstrData& i, StringBuffer* str);
typedef void* InstrEmitFn;
class InstrType {
public:
uint32_t opcode;
uint32_t opcode_mask; // Only used for certain opcodes (altivec, etc).
uint32_t format; // xe_ppc_instr_format_e
uint32_t type; // xe_ppc_instr_type_e
uint32_t flags; // xe_ppc_instr_flag_e
public:
uint32_t opcode;
uint32_t opcode_mask; // Only used for certain opcodes (altivec, etc).
uint32_t format; // xe_ppc_instr_format_e
uint32_t type; // xe_ppc_instr_type_e
uint32_t flags; // xe_ppc_instr_flag_e
InstrDisasmFn disasm;
char name[16];
char name[16];
InstrEmitFn emit;
InstrEmitFn emit;
};
InstrType* GetInstrType(uint32_t code);
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);
} // namespace ppc
} // namespace frontend
} // namespace alloy
#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/runtime/runtime.h>
using namespace alloy;
using namespace alloy::frontend;
using namespace alloy::frontend::ppc;
using namespace alloy::runtime;
namespace alloy {
namespace frontend {
namespace ppc {
using alloy::runtime::FunctionInfo;
PPCScanner::PPCScanner(PPCFrontend* frontend) :
frontend_(frontend) {
}
PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {}
PPCScanner::~PPCScanner() {
}
PPCScanner::~PPCScanner() {}
bool PPCScanner::IsRestGprLr(uint64_t address) {
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
// of whether or not this is a normal function with a prolog/epilog.
// Some valid leaf functions won't have this, but most will.
if (address == start_address &&
i.type &&
i.type->opcode == 0x7C0002A6 &&
if (address == start_address && i.type && i.type->opcode == 0x7C0002A6 &&
(((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F)) == 8) {
starts_with_mfspr_lr = true;
}
@@ -104,8 +99,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// This is generally a return.
if (furthest_target > address) {
// Remaining targets within function, not end.
XELOGSDB("ignoring blr %.8X (branch to %.8X)",
address, furthest_target);
XELOGSDB("ignoring blr %.8X (branch to %.8X)", address,
furthest_target);
} else {
// Function end point.
XELOGSDB("function end %.8X", address);
@@ -131,7 +126,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// b/ba/bl/bla
uint32_t target =
(uint32_t)XEEXTS26(i.I.LI << 2) + (i.I.AA ? 0 : (int32_t)address);
if (i.I.LK) {
XELOGSDB("bl %.8X -> %.8X", address, target);
// Queue call target if needed.
@@ -142,16 +137,15 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// If the target is back into the function and there's no further target
// we are at the end of a function.
// (Indirect branches may still go beyond, but no way of knowing).
if (target >= start_address &&
target < address && furthest_target <= address) {
if (target >= start_address && target < address &&
furthest_target <= address) {
XELOGSDB("function end %.8X (back b)", address);
ends_fn = true;
}
// If the target is not a branch and it goes to before the current
// address it's definitely a tail call.
if (!ends_fn &&
target < start_address && furthest_target <= address) {
if (!ends_fn && target < start_address && furthest_target <= address) {
XELOGSDB("function end %.8X (back b before addr)", address);
ends_fn = true;
}
@@ -160,9 +154,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// Note that sometimes functions stick this in a basic block *inside*
// of the function somewhere, so ensure we don't have any branches over
// it.
if (!ends_fn &&
furthest_target <= address &&
IsRestGprLr(target)) {
if (!ends_fn && furthest_target <= address && IsRestGprLr(target)) {
XELOGSDB("function end %.8X (__restgprlr_*)", address);
ends_fn = true;
}
@@ -174,9 +166,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// b KeBugCheck
// This check may hit on functions that jump over data code, so only
// trigger this check in leaf functions (no mfspr lr/prolog).
if (!ends_fn &&
!starts_with_mfspr_lr &&
blocks_found == 1) {
if (!ends_fn && !starts_with_mfspr_lr && blocks_found == 1) {
XELOGSDB("HEURISTIC: ending at simple leaf thunk %.8X", address);
ends_fn = true;
}
@@ -206,7 +196,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// TODO(benvanik): perhaps queue up for a speculative check? I think
// we are running over tail-call functions here that branch to
// somewhere else.
//GetOrInsertFunction(target);
// GetOrInsertFunction(target);
}
}
ends_block = true;
@@ -220,7 +210,7 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// Queue call target if needed.
// TODO(benvanik): see if this is correct - not sure anyone makes
// function calls with bcl.
//GetOrInsertFunction(target);
// GetOrInsertFunction(target);
} else {
XELOGSDB("bc %.8X -> %.8X", address, target);
@@ -259,8 +249,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
address += 4;
if (end_address && address > end_address) {
// Hmm....
XELOGSDB("Ran over function bounds! %.8X-%.8X",
start_address, end_address);
XELOGSDB("Ran over function bounds! %.8X-%.8X", start_address,
end_address);
break;
}
}
@@ -270,8 +260,8 @@ int PPCScanner::FindExtents(FunctionInfo* symbol_info) {
// 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
// function below this one.
XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X",
start_address, end_address, address + 4);
XELOGSDB("Function ran under: %.8X-%.8X ended at %.8X", start_address,
end_address, address + 4);
}
symbol_info->set_end_address(address);
@@ -300,8 +290,7 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
bool in_block = false;
uint64_t block_start = 0;
InstrData i;
for (uint64_t address = start_address;
address <= end_address; address += 4) {
for (uint64_t address = start_address; address <= end_address; address += 4) {
i.address = address;
i.code = XEGETUINT32BE(p + address);
if (!i.code) {
@@ -330,12 +319,12 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
ends_block = true;
} else if (i.type->opcode == 0x48000000) {
// b/ba/bl/bla
//uint32_t target =
// uint32_t target =
// (uint32_t)XEEXTS26(i.I.LI << 2) + (i.I.AA ? 0 : (int32_t)address);
ends_block = true;
} else if (i.type->opcode == 0x40000000) {
// bc/bca/bcl/bcla
//uint32_t target =
// uint32_t target =
// (uint32_t)XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)address);
ends_block = true;
} else if (i.type->opcode == 0x4C000020) {
@@ -349,16 +338,14 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
if (ends_block) {
in_block = false;
block_map[block_start] = {
block_start,
address,
block_start, address,
};
}
}
if (in_block) {
block_map[block_start] = {
block_start,
end_address,
block_start, end_address,
};
}
@@ -368,3 +355,7 @@ std::vector<BlockInfo> PPCScanner::FindBlocks(FunctionInfo* symbol_info) {
}
return blocks;
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@@ -13,7 +13,6 @@
#include <alloy/core.h>
#include <alloy/runtime/symbol_info.h>
namespace alloy {
namespace frontend {
namespace ppc {
@@ -25,9 +24,8 @@ typedef struct BlockInfo_t {
uint64_t end_address;
} BlockInfo;
class PPCScanner {
public:
public:
PPCScanner(PPCFrontend* frontend);
~PPCScanner();
@@ -35,17 +33,15 @@ public:
std::vector<BlockInfo> FindBlocks(runtime::FunctionInfo* symbol_info);
private:
private:
bool IsRestGprLr(uint64_t address);
private:
private:
PPCFrontend* frontend_;
};
} // namespace ppc
} // namespace frontend
} // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_SCANNER_H_

View File

@@ -19,17 +19,20 @@
#include <alloy/frontend/ppc/ppc_scanner.h>
#include <alloy/runtime/runtime.h>
using namespace alloy;
using namespace alloy::backend;
using namespace alloy::compiler;
using namespace alloy::frontend;
using namespace alloy::frontend::ppc;
using namespace alloy::hir;
namespace alloy {
namespace frontend {
namespace ppc {
// TODO(benvanik): remove when enums redefined.
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) :
frontend_(frontend) {
PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
Backend* backend = frontend->runtime()->backend();
scanner_ = new PPCScanner(frontend);
@@ -54,21 +57,21 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) :
if (validate) compiler_->AddPass(new passes::ValidationPass());
compiler_->AddPass(new passes::SimplificationPass());
if (validate) compiler_->AddPass(new passes::ValidationPass());
//compiler_->AddPass(new passes::DeadStoreEliminationPass());
//if (validate) compiler_->AddPass(new passes::ValidationPass());
// compiler_->AddPass(new passes::DeadStoreEliminationPass());
// if (validate) compiler_->AddPass(new passes::ValidationPass());
compiler_->AddPass(new passes::DeadCodeEliminationPass());
if (validate) compiler_->AddPass(new passes::ValidationPass());
//// Removes all unneeded variables. Try not to add new ones after this.
//compiler_->AddPass(new passes::ValueReductionPass());
//if (validate) compiler_->AddPass(new passes::ValidationPass());
// compiler_->AddPass(new passes::ValueReductionPass());
// if (validate) compiler_->AddPass(new passes::ValidationPass());
// Register allocation for the target backend.
// Will modify the HIR to add loads/stores.
// This should be the last pass before finalization, as after this all
// registers are assigned and ready to be emitted.
compiler_->AddPass(new passes::RegisterAllocationPass(
backend->machine_info()));
compiler_->AddPass(
new passes::RegisterAllocationPass(backend->machine_info()));
if (validate) compiler_->AddPass(new passes::ValidationPass());
// Must come last. The HIR is not really HIR after this.
@@ -82,10 +85,9 @@ PPCTranslator::~PPCTranslator() {
delete scanner_;
}
int PPCTranslator::Translate(
FunctionInfo* symbol_info,
uint32_t debug_info_flags,
Function** out_function) {
int PPCTranslator::Translate(FunctionInfo* symbol_info,
uint32_t debug_info_flags,
Function** out_function) {
SCOPE_profile_cpu_f("alloy");
// Scan the function to find its extents. We only need to do this if we
@@ -139,10 +141,8 @@ int PPCTranslator::Translate(
}
// Assemble to backend machine code.
result = assembler_->Assemble(
symbol_info, builder_,
debug_info_flags, debug_info,
out_function);
result = assembler_->Assemble(symbol_info, builder_, debug_info_flags,
debug_info, out_function);
XEEXPECTZERO(result);
result = 0;
@@ -158,15 +158,14 @@ XECLEANUP:
return result;
};
void PPCTranslator::DumpSource(
runtime::FunctionInfo* symbol_info, StringBuffer* string_buffer) {
void PPCTranslator::DumpSource(runtime::FunctionInfo* symbol_info,
StringBuffer* string_buffer) {
Memory* memory = frontend_->memory();
const uint8_t* p = memory->membase();
string_buffer->Append("%s fn %.8X-%.8X %s\n",
symbol_info->module()->name(),
symbol_info->address(), symbol_info->end_address(),
symbol_info->name());
string_buffer->Append("%s fn %.8X-%.8X %s\n", symbol_info->module()->name(),
symbol_info->address(), symbol_info->end_address(),
symbol_info->name());
auto blocks = scanner_->FindBlocks(symbol_info);
@@ -182,10 +181,8 @@ void PPCTranslator::DumpSource(
i.type = GetInstrType(i.code);
// Check labels.
if (block_it != blocks.end() &&
block_it->start_address == address) {
string_buffer->Append(
"%.8X loc_%.8X:\n", address, address);
if (block_it != blocks.end() && block_it->start_address == address) {
string_buffer->Append("%.8X loc_%.8X:\n", address, address);
++block_it;
}
@@ -194,3 +191,7 @@ void PPCTranslator::DumpSource(
string_buffer->Append("\n");
}
}
} // namespace ppc
} // namespace frontend
} // namespace alloy

View File

@@ -15,7 +15,6 @@
#include <alloy/compiler/compiler.h>
#include <alloy/runtime/symbol_info.h>
namespace alloy {
namespace frontend {
namespace ppc {
@@ -24,34 +23,30 @@ class PPCFrontend;
class PPCHIRBuilder;
class PPCScanner;
class PPCTranslator {
public:
public:
PPCTranslator(PPCFrontend* frontend);
~PPCTranslator();
int Translate(runtime::FunctionInfo* symbol_info,
uint32_t debug_info_flags,
int Translate(runtime::FunctionInfo* symbol_info, uint32_t debug_info_flags,
runtime::Function** out_function);
private:
private:
void DumpSource(runtime::FunctionInfo* symbol_info,
StringBuffer* string_buffer);
private:
PPCFrontend* frontend_;
PPCScanner* scanner_;
PPCHIRBuilder* builder_;
compiler::Compiler* compiler_;
backend::Assembler* assembler_;
private:
PPCFrontend* frontend_;
PPCScanner* scanner_;
PPCHIRBuilder* builder_;
compiler::Compiler* compiler_;
backend::Assembler* assembler_;
StringBuffer string_buffer_;
StringBuffer string_buffer_;
};
} // namespace ppc
} // namespace frontend
} // namespace alloy
#endif // ALLOY_FRONTEND_PPC_PPC_TRANSLATOR_H_

View File

@@ -13,18 +13,16 @@
#include <alloy/tracing/tracing.h>
#include <alloy/tracing/event_type.h>
namespace alloy {
namespace frontend {
const uint32_t ALLOY_FRONTEND = alloy::tracing::EventType::ALLOY_FRONTEND;
class EventType {
public:
public:
enum {
ALLOY_FRONTEND_INIT = ALLOY_FRONTEND | (1),
ALLOY_FRONTEND_DEINIT = ALLOY_FRONTEND | (2),
ALLOY_FRONTEND_INIT = ALLOY_FRONTEND | (1),
ALLOY_FRONTEND_DEINIT = ALLOY_FRONTEND | (2),
};
typedef struct Init_s {
@@ -35,9 +33,7 @@ public:
} Deinit;
};
} // namespace frontend
} // namespace alloy
#endif // ALLOY_FRONTEND_TRACING_H_