blob: bad30238a5ec6535d79128d5dd48c71830d37683 [file] [log] [blame]
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#ifndef ART_SRC_ASSEMBLER_ARM_H_
4#define ART_SRC_ASSEMBLER_ARM_H_
5
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07006#include "constants.h"
7#include "managed_register.h"
8#include "logging.h"
9#include "offsets.h"
10#include "utils.h"
Ian Rogers0d666d82011-08-14 16:03:46 -070011#include <vector>
Carl Shapiroa2e18e12011-06-21 18:57:55 -070012
Carl Shapiro6b6b5f02011-06-21 15:05:09 -070013namespace art {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070014
Carl Shapiroa2e18e12011-06-21 18:57:55 -070015// Encodes Addressing Mode 1 - Data-processing operands defined in Section 5.1.
16class ShifterOperand {
17 public:
18 // Data-processing operands - Uninitialized
19 ShifterOperand() {
20 type_ = -1;
21 }
22
23 // Data-processing operands - Immediate
24 explicit ShifterOperand(uint32_t immediate) {
25 CHECK(immediate < (1 << kImmed8Bits));
26 type_ = 1;
27 encoding_ = immediate;
28 }
29
30 // Data-processing operands - Rotated immediate
31 ShifterOperand(uint32_t rotate, uint32_t immed8) {
32 CHECK((rotate < (1 << kRotateBits)) && (immed8 < (1 << kImmed8Bits)));
33 type_ = 1;
34 encoding_ = (rotate << kRotateShift) | (immed8 << kImmed8Shift);
35 }
36
37 // Data-processing operands - Register
38 explicit ShifterOperand(Register rm) {
39 type_ = 0;
40 encoding_ = static_cast<uint32_t>(rm);
41 }
42
43 // Data-processing operands - Logical shift/rotate by immediate
44 ShifterOperand(Register rm, Shift shift, uint32_t shift_imm) {
45 CHECK(shift_imm < (1 << kShiftImmBits));
46 type_ = 0;
47 encoding_ = shift_imm << kShiftImmShift |
48 static_cast<uint32_t>(shift) << kShiftShift |
49 static_cast<uint32_t>(rm);
50 }
51
52 // Data-processing operands - Logical shift/rotate by register
53 ShifterOperand(Register rm, Shift shift, Register rs) {
54 type_ = 0;
55 encoding_ = static_cast<uint32_t>(rs) << kShiftRegisterShift |
56 static_cast<uint32_t>(shift) << kShiftShift | (1 << 4) |
57 static_cast<uint32_t>(rm);
58 }
59
60 static bool CanHold(uint32_t immediate, ShifterOperand* shifter_op) {
61 // Avoid the more expensive test for frequent small immediate values.
62 if (immediate < (1 << kImmed8Bits)) {
63 shifter_op->type_ = 1;
64 shifter_op->encoding_ = (0 << kRotateShift) | (immediate << kImmed8Shift);
65 return true;
66 }
67 // Note that immediate must be unsigned for the test to work correctly.
68 for (int rot = 0; rot < 16; rot++) {
69 uint32_t imm8 = (immediate << 2*rot) | (immediate >> (32 - 2*rot));
70 if (imm8 < (1 << kImmed8Bits)) {
71 shifter_op->type_ = 1;
72 shifter_op->encoding_ = (rot << kRotateShift) | (imm8 << kImmed8Shift);
73 return true;
74 }
75 }
76 return false;
77 }
78
79 private:
80 bool is_valid() const { return (type_ == 0) || (type_ == 1); }
81
82 uint32_t type() const {
83 CHECK(is_valid());
84 return type_;
85 }
86
87 uint32_t encoding() const {
88 CHECK(is_valid());
89 return encoding_;
90 }
91
92 uint32_t type_; // Encodes the type field (bits 27-25) in the instruction.
93 uint32_t encoding_;
94
95 friend class Assembler;
96#ifdef SOURCE_ASSEMBLER_SUPPORT
97 friend class BinaryAssembler;
98#endif
99};
100
101
102enum LoadOperandType {
103 kLoadSignedByte,
104 kLoadUnsignedByte,
105 kLoadSignedHalfword,
106 kLoadUnsignedHalfword,
107 kLoadWord,
108 kLoadWordPair,
109 kLoadSWord,
110 kLoadDWord
111};
112
113
114enum StoreOperandType {
115 kStoreByte,
116 kStoreHalfword,
117 kStoreWord,
118 kStoreWordPair,
119 kStoreSWord,
120 kStoreDWord
121};
122
123
124// Load/store multiple addressing mode.
125enum BlockAddressMode {
126 // bit encoding P U W
127 DA = (0|0|0) << 21, // decrement after
128 IA = (0|4|0) << 21, // increment after
129 DB = (8|0|0) << 21, // decrement before
130 IB = (8|4|0) << 21, // increment before
131 DA_W = (0|0|1) << 21, // decrement after with writeback to base
132 IA_W = (0|4|1) << 21, // increment after with writeback to base
133 DB_W = (8|0|1) << 21, // decrement before with writeback to base
134 IB_W = (8|4|1) << 21 // increment before with writeback to base
135};
136
137
138class Address {
139 public:
140 // Memory operand addressing mode
141 enum Mode {
142 // bit encoding P U W
143 Offset = (8|4|0) << 21, // offset (w/o writeback to base)
144 PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback
145 PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback
146 NegOffset = (8|0|0) << 21, // negative offset (w/o writeback to base)
147 NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback
148 NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback
149 };
150
151 explicit Address(Register rn, int32_t offset = 0, Mode am = Offset) {
152 CHECK(IsAbsoluteUint(12, offset));
153 if (offset < 0) {
154 encoding_ = (am ^ (1 << kUShift)) | -offset; // Flip U to adjust sign.
155 } else {
156 encoding_ = am | offset;
157 }
158 encoding_ |= static_cast<uint32_t>(rn) << kRnShift;
159 }
160
161 static bool CanHoldLoadOffset(LoadOperandType type, int offset);
162 static bool CanHoldStoreOffset(StoreOperandType type, int offset);
163
164 private:
165 uint32_t encoding() const { return encoding_; }
166
167 // Encoding for addressing mode 3.
168 uint32_t encoding3() const {
169 const uint32_t offset_mask = (1 << 12) - 1;
170 uint32_t offset = encoding_ & offset_mask;
Ian Rogersb033c752011-07-20 12:22:35 -0700171 CHECK_LT(offset, 256u);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700172 return (encoding_ & ~offset_mask) | ((offset & 0xf0) << 4) | (offset & 0xf);
173 }
174
175 // Encoding for vfp load/store addressing.
176 uint32_t vencoding() const {
177 const uint32_t offset_mask = (1 << 12) - 1;
178 uint32_t offset = encoding_ & offset_mask;
179 CHECK(IsAbsoluteUint(10, offset)); // In the range -1020 to +1020.
180 CHECK(IsAligned(offset, 2)); // Multiple of 4.
181 int mode = encoding_ & ((8|4|1) << 21);
182 CHECK((mode == Offset) || (mode == NegOffset));
183 uint32_t vencoding = (encoding_ & (0xf << kRnShift)) | (offset >> 2);
184 if (mode == Offset) {
185 vencoding |= 1 << 23;
186 }
187 return vencoding;
188 }
189
190 uint32_t encoding_;
191
192 friend class Assembler;
193};
194
195
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700196class Assembler {
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700197 public:
198 Assembler() : buffer_() {}
199
200 // Data-processing instructions.
201 void and_(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
202
203 void eor(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
204
205 void sub(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
206 void subs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
207
208 void rsb(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
209 void rsbs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
210
211 void add(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
212
213 void adds(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
214
215 void adc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
216
217 void sbc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
218
219 void rsc(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
220
221 void tst(Register rn, ShifterOperand so, Condition cond = AL);
222
223 void teq(Register rn, ShifterOperand so, Condition cond = AL);
224
225 void cmp(Register rn, ShifterOperand so, Condition cond = AL);
226
227 void cmn(Register rn, ShifterOperand so, Condition cond = AL);
228
229 void orr(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
230 void orrs(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
231
232 void mov(Register rd, ShifterOperand so, Condition cond = AL);
233 void movs(Register rd, ShifterOperand so, Condition cond = AL);
234
235 void bic(Register rd, Register rn, ShifterOperand so, Condition cond = AL);
236
237 void mvn(Register rd, ShifterOperand so, Condition cond = AL);
238 void mvns(Register rd, ShifterOperand so, Condition cond = AL);
239
240 // Miscellaneous data-processing instructions.
241 void clz(Register rd, Register rm, Condition cond = AL);
242 void movw(Register rd, uint16_t imm16, Condition cond = AL);
243 void movt(Register rd, uint16_t imm16, Condition cond = AL);
244
245 // Multiply instructions.
246 void mul(Register rd, Register rn, Register rm, Condition cond = AL);
247 void mla(Register rd, Register rn, Register rm, Register ra,
248 Condition cond = AL);
249 void mls(Register rd, Register rn, Register rm, Register ra,
250 Condition cond = AL);
251 void umull(Register rd_lo, Register rd_hi, Register rn, Register rm,
252 Condition cond = AL);
253
254 // Load/store instructions.
255 void ldr(Register rd, Address ad, Condition cond = AL);
256 void str(Register rd, Address ad, Condition cond = AL);
257
258 void ldrb(Register rd, Address ad, Condition cond = AL);
259 void strb(Register rd, Address ad, Condition cond = AL);
260
261 void ldrh(Register rd, Address ad, Condition cond = AL);
262 void strh(Register rd, Address ad, Condition cond = AL);
263
264 void ldrsb(Register rd, Address ad, Condition cond = AL);
265 void ldrsh(Register rd, Address ad, Condition cond = AL);
266
267 void ldrd(Register rd, Address ad, Condition cond = AL);
268 void strd(Register rd, Address ad, Condition cond = AL);
269
270 void ldm(BlockAddressMode am, Register base,
271 RegList regs, Condition cond = AL);
272 void stm(BlockAddressMode am, Register base,
273 RegList regs, Condition cond = AL);
274
275 void ldrex(Register rd, Register rn, Condition cond = AL);
276 void strex(Register rd, Register rt, Register rn, Condition cond = AL);
277
278 // Miscellaneous instructions.
279 void clrex();
280 void nop(Condition cond = AL);
281
282 // Note that gdb sets breakpoints using the undefined instruction 0xe7f001f0.
283 void bkpt(uint16_t imm16);
284 void svc(uint32_t imm24);
285
286 // Floating point instructions (VFPv3-D16 and VFPv3-D32 profiles).
287 void vmovsr(SRegister sn, Register rt, Condition cond = AL);
288 void vmovrs(Register rt, SRegister sn, Condition cond = AL);
289 void vmovsrr(SRegister sm, Register rt, Register rt2, Condition cond = AL);
290 void vmovrrs(Register rt, Register rt2, SRegister sm, Condition cond = AL);
291 void vmovdrr(DRegister dm, Register rt, Register rt2, Condition cond = AL);
292 void vmovrrd(Register rt, Register rt2, DRegister dm, Condition cond = AL);
293 void vmovs(SRegister sd, SRegister sm, Condition cond = AL);
294 void vmovd(DRegister dd, DRegister dm, Condition cond = AL);
295
296 // Returns false if the immediate cannot be encoded.
297 bool vmovs(SRegister sd, float s_imm, Condition cond = AL);
298 bool vmovd(DRegister dd, double d_imm, Condition cond = AL);
299
300 void vldrs(SRegister sd, Address ad, Condition cond = AL);
301 void vstrs(SRegister sd, Address ad, Condition cond = AL);
302 void vldrd(DRegister dd, Address ad, Condition cond = AL);
303 void vstrd(DRegister dd, Address ad, Condition cond = AL);
304
305 void vadds(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
306 void vaddd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
307 void vsubs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
308 void vsubd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
309 void vmuls(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
310 void vmuld(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
311 void vmlas(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
312 void vmlad(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
313 void vmlss(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
314 void vmlsd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
315 void vdivs(SRegister sd, SRegister sn, SRegister sm, Condition cond = AL);
316 void vdivd(DRegister dd, DRegister dn, DRegister dm, Condition cond = AL);
317
318 void vabss(SRegister sd, SRegister sm, Condition cond = AL);
319 void vabsd(DRegister dd, DRegister dm, Condition cond = AL);
320 void vnegs(SRegister sd, SRegister sm, Condition cond = AL);
321 void vnegd(DRegister dd, DRegister dm, Condition cond = AL);
322 void vsqrts(SRegister sd, SRegister sm, Condition cond = AL);
323 void vsqrtd(DRegister dd, DRegister dm, Condition cond = AL);
324
325 void vcvtsd(SRegister sd, DRegister dm, Condition cond = AL);
326 void vcvtds(DRegister dd, SRegister sm, Condition cond = AL);
327 void vcvtis(SRegister sd, SRegister sm, Condition cond = AL);
328 void vcvtid(SRegister sd, DRegister dm, Condition cond = AL);
329 void vcvtsi(SRegister sd, SRegister sm, Condition cond = AL);
330 void vcvtdi(DRegister dd, SRegister sm, Condition cond = AL);
331 void vcvtus(SRegister sd, SRegister sm, Condition cond = AL);
332 void vcvtud(SRegister sd, DRegister dm, Condition cond = AL);
333 void vcvtsu(SRegister sd, SRegister sm, Condition cond = AL);
334 void vcvtdu(DRegister dd, SRegister sm, Condition cond = AL);
335
336 void vcmps(SRegister sd, SRegister sm, Condition cond = AL);
337 void vcmpd(DRegister dd, DRegister dm, Condition cond = AL);
338 void vcmpsz(SRegister sd, Condition cond = AL);
339 void vcmpdz(DRegister dd, Condition cond = AL);
340 void vmstat(Condition cond = AL); // VMRS APSR_nzcv, FPSCR
341
342 // Branch instructions.
343 void b(Label* label, Condition cond = AL);
344 void bl(Label* label, Condition cond = AL);
345 void blx(Register rm, Condition cond = AL);
346
347 // Macros.
348 // Add signed constant value to rd. May clobber IP.
349 void AddConstant(Register rd, int32_t value, Condition cond = AL);
350 void AddConstant(Register rd, Register rn, int32_t value,
351 Condition cond = AL);
352 void AddConstantSetFlags(Register rd, Register rn, int32_t value,
353 Condition cond = AL);
354 void AddConstantWithCarry(Register rd, Register rn, int32_t value,
355 Condition cond = AL);
356
357 // Load and Store. May clobber IP.
358 void LoadImmediate(Register rd, int32_t value, Condition cond = AL);
359 void LoadSImmediate(SRegister sd, float value, Condition cond = AL);
360 void LoadDImmediate(DRegister dd, double value,
361 Register scratch, Condition cond = AL);
362 void MarkExceptionHandler(Label* label);
363 void LoadFromOffset(LoadOperandType type,
364 Register reg,
365 Register base,
366 int32_t offset,
367 Condition cond = AL);
368 void StoreToOffset(StoreOperandType type,
369 Register reg,
370 Register base,
371 int32_t offset,
372 Condition cond = AL);
373 void LoadSFromOffset(SRegister reg,
374 Register base,
375 int32_t offset,
376 Condition cond = AL);
377 void StoreSToOffset(SRegister reg,
378 Register base,
379 int32_t offset,
380 Condition cond = AL);
381 void LoadDFromOffset(DRegister reg,
382 Register base,
383 int32_t offset,
384 Condition cond = AL);
385 void StoreDToOffset(DRegister reg,
386 Register base,
387 int32_t offset,
388 Condition cond = AL);
389
390 void Push(Register rd, Condition cond = AL);
391 void Pop(Register rd, Condition cond = AL);
392
393 void PushList(RegList regs, Condition cond = AL);
394 void PopList(RegList regs, Condition cond = AL);
395
396 void Mov(Register rd, Register rm, Condition cond = AL);
397
398 // Convenience shift instructions. Use mov instruction with shifter operand
399 // for variants setting the status flags or using a register shift count.
400 void Lsl(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
401 void Lsr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
402 void Asr(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
403 void Ror(Register rd, Register rm, uint32_t shift_imm, Condition cond = AL);
404 void Rrx(Register rd, Register rm, Condition cond = AL);
405
406 // Encode a signed constant in tst instructions, only affecting the flags.
407 void EncodeUint32InTstInstructions(uint32_t data);
408 // ... and decode from a pc pointing to the start of encoding instructions.
409 static uint32_t DecodeUint32FromTstInstructions(uword pc);
410 static bool IsInstructionForExceptionHandling(uword pc);
411
Ian Rogersb033c752011-07-20 12:22:35 -0700412 // Emit code that will create an activation on the stack
Ian Rogers0d666d82011-08-14 16:03:46 -0700413 void BuildFrame(size_t frame_size, ManagedRegister method_reg,
414 const std::vector<ManagedRegister>& spill_regs);
Ian Rogersb033c752011-07-20 12:22:35 -0700415
416 // Emit code that will remove an activation from the stack
Ian Rogers0d666d82011-08-14 16:03:46 -0700417 void RemoveFrame(size_t frame_size,
418 const std::vector<ManagedRegister>& spill_regs);
419
420 // Fill registers from spill area, excluding R0 (Method*) and LR
421 void FillFromSpillArea(const std::vector<ManagedRegister>& spill_regs,
422 size_t displacement);
Ian Rogersb033c752011-07-20 12:22:35 -0700423
424 void IncreaseFrameSize(size_t adjust);
425 void DecreaseFrameSize(size_t adjust);
426
427 // Store bytes from the given register onto the stack
428 void Store(FrameOffset dest, ManagedRegister src, size_t size);
Ian Rogersb033c752011-07-20 12:22:35 -0700429 void StoreRef(FrameOffset dest, ManagedRegister src);
Ian Rogersdf20fe02011-07-20 20:34:16 -0700430 void StoreRawPtr(FrameOffset dest, ManagedRegister src);
431
Ian Rogersb033c752011-07-20 12:22:35 -0700432 void CopyRef(FrameOffset dest, FrameOffset src, ManagedRegister scratch);
433 void LoadRef(ManagedRegister dest, ManagedRegister base, MemberOffset offs);
Ian Rogersa04d3972011-08-17 11:33:44 -0700434 void LoadRawPtr(ManagedRegister dest, ManagedRegister base, Offset offs);
Ian Rogersb033c752011-07-20 12:22:35 -0700435
436 void StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
437 ManagedRegister scratch);
438 void StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
439 ManagedRegister scratch);
440
441 void Load(ManagedRegister dest, FrameOffset src, size_t size);
442
443 void LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset offs);
444 void CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset thr_offs,
445 ManagedRegister scratch);
446 void CopyRawPtrToThread(ThreadOffset thr_offs, FrameOffset fr_offs,
447 ManagedRegister scratch);
448
449 void StoreStackOffsetToThread(ThreadOffset thr_offs, FrameOffset fr_offs,
450 ManagedRegister scratch);
Ian Rogers45a76cb2011-07-21 22:00:15 -0700451 void StoreStackPointerToThread(ThreadOffset thr_offs);
Ian Rogersb033c752011-07-20 12:22:35 -0700452
453 void Move(ManagedRegister dest, ManagedRegister src);
454 void Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch,
455 size_t size);
456 void CreateStackHandle(ManagedRegister out_reg, FrameOffset handle_offset,
457 ManagedRegister in_reg, bool null_allowed);
458
459 void CreateStackHandle(FrameOffset out_off, FrameOffset handle_offset,
460 ManagedRegister scratch, bool null_allowed);
461
Ian Rogersdf20fe02011-07-20 20:34:16 -0700462 void LoadReferenceFromStackHandle(ManagedRegister dst, ManagedRegister src);
Ian Rogersb033c752011-07-20 12:22:35 -0700463
464 void ValidateRef(ManagedRegister src, bool could_be_null);
465
466 void ValidateRef(FrameOffset src, bool could_be_null);
467
Ian Rogersdf20fe02011-07-20 20:34:16 -0700468 void Call(ManagedRegister base, Offset offset, ManagedRegister scratch);
Carl Shapiroe2d373e2011-07-25 15:20:06 -0700469 void Call(FrameOffset base, Offset offset, ManagedRegister scratch);
Ian Rogersb033c752011-07-20 12:22:35 -0700470
Ian Rogers45a76cb2011-07-21 22:00:15 -0700471 // Generate code to check if Thread::Current()->suspend_count_ is non-zero
472 // and branch to a SuspendSlowPath if it is. The SuspendSlowPath will continue
473 // at the next instruction.
474 void SuspendPoll(ManagedRegister scratch, ManagedRegister return_reg,
475 FrameOffset return_save_location, size_t return_size);
476
477 // Generate code to check if Thread::Current()->exception_ is non-null
478 // and branch to a ExceptionSlowPath if it is.
479 void ExceptionPoll(ManagedRegister scratch);
480
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700481 // Emit data (e.g. encoded instruction or immediate) to the
482 // instruction stream.
483 void Emit(int32_t value);
484
485 void Bind(Label* label);
486
Ian Rogers45a76cb2011-07-21 22:00:15 -0700487 void EmitSlowPaths() { buffer_.EmitSlowPaths(this); }
488
Ian Rogersb033c752011-07-20 12:22:35 -0700489 size_t CodeSize() const { return buffer_.Size(); }
490
491 void FinalizeInstructions(const MemoryRegion& region) {
492 buffer_.FinalizeInstructions(region);
493 }
494
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700495 private:
496 AssemblerBuffer buffer_;
497
498 void EmitType01(Condition cond,
499 int type,
500 Opcode opcode,
501 int set_cc,
502 Register rn,
503 Register rd,
504 ShifterOperand so);
505
506 void EmitType5(Condition cond, int offset, bool link);
507
508 void EmitMemOp(Condition cond,
509 bool load,
510 bool byte,
511 Register rd,
512 Address ad);
513
514 void EmitMemOpAddressMode3(Condition cond,
515 int32_t mode,
516 Register rd,
517 Address ad);
518
519 void EmitMultiMemOp(Condition cond,
520 BlockAddressMode am,
521 bool load,
522 Register base,
523 RegList regs);
524
525 void EmitShiftImmediate(Condition cond,
526 Shift opcode,
527 Register rd,
528 Register rm,
529 ShifterOperand so);
530
531 void EmitShiftRegister(Condition cond,
532 Shift opcode,
533 Register rd,
534 Register rm,
535 ShifterOperand so);
536
537 void EmitMulOp(Condition cond,
538 int32_t opcode,
539 Register rd,
540 Register rn,
541 Register rm,
542 Register rs);
543
544 void EmitVFPsss(Condition cond,
545 int32_t opcode,
546 SRegister sd,
547 SRegister sn,
548 SRegister sm);
549
550 void EmitVFPddd(Condition cond,
551 int32_t opcode,
552 DRegister dd,
553 DRegister dn,
554 DRegister dm);
555
556 void EmitVFPsd(Condition cond,
557 int32_t opcode,
558 SRegister sd,
559 DRegister dm);
560
561 void EmitVFPds(Condition cond,
562 int32_t opcode,
563 DRegister dd,
564 SRegister sm);
565
566 void EmitBranch(Condition cond, Label* label, bool link);
567 static int32_t EncodeBranchOffset(int offset, int32_t inst);
568 static int DecodeBranchOffset(int32_t inst);
569 int32_t EncodeTstOffset(int offset, int32_t inst);
570 int DecodeTstOffset(int32_t inst);
571
572 // Returns whether or not the given register is used for passing parameters.
573 static int RegisterCompare(const Register* reg1, const Register* reg2) {
574 return *reg1 - *reg2;
575 }
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700576};
577
Ian Rogersb033c752011-07-20 12:22:35 -0700578} // namespace art
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700579
580#endif // ART_SRC_ASSEMBLER_ARM_H_