Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Unified Diff: src/arm/assembler-arm.cc

Issue 3107027: Fix incorrect encoding of single and double precision registers for some... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/assembler-arm.cc
===================================================================
--- src/arm/assembler-arm.cc (revision 5347)
+++ src/arm/assembler-arm.cc (working copy)
@@ -1809,6 +1809,7 @@
// Support for VFP.
+
void Assembler::vldr(const DwVfpRegister dst,
const Register base,
int offset,
@@ -1838,7 +1839,9 @@
ASSERT(offset % 4 == 0);
ASSERT((offset / 4) < 256);
ASSERT(offset >= 0);
- emit(cond | 0xD9*B20 | base.code()*B16 | dst.code()*B12 |
+ int sd, d;
+ dst.split_code(&sd, &d);
+ emit(cond | d*B22 | 0xD9*B20 | base.code()*B16 | sd*B12 |
0xA*B8 | ((offset / 4) & 255));
}
@@ -1872,7 +1875,9 @@
ASSERT(offset % 4 == 0);
ASSERT((offset / 4) < 256);
ASSERT(offset >= 0);
- emit(cond | 0xD8*B20 | base.code()*B16 | src.code()*B12 |
+ int sd, d;
+ src.split_code(&sd, &d);
+ emit(cond | d*B22 | 0xD8*B20 | base.code()*B16 | sd*B12 |
0xA*B8 | ((offset / 4) & 255));
}
@@ -1979,8 +1984,10 @@
// Sd = Sm
// Instruction details available in ARM DDI 0406B, A8-642.
ASSERT(CpuFeatures::IsEnabled(VFP3));
- emit(cond | 0xE*B24 | 0xB*B20 |
- dst.code()*B12 | 0x5*B9 | B6 | src.code());
+ int sd, d, sm, m;
+ dst.split_code(&sd, &d);
+ src.split_code(&sm, &m);
+ emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm);
}
@@ -2034,8 +2041,9 @@
// Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
ASSERT(CpuFeatures::IsEnabled(VFP3));
ASSERT(!src.is(pc));
- emit(cond | 0xE*B24 | (dst.code() >> 1)*B16 |
- src.code()*B12 | 0xA*B8 | (0x1 & dst.code())*B7 | B4);
+ int sn, n;
+ dst.split_code(&sn, &n);
+ emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4);
}
@@ -2048,8 +2056,9 @@
// Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
ASSERT(CpuFeatures::IsEnabled(VFP3));
ASSERT(!dst.is(pc));
- emit(cond | 0xE*B24 | B20 | (src.code() >> 1)*B16 |
- dst.code()*B12 | 0xA*B8 | (0x1 & src.code())*B7 | B4);
+ int sn, n;
+ src.split_code(&sn, &n);
+ emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4);
}
@@ -2099,16 +2108,21 @@
}
-// Depending on split_last_bit split binary representation of reg_code into Vm:M
-// or M:Vm form (where M is single bit).
-static void SplitRegCode(bool split_last_bit,
+// Split five bit reg_code based on size of reg_type.
+// 32-bit register codes are Vm:M
+// 64-bit register codes are M:Vm
+// where Vm is four bits, and M is a single bit.
+static void SplitRegCode(VFPType reg_type,
int reg_code,
int* vm,
int* m) {
- if (split_last_bit) {
+ ASSERT((reg_code >= 0) && (reg_code <= 31));
+ if (IsIntegerVFPType(reg_type) || !IsDoubleVFPType(reg_type)) {
+ // 32 bit type.
*m = reg_code & 0x1;
*vm = reg_code >> 1;
} else {
+ // 64 bit type.
*m = (reg_code & 0x10) >> 4;
*vm = reg_code & 0x0F;
}
@@ -2121,6 +2135,11 @@
const VFPType src_type,
const int src_code,
const Condition cond) {
+ ASSERT(src_type != dst_type);
+ int D, Vd, M, Vm;
+ SplitRegCode(src_type, src_code, &Vm, &M);
+ SplitRegCode(dst_type, dst_code, &Vd, &D);
+
if (IsIntegerVFPType(dst_type) || IsIntegerVFPType(src_type)) {
// Conversion between IEEE floating point and 32-bit integer.
// Instruction details available in ARM DDI 0406B, A8.6.295.
@@ -2128,22 +2147,17 @@
// Vd(15-12) | 101(11-9) | sz(8) | op(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
ASSERT(!IsIntegerVFPType(dst_type) || !IsIntegerVFPType(src_type));
- int sz, opc2, D, Vd, M, Vm, op;
+ int sz, opc2, op;
if (IsIntegerVFPType(dst_type)) {
opc2 = IsSignedVFPType(dst_type) ? 0x5 : 0x4;
sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
op = 1; // round towards zero
- SplitRegCode(!IsDoubleVFPType(src_type), src_code, &Vm, &M);
- SplitRegCode(true, dst_code, &Vd, &D);
} else {
ASSERT(IsIntegerVFPType(src_type));
-
opc2 = 0x0;
sz = IsDoubleVFPType(dst_type) ? 0x1 : 0x0;
op = IsSignedVFPType(src_type) ? 0x1 : 0x0;
- SplitRegCode(true, src_code, &Vm, &M);
- SplitRegCode(!IsDoubleVFPType(dst_type), dst_code, &Vd, &D);
}
return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | B19 | opc2*B16 |
@@ -2153,13 +2167,7 @@
// Instruction details available in ARM DDI 0406B, A8.6.298.
// cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0111(19-16) |
// Vd(15-12) | 101(11-9) | sz(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
- int sz, D, Vd, M, Vm;
-
- ASSERT(IsDoubleVFPType(dst_type) != IsDoubleVFPType(src_type));
- sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
- SplitRegCode(IsDoubleVFPType(src_type), dst_code, &Vd, &D);
- SplitRegCode(!IsDoubleVFPType(src_type), src_code, &Vm, &M);
-
+ int sz = IsDoubleVFPType(src_type) ? 0x1 : 0x0;
return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 |
Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm);
}
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698