OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 24 matching lines...) Expand all Loading... |
35 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 35 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
36 | 36 |
37 #include "v8.h" | 37 #include "v8.h" |
38 | 38 |
39 #include "arm/assembler-arm-inl.h" | 39 #include "arm/assembler-arm-inl.h" |
40 #include "serialize.h" | 40 #include "serialize.h" |
41 | 41 |
42 namespace v8 { | 42 namespace v8 { |
43 namespace internal { | 43 namespace internal { |
44 | 44 |
| 45 // Safe default is no features. |
| 46 uint64_t CpuFeatures::supported_ = 0; |
| 47 uint64_t CpuFeatures::enabled_ = 0; |
| 48 |
| 49 void CpuFeatures::Probe() { |
| 50 // Perform runtime detection of VFP. |
| 51 static const char* descriptive_file_linux = "/proc/cpuinfo"; |
| 52 |
| 53 #if !defined(__arm__) || (defined(__VFP_FP__) && !defined(__SOFTFP__)) |
| 54 // The supported & enabled flags for VFP are set to true for the following |
| 55 // conditions, even without runtime detection of VFP: |
| 56 // (1) For the simulator=arm build, always use VFP since |
| 57 // the arm simulator has VFP support. |
| 58 // (2) If V8 is being compiled with GCC with the vfp option turned on, |
| 59 // always use VFP since the build system assumes that V8 will run on |
| 60 // a platform that has VFP hardware. |
| 61 supported_ |= static_cast<uint64_t>(1) << VFP3; |
| 62 enabled_ |= static_cast<uint64_t>(1) << VFP3; |
| 63 #endif |
| 64 |
| 65 if (OS::fgrep_vfp(descriptive_file_linux, "vfp")) { |
| 66 // This implementation also sets the VFP flags if |
| 67 // runtime detection of VFP returns true. |
| 68 supported_ |= static_cast<uint64_t>(1) << VFP3; |
| 69 enabled_ |= static_cast<uint64_t>(1) << VFP3; |
| 70 } |
| 71 } |
| 72 |
45 // ----------------------------------------------------------------------------- | 73 // ----------------------------------------------------------------------------- |
46 // Implementation of Register and CRegister | 74 // Implementation of Register and CRegister |
47 | 75 |
48 Register no_reg = { -1 }; | 76 Register no_reg = { -1 }; |
49 | 77 |
50 Register r0 = { 0 }; | 78 Register r0 = { 0 }; |
51 Register r1 = { 1 }; | 79 Register r1 = { 1 }; |
52 Register r2 = { 2 }; | 80 Register r2 = { 2 }; |
53 Register r3 = { 3 }; | 81 Register r3 = { 3 }; |
54 Register r4 = { 4 }; | 82 Register r4 = { 4 }; |
(...skipping 22 matching lines...) Expand all Loading... |
77 CRegister cr7 = { 7 }; | 105 CRegister cr7 = { 7 }; |
78 CRegister cr8 = { 8 }; | 106 CRegister cr8 = { 8 }; |
79 CRegister cr9 = { 9 }; | 107 CRegister cr9 = { 9 }; |
80 CRegister cr10 = { 10 }; | 108 CRegister cr10 = { 10 }; |
81 CRegister cr11 = { 11 }; | 109 CRegister cr11 = { 11 }; |
82 CRegister cr12 = { 12 }; | 110 CRegister cr12 = { 12 }; |
83 CRegister cr13 = { 13 }; | 111 CRegister cr13 = { 13 }; |
84 CRegister cr14 = { 14 }; | 112 CRegister cr14 = { 14 }; |
85 CRegister cr15 = { 15 }; | 113 CRegister cr15 = { 15 }; |
86 | 114 |
| 115 // Support for the VFP registers s0 to s31 (d0 to d15). |
| 116 // Note that "sN:sM" is the same as "dN/2". |
| 117 Register s0 = { 0 }; |
| 118 Register s1 = { 1 }; |
| 119 Register s2 = { 2 }; |
| 120 Register s3 = { 3 }; |
| 121 Register s4 = { 4 }; |
| 122 Register s5 = { 5 }; |
| 123 Register s6 = { 6 }; |
| 124 Register s7 = { 7 }; |
| 125 Register s8 = { 8 }; |
| 126 Register s9 = { 9 }; |
| 127 Register s10 = { 10 }; |
| 128 Register s11 = { 11 }; |
| 129 Register s12 = { 12 }; |
| 130 Register s13 = { 13 }; |
| 131 Register s14 = { 14 }; |
| 132 Register s15 = { 15 }; |
| 133 Register s16 = { 16 }; |
| 134 Register s17 = { 17 }; |
| 135 Register s18 = { 18 }; |
| 136 Register s19 = { 19 }; |
| 137 Register s20 = { 20 }; |
| 138 Register s21 = { 21 }; |
| 139 Register s22 = { 22 }; |
| 140 Register s23 = { 23 }; |
| 141 Register s24 = { 24 }; |
| 142 Register s25 = { 25 }; |
| 143 Register s26 = { 26 }; |
| 144 Register s27 = { 27 }; |
| 145 Register s28 = { 28 }; |
| 146 Register s29 = { 29 }; |
| 147 Register s30 = { 30 }; |
| 148 Register s31 = { 31 }; |
| 149 |
| 150 Register d0 = { 0 }; |
| 151 Register d1 = { 1 }; |
| 152 Register d2 = { 2 }; |
| 153 Register d3 = { 3 }; |
| 154 Register d4 = { 4 }; |
| 155 Register d5 = { 5 }; |
| 156 Register d6 = { 6 }; |
| 157 Register d7 = { 7 }; |
| 158 Register d8 = { 8 }; |
| 159 Register d9 = { 9 }; |
| 160 Register d10 = { 10 }; |
| 161 Register d11 = { 11 }; |
| 162 Register d12 = { 12 }; |
| 163 Register d13 = { 13 }; |
| 164 Register d14 = { 14 }; |
| 165 Register d15 = { 15 }; |
87 | 166 |
88 // ----------------------------------------------------------------------------- | 167 // ----------------------------------------------------------------------------- |
89 // Implementation of RelocInfo | 168 // Implementation of RelocInfo |
90 | 169 |
91 const int RelocInfo::kApplyMask = 0; | 170 const int RelocInfo::kApplyMask = 0; |
92 | 171 |
93 | 172 |
94 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { | 173 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { |
95 // Patch the code at the current address with the supplied instructions. | 174 // Patch the code at the current address with the supplied instructions. |
96 Instr* pc = reinterpret_cast<Instr*>(pc_); | 175 Instr* pc = reinterpret_cast<Instr*>(pc_); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 W = 1 << 21, // writeback base register (or leave unchanged) | 275 W = 1 << 21, // writeback base register (or leave unchanged) |
197 A = 1 << 21, // accumulate in multiply instruction (or not) | 276 A = 1 << 21, // accumulate in multiply instruction (or not) |
198 B = 1 << 22, // unsigned byte (or word) | 277 B = 1 << 22, // unsigned byte (or word) |
199 N = 1 << 22, // long (or short) | 278 N = 1 << 22, // long (or short) |
200 U = 1 << 23, // positive (or negative) offset/index | 279 U = 1 << 23, // positive (or negative) offset/index |
201 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) | 280 P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) |
202 I = 1 << 25, // immediate shifter operand (or not) | 281 I = 1 << 25, // immediate shifter operand (or not) |
203 | 282 |
204 B4 = 1 << 4, | 283 B4 = 1 << 4, |
205 B5 = 1 << 5, | 284 B5 = 1 << 5, |
| 285 B6 = 1 << 6, |
206 B7 = 1 << 7, | 286 B7 = 1 << 7, |
207 B8 = 1 << 8, | 287 B8 = 1 << 8, |
| 288 B9 = 1 << 9, |
208 B12 = 1 << 12, | 289 B12 = 1 << 12, |
209 B16 = 1 << 16, | 290 B16 = 1 << 16, |
| 291 B18 = 1 << 18, |
| 292 B19 = 1 << 19, |
210 B20 = 1 << 20, | 293 B20 = 1 << 20, |
211 B21 = 1 << 21, | 294 B21 = 1 << 21, |
212 B22 = 1 << 22, | 295 B22 = 1 << 22, |
213 B23 = 1 << 23, | 296 B23 = 1 << 23, |
214 B24 = 1 << 24, | 297 B24 = 1 << 24, |
215 B25 = 1 << 25, | 298 B25 = 1 << 25, |
216 B26 = 1 << 26, | 299 B26 = 1 << 26, |
217 B27 = 1 << 27, | 300 B27 = 1 << 27, |
218 | 301 |
219 // Instruction bit masks | 302 // Instruction bit masks |
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 | 1357 |
1275 | 1358 |
1276 void Assembler::stc2(Coprocessor coproc, | 1359 void Assembler::stc2(Coprocessor coproc, |
1277 CRegister crd, | 1360 CRegister crd, |
1278 Register rn, | 1361 Register rn, |
1279 int option, | 1362 int option, |
1280 LFlag l) { // v5 and above | 1363 LFlag l) { // v5 and above |
1281 stc(coproc, crd, rn, option, l, static_cast<Condition>(nv)); | 1364 stc(coproc, crd, rn, option, l, static_cast<Condition>(nv)); |
1282 } | 1365 } |
1283 | 1366 |
| 1367 // Support for VFP. |
| 1368 void Assembler::fmdrr(const Register dst, |
| 1369 const Register src1, |
| 1370 const Register src2, |
| 1371 const SBit s, |
| 1372 const Condition cond) { |
| 1373 // Dm = <Rt,Rt2>. |
| 1374 // Instruction details available in ARM DDI 0406A, A8-646. |
| 1375 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | |
| 1376 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
| 1377 |
| 1378 ASSERT(!src1.is(pc) && !src2.is(pc)); |
| 1379 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
| 1380 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); |
| 1381 } |
| 1382 |
| 1383 |
| 1384 void Assembler::fmrrd(const Register dst1, |
| 1385 const Register dst2, |
| 1386 const Register src, |
| 1387 const SBit s, |
| 1388 const Condition cond) { |
| 1389 // <Rt,Rt2> = Dm. |
| 1390 // Instruction details available in ARM DDI 0406A, A8-646. |
| 1391 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | |
| 1392 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
| 1393 |
| 1394 ASSERT(!dst1.is(pc) && !dst2.is(pc)); |
| 1395 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
| 1396 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); |
| 1397 } |
| 1398 |
| 1399 |
| 1400 void Assembler::fmsr(const Register dst, |
| 1401 const Register src, |
| 1402 const SBit s, |
| 1403 const Condition cond) { |
| 1404 // Sn = Rt. |
| 1405 // Instruction details available in ARM DDI 0406A, A8-642. |
| 1406 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | |
| 1407 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
| 1408 |
| 1409 ASSERT(!src.is(pc)); |
| 1410 emit(cond | 0xE*B24 | (dst.code() >> 1)*B16 | |
| 1411 src.code()*B12 | 0xA*B8 | (0x1 & dst.code())*B7 | B4); |
| 1412 } |
| 1413 |
| 1414 |
| 1415 void Assembler::fmrs(const Register dst, |
| 1416 const Register src, |
| 1417 const SBit s, |
| 1418 const Condition cond) { |
| 1419 // Rt = Sn. |
| 1420 // Instruction details available in ARM DDI 0406A, A8-642. |
| 1421 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | |
| 1422 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
| 1423 |
| 1424 ASSERT(!dst.is(pc)); |
| 1425 emit(cond | 0xE*B24 | B20 | (src.code() >> 1)*B16 | |
| 1426 dst.code()*B12 | 0xA*B8 | (0x1 & src.code())*B7 | B4); |
| 1427 } |
| 1428 |
| 1429 |
| 1430 void Assembler::fsitod(const Register dst, |
| 1431 const Register src, |
| 1432 const SBit s, |
| 1433 const Condition cond) { |
| 1434 // Dd = Sm (integer in Sm converted to IEEE 64-bit doubles in Dd). |
| 1435 // Instruction details available in ARM DDI 0406A, A8-576. |
| 1436 // cond(31-28) | 11101(27-23)| D=?(22) | 11(21-20) | 1(19) |opc2=000(18-16) | |
| 1437 // Vd(15-12) | 101(11-9) | sz(8)=1 | op(7)=1 | 1(6) | M=?(5) | 0(4) | Vm(3-0) |
| 1438 |
| 1439 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B19 | |
| 1440 dst.code()*B12 | 0x5*B9 | B8 | B7 | B6 | |
| 1441 (0x1 & src.code())*B5 | (src.code() >> 1)); |
| 1442 } |
| 1443 |
| 1444 |
| 1445 void Assembler::ftosid(const Register dst, |
| 1446 const Register src, |
| 1447 const SBit s, |
| 1448 const Condition cond) { |
| 1449 // Sd = Dm (IEEE 64-bit doubles in Dm converted to 32 bit integer in Sd). |
| 1450 // Instruction details available in ARM DDI 0406A, A8-576. |
| 1451 // cond(31-28) | 11101(27-23)| D=?(22) | 11(21-20) | 1(19) | opc2=101(18-16)| |
| 1452 // Vd(15-12) | 101(11-9) | sz(8)=1 | op(7)=? | 1(6) | M=?(5) | 0(4) | Vm(3-0) |
| 1453 |
| 1454 emit(cond | 0xE*B24 | B23 |(0x1 & dst.code())*B22 | |
| 1455 0x3*B20 | B19 | 0x5*B16 | (dst.code() >> 1)*B12 | |
| 1456 0x5*B9 | B8 | B7 | B6 | src.code()); |
| 1457 } |
| 1458 |
| 1459 |
| 1460 void Assembler::faddd(const Register dst, |
| 1461 const Register src1, |
| 1462 const Register src2, |
| 1463 const SBit s, |
| 1464 const Condition cond) { |
| 1465 // Dd = faddd(Dn, Dm) double precision floating point addition. |
| 1466 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| 1467 // Instruction details available in ARM DDI 0406A, A8-536. |
| 1468 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | |
| 1469 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
| 1470 |
| 1471 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
| 1472 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
| 1473 } |
| 1474 |
| 1475 |
| 1476 void Assembler::fsubd(const Register dst, |
| 1477 const Register src1, |
| 1478 const Register src2, |
| 1479 const SBit s, |
| 1480 const Condition cond) { |
| 1481 // Dd = fsubd(Dn, Dm) double precision floating point subtraction. |
| 1482 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| 1483 // Instruction details available in ARM DDI 0406A, A8-784. |
| 1484 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | |
| 1485 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0) |
| 1486 |
| 1487 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
| 1488 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
| 1489 } |
| 1490 |
| 1491 |
| 1492 void Assembler::fmuld(const Register dst, |
| 1493 const Register src1, |
| 1494 const Register src2, |
| 1495 const SBit s, |
| 1496 const Condition cond) { |
| 1497 // Dd = fmuld(Dn, Dm) double precision floating point multiplication. |
| 1498 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| 1499 // Instruction details available in ARM DDI 0406A, A8-784. |
| 1500 // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | |
| 1501 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
| 1502 |
| 1503 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | |
| 1504 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
| 1505 } |
| 1506 |
| 1507 |
| 1508 void Assembler::fdivd(const Register dst, |
| 1509 const Register src1, |
| 1510 const Register src2, |
| 1511 const SBit s, |
| 1512 const Condition cond) { |
| 1513 // Dd = fdivd(Dn, Dm) double precision floating point division. |
| 1514 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
| 1515 // Instruction details available in ARM DDI 0406A, A8-584. |
| 1516 // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | |
| 1517 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0) |
| 1518 |
| 1519 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | |
| 1520 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
| 1521 } |
| 1522 |
| 1523 |
| 1524 void Assembler::fcmp(const Register src1, |
| 1525 const Register src2, |
| 1526 const SBit s, |
| 1527 const Condition cond) { |
| 1528 // vcmp(Dd, Dm) double precision floating point comparison. |
| 1529 // Instruction details available in ARM DDI 0406A, A8-570. |
| 1530 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | |
| 1531 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=? | 1(6) | M(5)=? | 0(4) | Vm(3-0) |
| 1532 |
| 1533 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | |
| 1534 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
| 1535 } |
| 1536 |
| 1537 |
| 1538 void Assembler::vmrs(Register dst, Condition cond) { |
| 1539 // Instruction details available in ARM DDI 0406A, A8-652. |
| 1540 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | |
| 1541 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
| 1542 |
| 1543 emit(cond | 0xE*B24 | 0xF*B20 | B16 | |
| 1544 dst.code()*B12 | 0xA*B8 | B4); |
| 1545 } |
| 1546 |
1284 | 1547 |
1285 // Pseudo instructions | 1548 // Pseudo instructions |
1286 void Assembler::lea(Register dst, | 1549 void Assembler::lea(Register dst, |
1287 const MemOperand& x, | 1550 const MemOperand& x, |
1288 SBit s, | 1551 SBit s, |
1289 Condition cond) { | 1552 Condition cond) { |
1290 int am = x.am_; | 1553 int am = x.am_; |
1291 if (!x.rm_.is_valid()) { | 1554 if (!x.rm_.is_valid()) { |
1292 // immediate offset | 1555 // immediate offset |
1293 if ((am & P) == 0) // post indexing | 1556 if ((am & P) == 0) // post indexing |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1536 bind(&after_pool); | 1799 bind(&after_pool); |
1537 } | 1800 } |
1538 | 1801 |
1539 // Since a constant pool was just emitted, move the check offset forward by | 1802 // Since a constant pool was just emitted, move the check offset forward by |
1540 // the standard interval. | 1803 // the standard interval. |
1541 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 1804 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
1542 } | 1805 } |
1543 | 1806 |
1544 | 1807 |
1545 } } // namespace v8::internal | 1808 } } // namespace v8::internal |
OLD | NEW |