Index: src/arm/assembler-arm.cc |
=================================================================== |
--- src/arm/assembler-arm.cc (revision 3208) |
+++ src/arm/assembler-arm.cc (working copy) |
@@ -42,6 +42,34 @@ |
namespace v8 { |
namespace internal { |
+// Safe default is no features. |
+uint64_t CpuFeatures::supported_ = 0; |
+uint64_t CpuFeatures::enabled_ = 0; |
+ |
+void CpuFeatures::Probe() { |
+ // Perform runtime detection of VFP. |
+ static const char* descriptive_file_linux = "/proc/cpuinfo"; |
+ |
+ #if !defined(__arm__) || (defined(__VFP_FP__) && !defined(__SOFTFP__)) |
+ // The supported & enabled flags for VFP are set to true for the following |
+ // conditions, even without runtime detection of VFP: |
+ // (1) For the simulator=arm build, always use VFP since |
+ // the arm simulator has VFP support. |
+ // (2) If V8 is being compiled with GCC with the vfp option turned on, |
+ // always use VFP since the build system assumes that V8 will run on |
+ // a platform that has VFP hardware. |
+ supported_ |= static_cast<uint64_t>(1) << VFP3; |
+ enabled_ |= static_cast<uint64_t>(1) << VFP3; |
+ #endif |
+ |
+ if (OS::fgrep_vfp(descriptive_file_linux, "vfp")) { |
+ // This implementation also sets the VFP flags if |
+ // runtime detection of VFP returns true. |
+ supported_ |= static_cast<uint64_t>(1) << VFP3; |
+ enabled_ |= static_cast<uint64_t>(1) << VFP3; |
+ } |
+} |
+ |
// ----------------------------------------------------------------------------- |
// Implementation of Register and CRegister |
@@ -84,7 +112,58 @@ |
CRegister cr14 = { 14 }; |
CRegister cr15 = { 15 }; |
+// Support for the VFP registers s0 to s31 (d0 to d15). |
+// Note that "sN:sM" is the same as "dN/2". |
+Register s0 = { 0 }; |
+Register s1 = { 1 }; |
+Register s2 = { 2 }; |
+Register s3 = { 3 }; |
+Register s4 = { 4 }; |
+Register s5 = { 5 }; |
+Register s6 = { 6 }; |
+Register s7 = { 7 }; |
+Register s8 = { 8 }; |
+Register s9 = { 9 }; |
+Register s10 = { 10 }; |
+Register s11 = { 11 }; |
+Register s12 = { 12 }; |
+Register s13 = { 13 }; |
+Register s14 = { 14 }; |
+Register s15 = { 15 }; |
+Register s16 = { 16 }; |
+Register s17 = { 17 }; |
+Register s18 = { 18 }; |
+Register s19 = { 19 }; |
+Register s20 = { 20 }; |
+Register s21 = { 21 }; |
+Register s22 = { 22 }; |
+Register s23 = { 23 }; |
+Register s24 = { 24 }; |
+Register s25 = { 25 }; |
+Register s26 = { 26 }; |
+Register s27 = { 27 }; |
+Register s28 = { 28 }; |
+Register s29 = { 29 }; |
+Register s30 = { 30 }; |
+Register s31 = { 31 }; |
+Register d0 = { 0 }; |
+Register d1 = { 1 }; |
+Register d2 = { 2 }; |
+Register d3 = { 3 }; |
+Register d4 = { 4 }; |
+Register d5 = { 5 }; |
+Register d6 = { 6 }; |
+Register d7 = { 7 }; |
+Register d8 = { 8 }; |
+Register d9 = { 9 }; |
+Register d10 = { 10 }; |
+Register d11 = { 11 }; |
+Register d12 = { 12 }; |
+Register d13 = { 13 }; |
+Register d14 = { 14 }; |
+Register d15 = { 15 }; |
+ |
// ----------------------------------------------------------------------------- |
// Implementation of RelocInfo |
@@ -203,10 +282,14 @@ |
B4 = 1 << 4, |
B5 = 1 << 5, |
+ B6 = 1 << 6, |
B7 = 1 << 7, |
B8 = 1 << 8, |
+ B9 = 1 << 9, |
B12 = 1 << 12, |
B16 = 1 << 16, |
+ B18 = 1 << 18, |
+ B19 = 1 << 19, |
B20 = 1 << 20, |
B21 = 1 << 21, |
B22 = 1 << 22, |
@@ -1281,7 +1364,187 @@ |
stc(coproc, crd, rn, option, l, static_cast<Condition>(nv)); |
} |
+// Support for VFP. |
+void Assembler::fmdrr(const Register dst, |
+ const Register src1, |
+ const Register src2, |
+ const SBit s, |
+ const Condition cond) { |
+ // Dm = <Rt,Rt2>. |
+ // Instruction details available in ARM DDI 0406A, A8-646. |
+ // 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(!src1.is(pc) && !src2.is(pc)); |
+ emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
+ src1.code()*B12 | 0xB*B8 | B4 | dst.code()); |
+} |
+ |
+ |
+void Assembler::fmrrd(const Register dst1, |
+ const Register dst2, |
+ const Register src, |
+ const SBit s, |
+ const Condition cond) { |
+ // <Rt,Rt2> = Dm. |
+ // Instruction details available in ARM DDI 0406A, A8-646. |
+ // 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(!dst1.is(pc) && !dst2.is(pc)); |
+ emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
+ dst1.code()*B12 | 0xB*B8 | B4 | src.code()); |
+} |
+ |
+ |
+void Assembler::fmsr(const Register dst, |
+ const Register src, |
+ const SBit s, |
+ const Condition cond) { |
+ // Sn = Rt. |
+ // Instruction details available in ARM DDI 0406A, A8-642. |
+ // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | |
+ // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
+ |
+ ASSERT(!src.is(pc)); |
+ emit(cond | 0xE*B24 | (dst.code() >> 1)*B16 | |
+ src.code()*B12 | 0xA*B8 | (0x1 & dst.code())*B7 | B4); |
+} |
+ |
+ |
+void Assembler::fmrs(const Register dst, |
+ const Register src, |
+ const SBit s, |
+ const Condition cond) { |
+ // Rt = Sn. |
+ // Instruction details available in ARM DDI 0406A, A8-642. |
+ // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | |
+ // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
+ |
+ ASSERT(!dst.is(pc)); |
+ emit(cond | 0xE*B24 | B20 | (src.code() >> 1)*B16 | |
+ dst.code()*B12 | 0xA*B8 | (0x1 & src.code())*B7 | B4); |
+} |
+ |
+ |
+void Assembler::fsitod(const Register dst, |
+ const Register src, |
+ const SBit s, |
+ const Condition cond) { |
+ // Dd = Sm (integer in Sm converted to IEEE 64-bit doubles in Dd). |
+ // Instruction details available in ARM DDI 0406A, A8-576. |
+ // cond(31-28) | 11101(27-23)| D=?(22) | 11(21-20) | 1(19) |opc2=000(18-16) | |
+ // Vd(15-12) | 101(11-9) | sz(8)=1 | op(7)=1 | 1(6) | M=?(5) | 0(4) | Vm(3-0) |
+ |
+ emit(cond | 0xE*B24 | B23 | 0x3*B20 | B19 | |
+ dst.code()*B12 | 0x5*B9 | B8 | B7 | B6 | |
+ (0x1 & src.code())*B5 | (src.code() >> 1)); |
+} |
+ |
+ |
+void Assembler::ftosid(const Register dst, |
+ const Register src, |
+ const SBit s, |
+ const Condition cond) { |
+ // Sd = Dm (IEEE 64-bit doubles in Dm converted to 32 bit integer in Sd). |
+ // Instruction details available in ARM DDI 0406A, A8-576. |
+ // cond(31-28) | 11101(27-23)| D=?(22) | 11(21-20) | 1(19) | opc2=101(18-16)| |
+ // Vd(15-12) | 101(11-9) | sz(8)=1 | op(7)=? | 1(6) | M=?(5) | 0(4) | Vm(3-0) |
+ |
+ emit(cond | 0xE*B24 | B23 |(0x1 & dst.code())*B22 | |
+ 0x3*B20 | B19 | 0x5*B16 | (dst.code() >> 1)*B12 | |
+ 0x5*B9 | B8 | B7 | B6 | src.code()); |
+} |
+ |
+ |
+void Assembler::faddd(const Register dst, |
+ const Register src1, |
+ const Register src2, |
+ const SBit s, |
+ const Condition cond) { |
+ // Dd = faddd(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) |
+ |
+ emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
+ dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
+} |
+ |
+ |
+void Assembler::fsubd(const Register dst, |
+ const Register src1, |
+ const Register src2, |
+ const SBit s, |
+ const Condition cond) { |
+ // Dd = fsubd(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) |
+ |
+ emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
+ dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
+} |
+ |
+ |
+void Assembler::fmuld(const Register dst, |
+ const Register src1, |
+ const Register src2, |
+ const SBit s, |
+ const Condition cond) { |
+ // Dd = fmuld(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) |
+ |
+ emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | |
+ dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
+} |
+ |
+ |
+void Assembler::fdivd(const Register dst, |
+ const Register src1, |
+ const Register src2, |
+ const SBit s, |
+ const Condition cond) { |
+ // Dd = fdivd(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) |
+ |
+ emit(cond | 0xE*B24 | B23 | src1.code()*B16 | |
+ dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
+} |
+ |
+ |
+void Assembler::fcmp(const Register src1, |
+ const Register src2, |
+ const SBit s, |
+ 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)=? | 1(6) | M(5)=? | 0(4) | Vm(3-0) |
+ |
+ emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | |
+ src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
+} |
+ |
+ |
+void Assembler::vmrs(Register dst, Condition cond) { |
+ // Instruction details available in ARM DDI 0406A, A8-652. |
+ // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | |
+ // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
+ |
+ emit(cond | 0xE*B24 | 0xF*B20 | B16 | |
+ dst.code()*B12 | 0xA*B8 | B4); |
+} |
+ |
+ |
// Pseudo instructions |
void Assembler::lea(Register dst, |
const MemOperand& x, |