Commit f53fda63 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: Remove register index/code indirection

Port 5cf1c0bc

Original commit message:
    Previous to this patch, both the lithium and TurboFan register
    allocators tracked allocated registers by "indices", rather than
    the register codes used elsewhere in the runtime. This patch
    ensures that codes are used everywhere, and in the process cleans
    up a bunch of redundant code and adds more structure to how the
    set of allocatable registers is defined.

    Some highlights of changes:

    * TurboFan's RegisterConfiguration class moved to V8's top level
      so that it can be shared with Crankshaft.
    * Various "ToAllocationIndex" and related methods removed.
    * Code that can be easily shared between Register classes on
      different platforms is now shared.
    * The list of allocatable registers on each platform is declared
      as a list rather than implicitly via the register index <->
      code mapping.

R=danno@chromium.org, bmeurer@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, dstence@us.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1381383002

Cr-Commit-Position: refs/heads/master@{#31114}
parent 57ca0f36
...@@ -128,16 +128,6 @@ Register ToRegister(int num) { ...@@ -128,16 +128,6 @@ Register ToRegister(int num) {
} }
const char* DoubleRegister::AllocationIndexToString(int index) {
DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
const char* const names[] = {
"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10",
"d11", "d12", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
"d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
return names[index];
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Implementation of RelocInfo // Implementation of RelocInfo
...@@ -286,14 +276,14 @@ bool Assembler::IsBranch(Instr instr) { return ((instr & kOpcodeMask) == BCX); } ...@@ -286,14 +276,14 @@ bool Assembler::IsBranch(Instr instr) { return ((instr & kOpcodeMask) == BCX); }
Register Assembler::GetRA(Instr instr) { Register Assembler::GetRA(Instr instr) {
Register reg; Register reg;
reg.code_ = Instruction::RAValue(instr); reg.reg_code = Instruction::RAValue(instr);
return reg; return reg;
} }
Register Assembler::GetRB(Instr instr) { Register Assembler::GetRB(Instr instr) {
Register reg; Register reg;
reg.code_ = Instruction::RBValue(instr); reg.reg_code = Instruction::RBValue(instr);
return reg; return reg;
} }
......
...@@ -61,9 +61,9 @@ ...@@ -61,9 +61,9 @@
(V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN) (V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN)
#if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64 #if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64
#define ABI_TOC_REGISTER kRegister_r2_Code #define ABI_TOC_REGISTER Register::kCode_r2
#else #else
#define ABI_TOC_REGISTER kRegister_r13_Code #define ABI_TOC_REGISTER Register::kCode_r13
#endif #endif
#define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC #define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC
...@@ -71,6 +71,40 @@ ...@@ -71,6 +71,40 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// clang-format off
#define GENERAL_REGISTERS(V) \
V(r0) V(sp) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \
V(r8) V(r9) V(r10) V(r11) V(ip) V(r13) V(r14) V(r15) \
V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \
V(r24) V(r25) V(r26) V(r27) V(r28) V(r29) V(r30) V(fp)
#if V8_EMBEDDED_CONSTANT_POOL
#define ALLOCATABLE_GENERAL_REGISTERS(V) \
V(r3) V(r4) V(r5) V(r6) V(r7) \
V(r8) V(r9) V(r10) V(r14) V(r15) \
V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \
V(r24) V(r25) V(r26) V(r27) V(r30)
#else
#define ALLOCATABLE_GENERAL_REGISTERS(V) \
V(r3) V(r4) V(r5) V(r6) V(r7) \
V(r8) V(r9) V(r10) V(r14) V(r15) \
V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \
V(r24) V(r25) V(r26) V(r27) V(r28) V(r30)
#endif
#define DOUBLE_REGISTERS(V) \
V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) \
V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
V(d8) V(d9) V(d10) V(d11) V(d12) V(d15) \
V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
// clang-format on
// CPU Registers. // CPU Registers.
// //
// 1) We would prefer to use an enum, but enum values are assignment- // 1) We would prefer to use an enum, but enum values are assignment-
...@@ -92,310 +126,112 @@ namespace internal { ...@@ -92,310 +126,112 @@ namespace internal {
// mode. This way we get the compile-time error checking in debug mode // mode. This way we get the compile-time error checking in debug mode
// and best performance in optimized code. // and best performance in optimized code.
// Core register
struct Register { struct Register {
static const int kNumRegisters = 32; enum Code {
static const int kSizeInBytes = kPointerSize; #define REGISTER_CODE(R) kCode_##R,
GENERAL_REGISTERS(REGISTER_CODE)
#if V8_TARGET_LITTLE_ENDIAN #undef REGISTER_CODE
static const int kMantissaOffset = 0; kAfterLast,
static const int kExponentOffset = 4; kCode_no_reg = -1
#else };
static const int kMantissaOffset = 4;
static const int kExponentOffset = 0;
#endif
static const int kAllocatableLowRangeBegin = 3; static const int kNumRegisters = Code::kAfterLast;
static const int kAllocatableLowRangeEnd = 10;
static const int kAllocatableHighRangeBegin = 14;
static const int kAllocatableHighRangeEnd =
FLAG_enable_embedded_constant_pool ? 27 : 28;
static const int kAllocatableContext = 30;
static const int kNumAllocatableLow =
kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1;
static const int kNumAllocatableHigh =
kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1;
static const int kMaxNumAllocatableRegisters =
kNumAllocatableLow + kNumAllocatableHigh + 1; // cp
static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
static int ToAllocationIndex(Register reg) {
int index;
int code = reg.code();
if (code == kAllocatableContext) {
// Context is the last index
index = NumAllocatableRegisters() - 1;
} else if (code <= kAllocatableLowRangeEnd) {
// low range
index = code - kAllocatableLowRangeBegin;
} else {
// high range
index = code - kAllocatableHighRangeBegin + kNumAllocatableLow;
}
DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
return index;
}
static Register FromAllocationIndex(int index) { #define REGISTER_COUNT(R) 1 +
DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); static const int kNumAllocatable =
// Last index is always the 'cp' register. ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT)0;
if (index == kMaxNumAllocatableRegisters - 1) { #undef REGISTER_COUNT
return from_code(kAllocatableContext);
}
return (index < kNumAllocatableLow)
? from_code(index + kAllocatableLowRangeBegin)
: from_code(index - kNumAllocatableLow +
kAllocatableHighRangeBegin);
}
static const char* AllocationIndexToString(int index) {
DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
const char* const names[] = {
"r3",
"r4",
"r5",
"r6",
"r7",
"r8",
"r9",
"r10",
"r14",
"r15",
"r16",
"r17",
"r18",
"r19",
"r20",
"r21",
"r22",
"r23",
"r24",
"r25",
"r26",
"r27",
"r28",
"cp",
};
if (FLAG_enable_embedded_constant_pool &&
(index == kMaxNumAllocatableRegisters - 2)) {
return names[index + 1];
}
return names[index];
}
#define REGISTER_BIT(R) 1 << kCode_##R |
static const RegList kAllocatable = static const RegList kAllocatable =
1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 | ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT)0;
1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 | #undef REGISTER_BIT
1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 |
(FLAG_enable_embedded_constant_pool ? 0 : 1 << 28) | 1 << 30;
static Register from_code(int code) { static Register from_code(int code) {
DCHECK(code >= 0);
DCHECK(code < kNumRegisters);
Register r = {code}; Register r = {code};
return r; return r;
} }
const char* ToString();
bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } bool IsAllocatable() const;
bool is(Register reg) const { return code_ == reg.code_; } bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
bool is(Register reg) const { return reg_code == reg.reg_code; }
int code() const { int code() const {
DCHECK(is_valid()); DCHECK(is_valid());
return code_; return reg_code;
} }
int bit() const { int bit() const {
DCHECK(is_valid()); DCHECK(is_valid());
return 1 << code_; return 1 << reg_code;
} }
void set_code(int code) { void set_code(int code) {
code_ = code; reg_code = code;
DCHECK(is_valid()); DCHECK(is_valid());
} }
#if V8_TARGET_LITTLE_ENDIAN
static const int kMantissaOffset = 0;
static const int kExponentOffset = 4;
#else
static const int kMantissaOffset = 4;
static const int kExponentOffset = 0;
#endif
// Unfortunately we can't make this private in a struct. // Unfortunately we can't make this private in a struct.
int code_; int reg_code;
}; };
// These constants are used in several locations, including static initializers #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
const int kRegister_no_reg_Code = -1; GENERAL_REGISTERS(DECLARE_REGISTER)
const int kRegister_r0_Code = 0; // general scratch #undef DECLARE_REGISTER
const int kRegister_sp_Code = 1; // stack pointer const Register no_reg = {Register::kCode_no_reg};
const int kRegister_r2_Code = 2; // special on PowerPC
const int kRegister_r3_Code = 3; // Aliases
const int kRegister_r4_Code = 4; const Register kLithiumScratch = r11; // lithium scratch.
const int kRegister_r5_Code = 5; const Register kConstantPoolRegister = r28; // Constant pool.
const int kRegister_r6_Code = 6; const Register kRootRegister = r29; // Roots array pointer.
const int kRegister_r7_Code = 7; const Register cp = r30; // JavaScript context pointer.
const int kRegister_r8_Code = 8;
const int kRegister_r9_Code = 9;
const int kRegister_r10_Code = 10;
const int kRegister_r11_Code = 11; // lithium scratch
const int kRegister_ip_Code = 12; // ip (general scratch)
const int kRegister_r13_Code = 13; // special on PowerPC
const int kRegister_r14_Code = 14;
const int kRegister_r15_Code = 15;
const int kRegister_r16_Code = 16;
const int kRegister_r17_Code = 17;
const int kRegister_r18_Code = 18;
const int kRegister_r19_Code = 19;
const int kRegister_r20_Code = 20;
const int kRegister_r21_Code = 21;
const int kRegister_r22_Code = 22;
const int kRegister_r23_Code = 23;
const int kRegister_r24_Code = 24;
const int kRegister_r25_Code = 25;
const int kRegister_r26_Code = 26;
const int kRegister_r27_Code = 27;
const int kRegister_r28_Code = 28; // constant pool pointer
const int kRegister_r29_Code = 29; // roots array pointer
const int kRegister_r30_Code = 30; // context pointer
const int kRegister_fp_Code = 31; // frame pointer
const Register no_reg = {kRegister_no_reg_Code};
const Register r0 = {kRegister_r0_Code};
const Register sp = {kRegister_sp_Code};
const Register r2 = {kRegister_r2_Code};
const Register r3 = {kRegister_r3_Code};
const Register r4 = {kRegister_r4_Code};
const Register r5 = {kRegister_r5_Code};
const Register r6 = {kRegister_r6_Code};
const Register r7 = {kRegister_r7_Code};
const Register r8 = {kRegister_r8_Code};
const Register r9 = {kRegister_r9_Code};
const Register r10 = {kRegister_r10_Code};
const Register r11 = {kRegister_r11_Code};
const Register ip = {kRegister_ip_Code};
const Register r13 = {kRegister_r13_Code};
const Register r14 = {kRegister_r14_Code};
const Register r15 = {kRegister_r15_Code};
const Register r16 = {kRegister_r16_Code};
const Register r17 = {kRegister_r17_Code};
const Register r18 = {kRegister_r18_Code};
const Register r19 = {kRegister_r19_Code};
const Register r20 = {kRegister_r20_Code};
const Register r21 = {kRegister_r21_Code};
const Register r22 = {kRegister_r22_Code};
const Register r23 = {kRegister_r23_Code};
const Register r24 = {kRegister_r24_Code};
const Register r25 = {kRegister_r25_Code};
const Register r26 = {kRegister_r26_Code};
const Register r27 = {kRegister_r27_Code};
const Register r28 = {kRegister_r28_Code};
const Register r29 = {kRegister_r29_Code};
const Register r30 = {kRegister_r30_Code};
const Register fp = {kRegister_fp_Code};
// Give alias names to registers
const Register cp = {kRegister_r30_Code}; // JavaScript context pointer
const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer.
const Register kConstantPoolRegister = {kRegister_r28_Code}; // Constant pool
// Double word FP register. // Double word FP register.
struct DoubleRegister { struct DoubleRegister {
static const int kNumRegisters = 32; enum Code {
static const int kMaxNumRegisters = kNumRegisters; #define REGISTER_CODE(R) kCode_##R,
static const int kNumVolatileRegisters = 14; // d0-d13 DOUBLE_REGISTERS(REGISTER_CODE)
static const int kSizeInBytes = 8; #undef REGISTER_CODE
kAfterLast,
static const int kAllocatableLowRangeBegin = 1; kCode_no_reg = -1
static const int kAllocatableLowRangeEnd = 12; };
static const int kAllocatableHighRangeBegin = 15;
static const int kAllocatableHighRangeEnd = 31;
static const int kNumAllocatableLow =
kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1;
static const int kNumAllocatableHigh =
kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1;
static const int kMaxNumAllocatableRegisters =
kNumAllocatableLow + kNumAllocatableHigh;
static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
// TODO(turbofan)
inline static int NumAllocatableAliasedRegisters() {
return NumAllocatableRegisters();
}
static int ToAllocationIndex(DoubleRegister reg) {
int code = reg.code();
int index = (code <= kAllocatableLowRangeEnd)
? code - kAllocatableLowRangeBegin
: code - kAllocatableHighRangeBegin + kNumAllocatableLow;
DCHECK(index < kMaxNumAllocatableRegisters);
return index;
}
static DoubleRegister FromAllocationIndex(int index) {
DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
return (index < kNumAllocatableLow)
? from_code(index + kAllocatableLowRangeBegin)
: from_code(index - kNumAllocatableLow +
kAllocatableHighRangeBegin);
}
static const char* AllocationIndexToString(int index);
static DoubleRegister from_code(int code) {
DoubleRegister r = {code};
return r;
}
bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters; } static const int kNumRegisters = Code::kAfterLast;
bool is(DoubleRegister reg) const { return code_ == reg.code_; } static const int kMaxNumRegisters = kNumRegisters;
const char* ToString();
bool IsAllocatable() const;
bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
int code() const { int code() const {
DCHECK(is_valid()); DCHECK(is_valid());
return code_; return reg_code;
} }
int bit() const { int bit() const {
DCHECK(is_valid()); DCHECK(is_valid());
return 1 << code_; return 1 << reg_code;
} }
void split_code(int* vm, int* m) const {
DCHECK(is_valid()); static DoubleRegister from_code(int code) {
*m = (code_ & 0x10) >> 4; DoubleRegister r = {code};
*vm = code_ & 0x0F; return r;
} }
int code_; int reg_code;
}; };
#define DECLARE_REGISTER(R) \
const DoubleRegister no_dreg = {-1}; const DoubleRegister R = {DoubleRegister::kCode_##R};
const DoubleRegister d0 = {0}; DOUBLE_REGISTERS(DECLARE_REGISTER)
const DoubleRegister d1 = {1}; #undef DECLARE_REGISTER
const DoubleRegister d2 = {2}; const Register no_dreg = {Register::kCode_no_reg};
const DoubleRegister d3 = {3};
const DoubleRegister d4 = {4};
const DoubleRegister d5 = {5};
const DoubleRegister d6 = {6};
const DoubleRegister d7 = {7};
const DoubleRegister d8 = {8};
const DoubleRegister d9 = {9};
const DoubleRegister d10 = {10};
const DoubleRegister d11 = {11};
const DoubleRegister d12 = {12};
const DoubleRegister d13 = {13};
const DoubleRegister d14 = {14};
const DoubleRegister d15 = {15};
const DoubleRegister d16 = {16};
const DoubleRegister d17 = {17};
const DoubleRegister d18 = {18};
const DoubleRegister d19 = {19};
const DoubleRegister d20 = {20};
const DoubleRegister d21 = {21};
const DoubleRegister d22 = {22};
const DoubleRegister d23 = {23};
const DoubleRegister d24 = {24};
const DoubleRegister d25 = {25};
const DoubleRegister d26 = {26};
const DoubleRegister d27 = {27};
const DoubleRegister d28 = {28};
const DoubleRegister d29 = {29};
const DoubleRegister d30 = {30};
const DoubleRegister d31 = {31};
// Aliases for double registers. Defined using #define instead of // Aliases for double registers. Defined using #define instead of
// "static const DoubleRegister&" because Clang complains otherwise when a // "static const DoubleRegister&" because Clang complains otherwise when a
...@@ -409,19 +245,19 @@ Register ToRegister(int num); ...@@ -409,19 +245,19 @@ Register ToRegister(int num);
// Coprocessor register // Coprocessor register
struct CRegister { struct CRegister {
bool is_valid() const { return 0 <= code_ && code_ < 16; } bool is_valid() const { return 0 <= reg_code && reg_code < 16; }
bool is(CRegister creg) const { return code_ == creg.code_; } bool is(CRegister creg) const { return reg_code == creg.reg_code; }
int code() const { int code() const {
DCHECK(is_valid()); DCHECK(is_valid());
return code_; return reg_code;
} }
int bit() const { int bit() const {
DCHECK(is_valid()); DCHECK(is_valid());
return 1 << code_; return 1 << reg_code;
} }
// Unfortunately we can't make this private in a struct. // Unfortunately we can't make this private in a struct.
int code_; int reg_code;
}; };
......
...@@ -14,45 +14,18 @@ namespace internal { ...@@ -14,45 +14,18 @@ namespace internal {
// formatting. See for example the command "objdump -d <binary file>". // formatting. See for example the command "objdump -d <binary file>".
const char* Registers::names_[kNumRegisters] = { const char* Registers::names_[kNumRegisters] = {
"r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r0", "sp", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r11", "ip", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
"r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "fp"}; "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "fp"};
// List of alias names which can be used when referring to PPC registers. const char* DoubleRegisters::names_[kNumDoubleRegisters] = {
const Registers::RegisterAlias Registers::aliases_[] = {{10, "sl"},
{11, "r11"},
{12, "r12"},
{13, "r13"},
{14, "r14"},
{15, "r15"},
{kNoRegister, NULL}};
const char* Registers::Name(int reg) {
const char* result;
if ((0 <= reg) && (reg < kNumRegisters)) {
result = names_[reg];
} else {
result = "noreg";
}
return result;
}
const char* FPRegisters::names_[kNumFPRegisters] = {
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10",
"d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21",
"d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"}; "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
const char* FPRegisters::Name(int reg) { int DoubleRegisters::Number(const char* name) {
DCHECK((0 <= reg) && (reg < kNumFPRegisters)); for (int i = 0; i < kNumDoubleRegisters; i++) {
return names_[reg];
}
int FPRegisters::Number(const char* name) {
for (int i = 0; i < kNumFPRegisters; i++) {
if (strcmp(names_[i], name) == 0) { if (strcmp(names_[i], name) == 0) {
return i; return i;
} }
...@@ -71,15 +44,6 @@ int Registers::Number(const char* name) { ...@@ -71,15 +44,6 @@ int Registers::Number(const char* name) {
} }
} }
// Look through the alias names.
int i = 0;
while (aliases_[i].reg != kNoRegister) {
if (strcmp(aliases_[i].name, name) == 0) {
return aliases_[i].reg;
}
i++;
}
// No register with the requested name found. // No register with the requested name found.
return kNoRegister; return kNoRegister;
} }
......
...@@ -18,8 +18,7 @@ namespace internal { ...@@ -18,8 +18,7 @@ namespace internal {
const int kNumRegisters = 32; const int kNumRegisters = 32;
// FP support. // FP support.
const int kNumFPDoubleRegisters = 32; const int kNumDoubleRegisters = 32;
const int kNumFPRegisters = kNumFPDoubleRegisters;
const int kNoRegister = -1; const int kNoRegister = -1;
...@@ -564,33 +563,21 @@ class Instruction { ...@@ -564,33 +563,21 @@ class Instruction {
// Helper functions for converting between register numbers and names. // Helper functions for converting between register numbers and names.
class Registers { class Registers {
public: public:
// Return the name of the register.
static const char* Name(int reg);
// Lookup the register number for the name provided. // Lookup the register number for the name provided.
static int Number(const char* name); static int Number(const char* name);
struct RegisterAlias {
int reg;
const char* name;
};
private: private:
static const char* names_[kNumRegisters]; static const char* names_[kNumRegisters];
static const RegisterAlias aliases_[];
}; };
// Helper functions for converting between FP register numbers and names. // Helper functions for converting between FP register numbers and names.
class FPRegisters { class DoubleRegisters {
public: public:
// Return the name of the register.
static const char* Name(int reg);
// Lookup the register number for the name provided. // Lookup the register number for the name provided.
static int Number(const char* name); static int Number(const char* name);
private: private:
static const char* names_[kNumFPRegisters]; static const char* names_[kNumDoubleRegisters];
}; };
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "src/codegen.h" #include "src/codegen.h"
#include "src/deoptimizer.h" #include "src/deoptimizer.h"
#include "src/full-codegen/full-codegen.h" #include "src/full-codegen/full-codegen.h"
#include "src/register-configuration.h"
#include "src/safepoint-table.h" #include "src/safepoint-table.h"
namespace v8 { namespace v8 {
...@@ -99,7 +100,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { ...@@ -99,7 +100,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
} }
input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
input_->SetDoubleRegister(i, 0.0); input_->SetDoubleRegister(i, 0.0);
} }
...@@ -123,7 +124,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters( ...@@ -123,7 +124,7 @@ void Deoptimizer::SetPlatformCompiledStubRegisters(
void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) { for (int i = 0; i < DoubleRegister::kNumRegisters; ++i) {
double double_value = input_->GetDoubleRegister(i); double double_value = input_->GetDoubleRegister(i);
output_frame->SetDoubleRegister(i, double_value); output_frame->SetDoubleRegister(i, double_value);
} }
...@@ -150,15 +151,16 @@ void Deoptimizer::TableEntryGenerator::Generate() { ...@@ -150,15 +151,16 @@ void Deoptimizer::TableEntryGenerator::Generate() {
RegList restored_regs = kJSCallerSaved | kCalleeSaved; RegList restored_regs = kJSCallerSaved | kCalleeSaved;
RegList saved_regs = restored_regs | sp.bit(); RegList saved_regs = restored_regs | sp.bit();
const int kDoubleRegsSize = const int kDoubleRegsSize = kDoubleSize * DoubleRegister::kNumRegisters;
kDoubleSize * DoubleRegister::kMaxNumAllocatableRegisters;
// Save all FPU registers before messing with them. // Save all double registers before messing with them.
__ subi(sp, sp, Operand(kDoubleRegsSize)); __ subi(sp, sp, Operand(kDoubleRegsSize));
for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) { const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
DoubleRegister fpu_reg = DoubleRegister::FromAllocationIndex(i); for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int offset = i * kDoubleSize; int code = config->GetAllocatableDoubleCode(i);
__ stfd(fpu_reg, MemOperand(sp, offset)); const DoubleRegister dreg = DoubleRegister::from_code(code);
int offset = code * kDoubleSize;
__ stfd(dreg, MemOperand(sp, offset));
} }
// Push saved_regs (needed to populate FrameDescription::registers_). // Push saved_regs (needed to populate FrameDescription::registers_).
...@@ -215,11 +217,12 @@ void Deoptimizer::TableEntryGenerator::Generate() { ...@@ -215,11 +217,12 @@ void Deoptimizer::TableEntryGenerator::Generate() {
} }
int double_regs_offset = FrameDescription::double_registers_offset(); int double_regs_offset = FrameDescription::double_registers_offset();
// Copy VFP registers to // Copy double registers to
// double_registers_[DoubleRegister::kNumAllocatableRegisters] // double_registers_[DoubleRegister::kNumRegisters]
for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) { for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
int dst_offset = i * kDoubleSize + double_regs_offset; int code = config->GetAllocatableDoubleCode(i);
int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; int dst_offset = code * kDoubleSize + double_regs_offset;
int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize;
__ lfd(d0, MemOperand(sp, src_offset)); __ lfd(d0, MemOperand(sp, src_offset));
__ stfd(d0, MemOperand(r4, dst_offset)); __ stfd(d0, MemOperand(r4, dst_offset));
} }
...@@ -291,9 +294,10 @@ void Deoptimizer::TableEntryGenerator::Generate() { ...@@ -291,9 +294,10 @@ void Deoptimizer::TableEntryGenerator::Generate() {
__ blt(&outer_push_loop); __ blt(&outer_push_loop);
__ LoadP(r4, MemOperand(r3, Deoptimizer::input_offset())); __ LoadP(r4, MemOperand(r3, Deoptimizer::input_offset()));
for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) { for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
const DoubleRegister dreg = DoubleRegister::FromAllocationIndex(i); int code = config->GetAllocatableDoubleCode(i);
int src_offset = i * kDoubleSize + double_regs_offset; const DoubleRegister dreg = DoubleRegister::from_code(code);
int src_offset = code * kDoubleSize + double_regs_offset;
__ lfd(dreg, MemOperand(r4, src_offset)); __ lfd(dreg, MemOperand(r4, src_offset));
} }
......
...@@ -116,7 +116,9 @@ void Decoder::PrintRegister(int reg) { ...@@ -116,7 +116,9 @@ void Decoder::PrintRegister(int reg) {
// Print the double FP register name according to the active name converter. // Print the double FP register name according to the active name converter.
void Decoder::PrintDRegister(int reg) { Print(FPRegisters::Name(reg)); } void Decoder::PrintDRegister(int reg) {
Print(DoubleRegister::from_code(reg).ToString());
}
// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of // Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
...@@ -1349,7 +1351,7 @@ const char* NameConverter::NameOfConstant(byte* addr) const { ...@@ -1349,7 +1351,7 @@ const char* NameConverter::NameOfConstant(byte* addr) const {
const char* NameConverter::NameOfCPURegister(int reg) const { const char* NameConverter::NameOfCPURegister(int reg) const {
return v8::internal::Registers::Name(reg); return v8::internal::Register::from_code(reg).ToString();
} }
const char* NameConverter::NameOfByteCPURegister(int reg) const { const char* NameConverter::NameOfByteCPURegister(int reg) const {
......
...@@ -70,6 +70,8 @@ const RegList kCallerSavedDoubles = 1 << 0 | // d0 ...@@ -70,6 +70,8 @@ const RegList kCallerSavedDoubles = 1 << 0 | // d0
1 << 12 | // d12 1 << 12 | // d12
1 << 13; // d13 1 << 13; // d13
const int kNumCallerSavedDoubles = 14;
const RegList kCalleeSavedDoubles = 1 << 14 | // d14 const RegList kCalleeSavedDoubles = 1 << 14 | // d14
1 << 15 | // d15 1 << 15 | // d15
1 << 16 | // d16 1 << 16 | // d16
......
...@@ -73,7 +73,7 @@ void LCodeGen::SaveCallerDoubles() { ...@@ -73,7 +73,7 @@ void LCodeGen::SaveCallerDoubles() {
BitVector* doubles = chunk()->allocated_double_registers(); BitVector* doubles = chunk()->allocated_double_registers();
BitVector::Iterator save_iterator(doubles); BitVector::Iterator save_iterator(doubles);
while (!save_iterator.Done()) { while (!save_iterator.Done()) {
__ stfd(DoubleRegister::FromAllocationIndex(save_iterator.Current()), __ stfd(DoubleRegister::from_code(save_iterator.Current()),
MemOperand(sp, count * kDoubleSize)); MemOperand(sp, count * kDoubleSize));
save_iterator.Advance(); save_iterator.Advance();
count++; count++;
...@@ -89,7 +89,7 @@ void LCodeGen::RestoreCallerDoubles() { ...@@ -89,7 +89,7 @@ void LCodeGen::RestoreCallerDoubles() {
BitVector::Iterator save_iterator(doubles); BitVector::Iterator save_iterator(doubles);
int count = 0; int count = 0;
while (!save_iterator.Done()) { while (!save_iterator.Done()) {
__ lfd(DoubleRegister::FromAllocationIndex(save_iterator.Current()), __ lfd(DoubleRegister::from_code(save_iterator.Current()),
MemOperand(sp, count * kDoubleSize)); MemOperand(sp, count * kDoubleSize));
save_iterator.Advance(); save_iterator.Advance();
count++; count++;
...@@ -394,13 +394,13 @@ bool LCodeGen::GenerateSafepointTable() { ...@@ -394,13 +394,13 @@ bool LCodeGen::GenerateSafepointTable() {
} }
Register LCodeGen::ToRegister(int index) const { Register LCodeGen::ToRegister(int code) const {
return Register::FromAllocationIndex(index); return Register::from_code(code);
} }
DoubleRegister LCodeGen::ToDoubleRegister(int index) const { DoubleRegister LCodeGen::ToDoubleRegister(int code) const {
return DoubleRegister::FromAllocationIndex(index); return DoubleRegister::from_code(code);
} }
......
...@@ -137,7 +137,7 @@ class LCodeGen : public LCodeGenBase { ...@@ -137,7 +137,7 @@ class LCodeGen : public LCodeGenBase {
Scope* scope() const { return scope_; } Scope* scope() const { return scope_; }
Register scratch0() { return r11; } Register scratch0() { return kLithiumScratch; }
DoubleRegister double_scratch0() { return kScratchDoubleReg; } DoubleRegister double_scratch0() { return kScratchDoubleReg; }
LInstruction* GetNextInstruction(); LInstruction* GetNextInstruction();
......
...@@ -457,14 +457,13 @@ LPlatformChunk* LChunkBuilder::Build() { ...@@ -457,14 +457,13 @@ LPlatformChunk* LChunkBuilder::Build() {
LUnallocated* LChunkBuilder::ToUnallocated(Register reg) { LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER, reg.code());
Register::ToAllocationIndex(reg));
} }
LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) { LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
return new (zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, return new (zone())
DoubleRegister::ToAllocationIndex(reg)); LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, reg.code());
} }
......
...@@ -12,9 +12,11 @@ ...@@ -12,9 +12,11 @@
#include "src/bootstrapper.h" #include "src/bootstrapper.h"
#include "src/codegen.h" #include "src/codegen.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/ppc/macro-assembler-ppc.h" #include "src/register-configuration.h"
#include "src/runtime/runtime.h" #include "src/runtime/runtime.h"
#include "src/ppc/macro-assembler-ppc.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -564,7 +566,7 @@ void MacroAssembler::PopFixedFrame(Register marker_reg) { ...@@ -564,7 +566,7 @@ void MacroAssembler::PopFixedFrame(Register marker_reg) {
const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable; const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable;
const int MacroAssembler::kNumSafepointSavedRegisters = const int MacroAssembler::kNumSafepointSavedRegisters =
Register::kMaxNumAllocatableRegisters; Register::kNumAllocatable;
// Push and pop all registers that can hold pointers. // Push and pop all registers that can hold pointers.
void MacroAssembler::PushSafepointRegisters() { void MacroAssembler::PushSafepointRegisters() {
...@@ -623,7 +625,8 @@ MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) { ...@@ -623,7 +625,8 @@ MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
// General purpose registers are pushed last on the stack. // General purpose registers are pushed last on the stack.
int doubles_size = DoubleRegister::NumAllocatableRegisters() * kDoubleSize; const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
int doubles_size = config->num_allocatable_double_registers() * kDoubleSize;
int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
return MemOperand(sp, doubles_size + register_offset); return MemOperand(sp, doubles_size + register_offset);
} }
...@@ -863,7 +866,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { ...@@ -863,7 +866,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
MultiPushDoubles(kCallerSavedDoubles); MultiPushDoubles(kCallerSavedDoubles);
// Note that d0 will be accessible at // Note that d0 will be accessible at
// fp - ExitFrameConstants::kFrameSize - // fp - ExitFrameConstants::kFrameSize -
// kNumVolatileRegisters * kDoubleSize, // kNumCallerSavedDoubles * kDoubleSize,
// since the sp slot and code slot were pushed after the fp. // since the sp slot and code slot were pushed after the fp.
} }
...@@ -922,7 +925,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, ...@@ -922,7 +925,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
// Optionally restore all double registers. // Optionally restore all double registers.
if (save_doubles) { if (save_doubles) {
// Calculate the stack location of the saved doubles and restore them. // Calculate the stack location of the saved doubles and restore them.
const int kNumRegs = DoubleRegister::kNumVolatileRegisters; const int kNumRegs = kNumCallerSavedDoubles;
const int offset = const int offset =
(ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize);
addi(r6, fp, Operand(-offset)); addi(r6, fp, Operand(-offset));
...@@ -4250,8 +4253,10 @@ Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2, Register reg3, ...@@ -4250,8 +4253,10 @@ Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2, Register reg3,
if (reg5.is_valid()) regs |= reg5.bit(); if (reg5.is_valid()) regs |= reg5.bit();
if (reg6.is_valid()) regs |= reg6.bit(); if (reg6.is_valid()) regs |= reg6.bit();
for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { const RegisterConfiguration* config = RegisterConfiguration::ArchDefault();
Register candidate = Register::FromAllocationIndex(i); for (int i = 0; i < config->num_allocatable_general_registers(); ++i) {
int code = config->GetAllocatableGeneralCode(i);
Register candidate = Register::from_code(code);
if (regs & candidate.bit()) continue; if (regs & candidate.bit()) continue;
return candidate; return candidate;
} }
......
...@@ -14,17 +14,17 @@ namespace v8 { ...@@ -14,17 +14,17 @@ namespace v8 {
namespace internal { namespace internal {
// Give alias names to registers for calling conventions. // Give alias names to registers for calling conventions.
const Register kReturnRegister0 = {kRegister_r3_Code}; const Register kReturnRegister0 = {Register::kCode_r3};
const Register kReturnRegister1 = {kRegister_r4_Code}; const Register kReturnRegister1 = {Register::kCode_r4};
const Register kJSFunctionRegister = {kRegister_r4_Code}; const Register kJSFunctionRegister = {Register::kCode_r4};
const Register kContextRegister = {kRegister_r30_Code}; const Register kContextRegister = {Register::kCode_r30};
const Register kInterpreterAccumulatorRegister = {kRegister_r3_Code}; const Register kInterpreterAccumulatorRegister = {Register::kCode_r3};
const Register kInterpreterRegisterFileRegister = {kRegister_r14_Code}; const Register kInterpreterRegisterFileRegister = {Register::kCode_r14};
const Register kInterpreterBytecodeOffsetRegister = {kRegister_r15_Code}; const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r15};
const Register kInterpreterBytecodeArrayRegister = {kRegister_r16_Code}; const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r16};
const Register kInterpreterDispatchTableRegister = {kRegister_r17_Code}; const Register kInterpreterDispatchTableRegister = {Register::kCode_r17};
const Register kRuntimeCallFunctionRegister = {kRegister_r4_Code}; const Register kRuntimeCallFunctionRegister = {Register::kCode_r4};
const Register kRuntimeCallArgCountRegister = {kRegister_r3_Code}; const Register kRuntimeCallArgCountRegister = {Register::kCode_r3};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Static helper functions // Static helper functions
......
...@@ -164,7 +164,7 @@ bool PPCDebugger::GetValue(const char* desc, intptr_t* value) { ...@@ -164,7 +164,7 @@ bool PPCDebugger::GetValue(const char* desc, intptr_t* value) {
bool PPCDebugger::GetFPDoubleValue(const char* desc, double* value) { bool PPCDebugger::GetFPDoubleValue(const char* desc, double* value) {
int regnum = FPRegisters::Number(desc); int regnum = DoubleRegisters::Number(desc);
if (regnum != kNoRegister) { if (regnum != kNoRegister) {
*value = sim_->get_double_from_d_register(regnum); *value = sim_->get_double_from_d_register(regnum);
return true; return true;
...@@ -313,7 +313,8 @@ void PPCDebugger::Debug() { ...@@ -313,7 +313,8 @@ void PPCDebugger::Debug() {
if (strcmp(arg1, "all") == 0) { if (strcmp(arg1, "all") == 0) {
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
value = GetRegisterValue(i); value = GetRegisterValue(i);
PrintF(" %3s: %08" V8PRIxPTR, Registers::Name(i), value); PrintF(" %3s: %08" V8PRIxPTR,
Register::from_code(i).ToString(), value);
if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 && if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
(i % 2) == 0) { (i % 2) == 0) {
dvalue = GetRegisterPairDoubleValue(i); dvalue = GetRegisterPairDoubleValue(i);
...@@ -332,7 +333,7 @@ void PPCDebugger::Debug() { ...@@ -332,7 +333,7 @@ void PPCDebugger::Debug() {
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
value = GetRegisterValue(i); value = GetRegisterValue(i);
PrintF(" %3s: %08" V8PRIxPTR " %11" V8PRIdPTR, PrintF(" %3s: %08" V8PRIxPTR " %11" V8PRIdPTR,
Registers::Name(i), value, value); Register::from_code(i).ToString(), value, value);
if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 && if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
(i % 2) == 0) { (i % 2) == 0) {
dvalue = GetRegisterPairDoubleValue(i); dvalue = GetRegisterPairDoubleValue(i);
...@@ -351,7 +352,8 @@ void PPCDebugger::Debug() { ...@@ -351,7 +352,8 @@ void PPCDebugger::Debug() {
for (int i = 0; i < DoubleRegister::kNumRegisters; i++) { for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
dvalue = GetFPDoubleRegisterValue(i); dvalue = GetFPDoubleRegisterValue(i);
uint64_t as_words = bit_cast<uint64_t>(dvalue); uint64_t as_words = bit_cast<uint64_t>(dvalue);
PrintF("%3s: %f 0x%08x %08x\n", FPRegisters::Name(i), dvalue, PrintF("%3s: %f 0x%08x %08x\n",
DoubleRegister::from_code(i).ToString(), dvalue,
static_cast<uint32_t>(as_words >> 32), static_cast<uint32_t>(as_words >> 32),
static_cast<uint32_t>(as_words & 0xffffffff)); static_cast<uint32_t>(as_words & 0xffffffff));
} }
......
...@@ -69,6 +69,10 @@ class ArchDefaultRegisterConfiguration : public RegisterConfiguration { ...@@ -69,6 +69,10 @@ class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
kMaxAllocatableGeneralRegisterCount, kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount, kMaxAllocatableDoubleRegisterCount,
kMaxAllocatableDoubleRegisterCount, kMaxAllocatableDoubleRegisterCount,
#elif V8_TARGET_ARCH_PPC
kMaxAllocatableGeneralRegisterCount,
kMaxAllocatableDoubleRegisterCount,
kMaxAllocatableDoubleRegisterCount,
#else #else
GetAllocatableGeneralRegisterCount(), GetAllocatableGeneralRegisterCount(),
GetAllocatableDoubleRegisterCount(), GetAllocatableDoubleRegisterCount(),
......
...@@ -99,7 +99,7 @@ TEST(DisasmPPC) { ...@@ -99,7 +99,7 @@ TEST(DisasmPPC) {
COMPARE(addc(r9, r7, r9), "7d274814 addc r9, r7, r9"); COMPARE(addc(r9, r7, r9), "7d274814 addc r9, r7, r9");
COMPARE(addic(r3, r5, Operand(20)), "30650014 addic r3, r5, 20"); COMPARE(addic(r3, r5, Operand(20)), "30650014 addic r3, r5, 20");
COMPARE(addi(r0, ip, Operand(63)), "380c003f addi r0, r12, 63"); COMPARE(addi(r0, ip, Operand(63)), "380c003f addi r0, ip, 63");
COMPARE(add(r5, r7, r0), "7ca70214 add r5, r7, r0"); COMPARE(add(r5, r7, r0), "7ca70214 add r5, r7, r0");
COMPARE(addze(r0, r0, LeaveOE, SetRC), "7c000195 addze. r0, r0"); COMPARE(addze(r0, r0, LeaveOE, SetRC), "7c000195 addze. r0, r0");
COMPARE(andi(r0, r3, Operand(4)), "70600004 andi. r0, r3, 4"); COMPARE(andi(r0, r3, Operand(4)), "70600004 andi. r0, r3, 4");
...@@ -130,8 +130,8 @@ TEST(DisasmPPC) { ...@@ -130,8 +130,8 @@ TEST(DisasmPPC) {
COMPARE(lfd(d0, MemOperand(sp, 128)), "c8010080 lfd d0, 128(sp)"); COMPARE(lfd(d0, MemOperand(sp, 128)), "c8010080 lfd d0, 128(sp)");
COMPARE(li(r0, Operand(16)), "38000010 li r0, 16"); COMPARE(li(r0, Operand(16)), "38000010 li r0, 16");
COMPARE(lis(r8, Operand(22560)), "3d005820 lis r8, 22560"); COMPARE(lis(r8, Operand(22560)), "3d005820 lis r8, 22560");
COMPARE(lwz(ip, MemOperand(r19, 44)), "8193002c lwz r12, 44(r19)"); COMPARE(lwz(ip, MemOperand(r19, 44)), "8193002c lwz ip, 44(r19)");
COMPARE(lwzx(r0, MemOperand(r5, ip)), "7c05602e lwzx r0, r5, r12"); COMPARE(lwzx(r0, MemOperand(r5, ip)), "7c05602e lwzx r0, r5, ip");
COMPARE(mflr(r0), "7c0802a6 mflr r0"); COMPARE(mflr(r0), "7c0802a6 mflr r0");
COMPARE(mr(r15, r4), "7c8f2378 mr r15, r4"); COMPARE(mr(r15, r4), "7c8f2378 mr r15, r4");
COMPARE(mtctr(r0), "7c0903a6 mtctr r0"); COMPARE(mtctr(r0), "7c0903a6 mtctr r0");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment