| 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 |