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