Index: src/arm/assembler-arm.h |
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h |
index 3b9bb804fd331c144563d6522239c6967933a817..4dbd515eac53ec7d28d46d8b9658928317ed7783 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; |
// 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); |
+ ASSERT(index >= 0 && index < NumAllocatableRegisters()); |
+ if (index >= ZeroReg().code()) |
+ return from_code(index + kNumReservedRegisters); |
return from_code(index); |
} |
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, |
@@ -1066,6 +1113,10 @@ class Assembler : public AssemblerBase { |
const DwVfpRegister src, |
const Condition cond = al); |
void vmov(const DwVfpRegister dst, |
+ int x, |
+ const Register src, |
+ const Condition cond = al); |
+ void vmov(const DwVfpRegister dst, |
const Register src1, |
const Register src2, |
const Condition cond = al); |