OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 | 1109 |
1110 | 1110 |
1111 // Emulated condtional branches do not emit a nop in the branch delay slot. | 1111 // Emulated condtional branches do not emit a nop in the branch delay slot. |
1112 // | 1112 // |
1113 // BRANCH_ARGS_CHECK checks that conditional jump arguments are correct. | 1113 // BRANCH_ARGS_CHECK checks that conditional jump arguments are correct. |
1114 #define BRANCH_ARGS_CHECK(cond, rs, rt) ASSERT( \ | 1114 #define BRANCH_ARGS_CHECK(cond, rs, rt) ASSERT( \ |
1115 (cond == cc_always && rs.is(zero_reg) && rt.rm().is(zero_reg)) || \ | 1115 (cond == cc_always && rs.is(zero_reg) && rt.rm().is(zero_reg)) || \ |
1116 (cond != cc_always && (!rs.is(zero_reg) || !rt.rm().is(zero_reg)))) | 1116 (cond != cc_always && (!rs.is(zero_reg) || !rt.rm().is(zero_reg)))) |
1117 | 1117 |
1118 | 1118 |
| 1119 bool MacroAssembler::UseAbsoluteCodePointers() { |
| 1120 if (is_trampoline_emitted()) { |
| 1121 return true; |
| 1122 } else { |
| 1123 return false; |
| 1124 } |
| 1125 } |
| 1126 |
| 1127 |
1119 void MacroAssembler::Branch(int16_t offset, BranchDelaySlot bdslot) { | 1128 void MacroAssembler::Branch(int16_t offset, BranchDelaySlot bdslot) { |
| 1129 BranchShort(offset, bdslot); |
| 1130 } |
| 1131 |
| 1132 |
| 1133 void MacroAssembler::Branch(int16_t offset, Condition cond, Register rs, |
| 1134 const Operand& rt, |
| 1135 BranchDelaySlot bdslot) { |
| 1136 BranchShort(offset, cond, rs, rt, bdslot); |
| 1137 } |
| 1138 |
| 1139 |
| 1140 void MacroAssembler::Branch(Label* L, BranchDelaySlot bdslot) { |
| 1141 bool is_label_near = is_near(L); |
| 1142 if (UseAbsoluteCodePointers() && !is_label_near) { |
| 1143 Jr(L, bdslot); |
| 1144 } else { |
| 1145 BranchShort(L, bdslot); |
| 1146 } |
| 1147 } |
| 1148 |
| 1149 |
| 1150 void MacroAssembler::Branch(Label* L, Condition cond, Register rs, |
| 1151 const Operand& rt, |
| 1152 BranchDelaySlot bdslot) { |
| 1153 bool is_label_near = is_near(L); |
| 1154 if (UseAbsoluteCodePointers() && !is_label_near) { |
| 1155 Label skip; |
| 1156 Condition neg_cond = NegateCondition(cond); |
| 1157 BranchShort(&skip, neg_cond, rs, rt); |
| 1158 Jr(L, bdslot); |
| 1159 bind(&skip); |
| 1160 } else { |
| 1161 BranchShort(L, cond, rs, rt, bdslot); |
| 1162 } |
| 1163 } |
| 1164 |
| 1165 |
| 1166 void MacroAssembler::BranchShort(int16_t offset, BranchDelaySlot bdslot) { |
1120 b(offset); | 1167 b(offset); |
1121 | 1168 |
1122 // Emit a nop in the branch delay slot if required. | 1169 // Emit a nop in the branch delay slot if required. |
1123 if (bdslot == PROTECT) | 1170 if (bdslot == PROTECT) |
1124 nop(); | 1171 nop(); |
1125 } | 1172 } |
1126 | 1173 |
1127 | 1174 |
1128 void MacroAssembler::Branch(int16_t offset, Condition cond, Register rs, | 1175 void MacroAssembler::BranchShort(int16_t offset, Condition cond, Register rs, |
1129 const Operand& rt, | 1176 const Operand& rt, |
1130 BranchDelaySlot bdslot) { | 1177 BranchDelaySlot bdslot) { |
1131 BRANCH_ARGS_CHECK(cond, rs, rt); | 1178 BRANCH_ARGS_CHECK(cond, rs, rt); |
1132 ASSERT(!rs.is(zero_reg)); | 1179 ASSERT(!rs.is(zero_reg)); |
1133 Register r2 = no_reg; | 1180 Register r2 = no_reg; |
1134 Register scratch = at; | 1181 Register scratch = at; |
1135 | 1182 |
1136 if (rt.is_reg()) { | 1183 if (rt.is_reg()) { |
1137 // We don't want any other register but scratch clobbered. | 1184 // We don't want any other register but scratch clobbered. |
1138 ASSERT(!scratch.is(rs) && !scratch.is(rt.rm_)); | 1185 ASSERT(!scratch.is(rs) && !scratch.is(rt.rm_)); |
1139 r2 = rt.rm_; | 1186 r2 = rt.rm_; |
1140 switch (cond) { | 1187 switch (cond) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 case Ugreater_equal: | 1239 case Ugreater_equal: |
1193 if (r2.is(zero_reg)) { | 1240 if (r2.is(zero_reg)) { |
1194 bgez(rs, offset); | 1241 bgez(rs, offset); |
1195 } else { | 1242 } else { |
1196 sltu(scratch, rs, r2); | 1243 sltu(scratch, rs, r2); |
1197 beq(scratch, zero_reg, offset); | 1244 beq(scratch, zero_reg, offset); |
1198 } | 1245 } |
1199 break; | 1246 break; |
1200 case Uless: | 1247 case Uless: |
1201 if (r2.is(zero_reg)) { | 1248 if (r2.is(zero_reg)) { |
1202 b(offset); | 1249 // No code needs to be emitted. |
| 1250 return; |
1203 } else { | 1251 } else { |
1204 sltu(scratch, rs, r2); | 1252 sltu(scratch, rs, r2); |
1205 bne(scratch, zero_reg, offset); | 1253 bne(scratch, zero_reg, offset); |
1206 } | 1254 } |
1207 break; | 1255 break; |
1208 case Uless_equal: | 1256 case Uless_equal: |
1209 if (r2.is(zero_reg)) { | 1257 if (r2.is(zero_reg)) { |
1210 b(offset); | 1258 b(offset); |
1211 } else { | 1259 } else { |
1212 sltu(scratch, r2, rs); | 1260 sltu(scratch, r2, rs); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 break; | 1299 break; |
1252 case greater_equal: | 1300 case greater_equal: |
1253 if (rt.imm32_ == 0) { | 1301 if (rt.imm32_ == 0) { |
1254 bgez(rs, offset); | 1302 bgez(rs, offset); |
1255 } else if (is_int16(rt.imm32_)) { | 1303 } else if (is_int16(rt.imm32_)) { |
1256 slti(scratch, rs, rt.imm32_); | 1304 slti(scratch, rs, rt.imm32_); |
1257 beq(scratch, zero_reg, offset); | 1305 beq(scratch, zero_reg, offset); |
1258 } else { | 1306 } else { |
1259 r2 = scratch; | 1307 r2 = scratch; |
1260 li(r2, rt); | 1308 li(r2, rt); |
1261 sltu(scratch, rs, r2); | 1309 slt(scratch, rs, r2); |
1262 beq(scratch, zero_reg, offset); | 1310 beq(scratch, zero_reg, offset); |
1263 } | 1311 } |
1264 break; | 1312 break; |
1265 case less: | 1313 case less: |
1266 if (rt.imm32_ == 0) { | 1314 if (rt.imm32_ == 0) { |
1267 bltz(rs, offset); | 1315 bltz(rs, offset); |
1268 } else if (is_int16(rt.imm32_)) { | 1316 } else if (is_int16(rt.imm32_)) { |
1269 slti(scratch, rs, rt.imm32_); | 1317 slti(scratch, rs, rt.imm32_); |
1270 bne(scratch, zero_reg, offset); | 1318 bne(scratch, zero_reg, offset); |
1271 } else { | 1319 } else { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 beq(scratch, zero_reg, offset); | 1352 beq(scratch, zero_reg, offset); |
1305 } else { | 1353 } else { |
1306 r2 = scratch; | 1354 r2 = scratch; |
1307 li(r2, rt); | 1355 li(r2, rt); |
1308 sltu(scratch, rs, r2); | 1356 sltu(scratch, rs, r2); |
1309 beq(scratch, zero_reg, offset); | 1357 beq(scratch, zero_reg, offset); |
1310 } | 1358 } |
1311 break; | 1359 break; |
1312 case Uless: | 1360 case Uless: |
1313 if (rt.imm32_ == 0) { | 1361 if (rt.imm32_ == 0) { |
1314 b(offset); | 1362 // No code needs to be emitted. |
| 1363 return; |
1315 } else if (is_int16(rt.imm32_)) { | 1364 } else if (is_int16(rt.imm32_)) { |
1316 sltiu(scratch, rs, rt.imm32_); | 1365 sltiu(scratch, rs, rt.imm32_); |
1317 bne(scratch, zero_reg, offset); | 1366 bne(scratch, zero_reg, offset); |
1318 } else { | 1367 } else { |
1319 r2 = scratch; | 1368 r2 = scratch; |
1320 li(r2, rt); | 1369 li(r2, rt); |
1321 sltu(scratch, rs, r2); | 1370 sltu(scratch, rs, r2); |
1322 bne(scratch, zero_reg, offset); | 1371 bne(scratch, zero_reg, offset); |
1323 } | 1372 } |
1324 break; | 1373 break; |
(...skipping 10 matching lines...) Expand all Loading... |
1335 default: | 1384 default: |
1336 UNREACHABLE(); | 1385 UNREACHABLE(); |
1337 } | 1386 } |
1338 } | 1387 } |
1339 // Emit a nop in the branch delay slot if required. | 1388 // Emit a nop in the branch delay slot if required. |
1340 if (bdslot == PROTECT) | 1389 if (bdslot == PROTECT) |
1341 nop(); | 1390 nop(); |
1342 } | 1391 } |
1343 | 1392 |
1344 | 1393 |
1345 void MacroAssembler::Branch(Label* L, BranchDelaySlot bdslot) { | 1394 void MacroAssembler::BranchShort(Label* L, BranchDelaySlot bdslot) { |
1346 // We use branch_offset as an argument for the branch instructions to be sure | 1395 // We use branch_offset as an argument for the branch instructions to be sure |
1347 // it is called just before generating the branch instruction, as needed. | 1396 // it is called just before generating the branch instruction, as needed. |
1348 | 1397 |
1349 b(shifted_branch_offset(L, false)); | 1398 b(shifted_branch_offset(L, false)); |
1350 | 1399 |
1351 // Emit a nop in the branch delay slot if required. | 1400 // Emit a nop in the branch delay slot if required. |
1352 if (bdslot == PROTECT) | 1401 if (bdslot == PROTECT) |
1353 nop(); | 1402 nop(); |
1354 } | 1403 } |
1355 | 1404 |
1356 | 1405 |
1357 void MacroAssembler::Branch(Label* L, Condition cond, Register rs, | 1406 void MacroAssembler::BranchShort(Label* L, Condition cond, Register rs, |
1358 const Operand& rt, | 1407 const Operand& rt, |
1359 BranchDelaySlot bdslot) { | 1408 BranchDelaySlot bdslot) { |
1360 BRANCH_ARGS_CHECK(cond, rs, rt); | 1409 BRANCH_ARGS_CHECK(cond, rs, rt); |
1361 | 1410 |
1362 int32_t offset; | 1411 int32_t offset; |
1363 Register r2 = no_reg; | 1412 Register r2 = no_reg; |
1364 Register scratch = at; | 1413 Register scratch = at; |
1365 if (rt.is_reg()) { | 1414 if (rt.is_reg()) { |
1366 r2 = rt.rm_; | 1415 r2 = rt.rm_; |
1367 // Be careful to always use shifted_branch_offset only just before the | 1416 // Be careful to always use shifted_branch_offset only just before the |
1368 // branch instruction, as the location will be remember for patching the | 1417 // branch instruction, as the location will be remember for patching the |
1369 // target. | 1418 // target. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1437 offset = shifted_branch_offset(L, false); | 1486 offset = shifted_branch_offset(L, false); |
1438 bgez(rs, offset); | 1487 bgez(rs, offset); |
1439 } else { | 1488 } else { |
1440 sltu(scratch, rs, r2); | 1489 sltu(scratch, rs, r2); |
1441 offset = shifted_branch_offset(L, false); | 1490 offset = shifted_branch_offset(L, false); |
1442 beq(scratch, zero_reg, offset); | 1491 beq(scratch, zero_reg, offset); |
1443 } | 1492 } |
1444 break; | 1493 break; |
1445 case Uless: | 1494 case Uless: |
1446 if (r2.is(zero_reg)) { | 1495 if (r2.is(zero_reg)) { |
1447 offset = shifted_branch_offset(L, false); | 1496 // No code needs to be emitted. |
1448 b(offset); | 1497 return; |
1449 } else { | 1498 } else { |
1450 sltu(scratch, rs, r2); | 1499 sltu(scratch, rs, r2); |
1451 offset = shifted_branch_offset(L, false); | 1500 offset = shifted_branch_offset(L, false); |
1452 bne(scratch, zero_reg, offset); | 1501 bne(scratch, zero_reg, offset); |
1453 } | 1502 } |
1454 break; | 1503 break; |
1455 case Uless_equal: | 1504 case Uless_equal: |
1456 if (r2.is(zero_reg)) { | 1505 if (r2.is(zero_reg)) { |
1457 offset = shifted_branch_offset(L, false); | 1506 offset = shifted_branch_offset(L, false); |
1458 b(offset); | 1507 b(offset); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 if (rt.imm32_ == 0) { | 1552 if (rt.imm32_ == 0) { |
1504 offset = shifted_branch_offset(L, false); | 1553 offset = shifted_branch_offset(L, false); |
1505 bgez(rs, offset); | 1554 bgez(rs, offset); |
1506 } else if (is_int16(rt.imm32_)) { | 1555 } else if (is_int16(rt.imm32_)) { |
1507 slti(scratch, rs, rt.imm32_); | 1556 slti(scratch, rs, rt.imm32_); |
1508 offset = shifted_branch_offset(L, false); | 1557 offset = shifted_branch_offset(L, false); |
1509 beq(scratch, zero_reg, offset); | 1558 beq(scratch, zero_reg, offset); |
1510 } else { | 1559 } else { |
1511 r2 = scratch; | 1560 r2 = scratch; |
1512 li(r2, rt); | 1561 li(r2, rt); |
1513 sltu(scratch, rs, r2); | 1562 slt(scratch, rs, r2); |
1514 offset = shifted_branch_offset(L, false); | 1563 offset = shifted_branch_offset(L, false); |
1515 beq(scratch, zero_reg, offset); | 1564 beq(scratch, zero_reg, offset); |
1516 } | 1565 } |
1517 break; | 1566 break; |
1518 case less: | 1567 case less: |
1519 if (rt.imm32_ == 0) { | 1568 if (rt.imm32_ == 0) { |
1520 offset = shifted_branch_offset(L, false); | 1569 offset = shifted_branch_offset(L, false); |
1521 bltz(rs, offset); | 1570 bltz(rs, offset); |
1522 } else if (is_int16(rt.imm32_)) { | 1571 } else if (is_int16(rt.imm32_)) { |
1523 slti(scratch, rs, rt.imm32_); | 1572 slti(scratch, rs, rt.imm32_); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 } else { | 1616 } else { |
1568 r2 = scratch; | 1617 r2 = scratch; |
1569 li(r2, rt); | 1618 li(r2, rt); |
1570 sltu(scratch, rs, r2); | 1619 sltu(scratch, rs, r2); |
1571 offset = shifted_branch_offset(L, false); | 1620 offset = shifted_branch_offset(L, false); |
1572 beq(scratch, zero_reg, offset); | 1621 beq(scratch, zero_reg, offset); |
1573 } | 1622 } |
1574 break; | 1623 break; |
1575 case Uless: | 1624 case Uless: |
1576 if (rt.imm32_ == 0) { | 1625 if (rt.imm32_ == 0) { |
1577 offset = shifted_branch_offset(L, false); | 1626 // No code needs to be emitted. |
1578 b(offset); | 1627 return; |
1579 } else if (is_int16(rt.imm32_)) { | 1628 } else if (is_int16(rt.imm32_)) { |
1580 sltiu(scratch, rs, rt.imm32_); | 1629 sltiu(scratch, rs, rt.imm32_); |
1581 offset = shifted_branch_offset(L, false); | 1630 offset = shifted_branch_offset(L, false); |
1582 bne(scratch, zero_reg, offset); | 1631 bne(scratch, zero_reg, offset); |
1583 } else { | 1632 } else { |
1584 r2 = scratch; | 1633 r2 = scratch; |
1585 li(r2, rt); | 1634 li(r2, rt); |
1586 sltu(scratch, rs, r2); | 1635 sltu(scratch, rs, r2); |
1587 offset = shifted_branch_offset(L, false); | 1636 offset = shifted_branch_offset(L, false); |
1588 bne(scratch, zero_reg, offset); | 1637 bne(scratch, zero_reg, offset); |
(...skipping 16 matching lines...) Expand all Loading... |
1605 } | 1654 } |
1606 } | 1655 } |
1607 // Check that offset could actually hold on an int16_t. | 1656 // Check that offset could actually hold on an int16_t. |
1608 ASSERT(is_int16(offset)); | 1657 ASSERT(is_int16(offset)); |
1609 // Emit a nop in the branch delay slot if required. | 1658 // Emit a nop in the branch delay slot if required. |
1610 if (bdslot == PROTECT) | 1659 if (bdslot == PROTECT) |
1611 nop(); | 1660 nop(); |
1612 } | 1661 } |
1613 | 1662 |
1614 | 1663 |
| 1664 void MacroAssembler::BranchAndLink(int16_t offset, BranchDelaySlot bdslot) { |
| 1665 BranchAndLinkShort(offset, bdslot); |
| 1666 } |
| 1667 |
| 1668 |
| 1669 void MacroAssembler::BranchAndLink(int16_t offset, Condition cond, Register rs, |
| 1670 const Operand& rt, |
| 1671 BranchDelaySlot bdslot) { |
| 1672 BranchAndLinkShort(offset, cond, rs, rt, bdslot); |
| 1673 } |
| 1674 |
| 1675 |
| 1676 void MacroAssembler::BranchAndLink(Label* L, BranchDelaySlot bdslot) { |
| 1677 bool is_label_near = is_near(L); |
| 1678 if (UseAbsoluteCodePointers() && !is_label_near) { |
| 1679 Jalr(L, bdslot); |
| 1680 } else { |
| 1681 BranchAndLinkShort(L, bdslot); |
| 1682 } |
| 1683 } |
| 1684 |
| 1685 |
| 1686 void MacroAssembler::BranchAndLink(Label* L, Condition cond, Register rs, |
| 1687 const Operand& rt, |
| 1688 BranchDelaySlot bdslot) { |
| 1689 bool is_label_near = is_near(L); |
| 1690 if (UseAbsoluteCodePointers() && !is_label_near) { |
| 1691 Label skip; |
| 1692 Condition neg_cond = NegateCondition(cond); |
| 1693 BranchShort(&skip, neg_cond, rs, rt); |
| 1694 Jalr(L, bdslot); |
| 1695 bind(&skip); |
| 1696 } else { |
| 1697 BranchAndLinkShort(L, cond, rs, rt, bdslot); |
| 1698 } |
| 1699 } |
| 1700 |
| 1701 |
1615 // We need to use a bgezal or bltzal, but they can't be used directly with the | 1702 // We need to use a bgezal or bltzal, but they can't be used directly with the |
1616 // slt instructions. We could use sub or add instead but we would miss overflow | 1703 // slt instructions. We could use sub or add instead but we would miss overflow |
1617 // cases, so we keep slt and add an intermediate third instruction. | 1704 // cases, so we keep slt and add an intermediate third instruction. |
1618 void MacroAssembler::BranchAndLink(int16_t offset, | 1705 void MacroAssembler::BranchAndLinkShort(int16_t offset, |
1619 BranchDelaySlot bdslot) { | 1706 BranchDelaySlot bdslot) { |
1620 bal(offset); | 1707 bal(offset); |
1621 | 1708 |
1622 // Emit a nop in the branch delay slot if required. | 1709 // Emit a nop in the branch delay slot if required. |
1623 if (bdslot == PROTECT) | 1710 if (bdslot == PROTECT) |
1624 nop(); | 1711 nop(); |
1625 } | 1712 } |
1626 | 1713 |
1627 | 1714 |
1628 void MacroAssembler::BranchAndLink(int16_t offset, Condition cond, Register rs, | 1715 void MacroAssembler::BranchAndLinkShort(int16_t offset, Condition cond, |
1629 const Operand& rt, | 1716 Register rs, const Operand& rt, |
1630 BranchDelaySlot bdslot) { | 1717 BranchDelaySlot bdslot) { |
1631 BRANCH_ARGS_CHECK(cond, rs, rt); | 1718 BRANCH_ARGS_CHECK(cond, rs, rt); |
1632 Register r2 = no_reg; | 1719 Register r2 = no_reg; |
1633 Register scratch = at; | 1720 Register scratch = at; |
1634 | 1721 |
1635 if (rt.is_reg()) { | 1722 if (rt.is_reg()) { |
1636 r2 = rt.rm_; | 1723 r2 = rt.rm_; |
1637 } else if (cond != cc_always) { | 1724 } else if (cond != cc_always) { |
1638 r2 = scratch; | 1725 r2 = scratch; |
1639 li(r2, rt); | 1726 li(r2, rt); |
1640 } | 1727 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 | 1787 |
1701 default: | 1788 default: |
1702 UNREACHABLE(); | 1789 UNREACHABLE(); |
1703 } | 1790 } |
1704 // Emit a nop in the branch delay slot if required. | 1791 // Emit a nop in the branch delay slot if required. |
1705 if (bdslot == PROTECT) | 1792 if (bdslot == PROTECT) |
1706 nop(); | 1793 nop(); |
1707 } | 1794 } |
1708 | 1795 |
1709 | 1796 |
1710 void MacroAssembler::BranchAndLink(Label* L, BranchDelaySlot bdslot) { | 1797 void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) { |
1711 bal(shifted_branch_offset(L, false)); | 1798 bal(shifted_branch_offset(L, false)); |
1712 | 1799 |
1713 // Emit a nop in the branch delay slot if required. | 1800 // Emit a nop in the branch delay slot if required. |
1714 if (bdslot == PROTECT) | 1801 if (bdslot == PROTECT) |
1715 nop(); | 1802 nop(); |
1716 } | 1803 } |
1717 | 1804 |
1718 | 1805 |
1719 void MacroAssembler::BranchAndLink(Label* L, Condition cond, Register rs, | 1806 void MacroAssembler::BranchAndLinkShort(Label* L, Condition cond, Register rs, |
1720 const Operand& rt, | 1807 const Operand& rt, |
1721 BranchDelaySlot bdslot) { | 1808 BranchDelaySlot bdslot) { |
1722 BRANCH_ARGS_CHECK(cond, rs, rt); | 1809 BRANCH_ARGS_CHECK(cond, rs, rt); |
1723 | 1810 |
1724 int32_t offset; | 1811 int32_t offset; |
1725 Register r2 = no_reg; | 1812 Register r2 = no_reg; |
1726 Register scratch = at; | 1813 Register scratch = at; |
1727 if (rt.is_reg()) { | 1814 if (rt.is_reg()) { |
1728 r2 = rt.rm_; | 1815 r2 = rt.rm_; |
1729 } else if (cond != cc_always) { | 1816 } else if (cond != cc_always) { |
1730 r2 = scratch; | 1817 r2 = scratch; |
1731 li(r2, rt); | 1818 li(r2, rt); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 | 1894 |
1808 // Check that offset could actually hold on an int16_t. | 1895 // Check that offset could actually hold on an int16_t. |
1809 ASSERT(is_int16(offset)); | 1896 ASSERT(is_int16(offset)); |
1810 | 1897 |
1811 // Emit a nop in the branch delay slot if required. | 1898 // Emit a nop in the branch delay slot if required. |
1812 if (bdslot == PROTECT) | 1899 if (bdslot == PROTECT) |
1813 nop(); | 1900 nop(); |
1814 } | 1901 } |
1815 | 1902 |
1816 | 1903 |
| 1904 void MacroAssembler::J(Label* L, BranchDelaySlot bdslot) { |
| 1905 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 1906 |
| 1907 uint32_t imm28; |
| 1908 imm28 = jump_address(L); |
| 1909 imm28 &= kImm28Mask; |
| 1910 { BlockGrowBufferScope block_buf_growth(this); |
| 1911 // Buffer growth (and relocation) must be blocked for internal references |
| 1912 // until associated instructions are emitted and available to be patched. |
| 1913 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); |
| 1914 j(imm28); |
| 1915 } |
| 1916 // Emit a nop in the branch delay slot if required. |
| 1917 if (bdslot == PROTECT) |
| 1918 nop(); |
| 1919 } |
| 1920 |
| 1921 |
| 1922 void MacroAssembler::Jr(Label* L, BranchDelaySlot bdslot) { |
| 1923 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 1924 |
| 1925 uint32_t imm32; |
| 1926 imm32 = jump_address(L); |
| 1927 { BlockGrowBufferScope block_buf_growth(this); |
| 1928 // Buffer growth (and relocation) must be blocked for internal references |
| 1929 // until associated instructions are emitted and available to be patched. |
| 1930 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); |
| 1931 lui(at, (imm32 & kHiMask) >> kLuiShift); |
| 1932 ori(at, at, (imm32 & kImm16Mask)); |
| 1933 } |
| 1934 jr(at); |
| 1935 |
| 1936 // Emit a nop in the branch delay slot if required. |
| 1937 if (bdslot == PROTECT) |
| 1938 nop(); |
| 1939 } |
| 1940 |
| 1941 |
| 1942 void MacroAssembler::Jalr(Label* L, BranchDelaySlot bdslot) { |
| 1943 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 1944 |
| 1945 uint32_t imm32; |
| 1946 imm32 = jump_address(L); |
| 1947 { BlockGrowBufferScope block_buf_growth(this); |
| 1948 // Buffer growth (and relocation) must be blocked for internal references |
| 1949 // until associated instructions are emitted and available to be patched. |
| 1950 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); |
| 1951 lui(at, (imm32 & kHiMask) >> kLuiShift); |
| 1952 ori(at, at, (imm32 & kImm16Mask)); |
| 1953 } |
| 1954 jalr(at); |
| 1955 |
| 1956 // Emit a nop in the branch delay slot if required. |
| 1957 if (bdslot == PROTECT) |
| 1958 nop(); |
| 1959 } |
| 1960 |
| 1961 |
1817 void MacroAssembler::Jump(const Operand& target, BranchDelaySlot bdslot) { | 1962 void MacroAssembler::Jump(const Operand& target, BranchDelaySlot bdslot) { |
1818 BlockTrampolinePoolScope block_trampoline_pool(this); | 1963 BlockTrampolinePoolScope block_trampoline_pool(this); |
1819 if (target.is_reg()) { | 1964 if (target.is_reg()) { |
1820 jr(target.rm()); | 1965 jr(target.rm()); |
1821 } else { | 1966 } else { |
1822 if (!MustUseReg(target.rmode_)) { | 1967 if (!MustUseReg(target.rmode_)) { |
1823 j(target.imm32_); | 1968 j(target.imm32_); |
1824 } else { | 1969 } else { |
1825 li(t9, target); | 1970 li(t9, target); |
1826 jr(t9); | 1971 jr(t9); |
(...skipping 2269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4096 opcode == BGTZL); | 4241 opcode == BGTZL); |
4097 opcode = (cond == eq) ? BEQ : BNE; | 4242 opcode = (cond == eq) ? BEQ : BNE; |
4098 instr = (instr & ~kOpcodeMask) | opcode; | 4243 instr = (instr & ~kOpcodeMask) | opcode; |
4099 masm_.emit(instr); | 4244 masm_.emit(instr); |
4100 } | 4245 } |
4101 | 4246 |
4102 | 4247 |
4103 } } // namespace v8::internal | 4248 } } // namespace v8::internal |
4104 | 4249 |
4105 #endif // V8_TARGET_ARCH_MIPS | 4250 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |