| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 | 9 |
| 10 #include "vm/stub_code.h" | 10 #include "vm/stub_code.h" |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 void Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR | 983 void Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR |
| 984 ASSERT(cond != kNoCondition); | 984 ASSERT(cond != kNoCondition); |
| 985 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | | 985 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 986 B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | | 986 B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | |
| 987 (static_cast<int32_t>(PC)*B12) | | 987 (static_cast<int32_t>(PC)*B12) | |
| 988 B11 | B9 | B4; | 988 B11 | B9 | B4; |
| 989 Emit(encoding); | 989 Emit(encoding); |
| 990 } | 990 } |
| 991 | 991 |
| 992 | 992 |
| 993 void Assembler::svc(uint32_t imm24) { | 993 void Assembler::svc(uint32_t imm24, Condition cond) { |
| 994 ASSERT(cond != kNoCondition); |
| 994 ASSERT(imm24 < (1 << 24)); | 995 ASSERT(imm24 < (1 << 24)); |
| 995 int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24; | 996 int32_t encoding = (cond << kConditionShift) | B27 | B26 | B25 | B24 | imm24; |
| 996 Emit(encoding); | 997 Emit(encoding); |
| 997 } | 998 } |
| 998 | 999 |
| 999 | 1000 |
| 1000 void Assembler::bkpt(uint16_t imm16) { | 1001 void Assembler::bkpt(uint16_t imm16, Condition cond) { |
| 1001 int32_t encoding = (AL << kConditionShift) | B24 | B21 | | 1002 ASSERT(cond != kNoCondition); |
| 1003 int32_t encoding = (cond << kConditionShift) | B24 | B21 | |
| 1002 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); | 1004 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); |
| 1003 Emit(encoding); | 1005 Emit(encoding); |
| 1004 } | 1006 } |
| 1005 | 1007 |
| 1006 | 1008 |
| 1007 void Assembler::b(Label* label, Condition cond) { | 1009 void Assembler::b(Label* label, Condition cond) { |
| 1008 EmitBranch(cond, label, false); | 1010 EmitBranch(cond, label, false); |
| 1009 } | 1011 } |
| 1010 | 1012 |
| 1011 | 1013 |
| 1012 void Assembler::bl(Label* label, Condition cond) { | 1014 void Assembler::bl(Label* label, Condition cond) { |
| 1013 EmitBranch(cond, label, true); | 1015 EmitBranch(cond, label, true); |
| 1014 } | 1016 } |
| 1015 | 1017 |
| 1016 | 1018 |
| 1019 void Assembler::bx(Register rm, Condition cond) { |
| 1020 ASSERT(rm != kNoRegister); |
| 1021 ASSERT(cond != kNoCondition); |
| 1022 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 1023 B24 | B21 | (0xfff << 8) | B4 | |
| 1024 (static_cast<int32_t>(rm) << kRmShift); |
| 1025 Emit(encoding); |
| 1026 } |
| 1027 |
| 1028 |
| 1017 void Assembler::blx(Register rm, Condition cond) { | 1029 void Assembler::blx(Register rm, Condition cond) { |
| 1018 ASSERT(rm != kNoRegister); | 1030 ASSERT(rm != kNoRegister); |
| 1019 ASSERT(cond != kNoCondition); | 1031 ASSERT(cond != kNoCondition); |
| 1020 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | | 1032 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 1021 B24 | B21 | (0xfff << 8) | B5 | B4 | | 1033 B24 | B21 | (0xfff << 8) | B5 | B4 | |
| 1022 (static_cast<int32_t>(rm) << kRmShift); | 1034 (static_cast<int32_t>(rm) << kRmShift); |
| 1023 Emit(encoding); | 1035 Emit(encoding); |
| 1024 } | 1036 } |
| 1025 | 1037 |
| 1026 | 1038 |
| 1027 void Assembler::MarkExceptionHandler(Label* label) { | 1039 void Assembler::MarkExceptionHandler(Label* label) { |
| 1028 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); | 1040 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); |
| 1029 Label l; | 1041 Label l; |
| 1030 b(&l); | 1042 b(&l); |
| 1031 EmitBranch(AL, label, false); | 1043 EmitBranch(AL, label, false); |
| 1032 Bind(&l); | 1044 Bind(&l); |
| 1033 } | 1045 } |
| 1034 | 1046 |
| 1035 | 1047 |
| 1036 void Assembler::LoadObject(Register rd, const Object& object) { | 1048 void Assembler::LoadObject(Register rd, const Object& object) { |
| 1037 // TODO(regis): If the object is never relocated (null, true, false, ...), | 1049 if (object.IsNull() || |
| 1038 // load as immediate. | 1050 object.IsSmi() || |
| 1051 (object.raw() == Bool::True().raw()) || |
| 1052 (object.raw() == Bool::False().raw())) { |
| 1053 // This object is never relocated; do not use object pool. |
| 1054 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); |
| 1055 return; |
| 1056 } |
| 1039 const int32_t offset = | 1057 const int32_t offset = |
| 1040 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; | 1058 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; |
| 1041 if (Address::CanHoldLoadOffset(kLoadWord, offset)) { | 1059 if (Address::CanHoldLoadOffset(kLoadWord, offset)) { |
| 1042 ldr(rd, Address(PP, offset)); | 1060 ldr(rd, Address(PP, offset)); |
| 1043 } else { | 1061 } else { |
| 1044 int32_t offset12_hi = offset & ~kOffset12Mask; // signed | 1062 int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 1045 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | 1063 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 1046 AddConstant(rd, PP, offset12_hi); | 1064 AddImmediate(rd, PP, offset12_hi); |
| 1047 ldr(rd, Address(rd, offset12_lo)); | 1065 ldr(rd, Address(rd, offset12_lo)); |
| 1048 } | 1066 } |
| 1049 } | 1067 } |
| 1050 | 1068 |
| 1051 | 1069 |
| 1052 void Assembler::Bind(Label* label) { | 1070 void Assembler::Bind(Label* label) { |
| 1053 ASSERT(!label->IsBound()); | 1071 ASSERT(!label->IsBound()); |
| 1054 int bound_pc = buffer_.Size(); | 1072 int bound_pc = buffer_.Size(); |
| 1055 while (label->IsLinked()) { | 1073 while (label->IsLinked()) { |
| 1056 int32_t position = label->Position(); | 1074 int32_t position = label->Position(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 ASSERT(shift_imm != 0); // Use Rrx instruction. | 1174 ASSERT(shift_imm != 0); // Use Rrx instruction. |
| 1157 mov(rd, ShifterOperand(rm, ROR, shift_imm), cond); | 1175 mov(rd, ShifterOperand(rm, ROR, shift_imm), cond); |
| 1158 } | 1176 } |
| 1159 | 1177 |
| 1160 | 1178 |
| 1161 void Assembler::Rrx(Register rd, Register rm, Condition cond) { | 1179 void Assembler::Rrx(Register rd, Register rm, Condition cond) { |
| 1162 mov(rd, ShifterOperand(rm, ROR, 0), cond); | 1180 mov(rd, ShifterOperand(rm, ROR, 0), cond); |
| 1163 } | 1181 } |
| 1164 | 1182 |
| 1165 | 1183 |
| 1166 void Assembler::Branch(const ExternalLabel* label) { | 1184 void Assembler::Branch(const ExternalLabel* label, Condition cond) { |
| 1167 LoadImmediate(IP, label->address()); // Target address is never patched. | 1185 LoadImmediate(IP, label->address(), cond); // Address is never patched. |
| 1168 mov(PC, ShifterOperand(IP)); | 1186 mov(PC, ShifterOperand(IP), cond); |
| 1169 } | 1187 } |
| 1170 | 1188 |
| 1171 | 1189 |
| 1172 void Assembler::BranchLink(const ExternalLabel* label) { | 1190 void Assembler::BranchLink(const ExternalLabel* label) { |
| 1173 LoadImmediate(IP, label->address()); // Target address is never patched. | 1191 LoadImmediate(IP, label->address()); // Target address is never patched. |
| 1174 blx(IP); // Use blx instruction so that the return branch prediction works. | 1192 blx(IP); // Use blx instruction so that the return branch prediction works. |
| 1175 } | 1193 } |
| 1176 | 1194 |
| 1177 | 1195 |
| 1178 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { | 1196 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { |
| 1179 // Make sure that class CallPattern is able to patch the label referred | 1197 // Make sure that class CallPattern is able to patch the label referred |
| 1180 // to by this code sequence. | 1198 // to by this code sequence. |
| 1181 // For added code robustness, use 'blx lr' in a patchable sequence and | 1199 // For added code robustness, use 'blx lr' in a patchable sequence and |
| 1182 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). | 1200 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). |
| 1183 const int32_t offset = | 1201 const int32_t offset = |
| 1184 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; | 1202 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; |
| 1185 if (Address::CanHoldLoadOffset(kLoadWord, offset)) { | 1203 if (Address::CanHoldLoadOffset(kLoadWord, offset)) { |
| 1186 ldr(LR, Address(PP, offset)); | 1204 ldr(LR, Address(PP, offset)); |
| 1187 } else { | 1205 } else { |
| 1188 int32_t offset12_hi = offset & ~kOffset12Mask; // signed | 1206 int32_t offset12_hi = offset & ~kOffset12Mask; // signed |
| 1189 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned | 1207 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned |
| 1190 // Inline a simplified version of AddConstant(LR, CP, offset12_hi). | 1208 // Inline a simplified version of AddImmediate(LR, CP, offset12_hi). |
| 1191 ShifterOperand shifter_op; | 1209 ShifterOperand shifter_op; |
| 1192 if (ShifterOperand::CanHold(offset12_hi, &shifter_op)) { | 1210 if (ShifterOperand::CanHold(offset12_hi, &shifter_op)) { |
| 1193 add(LR, PP, shifter_op); | 1211 add(LR, PP, shifter_op); |
| 1194 } else { | 1212 } else { |
| 1195 movw(LR, Utils::Low16Bits(offset12_hi)); | 1213 movw(LR, Utils::Low16Bits(offset12_hi)); |
| 1196 const uint16_t value_high = Utils::High16Bits(offset12_hi); | 1214 const uint16_t value_high = Utils::High16Bits(offset12_hi); |
| 1197 if (value_high != 0) { | 1215 if (value_high != 0) { |
| 1198 movt(LR, value_high); | 1216 movt(LR, value_high); |
| 1199 } | 1217 } |
| 1200 add(LR, PP, ShifterOperand(LR)); | 1218 add(LR, PP, ShifterOperand(LR)); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 LoadImmediate(IP, offset, cond); | 1423 LoadImmediate(IP, offset, cond); |
| 1406 add(IP, IP, ShifterOperand(base), cond); | 1424 add(IP, IP, ShifterOperand(base), cond); |
| 1407 base = IP; | 1425 base = IP; |
| 1408 offset = 0; | 1426 offset = 0; |
| 1409 } | 1427 } |
| 1410 ASSERT(Address::CanHoldStoreOffset(kStoreDWord, offset)); | 1428 ASSERT(Address::CanHoldStoreOffset(kStoreDWord, offset)); |
| 1411 vstrd(reg, Address(base, offset), cond); | 1429 vstrd(reg, Address(base, offset), cond); |
| 1412 } | 1430 } |
| 1413 | 1431 |
| 1414 | 1432 |
| 1415 void Assembler::AddConstant(Register rd, int32_t value, Condition cond) { | 1433 void Assembler::AddImmediate(Register rd, int32_t value, Condition cond) { |
| 1416 AddConstant(rd, rd, value, cond); | 1434 AddImmediate(rd, rd, value, cond); |
| 1417 } | 1435 } |
| 1418 | 1436 |
| 1419 | 1437 |
| 1420 void Assembler::AddConstant(Register rd, Register rn, int32_t value, | 1438 void Assembler::AddImmediate(Register rd, Register rn, int32_t value, |
| 1421 Condition cond) { | 1439 Condition cond) { |
| 1422 if (value == 0) { | 1440 if (value == 0) { |
| 1423 if (rd != rn) { | 1441 if (rd != rn) { |
| 1424 mov(rd, ShifterOperand(rn), cond); | 1442 mov(rd, ShifterOperand(rn), cond); |
| 1425 } | 1443 } |
| 1426 return; | 1444 return; |
| 1427 } | 1445 } |
| 1428 // We prefer to select the shorter code sequence rather than selecting add for | 1446 // We prefer to select the shorter code sequence rather than selecting add for |
| 1429 // positive values and sub for negatives ones, which would slightly improve | 1447 // positive values and sub for negatives ones, which would slightly improve |
| 1430 // the readability of generated code for some constants. | 1448 // the readability of generated code for some constants. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1446 uint16_t value_high = Utils::High16Bits(value); | 1464 uint16_t value_high = Utils::High16Bits(value); |
| 1447 if (value_high != 0) { | 1465 if (value_high != 0) { |
| 1448 movt(IP, value_high, cond); | 1466 movt(IP, value_high, cond); |
| 1449 } | 1467 } |
| 1450 add(rd, rn, ShifterOperand(IP), cond); | 1468 add(rd, rn, ShifterOperand(IP), cond); |
| 1451 } | 1469 } |
| 1452 } | 1470 } |
| 1453 } | 1471 } |
| 1454 | 1472 |
| 1455 | 1473 |
| 1456 void Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value, | 1474 void Assembler::AddImmediateSetFlags(Register rd, Register rn, int32_t value, |
| 1457 Condition cond) { | 1475 Condition cond) { |
| 1458 ShifterOperand shifter_op; | 1476 ShifterOperand shifter_op; |
| 1459 if (ShifterOperand::CanHold(value, &shifter_op)) { | 1477 if (ShifterOperand::CanHold(value, &shifter_op)) { |
| 1460 adds(rd, rn, shifter_op, cond); | 1478 adds(rd, rn, shifter_op, cond); |
| 1461 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { | 1479 } else if (ShifterOperand::CanHold(-value, &shifter_op)) { |
| 1462 subs(rd, rn, shifter_op, cond); | 1480 subs(rd, rn, shifter_op, cond); |
| 1463 } else { | 1481 } else { |
| 1464 ASSERT(rn != IP); | 1482 ASSERT(rn != IP); |
| 1465 if (ShifterOperand::CanHold(~value, &shifter_op)) { | 1483 if (ShifterOperand::CanHold(~value, &shifter_op)) { |
| 1466 mvn(IP, shifter_op, cond); | 1484 mvn(IP, shifter_op, cond); |
| 1467 adds(rd, rn, ShifterOperand(IP), cond); | 1485 adds(rd, rn, ShifterOperand(IP), cond); |
| 1468 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { | 1486 } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { |
| 1469 mvn(IP, shifter_op, cond); | 1487 mvn(IP, shifter_op, cond); |
| 1470 subs(rd, rn, ShifterOperand(IP), cond); | 1488 subs(rd, rn, ShifterOperand(IP), cond); |
| 1471 } else { | 1489 } else { |
| 1472 movw(IP, Utils::Low16Bits(value), cond); | 1490 movw(IP, Utils::Low16Bits(value), cond); |
| 1473 uint16_t value_high = Utils::High16Bits(value); | 1491 uint16_t value_high = Utils::High16Bits(value); |
| 1474 if (value_high != 0) { | 1492 if (value_high != 0) { |
| 1475 movt(IP, value_high, cond); | 1493 movt(IP, value_high, cond); |
| 1476 } | 1494 } |
| 1477 adds(rd, rn, ShifterOperand(IP), cond); | 1495 adds(rd, rn, ShifterOperand(IP), cond); |
| 1478 } | 1496 } |
| 1479 } | 1497 } |
| 1480 } | 1498 } |
| 1481 | 1499 |
| 1482 | 1500 |
| 1483 void Assembler::AddConstantWithCarry(Register rd, Register rn, int32_t value, | 1501 void Assembler::AddImmediateWithCarry(Register rd, Register rn, int32_t value, |
| 1484 Condition cond) { | 1502 Condition cond) { |
| 1485 ShifterOperand shifter_op; | 1503 ShifterOperand shifter_op; |
| 1486 if (ShifterOperand::CanHold(value, &shifter_op)) { | 1504 if (ShifterOperand::CanHold(value, &shifter_op)) { |
| 1487 adc(rd, rn, shifter_op, cond); | 1505 adc(rd, rn, shifter_op, cond); |
| 1488 } else if (ShifterOperand::CanHold(-value - 1, &shifter_op)) { | 1506 } else if (ShifterOperand::CanHold(-value - 1, &shifter_op)) { |
| 1489 sbc(rd, rn, shifter_op, cond); | 1507 sbc(rd, rn, shifter_op, cond); |
| 1490 } else { | 1508 } else { |
| 1491 ASSERT(rn != IP); | 1509 ASSERT(rn != IP); |
| 1492 if (ShifterOperand::CanHold(~value, &shifter_op)) { | 1510 if (ShifterOperand::CanHold(~value, &shifter_op)) { |
| 1493 mvn(IP, shifter_op, cond); | 1511 mvn(IP, shifter_op, cond); |
| 1494 adc(rd, rn, ShifterOperand(IP), cond); | 1512 adc(rd, rn, ShifterOperand(IP), cond); |
| 1495 } else if (ShifterOperand::CanHold(~(-value - 1), &shifter_op)) { | 1513 } else if (ShifterOperand::CanHold(~(-value - 1), &shifter_op)) { |
| 1496 mvn(IP, shifter_op, cond); | 1514 mvn(IP, shifter_op, cond); |
| 1497 sbc(rd, rn, ShifterOperand(IP), cond); | 1515 sbc(rd, rn, ShifterOperand(IP), cond); |
| 1498 } else { | 1516 } else { |
| 1499 movw(IP, Utils::Low16Bits(value), cond); | 1517 movw(IP, Utils::Low16Bits(value), cond); |
| 1500 uint16_t value_high = Utils::High16Bits(value); | 1518 uint16_t value_high = Utils::High16Bits(value); |
| 1501 if (value_high != 0) { | 1519 if (value_high != 0) { |
| 1502 movt(IP, value_high, cond); | 1520 movt(IP, value_high, cond); |
| 1503 } | 1521 } |
| 1504 adc(rd, rn, ShifterOperand(IP), cond); | 1522 adc(rd, rn, ShifterOperand(IP), cond); |
| 1505 } | 1523 } |
| 1506 } | 1524 } |
| 1507 } | 1525 } |
| 1508 | 1526 |
| 1509 | 1527 |
| 1528 void Assembler::CompareImmediate(Register rn, int32_t value, Condition cond) { |
| 1529 ShifterOperand shifter_op; |
| 1530 if (ShifterOperand::CanHold(value, &shifter_op)) { |
| 1531 cmp(rn, shifter_op, cond); |
| 1532 } else { |
| 1533 ASSERT(rn != IP); |
| 1534 LoadImmediate(IP, cond); |
| 1535 cmp(rn, ShifterOperand(IP), cond); |
| 1536 } |
| 1537 } |
| 1538 |
| 1539 |
| 1540 static int NumRegsBelowFP(RegList regs) { |
| 1541 int count = 0; |
| 1542 for (int i = 0; i < FP; i++) { |
| 1543 if ((regs & (1 << i)) != 0) { |
| 1544 count++; |
| 1545 } |
| 1546 } |
| 1547 return count; |
| 1548 } |
| 1549 |
| 1550 |
| 1551 void Assembler::EnterFrame(RegList regs, intptr_t frame_size) { |
| 1552 if (prologue_offset_ == -1) { |
| 1553 prologue_offset_ = CodeSize(); |
| 1554 } |
| 1555 PushList(regs); |
| 1556 if ((regs & (1 << FP)) != 0) { |
| 1557 // Set FP to the saved previous FP. |
| 1558 add(FP, SP, ShifterOperand(4 * NumRegsBelowFP(regs))); |
| 1559 } |
| 1560 AddImmediate(SP, -frame_size); |
| 1561 } |
| 1562 |
| 1563 |
| 1564 void Assembler::LeaveFrame(RegList regs) { |
| 1565 ASSERT((regs & (1 << PC)) == 0); // Must not pop PC. |
| 1566 if ((regs & (1 << FP)) != 0) { |
| 1567 // Use FP to set SP. |
| 1568 sub(SP, FP, ShifterOperand(4 * NumRegsBelowFP(regs))); |
| 1569 } |
| 1570 PopList(regs); |
| 1571 } |
| 1572 |
| 1573 |
| 1574 void Assembler::Ret() { |
| 1575 bx(LR); |
| 1576 } |
| 1577 |
| 1578 |
| 1579 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { |
| 1580 // Reserve space for arguments and align frame before entering |
| 1581 // the C++ world. |
| 1582 AddImmediate(SP, -frame_space); |
| 1583 if (OS::ActivationFrameAlignment() > 0) { |
| 1584 and_(SP, SP, ShifterOperand(~(OS::ActivationFrameAlignment() - 1))); |
| 1585 } |
| 1586 } |
| 1587 |
| 1588 |
| 1510 void Assembler::Stop(const char* message) { | 1589 void Assembler::Stop(const char* message) { |
| 1511 if (FLAG_print_stop_message) { | 1590 if (FLAG_print_stop_message) { |
| 1512 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. | 1591 PushList((1 << R0) | (1 << IP) | (1 << LR)); // Preserve R0, IP, LR. |
| 1513 LoadImmediate(R0, reinterpret_cast<int32_t>(message)); | 1592 LoadImmediate(R0, reinterpret_cast<int32_t>(message)); |
| 1514 // PrintStopMessage() preserves all registers. | 1593 // PrintStopMessage() preserves all registers. |
| 1515 BranchLink(&StubCode::PrintStopMessageLabel()); // Passing message in R0. | 1594 BranchLink(&StubCode::PrintStopMessageLabel()); // Passing message in R0. |
| 1516 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. | 1595 PopList((1 << R0) | (1 << IP) | (1 << LR)); // Restore R0, IP, LR. |
| 1517 } | 1596 } |
| 1518 // Emit the message address before the svc instruction, so that we can | 1597 // Emit the message address before the svc instruction, so that we can |
| 1519 // 'unstop' and continue execution in the simulator or jump to the next | 1598 // 'unstop' and continue execution in the simulator or jump to the next |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 // Do not reuse an existing entry, since each reference may be patched | 1653 // Do not reuse an existing entry, since each reference may be patched |
| 1575 // independently. | 1654 // independently. |
| 1576 object_pool_.Add(smi); | 1655 object_pool_.Add(smi); |
| 1577 return object_pool_.Length() - 1; | 1656 return object_pool_.Length() - 1; |
| 1578 } | 1657 } |
| 1579 | 1658 |
| 1580 } // namespace dart | 1659 } // namespace dart |
| 1581 | 1660 |
| 1582 #endif // defined TARGET_ARCH_ARM | 1661 #endif // defined TARGET_ARCH_ARM |
| 1583 | 1662 |
| OLD | NEW |