Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Side by Side Diff: runtime/vm/assembler_arm.cc

Issue 12518016: Decode ic data and arguments descriptor passed in calls on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/code_patcher_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "vm/simulator.h" 9 #include "vm/simulator.h"
10 #include "vm/runtime_entry.h" 10 #include "vm/runtime_entry.h"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 type << kTypeShift | 164 type << kTypeShift |
165 static_cast<int32_t>(opcode) << kOpcodeShift | 165 static_cast<int32_t>(opcode) << kOpcodeShift |
166 set_cc << kSShift | 166 set_cc << kSShift |
167 static_cast<int32_t>(rn) << kRnShift | 167 static_cast<int32_t>(rn) << kRnShift |
168 static_cast<int32_t>(rd) << kRdShift | 168 static_cast<int32_t>(rd) << kRdShift |
169 so.encoding(); 169 so.encoding();
170 Emit(encoding); 170 Emit(encoding);
171 } 171 }
172 172
173 173
174 void Assembler::EmitType5(Condition cond, int offset, bool link) { 174 void Assembler::EmitType5(Condition cond, int32_t offset, bool link) {
175 ASSERT(cond != kNoCondition); 175 ASSERT(cond != kNoCondition);
176 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 176 int32_t encoding = static_cast<int32_t>(cond) << kConditionShift |
177 5 << kTypeShift | 177 5 << kTypeShift |
178 (link ? 1 : 0) << kLinkShift; 178 (link ? 1 : 0) << kLinkShift;
179 Emit(Assembler::EncodeBranchOffset(offset, encoding)); 179 Emit(Assembler::EncodeBranchOffset(offset, encoding));
180 } 180 }
181 181
182 182
183 void Assembler::EmitMemOp(Condition cond, 183 void Assembler::EmitMemOp(Condition cond,
184 bool load, 184 bool load,
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 1228
1229 1229
1230 void Assembler::Drop(intptr_t stack_elements) { 1230 void Assembler::Drop(intptr_t stack_elements) {
1231 ASSERT(stack_elements >= 0); 1231 ASSERT(stack_elements >= 0);
1232 if (stack_elements > 0) { 1232 if (stack_elements > 0) {
1233 AddImmediate(SP, SP, stack_elements * kWordSize); 1233 AddImmediate(SP, SP, stack_elements * kWordSize);
1234 } 1234 }
1235 } 1235 }
1236 1236
1237 1237
1238 // Uses a code sequence that can easily be decoded.
1239 void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) {
1240 ASSERT(rd != PP);
1241 int32_t offset_mask = 0;
1242 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) {
1243 ldr(rd, Address(PP, offset));
1244 } else {
1245 int32_t offset_hi = offset & ~offset_mask; // signed
1246 uint32_t offset_lo = offset & offset_mask; // unsigned
1247 // Inline a simplified version of AddImmediate(rd, PP, offset_hi).
1248 ShifterOperand shifter_op;
1249 if (ShifterOperand::CanHold(offset_hi, &shifter_op)) {
1250 add(rd, PP, shifter_op);
1251 } else {
1252 movw(rd, Utils::Low16Bits(offset_hi));
1253 const uint16_t value_high = Utils::High16Bits(offset_hi);
1254 if (value_high != 0) {
1255 movt(rd, value_high);
1256 }
1257 add(rd, PP, ShifterOperand(LR));
1258 }
1259 ldr(rd, Address(rd, offset_lo));
1260 }
1261 }
1262
1263
1238 void Assembler::LoadObject(Register rd, const Object& object) { 1264 void Assembler::LoadObject(Register rd, const Object& object) {
1239 if (object.IsNull() || 1265 if (object.IsNull() ||
1240 object.IsSmi() || 1266 object.IsSmi() ||
1241 (object.raw() == Bool::True().raw()) || 1267 (object.raw() == Bool::True().raw()) ||
1242 (object.raw() == Bool::False().raw())) { 1268 (object.raw() == Bool::False().raw())) {
1243 // This object is never relocated; do not use object pool. 1269 // This object is never relocated; do not use object pool.
1244 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); 1270 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()));
1245 return; 1271 return;
1246 } 1272 }
1247 const int32_t offset = 1273 const int32_t offset =
1248 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; 1274 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag;
1249 int32_t offset_mask = 0; 1275 LoadWordFromPoolOffset(rd, offset);
1250 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) {
1251 ldr(rd, Address(PP, offset));
1252 } else {
1253 int32_t offset_hi = offset & ~offset_mask; // signed
1254 uint32_t offset_lo = offset & offset_mask; // unsigned
1255 AddImmediate(rd, PP, offset_hi);
1256 ldr(rd, Address(rd, offset_lo));
1257 }
1258 } 1276 }
1259 1277
1260 1278
1261 void Assembler::PushObject(const Object& object) { 1279 void Assembler::PushObject(const Object& object) {
1262 LoadObject(IP, object); 1280 LoadObject(IP, object);
1263 Push(IP); 1281 Push(IP);
1264 } 1282 }
1265 1283
1266 1284
1267 void Assembler::Bind(Label* label) { 1285 void Assembler::Bind(Label* label) {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 } 1437 }
1420 1438
1421 1439
1422 void Assembler::BranchLinkPatchable(const ExternalLabel* label) { 1440 void Assembler::BranchLinkPatchable(const ExternalLabel* label) {
1423 // Make sure that class CallPattern is able to patch the label referred 1441 // Make sure that class CallPattern is able to patch the label referred
1424 // to by this code sequence. 1442 // to by this code sequence.
1425 // For added code robustness, use 'blx lr' in a patchable sequence and 1443 // For added code robustness, use 'blx lr' in a patchable sequence and
1426 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). 1444 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
1427 const int32_t offset = 1445 const int32_t offset =
1428 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag; 1446 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag;
1429 int32_t offset_mask = 0; 1447 LoadWordFromPoolOffset(LR, offset);
1430 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) {
1431 ldr(LR, Address(PP, offset));
1432 } else {
1433 int32_t offset_hi = offset & ~offset_mask; // signed
1434 uint32_t offset_lo = offset & offset_mask; // unsigned
1435 // Inline a simplified version of AddImmediate(LR, CP, offset_hi).
1436 ShifterOperand shifter_op;
1437 if (ShifterOperand::CanHold(offset_hi, &shifter_op)) {
1438 add(LR, PP, shifter_op);
1439 } else {
1440 movw(LR, Utils::Low16Bits(offset_hi));
1441 const uint16_t value_high = Utils::High16Bits(offset_hi);
1442 if (value_high != 0) {
1443 movt(LR, value_high);
1444 }
1445 add(LR, PP, ShifterOperand(LR));
1446 }
1447 ldr(LR, Address(LR, offset_lo));
1448 }
1449 blx(LR); // Use blx instruction so that the return branch prediction works. 1448 blx(LR); // Use blx instruction so that the return branch prediction works.
1450 } 1449 }
1451 1450
1452 1451
1453 void Assembler::BranchLinkStore(const ExternalLabel* label, Address ad) { 1452 void Assembler::BranchLinkStore(const ExternalLabel* label, Address ad) {
1454 // TODO(regis): Revisit this code sequence. 1453 // TODO(regis): Revisit this code sequence.
1455 LoadImmediate(IP, label->address()); // Target address is never patched. 1454 LoadImmediate(IP, label->address()); // Target address is never patched.
1456 str(PC, ad); 1455 str(PC, ad);
1457 blx(IP); // Use blx instruction so that the return branch prediction works. 1456 blx(IP); // Use blx instruction so that the return branch prediction works.
1458 } 1457 }
1459 1458
1460 1459
1461 void Assembler::BranchLinkOffset(Register base, int offset) { 1460 void Assembler::BranchLinkOffset(Register base, int32_t offset) {
1462 ASSERT(base != PC); 1461 ASSERT(base != PC);
1463 ASSERT(base != IP); 1462 ASSERT(base != IP);
1464 int32_t offset_mask = 0; 1463 LoadFromOffset(kLoadWord, IP, base, offset);
1465 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) {
1466 ldr(IP, Address(base, offset));
1467 } else {
1468 int offset_hi = offset & ~offset_mask;
1469 int offset_lo = offset & offset_mask;
1470 ShifterOperand offset_hi_op;
1471 if (ShifterOperand::CanHold(offset_hi, &offset_hi_op)) {
1472 add(IP, base, offset_hi_op);
1473 ldr(IP, Address(IP, offset_lo));
1474 } else {
1475 LoadImmediate(IP, offset_hi);
1476 add(IP, IP, ShifterOperand(base));
1477 ldr(IP, Address(IP, offset_lo));
1478 }
1479 }
1480 blx(IP); // Use blx instruction so that the return branch prediction works. 1464 blx(IP); // Use blx instruction so that the return branch prediction works.
1481 } 1465 }
1482 1466
1483 1467
1484 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 1468 void Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) {
1485 ShifterOperand shifter_op; 1469 ShifterOperand shifter_op;
1486 if (ShifterOperand::CanHold(value, &shifter_op)) { 1470 if (ShifterOperand::CanHold(value, &shifter_op)) {
1487 mov(rd, shifter_op, cond); 1471 mov(rd, shifter_op, cond);
1488 } else if (ShifterOperand::CanHold(~value, &shifter_op)) { 1472 } else if (ShifterOperand::CanHold(~value, &shifter_op)) {
1489 mvn(rd, shifter_op, cond); 1473 mvn(rd, shifter_op, cond);
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 // 'unstop' and continue execution in the simulator or jump to the next 1892 // 'unstop' and continue execution in the simulator or jump to the next
1909 // instruction in gdb. 1893 // instruction in gdb.
1910 Label stop; 1894 Label stop;
1911 b(&stop); 1895 b(&stop);
1912 Emit(reinterpret_cast<int32_t>(message)); 1896 Emit(reinterpret_cast<int32_t>(message));
1913 Bind(&stop); 1897 Bind(&stop);
1914 svc(kStopMessageSvcCode); 1898 svc(kStopMessageSvcCode);
1915 } 1899 }
1916 1900
1917 1901
1918 int32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) { 1902 int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
1919 // The offset is off by 8 due to the way the ARM CPUs read PC. 1903 // The offset is off by 8 due to the way the ARM CPUs read PC.
1920 offset -= 8; 1904 offset -= 8;
1921 ASSERT(Utils::IsAligned(offset, 4)); 1905 ASSERT(Utils::IsAligned(offset, 4));
1922 ASSERT(Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset)); 1906 ASSERT(Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset));
1923 1907
1924 // Properly preserve only the bits supported in the instruction. 1908 // Properly preserve only the bits supported in the instruction.
1925 offset >>= 2; 1909 offset >>= 2;
1926 offset &= kBranchOffsetMask; 1910 offset &= kBranchOffsetMask;
1927 return (inst & ~kBranchOffsetMask) | offset; 1911 return (inst & ~kBranchOffsetMask) | offset;
1928 } 1912 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1963 // Do not reuse an existing entry, since each reference may be patched 1947 // Do not reuse an existing entry, since each reference may be patched
1964 // independently. 1948 // independently.
1965 object_pool_.Add(smi); 1949 object_pool_.Add(smi);
1966 return object_pool_.Length() - 1; 1950 return object_pool_.Length() - 1;
1967 } 1951 }
1968 1952
1969 } // namespace dart 1953 } // namespace dart
1970 1954
1971 #endif // defined TARGET_ARCH_ARM 1955 #endif // defined TARGET_ARCH_ARM
1972 1956
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/code_patcher_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698