| Index: src/arm/assembler-arm.h
|
| diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
|
| index 3b9bb804fd331c144563d6522239c6967933a817..1e2082ec36d4c6d0e0db639d645271825cd2eba4 100644
|
| --- a/src/arm/assembler-arm.h
|
| +++ b/src/arm/assembler-arm.h
|
| @@ -190,24 +190,45 @@ struct SwVfpRegister {
|
|
|
| // Double word VFP register.
|
| struct DwVfpRegister {
|
| - static const int kNumRegisters = 16;
|
| + static const int kNumRegisters = 32; // XXX
|
| // A few double registers are reserved: one as a scratch register and one to
|
| // hold 0.0, that does not fit in the immediate field of vmov instructions.
|
| // d14: 0.0
|
| // d15: scratch register.
|
| static const int kNumReservedRegisters = 2;
|
| - static const int kNumAllocatableRegisters = kNumRegisters -
|
| - kNumReservedRegisters;
|
| + static int NumAvailableRegisters() {
|
| + return 32; // XXX: 16 or 32, detected at runtime.
|
| + }
|
| + static int NumAllocatableRegisters() {
|
| + return NumAvailableRegisters() - kNumReservedRegisters;
|
| + }
|
| + static DwVfpRegister FirstCalleeSavedReg() { return from_code(8); }
|
| + static DwVfpRegister LastCalleeSavedReg() {
|
| + return from_code(15);
|
| + }
|
| + static DwVfpRegister ZeroReg() {
|
| + return from_code(14);
|
| + }
|
| + static DwVfpRegister ScratchReg() {
|
| + return from_code(15);
|
| + }
|
| + static int NumCalleeSaved() {
|
| + return LastCalleeSavedReg().code() - FirstCalleeSavedReg().code() + 1;
|
| + }
|
|
|
| inline static int ToAllocationIndex(DwVfpRegister reg);
|
|
|
| static DwVfpRegister FromAllocationIndex(int index) {
|
| - ASSERT(index >= 0 && index < kNumAllocatableRegisters);
|
| - return from_code(index);
|
| + ASSERT(index >= 0 && index < NumAllocatableRegisters());
|
| + if (index < ZeroReg().code())
|
| + return from_code(index);
|
| + return from_code(index + kNumReservedRegisters);
|
| }
|
|
|
| static const char* AllocationIndexToString(int index) {
|
| - ASSERT(index >= 0 && index < kNumAllocatableRegisters);
|
| + ASSERT(index >= 0 && index < NumAllocatableRegisters());
|
| + if (index >= ZeroReg().code())
|
| + index += kNumReservedRegisters;
|
| const char* const names[] = {
|
| "d0",
|
| "d1",
|
| @@ -222,7 +243,25 @@ struct DwVfpRegister {
|
| "d10",
|
| "d11",
|
| "d12",
|
| - "d13"
|
| + "d13",
|
| + "d14",
|
| + "d15",
|
| + "d16",
|
| + "d17",
|
| + "d18",
|
| + "d19",
|
| + "d20",
|
| + "d21",
|
| + "d22",
|
| + "d23",
|
| + "d24",
|
| + "d25",
|
| + "d26",
|
| + "d27",
|
| + "d28",
|
| + "d29",
|
| + "d30",
|
| + "d31"
|
| };
|
| return names[index];
|
| }
|
| @@ -232,10 +271,12 @@ struct DwVfpRegister {
|
| return r;
|
| }
|
|
|
| - // Supporting d0 to d15, can be later extended to d31.
|
| - bool is_valid() const { return 0 <= code_ && code_ < 16; }
|
| + bool is_valid() const {
|
| + return 0 <= code_ && code_ < NumAvailableRegisters();
|
| + }
|
| bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
|
| SwVfpRegister low() const {
|
| + ASSERT(code_ < 16);
|
| SwVfpRegister reg;
|
| reg.code_ = code_ * 2;
|
|
|
| @@ -243,6 +284,7 @@ struct DwVfpRegister {
|
| return reg;
|
| }
|
| SwVfpRegister high() const {
|
| + ASSERT(code_ < 16);
|
| SwVfpRegister reg;
|
| reg.code_ = (code_ * 2) + 1;
|
|
|
| @@ -322,14 +364,22 @@ const DwVfpRegister d12 = { 12 };
|
| const DwVfpRegister d13 = { 13 };
|
| const DwVfpRegister d14 = { 14 };
|
| const DwVfpRegister d15 = { 15 };
|
| -
|
| -// Aliases for double registers. Defined using #define instead of
|
| -// "static const DwVfpRegister&" because Clang complains otherwise when a
|
| -// compilation unit that includes this header doesn't use the variables.
|
| -#define kFirstCalleeSavedDoubleReg d8
|
| -#define kLastCalleeSavedDoubleReg d15
|
| -#define kDoubleRegZero d14
|
| -#define kScratchDoubleReg d15
|
| +const DwVfpRegister d16 = { 16 };
|
| +const DwVfpRegister d17 = { 17 };
|
| +const DwVfpRegister d18 = { 18 };
|
| +const DwVfpRegister d19 = { 19 };
|
| +const DwVfpRegister d20 = { 20 };
|
| +const DwVfpRegister d21 = { 21 };
|
| +const DwVfpRegister d22 = { 22 };
|
| +const DwVfpRegister d23 = { 23 };
|
| +const DwVfpRegister d24 = { 24 };
|
| +const DwVfpRegister d25 = { 25 };
|
| +const DwVfpRegister d26 = { 26 };
|
| +const DwVfpRegister d27 = { 27 };
|
| +const DwVfpRegister d28 = { 28 };
|
| +const DwVfpRegister d29 = { 29 };
|
| +const DwVfpRegister d30 = { 30 };
|
| +const DwVfpRegister d31 = { 31 };
|
|
|
|
|
| // Coprocessor register
|
| @@ -994,10 +1044,7 @@ class Assembler : public AssemblerBase {
|
| LFlag l = Short); // v5 and above
|
|
|
| // Support for VFP.
|
| - // All these APIs support S0 to S31 and D0 to D15.
|
| - // Currently these APIs do not support extended D registers, i.e, D16 to D31.
|
| - // However, some simple modifications can allow
|
| - // these APIs to support D16 to D31.
|
| + // All these APIs support S0 to S31 and D0 to D31.
|
|
|
| void vldr(const DwVfpRegister dst,
|
| const Register base,
|
|
|