Chromium Code Reviews| Index: src/arm/assembler-arm.cc |
| diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc |
| index 47ea0e20666e2f44621e42959b7094067c43ed79..558f48b0fa0586c7d8636bec6c80a569f6da653f 100644 |
| --- a/src/arm/assembler-arm.cc |
| +++ b/src/arm/assembler-arm.cc |
| @@ -1680,19 +1680,22 @@ void Assembler::vldr(const DwVfpRegister dst, |
| int offset, |
| const Condition cond) { |
| // Ddst = MEM(Rbase + offset). |
| - // Instruction details available in ARM DDI 0406A, A8-628. |
| - // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | |
| - // Vdst(15-12) | 1011(11-8) | offset |
| + // Instruction details available in ARM DDI 0406C.b, A8-924. |
| + // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) | |
| + // Vd(15-12) | 1011(11-8) | offset |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| int u = 1; |
| if (offset < 0) { |
| offset = -offset; |
| u = 0; |
| } |
| + ASSERT(offset >= 0); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| ASSERT(offset >= 0); |
| if ((offset % 4) == 0 && (offset / 4) < 256) { |
| - emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | |
| + emit(cond | 0xD*B24 | u*B23 | d*B22 | B20 | base.code()*B16 | vd*B12 | |
| 0xB*B8 | ((offset / 4) & 255)); |
| } else { |
| // Larger offsets must be handled by computing the correct address |
| @@ -1703,7 +1706,7 @@ void Assembler::vldr(const DwVfpRegister dst, |
| } else { |
| sub(ip, base, Operand(offset)); |
| } |
| - emit(cond | 0xD1*B20 | ip.code()*B16 | dst.code()*B12 | 0xB*B8); |
| + emit(cond | 0xD*B24 | d*B22 | B20 | ip.code()*B16 | vd*B12 | 0xB*B8); |
| } |
| } |
| @@ -1766,9 +1769,9 @@ void Assembler::vstr(const DwVfpRegister src, |
| int offset, |
| const Condition cond) { |
| // MEM(Rbase + offset) = Dsrc. |
| - // Instruction details available in ARM DDI 0406A, A8-786. |
| - // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | |
| - // Vsrc(15-12) | 1011(11-8) | (offset/4) |
| + // Instruction details available in ARM DDI 0406C.b, A8-1082. |
| + // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) | |
| + // Vd(15-12) | 1011(11-8) | (offset/4) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| int u = 1; |
| if (offset < 0) { |
| @@ -1776,9 +1779,12 @@ void Assembler::vstr(const DwVfpRegister src, |
| u = 0; |
| } |
| ASSERT(offset >= 0); |
| + int vd, d; |
| + src.split_code(&vd, &d); |
| + |
| if ((offset % 4) == 0 && (offset / 4) < 256) { |
| - emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | |
| - 0xB*B8 | ((offset / 4) & 255)); |
| + emit(cond | 0xD*B24 | u*B23 | d*B22 | base.code()*B16 | vd*B12 | 0xB*B8 | |
| + ((offset / 4) & 255)); |
| } else { |
| // Larger offsets must be handled by computing the correct address |
| // in the ip register. |
| @@ -1788,7 +1794,7 @@ void Assembler::vstr(const DwVfpRegister src, |
| } else { |
| sub(ip, base, Operand(offset)); |
| } |
| - emit(cond | 0xD0*B20 | ip.code()*B16 | src.code()*B12 | 0xB*B8); |
| + emit(cond | 0xD*B24 | d*B22 | ip.code()*B16 | vd*B12 | 0xB*B8); |
| } |
| } |
| @@ -1850,9 +1856,9 @@ void Assembler::vldm(BlockAddrMode am, |
| DwVfpRegister first, |
| DwVfpRegister last, |
| Condition cond) { |
| - // Instruction details available in ARM DDI 0406A, A8-626. |
| + // Instruction details available in ARM DDI 0406C.b, A8-922. |
| // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
| - // first(15-12) | 1010(11-8) | (count * 2) |
| + // first(15-12) | 1011(11-8) | (count * 2) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| ASSERT_LE(first.code(), last.code()); |
| ASSERT(am == ia || am == ia_w || am == db_w); |
| @@ -1872,7 +1878,7 @@ void Assembler::vstm(BlockAddrMode am, |
| DwVfpRegister first, |
| DwVfpRegister last, |
| Condition cond) { |
| - // Instruction details available in ARM DDI 0406A, A8-784. |
| + // Instruction details available in ARM DDI 0406C.b, A8-1080. |
| // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
| // first(15-12) | 1011(11-8) | (count * 2) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| @@ -2008,14 +2014,28 @@ void Assembler::vmov(const DwVfpRegister dst, |
| mov(ip, Operand(lo)); |
| if (scratch.is(no_reg)) { |
| - // Move the low part of the double into the lower of the corresponsing S |
| - // registers of D register dst. |
| - vmov(dst.low(), ip, cond); |
| - |
| - // Move the high part of the double into the higher of the corresponsing S |
| - // registers of D register dst. |
| - mov(ip, Operand(hi)); |
| - vmov(dst.high(), ip, cond); |
| + if (dst.code() < 16) { |
| + // Move the low part of the double into the lower of the corresponsing S |
| + // registers of D register dst. |
| + vmov(dst.low(), ip, cond); |
| + |
| + // Move the high part of the double into the higher of the corresponsing S |
| + // registers of D register dst. |
| + mov(ip, Operand(hi)); |
| + vmov(dst.high(), ip, cond); |
| + } else { |
| + // There are no corresponding S registers for D register dst. |
| + |
| + // FIXME: We need a way to do this! For now, let's use the stack. |
| + // Push r4, r5 on the stack. |
|
Rodolph Perfetta
2012/12/05 00:42:10
There is an instruction which lets you move an ARM
hans
2012/12/05 14:12:58
Awesome, I'll just use vmov.32 then. Thanks!
|
| + push(r4); |
| + push(r5); |
| + mov(r4, Operand(lo)); |
| + mov(r5, Operand(hi)); |
| + vmov(dst, r4, r5, cond); |
| + pop(r5); |
| + pop(r4); |
| + } |
| } else { |
| // Move the low and high parts of the double to a D register in one |
| // instruction. |
| @@ -2043,10 +2063,16 @@ void Assembler::vmov(const DwVfpRegister dst, |
| const DwVfpRegister src, |
| const Condition cond) { |
| // Dd = Dm |
| - // Instruction details available in ARM DDI 0406B, A8-642. |
| + // Instruction details available in ARM DDI 0406C.b, A8-938. |
| + // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
| + // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 | 0xB*B20 | |
| - dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vm, m; |
| + src.split_code(&vm, &m); |
| + emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 | |
| + vm); |
| } |
| @@ -2055,13 +2081,15 @@ void Assembler::vmov(const DwVfpRegister dst, |
| const Register src2, |
| const Condition cond) { |
| // Dm = <Rt,Rt2>. |
| - // Instruction details available in ARM DDI 0406A, A8-646. |
| + // Instruction details available in ARM DDI 0406C.b, A8-948. |
| // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | |
| // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| ASSERT(!src1.is(pc) && !src2.is(pc)); |
| + int vm, m; |
| + dst.split_code(&vm, &m); |
| emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
| - src1.code()*B12 | 0xB*B8 | B4 | dst.code()); |
| + src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
| } |
| @@ -2070,13 +2098,15 @@ void Assembler::vmov(const Register dst1, |
| const DwVfpRegister src, |
| const Condition cond) { |
| // <Rt,Rt2> = Dm. |
| - // Instruction details available in ARM DDI 0406A, A8-646. |
| + // Instruction details available in ARM DDI 0406C.b, A8-948. |
| // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | |
| // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| ASSERT(!dst1.is(pc) && !dst2.is(pc)); |
| + int vm, m; |
| + src.split_code(&vm, &m); |
| emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
| - dst1.code()*B12 | 0xB*B8 | B4 | src.code()); |
| + dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
| } |
| @@ -2289,18 +2319,33 @@ void Assembler::vcvt_f32_f64(const SwVfpRegister dst, |
| void Assembler::vneg(const DwVfpRegister dst, |
| const DwVfpRegister src, |
| const Condition cond) { |
| + // Instruction details available in ARM DDI 0406C.b, A8-968. |
| + // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | |
| + // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | |
| - 0x5*B9 | B8 | B6 | src.code()); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vm, m; |
| + src.split_code(&vm, &m); |
| + |
| + emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
| + m*B5 | vm); |
| } |
| void Assembler::vabs(const DwVfpRegister dst, |
| const DwVfpRegister src, |
| const Condition cond) { |
| + // Instruction details available in ARM DDI 0406C.b, A8-524. |
| + // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
| + // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0). |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | |
| - 0x5*B9 | B8 | 0x3*B6 | src.code()); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vm, m; |
| + src.split_code(&vm, &m); |
| + emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 | |
| + m*B5 | vm); |
| } |
| @@ -2310,12 +2355,18 @@ void Assembler::vadd(const DwVfpRegister dst, |
| const Condition cond) { |
| // Dd = vadd(Dn, Dm) double precision floating point addition. |
| // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| - // Instruction details available in ARM DDI 0406A, A8-536. |
| - // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | |
| - // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
| + // Instruction details available in ARM DDI 0406C.b, A8-830. |
| + // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
| + // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
| - dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vn, n; |
| + src1.split_code(&vn, &n); |
| + int vm, m; |
| + src2.split_code(&vm, &m); |
| + emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
| + n*B7 | m*B5 | vm); |
| } |
| @@ -2325,12 +2376,18 @@ void Assembler::vsub(const DwVfpRegister dst, |
| const Condition cond) { |
| // Dd = vsub(Dn, Dm) double precision floating point subtraction. |
| // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| - // Instruction details available in ARM DDI 0406A, A8-784. |
| - // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | |
| - // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0) |
| + // Instruction details available in ARM DDI 0406C.b, A8-1086. |
| + // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
| + // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
| - dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vn, n; |
| + src1.split_code(&vn, &n); |
| + int vm, m; |
| + src2.split_code(&vm, &m); |
| + emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
| + n*B7 | B6 | m*B5 | vm); |
| } |
| @@ -2340,12 +2397,18 @@ void Assembler::vmul(const DwVfpRegister dst, |
| const Condition cond) { |
| // Dd = vmul(Dn, Dm) double precision floating point multiplication. |
| // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| - // Instruction details available in ARM DDI 0406A, A8-784. |
| - // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | |
| - // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
| + // Instruction details available in ARM DDI 0406C.b, A8-960. |
| + // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) | |
| + // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | |
| - dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vn, n; |
| + src1.split_code(&vn, &n); |
| + int vm, m; |
| + src2.split_code(&vm, &m); |
| + emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
| + n*B7 | m*B5 | vm); |
| } |
| @@ -2353,13 +2416,17 @@ void Assembler::vmla(const DwVfpRegister dst, |
| const DwVfpRegister src1, |
| const DwVfpRegister src2, |
| const Condition cond) { |
| - // Instruction details available in ARM DDI 0406C.b, A8-892. |
| - // cond(31-28) | 11100(27-23) | D=?(22) | 00(21-20) | Vn(19-16) | |
| - // Vd(15-12) | 101(11-9) | sz(8)=1 | N=?(7) | op(6)=0 | M=?(5) | 0(4) | |
| - // Vm(3-0) |
| - unsigned x = (cond | 0x1C*B23 | src1.code()*B16 | |
| - dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
| - emit(x); |
| + // Instruction details available in ARM DDI 0406C.b, A8-932. |
| + // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) | |
| + // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=0(6) | M(5) | 0(4) | Vm(3-0) |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vn, n; |
| + src1.split_code(&vn, &n); |
| + int vm, m; |
| + src2.split_code(&vm, &m); |
| + emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | |
| + vm); |
| } |
| @@ -2369,12 +2436,18 @@ void Assembler::vdiv(const DwVfpRegister dst, |
| const Condition cond) { |
| // Dd = vdiv(Dn, Dm) double precision floating point division. |
| // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| - // Instruction details available in ARM DDI 0406A, A8-584. |
| - // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | |
| - // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
| + // Instruction details available in ARM DDI 0406C.b, A8-882. |
| + // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) | |
| + // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 | B23 | src1.code()*B16 | |
| - dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vn, n; |
| + src1.split_code(&vn, &n); |
| + int vm, m; |
| + src2.split_code(&vm, &m); |
| + emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | |
| + vm); |
| } |
| @@ -2382,26 +2455,31 @@ void Assembler::vcmp(const DwVfpRegister src1, |
| const DwVfpRegister src2, |
| const Condition cond) { |
| // vcmp(Dd, Dm) double precision floating point comparison. |
| - // Instruction details available in ARM DDI 0406A, A8-570. |
| - // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | |
| - // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0) |
| + // Instruction details available in ARM DDI 0406C.b, A8-864. |
| + // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) | |
| + // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | |
| - src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
| + int vd, d; |
| + src1.split_code(&vd, &d); |
| + int vm, m; |
| + src2.split_code(&vm, &m); |
| + emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
| + m*B5 | vm); |
| } |
| void Assembler::vcmp(const DwVfpRegister src1, |
| const double src2, |
| const Condition cond) { |
| - // vcmp(Dd, Dm) double precision floating point comparison. |
| - // Instruction details available in ARM DDI 0406A, A8-570. |
| - // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) | |
| - // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0) |
| + // vcmp(Dd, #0.0) double precision floating point comparison. |
| + // Instruction details available in ARM DDI 0406C.b, A8-864. |
| + // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | |
| + // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| ASSERT(src2 == 0.0); |
| - emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | |
| - src1.code()*B12 | 0x5*B9 | B8 | B6); |
| + int vd, d; |
| + src1.split_code(&vd, &d); |
| + emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6); |
| } |
| @@ -2428,11 +2506,16 @@ void Assembler::vmrs(Register dst, Condition cond) { |
| void Assembler::vsqrt(const DwVfpRegister dst, |
| const DwVfpRegister src, |
| const Condition cond) { |
| - // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) | |
| - // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0) |
| + // Instruction details available in ARM DDI 0406C.b, A8-1058. |
| + // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) | |
| + // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) |
| ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| - emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | |
| - dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); |
| + int vd, d; |
| + dst.split_code(&vd, &d); |
| + int vm, m; |
| + src.split_code(&vm, &m); |
| + emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | |
| + m*B5 | vm); |
| } |