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

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

Issue 12224024: Generate first ARM assembler test and execute (simulate) it. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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/assembler_arm_test.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 9
10 namespace dart { 10 namespace dart {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 uint32_t offset = encoding_ & offset_mask; 65 uint32_t offset = encoding_ & offset_mask;
66 ASSERT(offset < 256); 66 ASSERT(offset < 256);
67 return (encoding_ & ~offset_mask) | ((offset & 0xf0) << 4) | (offset & 0xf); 67 return (encoding_ & ~offset_mask) | ((offset & 0xf0) << 4) | (offset & 0xf);
68 } 68 }
69 69
70 70
71 uint32_t Address::vencoding() const { 71 uint32_t Address::vencoding() const {
72 const uint32_t offset_mask = (1 << 12) - 1; 72 const uint32_t offset_mask = (1 << 12) - 1;
73 uint32_t offset = encoding_ & offset_mask; 73 uint32_t offset = encoding_ & offset_mask;
74 ASSERT(offset < (1 << 10)); // In the range 0 to +1020. 74 ASSERT(offset < (1 << 10)); // In the range 0 to +1020.
75 ASSERT(Utils::Utils::IsAligned(offset, 2)); // Multiple of 4. 75 ASSERT(Utils::IsAligned(offset, 4)); // Multiple of 4.
76 int mode = encoding_ & ((8|4|1) << 21); 76 int mode = encoding_ & ((8|4|1) << 21);
77 ASSERT((mode == Offset) || (mode == NegOffset)); 77 ASSERT((mode == Offset) || (mode == NegOffset));
78 uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2); 78 uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2);
79 if (mode == Offset) { 79 if (mode == Offset) {
80 vencoding |= 1 << 23; 80 vencoding |= 1 << 23;
81 } 81 }
82 return vencoding; 82 return vencoding;
83 } 83 }
84 84
85 85
86 void Assembler::InitializeMemoryWithBreakpoints(uword data, int length) {
87 ASSERT(Utils::IsAligned(data, 4));
88 ASSERT(Utils::IsAligned(length, 4));
89 const uword end = data + length;
90 while (data < end) {
91 *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction;
92 data += 4;
93 }
94 }
95
96
86 void Assembler::Emit(int32_t value) { 97 void Assembler::Emit(int32_t value) {
87 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 98 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
88 buffer_.Emit<int32_t>(value); 99 buffer_.Emit<int32_t>(value);
89 } 100 }
90 101
91 102
92 void Assembler::EmitType01(Condition cond, 103 void Assembler::EmitType01(Condition cond,
93 int type, 104 int type,
94 Opcode opcode, 105 Opcode opcode,
95 int set_cc, 106 int set_cc,
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 void Assembler::MarkExceptionHandler(Label* label) { 1024 void Assembler::MarkExceptionHandler(Label* label) {
1014 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); 1025 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0));
1015 Label l; 1026 Label l;
1016 b(&l); 1027 b(&l);
1017 EmitBranch(AL, label, false); 1028 EmitBranch(AL, label, false);
1018 Bind(&l); 1029 Bind(&l);
1019 } 1030 }
1020 1031
1021 1032
1022 void Assembler::LoadObject(Register rd, const Object& object) { 1033 void Assembler::LoadObject(Register rd, const Object& object) {
1023 UNIMPLEMENTED(); 1034 // TODO(regis): If the object is never relocated (null, true, false, ...),
1035 // load as immediate.
1036 const int32_t offset =
1037 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag;
1038 if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
1039 ldr(rd, Address(CP, offset));
1040 } else {
1041 int32_t offset12_hi = offset & ~kOffset12Mask; // signed
1042 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned
1043 AddConstant(rd, CP, offset12_hi);
1044 ldr(rd, Address(rd, offset12_lo));
1045 }
1024 } 1046 }
1025 1047
1026 1048
1027 void Assembler::Bind(Label* label) { 1049 void Assembler::Bind(Label* label) {
1028 ASSERT(!label->IsBound()); 1050 ASSERT(!label->IsBound());
1029 int bound_pc = buffer_.Size(); 1051 int bound_pc = buffer_.Size();
1030 while (label->IsLinked()) { 1052 while (label->IsLinked()) {
1031 int32_t position = label->Position(); 1053 int32_t position = label->Position();
1032 int32_t next = buffer_.Load<int32_t>(position); 1054 int32_t next = buffer_.Load<int32_t>(position);
1033 int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next); 1055 int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 mov(rd, ShifterOperand(rm, ROR, shift_imm), cond); 1154 mov(rd, ShifterOperand(rm, ROR, shift_imm), cond);
1133 } 1155 }
1134 1156
1135 1157
1136 void Assembler::Rrx(Register rd, Register rm, Condition cond) { 1158 void Assembler::Rrx(Register rd, Register rm, Condition cond) {
1137 mov(rd, ShifterOperand(rm, ROR, 0), cond); 1159 mov(rd, ShifterOperand(rm, ROR, 0), cond);
1138 } 1160 }
1139 1161
1140 1162
1141 void Assembler::Branch(const ExternalLabel* label) { 1163 void Assembler::Branch(const ExternalLabel* label) {
1142 // TODO(regis): Revisit this code sequence.
1143 LoadImmediate(IP, label->address()); // Target address is never patched. 1164 LoadImmediate(IP, label->address()); // Target address is never patched.
1144 mov(PC, ShifterOperand(IP)); 1165 mov(PC, ShifterOperand(IP));
1145 } 1166 }
1146 1167
1147 1168
1148 void Assembler::BranchLink(const ExternalLabel* label) { 1169 void Assembler::BranchLink(const ExternalLabel* label) {
1149 // TODO(regis): Revisit this code sequence. 1170 // TODO(regis): Make sure that CodePatcher is able to patch the label referred
1150 // Make sure that CodePatcher is able to patch this code sequence. 1171 // to by this code sequence.
1151 // For added code robustness, use 'blx lr' in a patchable sequence and 1172 // For added code robustness, use 'blx lr' in a patchable sequence and
1152 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors). 1173 // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
1153 ldr(LR, Address(PC)); 1174 const int32_t offset =
1154 Label skip; 1175 Array::data_offset() + 4*AddExternalLabel(label) - kHeapObjectTag;
1155 b(&skip); 1176 if (Address::CanHoldLoadOffset(kLoadWord, offset)) {
1156 Emit(label->address()); // May get patched. 1177 ldr(LR, Address(CP, offset));
1157 Bind(&skip); 1178 } else {
1179 int32_t offset12_hi = offset & ~kOffset12Mask; // signed
1180 uint32_t offset12_lo = offset & kOffset12Mask; // unsigned
1181 // Inline a simplified version of AddConstant(LR, CP, offset12_hi).
1182 ShifterOperand shifter_op;
1183 if (ShifterOperand::CanHold(offset12_hi, &shifter_op)) {
1184 add(LR, CP, shifter_op);
1185 } else {
1186 movw(LR, Utils::Low16Bits(offset12_hi));
1187 const uint16_t value_high = Utils::High16Bits(offset12_hi);
1188 if (value_high != 0) {
1189 movt(LR, value_high);
1190 }
1191 add(LR, CP, ShifterOperand(LR));
1192 }
1193 ldr(LR, Address(LR, offset12_lo));
1194 }
1158 blx(LR); // Use blx instruction so that the return branch prediction works. 1195 blx(LR); // Use blx instruction so that the return branch prediction works.
1159 } 1196 }
1160 1197
1161 1198
1162 void Assembler::BranchLinkStore(const ExternalLabel* label, Address ad) { 1199 void Assembler::BranchLinkStore(const ExternalLabel* label, Address ad) {
1163 // TODO(regis): Revisit this code sequence. 1200 // TODO(regis): Revisit this code sequence.
1164 LoadImmediate(IP, label->address()); // Target address is never patched. 1201 LoadImmediate(IP, label->address()); // Target address is never patched.
1165 str(PC, ad); 1202 str(PC, ad);
1166 blx(IP); // Use blx instruction so that the return branch prediction works. 1203 blx(IP); // Use blx instruction so that the return branch prediction works.
1167 } 1204 }
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 offset &= kBranchOffsetMask; 1524 offset &= kBranchOffsetMask;
1488 return (inst & ~kBranchOffsetMask) | offset; 1525 return (inst & ~kBranchOffsetMask) | offset;
1489 } 1526 }
1490 1527
1491 1528
1492 int Assembler::DecodeBranchOffset(int32_t inst) { 1529 int Assembler::DecodeBranchOffset(int32_t inst) {
1493 // Sign-extend, left-shift by 2, then add 8. 1530 // Sign-extend, left-shift by 2, then add 8.
1494 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); 1531 return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8);
1495 } 1532 }
1496 1533
1534
1535 int32_t Assembler::AddObject(const Object& obj) {
1536 for (int i = 0; i < object_pool_.Length(); i++) {
1537 if (object_pool_.At(i) == obj.raw()) {
1538 return i;
1539 }
1540 }
1541 object_pool_.Add(obj);
1542 return object_pool_.Length();
1543 }
1544
1545
1546 int32_t Assembler::AddExternalLabel(const ExternalLabel* label) {
1547 const uword address = label->address();
1548 ASSERT(Utils::IsAligned(address, 4));
1549 // The address is stored in the object array as a RawSmi.
1550 const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift));
1551 // Do not reuse an existing entry, since each reference may be patched
1552 // independently.
1553 object_pool_.Add(smi);
1554 return object_pool_.Length();
1555 }
1556
1497 } // namespace dart 1557 } // namespace dart
1498 1558
1499 #endif // defined TARGET_ARCH_ARM 1559 #endif // defined TARGET_ARCH_ARM
1500 1560
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698