Renaming xe::cpu::frontend to xe::cpu::ppc.
This commit is contained in:
155
src/xenia/cpu/ppc/ppc_context.cc
Normal file
155
src/xenia/cpu/ppc/ppc_context.cc
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_context.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/string_util.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
std::string PPCContext::GetRegisterName(PPCRegister reg) {
|
||||
switch (reg) {
|
||||
case PPCRegister::kLR:
|
||||
return "lr";
|
||||
case PPCRegister::kCTR:
|
||||
return "ctr";
|
||||
case PPCRegister::kXER:
|
||||
return "xer";
|
||||
case PPCRegister::kFPSCR:
|
||||
return "fpscr";
|
||||
case PPCRegister::kVSCR:
|
||||
return "vscr";
|
||||
case PPCRegister::kCR:
|
||||
return "cr";
|
||||
default:
|
||||
if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kR0) &&
|
||||
static_cast<int>(reg) <= static_cast<int>(PPCRegister::kR31)) {
|
||||
return std::string("r") +
|
||||
std::to_string(static_cast<int>(reg) -
|
||||
static_cast<int>(PPCRegister::kR0));
|
||||
} else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kFR0) &&
|
||||
static_cast<int>(reg) <=
|
||||
static_cast<int>(PPCRegister::kFR31)) {
|
||||
return std::string("fr") +
|
||||
std::to_string(static_cast<int>(reg) -
|
||||
static_cast<int>(PPCRegister::kFR0));
|
||||
} else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kVR0) &&
|
||||
static_cast<int>(reg) <=
|
||||
static_cast<int>(PPCRegister::kVR128)) {
|
||||
return std::string("vr") +
|
||||
std::to_string(static_cast<int>(reg) -
|
||||
static_cast<int>(PPCRegister::kVR0));
|
||||
} else {
|
||||
assert_unhandled_case(reg);
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string PPCContext::GetStringFromValue(PPCRegister reg) const {
|
||||
switch (reg) {
|
||||
case PPCRegister::kLR:
|
||||
return string_util::to_hex_string(lr);
|
||||
case PPCRegister::kCTR:
|
||||
return string_util::to_hex_string(ctr);
|
||||
case PPCRegister::kXER:
|
||||
// return Int64ToHex(xer_ca);
|
||||
return "?";
|
||||
case PPCRegister::kFPSCR:
|
||||
// return Int64ToHex(fpscr);
|
||||
return "?";
|
||||
case PPCRegister::kVSCR:
|
||||
// return Int64ToHex(vscr_sat);
|
||||
return "?";
|
||||
case PPCRegister::kCR:
|
||||
// return Int64ToHex(cr);
|
||||
return "?";
|
||||
default:
|
||||
if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kR0) &&
|
||||
static_cast<int>(reg) <= static_cast<int>(PPCRegister::kR31)) {
|
||||
return string_util::to_hex_string(
|
||||
r[static_cast<int>(reg) - static_cast<int>(PPCRegister::kR0)]);
|
||||
} else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kFR0) &&
|
||||
static_cast<int>(reg) <=
|
||||
static_cast<int>(PPCRegister::kFR31)) {
|
||||
return string_util::to_hex_string(
|
||||
f[static_cast<int>(reg) - static_cast<int>(PPCRegister::kFR0)]);
|
||||
} else if (static_cast<int>(reg) >= static_cast<int>(PPCRegister::kVR0) &&
|
||||
static_cast<int>(reg) <=
|
||||
static_cast<int>(PPCRegister::kVR128)) {
|
||||
return string_util::to_hex_string(
|
||||
v[static_cast<int>(reg) - static_cast<int>(PPCRegister::kVR0)]);
|
||||
} else {
|
||||
assert_unhandled_case(reg);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PPCContext::SetValueFromString(PPCRegister reg, std::string value) {
|
||||
// TODO(benvanik): set value from string to replace SetRegFromString?
|
||||
assert_always(false);
|
||||
}
|
||||
|
||||
void PPCContext::SetRegFromString(const char* name, const char* value) {
|
||||
int n;
|
||||
if (sscanf(name, "r%d", &n) == 1) {
|
||||
this->r[n] = string_util::from_string<uint64_t>(value);
|
||||
} else if (sscanf(name, "f%d", &n) == 1) {
|
||||
this->f[n] = string_util::from_string<double>(value);
|
||||
} else if (sscanf(name, "v%d", &n) == 1) {
|
||||
this->v[n] = string_util::from_string<vec128_t>(value);
|
||||
} else {
|
||||
printf("Unrecognized register name: %s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
bool PPCContext::CompareRegWithString(const char* name, const char* value,
|
||||
char* out_value,
|
||||
size_t out_value_size) const {
|
||||
int n;
|
||||
if (sscanf(name, "r%d", &n) == 1) {
|
||||
uint64_t expected = string_util::from_string<uint64_t>(value);
|
||||
if (this->r[n] != expected) {
|
||||
std::snprintf(out_value, out_value_size, "%016" PRIX64, this->r[n]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else if (sscanf(name, "f%d", &n) == 1) {
|
||||
double expected = string_util::from_string<double>(value);
|
||||
// TODO(benvanik): epsilon
|
||||
if (this->f[n] != expected) {
|
||||
std::snprintf(out_value, out_value_size, "%f", this->f[n]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else if (sscanf(name, "v%d", &n) == 1) {
|
||||
vec128_t expected = string_util::from_string<vec128_t>(value);
|
||||
if (this->v[n] != expected) {
|
||||
std::snprintf(out_value, out_value_size, "[%.8X, %.8X, %.8X, %.8X]",
|
||||
this->v[n].i32[0], this->v[n].i32[1], this->v[n].i32[2],
|
||||
this->v[n].i32[3]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
assert_always("Unrecognized register name: %s\n", name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
442
src/xenia/cpu/ppc/ppc_context.h
Normal file
442
src/xenia/cpu/ppc/ppc_context.h
Normal file
@@ -0,0 +1,442 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_CONTEXT_H_
|
||||
#define XENIA_CPU_PPC_PPC_CONTEXT_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "xenia/base/vec128.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
class Processor;
|
||||
class ThreadState;
|
||||
} // namespace cpu
|
||||
namespace kernel {
|
||||
class KernelState;
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
// Map:
|
||||
// 0-31: GPR
|
||||
// 32-63: FPR
|
||||
// 64: LR
|
||||
// 65: CTR
|
||||
// 66: XER
|
||||
// 67: FPSCR
|
||||
// 68: VSCR
|
||||
// 69-76: CR0-7
|
||||
// 100: invalid
|
||||
// 128-256: VR
|
||||
|
||||
enum class PPCRegister {
|
||||
kR0 = 0,
|
||||
kR1,
|
||||
kR2,
|
||||
kR3,
|
||||
kR4,
|
||||
kR5,
|
||||
kR6,
|
||||
kR7,
|
||||
kR8,
|
||||
kR9,
|
||||
kR10,
|
||||
kR11,
|
||||
kR12,
|
||||
kR13,
|
||||
kR14,
|
||||
kR15,
|
||||
kR16,
|
||||
kR17,
|
||||
kR18,
|
||||
kR19,
|
||||
kR20,
|
||||
kR21,
|
||||
kR22,
|
||||
kR23,
|
||||
kR24,
|
||||
kR25,
|
||||
kR26,
|
||||
kR27,
|
||||
kR28,
|
||||
kR29,
|
||||
kR30,
|
||||
kR31,
|
||||
kFR0 = 32,
|
||||
kFR1,
|
||||
kFR2,
|
||||
kFR3,
|
||||
kFR4,
|
||||
kFR5,
|
||||
kFR6,
|
||||
kFR7,
|
||||
kFR8,
|
||||
kFR9,
|
||||
kFR10,
|
||||
kFR11,
|
||||
kFR12,
|
||||
kFR13,
|
||||
kFR14,
|
||||
kFR15,
|
||||
kFR16,
|
||||
kFR17,
|
||||
kFR18,
|
||||
kFR19,
|
||||
kFR20,
|
||||
kFR21,
|
||||
kFR22,
|
||||
kFR23,
|
||||
kFR24,
|
||||
kFR25,
|
||||
kFR26,
|
||||
kFR27,
|
||||
kFR28,
|
||||
kFR29,
|
||||
kFR30,
|
||||
kFR31,
|
||||
kVR0 = 64,
|
||||
kVR1,
|
||||
kVR2,
|
||||
kVR3,
|
||||
kVR4,
|
||||
kVR5,
|
||||
kVR6,
|
||||
kVR7,
|
||||
kVR8,
|
||||
kVR9,
|
||||
kVR10,
|
||||
kVR11,
|
||||
kVR12,
|
||||
kVR13,
|
||||
kVR14,
|
||||
kVR15,
|
||||
kVR16,
|
||||
kVR17,
|
||||
kVR18,
|
||||
kVR19,
|
||||
kVR20,
|
||||
kVR21,
|
||||
kVR22,
|
||||
kVR23,
|
||||
kVR24,
|
||||
kVR25,
|
||||
kVR26,
|
||||
kVR27,
|
||||
kVR28,
|
||||
kVR29,
|
||||
kVR30,
|
||||
kVR31,
|
||||
kVR32,
|
||||
kVR33,
|
||||
kVR34,
|
||||
kVR35,
|
||||
kVR36,
|
||||
kVR37,
|
||||
kVR38,
|
||||
kVR39,
|
||||
kVR40,
|
||||
kVR41,
|
||||
kVR42,
|
||||
kVR43,
|
||||
kVR44,
|
||||
kVR45,
|
||||
kVR46,
|
||||
kVR47,
|
||||
kVR48,
|
||||
kVR49,
|
||||
kVR50,
|
||||
kVR51,
|
||||
kVR52,
|
||||
kVR53,
|
||||
kVR54,
|
||||
kVR55,
|
||||
kVR56,
|
||||
kVR57,
|
||||
kVR58,
|
||||
kVR59,
|
||||
kVR60,
|
||||
kVR61,
|
||||
kVR62,
|
||||
kVR63,
|
||||
kVR64,
|
||||
kVR65,
|
||||
kVR66,
|
||||
kVR67,
|
||||
kVR68,
|
||||
kVR69,
|
||||
kVR70,
|
||||
kVR71,
|
||||
kVR72,
|
||||
kVR73,
|
||||
kVR74,
|
||||
kVR75,
|
||||
kVR76,
|
||||
kVR77,
|
||||
kVR78,
|
||||
kVR79,
|
||||
kVR80,
|
||||
kVR81,
|
||||
kVR82,
|
||||
kVR83,
|
||||
kVR84,
|
||||
kVR85,
|
||||
kVR86,
|
||||
kVR87,
|
||||
kVR88,
|
||||
kVR89,
|
||||
kVR90,
|
||||
kVR91,
|
||||
kVR92,
|
||||
kVR93,
|
||||
kVR94,
|
||||
kVR95,
|
||||
kVR96,
|
||||
kVR97,
|
||||
kVR98,
|
||||
kVR99,
|
||||
kVR100,
|
||||
kVR101,
|
||||
kVR102,
|
||||
kVR103,
|
||||
kVR104,
|
||||
kVR105,
|
||||
kVR106,
|
||||
kVR107,
|
||||
kVR108,
|
||||
kVR109,
|
||||
kVR110,
|
||||
kVR111,
|
||||
kVR112,
|
||||
kVR113,
|
||||
kVR114,
|
||||
kVR115,
|
||||
kVR116,
|
||||
kVR117,
|
||||
kVR118,
|
||||
kVR119,
|
||||
kVR120,
|
||||
kVR121,
|
||||
kVR122,
|
||||
kVR123,
|
||||
kVR124,
|
||||
kVR125,
|
||||
kVR126,
|
||||
kVR127,
|
||||
kVR128,
|
||||
|
||||
kLR,
|
||||
kCTR,
|
||||
kXER,
|
||||
kFPSCR,
|
||||
kVSCR,
|
||||
kCR,
|
||||
};
|
||||
|
||||
#pragma pack(push, 8)
|
||||
typedef struct PPCContext_s {
|
||||
// Must be stored at 0x0 for now.
|
||||
// TODO(benvanik): find a nice way to describe this to the JIT.
|
||||
ThreadState* thread_state;
|
||||
// TODO(benvanik): this is getting nasty. Must be here.
|
||||
uint8_t* virtual_membase;
|
||||
|
||||
// Most frequently used registers first.
|
||||
uint64_t lr; // Link register
|
||||
uint64_t ctr; // Count register
|
||||
uint64_t r[32]; // General purpose registers
|
||||
double f[32]; // Floating-point registers
|
||||
vec128_t v[128]; // VMX128 vector registers
|
||||
|
||||
// XER register
|
||||
// Split to make it easier to do individual updates.
|
||||
uint8_t xer_ca;
|
||||
uint8_t xer_ov;
|
||||
uint8_t xer_so;
|
||||
|
||||
// Condition registers
|
||||
// These are split to make it easier to do DCE on unused stores.
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t cr0_lt; // Negative (LT) - result is negative
|
||||
uint8_t cr0_gt; // Positive (GT) - result is positive (and not zero)
|
||||
uint8_t cr0_eq; // Zero (EQ) - result is zero or a stwcx/stdcx completed
|
||||
// successfully
|
||||
uint8_t cr0_so; // Summary Overflow (SO) - copy of XER[SO]
|
||||
};
|
||||
} cr0;
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t cr1_fx; // FP exception summary - copy of FPSCR[FX]
|
||||
uint8_t cr1_fex; // FP enabled exception summary - copy of FPSCR[FEX]
|
||||
uint8_t
|
||||
cr1_vx; // FP invalid operation exception summary - copy of FPSCR[VX]
|
||||
uint8_t cr1_ox; // FP overflow exception - copy of FPSCR[OX]
|
||||
};
|
||||
} cr1;
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t cr2_0;
|
||||
uint8_t cr2_1;
|
||||
uint8_t cr2_2;
|
||||
uint8_t cr2_3;
|
||||
};
|
||||
} cr2;
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t cr3_0;
|
||||
uint8_t cr3_1;
|
||||
uint8_t cr3_2;
|
||||
uint8_t cr3_3;
|
||||
};
|
||||
} cr3;
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t cr4_0;
|
||||
uint8_t cr4_1;
|
||||
uint8_t cr4_2;
|
||||
uint8_t cr4_3;
|
||||
};
|
||||
} cr4;
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t cr5_0;
|
||||
uint8_t cr5_1;
|
||||
uint8_t cr5_2;
|
||||
uint8_t cr5_3;
|
||||
};
|
||||
} cr5;
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t cr6_all_equal;
|
||||
uint8_t cr6_1;
|
||||
uint8_t cr6_none_equal;
|
||||
uint8_t cr6_3;
|
||||
};
|
||||
} cr6;
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t cr7_0;
|
||||
uint8_t cr7_1;
|
||||
uint8_t cr7_2;
|
||||
uint8_t cr7_3;
|
||||
};
|
||||
} cr7;
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t rn : 2; // FP rounding control: 00 = nearest
|
||||
// 01 = toward zero
|
||||
// 10 = toward +infinity
|
||||
// 11 = toward -infinity
|
||||
uint32_t ni : 1; // Floating-point non-IEEE mode
|
||||
uint32_t xe : 1; // IEEE floating-point inexact exception enable
|
||||
uint32_t ze : 1; // IEEE floating-point zero divide exception enable
|
||||
uint32_t ue : 1; // IEEE floating-point underflow exception enable
|
||||
uint32_t oe : 1; // IEEE floating-point overflow exception enable
|
||||
uint32_t ve : 1; // FP invalid op exception enable
|
||||
uint32_t vxcvi : 1; // FP invalid op exception: invalid integer convert
|
||||
// -- sticky
|
||||
uint32_t vxsqrt : 1; // FP invalid op exception: invalid sqrt -- sticky
|
||||
uint32_t vxsoft : 1; // FP invalid op exception: software request
|
||||
// -- sticky
|
||||
uint32_t reserved : 1;
|
||||
uint32_t fprf_un : 1; // FP result unordered or NaN (FU or ?)
|
||||
uint32_t fprf_eq : 1; // FP result equal or zero (FE or =)
|
||||
uint32_t fprf_gt : 1; // FP result greater than or positive (FG or >)
|
||||
uint32_t fprf_lt : 1; // FP result less than or negative (FL or <)
|
||||
uint32_t fprf_c : 1; // FP result class
|
||||
uint32_t fi : 1; // FP fraction inexact
|
||||
uint32_t fr : 1; // FP fraction rounded
|
||||
uint32_t vxvc : 1; // FP invalid op exception: invalid compare --
|
||||
// sticky
|
||||
uint32_t vximz : 1; // FP invalid op exception: infinity * 0 -- sticky
|
||||
uint32_t vxzdz : 1; // FP invalid op exception: 0 / 0 -- sticky
|
||||
uint32_t vxidi : 1; // FP invalid op exception: infinity / infinity
|
||||
// -- sticky
|
||||
uint32_t vxisi : 1; // FP invalid op exception: infinity - infinity
|
||||
// -- sticky
|
||||
uint32_t vxsnan : 1; // FP invalid op exception: SNaN -- sticky
|
||||
uint32_t
|
||||
xx : 1; // FP inexact exception -- sticky
|
||||
uint32_t
|
||||
zx : 1; // FP zero divide exception -- sticky
|
||||
uint32_t
|
||||
ux : 1; // FP underflow exception -- sticky
|
||||
uint32_t
|
||||
ox : 1; // FP overflow exception -- sticky
|
||||
uint32_t vx : 1; // FP invalid operation exception summary
|
||||
uint32_t fex : 1; // FP enabled exception summary
|
||||
uint32_t
|
||||
fx : 1; // FP exception summary -- sticky
|
||||
} bits;
|
||||
} fpscr; // Floating-point status and control register
|
||||
|
||||
uint8_t vscr_sat;
|
||||
|
||||
// uint32_t get_fprf() {
|
||||
// return fpscr.value & 0x000F8000;
|
||||
// }
|
||||
// void set_fprf(const uint32_t v) {
|
||||
// fpscr.value = (fpscr.value & ~0x000F8000) | v;
|
||||
// }
|
||||
|
||||
// Thread ID assigned to this context.
|
||||
uint32_t thread_id;
|
||||
|
||||
// Global interrupt lock, held while interrupts are disabled or interrupts are
|
||||
// executing. This is shared among all threads and comes from the processor.
|
||||
std::recursive_mutex* global_mutex;
|
||||
|
||||
// Used to shuttle data into externs. Contents volatile.
|
||||
uint64_t scratch;
|
||||
|
||||
// Processor-specific data pointer. Used on callbacks to get access to the
|
||||
// current runtime and its data.
|
||||
Processor* processor;
|
||||
|
||||
// Shared kernel state, for easy access from kernel exports.
|
||||
xe::kernel::KernelState* kernel_state;
|
||||
|
||||
uint8_t* physical_membase;
|
||||
|
||||
// Keep the struct padded out to 64b total.
|
||||
uint8_t _padding[8];
|
||||
|
||||
static std::string GetRegisterName(PPCRegister reg);
|
||||
std::string GetStringFromValue(PPCRegister reg) const;
|
||||
void SetValueFromString(PPCRegister reg, std::string value);
|
||||
|
||||
void SetRegFromString(const char* name, const char* value);
|
||||
bool CompareRegWithString(const char* name, const char* value,
|
||||
char* out_value, size_t out_value_size) const;
|
||||
} PPCContext;
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(PPCContext) % 64 == 0, "64b padded");
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_CONTEXT_H_
|
||||
519
src/xenia/cpu/ppc/ppc_disasm.cc
Normal file
519
src/xenia/cpu/ppc/ppc_disasm.cc
Normal file
@@ -0,0 +1,519 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_disasm.h"
|
||||
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/string_buffer.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
void Disasm_0(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-8s ???", i->type->name);
|
||||
}
|
||||
|
||||
void Disasm__(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-8s", i->type->name);
|
||||
}
|
||||
|
||||
void Disasm_X_FRT_FRB(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%-8s r%d, r%d, r%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->AppendFormat("%-8s r%d, r%d, r%d", i->type->name, i->X.RT, i->X.RA,
|
||||
i->X.RB);
|
||||
} else {
|
||||
str->AppendFormat("%-8s r%d, 0, r%d", i->type->name, i->X.RT, i->X.RB);
|
||||
}
|
||||
}
|
||||
void Disasm_X_FRT_RA_RB(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-8s f%d, r%d, r%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->AppendFormat("%-8s f%d, r%d, r%d", i->type->name, i->X.RT, i->X.RA,
|
||||
i->X.RB);
|
||||
} else {
|
||||
str->AppendFormat("%-8s f%d, 0, r%d", i->type->name, i->X.RT, i->X.RB);
|
||||
}
|
||||
}
|
||||
void Disasm_D_RT_RA_I(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-8s r%d", i->type->name, i->D.RA);
|
||||
}
|
||||
void Disasm_X_RA_RB(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-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->AppendFormat("%*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);
|
||||
}
|
||||
void Disasm_XO_RT_RA(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%*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);
|
||||
}
|
||||
void Disasm_X_RA_RT_RB(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%*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->AppendFormat("%-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->AppendFormat("%*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 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_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_VB128 (i->VX128_2.VB128l | (i->VX128_2.VB128h << 5))
|
||||
#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_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_VB128 (i->VX128_5.VB128l | (i->VX128_5.VB128h << 5))
|
||||
#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_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->AppendFormat("%-8s v%d, r%d, r%d", i->type->name, i->X.RT, i->X.RA,
|
||||
i->X.RB);
|
||||
} else {
|
||||
str->AppendFormat("%-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->AppendFormat("%-8s v%d, r%d, r%d", i->type->name, vd, i->VX128_1.RA,
|
||||
i->VX128_1.RB);
|
||||
} else {
|
||||
str->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-8s v%d, v%d, %.2Xh", i->type->name, vd, va, uimm);
|
||||
}
|
||||
void Disasm_VX_VD_VA_VB(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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;
|
||||
}
|
||||
str->AppendFormat("%-8s %.2X", name, L);
|
||||
}
|
||||
|
||||
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;
|
||||
default:
|
||||
name = "dcbf.??";
|
||||
break;
|
||||
}
|
||||
str->AppendFormat("%-8s r%d, r%d", name, i->X.RA, i->X.RB);
|
||||
}
|
||||
|
||||
void Disasm_dcbz(InstrData* i, StringBuffer* str) {
|
||||
// or dcbz128 0x7C2007EC
|
||||
if (i->X.RA) {
|
||||
str->AppendFormat("%-8s r%d, r%d", i->type->name, i->X.RA, i->X.RB);
|
||||
} else {
|
||||
str->AppendFormat("%-8s 0, r%d", i->type->name, i->X.RB);
|
||||
}
|
||||
}
|
||||
|
||||
void Disasm_fcmp(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-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->AppendFormat("%*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) {
|
||||
const char* name = i->I.LK ? "bl" : "b";
|
||||
uint32_t nia;
|
||||
if (i->I.AA) {
|
||||
nia = (uint32_t)XEEXTS26(i->I.LI << 2);
|
||||
} else {
|
||||
nia = (uint32_t)(i->address + XEEXTS26(i->I.LI << 2));
|
||||
}
|
||||
str->AppendFormat("%-8s %.8X", name, nia);
|
||||
// TODO(benvanik): resolve target name?
|
||||
}
|
||||
void Disasm_bcx(InstrData* i, StringBuffer* str) {
|
||||
const char* s0 = i->B.LK ? "lr, " : "";
|
||||
const char* s1;
|
||||
if (!select_bits(i->B.BO, 2, 2)) {
|
||||
s1 = "ctr, ";
|
||||
} else {
|
||||
s1 = "";
|
||||
}
|
||||
char s2[8] = {0};
|
||||
if (!select_bits(i->B.BO, 4, 4)) {
|
||||
snprintf(s2, xe::countof(s2), "cr%d, ", i->B.BI >> 2);
|
||||
}
|
||||
uint32_t nia;
|
||||
if (i->B.AA) {
|
||||
nia = (uint32_t)XEEXTS16(i->B.BD << 2);
|
||||
} else {
|
||||
nia = (uint32_t)(i->address + XEEXTS16(i->B.BD << 2));
|
||||
}
|
||||
str->AppendFormat("%-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] = {0};
|
||||
if (!select_bits(i->XL.BO, 4, 4)) {
|
||||
snprintf(s2, xe::countof(s2), "cr%d, ", i->XL.BI >> 2);
|
||||
}
|
||||
str->AppendFormat("%-8s %s%sctr", i->type->name, s0, s2);
|
||||
// TODO(benvanik): resolve target name?
|
||||
}
|
||||
void Disasm_bclrx(InstrData* i, StringBuffer* str) {
|
||||
const char* name = "bclr";
|
||||
if (i->code == 0x4E800020) {
|
||||
name = "blr";
|
||||
}
|
||||
const char* s1;
|
||||
if (!select_bits(i->XL.BO, 2, 2)) {
|
||||
s1 = "ctr, ";
|
||||
} else {
|
||||
s1 = "";
|
||||
}
|
||||
char s2[8] = {0};
|
||||
if (!select_bits(i->XL.BO, 4, 4)) {
|
||||
snprintf(s2, xe::countof(s2), "cr%d, ", i->XL.BI >> 2);
|
||||
}
|
||||
str->AppendFormat("%-8s %s%s", name, s1, s2);
|
||||
}
|
||||
|
||||
void Disasm_mfcr(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-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;
|
||||
}
|
||||
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->AppendFormat("%-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->AppendFormat("%-8s %s, r%d", i->type->name, reg, i->XFX.RT);
|
||||
}
|
||||
void Disasm_mftb(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-8s r%d, tb", i->type->name, i->XFX.RT);
|
||||
}
|
||||
void Disasm_mfmsr(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-8s r%d", i->type->name, i->X.RT);
|
||||
}
|
||||
void Disasm_mtmsr(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-8s r%d, %d", i->type->name, i->X.RT,
|
||||
(i->X.RA & 16) ? 1 : 0);
|
||||
}
|
||||
|
||||
void Disasm_cmp(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%*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 {
|
||||
assert_always();
|
||||
}
|
||||
}
|
||||
void Disasm_rlwim(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%*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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-8s v%d, v%d, v%d, %.2X", i->type->name, vd, va, vb, sh);
|
||||
}
|
||||
void Disasm_vspltb(InstrData* i, StringBuffer* str) {
|
||||
str->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-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->AppendFormat("%-8s v%d, %.8X", i->type->name, i->VX.VD, simm);
|
||||
}
|
||||
|
||||
int DisasmPPC(InstrData* i, StringBuffer* str) {
|
||||
if (!i->type) {
|
||||
str->Append("???");
|
||||
} else {
|
||||
i->type->disasm(i, str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
26
src/xenia/cpu/ppc/ppc_disasm.h
Normal file
26
src/xenia/cpu/ppc/ppc_disasm.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_DISASM_H_
|
||||
#define XENIA_CPU_PPC_PPC_DISASM_H_
|
||||
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/cpu/ppc/ppc_instr.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
int DisasmPPC(InstrData* i, StringBuffer* str);
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_DISASM_H_
|
||||
34
src/xenia/cpu/ppc/ppc_emit-private.h
Normal file
34
src/xenia/cpu/ppc/ppc_emit-private.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_EMIT_PRIVATE_H_
|
||||
#define XENIA_CPU_PPC_PPC_EMIT_PRIVATE_H_
|
||||
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/cpu/ppc/ppc_emit.h"
|
||||
#include "xenia/cpu/ppc/ppc_instr.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
#define XEEMITTER(name, opcode, format) int InstrEmit_##name
|
||||
|
||||
#define XEREGISTERINSTR(name, opcode) \
|
||||
RegisterInstrEmit(opcode, (InstrEmitFn)InstrEmit_##name);
|
||||
|
||||
#define XEINSTRNOTIMPLEMENTED() \
|
||||
XELOGE("Unimplemented instruction: %s", __FUNCTION__); \
|
||||
assert_always("Instruction not implemented");
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_EMIT_PRIVATE_H_
|
||||
29
src/xenia/cpu/ppc/ppc_emit.h
Normal file
29
src/xenia/cpu/ppc/ppc_emit.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_EMIT_H_
|
||||
#define XENIA_CPU_PPC_PPC_EMIT_H_
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_instr.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
void RegisterEmitCategoryAltivec();
|
||||
void RegisterEmitCategoryALU();
|
||||
void RegisterEmitCategoryControl();
|
||||
void RegisterEmitCategoryFPU();
|
||||
void RegisterEmitCategoryMemory();
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_EMIT_H_
|
||||
2445
src/xenia/cpu/ppc/ppc_emit_altivec.cc
Normal file
2445
src/xenia/cpu/ppc/ppc_emit_altivec.cc
Normal file
File diff suppressed because it is too large
Load Diff
1309
src/xenia/cpu/ppc/ppc_emit_alu.cc
Normal file
1309
src/xenia/cpu/ppc/ppc_emit_alu.cc
Normal file
File diff suppressed because it is too large
Load Diff
793
src/xenia/cpu/ppc/ppc_emit_control.cc
Normal file
793
src/xenia/cpu/ppc/ppc_emit_control.cc
Normal file
@@ -0,0 +1,793 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_emit-private.h"
|
||||
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/cpu/ppc/ppc_context.h"
|
||||
#include "xenia/cpu/ppc/ppc_frontend.h"
|
||||
#include "xenia/cpu/ppc/ppc_hir_builder.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
// TODO(benvanik): remove when enums redefined.
|
||||
using namespace xe::cpu::hir;
|
||||
|
||||
using xe::cpu::hir::Label;
|
||||
using xe::cpu::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!
|
||||
// The docs say always, though...
|
||||
// Note that we do the update before we branch/call as we need it to
|
||||
// be correct for returns.
|
||||
if (lk) {
|
||||
Value* return_address = f.LoadConstantUint64(cia + 4);
|
||||
f.SetReturnAddress(return_address);
|
||||
f.StoreLR(return_address);
|
||||
}
|
||||
|
||||
if (!lk) {
|
||||
// If LR is not set this call will never return here.
|
||||
call_flags |= CALL_TAIL;
|
||||
}
|
||||
|
||||
// TODO(benvanik): set CALL_TAIL if !lk and the last block in the fn.
|
||||
// This is almost always a jump to restore gpr.
|
||||
|
||||
if (nia->IsConstant()) {
|
||||
// Direct branch to address.
|
||||
// If it's a block inside of ourself, setup a fast jump.
|
||||
// Unless it's to ourselves directly, in which case it's
|
||||
// recursion.
|
||||
uint32_t nia_value = nia->AsUint64() & 0xFFFFFFFF;
|
||||
bool is_recursion = false;
|
||||
if (nia_value == f.function()->address() && lk) {
|
||||
is_recursion = true;
|
||||
}
|
||||
Label* label = is_recursion ? NULL : f.LookupLabel(nia_value);
|
||||
if (label) {
|
||||
// Branch to label.
|
||||
uint32_t branch_flags = 0;
|
||||
if (cond) {
|
||||
if (expect_true) {
|
||||
f.BranchTrue(cond, label, branch_flags);
|
||||
} else {
|
||||
f.BranchFalse(cond, label, branch_flags);
|
||||
}
|
||||
} else {
|
||||
f.Branch(label, branch_flags);
|
||||
}
|
||||
} else {
|
||||
// Call function.
|
||||
auto function = f.LookupFunction(nia_value);
|
||||
if (cond) {
|
||||
if (!expect_true) {
|
||||
cond = f.IsFalse(cond);
|
||||
}
|
||||
f.CallTrue(cond, function, call_flags);
|
||||
} else {
|
||||
f.Call(function, call_flags);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Indirect branch to pointer.
|
||||
|
||||
// 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!
|
||||
|
||||
//// 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
|
||||
// so that we can just use this.
|
||||
if (!lk && nia_is_lr) {
|
||||
// Return (most likely).
|
||||
// TODO(benvanik): test? ReturnCheck()?
|
||||
if (cond) {
|
||||
if (!expect_true) {
|
||||
cond = f.IsFalse(cond);
|
||||
}
|
||||
f.ReturnTrue(cond);
|
||||
} else {
|
||||
f.Return();
|
||||
}
|
||||
} else {
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(bx, 0x48000000, I)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// if AA then
|
||||
// NIA <- EXTS(LI || 0b00)
|
||||
// else
|
||||
// NIA <- CIA + EXTS(LI || 0b00)
|
||||
// if LK then
|
||||
// LR <- CIA + 4
|
||||
|
||||
uint32_t nia;
|
||||
if (i.I.AA) {
|
||||
nia = (uint32_t)XEEXTS26(i.I.LI << 2);
|
||||
} else {
|
||||
nia = (uint32_t)(i.address + XEEXTS26(i.I.LI << 2));
|
||||
}
|
||||
|
||||
return InstrEmit_branch(f, "bx", i.address, f.LoadConstantUint32(nia),
|
||||
i.I.LK);
|
||||
}
|
||||
|
||||
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])
|
||||
// cond_ok <- BO[0] | (CR[BI+32] ≡ BO[1])
|
||||
// if ctr_ok & cond_ok then
|
||||
// if AA then
|
||||
// NIA <- EXTS(BD || 0b00)
|
||||
// else
|
||||
// NIA <- CIA + EXTS(BD || 0b00)
|
||||
// if LK then
|
||||
// LR <- CIA + 4
|
||||
|
||||
// NOTE: the condition bits are reversed!
|
||||
// 01234 (docs)
|
||||
// 43210 (real)
|
||||
|
||||
Value* ctr_ok = NULL;
|
||||
if (select_bits(i.B.BO, 2, 2)) {
|
||||
// Ignore ctr.
|
||||
} else {
|
||||
// Decrement counter.
|
||||
Value* ctr = f.LoadCTR();
|
||||
ctr = f.Sub(ctr, f.LoadConstantUint64(1));
|
||||
f.StoreCTR(ctr);
|
||||
// Ctr check.
|
||||
ctr = f.Truncate(ctr, INT32_TYPE);
|
||||
// TODO(benvanik): could do something similar to cond and avoid the
|
||||
// is_true/branch_true pairing.
|
||||
if (select_bits(i.B.BO, 1, 1)) {
|
||||
ctr_ok = f.IsFalse(ctr);
|
||||
} else {
|
||||
ctr_ok = f.IsTrue(ctr);
|
||||
}
|
||||
}
|
||||
|
||||
Value* cond_ok = NULL;
|
||||
bool not_cond_ok = false;
|
||||
if (select_bits(i.B.BO, 4, 4)) {
|
||||
// Ignore cond.
|
||||
} else {
|
||||
Value* cr = f.LoadCRField(i.B.BI >> 2, i.B.BI & 3);
|
||||
cond_ok = cr;
|
||||
if (select_bits(i.B.BO, 3, 3)) {
|
||||
// Expect true.
|
||||
not_cond_ok = false;
|
||||
} else {
|
||||
// Expect false.
|
||||
not_cond_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
// We do a bit of optimization here to make the llvm assembly easier to read.
|
||||
Value* ok = NULL;
|
||||
bool expect_true = true;
|
||||
if (ctr_ok && cond_ok) {
|
||||
if (not_cond_ok) {
|
||||
cond_ok = f.IsFalse(cond_ok);
|
||||
}
|
||||
ok = f.And(ctr_ok, cond_ok);
|
||||
} else if (ctr_ok) {
|
||||
ok = ctr_ok;
|
||||
} else if (cond_ok) {
|
||||
ok = cond_ok;
|
||||
expect_true = !not_cond_ok;
|
||||
}
|
||||
|
||||
uint32_t nia;
|
||||
if (i.B.AA) {
|
||||
nia = (uint32_t)XEEXTS16(i.B.BD << 2);
|
||||
} else {
|
||||
nia = (uint32_t)(i.address + XEEXTS16(i.B.BD << 2));
|
||||
}
|
||||
return InstrEmit_branch(f, "bcx", i.address, f.LoadConstantUint32(nia),
|
||||
i.B.LK, ok, expect_true);
|
||||
}
|
||||
|
||||
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
|
||||
// if LK then
|
||||
// LR <- CIA + 4
|
||||
|
||||
// NOTE: the condition bits are reversed!
|
||||
// 01234 (docs)
|
||||
// 43210 (real)
|
||||
|
||||
Value* cond_ok = NULL;
|
||||
bool not_cond_ok = false;
|
||||
if (select_bits(i.XL.BO, 4, 4)) {
|
||||
// Ignore cond.
|
||||
} else {
|
||||
Value* cr = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
cond_ok = cr;
|
||||
if (select_bits(i.XL.BO, 3, 3)) {
|
||||
// Expect true.
|
||||
not_cond_ok = false;
|
||||
} else {
|
||||
// Expect false.
|
||||
not_cond_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool expect_true = !not_cond_ok;
|
||||
return InstrEmit_branch(f, "bcctrx", i.address, f.LoadCTR(), i.XL.LK, cond_ok,
|
||||
expect_true);
|
||||
}
|
||||
|
||||
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]
|
||||
// cond_ok <- BO[0] | (CR[BI+32] ≡ BO[1])
|
||||
// if ctr_ok & cond_ok then
|
||||
// NIA <- LR[0:61] || 0b00
|
||||
// if LK then
|
||||
// LR <- CIA + 4
|
||||
|
||||
// NOTE: the condition bits are reversed!
|
||||
// 01234 (docs)
|
||||
// 43210 (real)
|
||||
|
||||
Value* ctr_ok = NULL;
|
||||
if (select_bits(i.XL.BO, 2, 2)) {
|
||||
// Ignore ctr.
|
||||
} else {
|
||||
// Decrement counter.
|
||||
Value* ctr = f.LoadCTR();
|
||||
ctr = f.Sub(ctr, f.LoadConstantUint64(1));
|
||||
f.StoreCTR(ctr);
|
||||
// Ctr check.
|
||||
ctr = f.Truncate(ctr, INT32_TYPE);
|
||||
// TODO(benvanik): could do something similar to cond and avoid the
|
||||
// is_true/branch_true pairing.
|
||||
if (select_bits(i.XL.BO, 1, 1)) {
|
||||
ctr_ok = f.IsFalse(ctr);
|
||||
} else {
|
||||
ctr_ok = f.IsTrue(ctr);
|
||||
}
|
||||
}
|
||||
|
||||
Value* cond_ok = NULL;
|
||||
bool not_cond_ok = false;
|
||||
if (select_bits(i.XL.BO, 4, 4)) {
|
||||
// Ignore cond.
|
||||
} else {
|
||||
Value* cr = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
cond_ok = cr;
|
||||
if (select_bits(i.XL.BO, 3, 3)) {
|
||||
// Expect true.
|
||||
not_cond_ok = false;
|
||||
} else {
|
||||
// Expect false.
|
||||
not_cond_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
// We do a bit of optimization here to make the llvm assembly easier to read.
|
||||
Value* ok = NULL;
|
||||
bool expect_true = true;
|
||||
if (ctr_ok && cond_ok) {
|
||||
if (not_cond_ok) {
|
||||
cond_ok = f.IsFalse(cond_ok);
|
||||
}
|
||||
ok = f.And(ctr_ok, cond_ok);
|
||||
} else if (ctr_ok) {
|
||||
ok = ctr_ok;
|
||||
} else if (cond_ok) {
|
||||
ok = cond_ok;
|
||||
expect_true = !not_cond_ok;
|
||||
}
|
||||
|
||||
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) {
|
||||
// CR[bt] <- CR[ba] & CR[bb] bt=bo, ba=bi, bb=bb
|
||||
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
|
||||
Value* bt = f.And(ba, bb);
|
||||
f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(crandc, 0x4C000102, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// CR[bt] <- CR[ba] & ¬CR[bb] bt=bo, ba=bi, bb=bb
|
||||
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
|
||||
Value* bt = f.And(ba, f.And(f.Not(bb), f.LoadConstantInt8(0x01)));
|
||||
f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(creqv, 0x4C000242, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// CR[bt] <- CR[ba] == CR[bb] bt=bo, ba=bi, bb=bb
|
||||
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
|
||||
Value* bt = f.CompareEQ(ba, bb);
|
||||
f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(crnand, 0x4C0001C2, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// CR[bt] <- ¬(CR[ba] & CR[bb]) bt=bo, ba=bi, bb=bb
|
||||
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
|
||||
Value* bt = f.And(f.Not(f.And(ba, bb)), f.LoadConstantInt8(0x01));
|
||||
f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(crnor, 0x4C000042, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// CR[bt] <- ¬(CR[ba] | CR[bb]) bt=bo, ba=bi, bb=bb
|
||||
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
|
||||
Value* bt = f.And(f.Not(f.Or(ba, bb)), f.LoadConstantInt8(0x01));
|
||||
f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(cror, 0x4C000382, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// CR[bt] <- CR[ba] | CR[bb] bt=bo, ba=bi, bb=bb
|
||||
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
|
||||
Value* bt = f.Or(ba, bb);
|
||||
f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(crorc, 0x4C000342, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// CR[bt] <- CR[ba] | ¬CR[bb] bt=bo, ba=bi, bb=bb
|
||||
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
|
||||
Value* bt = f.Or(ba, f.And(f.Not(bb), f.LoadConstantInt8(0x01)));
|
||||
f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(crxor, 0x4C000182, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// CR[bt] <- CR[ba] xor CR[bb] bt=bo, ba=bi, bb=bb
|
||||
Value* ba = f.LoadCRField(i.XL.BI >> 2, i.XL.BI & 3);
|
||||
Value* bb = f.LoadCRField(i.XL.BB >> 2, i.XL.BB & 3);
|
||||
Value* bt = f.Xor(ba, bb);
|
||||
f.StoreCRField(i.XL.BO >> 2, i.XL.BO & 3, bt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(mcrf, 0x4C000000, XL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// System linkage (A-24)
|
||||
|
||||
XEEMITTER(sc, 0x44000002, SC)(PPCHIRBuilder& f, InstrData& i) {
|
||||
f.CallExtern(f.function());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Trap (A-25)
|
||||
|
||||
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
|
||||
// if (a <u b) & TO[3] then TRAP
|
||||
// if (a >u b) & TO[4] then TRAP
|
||||
// Bits swapped:
|
||||
// 01234
|
||||
// 43210
|
||||
if (!TO) {
|
||||
return 0;
|
||||
}
|
||||
Value* v = nullptr;
|
||||
if (TO & (1 << 4)) {
|
||||
// a < b
|
||||
auto cmp = f.CompareSLT(va, vb);
|
||||
v = v ? f.Or(v, cmp) : cmp;
|
||||
}
|
||||
if (TO & (1 << 3)) {
|
||||
// a > b
|
||||
auto cmp = f.CompareSGT(va, vb);
|
||||
v = v ? f.Or(v, cmp) : cmp;
|
||||
}
|
||||
if (TO & (1 << 2)) {
|
||||
// a = b
|
||||
auto cmp = f.CompareEQ(va, vb);
|
||||
v = v ? f.Or(v, cmp) : cmp;
|
||||
}
|
||||
if (TO & (1 << 1)) {
|
||||
// a <u b
|
||||
auto cmp = f.CompareULT(va, vb);
|
||||
v = v ? f.Or(v, cmp) : cmp;
|
||||
}
|
||||
if (TO & (1 << 0)) {
|
||||
// a >u b
|
||||
auto cmp = f.CompareUGT(va, vb);
|
||||
v = v ? f.Or(v, cmp) : cmp;
|
||||
}
|
||||
if (v) {
|
||||
f.TrapTrue(v);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(td, 0x7C000088, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// a <- (RA)
|
||||
// b <- (RB)
|
||||
// if (a < b) & TO[0] then TRAP
|
||||
// if (a > b) & TO[1] then TRAP
|
||||
// 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.LoadGPR(i.X.RA);
|
||||
Value* rb = f.LoadGPR(i.X.RB);
|
||||
return InstrEmit_trap(f, i, ra, rb, i.X.RT);
|
||||
}
|
||||
|
||||
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
|
||||
// if (a = EXTS(SI)) & TO[2] then TRAP
|
||||
// if (a <u EXTS(SI)) & TO[3] then TRAP
|
||||
// if (a >u EXTS(SI)) & TO[4] then TRAP
|
||||
Value* ra = f.LoadGPR(i.D.RA);
|
||||
Value* rb = f.LoadConstantInt64(XEEXTS16(i.D.DS));
|
||||
return InstrEmit_trap(f, i, ra, rb, i.D.RT);
|
||||
}
|
||||
|
||||
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
|
||||
// if (a > b) & TO[1] then TRAP
|
||||
// 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);
|
||||
return InstrEmit_trap(f, i, ra, rb, i.X.RT);
|
||||
}
|
||||
|
||||
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
|
||||
// if (a = EXTS(SI)) & TO[2] then TRAP
|
||||
// if (a <u EXTS(SI)) & TO[3] then TRAP
|
||||
// if (a >u EXTS(SI)) & TO[4] then TRAP
|
||||
if (i.D.RA == 0 && i.D.RT == 0x1F) {
|
||||
// This is a special trap. Probably.
|
||||
uint16_t type = (uint16_t)XEEXTS16(i.D.DS);
|
||||
f.Trap(type);
|
||||
return 0;
|
||||
}
|
||||
Value* ra =
|
||||
f.SignExtend(f.Truncate(f.LoadGPR(i.D.RA), INT32_TYPE), INT64_TYPE);
|
||||
Value* rb = f.LoadConstantInt64(XEEXTS16(i.D.DS));
|
||||
return InstrEmit_trap(f, i, ra, rb, i.D.RT);
|
||||
}
|
||||
|
||||
// Processor control (A-26)
|
||||
|
||||
XEEMITTER(mfcr, 0x7C000026, XFX)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// mfocrf RT,FXM
|
||||
// RT <- undefined
|
||||
// count <- 0
|
||||
// do i = 0 to 7
|
||||
// if FXMi = 1 then
|
||||
// n <- i
|
||||
// count <- count + 1
|
||||
// if count = 1 then
|
||||
// RT4un + 32:4un + 35 <- CR4un + 32 : 4un + 35
|
||||
|
||||
// TODO(benvanik): optimize mfcr sequences.
|
||||
// Often look something like this:
|
||||
// mfocrf r11, cr6
|
||||
// not r10, r11
|
||||
// extrwi r3, r10, 1, 26
|
||||
// Could recognize this and only load the appropriate CR bit.
|
||||
|
||||
Value* v;
|
||||
if (i.XFX.spr & (1 << 9)) {
|
||||
uint32_t bits = (i.XFX.spr & 0x1FF) >> 1;
|
||||
int count = 0;
|
||||
int cri = 0;
|
||||
for (int b = 0; b <= 7; ++b) {
|
||||
if (bits & (1 << b)) {
|
||||
cri = 7 - b;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
if (count == 1) {
|
||||
v = f.LoadCR(cri);
|
||||
} else {
|
||||
v = f.LoadZeroInt64();
|
||||
}
|
||||
} else {
|
||||
v = f.LoadCR();
|
||||
}
|
||||
f.StoreGPR(i.XFX.RT, v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(mfspr, 0x7C0002A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// n <- spr[5:9] || spr[0:4]
|
||||
// if length(SPR(n)) = 64 then
|
||||
// RT <- SPR(n)
|
||||
// else
|
||||
// RT <- i32.0 || SPR(n)
|
||||
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;
|
||||
case 256:
|
||||
// VRSAVE
|
||||
v = f.LoadZeroInt64();
|
||||
break;
|
||||
case 268:
|
||||
// TB
|
||||
v = f.LoadClock();
|
||||
break;
|
||||
case 269:
|
||||
// TBU
|
||||
v = f.Shr(f.LoadClock(), 32);
|
||||
break;
|
||||
default:
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.StoreGPR(i.XFX.RT, v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(mftb, 0x7C0002E6, XFX)(PPCHIRBuilder& f, InstrData& i) {
|
||||
Value* time = f.LoadClock();
|
||||
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
|
||||
if (n == 268) {
|
||||
// TB - full bits.
|
||||
} else {
|
||||
// TBU - upper bits only.
|
||||
time = f.Shr(time, 32);
|
||||
}
|
||||
f.StoreGPR(i.XFX.RT, time);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(mtcrf, 0x7C000120, XFX)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// mtocrf FXM,RS
|
||||
// count <- 0
|
||||
// do i = 0 to 7
|
||||
// if FXMi = 1 then
|
||||
// n <- i
|
||||
// count <- count + 1
|
||||
// if count = 1 then
|
||||
// CR4un + 32 : 4un + 35 <- RS4un + 32:4un + 35
|
||||
|
||||
Value* v = f.LoadGPR(i.XFX.RT);
|
||||
if (i.XFX.spr & (1 << 9)) {
|
||||
uint32_t bits = (i.XFX.spr & 0x1FF) >> 1;
|
||||
int count = 0;
|
||||
int cri = 0;
|
||||
for (int b = 0; b <= 7; ++b) {
|
||||
if (bits & (1 << b)) {
|
||||
cri = 7 - b;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
if (count == 1) {
|
||||
f.StoreCR(cri, v);
|
||||
} else {
|
||||
// Invalid; store zero to CR.
|
||||
f.StoreCR(f.LoadZeroInt64());
|
||||
}
|
||||
} else {
|
||||
uint32_t bits = (i.XFX.spr & 0x1FF) >> 1;
|
||||
for (int b = 0; b <= 7; ++b) {
|
||||
if (bits & (1 << b)) {
|
||||
int cri = 7 - b;
|
||||
f.StoreCR(cri, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(mtspr, 0x7C0003A6, XFX)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// n <- spr[5:9] || spr[0:4]
|
||||
// if length(SPR(n)) = 64 then
|
||||
// SPR(n) <- (RS)
|
||||
// else
|
||||
// SPR(n) <- (RS)[32:63]
|
||||
|
||||
Value* rt = f.LoadGPR(i.XFX.RT);
|
||||
|
||||
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;
|
||||
case 256:
|
||||
// VRSAVE
|
||||
break;
|
||||
default:
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// MSR is used for toggling interrupts (among other things).
|
||||
// We track it here for taking a global processor lock, as lots of lockfree
|
||||
// code requires it. Sequences of mtmsr/lwar/stcw/mtmsr come up a lot, and
|
||||
// without the lock here threads can livelock.
|
||||
|
||||
XEEMITTER(mfmsr, 0x7C0000A6, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// bit 48 = EE; interrupt enabled
|
||||
// bit 62 = RI; recoverable interrupt
|
||||
// return 8000h if unlocked (interrupts enabled), else 0
|
||||
f.MemoryBarrier();
|
||||
f.CallExtern(f.builtins()->check_global_lock);
|
||||
f.StoreGPR(i.X.RT, f.LoadContext(offsetof(PPCContext, scratch), INT64_TYPE));
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(mtmsr, 0x7C000124, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
if (i.X.RA & 0x01) {
|
||||
// L = 1
|
||||
// iff storing from r13
|
||||
f.MemoryBarrier();
|
||||
f.StoreContext(
|
||||
offsetof(PPCContext, scratch),
|
||||
f.ZeroExtend(f.ZeroExtend(f.LoadGPR(i.X.RT), INT64_TYPE), INT64_TYPE));
|
||||
if (i.X.RT == 13) {
|
||||
// iff storing from r13 we are taking a lock (disable interrupts).
|
||||
f.CallExtern(f.builtins()->enter_global_lock);
|
||||
} else {
|
||||
// Otherwise we are restoring interrupts (probably).
|
||||
f.CallExtern(f.builtins()->leave_global_lock);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
// L = 0
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
XEEMITTER(mtmsrd, 0x7C000164, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
if (i.X.RA & 0x01) {
|
||||
// L = 1
|
||||
f.MemoryBarrier();
|
||||
f.StoreContext(offsetof(PPCContext, scratch),
|
||||
f.ZeroExtend(f.LoadGPR(i.X.RT), INT64_TYPE));
|
||||
if (i.X.RT == 13) {
|
||||
// iff storing from r13 we are taking a lock (disable interrupts).
|
||||
f.CallExtern(f.builtins()->enter_global_lock);
|
||||
} else {
|
||||
// Otherwise we are restoring interrupts (probably).
|
||||
f.CallExtern(f.builtins()->leave_global_lock);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
// L = 0
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
584
src/xenia/cpu/ppc/ppc_emit_fpu.cc
Normal file
584
src/xenia/cpu/ppc/ppc_emit_fpu.cc
Normal file
@@ -0,0 +1,584 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_emit-private.h"
|
||||
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/cpu/ppc/ppc_context.h"
|
||||
#include "xenia/cpu/ppc/ppc_hir_builder.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
// TODO(benvanik): remove when enums redefined.
|
||||
using namespace xe::cpu::hir;
|
||||
|
||||
using xe::cpu::hir::RoundMode;
|
||||
using xe::cpu::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) {
|
||||
// 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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(fresx, 0xEC000030, A)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// frD <- 1.0 / (frB)
|
||||
Value* v = f.Convert(f.Div(f.LoadConstantFloat32(1.0f),
|
||||
f.Convert(f.LoadFPR(i.A.FRB), FLOAT32_TYPE)),
|
||||
FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(frsqrtex, 0xFC000034, A)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// Double precision:
|
||||
// frD <- 1/sqrt(frB)
|
||||
Value* v = f.RSqrt(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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(fselx, 0xFC00002E, A)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// if (frA) >= 0.0
|
||||
// then frD <- (frC)
|
||||
// else frD <- (frB)
|
||||
Value* ge = f.CompareSGE(f.LoadFPR(i.A.FRA), f.LoadZeroFloat64());
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(fsqrtx, 0xFC00002C, A)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// Double precision:
|
||||
// frD <- sqrt(frB)
|
||||
Value* v = f.Sqrt(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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(fsqrtsx, 0xEC00002C, A)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// Single precision:
|
||||
// frD <- sqrt(frB)
|
||||
Value* v = f.Sqrt(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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Floating-point multiply-add (A-9)
|
||||
|
||||
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));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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));
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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));
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(fnmaddx, 0xFC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// frD <- -([frA x frC] + frB)
|
||||
Value* v = f.Neg(
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(fnmaddsx, 0xEC00003E, A)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// frD <- -([frA x frC] + frB)
|
||||
Value* v = f.Neg(
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)));
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Floating-point rounding and conversion (A-10)
|
||||
|
||||
XEEMITTER(fcfidx, 0xFC00069C, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// frD <- signed_int64_to_double( frB )
|
||||
Value* v = f.Convert(f.Cast(f.LoadFPR(i.X.RB), INT64_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
Value* v = f.Convert(f.LoadFPR(i.X.RB), INT64_TYPE, round_mode);
|
||||
v = f.Cast(v, FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
// frD <- double_to_signed_int32( frB )
|
||||
// TODO(benvanik): pull from FPSCR[RN]
|
||||
RoundMode round_mode = ROUND_TO_ZERO;
|
||||
Value* v = f.Convert(f.LoadFPR(i.X.RB), INT32_TYPE, round_mode);
|
||||
v = f.Cast(f.ZeroExtend(v, INT64_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
// frD <- Round_single(frB)
|
||||
// TODO(benvanik): pull from FPSCR[RN]
|
||||
RoundMode round_mode = ROUND_TO_ZERO;
|
||||
Value* v = f.Convert(f.LoadFPR(i.X.RB), FLOAT32_TYPE, round_mode);
|
||||
v = f.Convert(v, FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.X.Rc) {
|
||||
// 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) {
|
||||
// if (FRA) is a NaN or (FRB) is a NaN then
|
||||
// c <- 0b0001
|
||||
// else if (FRA) < (FRB) then
|
||||
// c <- 0b1000
|
||||
// else if (FRA) > (FRB) then
|
||||
// c <- 0b0100
|
||||
// else {
|
||||
// c <- 0b0010
|
||||
// }
|
||||
// FPCC <- c
|
||||
// CR[4*BF:4*BF+3] <- c
|
||||
// if (FRA) is an SNaN or (FRB) is an SNaN then
|
||||
// VXSNAN <- 1
|
||||
|
||||
// TODO(benvanik): update FPCC for mffsx/etc
|
||||
// TODO(benvanik): update VXSNAN
|
||||
const uint32_t crf = i.X.RT >> 2;
|
||||
// f.UpdateFPRF(v);
|
||||
f.UpdateCR(crf, f.LoadFPR(i.X.RA), f.LoadFPR(i.X.RB), false);
|
||||
return 0;
|
||||
}
|
||||
XEEMITTER(fcmpo, 0xFC000040, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
return InstrEmit_fcmpx_(f, i, true);
|
||||
}
|
||||
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) {
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
|
||||
XEEMITTER(mffsx, 0xFC00048E, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
if (i.X.Rc) {
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
Value* v = f.Cast(f.LoadFPSCR(), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(mtfsb0x, 0xFC00008C, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
|
||||
XEEMITTER(mtfsb1x, 0xFC00004C, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
|
||||
XEEMITTER(mtfsfx, 0xFC00058E, XFL)(PPCHIRBuilder& f, InstrData& i) {
|
||||
if (i.XFL.Rc) {
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
if (i.XFL.L) {
|
||||
// Move/shift.
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
} else {
|
||||
// Directly store.
|
||||
// TODO(benvanik): use w/field mask to select bits.
|
||||
// i.XFL.W;
|
||||
// i.XFL.FM;
|
||||
f.StoreFPSCR(f.Cast(f.LoadFPR(i.XFL.RB), INT64_TYPE));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(mtfsfix, 0xFC00010C, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Floating-point move (A-21)
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEEMITTER(fnabsx, 0xFC000110, X)(PPCHIRBuilder& f, InstrData& i) {
|
||||
// frD <- !abs(frB)
|
||||
Value* v = f.Neg(f.Abs(f.LoadFPR(i.X.RB)));
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
1103
src/xenia/cpu/ppc/ppc_emit_memory.cc
Normal file
1103
src/xenia/cpu/ppc/ppc_emit_memory.cc
Normal file
File diff suppressed because it is too large
Load Diff
112
src/xenia/cpu/ppc/ppc_frontend.cc
Normal file
112
src/xenia/cpu/ppc/ppc_frontend.cc
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_frontend.h"
|
||||
|
||||
#include "xenia/base/atomic.h"
|
||||
#include "xenia/cpu/ppc/ppc_context.h"
|
||||
#include "xenia/cpu/ppc/ppc_disasm.h"
|
||||
#include "xenia/cpu/ppc/ppc_emit.h"
|
||||
#include "xenia/cpu/ppc/ppc_translator.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
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 CleanupOnShutdown() {}
|
||||
|
||||
PPCFrontend::PPCFrontend(Processor* processor) : processor_(processor) {
|
||||
InitializeIfNeeded();
|
||||
}
|
||||
|
||||
PPCFrontend::~PPCFrontend() {
|
||||
// Force cleanup now before we deinit.
|
||||
translator_pool_.Reset();
|
||||
}
|
||||
|
||||
Memory* PPCFrontend::memory() const { return processor_->memory(); }
|
||||
|
||||
// Checks the state of the global lock and sets scratch to the current MSR
|
||||
// value.
|
||||
void CheckGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) {
|
||||
auto global_mutex = reinterpret_cast<std::recursive_mutex*>(arg0);
|
||||
auto global_lock_count = reinterpret_cast<int32_t*>(arg1);
|
||||
std::lock_guard<std::recursive_mutex> lock(*global_mutex);
|
||||
ppc_context->scratch = *global_lock_count ? 0 : 0x8000;
|
||||
}
|
||||
|
||||
// Enters the global lock. Safe to recursion.
|
||||
void EnterGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) {
|
||||
auto global_mutex = reinterpret_cast<std::recursive_mutex*>(arg0);
|
||||
auto global_lock_count = reinterpret_cast<int32_t*>(arg1);
|
||||
global_mutex->lock();
|
||||
xe::atomic_inc(global_lock_count);
|
||||
}
|
||||
|
||||
// Leaves the global lock. Safe to recursion.
|
||||
void LeaveGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) {
|
||||
auto global_mutex = reinterpret_cast<std::recursive_mutex*>(arg0);
|
||||
auto global_lock_count = reinterpret_cast<int32_t*>(arg1);
|
||||
auto new_lock_count = xe::atomic_dec(global_lock_count);
|
||||
assert_true(new_lock_count >= 0);
|
||||
global_mutex->unlock();
|
||||
}
|
||||
|
||||
bool PPCFrontend::Initialize() {
|
||||
void* arg0 = reinterpret_cast<void*>(&xe::global_critical_region::mutex());
|
||||
void* arg1 = reinterpret_cast<void*>(&builtins_.global_lock_count);
|
||||
builtins_.check_global_lock =
|
||||
processor_->DefineBuiltin("CheckGlobalLock", CheckGlobalLock, arg0, arg1);
|
||||
builtins_.enter_global_lock =
|
||||
processor_->DefineBuiltin("EnterGlobalLock", EnterGlobalLock, arg0, arg1);
|
||||
builtins_.leave_global_lock =
|
||||
processor_->DefineBuiltin("LeaveGlobalLock", LeaveGlobalLock, arg0, arg1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PPCFrontend::DeclareFunction(GuestFunction* function) {
|
||||
// Could scan or something here.
|
||||
// Could also check to see if it's a well-known function type and classify
|
||||
// for later.
|
||||
// Could also kick off a precompiler, since we know it's likely the function
|
||||
// will be demanded soon.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PPCFrontend::DefineFunction(GuestFunction* function,
|
||||
uint32_t debug_info_flags) {
|
||||
auto translator = translator_pool_.Allocate(this);
|
||||
bool result = translator->Translate(function, debug_info_flags);
|
||||
translator_pool_.Release(translator);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
62
src/xenia/cpu/ppc/ppc_frontend.h
Normal file
62
src/xenia/cpu/ppc/ppc_frontend.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_FRONTEND_H_
|
||||
#define XENIA_CPU_PPC_PPC_FRONTEND_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "xenia/base/type_pool.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
#include "xenia/memory.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
class Processor;
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
class PPCTranslator;
|
||||
|
||||
struct PPCBuiltins {
|
||||
int32_t global_lock_count;
|
||||
Function* check_global_lock;
|
||||
Function* enter_global_lock;
|
||||
Function* leave_global_lock;
|
||||
};
|
||||
|
||||
class PPCFrontend {
|
||||
public:
|
||||
explicit PPCFrontend(Processor* processor);
|
||||
~PPCFrontend();
|
||||
|
||||
bool Initialize();
|
||||
|
||||
Processor* processor() const { return processor_; }
|
||||
Memory* memory() const;
|
||||
PPCBuiltins* builtins() { return &builtins_; }
|
||||
|
||||
bool DeclareFunction(GuestFunction* function);
|
||||
bool DefineFunction(GuestFunction* function, uint32_t debug_info_flags);
|
||||
|
||||
private:
|
||||
Processor* processor_;
|
||||
PPCBuiltins builtins_ = {0};
|
||||
TypePool<PPCTranslator, PPCFrontend*> translator_pool_;
|
||||
};
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_FRONTEND_H_
|
||||
444
src/xenia/cpu/ppc/ppc_hir_builder.cc
Normal file
444
src/xenia/cpu/ppc/ppc_hir_builder.cc
Normal file
@@ -0,0 +1,444 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_hir_builder.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/memory.h"
|
||||
#include "xenia/base/profiling.h"
|
||||
#include "xenia/cpu/cpu_flags.h"
|
||||
#include "xenia/cpu/hir/label.h"
|
||||
#include "xenia/cpu/ppc/ppc_context.h"
|
||||
#include "xenia/cpu/ppc/ppc_disasm.h"
|
||||
#include "xenia/cpu/ppc/ppc_frontend.h"
|
||||
#include "xenia/cpu/ppc/ppc_instr.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
// TODO(benvanik): remove when enums redefined.
|
||||
using namespace xe::cpu::hir;
|
||||
|
||||
using xe::cpu::hir::Label;
|
||||
using xe::cpu::hir::TypeName;
|
||||
using xe::cpu::hir::Value;
|
||||
|
||||
PPCHIRBuilder::PPCHIRBuilder(PPCFrontend* frontend)
|
||||
: HIRBuilder(), frontend_(frontend), comment_buffer_(4096) {}
|
||||
|
||||
PPCHIRBuilder::~PPCHIRBuilder() = default;
|
||||
|
||||
PPCBuiltins* PPCHIRBuilder::builtins() const { return frontend_->builtins(); }
|
||||
|
||||
void PPCHIRBuilder::Reset() {
|
||||
function_ = nullptr;
|
||||
start_address_ = 0;
|
||||
instr_count_ = 0;
|
||||
instr_offset_list_ = NULL;
|
||||
label_list_ = NULL;
|
||||
with_debug_info_ = false;
|
||||
HIRBuilder::Reset();
|
||||
}
|
||||
|
||||
bool PPCHIRBuilder::Emit(GuestFunction* function, uint32_t flags) {
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
Memory* memory = frontend_->memory();
|
||||
|
||||
function_ = function;
|
||||
start_address_ = function_->address();
|
||||
instr_count_ = (function_->end_address() - function_->address()) / 4 + 1;
|
||||
|
||||
with_debug_info_ = (flags & EMIT_DEBUG_COMMENTS) == EMIT_DEBUG_COMMENTS;
|
||||
if (with_debug_info_) {
|
||||
CommentFormat("%s fn %.8X-%.8X %s", function_->module()->name().c_str(),
|
||||
function_->address(), function_->end_address(),
|
||||
function_->name().c_str());
|
||||
}
|
||||
|
||||
// Allocate offset list.
|
||||
// This is used to quickly map labels to instructions.
|
||||
// The list is built as the instructions are traversed, with the values
|
||||
// being the previous HIR Instr before the given instruction. An
|
||||
// instruction may have a label assigned to it if it hasn't been hit
|
||||
// yet.
|
||||
size_t list_size = instr_count_ * sizeof(void*);
|
||||
instr_offset_list_ = (Instr**)arena_->Alloc(list_size);
|
||||
label_list_ = (Label**)arena_->Alloc(list_size);
|
||||
std::memset(instr_offset_list_, 0, list_size);
|
||||
std::memset(label_list_, 0, list_size);
|
||||
|
||||
// Always mark entry with label.
|
||||
label_list_[0] = NewLabel();
|
||||
|
||||
uint32_t start_address = function_->address();
|
||||
uint32_t end_address = function_->end_address();
|
||||
InstrData i;
|
||||
for (uint32_t address = start_address, offset = 0; address <= end_address;
|
||||
address += 4, offset++) {
|
||||
i.address = address;
|
||||
i.code = xe::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
|
||||
// TODO(benvanik): find a way to avoid using the opcode tables.
|
||||
i.type = GetInstrType(i.code);
|
||||
trace_info_.dest_count = 0;
|
||||
|
||||
// Mark label, if we were assigned one earlier on in the walk.
|
||||
// We may still get a label, but it'll be inserted by LookupLabel
|
||||
// as needed.
|
||||
Label* label = label_list_[offset];
|
||||
if (label) {
|
||||
MarkLabel(label);
|
||||
}
|
||||
|
||||
Instr* first_instr = 0;
|
||||
if (with_debug_info_) {
|
||||
if (label) {
|
||||
AnnotateLabel(address, label);
|
||||
}
|
||||
comment_buffer_.Reset();
|
||||
comment_buffer_.AppendFormat("%.8X %.8X ", address, i.code);
|
||||
DisasmPPC(&i, &comment_buffer_);
|
||||
Comment(comment_buffer_);
|
||||
first_instr = last_instr();
|
||||
}
|
||||
|
||||
// Mark source offset for debugging.
|
||||
// We could omit this if we never wanted to debug.
|
||||
SourceOffset(i.address);
|
||||
if (!first_instr) {
|
||||
first_instr = last_instr();
|
||||
}
|
||||
|
||||
// Stash instruction offset. It's either the SOURCE_OFFSET or the COMMENT.
|
||||
instr_offset_list_[offset] = first_instr;
|
||||
|
||||
if (!i.type) {
|
||||
XELOGE("Invalid instruction %.8llX %.8X", i.address, i.code);
|
||||
Comment("INVALID!");
|
||||
// TraceInvalidInstruction(i);
|
||||
continue;
|
||||
}
|
||||
++i.type->translation_count;
|
||||
|
||||
// Synchronize the PPC context as required.
|
||||
// This will ensure all registers are saved to the PPC context before this
|
||||
// instruction executes.
|
||||
if (i.type->type & kXEPPCInstrTypeSynchronizeContext) {
|
||||
ContextBarrier();
|
||||
}
|
||||
|
||||
typedef int (*InstrEmitter)(PPCHIRBuilder& f, InstrData& i);
|
||||
InstrEmitter emit = (InstrEmitter)i.type->emit;
|
||||
|
||||
if (i.address == FLAGS_break_on_instruction) {
|
||||
Comment("--break-on-instruction target");
|
||||
|
||||
if (FLAGS_break_condition_gpr < 0) {
|
||||
DebugBreak();
|
||||
} else {
|
||||
auto left = LoadGPR(FLAGS_break_condition_gpr);
|
||||
auto right = LoadConstantUint64(FLAGS_break_condition_value);
|
||||
if (FLAGS_break_condition_truncate) {
|
||||
left = Truncate(left, INT32_TYPE);
|
||||
right = Truncate(right, INT32_TYPE);
|
||||
}
|
||||
TrapTrue(CompareEQ(left, right));
|
||||
}
|
||||
}
|
||||
|
||||
if (!i.type->emit || emit(*this, i)) {
|
||||
XELOGE("Unimplemented instr %.8llX %.8X %s", i.address, i.code,
|
||||
i.type->name);
|
||||
Comment("UNIMPLEMENTED!");
|
||||
// DebugBreak();
|
||||
// TraceInvalidInstruction(i);
|
||||
}
|
||||
}
|
||||
|
||||
return Finalize();
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::AnnotateLabel(uint32_t address, Label* label) {
|
||||
char name_buffer[13];
|
||||
snprintf(name_buffer, xe::countof(name_buffer), "loc_%.8X", address);
|
||||
label->name = (char*)arena_->Alloc(sizeof(name_buffer));
|
||||
memcpy(label->name, name_buffer, sizeof(name_buffer));
|
||||
}
|
||||
|
||||
Function* PPCHIRBuilder::LookupFunction(uint32_t address) {
|
||||
return frontend_->processor()->LookupFunction(address);
|
||||
}
|
||||
|
||||
Label* PPCHIRBuilder::LookupLabel(uint32_t address) {
|
||||
if (address < start_address_) {
|
||||
return nullptr;
|
||||
}
|
||||
size_t offset = (address - start_address_) / 4;
|
||||
if (offset >= instr_count_) {
|
||||
return nullptr;
|
||||
}
|
||||
Label* label = label_list_[offset];
|
||||
if (label) {
|
||||
return label;
|
||||
}
|
||||
// No label. If we haven't yet hit the instruction in the walk
|
||||
// then create a label. Otherwise, we must go back and insert
|
||||
// the label.
|
||||
label = NewLabel();
|
||||
label_list_[offset] = label;
|
||||
Instr* instr = instr_offset_list_[offset];
|
||||
if (instr) {
|
||||
if (instr->prev) {
|
||||
// Insert label, breaking up existing instructions.
|
||||
InsertLabel(label, instr->prev);
|
||||
} else {
|
||||
// Instruction is at the head of a block, so just add the label.
|
||||
MarkLabel(label, instr->block);
|
||||
}
|
||||
|
||||
// Annotate the label, as we won't do it later.
|
||||
if (with_debug_info_) {
|
||||
AnnotateLabel(address, label);
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
// Value* PPCHIRBuilder::LoadXER() {
|
||||
//}
|
||||
//
|
||||
// void PPCHIRBuilder::StoreXER(Value* value) {
|
||||
//}
|
||||
|
||||
Value* PPCHIRBuilder::LoadLR() {
|
||||
return LoadContext(offsetof(PPCContext, lr), INT64_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreLR(Value* value) {
|
||||
assert_true(value->type == INT64_TYPE);
|
||||
StoreContext(offsetof(PPCContext, lr), value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
trace_reg.reg = 64;
|
||||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadCTR() {
|
||||
return LoadContext(offsetof(PPCContext, ctr), INT64_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreCTR(Value* value) {
|
||||
assert_true(value->type == INT64_TYPE);
|
||||
StoreContext(offsetof(PPCContext, ctr), value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
trace_reg.reg = 65;
|
||||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadCR() {
|
||||
// All bits. This is expensive, but seems to be less used than the
|
||||
// field-specific LoadCR.
|
||||
Value* v = LoadCR(0);
|
||||
for (int i = 1; i <= 7; ++i) {
|
||||
v = Or(v, LoadCR(i));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadCR(uint32_t n) {
|
||||
// Construct the entire word of just the bits we care about.
|
||||
// This makes it easier for the optimizer to exclude things, though
|
||||
// we could be even more clever and watch sequences.
|
||||
Value* v = Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 0,
|
||||
INT8_TYPE),
|
||||
INT64_TYPE),
|
||||
4 * (7 - n) + 3);
|
||||
v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 1,
|
||||
INT8_TYPE),
|
||||
INT64_TYPE),
|
||||
4 * (7 - n) + 2));
|
||||
v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 2,
|
||||
INT8_TYPE),
|
||||
INT64_TYPE),
|
||||
4 * (7 - n) + 1));
|
||||
v = Or(v, Shl(ZeroExtend(LoadContext(offsetof(PPCContext, cr0) + (4 * n) + 3,
|
||||
INT8_TYPE),
|
||||
INT64_TYPE),
|
||||
4 * (7 - n) + 0));
|
||||
return v;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadCRField(uint32_t n, uint32_t bit) {
|
||||
return LoadContext(offsetof(PPCContext, cr0) + (4 * n) + bit, INT8_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreCR(Value* value) {
|
||||
// All bits. This is expensive, but seems to be less used than the
|
||||
// field-specific StoreCR.
|
||||
for (int i = 0; i <= 7; ++i) {
|
||||
StoreCR(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreCR(uint32_t n, Value* value) {
|
||||
// Pull out the bits we are interested in.
|
||||
// Optimization passes will kill any unneeded stores (mostly).
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 0,
|
||||
And(Truncate(Shr(value, 4 * (7 - n) + 3), INT8_TYPE),
|
||||
LoadConstantUint8(1)));
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 1,
|
||||
And(Truncate(Shr(value, 4 * (7 - n) + 2), INT8_TYPE),
|
||||
LoadConstantUint8(1)));
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 2,
|
||||
And(Truncate(Shr(value, 4 * (7 - n) + 1), INT8_TYPE),
|
||||
LoadConstantUint8(1)));
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 3,
|
||||
And(Truncate(Shr(value, 4 * (7 - n) + 0), INT8_TYPE),
|
||||
LoadConstantUint8(1)));
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreCRField(uint32_t n, uint32_t bit, Value* value) {
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + bit, value);
|
||||
|
||||
// TODO(benvanik): trace CR.
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::UpdateCR(uint32_t n, Value* lhs, bool is_signed) {
|
||||
UpdateCR(n, Truncate(lhs, INT32_TYPE), LoadZeroInt32(), 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);
|
||||
Value* gt = CompareSGT(lhs, rhs);
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 1, gt);
|
||||
} else {
|
||||
Value* lt = CompareULT(lhs, rhs);
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 0, lt);
|
||||
Value* gt = CompareUGT(lhs, rhs);
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 1, gt);
|
||||
}
|
||||
Value* eq = CompareEQ(lhs, rhs);
|
||||
StoreContext(offsetof(PPCContext, cr0) + (4 * n) + 2, eq);
|
||||
|
||||
// Value* so = AllocValue(UINT8_TYPE);
|
||||
// StoreContext(offsetof(PPCContext, cr) + (4 * n) + 3, so);
|
||||
|
||||
// TOOD(benvanik): trace CR.
|
||||
}
|
||||
|
||||
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_1), LoadZeroInt8());
|
||||
StoreContext(offsetof(PPCContext, cr6.cr6_3), LoadZeroInt8());
|
||||
StoreContext(offsetof(PPCContext, cr6.cr6_all_equal),
|
||||
IsFalse(Not(src_value)));
|
||||
StoreContext(offsetof(PPCContext, cr6.cr6_none_equal), IsFalse(src_value));
|
||||
|
||||
// TOOD(benvanik): trace CR.
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadFPSCR() {
|
||||
return LoadContext(offsetof(PPCContext, fpscr), INT64_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreFPSCR(Value* value) {
|
||||
assert_true(value->type == INT64_TYPE);
|
||||
StoreContext(offsetof(PPCContext, fpscr), value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
trace_reg.reg = 67;
|
||||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadXER() {
|
||||
assert_always();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreXER(Value* value) { assert_always(); }
|
||||
|
||||
Value* PPCHIRBuilder::LoadCA() {
|
||||
return LoadContext(offsetof(PPCContext, xer_ca), INT8_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreCA(Value* value) {
|
||||
assert_true(value->type == INT8_TYPE);
|
||||
StoreContext(offsetof(PPCContext, xer_ca), value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
trace_reg.reg = 66;
|
||||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadSAT() {
|
||||
return LoadContext(offsetof(PPCContext, vscr_sat), INT8_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreSAT(Value* value) {
|
||||
value = Truncate(value, INT8_TYPE);
|
||||
StoreContext(offsetof(PPCContext, vscr_sat), value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
trace_reg.reg = 44;
|
||||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadGPR(uint32_t reg) {
|
||||
return LoadContext(offsetof(PPCContext, r) + reg * 8, INT64_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreGPR(uint32_t reg, Value* value) {
|
||||
assert_true(value->type == INT64_TYPE);
|
||||
StoreContext(offsetof(PPCContext, r) + reg * 8, value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
trace_reg.reg = reg;
|
||||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadFPR(uint32_t reg) {
|
||||
return LoadContext(offsetof(PPCContext, f) + reg * 8, FLOAT64_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreFPR(uint32_t reg, Value* value) {
|
||||
assert_true(value->type == FLOAT64_TYPE);
|
||||
StoreContext(offsetof(PPCContext, f) + reg * 8, value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
trace_reg.reg = reg + 32;
|
||||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadVR(uint32_t reg) {
|
||||
return LoadContext(offsetof(PPCContext, v) + reg * 16, VEC128_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreVR(uint32_t reg, Value* value) {
|
||||
assert_true(value->type == VEC128_TYPE);
|
||||
StoreContext(offsetof(PPCContext, v) + reg * 16, value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
trace_reg.reg = 128 + reg;
|
||||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
109
src/xenia/cpu/ppc/ppc_hir_builder.h
Normal file
109
src/xenia/cpu/ppc/ppc_hir_builder.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_HIR_BUILDER_H_
|
||||
#define XENIA_CPU_PPC_PPC_HIR_BUILDER_H_
|
||||
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
#include "xenia/cpu/hir/hir_builder.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
struct PPCBuiltins;
|
||||
class PPCFrontend;
|
||||
|
||||
class PPCHIRBuilder : public hir::HIRBuilder {
|
||||
using Instr = xe::cpu::hir::Instr;
|
||||
using Label = xe::cpu::hir::Label;
|
||||
using Value = xe::cpu::hir::Value;
|
||||
|
||||
public:
|
||||
explicit PPCHIRBuilder(PPCFrontend* frontend);
|
||||
~PPCHIRBuilder() override;
|
||||
|
||||
PPCBuiltins* builtins() const;
|
||||
|
||||
void Reset() override;
|
||||
|
||||
enum EmitFlags {
|
||||
// Emit comment nodes.
|
||||
EMIT_DEBUG_COMMENTS = 1 << 0,
|
||||
};
|
||||
bool Emit(GuestFunction* function, uint32_t flags);
|
||||
|
||||
GuestFunction* function() const { return function_; }
|
||||
Function* LookupFunction(uint32_t address);
|
||||
Label* LookupLabel(uint32_t address);
|
||||
|
||||
Value* LoadLR();
|
||||
void StoreLR(Value* value);
|
||||
Value* LoadCTR();
|
||||
void StoreCTR(Value* value);
|
||||
Value* LoadCR();
|
||||
Value* LoadCR(uint32_t n);
|
||||
Value* LoadCRField(uint32_t n, uint32_t bit);
|
||||
void StoreCR(Value* value);
|
||||
void StoreCR(uint32_t n, Value* value);
|
||||
void StoreCRField(uint32_t n, uint32_t bit, Value* value);
|
||||
void UpdateCR(uint32_t n, Value* lhs, bool is_signed = true);
|
||||
void UpdateCR(uint32_t n, Value* lhs, Value* rhs, bool is_signed = true);
|
||||
void UpdateCR6(Value* src_value);
|
||||
Value* LoadFPSCR();
|
||||
void StoreFPSCR(Value* value);
|
||||
Value* LoadXER();
|
||||
void StoreXER(Value* value);
|
||||
// void UpdateXERWithOverflow();
|
||||
// void UpdateXERWithOverflowAndCarry();
|
||||
// void StoreOV(Value* value);
|
||||
Value* LoadCA();
|
||||
void StoreCA(Value* value);
|
||||
Value* LoadSAT();
|
||||
void StoreSAT(Value* value);
|
||||
|
||||
Value* LoadGPR(uint32_t reg);
|
||||
void StoreGPR(uint32_t reg, Value* value);
|
||||
Value* LoadFPR(uint32_t reg);
|
||||
void StoreFPR(uint32_t reg, Value* value);
|
||||
Value* LoadVR(uint32_t reg);
|
||||
void StoreVR(uint32_t reg, Value* value);
|
||||
|
||||
private:
|
||||
void AnnotateLabel(uint32_t address, Label* label);
|
||||
|
||||
PPCFrontend* frontend_;
|
||||
|
||||
// Reset whenever needed:
|
||||
StringBuffer comment_buffer_;
|
||||
|
||||
// Reset each Emit:
|
||||
bool with_debug_info_;
|
||||
GuestFunction* function_;
|
||||
uint64_t start_address_;
|
||||
uint64_t instr_count_;
|
||||
Instr** instr_offset_list_;
|
||||
Label** label_list_;
|
||||
|
||||
// Reset each instruction.
|
||||
struct {
|
||||
uint32_t dest_count;
|
||||
struct {
|
||||
uint8_t reg;
|
||||
Value* value;
|
||||
} dests[4];
|
||||
} trace_info_;
|
||||
};
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_HIR_BUILDER_H_
|
||||
410
src/xenia/cpu/ppc/ppc_instr.cc
Normal file
410
src/xenia/cpu/ppc/ppc_instr.cc
Normal file
@@ -0,0 +1,410 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_instr.h"
|
||||
|
||||
#include <cinttypes>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/cpu/ppc/ppc_instr_tables.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
std::vector<InstrType*> all_instrs_;
|
||||
|
||||
void DumpAllInstrCounts() {
|
||||
StringBuffer sb;
|
||||
sb.Append("Instruction translation counts:\n");
|
||||
for (auto instr_type : all_instrs_) {
|
||||
if (instr_type->translation_count) {
|
||||
sb.AppendFormat("%8d : %s\n", instr_type->translation_count,
|
||||
instr_type->name);
|
||||
}
|
||||
}
|
||||
fprintf(stdout, "%s", sb.GetString());
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void InstrOperand::Dump(std::string& out_str) {
|
||||
if (display) {
|
||||
out_str += display;
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[32];
|
||||
const size_t max_count = xe::countof(buffer);
|
||||
switch (type) {
|
||||
case InstrOperand::kRegister:
|
||||
switch (reg.set) {
|
||||
case InstrRegister::kXER:
|
||||
snprintf(buffer, max_count, "XER");
|
||||
break;
|
||||
case InstrRegister::kLR:
|
||||
snprintf(buffer, max_count, "LR");
|
||||
break;
|
||||
case InstrRegister::kCTR:
|
||||
snprintf(buffer, max_count, "CTR");
|
||||
break;
|
||||
case InstrRegister::kCR:
|
||||
snprintf(buffer, max_count, "CR%d", reg.ordinal);
|
||||
break;
|
||||
case InstrRegister::kFPSCR:
|
||||
snprintf(buffer, max_count, "FPSCR");
|
||||
break;
|
||||
case InstrRegister::kGPR:
|
||||
snprintf(buffer, max_count, "r%d", reg.ordinal);
|
||||
break;
|
||||
case InstrRegister::kFPR:
|
||||
snprintf(buffer, max_count, "f%d", reg.ordinal);
|
||||
break;
|
||||
case InstrRegister::kVMX:
|
||||
snprintf(buffer, max_count, "vr%d", reg.ordinal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case InstrOperand::kImmediate:
|
||||
switch (imm.width) {
|
||||
case 1:
|
||||
if (imm.is_signed) {
|
||||
snprintf(buffer, max_count, "%d", (int32_t)(int8_t)imm.value);
|
||||
} else {
|
||||
snprintf(buffer, max_count, "0x%.2X", (uint8_t)imm.value);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (imm.is_signed) {
|
||||
snprintf(buffer, max_count, "%d", (int32_t)(int16_t)imm.value);
|
||||
} else {
|
||||
snprintf(buffer, max_count, "0x%.4X", (uint16_t)imm.value);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (imm.is_signed) {
|
||||
snprintf(buffer, max_count, "%d", (int32_t)imm.value);
|
||||
} else {
|
||||
snprintf(buffer, max_count, "0x%.8X", (uint32_t)imm.value);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (imm.is_signed) {
|
||||
snprintf(buffer, max_count, "%" PRId64, (int64_t)imm.value);
|
||||
} else {
|
||||
snprintf(buffer, max_count, "0x%.16" PRIX64, imm.value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
out_str += buffer;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void InstrAccessBits::MarkAccess(InstrRegister& reg) {
|
||||
uint64_t bits = 0;
|
||||
if (reg.access & InstrRegister::kRead) {
|
||||
bits |= 0x1;
|
||||
}
|
||||
if (reg.access & InstrRegister::kWrite) {
|
||||
bits |= 0x2;
|
||||
}
|
||||
|
||||
switch (reg.set) {
|
||||
case InstrRegister::kXER:
|
||||
spr |= bits << (2 * 0);
|
||||
break;
|
||||
case InstrRegister::kLR:
|
||||
spr |= bits << (2 * 1);
|
||||
break;
|
||||
case InstrRegister::kCTR:
|
||||
spr |= bits << (2 * 2);
|
||||
break;
|
||||
case InstrRegister::kCR:
|
||||
cr |= bits << (2 * reg.ordinal);
|
||||
break;
|
||||
case InstrRegister::kFPSCR:
|
||||
spr |= bits << (2 * 3);
|
||||
break;
|
||||
case InstrRegister::kGPR:
|
||||
gpr |= bits << (2 * reg.ordinal);
|
||||
break;
|
||||
case InstrRegister::kFPR:
|
||||
fpr |= bits << (2 * reg.ordinal);
|
||||
break;
|
||||
case InstrRegister::kVMX:
|
||||
if (reg.ordinal < 32) {
|
||||
vr31_0 |= bits << (2 * reg.ordinal);
|
||||
} else if (reg.ordinal < 64) {
|
||||
vr63_32 |= bits << (2 * (reg.ordinal - 32));
|
||||
} else if (reg.ordinal < 96) {
|
||||
vr95_64 |= bits << (2 * (reg.ordinal - 64));
|
||||
} else {
|
||||
vr127_96 |= bits << (2 * (reg.ordinal - 96));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_unhandled_case(reg.set);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InstrAccessBits::Dump(std::string& out_str) {
|
||||
std::stringstream str;
|
||||
if (spr) {
|
||||
uint64_t spr_t = spr;
|
||||
if (spr_t & 0x3) {
|
||||
str << "XER [";
|
||||
str << ((spr_t & 1) ? "R" : " ");
|
||||
str << ((spr_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
spr_t >>= 2;
|
||||
if (spr_t & 0x3) {
|
||||
str << "LR [";
|
||||
str << ((spr_t & 1) ? "R" : " ");
|
||||
str << ((spr_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
spr_t >>= 2;
|
||||
if (spr_t & 0x3) {
|
||||
str << "CTR [";
|
||||
str << ((spr_t & 1) ? "R" : " ");
|
||||
str << ((spr_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
spr_t >>= 2;
|
||||
if (spr_t & 0x3) {
|
||||
str << "FPCSR [";
|
||||
str << ((spr_t & 1) ? "R" : " ");
|
||||
str << ((spr_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
spr_t >>= 2;
|
||||
}
|
||||
|
||||
if (cr) {
|
||||
uint64_t cr_t = cr;
|
||||
for (size_t n = 0; n < 8; n++) {
|
||||
if (cr_t & 0x3) {
|
||||
str << "cr" << n << " [";
|
||||
str << ((cr_t & 1) ? "R" : " ");
|
||||
str << ((cr_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
cr_t >>= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (gpr) {
|
||||
uint64_t gpr_t = gpr;
|
||||
for (size_t n = 0; n < 32; n++) {
|
||||
if (gpr_t & 0x3) {
|
||||
str << "r" << n << " [";
|
||||
str << ((gpr_t & 1) ? "R" : " ");
|
||||
str << ((gpr_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
gpr_t >>= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (fpr) {
|
||||
uint64_t fpr_t = fpr;
|
||||
for (size_t n = 0; n < 32; n++) {
|
||||
if (fpr_t & 0x3) {
|
||||
str << "f" << n << " [";
|
||||
str << ((fpr_t & 1) ? "R" : " ");
|
||||
str << ((fpr_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
fpr_t >>= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (vr31_0) {
|
||||
uint64_t vr31_0_t = vr31_0;
|
||||
for (size_t n = 0; n < 32; n++) {
|
||||
if (vr31_0_t & 0x3) {
|
||||
str << "vr" << n << " [";
|
||||
str << ((vr31_0_t & 1) ? "R" : " ");
|
||||
str << ((vr31_0_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
vr31_0_t >>= 2;
|
||||
}
|
||||
}
|
||||
if (vr63_32) {
|
||||
uint64_t vr63_32_t = vr63_32;
|
||||
for (size_t n = 0; n < 32; n++) {
|
||||
if (vr63_32_t & 0x3) {
|
||||
str << "vr" << (n + 32) << " [";
|
||||
str << ((vr63_32_t & 1) ? "R" : " ");
|
||||
str << ((vr63_32_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
vr63_32_t >>= 2;
|
||||
}
|
||||
}
|
||||
if (vr95_64) {
|
||||
uint64_t vr95_64_t = vr95_64;
|
||||
for (size_t n = 0; n < 32; n++) {
|
||||
if (vr95_64_t & 0x3) {
|
||||
str << "vr" << (n + 64) << " [";
|
||||
str << ((vr95_64_t & 1) ? "R" : " ");
|
||||
str << ((vr95_64_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
vr95_64_t >>= 2;
|
||||
}
|
||||
}
|
||||
if (vr127_96) {
|
||||
uint64_t vr127_96_t = vr127_96;
|
||||
for (size_t n = 0; n < 32; n++) {
|
||||
if (vr127_96_t & 0x3) {
|
||||
str << "vr" << (n + 96) << " [";
|
||||
str << ((vr127_96_t & 1) ? "R" : " ");
|
||||
str << ((vr127_96_t & 2) ? "W" : " ");
|
||||
str << "] ";
|
||||
}
|
||||
vr127_96_t >>= 2;
|
||||
}
|
||||
}
|
||||
|
||||
out_str = str.str();
|
||||
}
|
||||
|
||||
void InstrDisasm::Init(const char* new_name, const char* new_info,
|
||||
uint32_t new_flags) {
|
||||
name = new_name;
|
||||
info = new_info;
|
||||
flags = new_flags;
|
||||
}
|
||||
|
||||
void InstrDisasm::AddLR(InstrRegister::Access access) {}
|
||||
|
||||
void InstrDisasm::AddCTR(InstrRegister::Access access) {}
|
||||
|
||||
void InstrDisasm::AddCR(uint32_t bf, 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::AddSImmOperand(uint64_t value, size_t width,
|
||||
const char* display) {}
|
||||
|
||||
void InstrDisasm::AddUImmOperand(uint64_t value, size_t width,
|
||||
const char* display) {}
|
||||
|
||||
int InstrDisasm::Finish() { return 0; }
|
||||
|
||||
void InstrDisasm::Dump(std::string& out_str, size_t pad) {
|
||||
out_str = name;
|
||||
if (flags & InstrDisasm::kOE) {
|
||||
out_str += "o";
|
||||
}
|
||||
if (flags & InstrDisasm::kRc) {
|
||||
out_str += ".";
|
||||
}
|
||||
if (flags & InstrDisasm::kLR) {
|
||||
out_str += "l";
|
||||
}
|
||||
}
|
||||
|
||||
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 = tables::instr_table_4[select_bits(code, 0, 10)];
|
||||
break;
|
||||
case 19:
|
||||
// Opcode = 19, index = bits 10-1 (10)
|
||||
slot = tables::instr_table_19[select_bits(code, 1, 10)];
|
||||
break;
|
||||
case 30:
|
||||
// Opcode = 30, index = bits 4-1 (4)
|
||||
// Special cased to an uber instruction.
|
||||
slot = tables::instr_table_30[select_bits(code, 0, 0)];
|
||||
break;
|
||||
case 31:
|
||||
// Opcode = 31, index = bits 10-1 (10)
|
||||
slot = tables::instr_table_31[select_bits(code, 1, 10)];
|
||||
break;
|
||||
case 58:
|
||||
// Opcode = 58, index = bits 1-0 (2)
|
||||
slot = tables::instr_table_58[select_bits(code, 0, 1)];
|
||||
break;
|
||||
case 59:
|
||||
// Opcode = 59, index = bits 5-1 (5)
|
||||
slot = tables::instr_table_59[select_bits(code, 1, 5)];
|
||||
break;
|
||||
case 62:
|
||||
// Opcode = 62, index = bits 1-0 (2)
|
||||
slot = tables::instr_table_62[select_bits(code, 0, 1)];
|
||||
break;
|
||||
case 63:
|
||||
// Opcode = 63, index = bits 10-1 (10)
|
||||
slot = tables::instr_table_63[select_bits(code, 1, 10)];
|
||||
break;
|
||||
default:
|
||||
slot = tables::instr_table[select_bits(code, 26, 31)];
|
||||
break;
|
||||
}
|
||||
if (slot && slot->opcode) {
|
||||
return slot;
|
||||
}
|
||||
|
||||
// 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 < xe::countof(tables::instr_table_scan); n++) {
|
||||
slot = &(tables::instr_table_scan[n]);
|
||||
if (slot->opcode == (code & slot->opcode_mask)) {
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
|
||||
InstrType* instr_type = GetInstrType(code);
|
||||
assert_not_null(instr_type);
|
||||
if (!instr_type) {
|
||||
return 1;
|
||||
}
|
||||
all_instrs_.push_back(instr_type);
|
||||
assert_null(instr_type->emit);
|
||||
instr_type->emit = emit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
526
src/xenia/cpu/ppc/ppc_instr.h
Normal file
526
src/xenia/cpu/ppc/ppc_instr.h
Normal file
@@ -0,0 +1,526 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_INSTR_H_
|
||||
#define XENIA_CPU_PPC_PPC_INSTR_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/base/string_buffer.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
inline uint32_t make_bitmask(uint32_t a, uint32_t b) {
|
||||
return (static_cast<uint32_t>(-1) >> (31 - b)) & ~((1u << a) - 1);
|
||||
}
|
||||
|
||||
inline uint32_t select_bits(uint32_t value, uint32_t a, uint32_t b) {
|
||||
return (value & make_bitmask(a, b)) >> a;
|
||||
}
|
||||
|
||||
// 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,
|
||||
} xe_ppc_instr_format_e;
|
||||
|
||||
enum xe_ppc_instr_mask_e : uint32_t {
|
||||
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,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
kXEPPCInstrTypeGeneral = (1 << 0),
|
||||
kXEPPCInstrTypeSynchronizeContext = (1 << 1),
|
||||
kXEPPCInstrTypeBranch = kXEPPCInstrTypeSynchronizeContext | (1 << 2),
|
||||
kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 3),
|
||||
kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 4),
|
||||
kXEPPCInstrTypeSyscall = kXEPPCInstrTypeSynchronizeContext | (1 << 5),
|
||||
} xe_ppc_instr_type_e;
|
||||
|
||||
typedef enum {
|
||||
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 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 XEMASK(uint32_t mstart, uint32_t mstop) {
|
||||
// if mstart ≤ mstop then
|
||||
// mask[mstart:mstop] = ones
|
||||
// mask[all other bits] = zeros
|
||||
// else
|
||||
// mask[mstart:63] = ones
|
||||
// mask[0:mstop] = ones
|
||||
// mask[all other bits] = zeros
|
||||
mstart &= 0x3F;
|
||||
mstop &= 0x3F;
|
||||
uint64_t value =
|
||||
(UINT64_MAX >> mstart) ^ ((mstop >= 63) ? 0 : UINT64_MAX >> (mstop + 1));
|
||||
return mstart <= mstop ? value : ~value;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
InstrType* type;
|
||||
uint32_t address;
|
||||
|
||||
union {
|
||||
uint32_t code;
|
||||
|
||||
// kXEPPCInstrFormatI
|
||||
struct {
|
||||
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;
|
||||
} B;
|
||||
|
||||
// kXEPPCInstrFormatSC
|
||||
// kXEPPCInstrFormatD
|
||||
struct {
|
||||
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;
|
||||
} 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;
|
||||
} 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;
|
||||
} XL;
|
||||
// kXEPPCInstrFormatXFX
|
||||
struct {
|
||||
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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} VXA;
|
||||
// kXEPPCInstrFormatVX
|
||||
struct {
|
||||
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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} VX128_R;
|
||||
// kXEPPCInstrFormatXDSS
|
||||
struct {
|
||||
} XDSS;
|
||||
};
|
||||
} InstrData;
|
||||
|
||||
typedef struct {
|
||||
enum RegisterSet {
|
||||
kXER,
|
||||
kLR,
|
||||
kCTR,
|
||||
kCR, // 0-7
|
||||
kFPSCR,
|
||||
kGPR, // 0-31
|
||||
kFPR, // 0-31
|
||||
kVMX, // 0-127
|
||||
};
|
||||
|
||||
enum Access {
|
||||
kRead = 1 << 0,
|
||||
kWrite = 1 << 1,
|
||||
kReadWrite = kRead | kWrite,
|
||||
};
|
||||
|
||||
RegisterSet set;
|
||||
uint32_t ordinal;
|
||||
Access access;
|
||||
} InstrRegister;
|
||||
|
||||
typedef struct {
|
||||
enum OperandType {
|
||||
kRegister,
|
||||
kImmediate,
|
||||
};
|
||||
|
||||
OperandType type;
|
||||
const char* display;
|
||||
union {
|
||||
InstrRegister reg;
|
||||
struct {
|
||||
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) {}
|
||||
|
||||
// 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 vr31_0;
|
||||
uint64_t vr63_32;
|
||||
uint64_t vr95_64;
|
||||
uint64_t vr127_96;
|
||||
|
||||
void Clear();
|
||||
void Extend(InstrAccessBits& other);
|
||||
void MarkAccess(InstrRegister& reg);
|
||||
void Dump(std::string& out_str);
|
||||
};
|
||||
|
||||
class InstrDisasm {
|
||||
public:
|
||||
enum Flags {
|
||||
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;
|
||||
|
||||
void Init(const char* new_name, const char* new_info, uint32_t new_flags);
|
||||
void AddLR(InstrRegister::Access access);
|
||||
void AddCTR(InstrRegister::Access access);
|
||||
void AddCR(uint32_t bf, InstrRegister::Access access);
|
||||
void AddFPSCR(InstrRegister::Access access);
|
||||
void AddRegOperand(InstrRegister::RegisterSet set, uint32_t ordinal,
|
||||
InstrRegister::Access access, const char* display = NULL);
|
||||
void AddSImmOperand(uint64_t value, size_t width, const char* display = NULL);
|
||||
void AddUImmOperand(uint64_t value, size_t width, const char* display = NULL);
|
||||
int Finish();
|
||||
|
||||
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
|
||||
InstrDisasmFn disasm;
|
||||
char name[16];
|
||||
uint32_t translation_count;
|
||||
|
||||
InstrEmitFn emit;
|
||||
};
|
||||
|
||||
void DumpAllInstrCounts();
|
||||
InstrType* GetInstrType(uint32_t code);
|
||||
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_INSTR_H_
|
||||
1100
src/xenia/cpu/ppc/ppc_instr_tables.h
Normal file
1100
src/xenia/cpu/ppc/ppc_instr_tables.h
Normal file
File diff suppressed because it is too large
Load Diff
371
src/xenia/cpu/ppc/ppc_scanner.cc
Normal file
371
src/xenia/cpu/ppc/ppc_scanner.cc
Normal file
@@ -0,0 +1,371 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_scanner.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/memory.h"
|
||||
#include "xenia/base/profiling.h"
|
||||
#include "xenia/cpu/ppc/ppc_frontend.h"
|
||||
#include "xenia/cpu/ppc/ppc_instr.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
|
||||
#if 0
|
||||
#define LOGPPC(fmt, ...) XELOGCORE('p', fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define LOGPPC(fmt, ...) \
|
||||
do { \
|
||||
} while (false)
|
||||
#endif
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
PPCScanner::PPCScanner(PPCFrontend* frontend) : frontend_(frontend) {}
|
||||
|
||||
PPCScanner::~PPCScanner() {}
|
||||
|
||||
bool PPCScanner::IsRestGprLr(uint32_t address) {
|
||||
auto function = frontend_->processor()->QueryFunction(address);
|
||||
return function && function->behavior() == Function::Behavior::kEpilogReturn;
|
||||
}
|
||||
|
||||
bool PPCScanner::Scan(GuestFunction* function, DebugInfo* debug_info) {
|
||||
// This is a simple basic block analyizer. It walks the start address to the
|
||||
// end address looking for branches. Each span of instructions between
|
||||
// branches is considered a basic block. When the last blr (that has no
|
||||
// branches to after it) is found the function is considered ended. If this
|
||||
// is before the expected end address then the function address range is
|
||||
// split up and the second half is treated as another function.
|
||||
|
||||
Memory* memory = frontend_->memory();
|
||||
|
||||
LOGPPC("Analyzing function %.8X...", function->address());
|
||||
|
||||
// For debug info, only if needed.
|
||||
uint32_t address_reference_count = 0;
|
||||
uint32_t instruction_result_count = 0;
|
||||
|
||||
uint32_t start_address = static_cast<uint32_t>(function->address());
|
||||
uint32_t end_address = static_cast<uint32_t>(function->end_address());
|
||||
uint32_t address = start_address;
|
||||
uint32_t furthest_target = start_address;
|
||||
size_t blocks_found = 0;
|
||||
bool in_block = false;
|
||||
bool starts_with_mfspr_lr = false;
|
||||
InstrData i;
|
||||
while (true) {
|
||||
i.address = address;
|
||||
i.code = xe::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
|
||||
|
||||
// If we fetched 0 assume that we somehow hit one of the awesome
|
||||
// 'no really we meant to end after that bl' functions.
|
||||
if (!i.code) {
|
||||
LOGPPC("function end %.8X (0x00000000 read)", address);
|
||||
// Don't include the 0's.
|
||||
address -= 4;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO(benvanik): find a way to avoid using the opcode tables.
|
||||
// This lookup is *expensive* and should be avoided when scanning.
|
||||
i.type = GetInstrType(i.code);
|
||||
|
||||
// TODO(benvanik): switch on instruction metadata.
|
||||
++address_reference_count;
|
||||
++instruction_result_count;
|
||||
|
||||
// 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 &&
|
||||
(((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F)) == 8) {
|
||||
starts_with_mfspr_lr = true;
|
||||
}
|
||||
|
||||
if (!in_block) {
|
||||
in_block = true;
|
||||
blocks_found++;
|
||||
}
|
||||
|
||||
bool ends_fn = false;
|
||||
bool ends_block = false;
|
||||
if (!i.type) {
|
||||
// Invalid instruction.
|
||||
// We can just ignore it because there's (very little)/no chance it'll
|
||||
// affect flow control.
|
||||
LOGPPC("Invalid instruction at %.8X: %.8X", address, i.code);
|
||||
} else if (i.code == 0x4E800020) {
|
||||
// blr -- unconditional branch to LR.
|
||||
// This is generally a return.
|
||||
if (furthest_target > address) {
|
||||
// Remaining targets within function, not end.
|
||||
LOGPPC("ignoring blr %.8X (branch to %.8X)", address, furthest_target);
|
||||
} else {
|
||||
// Function end point.
|
||||
LOGPPC("function end %.8X", address);
|
||||
ends_fn = true;
|
||||
}
|
||||
ends_block = true;
|
||||
} else if (i.code == 0x4E800420) {
|
||||
// bctr -- unconditional branch to CTR.
|
||||
// This is generally a jump to a function pointer (non-return).
|
||||
// This is almost always a jump table.
|
||||
// TODO(benvanik): decode jump tables.
|
||||
if (furthest_target > address) {
|
||||
// Remaining targets within function, not end.
|
||||
LOGPPC("ignoring bctr %.8X (branch to %.8X)", address, furthest_target);
|
||||
} else {
|
||||
// Function end point.
|
||||
LOGPPC("function end %.8X", address);
|
||||
ends_fn = true;
|
||||
}
|
||||
ends_block = true;
|
||||
} else if (i.type->opcode == 0x48000000) {
|
||||
// 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) {
|
||||
LOGPPC("bl %.8X -> %.8X", address, target);
|
||||
// Queue call target if needed.
|
||||
// GetOrInsertFunction(target);
|
||||
} else {
|
||||
LOGPPC("b %.8X -> %.8X", address, target);
|
||||
|
||||
// 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) {
|
||||
LOGPPC("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) {
|
||||
LOGPPC("function end %.8X (back b before addr)", address);
|
||||
ends_fn = true;
|
||||
}
|
||||
|
||||
// If the target is a __restgprlr_* method it's the end of a function.
|
||||
// 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)) {
|
||||
LOGPPC("function end %.8X (__restgprlr_*)", address);
|
||||
ends_fn = true;
|
||||
}
|
||||
|
||||
// Heuristic: if there's an unconditional branch in the first block of
|
||||
// the function it's likely a thunk.
|
||||
// Ex:
|
||||
// li r3, 0
|
||||
// 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) {
|
||||
LOGPPC("HEURISTIC: ending at simple leaf thunk %.8X", address);
|
||||
ends_fn = true;
|
||||
}
|
||||
|
||||
// Heuristic: if this is an unconditional branch at the end of the
|
||||
// function (nothing jumps over us) and we are jumping forward there's
|
||||
// a good chance it's a tail call.
|
||||
// This may not be true if the code is jumping over data/etc.
|
||||
// TODO(benvanik): figure out how to do this reliably. This check as is
|
||||
// is too aggressive and turns a lot of valid branches into tail calls.
|
||||
// It seems like a lot of functions end up with some prologue bit then
|
||||
// jump deep inside only to jump back towards the top soon after. May
|
||||
// need something more complex than just a simple 1-pass system to
|
||||
// detect these, unless more signals can be found.
|
||||
/*
|
||||
if (!ends_fn &&
|
||||
target > addr &&
|
||||
furthest_target < addr) {
|
||||
LOGPPC("HEURISTIC: ending at tail call branch %.8X", addr);
|
||||
ends_fn = true;
|
||||
}
|
||||
*/
|
||||
|
||||
if (!ends_fn && !IsRestGprLr(target)) {
|
||||
furthest_target = std::max(furthest_target, target);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
ends_block = true;
|
||||
} else if (i.type->opcode == 0x40000000) {
|
||||
// bc/bca/bcl/bcla
|
||||
uint32_t target =
|
||||
(uint32_t)XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)address);
|
||||
if (i.B.LK) {
|
||||
LOGPPC("bcl %.8X -> %.8X", address, target);
|
||||
|
||||
// Queue call target if needed.
|
||||
// TODO(benvanik): see if this is correct - not sure anyone makes
|
||||
// function calls with bcl.
|
||||
// GetOrInsertFunction(target);
|
||||
} else {
|
||||
LOGPPC("bc %.8X -> %.8X", address, target);
|
||||
|
||||
// TODO(benvanik): GetOrInsertFunction? it's likely a BB
|
||||
|
||||
if (!IsRestGprLr(target)) {
|
||||
furthest_target = std::max(furthest_target, target);
|
||||
}
|
||||
}
|
||||
ends_block = true;
|
||||
} else if (i.type->opcode == 0x4C000020) {
|
||||
// bclr/bclrl
|
||||
if (i.XL.LK) {
|
||||
LOGPPC("bclrl %.8X", address);
|
||||
} else {
|
||||
LOGPPC("bclr %.8X", address);
|
||||
}
|
||||
ends_block = true;
|
||||
} else if (i.type->opcode == 0x4C000420) {
|
||||
// bcctr/bcctrl
|
||||
if (i.XL.LK) {
|
||||
LOGPPC("bcctrl %.8X", address);
|
||||
} else {
|
||||
LOGPPC("bcctr %.8X", address);
|
||||
}
|
||||
ends_block = true;
|
||||
}
|
||||
|
||||
if (ends_block) {
|
||||
in_block = false;
|
||||
}
|
||||
if (ends_fn) {
|
||||
break;
|
||||
}
|
||||
|
||||
address += 4;
|
||||
if (end_address && address > end_address) {
|
||||
// Hmm....
|
||||
LOGPPC("Ran over function bounds! %.8X-%.8X", start_address, end_address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (end_address && address + 4 < end_address) {
|
||||
// Ran under the expected value - since we probably got the initial bounds
|
||||
// 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.
|
||||
LOGPPC("Function ran under: %.8X-%.8X ended at %.8X", start_address,
|
||||
end_address, address + 4);
|
||||
}
|
||||
function->set_end_address(address);
|
||||
|
||||
// If there's spare bits at the end, split the function.
|
||||
// TODO(benvanik): splitting?
|
||||
|
||||
// TODO(benvanik): find and record stack information
|
||||
// - look for __savegprlr_* and __restgprlr_*
|
||||
// - if present, flag function as needing a stack
|
||||
// - record prolog/epilog lengths/stack size/etc
|
||||
|
||||
if (debug_info) {
|
||||
debug_info->set_address_reference_count(address_reference_count);
|
||||
debug_info->set_instruction_result_count(instruction_result_count);
|
||||
}
|
||||
|
||||
LOGPPC("Finished analyzing %.8X", start_address);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<BlockInfo> PPCScanner::FindBlocks(GuestFunction* function) {
|
||||
Memory* memory = frontend_->memory();
|
||||
|
||||
std::map<uint32_t, BlockInfo> block_map;
|
||||
|
||||
uint32_t start_address = function->address();
|
||||
uint32_t end_address = function->end_address();
|
||||
bool in_block = false;
|
||||
uint32_t block_start = 0;
|
||||
InstrData i;
|
||||
for (uint32_t address = start_address; address <= end_address; address += 4) {
|
||||
i.address = address;
|
||||
i.code = xe::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
|
||||
if (!i.code) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO(benvanik): find a way to avoid using the opcode tables.
|
||||
// This lookup is *expensive* and should be avoided when scanning.
|
||||
i.type = GetInstrType(i.code);
|
||||
|
||||
if (!in_block) {
|
||||
in_block = true;
|
||||
block_start = address;
|
||||
}
|
||||
|
||||
bool ends_block = false;
|
||||
if (!i.type) {
|
||||
// Invalid instruction.
|
||||
} else if (i.code == 0x4E800020) {
|
||||
// blr -- unconditional branch to LR.
|
||||
ends_block = true;
|
||||
} else if (i.code == 0x4E800420) {
|
||||
// bctr -- unconditional branch to CTR.
|
||||
// This is almost always a jump table.
|
||||
// TODO(benvanik): decode jump tables.
|
||||
ends_block = true;
|
||||
} else if (i.type->opcode == 0x48000000) {
|
||||
// b/ba/bl/bla
|
||||
// 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)XEEXTS16(i.B.BD << 2) + (i.B.AA ? 0 : (int32_t)address);
|
||||
ends_block = true;
|
||||
} else if (i.type->opcode == 0x4C000020) {
|
||||
// bclr/bclrl
|
||||
ends_block = true;
|
||||
} else if (i.type->opcode == 0x4C000420) {
|
||||
// bcctr/bcctrl
|
||||
ends_block = true;
|
||||
}
|
||||
|
||||
if (ends_block) {
|
||||
in_block = false;
|
||||
block_map[block_start] = {
|
||||
block_start, address,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (in_block) {
|
||||
block_map[block_start] = {
|
||||
block_start, end_address,
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<BlockInfo> blocks;
|
||||
for (auto it = block_map.begin(); it != block_map.end(); ++it) {
|
||||
blocks.push_back(it->second);
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
48
src/xenia/cpu/ppc/ppc_scanner.h
Normal file
48
src/xenia/cpu/ppc/ppc_scanner.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_SCANNER_H_
|
||||
#define XENIA_CPU_PPC_PPC_SCANNER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/cpu/debug_info.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
class PPCFrontend;
|
||||
|
||||
struct BlockInfo {
|
||||
uint32_t start_address;
|
||||
uint32_t end_address;
|
||||
};
|
||||
|
||||
class PPCScanner {
|
||||
public:
|
||||
explicit PPCScanner(PPCFrontend* frontend);
|
||||
~PPCScanner();
|
||||
|
||||
bool Scan(GuestFunction* function, DebugInfo* debug_info);
|
||||
|
||||
std::vector<BlockInfo> FindBlocks(GuestFunction* function);
|
||||
|
||||
private:
|
||||
bool IsRestGprLr(uint32_t address);
|
||||
|
||||
PPCFrontend* frontend_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_SCANNER_H_
|
||||
246
src/xenia/cpu/ppc/ppc_translator.cc
Normal file
246
src/xenia/cpu/ppc/ppc_translator.cc
Normal file
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/cpu/ppc/ppc_translator.h"
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#include "xenia/base/assert.h"
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/base/memory.h"
|
||||
#include "xenia/base/profiling.h"
|
||||
#include "xenia/base/reset_scope.h"
|
||||
#include "xenia/cpu/compiler/compiler_passes.h"
|
||||
#include "xenia/cpu/cpu_flags.h"
|
||||
#include "xenia/cpu/ppc/ppc_disasm.h"
|
||||
#include "xenia/cpu/ppc/ppc_frontend.h"
|
||||
#include "xenia/cpu/ppc/ppc_hir_builder.h"
|
||||
#include "xenia/cpu/ppc/ppc_instr.h"
|
||||
#include "xenia/cpu/ppc/ppc_scanner.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
#include "xenia/debug/debugger.h"
|
||||
|
||||
DEFINE_bool(preserve_hir_disasm, true,
|
||||
"Preserves HIR disassembly for the debugger when it is attached.");
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
using xe::cpu::backend::Backend;
|
||||
using xe::cpu::compiler::Compiler;
|
||||
namespace passes = xe::cpu::compiler::passes;
|
||||
|
||||
PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
||||
Backend* backend = frontend->processor()->backend();
|
||||
|
||||
scanner_.reset(new PPCScanner(frontend));
|
||||
builder_.reset(new PPCHIRBuilder(frontend));
|
||||
compiler_.reset(new Compiler(frontend->processor()));
|
||||
assembler_ = backend->CreateAssembler();
|
||||
assembler_->Initialize();
|
||||
|
||||
bool validate = FLAGS_validate_hir;
|
||||
|
||||
// Merge blocks early. This will let us use more context in other passes.
|
||||
// The CFG is required for simplification and dirtied by it.
|
||||
compiler_->AddPass(std::make_unique<passes::ControlFlowAnalysisPass>());
|
||||
compiler_->AddPass(std::make_unique<passes::ControlFlowSimplificationPass>());
|
||||
|
||||
// Passes are executed in the order they are added. Multiple of the same
|
||||
// pass type may be used.
|
||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||
compiler_->AddPass(std::make_unique<passes::ContextPromotionPass>());
|
||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||
compiler_->AddPass(std::make_unique<passes::SimplificationPass>());
|
||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||
compiler_->AddPass(std::make_unique<passes::ConstantPropagationPass>());
|
||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||
if (backend->machine_info()->supports_extended_load_store) {
|
||||
// Backend supports the advanced LOAD/STORE instructions.
|
||||
// These will save us a lot of HIR opcodes.
|
||||
compiler_->AddPass(
|
||||
std::make_unique<passes::MemorySequenceCombinationPass>());
|
||||
if (validate)
|
||||
compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||
}
|
||||
compiler_->AddPass(std::make_unique<passes::SimplificationPass>());
|
||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||
// compiler_->AddPass(std::make_unique<passes::DeadStoreEliminationPass>());
|
||||
// if (validate)
|
||||
// compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||
compiler_->AddPass(std::make_unique<passes::DeadCodeEliminationPass>());
|
||||
if (validate) compiler_->AddPass(std::make_unique<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());
|
||||
|
||||
// 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(std::make_unique<passes::RegisterAllocationPass>(
|
||||
backend->machine_info()));
|
||||
if (validate) compiler_->AddPass(std::make_unique<passes::ValidationPass>());
|
||||
|
||||
// Must come last. The HIR is not really HIR after this.
|
||||
compiler_->AddPass(std::make_unique<passes::FinalizationPass>());
|
||||
}
|
||||
|
||||
PPCTranslator::~PPCTranslator() = default;
|
||||
|
||||
bool PPCTranslator::Translate(GuestFunction* function,
|
||||
uint32_t debug_info_flags) {
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
// Reset() all caching when we leave.
|
||||
xe::make_reset_scope(builder_);
|
||||
xe::make_reset_scope(compiler_);
|
||||
xe::make_reset_scope(assembler_);
|
||||
xe::make_reset_scope(&string_buffer_);
|
||||
|
||||
// NOTE: we only want to do this when required, as it's expensive to build.
|
||||
if (FLAGS_preserve_hir_disasm && frontend_->processor()->debugger() &&
|
||||
frontend_->processor()->debugger()->is_attached()) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoDisasmRawHir |
|
||||
DebugInfoFlags::kDebugInfoDisasmHir;
|
||||
}
|
||||
if (FLAGS_disassemble_functions) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoAllDisasm;
|
||||
}
|
||||
if (FLAGS_trace_functions) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctions;
|
||||
}
|
||||
if (FLAGS_trace_function_coverage) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionCoverage;
|
||||
}
|
||||
if (FLAGS_trace_function_references) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionReferences;
|
||||
}
|
||||
if (FLAGS_trace_function_data) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionData;
|
||||
}
|
||||
std::unique_ptr<DebugInfo> debug_info;
|
||||
if (debug_info_flags) {
|
||||
debug_info.reset(new DebugInfo());
|
||||
}
|
||||
|
||||
// Scan the function to find its extents and gather debug data.
|
||||
if (!scanner_->Scan(function, debug_info.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto debugger = frontend_->processor()->debugger();
|
||||
if (!debugger) {
|
||||
debug_info_flags &= ~DebugInfoFlags::kDebugInfoAllTracing;
|
||||
}
|
||||
|
||||
// Setup trace data, if needed.
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoTraceFunctions) {
|
||||
// Base trace data.
|
||||
size_t trace_data_size = debug::FunctionTraceData::SizeOfHeader();
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoTraceFunctionCoverage) {
|
||||
// Additional space for instruction coverage counts.
|
||||
trace_data_size += debug::FunctionTraceData::SizeOfInstructionCounts(
|
||||
function->address(), function->end_address());
|
||||
}
|
||||
uint8_t* trace_data = debugger->AllocateFunctionTraceData(trace_data_size);
|
||||
if (trace_data) {
|
||||
function->trace_data().Reset(trace_data, trace_data_size,
|
||||
function->address(),
|
||||
function->end_address());
|
||||
}
|
||||
}
|
||||
|
||||
// Stash source.
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoDisasmSource) {
|
||||
DumpSource(function, &string_buffer_);
|
||||
debug_info->set_source_disasm(string_buffer_.ToString());
|
||||
string_buffer_.Reset();
|
||||
}
|
||||
|
||||
if (false) {
|
||||
DumpAllInstrCounts();
|
||||
}
|
||||
|
||||
// Emit function.
|
||||
uint32_t emit_flags = 0;
|
||||
// if (debug_info) {
|
||||
emit_flags |= PPCHIRBuilder::EMIT_DEBUG_COMMENTS;
|
||||
//}
|
||||
if (!builder_->Emit(function, emit_flags)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stash raw HIR.
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoDisasmRawHir) {
|
||||
builder_->Dump(&string_buffer_);
|
||||
debug_info->set_raw_hir_disasm(string_buffer_.ToString());
|
||||
string_buffer_.Reset();
|
||||
}
|
||||
|
||||
// Compile/optimize/etc.
|
||||
if (!compiler_->Compile(builder_.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Stash optimized HIR.
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoDisasmHir) {
|
||||
builder_->Dump(&string_buffer_);
|
||||
debug_info->set_hir_disasm(string_buffer_.ToString());
|
||||
string_buffer_.Reset();
|
||||
}
|
||||
|
||||
// Assemble to backend machine code.
|
||||
if (!assembler_->Assemble(function, builder_.get(), debug_info_flags,
|
||||
std::move(debug_info))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PPCTranslator::DumpSource(GuestFunction* function,
|
||||
StringBuffer* string_buffer) {
|
||||
Memory* memory = frontend_->memory();
|
||||
|
||||
string_buffer->AppendFormat(
|
||||
"%s fn %.8X-%.8X %s\n", function->module()->name().c_str(),
|
||||
function->address(), function->end_address(), function->name().c_str());
|
||||
|
||||
auto blocks = scanner_->FindBlocks(function);
|
||||
|
||||
uint32_t start_address = function->address();
|
||||
uint32_t end_address = function->end_address();
|
||||
InstrData i;
|
||||
auto block_it = blocks.begin();
|
||||
for (uint32_t address = start_address, offset = 0; address <= end_address;
|
||||
address += 4, offset++) {
|
||||
i.address = address;
|
||||
i.code = xe::load_and_swap<uint32_t>(memory->TranslateVirtual(address));
|
||||
// TODO(benvanik): find a way to avoid using the opcode tables.
|
||||
i.type = GetInstrType(i.code);
|
||||
|
||||
// Check labels.
|
||||
if (block_it != blocks.end() && block_it->start_address == address) {
|
||||
string_buffer->AppendFormat("%.8X loc_%.8X:\n", address,
|
||||
address);
|
||||
++block_it;
|
||||
}
|
||||
|
||||
string_buffer->AppendFormat("%.8X %.8X ", address, i.code);
|
||||
DisasmPPC(&i, string_buffer);
|
||||
string_buffer->Append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
51
src/xenia/cpu/ppc/ppc_translator.h
Normal file
51
src/xenia/cpu/ppc/ppc_translator.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_PPC_TRANSLATOR_H_
|
||||
#define XENIA_CPU_PPC_PPC_TRANSLATOR_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/cpu/backend/assembler.h"
|
||||
#include "xenia/cpu/compiler/compiler.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
|
||||
namespace xe {
|
||||
namespace cpu {
|
||||
namespace ppc {
|
||||
|
||||
class PPCFrontend;
|
||||
class PPCHIRBuilder;
|
||||
class PPCScanner;
|
||||
|
||||
class PPCTranslator {
|
||||
public:
|
||||
explicit PPCTranslator(PPCFrontend* frontend);
|
||||
~PPCTranslator();
|
||||
|
||||
bool Translate(GuestFunction* function, uint32_t debug_info_flags);
|
||||
|
||||
private:
|
||||
void DumpSource(GuestFunction* function, StringBuffer* string_buffer);
|
||||
|
||||
PPCFrontend* frontend_;
|
||||
std::unique_ptr<PPCScanner> scanner_;
|
||||
std::unique_ptr<PPCHIRBuilder> builder_;
|
||||
std::unique_ptr<compiler::Compiler> compiler_;
|
||||
std::unique_ptr<backend::Assembler> assembler_;
|
||||
|
||||
StringBuffer string_buffer_;
|
||||
};
|
||||
|
||||
} // namespace ppc
|
||||
} // namespace cpu
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_CPU_PPC_PPC_TRANSLATOR_H_
|
||||
61
src/xenia/cpu/ppc/testing/README.md
Normal file
61
src/xenia/cpu/ppc/testing/README.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Codegen Tests
|
||||
|
||||
This directory contains the test assets used by the automated codegen test
|
||||
runner.
|
||||
|
||||
Each test is structured as a source `[name].s` PPC assembly file and the
|
||||
generated outputs. The outputs are made using the custom build of binutils
|
||||
setup when `xenia-build setup` is called and are checked in to make it easier
|
||||
to run the tests on Windows.
|
||||
|
||||
Tests are run using the `xenia-test` app or via `xenia-build test`.
|
||||
|
||||
## Execution
|
||||
|
||||
The test binary is placed into memory at `0x82010000` and all other memory is
|
||||
zeroed.
|
||||
|
||||
All registers are reset to zero. In order to provide useful inputs tests can
|
||||
specify `# REGISTER_IN` values.
|
||||
|
||||
The code is jumped into at the starting address and executed until the last
|
||||
instruction in the input file is reached.
|
||||
|
||||
After all instructions complete any `# REGISTER_OUT` values are checked and if
|
||||
they do not match the test is failed.
|
||||
|
||||
## Annotations
|
||||
|
||||
Annotations can appear at any line in a file. If a number is required it can
|
||||
be in either hex or decimal form, or IEEE if floating-point.
|
||||
|
||||
### REGISTER_IN
|
||||
|
||||
```
|
||||
# REGISTER_IN [register name] [register value]
|
||||
```
|
||||
|
||||
Sets the value of a register prior to executing the instructions.
|
||||
|
||||
Examples:
|
||||
```
|
||||
# REGISTER_IN r4 0x1234
|
||||
# REGISTER_IN r4 5678
|
||||
```
|
||||
|
||||
### REGISTER_OUT
|
||||
|
||||
```
|
||||
# REGISTER_OUT [register name] [register value]
|
||||
```
|
||||
|
||||
Defines the expected register value when the instructions have executed.
|
||||
If after all instructions have completed the register value does not match
|
||||
the value given here the test will fail.
|
||||
|
||||
Examples:
|
||||
```
|
||||
# REGISTER_OUT r3 123
|
||||
```
|
||||
|
||||
TODO: memory setup/assertions
|
||||
178
src/xenia/cpu/ppc/testing/instr_add.s
Normal file
178
src/xenia/cpu/ppc/testing/instr_add.s
Normal file
@@ -0,0 +1,178 @@
|
||||
test_add_1:
|
||||
#_ REGISTER_IN r5 0x00100000
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
|
||||
add r11, r5, r25
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x00100000
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0010FFFF
|
||||
|
||||
test_add_1_constant:
|
||||
lis r5, 0x10
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
|
||||
add r11, r5, r25
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x00100000
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0010FFFF
|
||||
|
||||
test_add_2:
|
||||
#_ REGISTER_IN r0 0x00100000
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
|
||||
add r11, r0, r25
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x00100000
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0010FFFF
|
||||
|
||||
test_add_2_constant:
|
||||
lis r0, 0x10
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
|
||||
add r11, r0, r25
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x00100000
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0010FFFF
|
||||
|
||||
test_add_cr_1:
|
||||
#_ REGISTER_IN r5 0x00100000
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
|
||||
add. r11, r5, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x00100000
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0010FFFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_add_cr_1_constant:
|
||||
lis r5, 0x10
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
|
||||
add. r11, r5, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x00100000
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0010FFFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_add_cr_2:
|
||||
#_ REGISTER_IN r0 0x00100000
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
|
||||
add. r11, r0, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x00100000
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0010FFFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_add_cr_2_constant:
|
||||
lis r0, 0x10
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
|
||||
add. r11, r0, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x00100000
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0010FFFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_add_cr_3:
|
||||
#_ REGISTER_IN r0 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0x000000000000FFFF
|
||||
|
||||
add. r11, r0, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x000000000000FFFF
|
||||
#_ REGISTER_OUT r11 0x000000000000FFFE
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_add_cr_3_constant:
|
||||
li r0, -1
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
|
||||
add. r11, r0, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x000000000000FFFF
|
||||
#_ REGISTER_OUT r11 0x000000000000FFFE
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_add_cr_4:
|
||||
#_ REGISTER_IN r0 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0x0000000000000001
|
||||
|
||||
add. r11, r0, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000000000000001
|
||||
#_ REGISTER_OUT r11 0x0000000000000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_add_cr_4_constant:
|
||||
li r0, -1
|
||||
li r25, 1
|
||||
|
||||
add. r11, r0, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000000000000001
|
||||
#_ REGISTER_OUT r11 0x0000000000000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_add_cr_5:
|
||||
#_ REGISTER_IN r0 -50
|
||||
#_ REGISTER_IN r25 -25
|
||||
|
||||
add. r11, r0, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 -50
|
||||
#_ REGISTER_OUT r25 -25
|
||||
#_ REGISTER_OUT r11 -75
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_add_cr_5_constant:
|
||||
li r0, -50
|
||||
li r25, -25
|
||||
|
||||
add. r11, r0, r25
|
||||
mfcr r12
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r0 -50
|
||||
#_ REGISTER_OUT r25 -25
|
||||
#_ REGISTER_OUT r11 -75
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
266
src/xenia/cpu/ppc/testing/instr_addc.s
Normal file
266
src/xenia/cpu/ppc/testing/instr_addc.s
Normal file
@@ -0,0 +1,266 @@
|
||||
test_addc_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 3
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addc_1_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 3
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addc_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addc_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addc_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addc_3_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addc_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 123
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007A
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addc_4_constant:
|
||||
li r4, -1
|
||||
li r5, 123
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007A
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addc_5:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addc_5_constant:
|
||||
li r5, -1
|
||||
srdi r4, r5, 1
|
||||
addc r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addc_cr_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 3
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addc_cr_1_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 3
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addc_cr_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addc_cr_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addc_cr_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addc_cr_3_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addc_cr_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 123
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007A
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addc_cr_4_constant:
|
||||
li r4, -1
|
||||
li r5, 123
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007A
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addc_cr_5:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addc_cr_5_constant:
|
||||
li r5, -1
|
||||
srdi r4, r5, 1
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addc_cr_6:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 2
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000001
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addc_cr_6_constant:
|
||||
li r4, -1
|
||||
srdi r4, r4, 1
|
||||
li r5, 2
|
||||
addc. r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000001
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
579
src/xenia/cpu/ppc/testing/instr_adde.s
Normal file
579
src/xenia/cpu/ppc/testing/instr_adde.s
Normal file
@@ -0,0 +1,579 @@
|
||||
test_adde_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 3
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_adde_1_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 3
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_adde_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 4
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_adde_2_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 4
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_adde_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_adde_3_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_adde_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_4_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_5_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_6_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 123
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007A
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_7_constant:
|
||||
li r4, -1
|
||||
li r5, 123
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007A
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_8:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 123
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007B
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_8_constant:
|
||||
li r4, -1
|
||||
li r5, 123
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007B
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_9:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_9_constant:
|
||||
li r5, -1
|
||||
srdi r4, r5, 1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_10:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_10_constant:
|
||||
li r5, -1
|
||||
srdi r4, r5, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_adde_cr_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 3
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_adde_cr_1_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 3
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_adde_cr_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 4
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_adde_cr_2_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 4
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_adde_cr_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r11 0x80000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_adde_cr_3_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r11 0x80000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_adde_cr_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x20000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_4_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x20000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x20000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_5_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x20000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_6_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 123
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007A
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_7_constant:
|
||||
li r4, -1
|
||||
li r5, 123
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007A
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_8:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 123
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007B
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_8_constant:
|
||||
li r4, -1
|
||||
li r5, 123
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000000000007B
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 123
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x40000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_9:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x80000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_9_constant:
|
||||
li r5, -1
|
||||
srdi r4, r5, 1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x80000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_10:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x80000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_adde_cr_10_constant:
|
||||
li r5, -1
|
||||
srdi r4, r5, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
adde. r3, r4, r5
|
||||
mfcr r11
|
||||
adde. r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r11 0x80000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
88
src/xenia/cpu/ppc/testing/instr_addic.s
Normal file
88
src/xenia/cpu/ppc/testing/instr_addic.s
Normal file
@@ -0,0 +1,88 @@
|
||||
test_addic_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
addic r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addic_1_constant:
|
||||
li r4, 1
|
||||
addic r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addic_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
addic r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addic_2_constant:
|
||||
li r4, -1
|
||||
addic r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addic_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFF
|
||||
addic r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addic_3_constant:
|
||||
li r4, 0xFFFFFFFF
|
||||
srwi r4, r4, 0
|
||||
addic r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addic_cr_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
addic. r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addic_cr_1_constant:
|
||||
li r4, 1
|
||||
addic. r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addic_cr_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
addic. r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addic_cr_2_constant:
|
||||
li r4, -1
|
||||
addic. r4, r4, 1
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
77
src/xenia/cpu/ppc/testing/instr_addis.s
Normal file
77
src/xenia/cpu/ppc/testing/instr_addis.s
Normal file
@@ -0,0 +1,77 @@
|
||||
test_addis_1:
|
||||
#_ REGISTER_IN r0 1234
|
||||
#_ REGISTER_IN r4 1
|
||||
addis r3, r0, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r0 1234
|
||||
#_ REGISTER_OUT r3 0x10000
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_addis_1_constant:
|
||||
li r0, 1234
|
||||
li r4, 1
|
||||
addis r3, r0, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r0 1234
|
||||
#_ REGISTER_OUT r3 0x10000
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_addis_2:
|
||||
#_ REGISTER_IN r4 1234
|
||||
#_ REGISTER_IN r5 1
|
||||
addis r3, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x104D2
|
||||
#_ REGISTER_OUT r4 1234
|
||||
|
||||
test_addis_2_constant:
|
||||
li r4, 1234
|
||||
li r5, 1
|
||||
addis r3, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x104D2
|
||||
#_ REGISTER_OUT r4 1234
|
||||
|
||||
test_lis_1:
|
||||
#_ REGISTER_IN r0 1234
|
||||
lis r3, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r0 1234
|
||||
#_ REGISTER_OUT r3 0x10000
|
||||
|
||||
test_lis_1_constant:
|
||||
li r0, 1234
|
||||
lis r3, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r0 1234
|
||||
#_ REGISTER_OUT r3 0x10000
|
||||
|
||||
test_lis_2:
|
||||
#_ REGISTER_IN r0 1234
|
||||
lis r3, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r0 1234
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF0000
|
||||
|
||||
test_lis_2_constant:
|
||||
li r0, 1234
|
||||
lis r3, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r0 1234
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF0000
|
||||
|
||||
test_subis_1:
|
||||
#_ REGISTER_IN r4 1234
|
||||
#_ REGISTER_IN r5 1
|
||||
subis r3, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF04D2
|
||||
#_ REGISTER_OUT r4 1234
|
||||
|
||||
test_subis_1_constant:
|
||||
li r4, 1234
|
||||
li r5, 1
|
||||
subis r3, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF04D2
|
||||
#_ REGISTER_OUT r4 1234
|
||||
367
src/xenia/cpu/ppc/testing/instr_addme.s
Normal file
367
src/xenia/cpu/ppc/testing/instr_addme.s
Normal file
@@ -0,0 +1,367 @@
|
||||
test_addme_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_1_constant:
|
||||
li r4, 1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_2_constant:
|
||||
li r4, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_3:
|
||||
#_ REGISTER_IN r4 12
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 11
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_3_constant:
|
||||
li r4, 12
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 11
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_4:
|
||||
#_ REGISTER_IN r4 12
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 12
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_4_constant:
|
||||
li r4, 12
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 12
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_5_constant:
|
||||
li r4, -1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_6_constant:
|
||||
li r4, -1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_7:
|
||||
#_ REGISTER_IN r4 0
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addme_7_constant:
|
||||
li r4, 0
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addme_8:
|
||||
#_ REGISTER_IN r4 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_8_constant:
|
||||
li r4, 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addme_cr_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addme_cr_1_constant:
|
||||
li r4, 1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addme_cr_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addme_cr_2_constant:
|
||||
li r4, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addme_cr_3:
|
||||
#_ REGISTER_IN r4 12
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 11
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addme_cr_3_constant:
|
||||
li r4, 12
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 11
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addme_cr_4:
|
||||
#_ REGISTER_IN r4 12
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 12
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addme_cr_4_constant:
|
||||
li r4, 12
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 12
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addme_cr_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addme_cr_5_constant:
|
||||
li r4, -1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addme_cr_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addme_cr_6_constant:
|
||||
li r4, -1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addme_cr_7:
|
||||
#_ REGISTER_IN r4 0
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addme_cr_7_constant:
|
||||
li r4, 0
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addme_cr_8:
|
||||
#_ REGISTER_IN r4 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addme_cr_8_constant:
|
||||
li r4, 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addme. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
367
src/xenia/cpu/ppc/testing/instr_addze.s
Normal file
367
src/xenia/cpu/ppc/testing/instr_addze.s
Normal file
@@ -0,0 +1,367 @@
|
||||
test_addze_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_1_constant:
|
||||
li r4, 1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_2_constant:
|
||||
li r4, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_3:
|
||||
#_ REGISTER_IN r4 12
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 12
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_3_constant:
|
||||
li r4, 12
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 12
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_4:
|
||||
#_ REGISTER_IN r4 12
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 13
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_4_constant:
|
||||
li r4, 12
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 13
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_5_constant:
|
||||
li r4, -1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addze_6_constant:
|
||||
li r4, -1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_addze_7:
|
||||
#_ REGISTER_IN r4 0
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_7_constant:
|
||||
li r4, 0
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_8:
|
||||
#_ REGISTER_IN r4 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_8_constant:
|
||||
li r4, 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze r3, r4
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_addze_cr_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_1_constant:
|
||||
li r4, 1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_2_constant:
|
||||
li r4, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_3:
|
||||
#_ REGISTER_IN r4 12
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 12
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_3_constant:
|
||||
li r4, 12
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 12
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_4:
|
||||
#_ REGISTER_IN r4 12
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 13
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_4_constant:
|
||||
li r4, 12
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 13
|
||||
#_ REGISTER_OUT r4 12
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addze_cr_5_constant:
|
||||
li r4, -1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_addze_cr_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addze_cr_6_constant:
|
||||
li r4, -1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addze_cr_7:
|
||||
#_ REGISTER_IN r4 0
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addze_cr_7_constant:
|
||||
li r4, 0
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_addze_cr_8:
|
||||
#_ REGISTER_IN r4 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_addze_cr_8_constant:
|
||||
li r4, 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1 # CA=1
|
||||
addze. r3, r4
|
||||
adde r6, r0, r0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
205
src/xenia/cpu/ppc/testing/instr_and.s
Normal file
205
src/xenia/cpu/ppc/testing/instr_and.s
Normal file
@@ -0,0 +1,205 @@
|
||||
test_and_1:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF
|
||||
and r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_and_1_constant:
|
||||
li r5, -1
|
||||
li r25, -1
|
||||
and r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_and_2:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0
|
||||
and r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
|
||||
test_and_2_constant:
|
||||
li r5, -1
|
||||
li r25, 0
|
||||
and r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
|
||||
test_and_3:
|
||||
#_ REGISTER_IN r5 0
|
||||
#_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF
|
||||
and r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
|
||||
test_and_3_constant:
|
||||
li r5, 0
|
||||
li r25, -1
|
||||
and r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
|
||||
test_and_4:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
and r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0000FFFF
|
||||
|
||||
test_and_4_constant:
|
||||
li r5, -1
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
and r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0000FFFF
|
||||
|
||||
test_and_5:
|
||||
#_ REGISTER_IN r0 0x100000FF
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
and r11, r0, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x000000FF
|
||||
|
||||
test_and_5_constant:
|
||||
lis r0, 0x1000
|
||||
ori r0, r0, 0xFF
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
and r11, r0, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x000000FF
|
||||
|
||||
test_and_cr_1:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF
|
||||
and. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_and_cr_1_constant:
|
||||
li r5, -1
|
||||
li r25, -1
|
||||
and. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_and_cr_2:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0
|
||||
and. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_and_cr_2_constant:
|
||||
li r5, -1
|
||||
li r25, 0
|
||||
and. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_and_cr_3:
|
||||
#_ REGISTER_IN r5 0
|
||||
#_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF
|
||||
and. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_and_cr_3_constant:
|
||||
li r5, 0
|
||||
li r25, -1
|
||||
and. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_and_cr_4:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
and. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0000FFFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_and_cr_4_constant:
|
||||
li r5, -1
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
and. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x0000FFFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_and_cr_5:
|
||||
#_ REGISTER_IN r0 0x100000FF
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
and. r11, r0, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x000000FF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_and_cr_5_constant:
|
||||
lis r0, 0x1000
|
||||
ori r0, r0, 0xFF
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
and. r11, r0, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x000000FF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
205
src/xenia/cpu/ppc/testing/instr_andc.s
Normal file
205
src/xenia/cpu/ppc/testing/instr_andc.s
Normal file
@@ -0,0 +1,205 @@
|
||||
test_andc_1:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF
|
||||
andc r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
|
||||
test_andc_1_constant:
|
||||
li r5, -1
|
||||
li r25, -1
|
||||
andc r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
|
||||
test_andc_2:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0
|
||||
andc r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_andc_2_constant:
|
||||
li r5, -1
|
||||
li r25, 0
|
||||
andc r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_andc_3:
|
||||
#_ REGISTER_IN r5 0
|
||||
#_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF
|
||||
andc r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
|
||||
test_andc_3_constant:
|
||||
li r5, 0
|
||||
li r25, -1
|
||||
andc r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
|
||||
test_andc_4:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
andc r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFF0000
|
||||
|
||||
test_andc_4_constant:
|
||||
li r5, -1
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
andc r11, r5, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFF0000
|
||||
|
||||
test_andc_5:
|
||||
#_ REGISTER_IN r0 0x100000FF
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
andc r11, r0, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x10000000
|
||||
|
||||
test_andc_5_constant:
|
||||
lis r0, 0x1000
|
||||
ori r0, r0, 0xFF
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
andc r11, r0, r25
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x10000000
|
||||
|
||||
test_andc_cr_1:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF
|
||||
andc. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andc_cr_1_constant:
|
||||
li r5, -1
|
||||
li r25, -1
|
||||
andc. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andc_cr_2:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0
|
||||
andc. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_andc_cr_2_constant:
|
||||
li r5, -1
|
||||
li r25, 0
|
||||
andc. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_andc_cr_3:
|
||||
#_ REGISTER_IN r5 0
|
||||
#_ REGISTER_IN r25 0xFFFFFFFFFFFFFFFF
|
||||
andc. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andc_cr_3_constant:
|
||||
li r5, 0
|
||||
li r25, -1
|
||||
andc. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r25 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andc_cr_4:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
andc. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFF0000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_andc_cr_4_constant:
|
||||
li r5, -1
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
andc. r11, r5, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFF0000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_andc_cr_5:
|
||||
#_ REGISTER_IN r0 0x100000FF
|
||||
#_ REGISTER_IN r25 0x0000FFFF
|
||||
andc. r11, r0, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x10000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_andc_cr_5_constant:
|
||||
lis r0, 0x1000
|
||||
ori r0, r0, 0xFF
|
||||
li r25, -1
|
||||
clrldi r25, r25, 48
|
||||
andc. r11, r0, r25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r25 0x0000FFFF
|
||||
#_ REGISTER_OUT r11 0x10000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
90
src/xenia/cpu/ppc/testing/instr_andi.s
Normal file
90
src/xenia/cpu/ppc/testing/instr_andi.s
Normal file
@@ -0,0 +1,90 @@
|
||||
test_andi_cr_1:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
andi. r11, r5, 0xCAFE
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0x0000CAFE
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_andi_cr_1_constant:
|
||||
li r5, -1
|
||||
andi. r11, r5, 0xCAFE
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0x0000CAFE
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_andi_cr_2:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
andi. r11, r5, 0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andi_cr_2_constant:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
andi. r11, r5, 0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andi_cr_3:
|
||||
#_ REGISTER_IN r5 0
|
||||
andi. r11, r5, 0xFFFF
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andi_cr_3_constant:
|
||||
li r5, 0
|
||||
andi. r11, r5, 0xFFFF
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andi_cr_4:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
andi. r11, r5, 0xCAFE
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0x0000CAFE
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_andi_cr_4_constant:
|
||||
li r5, -1
|
||||
andi. r11, r5, 0xCAFE
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0x0000CAFE
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_andi_cr_5:
|
||||
#_ REGISTER_IN r0 0x100000FF
|
||||
andi. r11, r0, 0xFFFF
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r11 0x000000FF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_andi_cr_5_constant:
|
||||
lis r0, 0x1000
|
||||
ori r0, r0, 0xFF
|
||||
andi. r11, r0, 0xFFFF
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r11 0x000000FF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
90
src/xenia/cpu/ppc/testing/instr_andis.s
Normal file
90
src/xenia/cpu/ppc/testing/instr_andis.s
Normal file
@@ -0,0 +1,90 @@
|
||||
test_andis_cr_1:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
andis. r11, r5, 0xCAFE
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xCAFE0000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_andis_cr_1_constant:
|
||||
li r5, -1
|
||||
andis. r11, r5, 0xCAFE
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xCAFE0000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_andis_cr_2:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
andis. r11, r5, 0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andis_cr_2_constant:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
andis. r11, r5, 0
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andis_cr_3:
|
||||
#_ REGISTER_IN r5 0
|
||||
andis. r11, r5, 0xFFFF
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andis_cr_3_constant:
|
||||
li r5, 0
|
||||
andis. r11, r5, 0xFFFF
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_andis_cr_4:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
andis. r11, r5, 0xCAFE
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xCAFE0000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_andis_cr_4_constant:
|
||||
li r5, -1
|
||||
andis. r11, r5, 0xCAFE
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xCAFE0000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_andis_cr_5:
|
||||
#_ REGISTER_IN r0 0x100000FF
|
||||
andis. r11, r0, 0xFFFF
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r11 0x10000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_andis_cr_5_constant:
|
||||
lis r0, 0x1000
|
||||
ori r0, r0, 0xFF
|
||||
andis. r11, r0, 0xFFFF
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r0 0x100000FF
|
||||
#_ REGISTER_OUT r11 0x10000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
186
src/xenia/cpu/ppc/testing/instr_cmp.s
Normal file
186
src/xenia/cpu/ppc/testing/instr_cmp.s
Normal file
@@ -0,0 +1,186 @@
|
||||
test_cmpd_1:
|
||||
#_ REGISTER_IN r3 0x0000000100000000
|
||||
#_ REGISTER_IN r4 0x0000000200000000
|
||||
cmpd r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r4 0x0000000200000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpd_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r3, 1
|
||||
cmpd r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r4 0x0000000200000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpd_2:
|
||||
#_ REGISTER_IN r3 0x0000000200000000
|
||||
#_ REGISTER_IN r4 0x0000000100000000
|
||||
cmpd r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000200000000
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpd_2_constant:
|
||||
li r4, 1
|
||||
sldi r4, r4, 32
|
||||
sldi r3, r4, 1
|
||||
cmpd r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000200000000
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpw_1:
|
||||
#_ REGISTER_IN r3 0x0000000100000000
|
||||
#_ REGISTER_IN r4 0x0000000200000000
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r4 0x0000000200000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmpw_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r3, 1
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r4 0x0000000200000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmpw_2:
|
||||
#_ REGISTER_IN r3 0x0000000200000000
|
||||
#_ REGISTER_IN r4 0x0000000100000000
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000200000000
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmpw_2_constant:
|
||||
li r4, 1
|
||||
sldi r4, r4, 32
|
||||
sldi r3, r4, 1
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000200000000
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmpw_3:
|
||||
#_ REGISTER_IN r3 1
|
||||
#_ REGISTER_IN r4 2
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpw_3_constant:
|
||||
li r3, 1
|
||||
li r4, 2
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpw_4:
|
||||
#_ REGISTER_IN r3 2
|
||||
#_ REGISTER_IN r4 1
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpw_4_constant:
|
||||
li r3, 2
|
||||
li r4, 1
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpw_5:
|
||||
#_ REGISTER_IN r3 0x0000000100000002
|
||||
#_ REGISTER_IN r4 0x0000000200000001
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000002
|
||||
#_ REGISTER_OUT r4 0x0000000200000001
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpw_5_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r3, 1
|
||||
addi r3, r3, 2
|
||||
addi r4, r4, 1
|
||||
cmpw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000002
|
||||
#_ REGISTER_OUT r4 0x0000000200000001
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmp_1:
|
||||
#_ REGISTER_IN r3 1
|
||||
#_ REGISTER_IN r4 2
|
||||
cmp 5, 0, r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r12 0x00000800
|
||||
|
||||
test_cmp_1_constant:
|
||||
li r3, 1
|
||||
li r4, 2
|
||||
cmp 5, 0, r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r12 0x00000800
|
||||
|
||||
test_cmp_2:
|
||||
#_ REGISTER_IN r3 2
|
||||
#_ REGISTER_IN r4 1
|
||||
cmp 3, 0, r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r12 0x00040000
|
||||
|
||||
test_cmp_2_constant:
|
||||
li r3, 2
|
||||
li r4, 1
|
||||
cmp 3, 0, r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r12 0x00040000
|
||||
116
src/xenia/cpu/ppc/testing/instr_cmpi.s
Normal file
116
src/xenia/cpu/ppc/testing/instr_cmpi.s
Normal file
@@ -0,0 +1,116 @@
|
||||
test_cmpdi_1:
|
||||
#_ REGISTER_IN r3 0x0000000100000000
|
||||
cmpdi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpdi_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
cmpdi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpdi_2:
|
||||
#_ REGISTER_IN r3 1
|
||||
cmpdi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpdi_2_constant:
|
||||
li r3, 1
|
||||
cmpdi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpwi_1:
|
||||
#_ REGISTER_IN r3 0x0000000100000000
|
||||
cmpwi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpwi_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
cmpwi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpwi_2:
|
||||
#_ REGISTER_IN r3 2
|
||||
cmpwi r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpwi_2_constant:
|
||||
li r3, 2
|
||||
cmpwi r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpwi_5:
|
||||
#_ REGISTER_IN r3 0x0000000100000002
|
||||
cmpwi r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000002
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpwi_5_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r3, 1
|
||||
addi r3, r3, 2
|
||||
cmpwi r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000002
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpi_1:
|
||||
#_ REGISTER_IN r3 1
|
||||
cmpi 5, 0, r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r12 0x00000800
|
||||
|
||||
test_cmpi_1_constant:
|
||||
li r3, 1
|
||||
cmpi 5, 0, r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r12 0x00000800
|
||||
|
||||
test_cmpi_2:
|
||||
#_ REGISTER_IN r3 2
|
||||
cmpi 3, 0, r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r12 0x00040000
|
||||
|
||||
test_cmpi_2_constant:
|
||||
li r3, 2
|
||||
cmpi 3, 0, r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r12 0x00040000
|
||||
209
src/xenia/cpu/ppc/testing/instr_cmpl.s
Normal file
209
src/xenia/cpu/ppc/testing/instr_cmpl.s
Normal file
@@ -0,0 +1,209 @@
|
||||
test_cmpld_1:
|
||||
#_ REGISTER_IN r3 0x0000000100000000
|
||||
#_ REGISTER_IN r4 0x0000000200000000
|
||||
cmpld r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r4 0x0000000200000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpld_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r3, 1
|
||||
cmpld r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r4 0x0000000200000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpld_2:
|
||||
#_ REGISTER_IN r3 0x0000000200000000
|
||||
#_ REGISTER_IN r4 0x0000000100000000
|
||||
cmpld r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000200000000
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpld_2_constant:
|
||||
li r4, 1
|
||||
sldi r4, r4, 32
|
||||
sldi r3, r4, 1
|
||||
cmpld r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000200000000
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmplw_1:
|
||||
#_ REGISTER_IN r3 0x0000000100000000
|
||||
#_ REGISTER_IN r4 0x0000000200000000
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r4 0x0000000200000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmplw_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r3, 1
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r4 0x0000000200000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmplw_2:
|
||||
#_ REGISTER_IN r3 0x0000000200000000
|
||||
#_ REGISTER_IN r4 0x0000000100000000
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000200000000
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmplw_2_constant:
|
||||
li r4, 1
|
||||
sldi r4, r4, 32
|
||||
sldi r3, r4, 1
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000200000000
|
||||
#_ REGISTER_OUT r4 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmplw_3:
|
||||
#_ REGISTER_IN r3 1
|
||||
#_ REGISTER_IN r4 2
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmplw_3_constant:
|
||||
li r3, 1
|
||||
li r4, 2
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmplw_4:
|
||||
#_ REGISTER_IN r3 2
|
||||
#_ REGISTER_IN r4 1
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmplw_4_constant:
|
||||
li r3, 2
|
||||
li r4, 1
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmplw_5:
|
||||
#_ REGISTER_IN r3 0x0000000100000002
|
||||
#_ REGISTER_IN r4 0x0000000200000001
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000002
|
||||
#_ REGISTER_OUT r4 0x0000000200000001
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmplw_5_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r3, 1
|
||||
addi r3, r3, 2
|
||||
addi r4, r4, 1
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000002
|
||||
#_ REGISTER_OUT r4 0x0000000200000001
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmplw_6:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_IN r4 0x0000000080000000
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0x0000000080000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmplw_6_constant:
|
||||
lis r3, 0x7FFF
|
||||
ori r3, r3, 0xFFFF
|
||||
not r3, r3
|
||||
li r4, 1
|
||||
sldi r4, r4, 31
|
||||
cmplw r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0x0000000080000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_cmpl_1:
|
||||
#_ REGISTER_IN r3 1
|
||||
#_ REGISTER_IN r4 2
|
||||
cmpl 5, 0, r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r12 0x00000800
|
||||
|
||||
test_cmpl_1_constant:
|
||||
li r3, 1
|
||||
li r4, 2
|
||||
cmpl 5, 0, r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r12 0x00000800
|
||||
|
||||
test_cmpl_2:
|
||||
#_ REGISTER_IN r3 2
|
||||
#_ REGISTER_IN r4 1
|
||||
cmpl 3, 0, r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r12 0x00040000
|
||||
|
||||
test_cmpl_2_constant:
|
||||
li r3, 2
|
||||
li r4, 1
|
||||
cmpl 3, 0, r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r12 0x00040000
|
||||
116
src/xenia/cpu/ppc/testing/instr_cmpli.s
Normal file
116
src/xenia/cpu/ppc/testing/instr_cmpli.s
Normal file
@@ -0,0 +1,116 @@
|
||||
test_cmpldi_1:
|
||||
#_ REGISTER_IN r3 0x0000000100000000
|
||||
cmpldi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpldi_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
cmpldi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpldi_2:
|
||||
#_ REGISTER_IN r3 1
|
||||
cmpldi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmpldi_2_constant:
|
||||
li r3, 1
|
||||
cmpldi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmplwi_1:
|
||||
#_ REGISTER_IN r3 0x0000000100000000
|
||||
cmplwi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmplwi_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
cmplwi r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_cmplwi_2:
|
||||
#_ REGISTER_IN r3 2
|
||||
cmplwi r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmplwi_2_constant:
|
||||
li r3, 2
|
||||
cmplwi r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmplwi_5:
|
||||
#_ REGISTER_IN r3 0x0000000100000002
|
||||
cmplwi r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000002
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmplwi_5_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r3, 1
|
||||
addi r3, r3, 2
|
||||
cmplwi r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000100000002
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_cmpli_1:
|
||||
#_ REGISTER_IN r3 1
|
||||
cmpli 5, 0, r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r12 0x00000800
|
||||
|
||||
test_cmpli_1_constant:
|
||||
li r3, 1
|
||||
cmpli 5, 0, r3, 2
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r12 0x00000800
|
||||
|
||||
test_cmpli_2:
|
||||
#_ REGISTER_IN r3 2
|
||||
cmpli 3, 0, r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r12 0x00040000
|
||||
|
||||
test_cmpli_2_constant:
|
||||
li r3, 2
|
||||
cmpli 3, 0, r3, 1
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r12 0x00040000
|
||||
56
src/xenia/cpu/ppc/testing/instr_cntlzd.s
Normal file
56
src/xenia/cpu/ppc/testing/instr_cntlzd.s
Normal file
@@ -0,0 +1,56 @@
|
||||
test_cntlzd_1:
|
||||
#_ REGISTER_IN r5 0
|
||||
cntlzd r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 64
|
||||
|
||||
test_cntlzd_1_constant:
|
||||
li r5, 0
|
||||
cntlzd r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 64
|
||||
|
||||
test_cntlzd_2:
|
||||
#_ REGISTER_IN r5 1
|
||||
cntlzd r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 63
|
||||
|
||||
test_cntlzd_2_constant:
|
||||
li r5, 1
|
||||
cntlzd r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 63
|
||||
|
||||
test_cntlzd_3:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
cntlzd r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_cntlzd_3_constant:
|
||||
li r5, -1
|
||||
cntlzd r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_cntlzd_4:
|
||||
#_ REGISTER_IN r5 0x7FFFFFFFFFFFFFFF
|
||||
cntlzd r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_cntlzd_4_constant:
|
||||
li r5, -1
|
||||
srdi r5, r5, 1
|
||||
cntlzd r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
73
src/xenia/cpu/ppc/testing/instr_cntlzw.s
Normal file
73
src/xenia/cpu/ppc/testing/instr_cntlzw.s
Normal file
@@ -0,0 +1,73 @@
|
||||
test_cntlzw_1:
|
||||
#_ REGISTER_IN r5 0
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 32
|
||||
|
||||
test_cntlzw_1_constant:
|
||||
li r5, 0
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 32
|
||||
|
||||
test_cntlzw_2:
|
||||
#_ REGISTER_IN r5 1
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 31
|
||||
|
||||
test_cntlzw_2_constant:
|
||||
li r5, 1
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 31
|
||||
|
||||
test_cntlzw_3:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFF
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_cntlzw_3_constant:
|
||||
li r5, -1
|
||||
srwi r5, r5, 0
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_cntlzw_4:
|
||||
#_ REGISTER_IN r5 0x7FFFFFFF
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x7FFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_cntlzw_4_constant:
|
||||
li r5, -1
|
||||
srwi r5, r5, 1
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x7FFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_cntlzw_5:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFF00000001
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF00000001
|
||||
#_ REGISTER_OUT r6 31
|
||||
|
||||
test_cntlzw_5_constant:
|
||||
li r5, -1
|
||||
sldi r5, r5, 32
|
||||
addi r5, r5, 1
|
||||
cntlzw r6, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF00000001
|
||||
#_ REGISTER_OUT r6 31
|
||||
166
src/xenia/cpu/ppc/testing/instr_divd.s
Normal file
166
src/xenia/cpu/ppc/testing/instr_divd.s
Normal file
@@ -0,0 +1,166 @@
|
||||
test_divd_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_divd_1_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
# TODO(benvanik): x64 ignore divide by zero (=0)
|
||||
#test_divd_2:
|
||||
# #_ REGISTER_IN r4 1
|
||||
# #_ REGISTER_IN r5 0
|
||||
# divd r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 1
|
||||
# #_ REGISTER_OUT r5 0
|
||||
|
||||
# TODO(benvanik): x64 ignore divide by zero (=0)
|
||||
#test_divd_2_constant:
|
||||
# li r4, 1
|
||||
# li r5, 0
|
||||
# divd r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 1
|
||||
# #_ REGISTER_OUT r5 0
|
||||
|
||||
test_divd_3:
|
||||
#_ REGISTER_IN r4 2
|
||||
#_ REGISTER_IN r5 1
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divd_3_constant:
|
||||
li r4, 2
|
||||
li r5, 1
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divd_4:
|
||||
#_ REGISTER_IN r4 35
|
||||
#_ REGISTER_IN r5 7
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 5
|
||||
#_ REGISTER_OUT r4 35
|
||||
#_ REGISTER_OUT r5 7
|
||||
|
||||
test_divd_4_constant:
|
||||
li r4, 35
|
||||
li r5, 7
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 5
|
||||
#_ REGISTER_OUT r4 35
|
||||
#_ REGISTER_OUT r5 7
|
||||
|
||||
test_divd_5:
|
||||
#_ REGISTER_IN r4 0
|
||||
#_ REGISTER_IN r5 1
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divd_5_constant:
|
||||
li r4, 0
|
||||
li r5, 1
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divd_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divd_6_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divd_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divd_7_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divd_8:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divd_8_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
divd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
# TODO(benvanik): integer overflow (=0)
|
||||
#test_divd_9:
|
||||
# #_ REGISTER_IN r4 0x8000000000000000
|
||||
# #_ REGISTER_IN r5 -1
|
||||
# divd r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 0x8000000000000000
|
||||
# #_ REGISTER_OUT r5 -1
|
||||
|
||||
# TODO(benvanik): integer overflow (=0)
|
||||
#test_divd_9_constant:
|
||||
# li r4, 1
|
||||
# sldi r4, r4, 63
|
||||
# li r5, -1
|
||||
# divd r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 0x8000000000000000
|
||||
# #_ REGISTER_OUT r5 -1
|
||||
165
src/xenia/cpu/ppc/testing/instr_divdu.s
Normal file
165
src/xenia/cpu/ppc/testing/instr_divdu.s
Normal file
@@ -0,0 +1,165 @@
|
||||
test_divdu_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_divdu_1_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
# TODO(benvanik): x64 ignore divide by zero (=0)
|
||||
#test_divdu_2:
|
||||
# #_ REGISTER_IN r4 1
|
||||
# #_ REGISTER_IN r5 0
|
||||
# divdu r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 1
|
||||
# #_ REGISTER_OUT r5 0
|
||||
|
||||
# TODO(benvanik): x64 ignore divide by zero (=0)
|
||||
#test_divdu_2_constant:
|
||||
# li r4, 1
|
||||
# li r5, 0
|
||||
# divdu r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 1
|
||||
# #_ REGISTER_OUT r5 0
|
||||
|
||||
test_divdu_3:
|
||||
#_ REGISTER_IN r4 2
|
||||
#_ REGISTER_IN r5 1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divdu_3_constant:
|
||||
li r4, 2
|
||||
li r5, 1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divdu_4:
|
||||
#_ REGISTER_IN r4 35
|
||||
#_ REGISTER_IN r5 7
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 5
|
||||
#_ REGISTER_OUT r4 35
|
||||
#_ REGISTER_OUT r5 7
|
||||
|
||||
test_divdu_4_constant:
|
||||
li r4, 35
|
||||
li r5, 7
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 5
|
||||
#_ REGISTER_OUT r4 35
|
||||
#_ REGISTER_OUT r5 7
|
||||
|
||||
test_divdu_5:
|
||||
#_ REGISTER_IN r4 0
|
||||
#_ REGISTER_IN r5 1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divdu_5_constant:
|
||||
li r4, 0
|
||||
li r5, 1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divdu_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divdu_6_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divdu_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divdu_7_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divdu_8:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divdu_8_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divdu_9:
|
||||
#_ REGISTER_IN r4 0x8000000000000000
|
||||
#_ REGISTER_IN r5 -1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x8000000000000000
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
# TODO(benvanik): integer overflow (=0)
|
||||
test_divdu_9_constant:
|
||||
li r4, 1
|
||||
sldi r4, r4, 63
|
||||
li r5, -1
|
||||
divdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x8000000000000000
|
||||
#_ REGISTER_OUT r5 -1
|
||||
223
src/xenia/cpu/ppc/testing/instr_divw.s
Normal file
223
src/xenia/cpu/ppc/testing/instr_divw.s
Normal file
@@ -0,0 +1,223 @@
|
||||
test_divw_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_divw_1_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
# TODO(benvanik): x64 ignore divide by zero (=0)
|
||||
#test_divw_2:
|
||||
# #_ REGISTER_IN r4 1
|
||||
# #_ REGISTER_IN r5 0
|
||||
# divw r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 1
|
||||
# #_ REGISTER_OUT r5 0
|
||||
|
||||
# TODO(benvanik): x64 ignore divide by zero (=0)
|
||||
#test_divw_2_constant:
|
||||
# li r4, 1
|
||||
# li r5, 0
|
||||
# divw r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 1
|
||||
# #_ REGISTER_OUT r5 0
|
||||
|
||||
test_divw_3:
|
||||
#_ REGISTER_IN r4 2
|
||||
#_ REGISTER_IN r5 1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divw_3_constant:
|
||||
li r4, 2
|
||||
li r5, 1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divw_4:
|
||||
#_ REGISTER_IN r4 35
|
||||
#_ REGISTER_IN r5 7
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 5
|
||||
#_ REGISTER_OUT r4 35
|
||||
#_ REGISTER_OUT r5 7
|
||||
|
||||
test_divw_4_constant:
|
||||
li r4, 35
|
||||
li r5, 7
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 5
|
||||
#_ REGISTER_OUT r4 35
|
||||
#_ REGISTER_OUT r5 7
|
||||
|
||||
test_divw_5:
|
||||
#_ REGISTER_IN r4 0
|
||||
#_ REGISTER_IN r5 1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divw_5_constant:
|
||||
li r4, 0
|
||||
li r5, 1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divw_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divw_6_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divw_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divw_7_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divw_8:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divw_8_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divw_9:
|
||||
#_ REGISTER_IN r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divw_9_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 33
|
||||
li r5, 1
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divw_10:
|
||||
#_ REGISTER_IN r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_IN r5 0x000000007FFFFFFF
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
test_divw_10_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 33
|
||||
mr r5, r4
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
test_divw_11:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0x000000007FFFFFFF
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
test_divw_11_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
clrldi r5, r5, 33
|
||||
divw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
# TODO(benvanik): integer overflow (=0)
|
||||
#test_divw_12:
|
||||
# #_ REGISTER_IN r4 0x80000000
|
||||
# #_ REGISTER_IN r5 -1
|
||||
# divw r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 0x80000000
|
||||
# #_ REGISTER_OUT r5 -1
|
||||
|
||||
# TODO(benvanik): integer overflow (=0)
|
||||
#test_divw_12_constant:
|
||||
# li r4, 1
|
||||
# srdi r4, 31
|
||||
# li r5, -1
|
||||
# divw r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 0x80000000
|
||||
# #_ REGISTER_OUT r5 -1
|
||||
221
src/xenia/cpu/ppc/testing/instr_divwu.s
Normal file
221
src/xenia/cpu/ppc/testing/instr_divwu.s
Normal file
@@ -0,0 +1,221 @@
|
||||
test_divwu_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 2
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_divwu_1_constant:
|
||||
li r4, 1
|
||||
li r5, 2
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
# TODO(benvanik): x64 ignore divide by zero (=0)
|
||||
#test_divwu_2:
|
||||
# #_ REGISTER_IN r4 1
|
||||
# #_ REGISTER_IN r5 0
|
||||
# divwu r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 1
|
||||
# #_ REGISTER_OUT r5 0
|
||||
|
||||
# TODO(benvanik): x64 ignore divide by zero (=0)
|
||||
#test_divwu_2_constant:
|
||||
# li r4, 1
|
||||
# li r5, 0
|
||||
# divwu r3, r4, r5
|
||||
# blr
|
||||
# #_ REGISTER_OUT r3 0
|
||||
# #_ REGISTER_OUT r4 1
|
||||
# #_ REGISTER_OUT r5 0
|
||||
|
||||
test_divwu_3:
|
||||
#_ REGISTER_IN r4 2
|
||||
#_ REGISTER_IN r5 1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divwu_3_constant:
|
||||
li r4, 2
|
||||
li r5, 1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 2
|
||||
#_ REGISTER_OUT r4 2
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divwu_4:
|
||||
#_ REGISTER_IN r4 35
|
||||
#_ REGISTER_IN r5 7
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 5
|
||||
#_ REGISTER_OUT r4 35
|
||||
#_ REGISTER_OUT r5 7
|
||||
|
||||
test_divwu_4_constant:
|
||||
li r4, 35
|
||||
li r5, 7
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 5
|
||||
#_ REGISTER_OUT r4 35
|
||||
#_ REGISTER_OUT r5 7
|
||||
|
||||
test_divwu_5:
|
||||
#_ REGISTER_IN r4 0
|
||||
#_ REGISTER_IN r5 1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divwu_5_constant:
|
||||
li r4, 0
|
||||
li r5, 1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divwu_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divwu_6_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divwu_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divwu_7_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divwu_8:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divwu_8_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_divwu_9:
|
||||
#_ REGISTER_IN r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divwu_9_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 33
|
||||
li r5, 1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_divwu_10:
|
||||
#_ REGISTER_IN r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_IN r5 0x000000007FFFFFFF
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
test_divwu_10_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 33
|
||||
mr r5, r4
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
test_divwu_11:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0x000000007FFFFFFF
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
test_divwu_11_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
clrldi r5, r5, 33
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
test_divwu_12:
|
||||
#_ REGISTER_IN r4 0x80000000
|
||||
#_ REGISTER_IN r5 -1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x80000000
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_divwu_12_constant:
|
||||
li r4, 1
|
||||
sldi r4, r4, 31
|
||||
li r5, -1
|
||||
divwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x80000000
|
||||
#_ REGISTER_OUT r5 -1
|
||||
119
src/xenia/cpu/ppc/testing/instr_eqv.s
Normal file
119
src/xenia/cpu/ppc/testing/instr_eqv.s
Normal file
@@ -0,0 +1,119 @@
|
||||
test_eqv_1:
|
||||
#_ REGISTER_IN r4 0
|
||||
#_ REGISTER_IN r5 1
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_eqv_1_constant:
|
||||
li r4, 0
|
||||
li r5, 1
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 0
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_eqv_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_eqv_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_eqv_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_eqv_3_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_eqv_4:
|
||||
#_ REGISTER_IN r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_IN r5 0xDEADBEEFDEADBEEF
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_OUT r5 0xDEADBEEFDEADBEEF
|
||||
|
||||
test_eqv_4_constant:
|
||||
lis r4, 0xDEAD
|
||||
ori r4, r4, 0xBEEF
|
||||
sldi r5, r4, 32
|
||||
clrldi r4, r4, 32
|
||||
or r4, r5, r4
|
||||
mr r5, r4
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_OUT r5 0xDEADBEEFDEADBEEF
|
||||
|
||||
test_eqv_5:
|
||||
#_ REGISTER_IN r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_eqv_5_constant:
|
||||
lis r4, 0xDEAD
|
||||
ori r4, r4, 0xBEEF
|
||||
sldi r5, r4, 32
|
||||
clrldi r4, r4, 32
|
||||
or r4, r5, r4
|
||||
li r5, -1
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_eqv_6:
|
||||
#_ REGISTER_IN r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_IN r5 0
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x2152411021524110
|
||||
#_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_eqv_6_constant:
|
||||
lis r4, 0xDEAD
|
||||
ori r4, r4, 0xBEEF
|
||||
sldi r5, r4, 32
|
||||
clrldi r4, r4, 32
|
||||
or r4, r5, r4
|
||||
li r5, 0
|
||||
eqv r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x2152411021524110
|
||||
#_ REGISTER_OUT r4 0xDEADBEEFDEADBEEF
|
||||
#_ REGISTER_OUT r5 0
|
||||
129
src/xenia/cpu/ppc/testing/instr_extsb.s
Normal file
129
src/xenia/cpu/ppc/testing/instr_extsb.s
Normal file
@@ -0,0 +1,129 @@
|
||||
test_extsb_1:
|
||||
#_ REGISTER_IN r4 0x0F
|
||||
extsb r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
|
||||
test_extsb_1_constant:
|
||||
li r4, 0x0F
|
||||
extsb r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
|
||||
test_extsb_2:
|
||||
#_ REGISTER_IN r4 0x7F
|
||||
extsb r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7F
|
||||
#_ REGISTER_OUT r4 0x7F
|
||||
|
||||
test_extsb_2_constant:
|
||||
li r4, 0x7F
|
||||
extsb r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7F
|
||||
#_ REGISTER_OUT r4 0x7F
|
||||
|
||||
test_extsb_3:
|
||||
#_ REGISTER_IN r4 0x80
|
||||
extsb r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80
|
||||
#_ REGISTER_OUT r4 0x80
|
||||
|
||||
test_extsb_3_constant:
|
||||
li r4, 0x80
|
||||
extsb r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80
|
||||
#_ REGISTER_OUT r4 0x80
|
||||
|
||||
test_extsb_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFF080
|
||||
extsb r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFF080
|
||||
|
||||
test_extsb_4_constant:
|
||||
li r4, 0xF7F
|
||||
not r4, r4
|
||||
extsb r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFF080
|
||||
|
||||
test_extsb_cr_1:
|
||||
#_ REGISTER_IN r4 0x0F
|
||||
extsb. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsb_cr_1_constant:
|
||||
li r4, 0x0F
|
||||
extsb. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsb_cr_2:
|
||||
#_ REGISTER_IN r4 0x7F
|
||||
extsb. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7F
|
||||
#_ REGISTER_OUT r4 0x7F
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsb_cr_2_constant:
|
||||
li r4, 0x7F
|
||||
extsb. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7F
|
||||
#_ REGISTER_OUT r4 0x7F
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsb_cr_3:
|
||||
#_ REGISTER_IN r4 0x80
|
||||
extsb. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80
|
||||
#_ REGISTER_OUT r4 0x80
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsb_cr_3_constant:
|
||||
li r4, 0x80
|
||||
extsb. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80
|
||||
#_ REGISTER_OUT r4 0x80
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsb_cr_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFF080
|
||||
extsb. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFF080
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsb_cr_4_constant:
|
||||
li r4, 0xF7F
|
||||
not r4, r4
|
||||
extsb. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFF80
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFF080
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
133
src/xenia/cpu/ppc/testing/instr_extsh.s
Normal file
133
src/xenia/cpu/ppc/testing/instr_extsh.s
Normal file
@@ -0,0 +1,133 @@
|
||||
test_extsh_1:
|
||||
#_ REGISTER_IN r4 0x0F
|
||||
extsh r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
|
||||
test_extsh_1_constant:
|
||||
li r4, 0x0F
|
||||
extsh r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
|
||||
test_extsh_2:
|
||||
#_ REGISTER_IN r4 0x7FFF
|
||||
extsh r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFF
|
||||
#_ REGISTER_OUT r4 0x7FFF
|
||||
|
||||
test_extsh_2_constant:
|
||||
li r4, 0x7FFF
|
||||
extsh r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFF
|
||||
#_ REGISTER_OUT r4 0x7FFF
|
||||
|
||||
test_extsh_3:
|
||||
#_ REGISTER_IN r4 0x8000
|
||||
extsh r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000
|
||||
#_ REGISTER_OUT r4 0x8000
|
||||
|
||||
test_extsh_3_constant:
|
||||
li r4, 0x80
|
||||
sldi r4, r4, 8
|
||||
extsh r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000
|
||||
#_ REGISTER_OUT r4 0x8000
|
||||
|
||||
test_extsh_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFF08000
|
||||
extsh r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFF08000
|
||||
|
||||
test_extsh_4_constant:
|
||||
li r4, 0xF7F
|
||||
not r4, r4
|
||||
sldi r4, r4, 8
|
||||
extsh r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFF08000
|
||||
|
||||
test_extsh_cr_1:
|
||||
#_ REGISTER_IN r4 0x0F
|
||||
extsh. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsh_cr_1_constant:
|
||||
li r4, 0x0F
|
||||
extsh. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsh_cr_2:
|
||||
#_ REGISTER_IN r4 0x7FFF
|
||||
extsh. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFF
|
||||
#_ REGISTER_OUT r4 0x7FFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsh_cr_2_constant:
|
||||
li r4, 0x7FFF
|
||||
extsh. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFF
|
||||
#_ REGISTER_OUT r4 0x7FFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsh_cr_3:
|
||||
#_ REGISTER_IN r4 0x8000
|
||||
extsh. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000
|
||||
#_ REGISTER_OUT r4 0x8000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsh_cr_3_constant:
|
||||
li r4, 0x80
|
||||
sldi r4, r4, 8
|
||||
extsh. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000
|
||||
#_ REGISTER_OUT r4 0x8000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsh_cr_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFF08000
|
||||
extsh. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFF08000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsh_cr_4_constant:
|
||||
li r4, 0xF7F
|
||||
not r4, r4
|
||||
sldi r4, r4, 8
|
||||
extsh. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFF8000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFF08000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
135
src/xenia/cpu/ppc/testing/instr_extsw.s
Normal file
135
src/xenia/cpu/ppc/testing/instr_extsw.s
Normal file
@@ -0,0 +1,135 @@
|
||||
test_extsw_1:
|
||||
#_ REGISTER_IN r4 0x0F
|
||||
extsw r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
|
||||
test_extsw_1_constant:
|
||||
li r4, 0x0F
|
||||
extsw r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
|
||||
test_extsw_2:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFF
|
||||
extsw r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFF
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFF
|
||||
|
||||
test_extsw_2_constant:
|
||||
lis r4, 0x7FFF
|
||||
ori r4, r4, 0xFFFF
|
||||
extsw r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFF
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFF
|
||||
|
||||
test_extsw_3:
|
||||
#_ REGISTER_IN r4 0x80000000
|
||||
extsw r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0x80000000
|
||||
|
||||
test_extsw_3_constant:
|
||||
li r4, 0x80
|
||||
sldi r4, r4, 24
|
||||
extsw r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0x80000000
|
||||
|
||||
test_extsw_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFF080000000
|
||||
extsw r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFF080000000
|
||||
|
||||
test_extsw_4_constant:
|
||||
li r4, 0xF7F
|
||||
not r4, r4
|
||||
sldi r4, r4, 24
|
||||
extsw r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFF080000000
|
||||
|
||||
test_extsw_cr_1:
|
||||
#_ REGISTER_IN r4 0x0F
|
||||
extsw. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsw_cr_1_constant:
|
||||
li r4, 0x0F
|
||||
extsw. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0F
|
||||
#_ REGISTER_OUT r4 0x0F
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsw_cr_2:
|
||||
#_ REGISTER_IN r4 0x7FFFFFFF
|
||||
extsw. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFF
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsw_cr_2_constant:
|
||||
lis r4, 0x7FFF
|
||||
ori r4, r4, 0xFFFF
|
||||
extsw. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFF
|
||||
#_ REGISTER_OUT r4 0x7FFFFFFF
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extsw_cr_3:
|
||||
#_ REGISTER_IN r4 0x80000000
|
||||
extsw. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0x80000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsw_cr_3_constant:
|
||||
li r4, 0x80
|
||||
sldi r4, r4, 24
|
||||
extsw. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0x80000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsw_cr_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFF080000000
|
||||
extsw. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFF080000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
|
||||
test_extsw_cr_4_constant:
|
||||
li r4, 0xF7F
|
||||
not r4, r4
|
||||
sldi r4, r4, 24
|
||||
extsw. r3, r4
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFF080000000
|
||||
#_ REGISTER_OUT r12 0x80000000
|
||||
41
src/xenia/cpu/ppc/testing/instr_fabs.s
Normal file
41
src/xenia/cpu/ppc/testing/instr_fabs.s
Normal file
@@ -0,0 +1,41 @@
|
||||
test_fabs_1:
|
||||
#_ REGISTER_IN f1 1.0
|
||||
fabs f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 1.0
|
||||
|
||||
test_fabs_2:
|
||||
#_ REGISTER_IN f1 -1.0
|
||||
fabs f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 1.0
|
||||
|
||||
test_fabs_3:
|
||||
#_ REGISTER_IN f1 -1234.0
|
||||
fabs f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 1234.0
|
||||
|
||||
#test_fabs_cr_1:
|
||||
# #_ REGISTER_IN f1 1.0
|
||||
# fabs. f1, f1
|
||||
# mfcr r12
|
||||
# blr
|
||||
# #_ REGISTER_OUT f1 1.0
|
||||
# #_ REGISTER_OUT r12 0x04000000
|
||||
|
||||
#test_fabs_cr_2:
|
||||
# #_ REGISTER_IN f1 -1.0
|
||||
# fabs. f1, f1
|
||||
# mfcr r12
|
||||
# blr
|
||||
# #_ REGISTER_OUT f1 1.0
|
||||
# #_ REGISTER_OUT r12 0x08000000
|
||||
|
||||
#test_fabs_cr_3:
|
||||
# #_ REGISTER_IN f1 -1234.0
|
||||
# fabs. f1, f1
|
||||
# mfcr r12
|
||||
# blr
|
||||
# #_ REGISTER_OUT f1 1234.0
|
||||
# #_ REGISTER_OUT r12 0x08000000
|
||||
20
src/xenia/cpu/ppc/testing/instr_fadd.s
Normal file
20
src/xenia/cpu/ppc/testing/instr_fadd.s
Normal file
@@ -0,0 +1,20 @@
|
||||
test_fadd_1:
|
||||
#_ REGISTER_IN f1 1.0
|
||||
#_ REGISTER_IN f2 2.0
|
||||
fadd f3, f1, f2
|
||||
blr
|
||||
#_ REGISTER_OUT f3 3.0
|
||||
|
||||
test_fadd_2:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 0.0
|
||||
fadd f3, f1, f2
|
||||
blr
|
||||
#_ REGISTER_OUT f3 0.0
|
||||
|
||||
test_fadd_3:
|
||||
#_ REGISTER_IN f1 -200.0
|
||||
#_ REGISTER_IN f2 200.0
|
||||
fadd f3, f1, f2
|
||||
blr
|
||||
#_ REGISTER_OUT f3 0.0
|
||||
47
src/xenia/cpu/ppc/testing/instr_fmadd.s
Normal file
47
src/xenia/cpu/ppc/testing/instr_fmadd.s
Normal file
@@ -0,0 +1,47 @@
|
||||
test_fmadd_1:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 5.0
|
||||
#_ REGISTER_IN f3 5.0
|
||||
#_ REGISTER_IN f4 0.0
|
||||
fmadd f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 25.0
|
||||
#_ REGISTER_OUT f2 5.0
|
||||
#_ REGISTER_OUT f3 5.0
|
||||
#_ REGISTER_OUT f4 0.0
|
||||
|
||||
test_fmadd_2:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 5.0
|
||||
#_ REGISTER_IN f3 0.0
|
||||
#_ REGISTER_IN f4 15.0
|
||||
fmadd f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 15.0
|
||||
#_ REGISTER_OUT f2 5.0
|
||||
#_ REGISTER_OUT f3 0.0
|
||||
#_ REGISTER_OUT f4 15.0
|
||||
|
||||
test_fmadd_3:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 5.0
|
||||
#_ REGISTER_IN f3 5.0
|
||||
#_ REGISTER_IN f4 15.0
|
||||
fmadd f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 40.0
|
||||
#_ REGISTER_OUT f2 5.0
|
||||
#_ REGISTER_OUT f3 5.0
|
||||
#_ REGISTER_OUT f4 15.0
|
||||
|
||||
test_fmadd_4:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 9999.99
|
||||
#_ REGISTER_IN f3 9999.99
|
||||
#_ REGISTER_IN f4 9999.99
|
||||
fmadd f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 100009799.9901
|
||||
#_ REGISTER_OUT f2 9999.99
|
||||
#_ REGISTER_OUT f3 9999.99
|
||||
#_ REGISTER_OUT f4 9999.99
|
||||
47
src/xenia/cpu/ppc/testing/instr_fmadds.s
Normal file
47
src/xenia/cpu/ppc/testing/instr_fmadds.s
Normal file
@@ -0,0 +1,47 @@
|
||||
test_fmadds_1:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 5.0
|
||||
#_ REGISTER_IN f3 5.0
|
||||
#_ REGISTER_IN f4 0.0
|
||||
fmadds f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 25.0
|
||||
#_ REGISTER_OUT f2 5.0
|
||||
#_ REGISTER_OUT f3 5.0
|
||||
#_ REGISTER_OUT f4 0.0
|
||||
|
||||
test_fmadds_2:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 5.0
|
||||
#_ REGISTER_IN f3 0.0
|
||||
#_ REGISTER_IN f4 15.0
|
||||
fmadds f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 15.0
|
||||
#_ REGISTER_OUT f2 5.0
|
||||
#_ REGISTER_OUT f3 0.0
|
||||
#_ REGISTER_OUT f4 15.0
|
||||
|
||||
test_fmadds_3:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 5.0
|
||||
#_ REGISTER_IN f3 5.0
|
||||
#_ REGISTER_IN f4 15.0
|
||||
fmadds f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 40.0
|
||||
#_ REGISTER_OUT f2 5.0
|
||||
#_ REGISTER_OUT f3 5.0
|
||||
#_ REGISTER_OUT f4 15.0
|
||||
|
||||
test_fmadds_4:
|
||||
#_ REGISTER_IN f1 0.0
|
||||
#_ REGISTER_IN f2 9999.99
|
||||
#_ REGISTER_IN f3 9999.99
|
||||
#_ REGISTER_IN f4 9999.99
|
||||
fmadds f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 100009800.0
|
||||
#_ REGISTER_OUT f2 9999.99
|
||||
#_ REGISTER_OUT f3 9999.99
|
||||
#_ REGISTER_OUT f4 9999.99
|
||||
20
src/xenia/cpu/ppc/testing/instr_fmul.s
Normal file
20
src/xenia/cpu/ppc/testing/instr_fmul.s
Normal file
@@ -0,0 +1,20 @@
|
||||
test_fmul_1:
|
||||
#_ REGISTER_IN f1 5.0
|
||||
#_ REGISTER_IN f2 5.0
|
||||
fmul f3, f1, f2
|
||||
blr
|
||||
#_ REGISTER_OUT f3 25.0
|
||||
|
||||
test_fmul_2:
|
||||
#_ REGISTER_IN f1 5.0
|
||||
#_ REGISTER_IN f2 0.0
|
||||
fmul f3, f1, f2
|
||||
blr
|
||||
#_ REGISTER_OUT f3 0.0
|
||||
|
||||
test_fmul_3:
|
||||
#_ REGISTER_IN f1 -2.0
|
||||
#_ REGISTER_IN f2 2.0
|
||||
fmul f3, f1, f2
|
||||
blr
|
||||
#_ REGISTER_OUT f3 -4.0
|
||||
5
src/xenia/cpu/ppc/testing/instr_fnabs.s
Normal file
5
src/xenia/cpu/ppc/testing/instr_fnabs.s
Normal file
@@ -0,0 +1,5 @@
|
||||
test_fnabs_1:
|
||||
#_ REGISTER_IN f1 0x400C000000000000
|
||||
fnabs f2, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f2 0xC00C000000000000
|
||||
19
src/xenia/cpu/ppc/testing/instr_frsqrte.s
Normal file
19
src/xenia/cpu/ppc/testing/instr_frsqrte.s
Normal file
@@ -0,0 +1,19 @@
|
||||
test_frsqrte_1:
|
||||
#_ REGISTER_IN f1 1.0
|
||||
frsqrte f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 0.99975585937500000
|
||||
# want: 0.97
|
||||
|
||||
test_frsqrte_2:
|
||||
#_ REGISTER_IN f1 64.0
|
||||
frsqrte f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 0.12496948242187500
|
||||
|
||||
test_frsqrte_3:
|
||||
#_ REGISTER_IN f1 0.5
|
||||
frsqrte f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 1.4138183593750000
|
||||
# want: 1.375
|
||||
32
src/xenia/cpu/ppc/testing/instr_fsel.s
Normal file
32
src/xenia/cpu/ppc/testing/instr_fsel.s
Normal file
@@ -0,0 +1,32 @@
|
||||
test_fsel_1:
|
||||
#_ REGISTER_IN f2 2.0
|
||||
#_ REGISTER_IN f3 3.0
|
||||
#_ REGISTER_IN f4 4.0
|
||||
fsel f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 3.0
|
||||
#_ REGISTER_OUT f2 2.0
|
||||
#_ REGISTER_OUT f3 3.0
|
||||
#_ REGISTER_OUT f4 4.0
|
||||
|
||||
test_fsel_2:
|
||||
#_ REGISTER_IN f2 -2.0
|
||||
#_ REGISTER_IN f3 3.0
|
||||
#_ REGISTER_IN f4 4.0
|
||||
fsel f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 4.0
|
||||
#_ REGISTER_OUT f2 -2.0
|
||||
#_ REGISTER_OUT f3 3.0
|
||||
#_ REGISTER_OUT f4 4.0
|
||||
|
||||
test_fsel_3:
|
||||
#_ REGISTER_IN f2 0.0
|
||||
#_ REGISTER_IN f3 3.0
|
||||
#_ REGISTER_IN f4 4.0
|
||||
fsel f1, f2, f3, f4
|
||||
blr
|
||||
#_ REGISTER_OUT f1 3.0
|
||||
#_ REGISTER_OUT f2 0.0
|
||||
#_ REGISTER_OUT f3 3.0
|
||||
#_ REGISTER_OUT f4 4.0
|
||||
17
src/xenia/cpu/ppc/testing/instr_fsqrt.s
Normal file
17
src/xenia/cpu/ppc/testing/instr_fsqrt.s
Normal file
@@ -0,0 +1,17 @@
|
||||
test_fsqrt_1:
|
||||
#_ REGISTER_IN f1 1.0
|
||||
fsqrt f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 1.0000000000000000
|
||||
|
||||
test_fsqrt_2:
|
||||
#_ REGISTER_IN f1 64.0
|
||||
fsqrt f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 8.0000000000000000
|
||||
|
||||
test_fsqrt_3:
|
||||
#_ REGISTER_IN f1 0.5
|
||||
fsqrt f1, f1
|
||||
blr
|
||||
#_ REGISTER_OUT f1 0.70710678118654757
|
||||
101
src/xenia/cpu/ppc/testing/instr_lvexx.s
Normal file
101
src/xenia/cpu/ppc/testing/instr_lvexx.s
Normal file
@@ -0,0 +1,101 @@
|
||||
test_lvebx_1:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
#_ REGISTER_IN r4 0x10001000
|
||||
lvebx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001000
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvebx_1_constant:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1000
|
||||
lvebx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001000
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvebx_2:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
#_ REGISTER_IN r4 0x10001004
|
||||
lvebx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001004
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvebx_2_constant:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1004
|
||||
lvebx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001004
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvehx_1:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
#_ REGISTER_IN r4 0x10001000
|
||||
lvehx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001000
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvehx_1_constant:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1000
|
||||
lvehx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001000
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvehx_2:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
#_ REGISTER_IN r4 0x10001004
|
||||
lvehx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001004
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvehx_2_constant:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1004
|
||||
lvehx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001004
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvewx_1:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
#_ REGISTER_IN r4 0x10001000
|
||||
lvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001000
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvewx_1_constant:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1000
|
||||
lvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001000
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvewx_2:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
#_ REGISTER_IN r4 0x10001004
|
||||
lvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001004
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvewx_2_constant:
|
||||
#_ MEMORY_IN 10001000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1004
|
||||
lvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001004
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
16
src/xenia/cpu/ppc/testing/instr_lvl.s
Normal file
16
src/xenia/cpu/ppc/testing/instr_lvl.s
Normal file
@@ -0,0 +1,16 @@
|
||||
test_lvl_1:
|
||||
#_ MEMORY_IN 10001077 0a 0b 0c 0d 0e 0f 10 13 0c 0d 0e 10 11 12 13 14 ff ff ff ff ff ff
|
||||
#_ REGISTER_IN r4 0x10001077
|
||||
lvlx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001077
|
||||
#_ REGISTER_OUT v3 [0A0B0C0D, 0E0F1013, 0C000000, 00000000]
|
||||
|
||||
test_lvl_1_constant:
|
||||
#_ MEMORY_IN 10001077 0a 0b 0c 0d 0e 0f 10 13 0c 0d 0e 10 11 12 13 14 ff ff ff ff ff ff
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1077
|
||||
lvlx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001077
|
||||
#_ REGISTER_OUT v3 [0A0B0C0D, 0E0F1013, 0C000000, 00000000]
|
||||
40
src/xenia/cpu/ppc/testing/instr_lvr.s
Normal file
40
src/xenia/cpu/ppc/testing/instr_lvr.s
Normal file
@@ -0,0 +1,40 @@
|
||||
test_lvr_1:
|
||||
#_ MEMORY_IN 100010B0 090A0A0B 0C0F120A 0B0C0D0E 0F10130C 0D0E1011 121314FF FFFFFFFF
|
||||
#_ REGISTER_IN r4 0x100010B7
|
||||
#_ REGISTER_IN r5 0x10
|
||||
lvrx v3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x100010B7
|
||||
#_ REGISTER_OUT r5 0x10
|
||||
#_ REGISTER_OUT v3 [00000000, 00000000, 000D0E10, 11121314]
|
||||
|
||||
test_lvr_1_constant:
|
||||
#_ MEMORY_IN 100010B0 090A0A0B 0C0F120A 0B0C0D0E 0F10130C 0D0E1011 121314FF FFFFFFFF
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x10B7
|
||||
li r5, 0x10
|
||||
lvrx v3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x100010B7
|
||||
#_ REGISTER_OUT r5 0x10
|
||||
#_ REGISTER_OUT v3 [00000000, 00000000, 000D0E10, 11121314]
|
||||
|
||||
test_lvr_2:
|
||||
#_ REGISTER_IN r4 0x20000000
|
||||
#_ REGISTER_IN r5 0x10
|
||||
#_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF]
|
||||
lvrx v3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x20000000
|
||||
#_ REGISTER_OUT r5 0x10
|
||||
#_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000]
|
||||
|
||||
test_lvr_2_constant:
|
||||
#_ REGISTER_IN v3 [FFFFFFFF, FFFFFFFF, FFFFFFFF, FFFFFFFF]
|
||||
lis r4, 0x2000
|
||||
li r5, 0x10
|
||||
lvrx v3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x20000000
|
||||
#_ REGISTER_OUT r5 0x10
|
||||
#_ REGISTER_OUT v3 [00000000, 00000000, 00000000, 00000000]
|
||||
41
src/xenia/cpu/ppc/testing/instr_lvsl.s
Normal file
41
src/xenia/cpu/ppc/testing/instr_lvsl.s
Normal file
@@ -0,0 +1,41 @@
|
||||
test_lvsl_1:
|
||||
#_ REGISTER_IN r4 0x1070
|
||||
lvsl v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1070
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvsl_1_constant:
|
||||
li r4, 0x1070
|
||||
lvsl v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1070
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
|
||||
test_lvsl_2:
|
||||
#_ REGISTER_IN r4 0x1071
|
||||
lvsl v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1071
|
||||
#_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10]
|
||||
|
||||
test_lvsl_2_constant:
|
||||
li r4, 0x1071
|
||||
lvsl v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1071
|
||||
#_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10]
|
||||
|
||||
test_lvsl_3:
|
||||
#_ REGISTER_IN r4 0x107F
|
||||
lvsl v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x107F
|
||||
#_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E]
|
||||
|
||||
test_lvsl_3_constant:
|
||||
li r4, 0x107F
|
||||
lvsl v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x107F
|
||||
#_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E]
|
||||
41
src/xenia/cpu/ppc/testing/instr_lvsr.s
Normal file
41
src/xenia/cpu/ppc/testing/instr_lvsr.s
Normal file
@@ -0,0 +1,41 @@
|
||||
test_lvsr_1:
|
||||
#_ REGISTER_IN r4 0x1070
|
||||
lvsr v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1070
|
||||
#_ REGISTER_OUT v3 [10111213, 14151617, 18191A1B, 1C1D1E1F]
|
||||
|
||||
test_lvsr_1_constant:
|
||||
li r4, 0x1070
|
||||
lvsr v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1070
|
||||
#_ REGISTER_OUT v3 [10111213, 14151617, 18191A1B, 1C1D1E1F]
|
||||
|
||||
test_lvsr_2:
|
||||
#_ REGISTER_IN r4 0x1071
|
||||
lvsr v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1071
|
||||
#_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E]
|
||||
|
||||
test_lvsr_2_constant:
|
||||
li r4, 0x1071
|
||||
lvsr v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1071
|
||||
#_ REGISTER_OUT v3 [0F101112, 13141516, 1718191A, 1B1C1D1E]
|
||||
|
||||
test_lvsr_3:
|
||||
#_ REGISTER_IN r4 0x107F
|
||||
lvsr v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x107F
|
||||
#_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10]
|
||||
|
||||
test_lvsr_3_constant:
|
||||
li r4, 0x107F
|
||||
lvsr v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x107F
|
||||
#_ REGISTER_OUT v3 [01020304, 05060708, 090A0B0C, 0D0E0F10]
|
||||
89
src/xenia/cpu/ppc/testing/instr_mulhd.s
Normal file
89
src/xenia/cpu/ppc/testing/instr_mulhd.s
Normal file
@@ -0,0 +1,89 @@
|
||||
test_mulhd_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulhd_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulhd_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhd_2_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhd_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 2
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_mulhd_3_constant:
|
||||
li r4, -1
|
||||
li r5, 2
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_mulhd_4:
|
||||
#_ REGISTER_IN r4 0x8000000000000000
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x8000000000000000
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhd_4_constant:
|
||||
li r5, 1
|
||||
sldi r4, r5, 63
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x8000000000000000
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhd_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulhd_5_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
mulhd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
89
src/xenia/cpu/ppc/testing/instr_mulhdu.s
Normal file
89
src/xenia/cpu/ppc/testing/instr_mulhdu.s
Normal file
@@ -0,0 +1,89 @@
|
||||
test_mulhdu_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulhdu_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulhdu_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhdu_2_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhdu_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 2
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_mulhdu_3_constant:
|
||||
li r4, -1
|
||||
li r5, 2
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_mulhdu_4:
|
||||
#_ REGISTER_IN r4 0x8000000000000000
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x8000000000000000
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhdu_4_constant:
|
||||
li r5, 1
|
||||
sldi r4, r5, 63
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x8000000000000000
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhdu_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulhdu_5_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
mulhdu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
113
src/xenia/cpu/ppc/testing/instr_mulhw.s
Normal file
113
src/xenia/cpu/ppc/testing/instr_mulhw.s
Normal file
@@ -0,0 +1,113 @@
|
||||
test_mulhw_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulhw_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulhw_2:
|
||||
#_ REGISTER_IN r4 0x00000000FFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhw_2_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 32
|
||||
li r5, 1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhw_3:
|
||||
#_ REGISTER_IN r4 0x00000001FFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x00000001FFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhw_3_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 31
|
||||
li r5, 1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x00000001FFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhw_4:
|
||||
#_ REGISTER_IN r4 0x800000007FFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x800000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhw_4_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 33
|
||||
li r5, 1
|
||||
sldi r5, r5, 63
|
||||
or r4, r4, r5
|
||||
li r5, 1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x800000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhw_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhw_5_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhw_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulhw_6_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
mulhw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
113
src/xenia/cpu/ppc/testing/instr_mulhwu.s
Normal file
113
src/xenia/cpu/ppc/testing/instr_mulhwu.s
Normal file
@@ -0,0 +1,113 @@
|
||||
test_mulhwu_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulhwu_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulhwu_2:
|
||||
#_ REGISTER_IN r4 0x00000000FFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhwu_2_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 32
|
||||
li r5, 1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhwu_3:
|
||||
#_ REGISTER_IN r4 0x00000001FFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x00000001FFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhwu_3_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 31
|
||||
li r5, 1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x00000001FFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhwu_4:
|
||||
#_ REGISTER_IN r4 0x800000007FFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x800000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhwu_4_constant:
|
||||
li r4, -1
|
||||
clrldi r4, r4, 33
|
||||
li r5, 1
|
||||
sldi r5, r5, 63
|
||||
or r4, r4, r5
|
||||
li r5, 1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0x800000007FFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhwu_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhwu_5_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulhwu_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0xFFFFFFFFFFFFFFFF
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulhwu_6_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
mulhwu r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFFFFFFFFFF
|
||||
143
src/xenia/cpu/ppc/testing/instr_mulld.s
Normal file
143
src/xenia/cpu/ppc/testing/instr_mulld.s
Normal file
@@ -0,0 +1,143 @@
|
||||
test_mulld_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulld_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mulld_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulld_2_constant:
|
||||
li r4, 1
|
||||
li r5, 1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulld_3:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 -1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mulld_3_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mulld_4:
|
||||
#_ REGISTER_IN r4 123
|
||||
#_ REGISTER_IN r5 -1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -123
|
||||
#_ REGISTER_OUT r4 123
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mulld_4_constant:
|
||||
li r4, 123
|
||||
li r5, -1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -123
|
||||
#_ REGISTER_OUT r4 123
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mulld_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulld_5_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mulld_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 2
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_mulld_6_constant:
|
||||
li r4, -1
|
||||
li r5, 2
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_mulld_7:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 -1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mulld_7_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mulld_8:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 -1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mulld_8_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
mulld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 -1
|
||||
111
src/xenia/cpu/ppc/testing/instr_mulli.s
Normal file
111
src/xenia/cpu/ppc/testing/instr_mulli.s
Normal file
@@ -0,0 +1,111 @@
|
||||
test_mulli_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
mulli r3, r4, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_mulli_1_constant:
|
||||
li r4, 1
|
||||
mulli r3, r4, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_mulli_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
mulli r3, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_mulli_2_constant:
|
||||
li r4, 1
|
||||
mulli r3, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_mulli_3:
|
||||
#_ REGISTER_IN r4 1
|
||||
mulli r3, r4, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_mulli_3_constant:
|
||||
li r4, 1
|
||||
mulli r3, r4, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_mulli_4:
|
||||
#_ REGISTER_IN r4 123
|
||||
mulli r3, r4, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -123
|
||||
#_ REGISTER_OUT r4 123
|
||||
|
||||
test_mulli_4_constant:
|
||||
li r4, 123
|
||||
mulli r3, r4, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -123
|
||||
#_ REGISTER_OUT r4 123
|
||||
|
||||
test_mulli_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
mulli r3, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulli_5_constant:
|
||||
li r4, -1
|
||||
mulli r3, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulli_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
mulli r3, r4, 2
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulli_6_constant:
|
||||
li r4, -1
|
||||
mulli r3, r4, 2
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulli_7:
|
||||
#_ REGISTER_IN r4 1
|
||||
mulli r3, r4, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_mulli_7_constant:
|
||||
li r4, 1
|
||||
mulli r3, r4, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_mulli_8:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
mulli r3, r4, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
test_mulli_8_constant:
|
||||
li r4, -1
|
||||
mulli r3, r4, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
200
src/xenia/cpu/ppc/testing/instr_mullw.s
Normal file
200
src/xenia/cpu/ppc/testing/instr_mullw.s
Normal file
@@ -0,0 +1,200 @@
|
||||
test_mullw_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mullw_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_mullw_2:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mullw_2_constant:
|
||||
li r4, 1
|
||||
li r5, 1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mullw_3:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 -1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mullw_3_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mullw_4:
|
||||
#_ REGISTER_IN r4 123
|
||||
#_ REGISTER_IN r5 -1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -123
|
||||
#_ REGISTER_OUT r4 123
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mullw_4_constant:
|
||||
li r4, 123
|
||||
li r5, -1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -123
|
||||
#_ REGISTER_OUT r4 123
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mullw_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mullw_5_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mullw_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 2
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_mullw_6_constant:
|
||||
li r4, -1
|
||||
li r5, 2
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_mullw_7:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 -1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mullw_7_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mullw_8:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 -1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mullw_8_constant:
|
||||
li r4, -1
|
||||
li r5, -1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 -1
|
||||
|
||||
test_mullw_9:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFF00000000
|
||||
#_ REGISTER_IN r5 1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFF00000000
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mullw_9_constant:
|
||||
li r4, -1
|
||||
sldi r4, r4, 32
|
||||
li r5, 1
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFF00000000
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_mullw_10:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0xFFFFFFFF00000000
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF00000000
|
||||
|
||||
test_mullw_10_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
sldi r5, r5, 32
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF00000000
|
||||
|
||||
test_mullw_11:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0x000000007FFFFFFF
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
|
||||
test_mullw_11_constant:
|
||||
li r4, 1
|
||||
li r5, -1
|
||||
clrldi r5, r5, 33
|
||||
mullw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0x000000007FFFFFFF
|
||||
37
src/xenia/cpu/ppc/testing/instr_neg.s
Normal file
37
src/xenia/cpu/ppc/testing/instr_neg.s
Normal file
@@ -0,0 +1,37 @@
|
||||
test_neg_1:
|
||||
#_ REGISTER_IN r3 0x0000000080000000
|
||||
neg r3, r3
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
|
||||
test_neg_1_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 31
|
||||
neg r3, r3
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFF80000000
|
||||
|
||||
test_neg_2:
|
||||
#_ REGISTER_IN r3 0x8000000000000000
|
||||
neg r3, r3
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
|
||||
test_neg_2_constant:
|
||||
li r3, 1
|
||||
sldi r3, r3, 63
|
||||
neg r3, r3
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
|
||||
test_neg_3:
|
||||
#_ REGISTER_IN r3 0x0000000000000005
|
||||
neg r3, r3
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFB
|
||||
|
||||
test_neg_3_constant:
|
||||
li r3, 5
|
||||
neg r3, r3
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFB
|
||||
20
src/xenia/cpu/ppc/testing/instr_nor.s
Normal file
20
src/xenia/cpu/ppc/testing/instr_nor.s
Normal file
@@ -0,0 +1,20 @@
|
||||
test_nor_cr_1:
|
||||
#_ REGISTER_IN r3 0x00000000FFFFFFFF
|
||||
nor. r3, r3, r3
|
||||
li r3, 0
|
||||
bne nor_cr_1_ne
|
||||
li r3, 1
|
||||
nor_cr_1_ne:
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
|
||||
test_nor_cr_1_constant:
|
||||
li r3, -1
|
||||
clrldi r3, r3, 32
|
||||
nor. r3, r3, r3
|
||||
li r3, 0
|
||||
bne nor_cr_1_constant_ne
|
||||
li r3, 1
|
||||
nor_cr_1_constant_ne:
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
42
src/xenia/cpu/ppc/testing/instr_ori.s
Normal file
42
src/xenia/cpu/ppc/testing/instr_ori.s
Normal file
@@ -0,0 +1,42 @@
|
||||
.macro make_test_constant dest
|
||||
lis \dest, 0xDEAD
|
||||
ori \dest, \dest, 0xBEEF
|
||||
sldi \dest, \dest, 32
|
||||
.endm
|
||||
|
||||
test_ori_1:
|
||||
#_ REGISTER_IN r4 0xDEADBEEF00000000
|
||||
|
||||
ori r3, r4, 0xFEDC
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xDEADBEEF0000FEDC
|
||||
#_ REGISTER_OUT r4 0xDEADBEEF00000000
|
||||
|
||||
test_ori_1_constant:
|
||||
make_test_constant r4
|
||||
ori r3, r4, 0xFEDC
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xDEADBEEF0000FEDC
|
||||
#_ REGISTER_OUT r4 0xDEADBEEF00000000
|
||||
|
||||
test_ori_2:
|
||||
#_ REGISTER_IN r4 0xDEADBEEF10000000
|
||||
|
||||
ori r3, r4, 0xFEDC
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xDEADBEEF1000FEDC
|
||||
#_ REGISTER_OUT r4 0xDEADBEEF10000000
|
||||
|
||||
test_ori_2_constant:
|
||||
make_test_constant r4
|
||||
lis r3, 0x1000
|
||||
or r4, r4, r3
|
||||
|
||||
ori r3, r4, 0xFEDC
|
||||
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xDEADBEEF1000FEDC
|
||||
#_ REGISTER_OUT r4 0xDEADBEEF10000000
|
||||
221
src/xenia/cpu/ppc/testing/instr_rldicl.s
Normal file
221
src/xenia/cpu/ppc/testing/instr_rldicl.s
Normal file
@@ -0,0 +1,221 @@
|
||||
.macro make_full_test_constant dest, a, b, c, d
|
||||
lis \dest, \a
|
||||
ori \dest, \dest, \b
|
||||
sldi \dest, \dest, 32
|
||||
lis r3, \c
|
||||
ori r3, r3, \d
|
||||
clrldi r3, r3, 32
|
||||
or \dest, \dest, r3
|
||||
.endm
|
||||
|
||||
test_rldicl_1:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 24, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x6789abcdef012345
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_1_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 24, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x6789abcdef012345
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_2:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 24, 8
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0089abcdef012345
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_2_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 24, 8
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0089abcdef012345
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_3:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 24, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_3_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 24, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_4:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 0, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0123456789abcdef
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_4_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 0, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0123456789abcdef
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_5:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 0, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_5_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 0, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_6:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 0, 8
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0023456789abcdef
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_6_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 0, 8
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0023456789abcdef
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_7:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 63, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8091a2b3c4d5e6f7
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_7_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 63, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8091a2b3c4d5e6f7
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_8:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 63, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_8_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 63, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_9:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicl r3, r4, 31, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xc4d5e6f78091a2b3
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_9_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicl r3, r4, 31, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xc4d5e6f78091a2b3
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicl_10:
|
||||
#_ REGISTER_IN r4 0x16300000
|
||||
rldicl r3, r4, 58, 6
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x58C000
|
||||
#_ REGISTER_OUT r4 0x16300000
|
||||
|
||||
test_rldicl_10_constant:
|
||||
lis r4, 0x1630
|
||||
rldicl r3, r4, 58, 6
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x58C000
|
||||
#_ REGISTER_OUT r4 0x16300000
|
||||
|
||||
test_srdi_1:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
srdi r3, r3, 0
|
||||
srdi r4, r4, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_srdi_1_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
li r3, -1
|
||||
srdi r3, r3, 0
|
||||
srdi r4, r4, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_srdi_2:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
srdi r3, r3, 1
|
||||
srdi r4, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7fffffffffffffff
|
||||
#_ REGISTER_OUT r4 0x0091a2b3c4d5e6f7
|
||||
|
||||
test_srdi_2_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
li r3, -1
|
||||
srdi r3, r3, 1
|
||||
srdi r4, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7fffffffffffffff
|
||||
#_ REGISTER_OUT r4 0x0091a2b3c4d5e6f7
|
||||
|
||||
test_srdi_3:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
srdi r3, r3, 32
|
||||
srdi r4, r4, 32
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000ffffffff
|
||||
#_ REGISTER_OUT r4 0x0000000001234567
|
||||
|
||||
test_srdi_3_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
li r3, -1
|
||||
srdi r3, r3, 32
|
||||
srdi r4, r4, 32
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000ffffffff
|
||||
#_ REGISTER_OUT r4 0x0000000001234567
|
||||
|
||||
test_srdi_4:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
srdi r3, r3, 63
|
||||
srdi r4, r4, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0x0000000000000000
|
||||
|
||||
test_srdi_4_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
li r3, -1
|
||||
srdi r3, r3, 63
|
||||
srdi r4, r4, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0x0000000000000000
|
||||
207
src/xenia/cpu/ppc/testing/instr_rldicr.s
Normal file
207
src/xenia/cpu/ppc/testing/instr_rldicr.s
Normal file
@@ -0,0 +1,207 @@
|
||||
.macro make_full_test_constant dest, a, b, c, d
|
||||
lis \dest, \a
|
||||
ori \dest, \dest, \b
|
||||
sldi \dest, \dest, 32
|
||||
lis r3, \c
|
||||
ori r3, r3, \d
|
||||
clrldi r3, r3, 32
|
||||
or \dest, \dest, r3
|
||||
.endm
|
||||
|
||||
test_rldicr_1:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 24, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_1_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 24, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_2:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 24, 8
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x6780000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_2_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 24, 8
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x6780000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_3:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 24, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x6789abcdef012345
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_3_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 24, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x6789abcdef012345
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_4:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 0, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_4_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 0, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_5:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 0, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0123456789abcdef
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_5_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 0, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0123456789abcdef
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_6:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 0, 8
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0100000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_6_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 0, 8
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0100000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_7:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 63, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_7_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 63, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_8:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 63, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8091a2b3c4d5e6f7
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_8_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 63, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8091a2b3c4d5e6f7
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_9:
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
rldicr r3, r4, 31, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_rldicr_9_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
rldicr r3, r4, 31, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_sldi_1:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
sldi r3, r3, 0
|
||||
sldi r4, r4, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_sldi_1_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
li r3, -1
|
||||
sldi r3, r3, 0
|
||||
sldi r4, r4, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0x0123456789ABCDEF
|
||||
|
||||
test_sldi_2:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
sldi r3, r3, 1
|
||||
sldi r4, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 0x02468acf13579bde
|
||||
|
||||
test_sldi_2_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
li r3, -1
|
||||
sldi r3, r3, 1
|
||||
sldi r4, r4, 1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 0x02468acf13579bde
|
||||
|
||||
test_sldi_3:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r4, 32
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffff00000000
|
||||
#_ REGISTER_OUT r4 0x89abcdef00000000
|
||||
|
||||
test_sldi_3_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
li r3, -1
|
||||
sldi r3, r3, 32
|
||||
sldi r4, r4, 32
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffff00000000
|
||||
#_ REGISTER_OUT r4 0x89abcdef00000000
|
||||
|
||||
test_sldi_4:
|
||||
#_ REGISTER_IN r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r4 0x0123456789ABCDEF
|
||||
sldi r3, r3, 63
|
||||
sldi r4, r4, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
#_ REGISTER_OUT r4 0x8000000000000000
|
||||
|
||||
test_sldi_4_constant:
|
||||
make_full_test_constant r4, 0x0123, 0x4567, 0x89AB, 0xCDEF
|
||||
li r3, -1
|
||||
sldi r3, r3, 63
|
||||
sldi r4, r4, 63
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
#_ REGISTER_OUT r4 0x8000000000000000
|
||||
25
src/xenia/cpu/ppc/testing/instr_rlwimi.s
Normal file
25
src/xenia/cpu/ppc/testing/instr_rlwimi.s
Normal file
@@ -0,0 +1,25 @@
|
||||
.macro make_full_test_constant dest, a, b, c, d
|
||||
lis \dest, \a
|
||||
ori \dest, \dest, \b
|
||||
sldi \dest, \dest, 32
|
||||
lis r3, \c
|
||||
ori r3, r3, \d
|
||||
clrldi r3, r3, 32
|
||||
or \dest, \dest, r3
|
||||
.endm
|
||||
|
||||
test_rlwimi:
|
||||
#_ REGISTER_IN r4 0xCAFEBABE90003000
|
||||
#_ REGISTER_IN r6 0xDEADBEEF00000003
|
||||
rlwimi r6, r4, 2, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0xCAFEBABE90003000
|
||||
#_ REGISTER_OUT r6 0xDEADBEEF4000C003
|
||||
|
||||
test_rlwimi_constant:
|
||||
make_full_test_constant r4, 0xCAFE, 0xBABE, 0x9000, 0x3000
|
||||
make_full_test_constant r6, 0xDEAD, 0xBEEF, 0x0000, 0x0003
|
||||
rlwimi r6, r4, 2, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0xCAFEBABE90003000
|
||||
#_ REGISTER_OUT r6 0xDEADBEEF4000C003
|
||||
242
src/xenia/cpu/ppc/testing/instr_rlwinm.s
Normal file
242
src/xenia/cpu/ppc/testing/instr_rlwinm.s
Normal file
@@ -0,0 +1,242 @@
|
||||
test_rlwinm_1:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
rlwinm r3, r4, 24, 8, 15
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00120000
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_1_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
rlwinm r3, r4, 24, 8, 15
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00120000
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_2:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
rlwinm r3, r4, 4, 0, 27
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x23456780
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_2_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
rlwinm r3, r4, 4, 0, 27
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x23456780
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_3:
|
||||
#_ REGISTER_IN r4 0x90003000
|
||||
rlwinm r3, r4, 2, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x4000C000
|
||||
#_ REGISTER_OUT r4 0x90003000
|
||||
|
||||
test_rlwinm_3_constant:
|
||||
lis r4, 0x9000
|
||||
ori r4, r4, 0x3000
|
||||
clrldi r4, r4, 32
|
||||
rlwinm r3, r4, 2, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x4000C000
|
||||
#_ REGISTER_OUT r4 0x90003000
|
||||
|
||||
test_rlwinm_4:
|
||||
#_ REGISTER_IN r4 0xB0043000
|
||||
rlwinm. r3, r4, 2, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xC010C000
|
||||
#_ REGISTER_OUT r4 0xB0043000
|
||||
# CRF = 0x8
|
||||
|
||||
test_rlwinm_4_constant:
|
||||
lis r4, 0xB004
|
||||
ori r4, r4, 0x3000
|
||||
clrldi r4, r4, 32
|
||||
rlwinm. r3, r4, 2, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xC010C000
|
||||
#_ REGISTER_OUT r4 0xB0043000
|
||||
# CRF = 0x8
|
||||
|
||||
test_rlwinm_5:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
rlwinm r3, r4, 0, 5, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x02345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_5_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
rlwinm r3, r4, 0, 5, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x02345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_6:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
rlwinm r3, r4, 0, 0, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_6_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
rlwinm r3, r4, 0, 0, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_7:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
rlwinm r3, r4, 0, 0, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12340000
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_7_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
rlwinm r3, r4, 0, 0, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12340000
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_8:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
rlwinm r3, r4, 0, 16, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00005678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_8_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
rlwinm r3, r4, 0, 16, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00005678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_9:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
rlwinm r3, r4, 16, 16, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00001234
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
test_rlwinm_9_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
rlwinm r3, r4, 16, 16, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00001234
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
|
||||
# Extract and right justify immediate
|
||||
# extrwi RA, RS, n, b
|
||||
# rlwinm RA, RS, b+n, 32-n, 31
|
||||
test_extrwi_1:
|
||||
# extrwi ra,rs,n,b (n > 0) == rlwinm ra,rs,b+n,32-n,31
|
||||
#_ REGISTER_IN r5 0x30
|
||||
rlwinm r7, r5, 29, 28, 31
|
||||
#extrwi r7, r5, 4, 25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x30
|
||||
#_ REGISTER_OUT r7 0x06
|
||||
|
||||
test_extrwi_1_constant:
|
||||
# extrwi ra,rs,n,b (n > 0) == rlwinm ra,rs,b+n,32-n,31
|
||||
li r5, 0x30
|
||||
rlwinm r7, r5, 29, 28, 31
|
||||
#extrwi r7, r5, 4, 25
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x30
|
||||
#_ REGISTER_OUT r7 0x06
|
||||
|
||||
test_extrwi_2:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFF01234567
|
||||
rlwinm r7, r5, 26, 16, 31
|
||||
#extrwi r7, r5, 16, 10
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF01234567
|
||||
#_ REGISTER_OUT r7 0x0000000000008D15
|
||||
|
||||
test_extrwi_2_constant:
|
||||
li r5, -1
|
||||
sldi r5, r5, 32
|
||||
oris r5, r5, 0x0123
|
||||
ori r5, r5, 0x4567
|
||||
rlwinm r7, r5, 26, 16, 31
|
||||
#extrwi r7, r5, 16, 10
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF01234567
|
||||
#_ REGISTER_OUT r7 0x0000000000008D15
|
||||
|
||||
test_extrwi_cr_1:
|
||||
#_ REGISTER_IN r5 0x30
|
||||
rlwinm. r7, r5, 29, 28, 31
|
||||
#extrwi. r7, r5, 4, 25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x30
|
||||
#_ REGISTER_OUT r7 0x06
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extrwi_cr_1_constant:
|
||||
li r5, 0x30
|
||||
rlwinm. r7, r5, 29, 28, 31
|
||||
#extrwi. r7, r5, 4, 25
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0x30
|
||||
#_ REGISTER_OUT r7 0x06
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extrwi_cr_2:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFF01234567
|
||||
rlwinm. r7, r5, 26, 16, 31
|
||||
#extrwi. r7, r5, 16, 10
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF01234567
|
||||
#_ REGISTER_OUT r7 0x0000000000008D15
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extrwi_cr_2_constant:
|
||||
li r5, -1
|
||||
sldi r5, r5, 32
|
||||
oris r5, r5, 0x0123
|
||||
ori r5, r5, 0x4567
|
||||
rlwinm. r7, r5, 26, 16, 31
|
||||
#extrwi. r7, r5, 16, 10
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF01234567
|
||||
#_ REGISTER_OUT r7 0x0000000000008D15
|
||||
#_ REGISTER_OUT r12 0x40000000
|
||||
|
||||
test_extrwi_cr_3:
|
||||
#_ REGISTER_IN r5 0xFFFFFFFF00000000
|
||||
rlwinm. r7, r5, 26, 16, 31
|
||||
#extrwi. r7, r5, 16, 10
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF00000000
|
||||
#_ REGISTER_OUT r7 0x0000000000000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
|
||||
test_extrwi_cr_3_constant:
|
||||
li r5, -1
|
||||
sldi r5, r5, 32
|
||||
rlwinm. r7, r5, 26, 16, 31
|
||||
#extrwi. r7, r5, 16, 10
|
||||
mfcr r12
|
||||
blr
|
||||
#_ REGISTER_OUT r5 0xFFFFFFFF00000000
|
||||
#_ REGISTER_OUT r7 0x0000000000000000
|
||||
#_ REGISTER_OUT r12 0x20000000
|
||||
193
src/xenia/cpu/ppc/testing/instr_rlwnm.s
Normal file
193
src/xenia/cpu/ppc/testing/instr_rlwnm.s
Normal file
@@ -0,0 +1,193 @@
|
||||
test_rlwnm_1:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
#_ REGISTER_IN r5 24
|
||||
rlwnm r3, r4, r5, 8, 15
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00120000
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 24
|
||||
|
||||
test_rlwnm_1_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
li r5, 24
|
||||
rlwnm r3, r4, r5, 8, 15
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00120000
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 24
|
||||
|
||||
test_rlwnm_2:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
#_ REGISTER_IN r5 4
|
||||
rlwnm r3, r4, r5, 0, 27
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x23456780
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 4
|
||||
|
||||
test_rlwnm_2_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
li r5, 4
|
||||
rlwnm r3, r4, r5, 0, 27
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x23456780
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 4
|
||||
|
||||
test_rlwnm_3:
|
||||
#_ REGISTER_IN r4 0x90003000
|
||||
#_ REGISTER_IN r5 2
|
||||
rlwnm r3, r4, r5, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x4000C000
|
||||
#_ REGISTER_OUT r4 0x90003000
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_rlwnm_3_constant:
|
||||
lis r4, 0x9000
|
||||
ori r4, r4, 0x3000
|
||||
clrldi r4, r4, 32
|
||||
li r5, 2
|
||||
rlwnm r3, r4, r5, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x4000C000
|
||||
#_ REGISTER_OUT r4 0x90003000
|
||||
#_ REGISTER_OUT r5 2
|
||||
|
||||
test_rlwnm_4:
|
||||
#_ REGISTER_IN r4 0xB0043000
|
||||
#_ REGISTER_IN r5 2
|
||||
rlwnm. r3, r4, r5, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xC010C000
|
||||
#_ REGISTER_OUT r4 0xB0043000
|
||||
#_ REGISTER_OUT r5 2
|
||||
# CRF = 0x8
|
||||
|
||||
test_rlwnm_4_constant:
|
||||
lis r4, 0xB004
|
||||
ori r4, r4, 0x3000
|
||||
clrldi r4, r4, 32
|
||||
li r5, 2
|
||||
rlwnm. r3, r4, r5, 0, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xC010C000
|
||||
#_ REGISTER_OUT r4 0xB0043000
|
||||
#_ REGISTER_OUT r5 2
|
||||
# CRF = 0x8
|
||||
|
||||
test_rlwnm_5:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
#_ REGISTER_IN r5 0
|
||||
rlwnm r3, r4, r5, 5, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x02345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_rlwnm_5_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
li r5, 0
|
||||
rlwnm r3, r4, r5, 5, 0x1D
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x02345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_rlwnm_6:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
#_ REGISTER_IN r5 0
|
||||
rlwnm r3, r4, r5, 0, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_rlwnm_6_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
li r5, 0
|
||||
rlwnm r3, r4, r5, 0, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_rlwnm_7:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
#_ REGISTER_IN r5 0
|
||||
rlwnm r3, r4, r5, 0, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12340000
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_rlwnm_7_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
li r5, 0
|
||||
rlwnm r3, r4, r5, 0, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12340000
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_rlwnm_8:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
#_ REGISTER_IN r5 0
|
||||
rlwnm r3, r4, r5, 16, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00005678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_rlwnm_8_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
li r5, 0
|
||||
rlwnm r3, r4, r5, 16, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00005678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_rlwnm_9:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
#_ REGISTER_IN r5 16
|
||||
rlwnm r3, r4, r5, 16, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00001234
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 16
|
||||
|
||||
test_rlwnm_9_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
li r5, 16
|
||||
rlwnm r3, r4, r5, 16, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00001234
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 16
|
||||
|
||||
test_rlwnm_10:
|
||||
#_ REGISTER_IN r4 0x12345678
|
||||
#_ REGISTER_IN r5 32
|
||||
rlwnm r3, r4, r5, 0, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 32
|
||||
|
||||
test_rlwnm_10_constant:
|
||||
lis r4, 0x1234
|
||||
ori r4, r4, 0x5678
|
||||
li r5, 32
|
||||
rlwnm r3, r4, r5, 0, 31
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x12345678
|
||||
#_ REGISTER_OUT r4 0x12345678
|
||||
#_ REGISTER_OUT r5 32
|
||||
125
src/xenia/cpu/ppc/testing/instr_sld.s
Normal file
125
src/xenia/cpu/ppc/testing/instr_sld.s
Normal file
@@ -0,0 +1,125 @@
|
||||
test_sld_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_sld_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_sld_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_sld_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_sld_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_sld_3_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_sld_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 62
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xc000000000000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 62
|
||||
|
||||
test_sld_4_constant:
|
||||
li r4, -1
|
||||
li r5, 62
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xc000000000000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 62
|
||||
|
||||
test_sld_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 63
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
|
||||
test_sld_5_constant:
|
||||
li r4, -1
|
||||
li r5, 63
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x8000000000000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
|
||||
test_sld_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 64
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
|
||||
test_sld_6_constant:
|
||||
li r4, -1
|
||||
li r5, 64
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
|
||||
test_sld_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 100
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
|
||||
test_sld_7_constant:
|
||||
li r4, -1
|
||||
li r5, 100
|
||||
sld r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
161
src/xenia/cpu/ppc/testing/instr_slw.s
Normal file
161
src/xenia/cpu/ppc/testing/instr_slw.s
Normal file
@@ -0,0 +1,161 @@
|
||||
test_slw_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_slw_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_slw_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_slw_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_slw_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_slw_3_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFE
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_slw_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 63
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
|
||||
test_slw_4_constant:
|
||||
li r4, -1
|
||||
li r5, 63
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
|
||||
test_slw_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 64
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
|
||||
test_slw_5_constant:
|
||||
li r4, -1
|
||||
li r5, 64
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
|
||||
test_slw_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 100
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
|
||||
test_slw_6_constant:
|
||||
li r4, -1
|
||||
li r5, 100
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
|
||||
test_slw_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 30
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000c0000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 30
|
||||
|
||||
test_slw_7_constant:
|
||||
li r4, -1
|
||||
li r5, 30
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000c0000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 30
|
||||
|
||||
test_slw_8:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 31
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000080000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 31
|
||||
|
||||
test_slw_8_constant:
|
||||
li r4, -1
|
||||
li r5, 31
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000080000000
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 31
|
||||
|
||||
test_slw_9:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 32
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 32
|
||||
|
||||
test_slw_9_constant:
|
||||
li r4, -1
|
||||
li r5, 32
|
||||
slw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 32
|
||||
153
src/xenia/cpu/ppc/testing/instr_srad.s
Normal file
153
src/xenia/cpu/ppc/testing/instr_srad.s
Normal file
@@ -0,0 +1,153 @@
|
||||
test_srad_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_srad_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_srad_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_srad_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_srad_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_3_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 62
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 62
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_4_constant:
|
||||
li r4, -1
|
||||
li r5, 62
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 62
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 63
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_5_constant:
|
||||
li r4, -1
|
||||
li r5, 63
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 64
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_6_constant:
|
||||
li r4, -1
|
||||
li r5, 64
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 100
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srad_7_constant:
|
||||
li r4, -1
|
||||
li r5, 100
|
||||
srad r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
#_ REGISTER_OUT r6 1
|
||||
89
src/xenia/cpu/ppc/testing/instr_sradi.s
Normal file
89
src/xenia/cpu/ppc/testing/instr_sradi.s
Normal file
@@ -0,0 +1,89 @@
|
||||
test_sradi_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
sradi r3, r4, 0
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sradi_1_constant:
|
||||
li r4, 1
|
||||
sradi r3, r4, 0
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sradi_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
sradi r3, r4, 0
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sradi_2_constant:
|
||||
li r4, -1
|
||||
sradi r3, r4, 0
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sradi_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
sradi r3, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sradi_3_constant:
|
||||
li r4, -1
|
||||
sradi r3, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sradi_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
sradi r3, r4, 62
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sradi_4_constant:
|
||||
li r4, -1
|
||||
sradi r3, r4, 62
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sradi_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
sradi r3, r4, 63
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sradi_5_constant:
|
||||
li r4, -1
|
||||
sradi r3, r4, 63
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
197
src/xenia/cpu/ppc/testing/instr_sraw.s
Normal file
197
src/xenia/cpu/ppc/testing/instr_sraw.s
Normal file
@@ -0,0 +1,197 @@
|
||||
test_sraw_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sraw_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sraw_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sraw_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sraw_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_3_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 63
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_4_constant:
|
||||
li r4, -1
|
||||
li r5, 63
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 64
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sraw_5_constant:
|
||||
li r4, -1
|
||||
li r5, 64
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_sraw_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 100
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_6_constant:
|
||||
li r4, -1
|
||||
li r5, 100
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 30
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 30
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_7_constant:
|
||||
li r4, -1
|
||||
li r5, 30
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 30
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_8:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 31
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 31
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_8_constant:
|
||||
li r4, -1
|
||||
li r5, 31
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 31
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_9:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 32
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 32
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_sraw_9_constant:
|
||||
li r4, -1
|
||||
li r5, 32
|
||||
sraw r3, r4, r5
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 32
|
||||
#_ REGISTER_OUT r6 1
|
||||
89
src/xenia/cpu/ppc/testing/instr_srawi.s
Normal file
89
src/xenia/cpu/ppc/testing/instr_srawi.s
Normal file
@@ -0,0 +1,89 @@
|
||||
test_srawi_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
srawi r3, r4, 0
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_srawi_1_constant:
|
||||
li r4, 1
|
||||
srawi r3, r4, 0
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_srawi_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
srawi r3, r4, 0
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_srawi_2_constant:
|
||||
li r4, -1
|
||||
srawi r3, r4, 0
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 0
|
||||
|
||||
test_srawi_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
srawi r3, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srawi_3_constant:
|
||||
li r4, -1
|
||||
srawi r3, r4, 1
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srawi_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
srawi r3, r4, 30
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srawi_4_constant:
|
||||
li r4, -1
|
||||
srawi r3, r4, 30
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srawi_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
srawi r3, r4, 31
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
|
||||
test_srawi_5_constant:
|
||||
li r4, -1
|
||||
srawi r3, r4, 31
|
||||
adde r6, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r6 1
|
||||
125
src/xenia/cpu/ppc/testing/instr_srd.s
Normal file
125
src/xenia/cpu/ppc/testing/instr_srd.s
Normal file
@@ -0,0 +1,125 @@
|
||||
test_srd_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_srd_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_srd_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_srd_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_srd_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_srd_3_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x7FFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_srd_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 62
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000003
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 62
|
||||
|
||||
test_srd_4_constant:
|
||||
li r4, -1
|
||||
li r5, 62
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000003
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 62
|
||||
|
||||
test_srd_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 63
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
|
||||
test_srd_5_constant:
|
||||
li r4, -1
|
||||
li r5, 63
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
|
||||
test_srd_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 64
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
|
||||
test_srd_6_constant:
|
||||
li r4, -1
|
||||
li r5, 64
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
|
||||
test_srd_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 100
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
|
||||
test_srd_7_constant:
|
||||
li r4, -1
|
||||
li r5, 100
|
||||
srd r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
161
src/xenia/cpu/ppc/testing/instr_srw.s
Normal file
161
src/xenia/cpu/ppc/testing/instr_srw.s
Normal file
@@ -0,0 +1,161 @@
|
||||
test_srw_1:
|
||||
#_ REGISTER_IN r4 1
|
||||
#_ REGISTER_IN r5 0
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_srw_1_constant:
|
||||
li r4, 1
|
||||
li r5, 0
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_srw_2:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 0
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_srw_2_constant:
|
||||
li r4, -1
|
||||
li r5, 0
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 0
|
||||
|
||||
test_srw_3:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 1
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_srw_3_constant:
|
||||
li r4, -1
|
||||
li r5, 1
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x000000007FFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 1
|
||||
|
||||
test_srw_4:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 63
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
|
||||
test_srw_4_constant:
|
||||
li r4, -1
|
||||
li r5, 63
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 63
|
||||
|
||||
test_srw_5:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 64
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
|
||||
test_srw_5_constant:
|
||||
li r4, -1
|
||||
li r5, 64
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x00000000FFFFFFFF
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 64
|
||||
|
||||
test_srw_6:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 100
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
|
||||
test_srw_6_constant:
|
||||
li r4, -1
|
||||
li r5, 100
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 100
|
||||
|
||||
test_srw_7:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 30
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000003
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 30
|
||||
|
||||
test_srw_7_constant:
|
||||
li r4, -1
|
||||
li r5, 30
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000003
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 30
|
||||
|
||||
test_srw_8:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 31
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 31
|
||||
|
||||
test_srw_8_constant:
|
||||
li r4, -1
|
||||
li r5, 31
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0x0000000000000001
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 31
|
||||
|
||||
test_srw_9:
|
||||
#_ REGISTER_IN r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r5 32
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 32
|
||||
|
||||
test_srw_9_constant:
|
||||
li r4, -1
|
||||
li r5, 32
|
||||
srw r3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r5 32
|
||||
83
src/xenia/cpu/ppc/testing/instr_stvew.s
Normal file
83
src/xenia/cpu/ppc/testing/instr_stvew.s
Normal file
@@ -0,0 +1,83 @@
|
||||
test_stvew_1:
|
||||
#_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
#_ REGISTER_IN r4 0x10001050
|
||||
#_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
stvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001050
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
#_ MEMORY_OUT 10001050 00010203 CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
|
||||
test_stvew_1_constant:
|
||||
#_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1050
|
||||
#_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
stvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001050
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
#_ MEMORY_OUT 10001050 00010203 CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
|
||||
test_stvew_2:
|
||||
#_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
#_ REGISTER_IN r4 0x10001054
|
||||
#_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
stvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001054
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
#_ MEMORY_OUT 10001050 CCCCCCCC 04050607 CCCCCCCC CCCCCCCC
|
||||
|
||||
test_stvew_2_constant:
|
||||
#_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1054
|
||||
#_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
stvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001054
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
#_ MEMORY_OUT 10001050 CCCCCCCC 04050607 CCCCCCCC CCCCCCCC
|
||||
|
||||
test_stvew_3:
|
||||
#_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
#_ REGISTER_IN r4 0x10001058
|
||||
#_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
stvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001058
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
#_ MEMORY_OUT 10001050 CCCCCCCC CCCCCCCC 08090A0B CCCCCCCC
|
||||
|
||||
test_stvew_3_constant:
|
||||
#_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1058
|
||||
#_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
stvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001058
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
#_ MEMORY_OUT 10001050 CCCCCCCC CCCCCCCC 08090A0B CCCCCCCC
|
||||
|
||||
test_stvew_4:
|
||||
#_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
#_ REGISTER_IN r4 0x1000105C
|
||||
#_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
stvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1000105C
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
#_ MEMORY_OUT 10001050 CCCCCCCC CCCCCCCC CCCCCCCC 0C0D0E0F
|
||||
|
||||
test_stvew_4_constant:
|
||||
#_ MEMORY_IN 10001050 CCCCCCCC CCCCCCCC CCCCCCCC CCCCCCCC
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x105C
|
||||
#_ REGISTER_IN v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
stvewx v3, r0, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x1000105C
|
||||
#_ REGISTER_OUT v3 [00010203, 04050607, 08090A0B, 0C0D0E0F]
|
||||
#_ MEMORY_OUT 10001050 CCCCCCCC CCCCCCCC CCCCCCCC 0C0D0E0F
|
||||
41
src/xenia/cpu/ppc/testing/instr_stvl.s
Normal file
41
src/xenia/cpu/ppc/testing/instr_stvl.s
Normal file
@@ -0,0 +1,41 @@
|
||||
test_stvl_1:
|
||||
#_ MEMORY_IN 10001040 00000000 00000000 00000000 3F800000
|
||||
#_ REGISTER_IN r4 0x10001040
|
||||
#_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
stvlx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001040
|
||||
#_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
#_ MEMORY_OUT 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F
|
||||
|
||||
test_stvl_1_constant:
|
||||
#_ MEMORY_IN 10001040 00000000 00000000 00000000 3F800000
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1040
|
||||
#_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
stvlx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001040
|
||||
#_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
#_ MEMORY_OUT 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F
|
||||
|
||||
test_stvl_2:
|
||||
#_ MEMORY_IN 10001040 00010203 04050607 08090A0B 0C0D0E0F
|
||||
#_ REGISTER_IN r4 0x10001044
|
||||
#_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF]
|
||||
stvlx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001044
|
||||
#_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF]
|
||||
#_ MEMORY_OUT 10001040 00010203 F0F1F2F3 F4F5F6F7 F8F9FAFB
|
||||
|
||||
test_stvl_2_constant:
|
||||
#_ MEMORY_IN 10001040 00010203 04050607 08090A0B 0C0D0E0F
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1044
|
||||
#_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF]
|
||||
stvlx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001044
|
||||
#_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF]
|
||||
#_ MEMORY_OUT 10001040 00010203 F0F1F2F3 F4F5F6F7 F8F9FAFB
|
||||
67
src/xenia/cpu/ppc/testing/instr_stvr.s
Normal file
67
src/xenia/cpu/ppc/testing/instr_stvr.s
Normal file
@@ -0,0 +1,67 @@
|
||||
test_stvr_1:
|
||||
#_ MEMORY_IN 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F
|
||||
#_ MEMORY_IN 10001050 00000000 00000000 00000000 00000000
|
||||
#_ REGISTER_IN r4 0x10001040
|
||||
#_ REGISTER_IN r5 0x10
|
||||
#_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
stvrx v3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001040
|
||||
#_ REGISTER_OUT r5 0x10
|
||||
#_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
#_ MEMORY_OUT 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F
|
||||
#_ MEMORY_OUT 10001050 00000000 00000000 00000000 00000000
|
||||
|
||||
test_stvr_1_constant:
|
||||
#_ MEMORY_IN 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F
|
||||
#_ MEMORY_IN 10001050 00000000 00000000 00000000 00000000
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1040
|
||||
li r5, 0x10
|
||||
#_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
stvrx v3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001040
|
||||
#_ REGISTER_OUT r5 0x10
|
||||
#_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
#_ MEMORY_OUT 10001040 BE74FCBD BD912ABA BF317BBB BF2D135F
|
||||
#_ MEMORY_OUT 10001050 00000000 00000000 00000000 00000000
|
||||
|
||||
test_stvr_2:
|
||||
#_ MEMORY_IN 10001040 00010203 04050607 08090A0B 0C0D0E0F
|
||||
#_ REGISTER_IN r4 0x10001044
|
||||
#_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF]
|
||||
stvrx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001044
|
||||
#_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF]
|
||||
#_ MEMORY_OUT 10001040 FCFDFEFF 04050607 08090A0B 0C0D0E0F
|
||||
|
||||
test_stvr_2_constant:
|
||||
#_ MEMORY_IN 10001040 00010203 04050607 08090A0B 0C0D0E0F
|
||||
lis r4, 0x1000
|
||||
ori r4, r4, 0x1044
|
||||
#_ REGISTER_IN v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF]
|
||||
stvrx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10001044
|
||||
#_ REGISTER_OUT v3 [F0F1F2F3, F4F5F6F7, F8F9FAFB, FCFDFEFF]
|
||||
#_ MEMORY_OUT 10001040 FCFDFEFF 04050607 08090A0B 0C0D0E0F
|
||||
|
||||
test_stvr_3:
|
||||
#_ REGISTER_IN r4 0x10010000
|
||||
#_ REGISTER_IN r5 0x0
|
||||
#_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
stvrx v3, r4, r5
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10010000
|
||||
#_ REGISTER_OUT r5 0x0
|
||||
#_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
|
||||
test_stvr_3_constant:
|
||||
#_ REGISTER_IN v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
lis r4, 0x1001
|
||||
stvrx v3, r4, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r4 0x10010000
|
||||
#_ REGISTER_OUT v3 [BE74FCBD, BD912ABA, BF317BBB, BF2D135F]
|
||||
91
src/xenia/cpu/ppc/testing/instr_subf.s
Normal file
91
src/xenia/cpu/ppc/testing/instr_subf.s
Normal file
@@ -0,0 +1,91 @@
|
||||
test_subf_1:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
#_ REGISTER_IN r11 0x00000000000103C0
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r11 0x00000000000103C0
|
||||
#_ REGISTER_OUT r3 0x1
|
||||
|
||||
test_subf_1_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
lis r11, 1
|
||||
ori r11, r11, 0x03C0
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r11 0x00000000000103C0
|
||||
#_ REGISTER_OUT r3 0x1
|
||||
|
||||
test_subf_2:
|
||||
#_ REGISTER_IN r10 0
|
||||
#_ REGISTER_IN r11 0
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_subf_2_constant:
|
||||
li r10, 0
|
||||
li r11, 0
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_subf_3:
|
||||
#_ REGISTER_IN r10 1
|
||||
#_ REGISTER_IN r11 0
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_subf_3_constant:
|
||||
li r10, 1
|
||||
li r11, 0
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_subf_4:
|
||||
#_ REGISTER_IN r10 0
|
||||
#_ REGISTER_IN r11 1
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 1
|
||||
#_ REGISTER_OUT r3 1
|
||||
|
||||
test_subf_4_constant:
|
||||
li r10, 0
|
||||
li r11, 1
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 1
|
||||
#_ REGISTER_OUT r3 1
|
||||
|
||||
test_subf_5:
|
||||
#_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r11 0xFFFFFFFFFFFFFFFF
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0x0
|
||||
|
||||
test_subf_5_constant:
|
||||
li r10, -1
|
||||
li r11, -1
|
||||
subf r3, r10, r11
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0x0
|
||||
111
src/xenia/cpu/ppc/testing/instr_subfc.s
Normal file
111
src/xenia/cpu/ppc/testing/instr_subfc.s
Normal file
@@ -0,0 +1,111 @@
|
||||
test_subfc_1:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
#_ REGISTER_IN r11 0x00000000000103C0
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r11 0x00000000000103C0
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfc_1_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
lis r11, 1
|
||||
ori r11, r11, 0x03C0
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r11 0x00000000000103C0
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfc_2:
|
||||
#_ REGISTER_IN r10 0
|
||||
#_ REGISTER_IN r11 0
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfc_2_constant:
|
||||
li r10, 0
|
||||
li r11, 0
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfc_3:
|
||||
#_ REGISTER_IN r10 1
|
||||
#_ REGISTER_IN r11 0
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfc_3_constant:
|
||||
li r10, 1
|
||||
li r11, 0
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfc_4:
|
||||
#_ REGISTER_IN r10 0
|
||||
#_ REGISTER_IN r11 1
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 1
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfc_4_constant:
|
||||
li r10, 0
|
||||
li r11, 1
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 1
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfc_5:
|
||||
#_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r11 0xFFFFFFFFFFFFFFFF
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfc_5_constant:
|
||||
li r10, -1
|
||||
li r11, -1
|
||||
subfc r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
111
src/xenia/cpu/ppc/testing/instr_subfe.s
Normal file
111
src/xenia/cpu/ppc/testing/instr_subfe.s
Normal file
@@ -0,0 +1,111 @@
|
||||
test_subfe_1:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
#_ REGISTER_IN r11 0x00000000000103C0
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r11 0x00000000000103C0
|
||||
#_ REGISTER_OUT r3 0x0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfe_1_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
lis r11, 1
|
||||
ori r11, r11, 0x03C0
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r11 0x00000000000103C0
|
||||
#_ REGISTER_OUT r3 0x0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfe_2:
|
||||
#_ REGISTER_IN r10 0
|
||||
#_ REGISTER_IN r11 0
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfe_2_constant:
|
||||
li r10, 0
|
||||
li r11, 0
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfe_3:
|
||||
#_ REGISTER_IN r10 1
|
||||
#_ REGISTER_IN r11 0
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfe_3_constant:
|
||||
li r10, 1
|
||||
li r11, 0
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r11 0
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfe_4:
|
||||
#_ REGISTER_IN r10 0
|
||||
#_ REGISTER_IN r11 1
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 1
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfe_4_constant:
|
||||
li r10, 0
|
||||
li r11, 1
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r11 1
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfe_5:
|
||||
#_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_IN r11 0xFFFFFFFFFFFFFFFF
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfe_5_constant:
|
||||
li r10, -1
|
||||
li r11, -1
|
||||
subfe r3, r10, r11
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r11 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r4 0
|
||||
109
src/xenia/cpu/ppc/testing/instr_subfic.s
Normal file
109
src/xenia/cpu/ppc/testing/instr_subfic.s
Normal file
@@ -0,0 +1,109 @@
|
||||
test_subfic_1:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
subfic r3, r10, 0x3C0
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xffffffffffff0001
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfic_1_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
subfic r3, r10, 0x3C0
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xffffffffffff0001
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfic_2:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
subfic r3, r10, -234
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefb57
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfic_2_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
subfic r3, r10, -234
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefb57
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfic_3:
|
||||
#_ REGISTER_IN r10 0
|
||||
subfic r3, r10, 0
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfic_3_constant:
|
||||
li r10, 0
|
||||
subfic r3, r10, 0
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfic_4:
|
||||
#_ REGISTER_IN r10 1
|
||||
subfic r3, r10, 0
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfic_4_constant:
|
||||
li r10, 1
|
||||
subfic r3, r10, 0
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfic_5:
|
||||
#_ REGISTER_IN r10 0
|
||||
subfic r3, r10, 1
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfic_5_constant:
|
||||
li r10, 0
|
||||
subfic r3, r10, 1
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfic_6:
|
||||
#_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF
|
||||
subfic r3, r10, -1
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfic_6_constant:
|
||||
li r10, -1
|
||||
subfic r3, r10, -1
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
185
src/xenia/cpu/ppc/testing/instr_subfme.s
Normal file
185
src/xenia/cpu/ppc/testing/instr_subfme.s
Normal file
@@ -0,0 +1,185 @@
|
||||
test_subfme_one_ca_1:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefc40
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_one_ca_1_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefc40
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_one_ca_2:
|
||||
#_ REGISTER_IN r10 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_one_ca_2_constant:
|
||||
li r10, 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_one_ca_3:
|
||||
#_ REGISTER_IN r10 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_one_ca_3_constant:
|
||||
li r10, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_one_ca_4:
|
||||
#_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_one_ca_4_constant:
|
||||
li r10, -1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_zero_ca_1:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefc3f
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_zero_ca_1_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefc3f
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_zero_ca_2:
|
||||
#_ REGISTER_IN r10 0
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_zero_ca_2_constant:
|
||||
li r10, 0
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_zero_ca_3:
|
||||
#_ REGISTER_IN r10 1
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffd
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_zero_ca_3_constant:
|
||||
li r10, 1
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffd
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfme_zero_ca_4:
|
||||
#_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfme_zero_ca_4_constant:
|
||||
li r10, -1
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfme r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0
|
||||
185
src/xenia/cpu/ppc/testing/instr_subfze.s
Normal file
185
src/xenia/cpu/ppc/testing/instr_subfze.s
Normal file
@@ -0,0 +1,185 @@
|
||||
test_subfze_one_ca_1:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefc41
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_one_ca_1_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefc41
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_one_ca_2:
|
||||
#_ REGISTER_IN r10 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfze_one_ca_2_constant:
|
||||
li r10, 0
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 1
|
||||
|
||||
test_subfze_one_ca_3:
|
||||
#_ REGISTER_IN r10 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_one_ca_3_constant:
|
||||
li r10, 1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_one_ca_4:
|
||||
#_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0x1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_one_ca_4_constant:
|
||||
li r10, -1
|
||||
xor r3, r3, r3
|
||||
not r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0x1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_zero_ca_1:
|
||||
#_ REGISTER_IN r10 0x00000000000103BF
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefc40
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_zero_ca_1_constant:
|
||||
lis r10, 1
|
||||
ori r10, r10, 0x03BF
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0x00000000000103BF
|
||||
#_ REGISTER_OUT r3 0xfffffffffffefc40
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_zero_ca_2:
|
||||
#_ REGISTER_IN r10 0
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_zero_ca_2_constant:
|
||||
li r10, 0
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0
|
||||
#_ REGISTER_OUT r3 0xffffffffffffffff
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_zero_ca_3:
|
||||
#_ REGISTER_IN r10 1
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_zero_ca_3_constant:
|
||||
li r10, 1
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 1
|
||||
#_ REGISTER_OUT r3 0xfffffffffffffffe
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_zero_ca_4:
|
||||
#_ REGISTER_IN r10 0xFFFFFFFFFFFFFFFF
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_subfze_zero_ca_4_constant:
|
||||
li r10, -1
|
||||
xor r3, r3, r3
|
||||
addic r3, r3, 1
|
||||
subfze r3, r10
|
||||
adde r4, r0, r0
|
||||
blr
|
||||
#_ REGISTER_OUT r10 0xFFFFFFFFFFFFFFFF
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
511
src/xenia/cpu/ppc/testing/instr_td.s
Normal file
511
src/xenia/cpu/ppc/testing/instr_td.s
Normal file
@@ -0,0 +1,511 @@
|
||||
test_tdlt_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
tdlt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdlt_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
tdlt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdlt_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
tdlt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdlt_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
tdlt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdle_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
tdle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdle_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
tdle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdle_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
tdle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdle_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
tdle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdeq_1:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 24
|
||||
tdeq r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 24
|
||||
|
||||
test_tdeq_1_constant:
|
||||
li r3, 0
|
||||
li r4, 24
|
||||
tdeq r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 24
|
||||
|
||||
test_tdeq_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
tdeq r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdeq_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
tdeq r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdge_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
tdge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdge_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
tdge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdge_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
tdge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdge_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
tdge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdge_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
#_ REGISTER_IN r4 0
|
||||
tdge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdge_3_constant:
|
||||
li r3, -1
|
||||
li r4, 0
|
||||
tdge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdgt_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
tdgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdgt_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
tdgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdgt_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
tdgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdgt_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
tdgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdgt_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
#_ REGISTER_IN r4 0
|
||||
tdgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdgt_3_constant:
|
||||
li r3, -1
|
||||
li r4, 0
|
||||
tdgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdnl_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
tdnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdnl_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
tdnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdnl_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
tdnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdnl_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
tdnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdnl_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
#_ REGISTER_IN r4 0
|
||||
tdnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdnl_3_constant:
|
||||
li r3, -1
|
||||
li r4, 0
|
||||
tdnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdne_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 24
|
||||
tdne r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 24
|
||||
|
||||
test_tdne_1_constant:
|
||||
li r3, 24
|
||||
li r4, 24
|
||||
tdne r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 24
|
||||
|
||||
test_tdne_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 0
|
||||
tdne r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdne_2_constant:
|
||||
li r3, 0
|
||||
li r4, 0
|
||||
tdne r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdng_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
tdng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdng_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
tdng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdng_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
tdng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdng_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
tdng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdng_3:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 -1
|
||||
tdng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 -1
|
||||
|
||||
test_tdng_3_constant:
|
||||
li r3, 0
|
||||
li r4, -1
|
||||
tdng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 -1
|
||||
|
||||
test_tdllt_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
tdllt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdllt_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
tdllt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdllt_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
tdllt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdllt_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
tdllt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdlle_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
tdlle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdlle_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
tdlle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdlle_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
tdlle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdlle_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
tdlle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdlge_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
tdlge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlge_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
tdlge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlge_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
tdlge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlge_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
tdlge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlgt_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
tdlgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlgt_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
tdlgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlgt_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
tdlgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlgt_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
tdlgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlnl_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
tdlnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlnl_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
tdlnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlnl_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
tdlnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlnl_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
tdlnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_tdlng_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
tdlng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdlng_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
tdlng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_tdlng_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
tdlng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tdlng_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
tdlng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
383
src/xenia/cpu/ppc/testing/instr_tdi.s
Normal file
383
src/xenia/cpu/ppc/testing/instr_tdi.s
Normal file
@@ -0,0 +1,383 @@
|
||||
test_tdlti_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlti r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlti_1_constant:
|
||||
li r3, 24
|
||||
tdlti r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlti_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlti_2_constant:
|
||||
li r3, 24
|
||||
tdlti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlei r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlei_1_constant:
|
||||
li r3, 24
|
||||
tdlei r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlei_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlei_2_constant:
|
||||
li r3, 24
|
||||
tdlei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdeqi_1:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdeqi r3, 24
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdeqi_1_constant:
|
||||
li r3, 0
|
||||
tdeqi r3, 24
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdeqi_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdeqi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdeqi_2_constant:
|
||||
li r3, 24
|
||||
tdeqi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdgei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdgei_1_constant:
|
||||
li r3, 24
|
||||
tdgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdgei_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdgei_2_constant:
|
||||
li r3, 0
|
||||
tdgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdgei_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
tdgei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_tdgei_3_constant:
|
||||
li r3, -1
|
||||
tdgei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_tdgti_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdgti_1_constant:
|
||||
li r3, 24
|
||||
tdgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdgti_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdgti_2_constant:
|
||||
li r3, 0
|
||||
tdgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdgti_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
tdgti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_tdgti_3_constant:
|
||||
li r3, -1
|
||||
tdgti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_tdnli_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdnli_1_constant:
|
||||
li r3, 24
|
||||
tdnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdnli_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdnli_2_constant:
|
||||
li r3, 0
|
||||
tdnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdnli_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
tdnli r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_tdnli_3_constant:
|
||||
li r3, -1
|
||||
tdnli r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_tdnei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdnei r3, 24
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdnei_1_constant:
|
||||
li r3, 24
|
||||
tdnei r3, 24
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdnei_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdnei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdnei_2_constant:
|
||||
li r3, 0
|
||||
tdnei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdngi_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdngi r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdngi_1_constant:
|
||||
li r3, 24
|
||||
tdngi r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdngi_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdngi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdngi_2_constant:
|
||||
li r3, 24
|
||||
tdngi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdngi_3:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdngi r3, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdngi_3_constant:
|
||||
li r3, 0
|
||||
tdngi r3, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdllti_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdllti r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdllti_1_constant:
|
||||
li r3, 24
|
||||
tdllti r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdllti_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdllti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdllti_2_constant:
|
||||
li r3, 24
|
||||
tdllti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdllei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdllei r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdllei_1_constant:
|
||||
li r3, 24
|
||||
tdllei r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdllei_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdllei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdllei_2_constant:
|
||||
li r3, 24
|
||||
tdllei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlgei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlgei_1_constant:
|
||||
li r3, 24
|
||||
tdlgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlgei_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdlgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdlgei_2_constant:
|
||||
li r3, 0
|
||||
tdlgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdlgti_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlgti_1_constant:
|
||||
li r3, 24
|
||||
tdlgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlgti_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdlgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdlgti_2_constant:
|
||||
li r3, 0
|
||||
tdlgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdlnli_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlnli_1_constant:
|
||||
li r3, 24
|
||||
tdlnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlnli_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
tdlnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdlnli_2_constant:
|
||||
li r3, 0
|
||||
tdlnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tdlngi_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlngi r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlngi_1_constant:
|
||||
li r3, 24
|
||||
tdlngi r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlngi_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
tdlngi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tdlngi_2_constant:
|
||||
li r3, 24
|
||||
tdlngi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
511
src/xenia/cpu/ppc/testing/instr_tw.s
Normal file
511
src/xenia/cpu/ppc/testing/instr_tw.s
Normal file
@@ -0,0 +1,511 @@
|
||||
test_twlt_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
twlt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twlt_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
twlt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twlt_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
twlt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twlt_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
twlt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twle_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
twle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twle_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
twle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twle_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
twle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twle_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
twle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tweq_1:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 24
|
||||
tweq r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 24
|
||||
|
||||
test_tweq_1_constant:
|
||||
li r3, 0
|
||||
li r4, 24
|
||||
tweq r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 24
|
||||
|
||||
test_tweq_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
tweq r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_tweq_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
tweq r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twge_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
twge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twge_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
twge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twge_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
twge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twge_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
twge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twge_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
#_ REGISTER_IN r4 0
|
||||
twge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twge_3_constant:
|
||||
li r3, -1
|
||||
li r4, 0
|
||||
twge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twgt_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
twgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twgt_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
twgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twgt_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
twgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twgt_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
twgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twgt_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
#_ REGISTER_IN r4 0
|
||||
twgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twgt_3_constant:
|
||||
li r3, -1
|
||||
li r4, 0
|
||||
twgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twnl_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
twnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twnl_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
twnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twnl_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
twnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twnl_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
twnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twnl_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
#_ REGISTER_IN r4 0
|
||||
twnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twnl_3_constant:
|
||||
li r3, -1
|
||||
li r4, 0
|
||||
twnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twne_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 24
|
||||
twne r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 24
|
||||
|
||||
test_twne_1_constant:
|
||||
li r3, 24
|
||||
li r4, 24
|
||||
twne r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 24
|
||||
|
||||
test_twne_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 0
|
||||
twne r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twne_2_constant:
|
||||
li r3, 0
|
||||
li r4, 0
|
||||
twne r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twng_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
twng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twng_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
twng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twng_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
twng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twng_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
twng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twng_3:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 -1
|
||||
twng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 -1
|
||||
|
||||
test_twng_3_constant:
|
||||
li r3, 0
|
||||
li r4, -1
|
||||
twng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 -1
|
||||
|
||||
test_twllt_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
twllt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twllt_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
twllt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twllt_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
twllt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twllt_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
twllt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twlle_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
twlle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twlle_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
twlle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twlle_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
twlle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twlle_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
twlle r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twlge_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
twlge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlge_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
twlge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlge_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
twlge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlge_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
twlge r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlgt_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
twlgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlgt_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
twlgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlgt_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
twlgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlgt_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
twlgt r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlnl_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 48
|
||||
twlnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlnl_1_constant:
|
||||
li r3, 24
|
||||
li r4, 48
|
||||
twlnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlnl_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
#_ REGISTER_IN r4 48
|
||||
twlnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlnl_2_constant:
|
||||
li r3, 0
|
||||
li r4, 48
|
||||
twlnl r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
#_ REGISTER_OUT r4 48
|
||||
|
||||
test_twlng_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 16
|
||||
twlng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twlng_1_constant:
|
||||
li r3, 24
|
||||
li r4, 16
|
||||
twlng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 16
|
||||
|
||||
test_twlng_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
#_ REGISTER_IN r4 0
|
||||
twlng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
|
||||
test_twlng_2_constant:
|
||||
li r3, 24
|
||||
li r4, 0
|
||||
twlng r3, r4
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
#_ REGISTER_OUT r4 0
|
||||
383
src/xenia/cpu/ppc/testing/instr_twi.s
Normal file
383
src/xenia/cpu/ppc/testing/instr_twi.s
Normal file
@@ -0,0 +1,383 @@
|
||||
test_twlti_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlti r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlti_1_constant:
|
||||
li r3, 24
|
||||
twlti r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlti_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlti_2_constant:
|
||||
li r3, 24
|
||||
twlti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlei r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlei_1_constant:
|
||||
li r3, 24
|
||||
twlei r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlei_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlei_2_constant:
|
||||
li r3, 24
|
||||
twlei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tweqi_1:
|
||||
#_ REGISTER_IN r3 0
|
||||
tweqi r3, 24
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tweqi_1_constant:
|
||||
li r3, 0
|
||||
tweqi r3, 24
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_tweqi_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
tweqi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_tweqi_2_constant:
|
||||
li r3, 24
|
||||
tweqi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twgei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twgei_1_constant:
|
||||
li r3, 24
|
||||
twgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twgei_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
twgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twgei_2_constant:
|
||||
li r3, 0
|
||||
twgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twgei_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
twgei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_twgei_3_constant:
|
||||
li r3, -1
|
||||
twgei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_twgti_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twgti_1_constant:
|
||||
li r3, 24
|
||||
twgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twgti_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
twgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twgti_2_constant:
|
||||
li r3, 0
|
||||
twgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twgti_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
twgti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_twgti_3_constant:
|
||||
li r3, -1
|
||||
twgti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_twnli_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twnli_1_constant:
|
||||
li r3, 24
|
||||
twnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twnli_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
twnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twnli_2_constant:
|
||||
li r3, 0
|
||||
twnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twnli_3:
|
||||
#_ REGISTER_IN r3 -1
|
||||
twnli r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_twnli_3_constant:
|
||||
li r3, -1
|
||||
twnli r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 -1
|
||||
|
||||
test_twnei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twnei r3, 24
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twnei_1_constant:
|
||||
li r3, 24
|
||||
twnei r3, 24
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twnei_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
twnei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twnei_2_constant:
|
||||
li r3, 0
|
||||
twnei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twngi_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twngi r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twngi_1_constant:
|
||||
li r3, 24
|
||||
twngi r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twngi_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
twngi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twngi_2_constant:
|
||||
li r3, 24
|
||||
twngi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twngi_3:
|
||||
#_ REGISTER_IN r3 0
|
||||
twngi r3, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twngi_3_constant:
|
||||
li r3, 0
|
||||
twngi r3, -1
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twllti_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twllti r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twllti_1_constant:
|
||||
li r3, 24
|
||||
twllti r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twllti_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
twllti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twllti_2_constant:
|
||||
li r3, 24
|
||||
twllti r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twllei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twllei r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twllei_1_constant:
|
||||
li r3, 24
|
||||
twllei r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twllei_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
twllei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twllei_2_constant:
|
||||
li r3, 24
|
||||
twllei r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlgei_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlgei_1_constant:
|
||||
li r3, 24
|
||||
twlgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlgei_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
twlgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twlgei_2_constant:
|
||||
li r3, 0
|
||||
twlgei r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twlgti_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlgti_1_constant:
|
||||
li r3, 24
|
||||
twlgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlgti_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
twlgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twlgti_2_constant:
|
||||
li r3, 0
|
||||
twlgti r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twlnli_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlnli_1_constant:
|
||||
li r3, 24
|
||||
twlnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlnli_2:
|
||||
#_ REGISTER_IN r3 0
|
||||
twlnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twlnli_2_constant:
|
||||
li r3, 0
|
||||
twlnli r3, 48
|
||||
blr
|
||||
#_ REGISTER_OUT r3 0
|
||||
|
||||
test_twlngi_1:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlngi r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlngi_1_constant:
|
||||
li r3, 24
|
||||
twlngi r3, 16
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlngi_2:
|
||||
#_ REGISTER_IN r3 24
|
||||
twlngi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
|
||||
test_twlngi_2_constant:
|
||||
li r3, 24
|
||||
twlngi r3, 0
|
||||
blr
|
||||
#_ REGISTER_OUT r3 24
|
||||
9
src/xenia/cpu/ppc/testing/instr_vaddfp.s
Normal file
9
src/xenia/cpu/ppc/testing/instr_vaddfp.s
Normal file
@@ -0,0 +1,9 @@
|
||||
test_vaddfp_1:
|
||||
# v3 = [10.0, -10.0, 15.0, -15.0]
|
||||
# v4 = [-10.0, 20.0, -20.0, 30.0]
|
||||
#_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000]
|
||||
#_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000]
|
||||
vaddfp v3, v3, v4
|
||||
blr
|
||||
#_ REGISTER_OUT v3 [00000000, 41200000, C0A00000, 41700000]
|
||||
#_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000]
|
||||
10
src/xenia/cpu/ppc/testing/instr_vaddfp128.s
Normal file
10
src/xenia/cpu/ppc/testing/instr_vaddfp128.s
Normal file
@@ -0,0 +1,10 @@
|
||||
test_vaddfp128_1:
|
||||
# v3 = [10.0, -10.0, 15.0, -15.0]
|
||||
# v4 = [-10.0, 20.0, -20.0, 30.0]
|
||||
#_ REGISTER_IN v3 [41200000, C1200000, 41700000, C1700000]
|
||||
#_ REGISTER_IN v4 [C1200000, 41A00000, C1A00000, 41F00000]
|
||||
vaddfp128 v0, v3, v4
|
||||
blr
|
||||
#_ REGISTER_OUT v0 [00000000, 41200000, C0A00000, 41700000]
|
||||
#_ REGISTER_OUT v3 [41200000, C1200000, 41700000, C1700000]
|
||||
#_ REGISTER_OUT v4 [C1200000, 41A00000, C1A00000, 41F00000]
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user