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