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-2012 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
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      ARMdiv_S,
388      ARMdiv_U
389   }
390   ARMMulDivOp;
391
392extern HChar* showARMMulOp ( ARMMulDivOp op );
393
394extern HChar* showARMDivOp ( ARMMulDivOp op );
395
396typedef
397   enum {
398      ARMvfp_ADD=70,
399      ARMvfp_SUB,
400      ARMvfp_MUL,
401      ARMvfp_DIV
402   }
403   ARMVfpOp;
404
405extern HChar* showARMVfpOp ( ARMVfpOp op );
406
407
408typedef
409   enum {
410      ARMvfpu_COPY=80,
411      ARMvfpu_NEG,
412      ARMvfpu_ABS,
413      ARMvfpu_SQRT
414   }
415   ARMVfpUnaryOp;
416
417extern HChar* showARMVfpUnaryOp ( ARMVfpUnaryOp op );
418
419typedef
420   enum {
421      ARMneon_VAND=90,
422      ARMneon_VORR,
423      ARMneon_VXOR,
424      ARMneon_VADD,
425      ARMneon_VADDFP,
426      ARMneon_VRHADDS,
427      ARMneon_VRHADDU,
428      ARMneon_VPADDFP,
429      ARMneon_VABDFP,
430      ARMneon_VSUB,
431      ARMneon_VSUBFP,
432      ARMneon_VMAXU,
433      ARMneon_VMAXS,
434      ARMneon_VMAXF,
435      ARMneon_VMINU,
436      ARMneon_VMINS,
437      ARMneon_VMINF,
438      ARMneon_VQADDU,
439      ARMneon_VQADDS,
440      ARMneon_VQSUBU,
441      ARMneon_VQSUBS,
442      ARMneon_VCGTU,
443      ARMneon_VCGTS,
444      ARMneon_VCGEU,
445      ARMneon_VCGES,
446      ARMneon_VCGTF,
447      ARMneon_VCGEF,
448      ARMneon_VCEQ,
449      ARMneon_VCEQF,
450      ARMneon_VEXT,
451      ARMneon_VMUL,
452      ARMneon_VMULFP,
453      ARMneon_VMULLU,
454      ARMneon_VMULLS,
455      ARMneon_VMULP,
456      ARMneon_VMULLP,
457      ARMneon_VQDMULH,
458      ARMneon_VQRDMULH,
459      ARMneon_VPADD,
460      ARMneon_VPMINU,
461      ARMneon_VPMINS,
462      ARMneon_VPMINF,
463      ARMneon_VPMAXU,
464      ARMneon_VPMAXS,
465      ARMneon_VPMAXF,
466      ARMneon_VTBL,
467      ARMneon_VQDMULL,
468      ARMneon_VRECPS,
469      ARMneon_VRSQRTS,
470      /* ... */
471   }
472   ARMNeonBinOp;
473
474typedef
475   enum {
476      ARMneon_VSHL=150,
477      ARMneon_VSAL, /* Yah, not SAR but SAL */
478      ARMneon_VQSHL,
479      ARMneon_VQSAL
480   }
481   ARMNeonShiftOp;
482
483typedef
484   enum {
485      ARMneon_COPY=160,
486      ARMneon_COPYLU,
487      ARMneon_COPYLS,
488      ARMneon_COPYN,
489      ARMneon_COPYQNSS,
490      ARMneon_COPYQNUS,
491      ARMneon_COPYQNUU,
492      ARMneon_NOT,
493      ARMneon_EQZ,
494      ARMneon_DUP,
495      ARMneon_PADDLS,
496      ARMneon_PADDLU,
497      ARMneon_CNT,
498      ARMneon_CLZ,
499      ARMneon_CLS,
500      ARMneon_VCVTxFPxINT,
501      ARMneon_VQSHLNSS,
502      ARMneon_VQSHLNUU,
503      ARMneon_VQSHLNUS,
504      ARMneon_VCVTFtoU,
505      ARMneon_VCVTFtoS,
506      ARMneon_VCVTUtoF,
507      ARMneon_VCVTStoF,
508      ARMneon_VCVTFtoFixedU,
509      ARMneon_VCVTFtoFixedS,
510      ARMneon_VCVTFixedUtoF,
511      ARMneon_VCVTFixedStoF,
512      ARMneon_VCVTF16toF32,
513      ARMneon_VCVTF32toF16,
514      ARMneon_REV16,
515      ARMneon_REV32,
516      ARMneon_REV64,
517      ARMneon_ABS,
518      ARMneon_VNEGF,
519      ARMneon_VRECIP,
520      ARMneon_VRECIPF,
521      ARMneon_VABSFP,
522      ARMneon_VRSQRTEFP,
523      ARMneon_VRSQRTE
524      /* ... */
525   }
526   ARMNeonUnOp;
527
528typedef
529   enum {
530      ARMneon_SETELEM=200,
531      ARMneon_GETELEMU,
532      ARMneon_GETELEMS,
533      ARMneon_VDUP,
534   }
535   ARMNeonUnOpS;
536
537typedef
538   enum {
539      ARMneon_TRN=210,
540      ARMneon_ZIP,
541      ARMneon_UZP
542      /* ... */
543   }
544   ARMNeonDualOp;
545
546extern HChar* showARMNeonBinOp ( ARMNeonBinOp op );
547extern HChar* showARMNeonUnOp ( ARMNeonUnOp op );
548extern HChar* showARMNeonUnOpS ( ARMNeonUnOpS op );
549extern HChar* showARMNeonShiftOp ( ARMNeonShiftOp op );
550extern HChar* showARMNeonDualOp ( ARMNeonDualOp op );
551extern HChar* showARMNeonBinOpDataType ( ARMNeonBinOp op );
552extern HChar* showARMNeonUnOpDataType ( ARMNeonUnOp op );
553extern HChar* showARMNeonUnOpSDataType ( ARMNeonUnOpS op );
554extern HChar* showARMNeonShiftOpDataType ( ARMNeonShiftOp op );
555extern HChar* showARMNeonDualOpDataType ( ARMNeonDualOp op );
556
557typedef
558   enum {
559      /* baseline */
560      ARMin_Alu=220,
561      ARMin_Shift,
562      ARMin_Unary,
563      ARMin_CmpOrTst,
564      ARMin_Mov,
565      ARMin_Imm32,
566      ARMin_LdSt32,
567      ARMin_LdSt16,
568      ARMin_LdSt8U,
569      ARMin_Ld8S,
570      ARMin_XDirect,     /* direct transfer to GA */
571      ARMin_XIndir,      /* indirect transfer to GA */
572      ARMin_XAssisted,   /* assisted transfer to GA */
573      ARMin_CMov,
574      ARMin_Call,
575      ARMin_Mul,
576      ARMin_Div,
577      ARMin_LdrEX,
578      ARMin_StrEX,
579      /* vfp */
580      ARMin_VLdStD,
581      ARMin_VLdStS,
582      ARMin_VAluD,
583      ARMin_VAluS,
584      ARMin_VUnaryD,
585      ARMin_VUnaryS,
586      ARMin_VCmpD,
587      ARMin_VCMovD,
588      ARMin_VCMovS,
589      ARMin_VCvtSD,
590      ARMin_VXferD,
591      ARMin_VXferS,
592      ARMin_VCvtID,
593      ARMin_FPSCR,
594      ARMin_MFence,
595      ARMin_CLREX,
596      /* Neon */
597      ARMin_NLdStQ,
598      ARMin_NLdStD,
599      ARMin_NUnary,
600      ARMin_NUnaryS,
601      ARMin_NDual,
602      ARMin_NBinary,
603      ARMin_NBinaryS,
604      ARMin_NShift,
605      ARMin_NeonImm,
606      ARMin_NCMovQ,
607      /* This is not a NEON instruction. Actually there is no corresponding
608         instruction in ARM instruction set at all. We need this one to
609         generate spill/reload of 128-bit registers since current register
610         allocator demands them to consist of no more than two instructions.
611         We will split this instruction into 2 or 3 ARM instructions on the
612         emiting phase.
613         NOTE: source and destination registers should be different! */
614      ARMin_Add32,
615      ARMin_EvCheck,     /* Event check */
616      ARMin_ProfInc      /* 64-bit profile counter increment */
617   }
618   ARMInstrTag;
619
620/* Destinations are on the LEFT (first operand) */
621
622typedef
623   struct {
624      ARMInstrTag tag;
625      union {
626         /* ADD/SUB/AND/OR/XOR, vanilla ALU op */
627         struct {
628            ARMAluOp op;
629            HReg     dst;
630            HReg     argL;
631            ARMRI84* argR;
632         } Alu;
633         /* SHL/SHR/SAR, 2nd arg is reg or imm */
634         struct {
635            ARMShiftOp op;
636            HReg       dst;
637            HReg       argL;
638            ARMRI5*    argR;
639         } Shift;
640         /* NOT/NEG/CLZ */
641         struct {
642            ARMUnaryOp op;
643            HReg       dst;
644            HReg       src;
645         } Unary;
646         /* CMP/TST; subtract/and, discard result, set NZCV */
647         struct {
648            Bool     isCmp;
649            HReg     argL;
650            ARMRI84* argR;
651         } CmpOrTst;
652         /* MOV dst, src -- reg-reg (or reg-imm8x4) move */
653         struct {
654            HReg     dst;
655            ARMRI84* src;
656         } Mov;
657         /* Pseudo-insn; make a 32-bit immediate */
658         struct {
659            HReg dst;
660            UInt imm32;
661         } Imm32;
662         /* 32-bit load or store */
663         struct {
664            Bool       isLoad;
665            HReg       rD;
666            ARMAMode1* amode;
667         } LdSt32;
668         /* 16-bit load or store */
669         struct {
670            Bool       isLoad;
671            Bool       signedLoad;
672            HReg       rD;
673            ARMAMode2* amode;
674         } LdSt16;
675         /* 8-bit (unsigned) load or store */
676         struct {
677            Bool       isLoad;
678            HReg       rD;
679            ARMAMode1* amode;
680         } LdSt8U;
681         /* 8-bit signed load */
682         struct {
683            HReg       rD;
684            ARMAMode2* amode;
685         } Ld8S;
686         /* Update the guest R15T value, then exit requesting to chain
687            to it.  May be conditional.  Urr, use of Addr32 implicitly
688            assumes that wordsize(guest) == wordsize(host). */
689         struct {
690            Addr32      dstGA;    /* next guest address */
691            ARMAMode1*  amR15T;   /* amode in guest state for R15T */
692            ARMCondCode cond;     /* can be ARMcc_AL */
693            Bool        toFastEP; /* chain to the slow or fast point? */
694         } XDirect;
695         /* Boring transfer to a guest address not known at JIT time.
696            Not chainable.  May be conditional. */
697         struct {
698            HReg        dstGA;
699            ARMAMode1*  amR15T;
700            ARMCondCode cond; /* can be ARMcc_AL */
701         } XIndir;
702         /* Assisted transfer to a guest address, most general case.
703            Not chainable.  May be conditional. */
704         struct {
705            HReg        dstGA;
706            ARMAMode1*  amR15T;
707            ARMCondCode cond; /* can be ARMcc_AL */
708            IRJumpKind  jk;
709         } XAssisted;
710         /* Mov src to dst on the given condition, which may not
711            be ARMcc_AL. */
712         struct {
713            ARMCondCode cond;
714            HReg        dst;
715            ARMRI84*    src;
716         } CMov;
717         /* Pseudo-insn.  Call target (an absolute address), on given
718            condition (which could be ARMcc_AL). */
719         struct {
720            ARMCondCode cond;
721            HWord       target;
722            Int         nArgRegs; /* # regs carrying args: 0 .. 4 */
723         } Call;
724         /* (PLAIN) 32 *  32 -> 32:  r0    = r2 * r3
725            (ZX)    32 *u 32 -> 64:  r1:r0 = r2 *u r3
726            (SX)    32 *s 32 -> 64:  r1:r0 = r2 *s r3
727            Why hardwired registers?  Because the ARM ARM specifies
728            (eg for straight MUL) the result (Rd) and the left arg (Rm)
729            may not be the same register.  That's not a constraint we
730            can enforce in the register allocator (without mucho extra
731            complexity).  Hence hardwire it.  At least using caller-saves
732            registers, which are less likely to be in use. */
733         struct {
734            ARMMulDivOp op;
735         } Mul;
736         /* ARMdiv_S/ARMdiv_U: signed/unsigned integer divides, respectively. */
737         struct {
738            ARMMulDivOp op;
739            HReg        dst;
740            HReg        argL;
741            HReg        argR;
742         } Div;
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            Bool isLoad;
892            HReg dQ;
893            ARMAModeN *amode;
894         } NLdStQ;
895         struct {
896            Bool isLoad;
897            HReg dD;
898            ARMAModeN *amode;
899         } NLdStD;
900         struct {
901            ARMNeonUnOpS op;
902            ARMNRS*  dst;
903            ARMNRS*  src;
904            UInt size;
905            Bool Q;
906         } NUnaryS;
907         struct {
908            ARMNeonUnOp op;
909            HReg  dst;
910            HReg  src;
911            UInt size;
912            Bool Q;
913         } NUnary;
914         /* Takes two arguments and modifies them both. */
915         struct {
916            ARMNeonDualOp op;
917            HReg  arg1;
918            HReg  arg2;
919            UInt size;
920            Bool Q;
921         } NDual;
922         struct {
923            HReg dst;
924            ARMNImm* imm;
925         } NeonImm;
926         /* 128-bit Neon move src to dst on the given condition, which
927            may not be ARMcc_AL. */
928         struct {
929            ARMCondCode cond;
930            HReg        dst;
931            HReg        src;
932         } NCMovQ;
933         struct {
934            /* Note: rD != rN */
935            HReg rD;
936            HReg rN;
937            UInt imm32;
938         } Add32;
939         struct {
940            ARMAMode1* amCounter;
941            ARMAMode1* amFailAddr;
942         } EvCheck;
943         struct {
944            /* No fields.  The address of the counter to inc is
945               installed later, post-translation, by patching it in,
946               as it is not known at translation time. */
947         } ProfInc;
948      } ARMin;
949   }
950   ARMInstr;
951
952
953extern ARMInstr* ARMInstr_Alu      ( ARMAluOp, HReg, HReg, ARMRI84* );
954extern ARMInstr* ARMInstr_Shift    ( ARMShiftOp, HReg, HReg, ARMRI5* );
955extern ARMInstr* ARMInstr_Unary    ( ARMUnaryOp, HReg, HReg );
956extern ARMInstr* ARMInstr_CmpOrTst ( Bool isCmp, HReg, ARMRI84* );
957extern ARMInstr* ARMInstr_Mov      ( HReg, ARMRI84* );
958extern ARMInstr* ARMInstr_Imm32    ( HReg, UInt );
959extern ARMInstr* ARMInstr_LdSt32   ( Bool isLoad, HReg, ARMAMode1* );
960extern ARMInstr* ARMInstr_LdSt16   ( Bool isLoad, Bool signedLoad,
961                                     HReg, ARMAMode2* );
962extern ARMInstr* ARMInstr_LdSt8U   ( Bool isLoad, HReg, ARMAMode1* );
963extern ARMInstr* ARMInstr_Ld8S     ( HReg, ARMAMode2* );
964extern ARMInstr* ARMInstr_XDirect  ( Addr32 dstGA, ARMAMode1* amR15T,
965                                     ARMCondCode cond, Bool toFastEP );
966extern ARMInstr* ARMInstr_XIndir   ( HReg dstGA, ARMAMode1* amR15T,
967                                     ARMCondCode cond );
968extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T,
969                                      ARMCondCode cond, IRJumpKind jk );
970extern ARMInstr* ARMInstr_CMov     ( ARMCondCode, HReg dst, ARMRI84* src );
971extern ARMInstr* ARMInstr_Call     ( ARMCondCode, HWord, Int nArgRegs );
972extern ARMInstr* ARMInstr_Mul      ( ARMMulDivOp op );
973extern ARMInstr* ARMInstr_Div      ( ARMMulDivOp op, HReg dst, HReg argL,
974                                     HReg argR );
975extern ARMInstr* ARMInstr_LdrEX    ( Int szB );
976extern ARMInstr* ARMInstr_StrEX    ( Int szB );
977extern ARMInstr* ARMInstr_VLdStD   ( Bool isLoad, HReg, ARMAModeV* );
978extern ARMInstr* ARMInstr_VLdStS   ( Bool isLoad, HReg, ARMAModeV* );
979extern ARMInstr* ARMInstr_VAluD    ( ARMVfpOp op, HReg, HReg, HReg );
980extern ARMInstr* ARMInstr_VAluS    ( ARMVfpOp op, HReg, HReg, HReg );
981extern ARMInstr* ARMInstr_VUnaryD  ( ARMVfpUnaryOp, HReg dst, HReg src );
982extern ARMInstr* ARMInstr_VUnaryS  ( ARMVfpUnaryOp, HReg dst, HReg src );
983extern ARMInstr* ARMInstr_VCmpD    ( HReg argL, HReg argR );
984extern ARMInstr* ARMInstr_VCMovD   ( ARMCondCode, HReg dst, HReg src );
985extern ARMInstr* ARMInstr_VCMovS   ( ARMCondCode, HReg dst, HReg src );
986extern ARMInstr* ARMInstr_VCvtSD   ( Bool sToD, HReg dst, HReg src );
987extern ARMInstr* ARMInstr_VXferD   ( Bool toD, HReg dD, HReg rHi, HReg rLo );
988extern ARMInstr* ARMInstr_VXferS   ( Bool toS, HReg fD, HReg rLo );
989extern ARMInstr* ARMInstr_VCvtID   ( Bool iToD, Bool syned,
990                                     HReg dst, HReg src );
991extern ARMInstr* ARMInstr_FPSCR    ( Bool toFPSCR, HReg iReg );
992extern ARMInstr* ARMInstr_MFence   ( void );
993extern ARMInstr* ARMInstr_CLREX    ( void );
994extern ARMInstr* ARMInstr_NLdStQ   ( Bool isLoad, HReg, ARMAModeN* );
995extern ARMInstr* ARMInstr_NLdStD   ( Bool isLoad, HReg, ARMAModeN* );
996extern ARMInstr* ARMInstr_NUnary   ( ARMNeonUnOp, HReg, HReg, UInt, Bool );
997extern ARMInstr* ARMInstr_NUnaryS  ( ARMNeonUnOpS, ARMNRS*, ARMNRS*,
998                                     UInt, Bool );
999extern ARMInstr* ARMInstr_NDual    ( ARMNeonDualOp, HReg, HReg, UInt, Bool );
1000extern ARMInstr* ARMInstr_NBinary  ( ARMNeonBinOp, HReg, HReg, HReg,
1001                                     UInt, Bool );
1002extern ARMInstr* ARMInstr_NShift   ( ARMNeonShiftOp, HReg, HReg, HReg,
1003                                     UInt, Bool );
1004extern ARMInstr* ARMInstr_NeonImm  ( HReg, ARMNImm* );
1005extern ARMInstr* ARMInstr_NCMovQ   ( ARMCondCode, HReg, HReg );
1006extern ARMInstr* ARMInstr_Add32    ( HReg rD, HReg rN, UInt imm32 );
1007extern ARMInstr* ARMInstr_EvCheck  ( ARMAMode1* amCounter,
1008                                     ARMAMode1* amFailAddr );
1009extern ARMInstr* ARMInstr_ProfInc  ( void );
1010
1011extern void ppARMInstr ( ARMInstr* );
1012
1013
1014/* Some functions that insulate the register allocator from details
1015   of the underlying instruction set. */
1016extern void getRegUsage_ARMInstr ( HRegUsage*, ARMInstr*, Bool );
1017extern void mapRegs_ARMInstr     ( HRegRemap*, ARMInstr*, Bool );
1018extern Bool isMove_ARMInstr      ( ARMInstr*, HReg*, HReg* );
1019extern Int  emit_ARMInstr        ( /*MB_MOD*/Bool* is_profInc,
1020                                   UChar* buf, Int nbuf, ARMInstr* i,
1021                                   Bool mode64,
1022                                   void* disp_cp_chain_me_to_slowEP,
1023                                   void* disp_cp_chain_me_to_fastEP,
1024                                   void* disp_cp_xindir,
1025                                   void* disp_cp_xassisted );
1026
1027extern void genSpill_ARM  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1028                            HReg rreg, Int offset, Bool );
1029extern void genReload_ARM ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1030                            HReg rreg, Int offset, Bool );
1031
1032extern void getAllocableRegs_ARM ( Int*, HReg** );
1033extern HInstrArray* iselSB_ARM   ( IRSB*,
1034                                   VexArch,
1035                                   VexArchInfo*,
1036                                   VexAbiInfo*,
1037                                   Int offs_Host_EvC_Counter,
1038                                   Int offs_Host_EvC_FailAddr,
1039                                   Bool chainingAllowed,
1040                                   Bool addProfInc,
1041                                   Addr64 max_ga );
1042
1043/* How big is an event check?  This is kind of a kludge because it
1044   depends on the offsets of host_EvC_FAILADDR and
1045   host_EvC_COUNTER. */
1046extern Int evCheckSzB_ARM ( void );
1047
1048/* Perform a chaining and unchaining of an XDirect jump. */
1049extern VexInvalRange chainXDirect_ARM ( void* place_to_chain,
1050                                        void* disp_cp_chain_me_EXPECTED,
1051                                        void* place_to_jump_to );
1052
1053extern VexInvalRange unchainXDirect_ARM ( void* place_to_unchain,
1054                                          void* place_to_jump_to_EXPECTED,
1055                                          void* disp_cp_chain_me );
1056
1057/* Patch the counter location into an existing ProfInc point. */
1058extern VexInvalRange patchProfInc_ARM ( void*  place_to_patch,
1059                                        ULong* location_of_counter );
1060
1061
1062#endif /* ndef __VEX_HOST_ARM_DEFS_H */
1063
1064/*---------------------------------------------------------------*/
1065/*--- end                                     host_arm_defs.h ---*/
1066/*---------------------------------------------------------------*/
1067