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

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

Issue 12090034: Initial revision of ARM assembler. (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.cc ('k') | runtime/vm/assembler_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 #ifndef VM_ASSEMBLER_ARM_H_ 5 #ifndef VM_ASSEMBLER_ARM_H_
6 #define VM_ASSEMBLER_ARM_H_ 6 #define VM_ASSEMBLER_ARM_H_
7 7
8 #ifndef VM_ASSEMBLER_H_ 8 #ifndef VM_ASSEMBLER_H_
9 #error Do not include assembler_arm.h directly; use assembler.h instead. 9 #error Do not include assembler_arm.h directly; use assembler.h instead.
10 #endif 10 #endif
11 11
12 #include "platform/assert.h" 12 #include "platform/assert.h"
13 #include "platform/utils.h"
13 #include "vm/constants_arm.h" 14 #include "vm/constants_arm.h"
14 15
15 namespace dart { 16 namespace dart {
16 17
17 class Operand : public ValueObject {
18 public:
19 Operand(const Operand& other) : ValueObject() {
20 UNIMPLEMENTED();
21 }
22
23 Operand& operator=(const Operand& other) {
24 UNIMPLEMENTED();
25 return *this;
26 }
27
28 protected:
29 Operand() { } // Needed by subclass Address.
30 };
31
32
33 class Address : public Operand {
34 public:
35 Address(Register base, int32_t disp) {
36 UNIMPLEMENTED();
37 }
38
39 Address(const Address& other) : Operand(other) { }
40
41 Address& operator=(const Address& other) {
42 Operand::operator=(other);
43 return *this;
44 }
45 };
46
47
48 class FieldAddress : public Address {
49 public:
50 FieldAddress(Register base, int32_t disp)
51 : Address(base, disp - kHeapObjectTag) { }
52
53 FieldAddress(const FieldAddress& other) : Address(other) { }
54
55 FieldAddress& operator=(const FieldAddress& other) {
56 Address::operator=(other);
57 return *this;
58 }
59 };
60
61
62 class Label : public ValueObject { 18 class Label : public ValueObject {
63 public: 19 public:
64 Label() : position_(0) { } 20 Label() : position_(0) { }
65 21
66 ~Label() { 22 ~Label() {
67 // Assert if label is being destroyed with unresolved branches pending. 23 // Assert if label is being destroyed with unresolved branches pending.
68 ASSERT(!IsLinked()); 24 ASSERT(!IsLinked());
69 } 25 }
70 26
71 // Returns the position for bound and linked labels. Cannot be used 27 // Returns the position for bound and linked labels. Cannot be used
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 class CPUFeatures : public AllStatic { 62 class CPUFeatures : public AllStatic {
107 public: 63 public:
108 static void InitOnce() { } 64 static void InitOnce() { }
109 static bool double_truncate_round_supported() { 65 static bool double_truncate_round_supported() {
110 UNIMPLEMENTED(); 66 UNIMPLEMENTED();
111 return false; 67 return false;
112 } 68 }
113 }; 69 };
114 70
115 71
72 // Encodes Addressing Mode 1 - Data-processing operands.
73 class ShifterOperand : public ValueObject {
74 public:
75 // Data-processing operands - Uninitialized.
76 ShifterOperand() : type_(-1) { }
77
78 // Data-processing operands - Copy constructor.
79 ShifterOperand(const ShifterOperand& other)
80 : ValueObject(), type_(other.type_), encoding_(other.encoding_) { }
81
82 // Data-processing operands - Assignment operator.
83 ShifterOperand& operator=(const ShifterOperand& other) {
84 type_ = other.type_;
85 encoding_ = other.encoding_;
86 return *this;
87 }
88
89 // Data-processing operands - Immediate.
90 explicit ShifterOperand(uint32_t immediate) {
91 ASSERT(immediate < (1 << kImmed8Bits));
92 type_ = 1;
93 encoding_ = immediate;
94 }
95
96 // Data-processing operands - Rotated immediate.
97 ShifterOperand(uint32_t rotate, uint32_t immed8) {
98 ASSERT((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits)));
99 type_ = 1;
100 encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift);
101 }
102
103 // Data-processing operands - Register.
104 explicit ShifterOperand(Register rm) {
105 type_ = 0;
106 encoding_ = static_cast<uint32_t>(rm);
107 }
108
109 // Data-processing operands - Logical shift/rotate by immediate.
110 ShifterOperand(Register rm, Shift shift, uint32_t shift_imm) {
111 ASSERT(shift_imm < (1 << kShiftImmBits));
112 type_ = 0;
113 encoding_ = shift_imm << kShiftImmShift |
114 static_cast<uint32_t>(shift) << kShiftShift |
115 static_cast<uint32_t>(rm);
116 }
117
118 // Data-processing operands - Logical shift/rotate by register.
119 ShifterOperand(Register rm, Shift shift, Register rs) {
120 type_ = 0;
121 encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift |
122 static_cast<uint32_t>(shift) << kShiftShift | (1 << 4) |
123 static_cast<uint32_t>(rm);
124 }
125
126 static bool CanHold(uint32_t immediate, ShifterOperand* shifter_op) {
127 // Avoid the more expensive test for frequent small immediate values.
128 if (immediate < (1 << kImmed8Bits)) {
129 shifter_op->type_ = 1;
130 shifter_op->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift);
131 return true;
132 }
133 // Note that immediate must be unsigned for the test to work correctly.
134 for (int rot = 0; rot < 16; rot++) {
135 uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot));
136 if (imm8 < (1 << kImmed8Bits)) {
137 shifter_op->type_ = 1;
138 shifter_op->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift);
139 return true;
140 }
141 }
142 return false;
143 }
144
145 private:
146 bool is_valid() const { return (type_ == 0) || (type_ == 1); }
147
148 uint32_t type() const {
149 ASSERT(is_valid());
150 return type_;
151 }
152
153 uint32_t encoding() const {
154 ASSERT(is_valid());
155 return encoding_;
156 }
157
158 uint32_t type_; // Encodes the type field (bits 27-25) in the instruction.
159 uint32_t encoding_;
160
161 friend class Assembler;
162 };
163
164
165 enum LoadOperandType {
166 kLoadSignedByte,
167 kLoadUnsignedByte,
168 kLoadSignedHalfword,
169 kLoadUnsignedHalfword,
170 kLoadWord,
171 kLoadWordPair,
172 kLoadSWord,
173 kLoadDWord
174 };
175
176
177 enum StoreOperandType {
178 kStoreByte,
179 kStoreHalfword,
180 kStoreWord,
181 kStoreWordPair,
182 kStoreSWord,
183 kStoreDWord
184 };
185
186
187 // Load/store multiple addressing mode.
188 enum BlockAddressMode {
189 // bit encoding P U W
190 DA = (0|0|0) << 21, // decrement after
191 IA = (0|4|0) << 21, // increment after
192 DB = (8|0|0) << 21, // decrement before
193 IB = (8|4|0) << 21, // increment before
194 DA_W = (0|0|1) << 21, // decrement after with writeback to base
195 IA_W = (0|4|1) << 21, // increment after with writeback to base
196 DB_W = (8|0|1) << 21, // decrement before with writeback to base
197 IB_W = (8|4|1) << 21 // increment before with writeback to base
198 };
199
200
201 class Address : public ValueObject {
202 public:
203 // Memory operand addressing mode
204 enum Mode {
205 // bit encoding P U W
206 Offset = (8|4|0) << 21, // offset (w/o writeback to base)
207 PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback
208 PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback
209 NegOffset = (8|0|0) << 21, // negative offset (w/o writeback to base)
210 NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback
211 NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback
212 };
213
214 Address(const Address& other) : ValueObject(), encoding_(other.encoding_) { }
215
216 Address& operator=(const Address& other) {
217 encoding_ = other.encoding_;
218 return *this;
219 }
220
221 explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) {
222 ASSERT(Utils::IsAbsoluteUint(12, offset));
223 if (offset < 0) {
224 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign.
225 } else {
226 encoding_ = am | offset;
227 }
228 encoding_ |= static_cast<uint32_t>(rn) << kRnShift;
229 }
230
231 static bool CanHoldLoadOffset(LoadOperandType type, int offset);
232 static bool CanHoldStoreOffset(StoreOperandType type, int offset);
233
234 private:
235 uint32_t encoding() const { return encoding_; }
236
237 // Encoding for addressing mode 3.
238 uint32_t encoding3() const;
239
240 // Encoding for vfp load/store addressing.
241 uint32_t vencoding() const;
242
243 uint32_t encoding_;
244
245 friend class Assembler;
246 };
247
248
249 class FieldAddress : public Address {
250 public:
251 FieldAddress(Register base, int32_t disp)
252 : Address(base, disp - kHeapObjectTag) { }
253
254 FieldAddress(const FieldAddress& other) : Address(other) { }
255
256 FieldAddress& operator=(const FieldAddress& other) {
257 Address::operator=(other);
258 return *this;
259 }
260 };
261
262
116 class Assembler : public ValueObject { 263 class Assembler : public ValueObject {
117 public: 264 public:
118 Assembler() { UNIMPLEMENTED(); } 265 Assembler() : buffer_(), prologue_offset_(-1), comments_() { }
119 ~Assembler() { } 266 ~Assembler() { }
120 267
121 void PopRegister(Register r) { 268 void PopRegister(Register r) { Pop(r); }
122 UNIMPLEMENTED(); 269
123 } 270 void Bind(Label* label);
124
125 void Bind(Label* label) {
126 UNIMPLEMENTED();
127 }
128 271
129 // Misc. functionality 272 // Misc. functionality
130 int CodeSize() const { 273 int CodeSize() const { return buffer_.Size(); }
131 UNIMPLEMENTED(); 274 int prologue_offset() const { return prologue_offset_; }
132 return 0;
133 }
134 int prologue_offset() const {
135 UNIMPLEMENTED();
136 return 0;
137 }
138 const ZoneGrowableArray<int>& GetPointerOffsets() const { 275 const ZoneGrowableArray<int>& GetPointerOffsets() const {
139 UNIMPLEMENTED(); 276 return buffer_.pointer_offsets();
140 return *pointer_offsets_; 277 }
141 } 278
142 void FinalizeInstructions(const MemoryRegion& region) { 279 void FinalizeInstructions(const MemoryRegion& region) {
143 UNIMPLEMENTED(); 280 buffer_.FinalizeInstructions(region);
144 } 281 }
145 282
146 // Debugging and bringup support. 283 // Debugging and bringup support.
147 void Stop(const char* message) { UNIMPLEMENTED(); } 284 void Stop(const char* message);
148 void Unimplemented(const char* message); 285 void Unimplemented(const char* message);
149 void Untested(const char* message); 286 void Untested(const char* message);
150 void Unreachable(const char* message); 287 void Unreachable(const char* message);
151 288
152 static void InitializeMemoryWithBreakpoints(uword data, int length) { 289 static void InitializeMemoryWithBreakpoints(uword data, int length) {
153 UNIMPLEMENTED(); 290 UNIMPLEMENTED();
154 } 291 }
155 292
156 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) { 293 void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
157 UNIMPLEMENTED();
158 }
159 294
160 const Code::Comments& GetCodeComments() const { 295 const Code::Comments& GetCodeComments() const;
161 UNIMPLEMENTED();
162 return Code::Comments::New(0);
163 }
164 296
165 static const char* RegisterName(Register reg) { 297 static const char* RegisterName(Register reg) {
166 UNIMPLEMENTED(); 298 UNIMPLEMENTED();
167 return NULL; 299 return NULL;
168 } 300 }
169 301
170 static const char* FpuRegisterName(FpuRegister reg) { 302 static const char* FpuRegisterName(FpuRegister reg) {
171 UNIMPLEMENTED(); 303 UNIMPLEMENTED();
172 return NULL; 304 return NULL;
173 } 305 }
174 306
307 // Data-processing instructions.
308 void and_(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
309
310 void eor(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
311
312 void sub(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
313 void subs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
314
315 void rsb(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
316 void rsbs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
317
318 void add(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
319
320 void adds(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
321
322 void adc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
323
324 void sbc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
325
326 void rsc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
327
328 void tst(Register rn, ShifterOperand so, Condition cond = AL);
329
330 void teq(Register rn, ShifterOperand so, Condition cond = AL);
331
332 void cmp(Register rn, ShifterOperand so, Condition cond = AL);
333
334 void cmn(Register rn, ShifterOperand so, Condition cond = AL);
335
336 void orr(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
337 void orrs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
338
339 void mov(Register rd, ShifterOperand so, Condition cond = AL);
340 void movs(Register rd, ShifterOperand so, Condition cond = AL);
341
342 void bic(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
343
344 void mvn(Register rd, ShifterOperand so, Condition cond = AL);
345 void mvns(Register rd, ShifterOperand so, Condition cond = AL);
346
347 // Miscellaneous data-processing instructions.
348 void clz(Register rd, Register rm, Condition cond = AL);
349 void movw(Register rd, uint16_t imm16, Condition cond = AL);
350 void movt(Register rd, uint16_t imm16, Condition cond = AL);
351
352 // Multiply instructions.
353 void mul(Register rd, Register rn, Register rm, Condition cond = AL);
354 void mla(Register rd, Register rn, Register rm, Register ra,
355 Condition cond = AL);
356 void mls(Register rd, Register rn, Register rm, Register ra,
357 Condition cond = AL);
358 void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
359 Condition cond = AL);
360
361 // Load/store instructions.
362 void ldr(Register rd, Address ad, Condition cond = AL);
363 void str(Register rd, Address ad, Condition cond = AL);
364
365 void ldrb(Register rd, Address ad, Condition cond = AL);
366 void strb(Register rd, Address ad, Condition cond = AL);
367
368 void ldrh(Register rd, Address ad, Condition cond = AL);
369 void strh(Register rd, Address ad, Condition cond = AL);
370
371 void ldrsb(Register rd, Address ad, Condition cond = AL);
372 void ldrsh(Register rd, Address ad, Condition cond = AL);
373
374 void ldrd(Register rd, Address ad, Condition cond = AL);
375 void strd(Register rd, Address ad, Condition cond = AL);
376
377 void ldm(BlockAddressMode am, Register base,
378 RegList regs, Condition cond = AL);
379 void stm(BlockAddressMode am, Register base,
380 RegList regs, Condition cond = AL);
381
382 void ldrex(Register rd, Register rn, Condition cond = AL);
383 void strex(Register rd, Register rt, Register rn, Condition cond = AL);
384
385 // Miscellaneous instructions.
386 void clrex();
387 void nop(Condition cond = AL);
388
389 // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
390 void bkpt(uint16_t imm16);
391 void svc(uint32_t imm24);
392
393 // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
394 void vmovsr(SRegister sn, Register rt, Condition cond = AL);
395 void vmovrs(Register rt, SRegister sn, Condition cond = AL);
396 void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL);
397 void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL);
398 void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL);
399 void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL);
400 void vmovs(SRegister sd, SRegister sm, Condition cond = AL);
401 void vmovd(DRegister dd, DRegister dm, Condition cond = AL);
402
403 // Returns false if the immediate cannot be encoded.
404 bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
405 bool vmovd(DRegister dd, double d_imm, Condition cond = AL);
406
407 void vldrs(SRegister sd, Address ad, Condition cond = AL);
408 void vstrs(SRegister sd, Address ad, Condition cond = AL);
409 void vldrd(DRegister dd, Address ad, Condition cond = AL);
410 void vstrd(DRegister dd, Address ad, Condition cond = AL);
411
412 void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
413 void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
414 void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
415 void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
416 void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
417 void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
418 void vmlas(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
419 void vmlad(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
420 void vmlss(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
421 void vmlsd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
422 void vdivs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
423 void vdivd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
424
425 void vabss(SRegister sd, SRegister sm, Condition cond = AL);
426 void vabsd(DRegister dd, DRegister dm, Condition cond = AL);
427 void vnegs(SRegister sd, SRegister sm, Condition cond = AL);
428 void vnegd(DRegister dd, DRegister dm, Condition cond = AL);
429 void vsqrts(SRegister sd, SRegister sm, Condition cond = AL);
430 void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL);
431
432 void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL);
433 void vcvtds(DRegister dd, SRegister sm, Condition cond = AL);
434 void vcvtis(SRegister sd, SRegister sm, Condition cond = AL);
435 void vcvtid(SRegister sd, DRegister dm, Condition cond = AL);
436 void vcvtsi(SRegister sd, SRegister sm, Condition cond = AL);
437 void vcvtdi(DRegister dd, SRegister sm, Condition cond = AL);
438 void vcvtus(SRegister sd, SRegister sm, Condition cond = AL);
439 void vcvtud(SRegister sd, DRegister dm, Condition cond = AL);
440 void vcvtsu(SRegister sd, SRegister sm, Condition cond = AL);
441 void vcvtdu(DRegister dd, SRegister sm, Condition cond = AL);
442
443 void vcmps(SRegister sd, SRegister sm, Condition cond = AL);
444 void vcmpd(DRegister dd, DRegister dm, Condition cond = AL);
445 void vcmpsz(SRegister sd, Condition cond = AL);
446 void vcmpdz(DRegister dd, Condition cond = AL);
447 void vmstat(Condition cond = AL); // VMRS APSR_nzcv, FPSCR
448
449 // Branch instructions.
450 void b(Label* label, Condition cond = AL);
451 void bl(Label* label, Condition cond = AL);
452 void blx(Register rm, Condition cond = AL);
453
454 // Macros.
455 // Branch to an entry address that can be patched at runtime.
456 void Branch(const ExternalLabel* label);
457 void BranchLink(const ExternalLabel* label);
458
459 // Branch to entry after setting LR and storing LR at ad.
460 void BranchLinkStore(const ExternalLabel* label, Address ad);
461
462 // Branch to [base + offset] after setting LR.
463 void BranchLinkOffset(Register base, int offset);
464
465 // Add signed constant value to rd. May clobber IP.
466 void AddConstant(Register rd, int32_t value, Condition cond = AL);
467 void AddConstant(Register rd, Register rn, int32_t value,
468 Condition cond = AL);
469 void AddConstantSetFlags(Register rd, Register rn, int32_t value,
470 Condition cond = AL);
471 void AddConstantWithCarry(Register rd, Register rn, int32_t value,
472 Condition cond = AL);
473
474 // Load and Store. May clobber IP.
475 void LoadImmediate(Register rd, int32_t value, Condition cond = AL);
476 void LoadSImmediate(SRegister sd, float value, Condition cond = AL);
477 void LoadDImmediate(DRegister dd, double value,
478 Register scratch, Condition cond = AL);
479 void MarkExceptionHandler(Label* label);
480 void LoadObject(Register rd, const Object& object);
481 void LoadFromOffset(LoadOperandType type,
482 Register reg,
483 Register base,
484 int32_t offset,
485 Condition cond = AL);
486 void StoreToOffset(StoreOperandType type,
487 Register reg,
488 Register base,
489 int32_t offset,
490 Condition cond = AL);
491 void LoadSFromOffset(SRegister reg,
492 Register base,
493 int32_t offset,
494 Condition cond = AL);
495 void StoreSToOffset(SRegister reg,
496 Register base,
497 int32_t offset,
498 Condition cond = AL);
499 void LoadDFromOffset(DRegister reg,
500 Register base,
501 int32_t offset,
502 Condition cond = AL);
503 void StoreDToOffset(DRegister reg,
504 Register base,
505 int32_t offset,
506 Condition cond = AL);
507
508 void Push(Register rd, Condition cond = AL);
509 void Pop(Register rd, Condition cond = AL);
510
511 void PushList(RegList regs, Condition cond = AL);
512 void PopList(RegList regs, Condition cond = AL);
513
514 void Mov(Register rd, Register rm, Condition cond = AL);
515
516 // Convenience shift instructions. Use mov instruction with shifter operand
517 // for variants setting the status flags or using a register shift count.
518 void Lsl(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
519 void Lsr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
520 void Asr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
521 void Ror(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
522 void Rrx(Register rd, Register rm, Condition cond = AL);
523
524 // Emit data (e.g encoded instruction or immediate) in instruction stream.
525 void Emit(int32_t value);
526
175 private: 527 private:
528 AssemblerBuffer buffer_;
176 ZoneGrowableArray<int>* pointer_offsets_; 529 ZoneGrowableArray<int>* pointer_offsets_;
530 int prologue_offset_;
531
532 class CodeComment : public ZoneAllocated {
533 public:
534 CodeComment(intptr_t pc_offset, const String& comment)
535 : pc_offset_(pc_offset), comment_(comment) { }
536
537 intptr_t pc_offset() const { return pc_offset_; }
538 const String& comment() const { return comment_; }
539
540 private:
541 intptr_t pc_offset_;
542 const String& comment_;
543
544 DISALLOW_COPY_AND_ASSIGN(CodeComment);
545 };
546
547 GrowableArray<CodeComment*> comments_;
548
549 void EmitType01(Condition cond,
550 int type,
551 Opcode opcode,
552 int set_cc,
553 Register rn,
554 Register rd,
555 ShifterOperand so);
556
557 void EmitType5(Condition cond, int offset, bool link);
558
559 void EmitMemOp(Condition cond,
560 bool load,
561 bool byte,
562 Register rd,
563 Address ad);
564
565 void EmitMemOpAddressMode3(Condition cond,
566 int32_t mode,
567 Register rd,
568 Address ad);
569
570 void EmitMultiMemOp(Condition cond,
571 BlockAddressMode am,
572 bool load,
573 Register base,
574 RegList regs);
575
576 void EmitShiftImmediate(Condition cond,
577 Shift opcode,
578 Register rd,
579 Register rm,
580 ShifterOperand so);
581
582 void EmitShiftRegister(Condition cond,
583 Shift opcode,
584 Register rd,
585 Register rm,
586 ShifterOperand so);
587
588 void EmitMulOp(Condition cond,
589 int32_t opcode,
590 Register rd,
591 Register rn,
592 Register rm,
593 Register rs);
594
595 void EmitVFPsss(Condition cond,
596 int32_t opcode,
597 SRegister sd,
598 SRegister sn,
599 SRegister sm);
600
601 void EmitVFPddd(Condition cond,
602 int32_t opcode,
603 DRegister dd,
604 DRegister dn,
605 DRegister dm);
606
607 void EmitVFPsd(Condition cond,
608 int32_t opcode,
609 SRegister sd,
610 DRegister dm);
611
612 void EmitVFPds(Condition cond,
613 int32_t opcode,
614 DRegister dd,
615 SRegister sm);
616
617 void EmitBranch(Condition cond, Label* label, bool link);
618 static int32_t EncodeBranchOffset(int offset, int32_t inst);
619 static int DecodeBranchOffset(int32_t inst);
620 int32_t EncodeTstOffset(int offset, int32_t inst);
621 int DecodeTstOffset(int32_t inst);
622
623 // Returns whether or not the given register is used for passing parameters.
624 static int RegisterCompare(const Register* reg1, const Register* reg2) {
625 return *reg1 - *reg2;
626 }
627
177 DISALLOW_ALLOCATION(); 628 DISALLOW_ALLOCATION();
178 DISALLOW_COPY_AND_ASSIGN(Assembler); 629 DISALLOW_COPY_AND_ASSIGN(Assembler);
179 }; 630 };
180 631
181 } // namespace dart 632 } // namespace dart
182 633
183 #endif // VM_ASSEMBLER_ARM_H_ 634 #endif // VM_ASSEMBLER_ARM_H_
OLDNEW
« no previous file with comments | « runtime/vm/assembler.cc ('k') | runtime/vm/assembler_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698