blob: 0dea3f5c6fbdb6a86ec082784af45afc372d42fc [file] [log] [blame]
Jeff Browned07e002011-02-03 17:46:23 -08001/*---------------------------------------------------------------*/
2/*--- begin host_arm_defs.h ---*/
3/*---------------------------------------------------------------*/
4
5/*
6 This file is part of Valgrind, a dynamic binary instrumentation
7 framework.
8
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +04009 Copyright (C) 2004-2011 OpenWorks LLP
Jeff Browned07e002011-02-03 17:46:23 -080010 info@open-works.net
11
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 02110-1301, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30#ifndef __VEX_HOST_ARM_DEFS_H
31#define __VEX_HOST_ARM_DEFS_H
32
33extern UInt arm_hwcaps;
34
35
36/* --------- Registers. --------- */
37
38/* The usual HReg abstraction.
39 There are 16 general purpose regs.
40*/
41
42extern void ppHRegARM ( HReg );
43
44extern HReg hregARM_R0 ( void );
45extern HReg hregARM_R1 ( void );
46extern HReg hregARM_R2 ( void );
47extern HReg hregARM_R3 ( void );
48extern HReg hregARM_R4 ( void );
49extern HReg hregARM_R5 ( void );
50extern HReg hregARM_R6 ( void );
51extern HReg hregARM_R7 ( void );
52extern HReg hregARM_R8 ( void );
53extern HReg hregARM_R9 ( void );
54extern HReg hregARM_R10 ( void );
55extern HReg hregARM_R11 ( void );
56extern HReg hregARM_R12 ( void );
57extern HReg hregARM_R13 ( void );
58extern HReg hregARM_R14 ( void );
59extern HReg hregARM_R15 ( void );
60extern HReg hregARM_D8 ( void );
61extern HReg hregARM_D9 ( void );
62extern HReg hregARM_D10 ( void );
63extern HReg hregARM_D11 ( void );
64extern HReg hregARM_D12 ( void );
65extern HReg hregARM_S26 ( void );
66extern HReg hregARM_S27 ( void );
67extern HReg hregARM_S28 ( void );
68extern HReg hregARM_S29 ( void );
69extern HReg hregARM_S30 ( void );
70extern HReg hregARM_Q8 ( void );
71extern HReg hregARM_Q9 ( void );
72extern HReg hregARM_Q10 ( void );
73extern HReg hregARM_Q11 ( void );
74extern HReg hregARM_Q12 ( void );
75extern HReg hregARM_Q13 ( void );
76extern HReg hregARM_Q14 ( void );
77extern HReg hregARM_Q15 ( void );
78
79/* Number of registers used arg passing in function calls */
80#define ARM_N_ARGREGS 4 /* r0, r1, r2, r3 */
81
82
83/* --------- Condition codes. --------- */
84
85typedef
86 enum {
87 ARMcc_EQ = 0, /* equal : Z=1 */
88 ARMcc_NE = 1, /* not equal : Z=0 */
89
90 ARMcc_HS = 2, /* >=u (higher or same) : C=1 */
91 ARMcc_LO = 3, /* <u (lower) : C=0 */
92
93 ARMcc_MI = 4, /* minus (negative) : N=1 */
94 ARMcc_PL = 5, /* plus (zero or +ve) : N=0 */
95
96 ARMcc_VS = 6, /* overflow : V=1 */
97 ARMcc_VC = 7, /* no overflow : V=0 */
98
99 ARMcc_HI = 8, /* >u (higher) : C=1 && Z=0 */
100 ARMcc_LS = 9, /* <=u (lower or same) : C=0 || Z=1 */
101
102 ARMcc_GE = 10, /* >=s (signed greater or equal) : N=V */
103 ARMcc_LT = 11, /* <s (signed less than) : N!=V */
104
105 ARMcc_GT = 12, /* >s (signed greater) : Z=0 && N=V */
106 ARMcc_LE = 13, /* <=s (signed less or equal) : Z=1 || N!=V */
107
108 ARMcc_AL = 14, /* always (unconditional) */
109 ARMcc_NV = 15 /* never (basically undefined meaning), deprecated */
110 }
111 ARMCondCode;
112
113extern HChar* showARMCondCode ( ARMCondCode );
114
115
116
117/* --------- Memory address expressions (amodes). --------- */
118
119/* --- Addressing Mode 1 --- */
120typedef
121 enum {
122 ARMam1_RI=1, /* reg +/- imm12 */
123 ARMam1_RRS /* reg1 + (reg2 << 0, 1 2 or 3) */
124 }
125 ARMAMode1Tag;
126
127typedef
128 struct {
129 ARMAMode1Tag tag;
130 union {
131 struct {
132 HReg reg;
133 Int simm13; /* -4095 .. +4095 */
134 } RI;
135 struct {
136 HReg base;
137 HReg index;
138 UInt shift; /* 0, 1 2 or 3 */
139 } RRS;
140 } ARMam1;
141 }
142 ARMAMode1;
143
144extern ARMAMode1* ARMAMode1_RI ( HReg reg, Int simm13 );
145extern ARMAMode1* ARMAMode1_RRS ( HReg base, HReg index, UInt shift );
146
147extern void ppARMAMode1 ( ARMAMode1* );
148
149
150/* --- Addressing Mode 2 --- */
151typedef
152 enum {
153 ARMam2_RI=3, /* reg +/- imm8 */
154 ARMam2_RR /* reg1 + reg2 */
155 }
156 ARMAMode2Tag;
157
158typedef
159 struct {
160 ARMAMode2Tag tag;
161 union {
162 struct {
163 HReg reg;
164 Int simm9; /* -255 .. 255 */
165 } RI;
166 struct {
167 HReg base;
168 HReg index;
169 } RR;
170 } ARMam2;
171 }
172 ARMAMode2;
173
174extern ARMAMode2* ARMAMode2_RI ( HReg reg, Int simm9 );
175extern ARMAMode2* ARMAMode2_RR ( HReg base, HReg index );
176
177extern void ppARMAMode2 ( ARMAMode2* );
178
179
180/* --- Addressing Mode suitable for VFP --- */
181/* The simm11 is encoded as 8 bits + 1 sign bit,
182 so can only be 0 % 4. */
183typedef
184 struct {
185 HReg reg;
186 Int simm11; /* -1020, -1016 .. 1016, 1020 */
187 }
188 ARMAModeV;
189
190extern ARMAModeV* mkARMAModeV ( HReg reg, Int simm11 );
191
192extern void ppARMAModeV ( ARMAModeV* );
193
194/* --- Addressing Mode suitable for Neon --- */
195typedef
196 enum {
197 ARMamN_R=5,
198 ARMamN_RR
199 /* ... */
200 }
201 ARMAModeNTag;
202
203typedef
204 struct {
205 ARMAModeNTag tag;
206 union {
207 struct {
208 HReg rN;
209 HReg rM;
210 } RR;
211 struct {
212 HReg rN;
213 } R;
214 /* ... */
215 } ARMamN;
216 }
217 ARMAModeN;
218
219extern ARMAModeN* mkARMAModeN_RR ( HReg, HReg );
220extern ARMAModeN* mkARMAModeN_R ( HReg );
221extern void ppARMAModeN ( ARMAModeN* );
222
223/* --------- Reg or imm-8x4 operands --------- */
224/* a.k.a (a very restricted form of) Shifter Operand,
225 in the ARM parlance. */
226
227typedef
228 enum {
229 ARMri84_I84=7, /* imm8 `ror` (2 * imm4) */
230 ARMri84_R /* reg */
231 }
232 ARMRI84Tag;
233
234typedef
235 struct {
236 ARMRI84Tag tag;
237 union {
238 struct {
239 UShort imm8;
240 UShort imm4;
241 } I84;
242 struct {
243 HReg reg;
244 } R;
245 } ARMri84;
246 }
247 ARMRI84;
248
249extern ARMRI84* ARMRI84_I84 ( UShort imm8, UShort imm4 );
250extern ARMRI84* ARMRI84_R ( HReg );
251
252extern void ppARMRI84 ( ARMRI84* );
253
254
255/* --------- Reg or imm5 operands --------- */
256typedef
257 enum {
258 ARMri5_I5=9, /* imm5, 1 .. 31 only (no zero!) */
259 ARMri5_R /* reg */
260 }
261 ARMRI5Tag;
262
263typedef
264 struct {
265 ARMRI5Tag tag;
266 union {
267 struct {
268 UInt imm5;
269 } I5;
270 struct {
271 HReg reg;
272 } R;
273 } ARMri5;
274 }
275 ARMRI5;
276
277extern ARMRI5* ARMRI5_I5 ( UInt imm5 );
278extern ARMRI5* ARMRI5_R ( HReg );
279
280extern void ppARMRI5 ( ARMRI5* );
281
282/* -------- Neon Immediate operand -------- */
283
284/* imm8 = abcdefgh, B = NOT(b);
285
286type | value (64bit binary)
287-----+-------------------------------------------------------------------------
288 0 | 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh
289 1 | 00000000 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000
290 2 | 00000000 abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000
291 3 | abcdefgh 00000000 00000000 00000000 abcdefgh 00000000 00000000 00000000
292 4 | 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh
293 5 | abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000 abcdefgh 00000000
294 6 | abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
295 7 | 00000000 00000000 abcdefgh 11111111 00000000 00000000 abcdefgh 11111111
296 8 | 00000000 abcdefgh 11111111 11111111 00000000 abcdefgh 11111111 11111111
297 9 | aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
298 10 | aBbbbbbc defgh000 00000000 00000000 aBbbbbbc defgh000 00000000 00000000
299-----+-------------------------------------------------------------------------
300
301Type 10 is:
302 (-1)^S * 2^exp * mantissa
303where S = a, exp = UInt(B:c:d) - 3, mantissa = (16 + UInt(e:f:g:h)) / 16
304*/
305
306typedef
307 struct {
308 UInt type;
309 UInt imm8;
310 }
311 ARMNImm;
312
313extern ARMNImm* ARMNImm_TI ( UInt type, UInt imm8 );
314extern ULong ARMNImm_to_Imm64 ( ARMNImm* );
315extern ARMNImm* Imm64_to_ARMNImm ( ULong );
316
317extern void ppARMNImm ( ARMNImm* );
318
319/* ------ Neon Register or Scalar Operand ------ */
320
321typedef
322 enum {
323 ARMNRS_Reg=11,
324 ARMNRS_Scalar
325 }
326 ARMNRS_tag;
327
328typedef
329 struct {
330 ARMNRS_tag tag;
331 HReg reg;
332 UInt index;
333 }
334 ARMNRS;
335
336extern ARMNRS* mkARMNRS(ARMNRS_tag, HReg reg, UInt index);
337extern void ppARMNRS ( ARMNRS* );
338
339/* --------- Instructions. --------- */
340
341/* --------- */
342typedef
343 enum {
344 ARMalu_ADD=20, /* plain 32-bit add */
345 ARMalu_ADDS, /* 32-bit add, and set the flags */
346 ARMalu_ADC, /* 32-bit add with carry */
347 ARMalu_SUB, /* plain 32-bit subtract */
348 ARMalu_SUBS, /* 32-bit subtract, and set the flags */
349 ARMalu_SBC, /* 32-bit subtract with carry */
350 ARMalu_AND,
351 ARMalu_BIC,
352 ARMalu_OR,
353 ARMalu_XOR
354 }
355 ARMAluOp;
356
357extern HChar* showARMAluOp ( ARMAluOp op );
358
359
360typedef
361 enum {
362 ARMsh_SHL=40,
363 ARMsh_SHR,
364 ARMsh_SAR
365 }
366 ARMShiftOp;
367
368extern HChar* showARMShiftOp ( ARMShiftOp op );
369
370
371typedef
372 enum {
373 ARMun_NEG=50,
374 ARMun_NOT,
375 ARMun_CLZ
376 }
377 ARMUnaryOp;
378
379extern HChar* showARMUnaryOp ( ARMUnaryOp op );
380
381
382typedef
383 enum {
384 ARMmul_PLAIN=60,
385 ARMmul_ZX,
386 ARMmul_SX
387 }
388 ARMMulOp;
389
390extern HChar* showARMMulOp ( ARMMulOp op );
391
392
393typedef
394 enum {
395 ARMvfp_ADD=70,
396 ARMvfp_SUB,
397 ARMvfp_MUL,
398 ARMvfp_DIV
399 }
400 ARMVfpOp;
401
402extern HChar* showARMVfpOp ( ARMVfpOp op );
403
404
405typedef
406 enum {
407 ARMvfpu_COPY=80,
408 ARMvfpu_NEG,
409 ARMvfpu_ABS,
410 ARMvfpu_SQRT
411 }
412 ARMVfpUnaryOp;
413
414extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
415
416typedef
417 enum {
418 ARMneon_VAND=90,
419 ARMneon_VORR,
420 ARMneon_VXOR,
421 ARMneon_VADD,
422 ARMneon_VADDFP,
423 ARMneon_VRHADDS,
424 ARMneon_VRHADDU,
425 ARMneon_VPADDFP,
426 ARMneon_VABDFP,
427 ARMneon_VSUB,
428 ARMneon_VSUBFP,
429 ARMneon_VMAXU,
430 ARMneon_VMAXS,
431 ARMneon_VMAXF,
432 ARMneon_VMINU,
433 ARMneon_VMINS,
434 ARMneon_VMINF,
435 ARMneon_VQADDU,
436 ARMneon_VQADDS,
437 ARMneon_VQSUBU,
438 ARMneon_VQSUBS,
439 ARMneon_VCGTU,
440 ARMneon_VCGTS,
441 ARMneon_VCGEU,
442 ARMneon_VCGES,
443 ARMneon_VCGTF,
444 ARMneon_VCGEF,
445 ARMneon_VCEQ,
446 ARMneon_VCEQF,
447 ARMneon_VEXT,
448 ARMneon_VMUL,
449 ARMneon_VMULFP,
450 ARMneon_VMULLU,
451 ARMneon_VMULLS,
452 ARMneon_VMULP,
453 ARMneon_VMULLP,
454 ARMneon_VQDMULH,
455 ARMneon_VQRDMULH,
456 ARMneon_VPADD,
457 ARMneon_VPMINU,
458 ARMneon_VPMINS,
459 ARMneon_VPMINF,
460 ARMneon_VPMAXU,
461 ARMneon_VPMAXS,
462 ARMneon_VPMAXF,
463 ARMneon_VTBL,
464 ARMneon_VQDMULL,
465 ARMneon_VRECPS,
466 ARMneon_VRSQRTS,
467 /* ... */
468 }
469 ARMNeonBinOp;
470
471typedef
472 enum {
473 ARMneon_VSHL=150,
474 ARMneon_VSAL, /* Yah, not SAR but SAL */
475 ARMneon_VQSHL,
476 ARMneon_VQSAL
477 }
478 ARMNeonShiftOp;
479
480typedef
481 enum {
482 ARMneon_COPY=160,
483 ARMneon_COPYLU,
484 ARMneon_COPYLS,
485 ARMneon_COPYN,
486 ARMneon_COPYQNSS,
487 ARMneon_COPYQNUS,
488 ARMneon_COPYQNUU,
489 ARMneon_NOT,
490 ARMneon_EQZ,
491 ARMneon_DUP,
492 ARMneon_PADDLS,
493 ARMneon_PADDLU,
494 ARMneon_CNT,
495 ARMneon_CLZ,
496 ARMneon_CLS,
497 ARMneon_VCVTxFPxINT,
498 ARMneon_VQSHLNSS,
499 ARMneon_VQSHLNUU,
500 ARMneon_VQSHLNUS,
501 ARMneon_VCVTFtoU,
502 ARMneon_VCVTFtoS,
503 ARMneon_VCVTUtoF,
504 ARMneon_VCVTStoF,
505 ARMneon_VCVTFtoFixedU,
506 ARMneon_VCVTFtoFixedS,
507 ARMneon_VCVTFixedUtoF,
508 ARMneon_VCVTFixedStoF,
509 ARMneon_VCVTF16toF32,
510 ARMneon_VCVTF32toF16,
511 ARMneon_REV16,
512 ARMneon_REV32,
513 ARMneon_REV64,
514 ARMneon_ABS,
515 ARMneon_VNEGF,
516 ARMneon_VRECIP,
517 ARMneon_VRECIPF,
518 ARMneon_VABSFP,
519 ARMneon_VRSQRTEFP,
520 ARMneon_VRSQRTE
521 /* ... */
522 }
523 ARMNeonUnOp;
524
525typedef
526 enum {
527 ARMneon_SETELEM=200,
528 ARMneon_GETELEMU,
529 ARMneon_GETELEMS,
530 ARMneon_VDUP,
531 }
532 ARMNeonUnOpS;
533
534typedef
535 enum {
536 ARMneon_TRN=210,
537 ARMneon_ZIP,
538 ARMneon_UZP
539 /* ... */
540 }
541 ARMNeonDualOp;
542
543extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
544extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
545extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
546extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
547extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
548extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
549extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
550extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
551extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
552extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
553
554typedef
555 enum {
556 /* baseline */
557 ARMin_Alu=220,
558 ARMin_Shift,
559 ARMin_Unary,
560 ARMin_CmpOrTst,
561 ARMin_Mov,
562 ARMin_Imm32,
563 ARMin_LdSt32,
564 ARMin_LdSt16,
565 ARMin_LdSt8U,
566 ARMin_Ld8S,
567 ARMin_Goto,
568 ARMin_CMov,
569 ARMin_Call,
570 ARMin_Mul,
571 ARMin_LdrEX,
572 ARMin_StrEX,
573 /* vfp */
574 ARMin_VLdStD,
575 ARMin_VLdStS,
576 ARMin_VAluD,
577 ARMin_VAluS,
578 ARMin_VUnaryD,
579 ARMin_VUnaryS,
580 ARMin_VCmpD,
581 ARMin_VCMovD,
582 ARMin_VCMovS,
583 ARMin_VCvtSD,
584 ARMin_VXferD,
585 ARMin_VXferS,
586 ARMin_VCvtID,
587 ARMin_FPSCR,
588 ARMin_MFence,
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400589 ARMin_CLREX,
Jeff Browned07e002011-02-03 17:46:23 -0800590 /* Neon */
591 ARMin_NLdStQ,
592 ARMin_NLdStD,
593 ARMin_NUnary,
594 ARMin_NUnaryS,
595 ARMin_NDual,
596 ARMin_NBinary,
597 ARMin_NBinaryS,
598 ARMin_NShift,
599 ARMin_NeonImm,
600 ARMin_NCMovQ,
601 /* This is not a NEON instruction. Actually there is no corresponding
602 instruction in ARM instruction set at all. We need this one to
603 generate spill/reload of 128-bit registers since current register
604 allocator demands them to consist of no more than two instructions.
605 We will split this instruction into 2 or 3 ARM instructions on the
606 emiting phase.
607
608 NOTE: source and destination registers should be different! */
609 ARMin_Add32
610 }
611 ARMInstrTag;
612
613/* Destinations are on the LEFT (first operand) */
614
615typedef
616 struct {
617 ARMInstrTag tag;
618 union {
619 /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
620 struct {
621 ARMAluOp op;
622 HReg dst;
623 HReg argL;
624 ARMRI84* argR;
625 } Alu;
626 /* SHL/SHR/SAR, 2nd arg is reg or imm */
627 struct {
628 ARMShiftOp op;
629 HReg dst;
630 HReg argL;
631 ARMRI5* argR;
632 } Shift;
633 /* NOT/NEG/CLZ */
634 struct {
635 ARMUnaryOp op;
636 HReg dst;
637 HReg src;
638 } Unary;
639 /* CMP/TST; subtract/and, discard result, set NZCV */
640 struct {
641 Bool isCmp;
642 HReg argL;
643 ARMRI84* argR;
644 } CmpOrTst;
645 /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
646 struct {
647 HReg dst;
648 ARMRI84* src;
649 } Mov;
650 /* Pseudo-insn; make a 32-bit immediate */
651 struct {
652 HReg dst;
653 UInt imm32;
654 } Imm32;
655 /* 32-bit load or store */
656 struct {
657 Bool isLoad;
658 HReg rD;
659 ARMAMode1* amode;
660 } LdSt32;
661 /* 16-bit load or store */
662 struct {
663 Bool isLoad;
664 Bool signedLoad;
665 HReg rD;
666 ARMAMode2* amode;
667 } LdSt16;
668 /* 8-bit (unsigned) load or store */
669 struct {
670 Bool isLoad;
671 HReg rD;
672 ARMAMode1* amode;
673 } LdSt8U;
674 /* 8-bit signed load */
675 struct {
676 HReg rD;
677 ARMAMode2* amode;
678 } Ld8S;
679 /* Pseudo-insn. Go to guest address gnext, on given
680 condition, which could be ARMcc_AL. */
681 struct {
682 IRJumpKind jk;
683 ARMCondCode cond;
684 HReg gnext;
685 } Goto;
686 /* Mov src to dst on the given condition, which may not
687 be ARMcc_AL. */
688 struct {
689 ARMCondCode cond;
690 HReg dst;
691 ARMRI84* src;
692 } CMov;
693 /* Pseudo-insn. Call target (an absolute address), on given
694 condition (which could be ARMcc_AL). */
695 struct {
696 ARMCondCode cond;
697 HWord target;
698 Int nArgRegs; /* # regs carrying args: 0 .. 4 */
699 } Call;
700 /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3
701 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3
702 (SX) 32 *s 32 -> 64: r1:r0 = r2 *s r3
703 Why hardwired registers? Because the ARM ARM specifies
704 (eg for straight MUL) the result (Rd) and the left arg (Rm)
705 may not be the same register. That's not a constraint we
706 can enforce in the register allocator (without mucho extra
707 complexity). Hence hardwire it. At least using caller-saves
708 registers, which are less likely to be in use. */
709 struct {
710 ARMMulOp op;
711 } Mul;
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400712 /* LDREX{,H,B} r2, [r4] and
713 LDREXD r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
Jeff Browned07e002011-02-03 17:46:23 -0800714 Again, hardwired registers since this is not performance
715 critical, and there are possibly constraints on the
716 registers that we can't express in the register allocator.*/
717 struct {
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400718 Int szB; /* 1, 2, 4 or 8 */
Jeff Browned07e002011-02-03 17:46:23 -0800719 } LdrEX;
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400720 /* STREX{,H,B} r0, r2, [r4] and
721 STREXD r0, r2, r3, [r4] (on LE hosts, transferred value is r3:r2)
722 r0 = SC( [r4] = r2 ) (8, 16, 32 bit transfers)
723 r0 = SC( [r4] = r3:r2) (64 bit transfers)
Jeff Browned07e002011-02-03 17:46:23 -0800724 Ditto comment re fixed registers. */
725 struct {
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400726 Int szB; /* 1, 2, 4 or 8 */
Jeff Browned07e002011-02-03 17:46:23 -0800727 } StrEX;
728 /* VFP INSTRUCTIONS */
729 /* 64-bit Fp load/store */
730 struct {
731 Bool isLoad;
732 HReg dD;
733 ARMAModeV* amode;
734 } VLdStD;
735 /* 32-bit Fp load/store */
736 struct {
737 Bool isLoad;
738 HReg fD;
739 ARMAModeV* amode;
740 } VLdStS;
741 /* 64-bit FP binary arithmetic */
742 struct {
743 ARMVfpOp op;
744 HReg dst;
745 HReg argL;
746 HReg argR;
747 } VAluD;
748 /* 32-bit FP binary arithmetic */
749 struct {
750 ARMVfpOp op;
751 HReg dst;
752 HReg argL;
753 HReg argR;
754 } VAluS;
755 /* 64-bit FP unary, also reg-reg move */
756 struct {
757 ARMVfpUnaryOp op;
758 HReg dst;
759 HReg src;
760 } VUnaryD;
761 /* 32-bit FP unary, also reg-reg move */
762 struct {
763 ARMVfpUnaryOp op;
764 HReg dst;
765 HReg src;
766 } VUnaryS;
767 /* 64-bit FP compare and move results to CPSR (FCMPD;FMSTAT) */
768 struct {
769 HReg argL;
770 HReg argR;
771 } VCmpD;
772 /* 64-bit FP mov src to dst on the given condition, which may
773 not be ARMcc_AL. */
774 struct {
775 ARMCondCode cond;
776 HReg dst;
777 HReg src;
778 } VCMovD;
779 /* 32-bit FP mov src to dst on the given condition, which may
780 not be ARMcc_AL. */
781 struct {
782 ARMCondCode cond;
783 HReg dst;
784 HReg src;
785 } VCMovS;
786 /* Convert between 32-bit and 64-bit FP values (both ways).
787 (FCVTSD, FCVTDS) */
788 struct {
789 Bool sToD; /* True: F32->F64. False: F64->F32 */
790 HReg dst;
791 HReg src;
792 } VCvtSD;
793 /* Transfer a VFP D reg to/from two integer registers (VMOV) */
794 struct {
795 Bool toD;
796 HReg dD;
797 HReg rHi;
798 HReg rLo;
799 } VXferD;
800 /* Transfer a VFP S reg to/from an integer register (VMOV) */
801 struct {
802 Bool toS;
803 HReg fD;
804 HReg rLo;
805 } VXferS;
806 /* Convert between 32-bit ints and 64-bit FP values (both ways
807 and both signednesses). (FSITOD, FUITOD, FTOSID, FTOUID) */
808 struct {
809 Bool iToD; /* True: I32->F64. False: F64->I32 */
810 Bool syned; /* True: I32 is signed. False: I32 is unsigned */
811 HReg dst;
812 HReg src;
813 } VCvtID;
814 /* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
815 struct {
816 Bool toFPSCR;
817 HReg iReg;
818 } FPSCR;
819 /* Mem fence. An insn which fences all loads and stores as
820 much as possible before continuing. On ARM we emit the
821 sequence
822 mcr 15,0,r0,c7,c10,4 (DSB)
823 mcr 15,0,r0,c7,c10,5 (DMB)
824 mcr 15,0,r0,c7,c5,4 (ISB)
825 which is probably total overkill, but better safe than
826 sorry.
827 */
828 struct {
829 } MFence;
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400830 /* A CLREX instruction. */
831 struct {
832 } CLREX;
Jeff Browned07e002011-02-03 17:46:23 -0800833 /* Neon data processing instruction: 3 registers of the same
834 length */
835 struct {
836 ARMNeonBinOp op;
837 HReg dst;
838 HReg argL;
839 HReg argR;
840 UInt size;
841 Bool Q;
842 } NBinary;
843 struct {
844 ARMNeonBinOp op;
845 ARMNRS* dst;
846 ARMNRS* argL;
847 ARMNRS* argR;
848 UInt size;
849 Bool Q;
850 } NBinaryS;
851 struct {
852 ARMNeonShiftOp op;
853 HReg dst;
854 HReg argL;
855 HReg argR;
856 UInt size;
857 Bool Q;
858 } NShift;
859 struct {
860 Bool isLoad;
861 HReg dQ;
862 ARMAModeN *amode;
863 } NLdStQ;
864 struct {
865 Bool isLoad;
866 HReg dD;
867 ARMAModeN *amode;
868 } NLdStD;
869 struct {
870 ARMNeonUnOpS op;
871 ARMNRS* dst;
872 ARMNRS* src;
873 UInt size;
874 Bool Q;
875 } NUnaryS;
876 struct {
877 ARMNeonUnOp op;
878 HReg dst;
879 HReg src;
880 UInt size;
881 Bool Q;
882 } NUnary;
883 /* Takes two arguments and modifies them both. */
884 struct {
885 ARMNeonDualOp op;
886 HReg arg1;
887 HReg arg2;
888 UInt size;
889 Bool Q;
890 } NDual;
891 struct {
892 HReg dst;
893 ARMNImm* imm;
894 } NeonImm;
895 /* 128-bit Neon move src to dst on the given condition, which
896 may not be ARMcc_AL. */
897 struct {
898 ARMCondCode cond;
899 HReg dst;
900 HReg src;
901 } NCMovQ;
902 struct {
903 /* Note: rD != rN */
904 HReg rD;
905 HReg rN;
906 UInt imm32;
907 } Add32;
908 } ARMin;
909 }
910 ARMInstr;
911
912
913extern ARMInstr* ARMInstr_Alu ( ARMAluOp, HReg, HReg, ARMRI84* );
914extern ARMInstr* ARMInstr_Shift ( ARMShiftOp, HReg, HReg, ARMRI5* );
915extern ARMInstr* ARMInstr_Unary ( ARMUnaryOp, HReg, HReg );
916extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
917extern ARMInstr* ARMInstr_Mov ( HReg, ARMRI84* );
918extern ARMInstr* ARMInstr_Imm32 ( HReg, UInt );
919extern ARMInstr* ARMInstr_LdSt32 ( Bool isLoad, HReg, ARMAMode1* );
920extern ARMInstr* ARMInstr_LdSt16 ( Bool isLoad, Bool signedLoad,
921 HReg, ARMAMode2* );
922extern ARMInstr* ARMInstr_LdSt8U ( Bool isLoad, HReg, ARMAMode1* );
923extern ARMInstr* ARMInstr_Ld8S ( HReg, ARMAMode2* );
924extern ARMInstr* ARMInstr_Goto ( IRJumpKind, ARMCondCode, HReg gnext );
925extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src );
926extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs );
927extern ARMInstr* ARMInstr_Mul ( ARMMulOp op );
928extern ARMInstr* ARMInstr_LdrEX ( Int szB );
929extern ARMInstr* ARMInstr_StrEX ( Int szB );
930extern ARMInstr* ARMInstr_VLdStD ( Bool isLoad, HReg, ARMAModeV* );
931extern ARMInstr* ARMInstr_VLdStS ( Bool isLoad, HReg, ARMAModeV* );
932extern ARMInstr* ARMInstr_VAluD ( ARMVfpOp op, HReg, HReg, HReg );
933extern ARMInstr* ARMInstr_VAluS ( ARMVfpOp op, HReg, HReg, HReg );
934extern ARMInstr* ARMInstr_VUnaryD ( ARMVfpUnaryOp, HReg dst, HReg src );
935extern ARMInstr* ARMInstr_VUnaryS ( ARMVfpUnaryOp, HReg dst, HReg src );
936extern ARMInstr* ARMInstr_VCmpD ( HReg argL, HReg argR );
937extern ARMInstr* ARMInstr_VCMovD ( ARMCondCode, HReg dst, HReg src );
938extern ARMInstr* ARMInstr_VCMovS ( ARMCondCode, HReg dst, HReg src );
939extern ARMInstr* ARMInstr_VCvtSD ( Bool sToD, HReg dst, HReg src );
940extern ARMInstr* ARMInstr_VXferD ( Bool toD, HReg dD, HReg rHi, HReg rLo );
941extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
942extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
943 HReg dst, HReg src );
944extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
945extern ARMInstr* ARMInstr_MFence ( void );
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400946extern ARMInstr* ARMInstr_CLREX ( void );
Jeff Browned07e002011-02-03 17:46:23 -0800947extern ARMInstr* ARMInstr_NLdStQ ( Bool isLoad, HReg, ARMAModeN* );
948extern ARMInstr* ARMInstr_NLdStD ( Bool isLoad, HReg, ARMAModeN* );
949extern ARMInstr* ARMInstr_NUnary ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400950extern ARMInstr* ARMInstr_NUnaryS ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
Jeff Browned07e002011-02-03 17:46:23 -0800951 UInt, Bool );
952extern ARMInstr* ARMInstr_NDual ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
953extern ARMInstr* ARMInstr_NBinary ( ARMNeonBinOp, HReg, HReg, HReg,
954 UInt, Bool );
955extern ARMInstr* ARMInstr_NShift ( ARMNeonShiftOp, HReg, HReg, HReg,
956 UInt, Bool );
957extern ARMInstr* ARMInstr_NeonImm ( HReg, ARMNImm* );
958extern ARMInstr* ARMInstr_NCMovQ ( ARMCondCode, HReg, HReg );
959extern ARMInstr* ARMInstr_Add32 ( HReg rD, HReg rN, UInt imm32 );
960
961extern void ppARMInstr ( ARMInstr* );
962
963
964/* Some functions that insulate the register allocator from details
965 of the underlying instruction set. */
966extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
967extern void mapRegs_ARMInstr ( HRegRemap*, ARMInstr*, Bool );
968extern Bool isMove_ARMInstr ( ARMInstr*, HReg*, HReg* );
969extern Int emit_ARMInstr ( UChar* buf, Int nbuf, ARMInstr*,
Evgeniy Stepanovb32f5802011-12-20 11:21:56 +0400970 Bool,
971 void* dispatch_unassisted,
972 void* dispatch_assisted );
Jeff Browned07e002011-02-03 17:46:23 -0800973
974extern void genSpill_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
975 HReg rreg, Int offset, Bool );
976extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
977 HReg rreg, Int offset, Bool );
978
979extern void getAllocableRegs_ARM ( Int*, HReg** );
980extern HInstrArray* iselSB_ARM ( IRSB*, VexArch,
981 VexArchInfo*, VexAbiInfo* );
982
983#endif /* ndef __VEX_HOST_ARM_DEFS_H */
984
985/*---------------------------------------------------------------*/
986/*--- end host_arm_defs.h ---*/
987/*---------------------------------------------------------------*/