1
2/*---------------------------------------------------------------*/
3/*--- begin                                   host_ppc_defs.h ---*/
4/*---------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2004-2012 OpenWorks LLP
11      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   Neither the names of the U.S. Department of Energy nor the
31   University of California nor the names of its contributors may be
32   used to endorse or promote products derived from this software
33   without prior written permission.
34*/
35
36#ifndef __VEX_HOST_PPC_DEFS_H
37#define __VEX_HOST_PPC_DEFS_H
38
39/* Num registers used for function calls */
40#define PPC_N_REGPARMS 8
41
42
43/* --------- Registers. --------- */
44
45/* The usual HReg abstraction.  There are 32 real int regs,
46   32 real float regs, and 32 real vector regs.
47*/
48
49extern void ppHRegPPC ( HReg );
50
51extern HReg hregPPC_GPR0  ( Bool mode64 ); // scratch reg / zero reg
52extern HReg hregPPC_GPR1  ( Bool mode64 ); // Stack Frame Pointer
53extern HReg hregPPC_GPR2  ( Bool mode64 ); // not used: TOC pointer
54extern HReg hregPPC_GPR3  ( Bool mode64 );
55extern HReg hregPPC_GPR4  ( Bool mode64 );
56extern HReg hregPPC_GPR5  ( Bool mode64 );
57extern HReg hregPPC_GPR6  ( Bool mode64 );
58extern HReg hregPPC_GPR7  ( Bool mode64 );
59extern HReg hregPPC_GPR8  ( Bool mode64 );
60extern HReg hregPPC_GPR9  ( Bool mode64 );
61extern HReg hregPPC_GPR10 ( Bool mode64 );
62extern HReg hregPPC_GPR11 ( Bool mode64 );
63extern HReg hregPPC_GPR12 ( Bool mode64 );
64extern HReg hregPPC_GPR13 ( Bool mode64 );
65extern HReg hregPPC_GPR14 ( Bool mode64 );
66extern HReg hregPPC_GPR15 ( Bool mode64 );
67extern HReg hregPPC_GPR16 ( Bool mode64 );
68extern HReg hregPPC_GPR17 ( Bool mode64 );
69extern HReg hregPPC_GPR18 ( Bool mode64 );
70extern HReg hregPPC_GPR19 ( Bool mode64 );
71extern HReg hregPPC_GPR20 ( Bool mode64 );
72extern HReg hregPPC_GPR21 ( Bool mode64 );
73extern HReg hregPPC_GPR22 ( Bool mode64 );
74extern HReg hregPPC_GPR23 ( Bool mode64 );
75extern HReg hregPPC_GPR24 ( Bool mode64 );
76extern HReg hregPPC_GPR25 ( Bool mode64 );
77extern HReg hregPPC_GPR26 ( Bool mode64 );
78extern HReg hregPPC_GPR27 ( Bool mode64 );
79extern HReg hregPPC_GPR28 ( Bool mode64 );
80extern HReg hregPPC_GPR29 ( Bool mode64 ); // reserved for dispatcher
81extern HReg hregPPC_GPR30 ( Bool mode64 ); // used as VMX spill temp
82extern HReg hregPPC_GPR31 ( Bool mode64 ); // GuestStatePtr (callee-saved)
83
84extern HReg hregPPC_FPR0  ( void );
85extern HReg hregPPC_FPR1  ( void );
86extern HReg hregPPC_FPR2  ( void );
87extern HReg hregPPC_FPR3  ( void );
88extern HReg hregPPC_FPR4  ( void );
89extern HReg hregPPC_FPR5  ( void );
90extern HReg hregPPC_FPR6  ( void );
91extern HReg hregPPC_FPR7  ( void );
92extern HReg hregPPC_FPR8  ( void );
93extern HReg hregPPC_FPR9  ( void );
94extern HReg hregPPC_FPR10 ( void );
95extern HReg hregPPC_FPR11 ( void );
96extern HReg hregPPC_FPR12 ( void );
97extern HReg hregPPC_FPR13 ( void );
98extern HReg hregPPC_FPR14 ( void );
99extern HReg hregPPC_FPR15 ( void );
100extern HReg hregPPC_FPR16 ( void );
101extern HReg hregPPC_FPR17 ( void );
102extern HReg hregPPC_FPR18 ( void );
103extern HReg hregPPC_FPR19 ( void );
104extern HReg hregPPC_FPR20 ( void );
105extern HReg hregPPC_FPR21 ( void );
106extern HReg hregPPC_FPR22 ( void );
107extern HReg hregPPC_FPR23 ( void );
108extern HReg hregPPC_FPR24 ( void );
109extern HReg hregPPC_FPR25 ( void );
110extern HReg hregPPC_FPR26 ( void );
111extern HReg hregPPC_FPR27 ( void );
112extern HReg hregPPC_FPR28 ( void );
113extern HReg hregPPC_FPR29 ( void );
114extern HReg hregPPC_FPR30 ( void );
115extern HReg hregPPC_FPR31 ( void );
116
117extern HReg hregPPC_VR0  ( void );
118extern HReg hregPPC_VR1  ( void );
119extern HReg hregPPC_VR2  ( void );
120extern HReg hregPPC_VR3  ( void );
121extern HReg hregPPC_VR4  ( void );
122extern HReg hregPPC_VR5  ( void );
123extern HReg hregPPC_VR6  ( void );
124extern HReg hregPPC_VR7  ( void );
125extern HReg hregPPC_VR8  ( void );
126extern HReg hregPPC_VR9  ( void );
127extern HReg hregPPC_VR10 ( void );
128extern HReg hregPPC_VR11 ( void );
129extern HReg hregPPC_VR12 ( void );
130extern HReg hregPPC_VR13 ( void );
131extern HReg hregPPC_VR14 ( void );
132extern HReg hregPPC_VR15 ( void );
133extern HReg hregPPC_VR16 ( void );
134extern HReg hregPPC_VR17 ( void );
135extern HReg hregPPC_VR18 ( void );
136extern HReg hregPPC_VR19 ( void );
137extern HReg hregPPC_VR20 ( void );
138extern HReg hregPPC_VR21 ( void );
139extern HReg hregPPC_VR22 ( void );
140extern HReg hregPPC_VR23 ( void );
141extern HReg hregPPC_VR24 ( void );
142extern HReg hregPPC_VR25 ( void );
143extern HReg hregPPC_VR26 ( void );
144extern HReg hregPPC_VR27 ( void );
145extern HReg hregPPC_VR28 ( void );
146extern HReg hregPPC_VR29 ( void );
147extern HReg hregPPC_VR30 ( void );
148extern HReg hregPPC_VR31 ( void );
149
150#define StackFramePtr(_mode64) hregPPC_GPR1(_mode64)
151#define GuestStatePtr(_mode64) hregPPC_GPR31(_mode64)
152
153
154
155/* --------- Condition codes --------- */
156
157/* This gives names from bitfields in CR; hence it names BI numbers */
158/* Using IBM/hardware indexing convention */
159typedef
160   enum {
161      // CR7, which we use for integer compares
162      Pcf_7LT  = 28,  /* neg  | lt          */
163      Pcf_7GT  = 29,  /* pos  | gt          */
164      Pcf_7EQ  = 30,  /* zero | equal       */
165      Pcf_7SO  = 31,  /* summary overflow   */
166      Pcf_NONE = 32   /* no condition; used with Pct_ALWAYS */
167   }
168   PPCCondFlag;
169
170typedef
171   enum {   /* Maps bc bitfield BO */
172      Pct_FALSE  = 0x4, /* associated PPCCondFlag must not be Pcf_NONE */
173      Pct_TRUE   = 0xC, /* associated PPCCondFlag must not be Pcf_NONE */
174      Pct_ALWAYS = 0x14 /* associated PPCCondFlag must be Pcf_NONE */
175   }
176   PPCCondTest;
177
178typedef
179   struct {
180      PPCCondFlag flag;
181      PPCCondTest test;
182   }
183   PPCCondCode;
184
185extern HChar* showPPCCondCode ( PPCCondCode );
186
187/* constructor */
188extern PPCCondCode mk_PPCCondCode ( PPCCondTest, PPCCondFlag );
189
190/* false->true, true->false */
191extern PPCCondTest invertCondTest ( PPCCondTest );
192
193
194
195
196/* --------- Memory address expressions (amodes). --------- */
197
198typedef
199   enum {
200     Pam_IR=1,      /* Immediate (signed 16-bit) + Reg */
201     Pam_RR=2       /* Reg1 + Reg2     */
202   }
203   PPCAModeTag;
204
205typedef
206   struct {
207      PPCAModeTag tag;
208      union {
209         struct {
210            HReg base;
211            Int  index;
212         } IR;
213         struct {
214            HReg base;
215            HReg index;
216         } RR;
217      } Pam;
218   }
219   PPCAMode;
220
221extern PPCAMode* PPCAMode_IR ( Int,  HReg );
222extern PPCAMode* PPCAMode_RR ( HReg, HReg );
223
224extern PPCAMode* dopyPPCAMode ( PPCAMode* );
225
226extern void ppPPCAMode ( PPCAMode* );
227
228
229/* --------- Operand, which can be a reg or a u16/s16. --------- */
230/* ("RH" == "Register or Halfword immediate") */
231typedef
232   enum {
233      Prh_Imm=3,
234      Prh_Reg=4
235   }
236   PPCRHTag;
237
238typedef
239   struct {
240      PPCRHTag tag;
241      union {
242         struct {
243            Bool   syned;
244            UShort imm16;
245         } Imm;
246         struct {
247            HReg reg;
248         } Reg;
249      }
250      Prh;
251   }
252   PPCRH;
253
254extern PPCRH* PPCRH_Imm ( Bool, UShort );
255extern PPCRH* PPCRH_Reg ( HReg );
256
257extern void ppPPCRH ( PPCRH* );
258
259
260/* --------- Operand, which can be a reg or a u32/64. --------- */
261
262typedef
263   enum {
264      Pri_Imm=5,
265      Pri_Reg=6
266   }
267   PPCRITag;
268
269typedef
270   struct {
271      PPCRITag tag;
272      union {
273         ULong Imm;
274         HReg  Reg;
275      }
276      Pri;
277   }
278   PPCRI;
279
280extern PPCRI* PPCRI_Imm ( ULong );
281extern PPCRI* PPCRI_Reg( HReg );
282
283extern void ppPPCRI ( PPCRI* );
284
285
286/* --------- Operand, which can be a vector reg or a s6. --------- */
287/* ("VI" == "Vector Register or Immediate") */
288typedef
289   enum {
290      Pvi_Imm=7,
291      Pvi_Reg=8
292   }
293   PPCVI5sTag;
294
295typedef
296   struct {
297      PPCVI5sTag tag;
298      union {
299         Char Imm5s;
300         HReg Reg;
301      }
302      Pvi;
303   }
304   PPCVI5s;
305
306extern PPCVI5s* PPCVI5s_Imm ( Char );
307extern PPCVI5s* PPCVI5s_Reg ( HReg );
308
309extern void ppPPCVI5s ( PPCVI5s* );
310
311
312/* --------- Instructions. --------- */
313
314/* --------- */
315typedef
316   enum {
317      Pun_NEG,
318      Pun_NOT,
319      Pun_CLZ32,
320      Pun_CLZ64,
321      Pun_EXTSW
322   }
323   PPCUnaryOp;
324
325extern HChar* showPPCUnaryOp ( PPCUnaryOp );
326
327
328/* --------- */
329typedef
330   enum {
331      Palu_INVALID,
332      Palu_ADD, Palu_SUB,
333      Palu_AND, Palu_OR, Palu_XOR,
334   }
335   PPCAluOp;
336
337extern
338HChar* showPPCAluOp ( PPCAluOp,
339                      Bool /* is the 2nd operand an immediate? */);
340
341
342/* --------- */
343typedef
344   enum {
345      Pshft_INVALID,
346      Pshft_SHL, Pshft_SHR, Pshft_SAR,
347   }
348   PPCShftOp;
349
350extern
351HChar* showPPCShftOp ( PPCShftOp,
352                       Bool /* is the 2nd operand an immediate? */,
353                       Bool /* is this a 32bit or 64bit op? */ );
354
355
356/* --------- */
357typedef
358   enum {
359      Pfp_INVALID,
360
361      /* Ternary */
362      Pfp_MADDD,  Pfp_MSUBD,
363      Pfp_MADDS,  Pfp_MSUBS,
364      Pfp_DFPADD, Pfp_DFPADDQ,
365      Pfp_DFPSUB, Pfp_DFPSUBQ,
366      Pfp_DFPMUL, Pfp_DFPMULQ,
367      Pfp_DFPDIV, Pfp_DFPDIVQ,
368      Pfp_DQUAQ,  Pfp_DRRNDQ,
369
370      /* Binary */
371      Pfp_ADDD, Pfp_SUBD, Pfp_MULD, Pfp_DIVD,
372      Pfp_ADDS, Pfp_SUBS, Pfp_MULS, Pfp_DIVS,
373      Pfp_DRSP, Pfp_DRDPQ, Pfp_DCTFIX, Pfp_DCTFIXQ, Pfp_DCFFIX,
374      Pfp_DQUA, Pfp_RRDTR, Pfp_DIEX, Pfp_DIEXQ,
375
376      /* Unary */
377      Pfp_SQRT, Pfp_ABS, Pfp_NEG, Pfp_MOV, Pfp_RES, Pfp_RSQRTE,
378      Pfp_FRIN, Pfp_FRIM, Pfp_FRIP, Pfp_FRIZ,
379      Pfp_DSCLI, Pfp_DSCRI, Pfp_DSCLIQ, Pfp_DSCRIQ, Pfp_DCTDP,
380      Pfp_DCTQPQ, Pfp_DCFFIXQ, Pfp_DXEX, Pfp_DXEXQ,
381
382   }
383   PPCFpOp;
384
385extern HChar* showPPCFpOp ( PPCFpOp );
386
387
388/* --------- */
389typedef
390   enum {
391      Pav_INVALID,
392
393      /* Integer Unary */
394      Pav_MOV,                             /* Mov */
395      Pav_NOT,                             /* Bitwise */
396      Pav_UNPCKH8S,  Pav_UNPCKH16S,        /* Unpack */
397      Pav_UNPCKL8S,  Pav_UNPCKL16S,
398      Pav_UNPCKHPIX, Pav_UNPCKLPIX,
399
400      /* Integer Binary */
401      Pav_AND, Pav_OR, Pav_XOR,            /* Bitwise */
402      Pav_ADDU, Pav_QADDU, Pav_QADDS,
403      Pav_SUBU, Pav_QSUBU, Pav_QSUBS,
404      Pav_OMULU, Pav_OMULS, Pav_EMULU, Pav_EMULS,
405      Pav_AVGU, Pav_AVGS,
406      Pav_MAXU, Pav_MAXS,
407      Pav_MINU, Pav_MINS,
408
409      /* Compare (always affects CR field 6) */
410      Pav_CMPEQU, Pav_CMPGTU, Pav_CMPGTS,
411
412      /* Shift */
413      Pav_SHL, Pav_SHR, Pav_SAR, Pav_ROTL,
414
415      /* Pack */
416      Pav_PACKUU, Pav_QPACKUU, Pav_QPACKSU, Pav_QPACKSS,
417      Pav_PACKPXL,
418
419      /* Merge */
420      Pav_MRGHI, Pav_MRGLO,
421   }
422   PPCAvOp;
423
424extern HChar* showPPCAvOp ( PPCAvOp );
425
426
427/* --------- */
428typedef
429   enum {
430      Pavfp_INVALID,
431
432      /* Floating point binary */
433      Pavfp_ADDF, Pavfp_SUBF, Pavfp_MULF,
434      Pavfp_MAXF, Pavfp_MINF,
435      Pavfp_CMPEQF, Pavfp_CMPGTF, Pavfp_CMPGEF,
436
437      /* Floating point unary */
438      Pavfp_RCPF, Pavfp_RSQRTF,
439      Pavfp_CVTU2F, Pavfp_CVTS2F, Pavfp_QCVTF2U, Pavfp_QCVTF2S,
440      Pavfp_ROUNDM, Pavfp_ROUNDP, Pavfp_ROUNDN, Pavfp_ROUNDZ,
441   }
442   PPCAvFpOp;
443
444extern HChar* showPPCAvFpOp ( PPCAvFpOp );
445
446
447/* --------- */
448typedef
449   enum {
450      Pin_LI,         /* load word (32/64-bit) immediate (fake insn) */
451      Pin_Alu,        /* word add/sub/and/or/xor */
452      Pin_Shft,       /* word shl/shr/sar */
453      Pin_AddSubC,    /* add/sub with read/write carry */
454      Pin_Cmp,        /* word compare */
455      Pin_Unary,      /* not, neg, clz */
456      Pin_MulL,       /* widening multiply */
457      Pin_Div,        /* div */
458      Pin_Call,       /* call to address in register */
459      Pin_XDirect,    /* direct transfer to GA */
460      Pin_XIndir,     /* indirect transfer to GA */
461      Pin_XAssisted,  /* assisted transfer to GA */
462      Pin_CMov,       /* conditional move */
463      Pin_Load,       /* zero-extending load a 8|16|32|64 bit value from mem */
464      Pin_LoadL,      /* load-linked (lwarx/ldarx) 32|64 bit value from mem */
465      Pin_Store,      /* store a 8|16|32|64 bit value to mem */
466      Pin_StoreC,     /* store-conditional (stwcx./stdcx.) 32|64 bit val */
467      Pin_Set,        /* convert condition code to value 0 or 1 */
468      Pin_MfCR,       /* move from condition register to GPR */
469      Pin_MFence,     /* mem fence */
470
471      Pin_FpUnary,    /* FP unary op */
472      Pin_FpBinary,   /* FP binary op */
473      Pin_FpMulAcc,   /* FP multipy-accumulate style op */
474      Pin_FpLdSt,     /* FP load/store */
475      Pin_FpSTFIW,    /* stfiwx */
476      Pin_FpRSP,      /* FP round IEEE754 double to IEEE754 single */
477      Pin_FpCftI,     /* fcfid[u,s,us]/fctid[u]/fctiw[u] */
478      Pin_FpCMov,     /* FP floating point conditional move */
479      Pin_FpLdFPSCR,  /* mtfsf */
480      Pin_FpCmp,      /* FP compare, generating value into int reg */
481
482      Pin_RdWrLR,     /* Read/Write Link Register */
483
484      Pin_AvLdSt,     /* AV load/store (kludging for AMode_IR) */
485      Pin_AvUnary,    /* AV unary general reg=>reg */
486
487      Pin_AvBinary,   /* AV binary general reg,reg=>reg */
488      Pin_AvBin8x16,  /* AV binary, 8x4 */
489      Pin_AvBin16x8,  /* AV binary, 16x4 */
490      Pin_AvBin32x4,  /* AV binary, 32x4 */
491
492      Pin_AvBin32Fx4, /* AV FP binary, 32Fx4 */
493      Pin_AvUn32Fx4,  /* AV FP unary,  32Fx4 */
494
495      Pin_AvPerm,     /* AV permute (shuffle) */
496      Pin_AvSel,      /* AV select */
497      Pin_AvShlDbl,   /* AV shift-left double by imm */
498      Pin_AvSplat,    /* One elem repeated throughout dst */
499      Pin_AvLdVSCR,   /* mtvscr */
500      Pin_AvCMov,     /* AV conditional move */
501      Pin_Dfp64Unary,   /* DFP64  unary op */
502      Pin_Dfp128Unary,  /* DFP128 unary op */
503      Pin_DfpShift,     /* Decimal floating point shift by immediate value */
504      Pin_Dfp64Binary,  /* DFP64  binary op */
505      Pin_Dfp128Binary, /* DFP128 binary op */
506      Pin_DfpShift128,  /* 128-bit Decimal floating point shift by
507                         * immediate value */
508      Pin_DfpD128toD64, /* DFP 128 to DFP 64 op */
509      Pin_DfpI64StoD128, /* DFP signed integer to DFP 128 */
510      Pin_DfpRound,       /* D64 round to D64 */
511      Pin_DfpRound128,    /* D128 round to D128 */
512      Pin_ExtractExpD128, /* DFP, extract 64 bit exponent */
513      Pin_InsertExpD128,  /* DFP, insert 64 bit exponent and 128 bit binary
514                           * significand into a DFP 128-bit value*/
515      Pin_Dfp64Cmp,       /* DFP 64-bit compare, generating value into
516                           * int reg */
517      Pin_Dfp128Cmp,      /* DFP 128-bit  compare, generating value into
518                           * int reg */
519      Pin_DfpQuantize,    /* D64 quantize using register value, significance
520                           * round */
521      Pin_DfpQuantize128, /* D128 quantize using register value, significance
522                           * round */
523      Pin_EvCheck,    /* Event check */
524      Pin_ProfInc     /* 64-bit profile counter increment */
525   }
526   PPCInstrTag;
527
528/* Destinations are on the LEFT (first operand) */
529
530typedef
531   struct {
532      PPCInstrTag tag;
533      union {
534         /* Get a 32/64-bit literal into a register.
535            May turn into a number of real insns. */
536         struct {
537            HReg dst;
538            ULong imm64;
539         } LI;
540         /* Integer add/sub/and/or/xor.  Limitations:
541            - For add, the immediate, if it exists, is a signed 16.
542            - For sub, the immediate, if it exists, is a signed 16
543              which may not be -32768, since no such instruction
544              exists, and so we have to emit addi with +32768, but
545              that is not possible.
546            - For and/or/xor,  the immediate, if it exists,
547              is an unsigned 16.
548         */
549         struct {
550            PPCAluOp op;
551            HReg     dst;
552            HReg     srcL;
553            PPCRH*   srcR;
554         } Alu;
555         /* Integer shl/shr/sar.
556            Limitations: the immediate, if it exists,
557            is a signed 5-bit value between 1 and 31 inclusive.
558         */
559         struct {
560            PPCShftOp op;
561            Bool      sz32;   /* mode64 has both 32 and 64bit shft */
562            HReg      dst;
563            HReg      srcL;
564            PPCRH*    srcR;
565         } Shft;
566         /*  */
567         struct {
568            Bool isAdd;  /* else sub */
569            Bool setC;   /* else read carry */
570            HReg dst;
571            HReg srcL;
572            HReg srcR;
573         } AddSubC;
574         /* If signed, the immediate, if it exists, is a signed 16,
575            else it is an unsigned 16. */
576         struct {
577            Bool   syned;
578            Bool   sz32;    /* mode64 has both 32 and 64bit cmp */
579            UInt   crfD;
580            HReg   srcL;
581            PPCRH* srcR;
582         } Cmp;
583         /* Not, Neg, Clz32/64, Extsw */
584         struct {
585            PPCUnaryOp op;
586            HReg       dst;
587            HReg       src;
588         } Unary;
589         struct {
590            Bool syned;  /* meaningless if hi32==False */
591            Bool hi;     /* False=>low, True=>high */
592            Bool sz32;   /* mode64 has both 32 & 64bit mull */
593            HReg dst;
594            HReg srcL;
595            HReg srcR;
596         } MulL;
597         /* ppc32 div/divu instruction. */
598         struct {
599            Bool extended;
600            Bool syned;
601            Bool sz32;   /* mode64 has both 32 & 64bit div */
602            HReg dst;
603            HReg srcL;
604            HReg srcR;
605         } Div;
606         /* Pseudo-insn.  Call target (an absolute address), on given
607            condition (which could be Pct_ALWAYS).  argiregs indicates
608            which of r3 .. r10 carries argument values for this call,
609            using a bit mask (1<<N is set if rN holds an arg, for N in
610            3 .. 10 inclusive). */
611         struct {
612            PPCCondCode cond;
613            Addr64      target;
614            UInt        argiregs;
615         } Call;
616         /* Update the guest CIA value, then exit requesting to chain
617            to it.  May be conditional.  Use of Addr64 in order to cope
618            with 64-bit hosts. */
619         struct {
620            Addr64      dstGA;    /* next guest address */
621            PPCAMode*   amCIA;    /* amode in guest state for CIA */
622            PPCCondCode cond;     /* can be ALWAYS */
623            Bool        toFastEP; /* chain to the slow or fast point? */
624         } XDirect;
625         /* Boring transfer to a guest address not known at JIT time.
626            Not chainable.  May be conditional. */
627         struct {
628            HReg        dstGA;
629            PPCAMode*   amCIA;
630            PPCCondCode cond; /* can be ALWAYS */
631         } XIndir;
632         /* Assisted transfer to a guest address, most general case.
633            Not chainable.  May be conditional. */
634         struct {
635            HReg        dstGA;
636            PPCAMode*   amCIA;
637            PPCCondCode cond; /* can be ALWAYS */
638            IRJumpKind  jk;
639         } XAssisted;
640         /* Mov src to dst on the given condition, which may not
641            be the bogus Pct_ALWAYS. */
642         struct {
643            PPCCondCode cond;
644            HReg        dst;
645            PPCRI*      src;
646         } CMov;
647         /* Zero extending loads.  Dst size is host word size */
648         struct {
649            UChar     sz; /* 1|2|4|8 */
650            HReg      dst;
651            PPCAMode* src;
652         } Load;
653         /* Load-and-reserve (lwarx, ldarx) */
654         struct {
655            UChar sz; /* 4|8 */
656            HReg  dst;
657            HReg  src;
658         } LoadL;
659         /* 64/32/16/8 bit stores */
660         struct {
661            UChar     sz; /* 1|2|4|8 */
662            PPCAMode* dst;
663            HReg      src;
664         } Store;
665         /* Store-conditional (stwcx., stdcx.) */
666         struct {
667            UChar sz; /* 4|8 */
668            HReg  dst;
669            HReg  src;
670         } StoreC;
671         /* Convert a ppc condition code to value 0 or 1. */
672         struct {
673            PPCCondCode cond;
674            HReg        dst;
675         } Set;
676         /* Move the entire CR to a GPR */
677         struct {
678            HReg dst;
679         } MfCR;
680         /* Mem fence.  In short, an insn which flushes all preceding
681            loads and stores as much as possible before continuing.
682            On PPC we emit a "sync". */
683         struct {
684         } MFence;
685
686         /* PPC Floating point */
687         struct {
688            PPCFpOp op;
689            HReg    dst;
690            HReg    src;
691         } FpUnary;
692         struct {
693            PPCFpOp op;
694            HReg    dst;
695            HReg    srcL;
696            HReg    srcR;
697         } FpBinary;
698         struct {
699            PPCFpOp op;
700            HReg    dst;
701            HReg    srcML;
702            HReg    srcMR;
703            HReg    srcAcc;
704         } FpMulAcc;
705         struct {
706            Bool      isLoad;
707            UChar     sz; /* only 4 (IEEE single) or 8 (IEEE double) */
708            HReg      reg;
709            PPCAMode* addr;
710         } FpLdSt;
711         struct {
712            HReg addr; /* int reg */
713            HReg data; /* float reg */
714         } FpSTFIW;
715         /* Round 64-bit FP value to 32-bit FP value in an FP reg. */
716         struct {
717            HReg src;
718            HReg dst;
719         } FpRSP;
720         /* fcfid[u,s,us]/fctid[u]/fctiw[u].  Only some combinations
721            of the various fields are allowed.  This is asserted for
722            and documented in the code for the constructor,
723            PPCInstr_FpCftI, in host_ppc_defs.c.  */
724         struct {
725            Bool fromI; /* True== I->F,    False== F->I */
726            Bool int32; /* True== I is 32, False== I is 64 */
727            Bool syned;
728            Bool flt64; /* True== F is 64, False== F is 32 */
729            HReg src;
730            HReg dst;
731         } FpCftI;
732         /* FP mov src to dst on the given condition. */
733         struct {
734            PPCCondCode cond;
735            HReg        dst;
736            HReg        src;
737         } FpCMov;
738         /* Load FP Status & Control Register */
739         struct {
740            HReg src;
741            UInt dfp_rm;
742         } FpLdFPSCR;
743         /* Do a compare, generating result into an int register. */
744         struct {
745            UChar crfD;
746            HReg  dst;
747            HReg  srcL;
748            HReg  srcR;
749         } FpCmp;
750
751         /* Read/Write Link Register */
752         struct {
753            Bool wrLR;
754            HReg gpr;
755         } RdWrLR;
756
757         /* Simplistic AltiVec */
758         struct {
759            Bool      isLoad;
760            UChar     sz;      /* 8|16|32|128 */
761            HReg      reg;
762            PPCAMode* addr;
763         } AvLdSt;
764         struct {
765            PPCAvOp op;
766            HReg    dst;
767            HReg    src;
768         } AvUnary;
769         struct {
770            PPCAvOp op;
771            HReg    dst;
772            HReg    srcL;
773            HReg    srcR;
774         } AvBinary;
775         struct {
776            PPCAvOp op;
777            HReg    dst;
778            HReg    srcL;
779            HReg    srcR;
780         } AvBin8x16;
781         struct {
782            PPCAvOp op;
783            HReg    dst;
784            HReg    srcL;
785            HReg    srcR;
786         } AvBin16x8;
787         struct {
788            PPCAvOp op;
789            HReg    dst;
790            HReg    srcL;
791            HReg    srcR;
792         } AvBin32x4;
793         struct {
794            PPCAvFpOp op;
795            HReg      dst;
796            HReg      srcL;
797            HReg      srcR;
798         } AvBin32Fx4;
799         struct {
800            PPCAvFpOp op;
801            HReg      dst;
802            HReg      src;
803         } AvUn32Fx4;
804         /* Perm,Sel,SlDbl,Splat are all weird AV permutations */
805         struct {
806            HReg dst;
807            HReg srcL;
808            HReg srcR;
809            HReg ctl;
810         } AvPerm;
811         struct {
812            HReg dst;
813            HReg srcL;
814            HReg srcR;
815            HReg ctl;
816         } AvSel;
817         struct {
818            UChar shift;
819            HReg  dst;
820            HReg  srcL;
821            HReg  srcR;
822         } AvShlDbl;
823         struct {
824            UChar    sz;   /* 8,16,32 */
825            HReg     dst;
826            PPCVI5s* src;
827         } AvSplat;
828         /* Mov src to dst on the given condition, which may not
829            be the bogus Xcc_ALWAYS. */
830         struct {
831            PPCCondCode cond;
832            HReg        dst;
833            HReg        src;
834         } AvCMov;
835         /* Load AltiVec Status & Control Register */
836         struct {
837            HReg src;
838         } AvLdVSCR;
839         struct {
840            PPCFpOp op;
841            HReg dst;
842            HReg src;
843         } Dfp64Unary;
844         struct {
845            PPCFpOp op;
846            HReg dst;
847            HReg srcL;
848            HReg srcR;
849         } Dfp64Binary;
850         struct {
851            PPCFpOp op;
852            HReg   dst;
853            HReg   src;
854            PPCRI* shift;
855         } DfpShift;
856         struct {
857            PPCFpOp op;
858            HReg dst_hi;
859            HReg dst_lo;
860            HReg src_hi;
861            HReg src_lo;
862         } Dfp128Unary;
863         struct {
864            /* The dst is used to pass the left source operand in and return
865             * the result.
866             */
867            PPCFpOp op;
868            HReg dst_hi;
869            HReg dst_lo;
870            HReg srcR_hi;
871            HReg srcR_lo;
872         } Dfp128Binary;
873         struct {
874            PPCFpOp op;
875            HReg   dst_hi;
876            HReg   dst_lo;
877            HReg   src_hi;
878            HReg   src_lo;
879            PPCRI* shift;
880         } DfpShift128;
881         struct {
882            HReg dst;
883            HReg src;
884            PPCRI* r_rmc;
885         } DfpRound;
886         struct {
887            HReg dst_hi;
888            HReg dst_lo;
889            HReg src_hi;
890            HReg src_lo;
891            PPCRI* r_rmc;
892         } DfpRound128;
893         struct {
894	    PPCFpOp op;
895            HReg dst;
896            HReg srcL;
897            HReg srcR;
898            PPCRI* rmc;
899         } DfpQuantize;
900         struct {
901	    PPCFpOp op;
902            HReg dst_hi;
903            HReg dst_lo;
904            HReg src_hi;
905            HReg src_lo;
906  	    PPCRI* rmc;
907         } DfpQuantize128;
908         struct {
909            PPCFpOp op;
910            HReg dst;
911            HReg src_hi;
912            HReg src_lo;
913         } ExtractExpD128;
914         struct {
915	    PPCFpOp op;
916            HReg dst_hi;
917            HReg dst_lo;
918            HReg srcL;
919            HReg srcR_hi;
920            HReg srcR_lo;
921         } InsertExpD128;
922         struct {
923            PPCFpOp op;
924            HReg   dst;
925            HReg   src_hi;
926            HReg   src_lo;
927         } DfpD128toD64;
928         struct {
929            PPCFpOp op;
930            HReg   dst_hi;
931            HReg   dst_lo;
932            HReg   src;
933         } DfpI64StoD128;
934         struct {
935            UChar crfD;
936            HReg  dst;
937            HReg  srcL;
938            HReg  srcR;
939         } Dfp64Cmp;
940         struct {
941            UChar crfD;
942            HReg  dst;
943            HReg  srcL_hi;
944            HReg  srcL_lo;
945            HReg  srcR_hi;
946            HReg  srcR_lo;
947         } Dfp128Cmp;
948         struct {
949            PPCAMode* amCounter;
950            PPCAMode* amFailAddr;
951         } EvCheck;
952         struct {
953            /* No fields.  The address of the counter to inc is
954               installed later, post-translation, by patching it in,
955               as it is not known at translation time. */
956         } ProfInc;
957      } Pin;
958   }
959   PPCInstr;
960
961
962extern PPCInstr* PPCInstr_LI         ( HReg, ULong, Bool );
963extern PPCInstr* PPCInstr_Alu        ( PPCAluOp, HReg, HReg, PPCRH* );
964extern PPCInstr* PPCInstr_Shft       ( PPCShftOp, Bool sz32, HReg, HReg, PPCRH* );
965extern PPCInstr* PPCInstr_AddSubC    ( Bool, Bool, HReg, HReg, HReg );
966extern PPCInstr* PPCInstr_Cmp        ( Bool, Bool, UInt, HReg, PPCRH* );
967extern PPCInstr* PPCInstr_Unary      ( PPCUnaryOp op, HReg dst, HReg src );
968extern PPCInstr* PPCInstr_MulL       ( Bool syned, Bool hi32, Bool sz32, HReg, HReg, HReg );
969extern PPCInstr* PPCInstr_Div        ( Bool extended, Bool syned, Bool sz32, HReg dst, HReg srcL, HReg srcR );
970extern PPCInstr* PPCInstr_Call       ( PPCCondCode, Addr64, UInt );
971extern PPCInstr* PPCInstr_XDirect    ( Addr64 dstGA, PPCAMode* amCIA,
972                                       PPCCondCode cond, Bool toFastEP );
973extern PPCInstr* PPCInstr_XIndir     ( HReg dstGA, PPCAMode* amCIA,
974                                       PPCCondCode cond );
975extern PPCInstr* PPCInstr_XAssisted  ( HReg dstGA, PPCAMode* amCIA,
976                                       PPCCondCode cond, IRJumpKind jk );
977extern PPCInstr* PPCInstr_CMov       ( PPCCondCode, HReg dst, PPCRI* src );
978extern PPCInstr* PPCInstr_Load       ( UChar sz,
979                                       HReg dst, PPCAMode* src, Bool mode64 );
980extern PPCInstr* PPCInstr_LoadL      ( UChar sz,
981                                       HReg dst, HReg src, Bool mode64 );
982extern PPCInstr* PPCInstr_Store      ( UChar sz, PPCAMode* dst,
983                                       HReg src, Bool mode64 );
984extern PPCInstr* PPCInstr_StoreC     ( UChar sz, HReg dst, HReg src,
985                                       Bool mode64 );
986extern PPCInstr* PPCInstr_Set        ( PPCCondCode cond, HReg dst );
987extern PPCInstr* PPCInstr_MfCR       ( HReg dst );
988extern PPCInstr* PPCInstr_MFence     ( void );
989
990extern PPCInstr* PPCInstr_FpUnary    ( PPCFpOp op, HReg dst, HReg src );
991extern PPCInstr* PPCInstr_FpBinary   ( PPCFpOp op, HReg dst, HReg srcL, HReg srcR );
992extern PPCInstr* PPCInstr_FpMulAcc   ( PPCFpOp op, HReg dst, HReg srcML,
993                                                   HReg srcMR, HReg srcAcc );
994extern PPCInstr* PPCInstr_FpLdSt     ( Bool isLoad, UChar sz, HReg, PPCAMode* );
995extern PPCInstr* PPCInstr_FpSTFIW    ( HReg addr, HReg data );
996extern PPCInstr* PPCInstr_FpRSP      ( HReg dst, HReg src );
997extern PPCInstr* PPCInstr_FpCftI     ( Bool fromI, Bool int32, Bool syned,
998                                       Bool dst64, HReg dst, HReg src );
999extern PPCInstr* PPCInstr_FpCMov     ( PPCCondCode, HReg dst, HReg src );
1000extern PPCInstr* PPCInstr_FpLdFPSCR  ( HReg src, Bool dfp_rm );
1001extern PPCInstr* PPCInstr_FpCmp      ( HReg dst, HReg srcL, HReg srcR );
1002
1003extern PPCInstr* PPCInstr_RdWrLR     ( Bool wrLR, HReg gpr );
1004
1005extern PPCInstr* PPCInstr_AvLdSt     ( Bool isLoad, UChar sz, HReg, PPCAMode* );
1006extern PPCInstr* PPCInstr_AvUnary    ( PPCAvOp op, HReg dst, HReg src );
1007extern PPCInstr* PPCInstr_AvBinary   ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR );
1008extern PPCInstr* PPCInstr_AvBin8x16  ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR );
1009extern PPCInstr* PPCInstr_AvBin16x8  ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR );
1010extern PPCInstr* PPCInstr_AvBin32x4  ( PPCAvOp op, HReg dst, HReg srcL, HReg srcR );
1011extern PPCInstr* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op, HReg dst, HReg srcL, HReg srcR );
1012extern PPCInstr* PPCInstr_AvUn32Fx4  ( PPCAvFpOp op, HReg dst, HReg src );
1013extern PPCInstr* PPCInstr_AvPerm     ( HReg dst, HReg srcL, HReg srcR, HReg ctl );
1014extern PPCInstr* PPCInstr_AvSel      ( HReg ctl, HReg dst, HReg srcL, HReg srcR );
1015extern PPCInstr* PPCInstr_AvShlDbl   ( UChar shift, HReg dst, HReg srcL, HReg srcR );
1016extern PPCInstr* PPCInstr_AvSplat    ( UChar sz, HReg dst, PPCVI5s* src );
1017extern PPCInstr* PPCInstr_AvCMov     ( PPCCondCode, HReg dst, HReg src );
1018extern PPCInstr* PPCInstr_AvLdVSCR   ( HReg src );
1019
1020extern PPCInstr* PPCInstr_Dfp64Unary  ( PPCFpOp op, HReg dst, HReg src );
1021extern PPCInstr* PPCInstr_Dfp64Binary ( PPCFpOp op, HReg dst, HReg srcL,
1022                                        HReg srcR );
1023extern PPCInstr* PPCInstr_DfpShift    ( PPCFpOp op, HReg dst, HReg src,
1024                                        PPCRI* shift );
1025extern PPCInstr* PPCInstr_Dfp128Unary  ( PPCFpOp op, HReg dst_hi, HReg dst_lo,
1026                                         HReg srcR_hi, HReg srcR_lo );
1027extern PPCInstr* PPCInstr_Dfp128Binary ( PPCFpOp op, HReg dst_hi, HReg dst_lo,
1028                                         HReg srcR_hi, HReg srcR_lo );
1029extern PPCInstr* PPCInstr_DfpShift128  ( PPCFpOp op, HReg dst_hi, HReg src_hi,
1030                                         HReg dst_lo, HReg src_lo,
1031                                         PPCRI* shift );
1032extern PPCInstr* PPCInstr_DfpD128toD64 ( PPCFpOp op, HReg dst,
1033                                         HReg dst_lo, HReg src_lo);
1034extern PPCInstr* PPCInstr_DfpI64StoD128  ( PPCFpOp op, HReg dst_hi,
1035                                           HReg dst_lo, HReg src);
1036extern PPCInstr* PPCInstr_DfpRound       ( HReg dst, HReg src, PPCRI* r_rmc );
1037extern PPCInstr* PPCInstr_DfpRound128    ( HReg dst_hi, HReg dst_lo, HReg src_hi,
1038                                           HReg src_lo, PPCRI* r_rmc );
1039extern PPCInstr* PPCInstr_DfpQuantize    ( PPCFpOp op, HReg dst, HReg srcL,
1040                                           HReg srcR, PPCRI* rmc );
1041extern PPCInstr* PPCInstr_DfpQuantize128 ( PPCFpOp op, HReg dst_hi,
1042                                           HReg dst_lo,
1043                                           HReg src_hi,
1044                                           HReg src_lo, PPCRI* rmc );
1045extern PPCInstr* PPCInstr_ExtractExpD128 ( PPCFpOp op,   HReg dst,
1046                                           HReg src_hi, HReg src_lo );
1047extern PPCInstr* PPCInstr_InsertExpD128  ( PPCFpOp op,   HReg dst_hi,
1048                                           HReg dst_lo,  HReg srcL,
1049                                           HReg srcR_hi, HReg srcR_lo );
1050extern PPCInstr* PPCInstr_Dfp64Cmp       ( HReg dst, HReg srcL, HReg srcR );
1051extern PPCInstr* PPCInstr_Dfp128Cmp      ( HReg dst, HReg srcL_hi, HReg srcL_lo,
1052                                           HReg srcR_hi, HReg srcR_lo );
1053extern PPCInstr* PPCInstr_EvCheck     ( PPCAMode* amCounter,
1054                                        PPCAMode* amFailAddr );
1055extern PPCInstr* PPCInstr_ProfInc     ( void );
1056
1057extern void ppPPCInstr(PPCInstr*, Bool mode64);
1058
1059
1060/* Some functions that insulate the register allocator from details
1061   of the underlying instruction set. */
1062extern void         getRegUsage_PPCInstr ( HRegUsage*, PPCInstr*, Bool mode64 );
1063extern void         mapRegs_PPCInstr     ( HRegRemap*, PPCInstr* , Bool mode64);
1064extern Bool         isMove_PPCInstr      ( PPCInstr*, HReg*, HReg* );
1065extern Int          emit_PPCInstr        ( /*MB_MOD*/Bool* is_profInc,
1066                                           UChar* buf, Int nbuf, PPCInstr* i,
1067                                           Bool mode64,
1068                                           void* disp_cp_chain_me_to_slowEP,
1069                                           void* disp_cp_chain_me_to_fastEP,
1070                                           void* disp_cp_xindir,
1071                                           void* disp_cp_xassisted );
1072
1073extern void genSpill_PPC  ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1074                            HReg rreg, Int offsetB, Bool mode64 );
1075extern void genReload_PPC ( /*OUT*/HInstr** i1, /*OUT*/HInstr** i2,
1076                            HReg rreg, Int offsetB, Bool mode64 );
1077
1078extern void         getAllocableRegs_PPC ( Int*, HReg**, Bool mode64 );
1079extern HInstrArray* iselSB_PPC           ( IRSB*,
1080                                           VexArch,
1081                                           VexArchInfo*,
1082                                           VexAbiInfo*,
1083                                           Int offs_Host_EvC_Counter,
1084                                           Int offs_Host_EvC_FailAddr,
1085                                           Bool chainingAllowed,
1086                                           Bool addProfInc,
1087                                           Addr64 max_ga );
1088
1089/* How big is an event check?  This is kind of a kludge because it
1090   depends on the offsets of host_EvC_FAILADDR and
1091   host_EvC_COUNTER. */
1092extern Int evCheckSzB_PPC ( void );
1093
1094/* Perform a chaining and unchaining of an XDirect jump. */
1095extern VexInvalRange chainXDirect_PPC ( void* place_to_chain,
1096                                        void* disp_cp_chain_me_EXPECTED,
1097                                        void* place_to_jump_to,
1098                                        Bool  mode64 );
1099
1100extern VexInvalRange unchainXDirect_PPC ( void* place_to_unchain,
1101                                          void* place_to_jump_to_EXPECTED,
1102                                          void* disp_cp_chain_me,
1103                                          Bool  mode64 );
1104
1105/* Patch the counter location into an existing ProfInc point. */
1106extern VexInvalRange patchProfInc_PPC ( void*  place_to_patch,
1107                                        ULong* location_of_counter,
1108                                        Bool   mode64 );
1109
1110
1111#endif /* ndef __VEX_HOST_PPC_DEFS_H */
1112
1113/*---------------------------------------------------------------*/
1114/*--- end                                     host_ppc_defs.h ---*/
1115/*---------------------------------------------------------------*/
1116