2 /*---------------------------------------------------------------*/
3 /*--- begin host_ppc_defs.c ---*/
4 /*---------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2004-2017 OpenWorks LLP
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.
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.
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
28 The GNU General Public License is contained in the file COPYING.
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.
36 #include "libvex_basictypes.h"
38 #include "libvex_trc_values.h"
40 #include "main_util.h"
41 #include "host_generic_regs.h"
42 #include "host_ppc_defs.h"
45 /* --------- Registers. --------- */
47 const RRegUniverse
* getRRegUniverse_PPC ( Bool mode64
)
49 /* The real-register universe is a big constant, so we just want to
50 initialise it once. rRegUniverse_PPC_initted values: 0=not initted,
51 1=initted for 32-bit-mode, 2=initted for 64-bit-mode */
52 static RRegUniverse rRegUniverse_PPC
;
53 static UInt rRegUniverse_PPC_initted
= 0;
55 /* Handy shorthand, nothing more */
56 RRegUniverse
* ru
= &rRegUniverse_PPC
;
58 /* This isn't thread-safe. Sigh. */
59 UInt howNeeded
= mode64
? 2 : 1;
60 if (LIKELY(rRegUniverse_PPC_initted
== howNeeded
))
63 RRegUniverse__init(ru
);
65 /* Add the registers. The initial segment of this array must be
66 those available for allocation by reg-alloc, and those that
67 follow are not available for allocation. */
68 // GPR0 = scratch reg where poss. - some ops interpret as value zero
69 // GPR1 = stack pointer
71 ru
->allocable_start
[(mode64
) ? HRcInt64
: HRcInt32
] = ru
->size
;
72 // GPR14 and above are callee save. List them first.
73 ru
->regs
[ru
->size
++] = hregPPC_GPR14(mode64
);
74 ru
->regs
[ru
->size
++] = hregPPC_GPR15(mode64
);
75 ru
->regs
[ru
->size
++] = hregPPC_GPR16(mode64
);
76 ru
->regs
[ru
->size
++] = hregPPC_GPR17(mode64
);
77 ru
->regs
[ru
->size
++] = hregPPC_GPR18(mode64
);
78 ru
->regs
[ru
->size
++] = hregPPC_GPR19(mode64
);
79 ru
->regs
[ru
->size
++] = hregPPC_GPR20(mode64
);
80 ru
->regs
[ru
->size
++] = hregPPC_GPR21(mode64
);
81 ru
->regs
[ru
->size
++] = hregPPC_GPR22(mode64
);
82 ru
->regs
[ru
->size
++] = hregPPC_GPR23(mode64
);
83 ru
->regs
[ru
->size
++] = hregPPC_GPR24(mode64
);
84 ru
->regs
[ru
->size
++] = hregPPC_GPR25(mode64
);
85 ru
->regs
[ru
->size
++] = hregPPC_GPR26(mode64
);
86 ru
->regs
[ru
->size
++] = hregPPC_GPR27(mode64
);
87 ru
->regs
[ru
->size
++] = hregPPC_GPR28(mode64
);
89 // Caller save registers now.
90 ru
->regs
[ru
->size
++] = hregPPC_GPR3(mode64
);
91 ru
->regs
[ru
->size
++] = hregPPC_GPR4(mode64
);
92 ru
->regs
[ru
->size
++] = hregPPC_GPR5(mode64
);
93 ru
->regs
[ru
->size
++] = hregPPC_GPR6(mode64
);
94 ru
->regs
[ru
->size
++] = hregPPC_GPR7(mode64
);
95 ru
->regs
[ru
->size
++] = hregPPC_GPR8(mode64
);
96 ru
->regs
[ru
->size
++] = hregPPC_GPR9(mode64
);
97 ru
->regs
[ru
->size
++] = hregPPC_GPR10(mode64
);
100 r11 used for calls by ptr / env ptr for some langs
101 r12 used for exception handling and global linkage code */
102 ru
->regs
[ru
->size
++] = hregPPC_GPR11(mode64
);
103 ru
->regs
[ru
->size
++] = hregPPC_GPR12(mode64
);
105 // GPR13 = thread specific pointer
106 ru
->allocable_end
[(mode64
) ? HRcInt64
: HRcInt32
] = ru
->size
- 1;
107 // GPR29 is reserved for the dispatcher
108 // GPR30 is reserved as AltiVec spill reg temporary
109 // GPR31 is reserved for the GuestStatePtr
111 /* Don't waste the reg-allocs's time trawling through zillions of
112 FP registers - they mostly will never be used. We'll tolerate
113 the occasional extra spill instead. */
114 /* For both ppc32-linux and ppc64-linux, f14-f31 are callee save.
116 ru
->allocable_start
[HRcFlt64
] = ru
->size
;
117 ru
->regs
[ru
->size
++] = hregPPC_FPR14(mode64
);
118 ru
->regs
[ru
->size
++] = hregPPC_FPR15(mode64
);
119 ru
->regs
[ru
->size
++] = hregPPC_FPR16(mode64
);
120 ru
->regs
[ru
->size
++] = hregPPC_FPR17(mode64
);
121 ru
->regs
[ru
->size
++] = hregPPC_FPR18(mode64
);
122 ru
->regs
[ru
->size
++] = hregPPC_FPR19(mode64
);
123 ru
->regs
[ru
->size
++] = hregPPC_FPR20(mode64
);
124 ru
->regs
[ru
->size
++] = hregPPC_FPR21(mode64
);
125 ru
->allocable_end
[HRcFlt64
] = ru
->size
- 1;
127 /* Same deal re Altivec */
128 /* For both ppc32-linux and ppc64-linux, v20-v31 are callee save.
130 /* NB, vr29 is used as a scratch temporary -- do not allocate */
131 ru
->allocable_start
[HRcVec128
] = ru
->size
;
132 ru
->regs
[ru
->size
++] = hregPPC_VR20(mode64
);
133 ru
->regs
[ru
->size
++] = hregPPC_VR21(mode64
);
134 ru
->regs
[ru
->size
++] = hregPPC_VR22(mode64
);
135 ru
->regs
[ru
->size
++] = hregPPC_VR23(mode64
);
136 ru
->regs
[ru
->size
++] = hregPPC_VR24(mode64
);
137 ru
->regs
[ru
->size
++] = hregPPC_VR25(mode64
);
138 ru
->regs
[ru
->size
++] = hregPPC_VR26(mode64
);
139 ru
->regs
[ru
->size
++] = hregPPC_VR27(mode64
);
140 ru
->allocable_end
[HRcVec128
] = ru
->size
- 1;
141 ru
->allocable
= ru
->size
;
143 /* And other regs, not available to the allocator. */
144 ru
->regs
[ru
->size
++] = hregPPC_GPR1(mode64
);
145 ru
->regs
[ru
->size
++] = hregPPC_GPR29(mode64
);
146 ru
->regs
[ru
->size
++] = hregPPC_GPR30(mode64
);
147 ru
->regs
[ru
->size
++] = hregPPC_GPR31(mode64
);
148 ru
->regs
[ru
->size
++] = hregPPC_VR29(mode64
);
150 rRegUniverse_PPC_initted
= howNeeded
;
152 RRegUniverse__check_is_sane(ru
);
157 UInt
ppHRegPPC ( HReg reg
)
160 static const HChar
* ireg32_names
[32]
161 = { "%r0", "%r1", "%r2", "%r3",
162 "%r4", "%r5", "%r6", "%r7",
163 "%r8", "%r9", "%r10", "%r11",
164 "%r12", "%r13", "%r14", "%r15",
165 "%r16", "%r17", "%r18", "%r19",
166 "%r20", "%r21", "%r22", "%r23",
167 "%r24", "%r25", "%r26", "%r27",
168 "%r28", "%r29", "%r30", "%r31" };
169 /* Be generic for all virtual regs. */
170 if (hregIsVirtual(reg
)) {
173 /* But specific for real regs. */
174 switch (hregClass(reg
)) {
176 r
= hregEncoding(reg
);
177 vassert(r
>= 0 && r
< 32);
178 return vex_printf("%s", ireg32_names
[r
]);
180 r
= hregEncoding(reg
);
181 vassert(r
>= 0 && r
< 32);
182 return vex_printf("%s", ireg32_names
[r
]);
184 r
= hregEncoding(reg
);
185 vassert(r
>= 0 && r
< 32);
186 return vex_printf("%%fr%d", r
);
188 r
= hregEncoding(reg
);
189 vassert(r
>= 0 && r
< 32);
190 return vex_printf("%%v%d", r
);
197 /* --------- Condition codes, Intel encoding. --------- */
199 const HChar
* showPPCCondCode ( PPCCondCode cond
)
201 if (cond
.test
== Pct_ALWAYS
) return "always";
205 return (cond
.test
== Pct_TRUE
) ? "cr7.so=1" : "cr7.so=0";
207 return (cond
.test
== Pct_TRUE
) ? "cr7.eq=1" : "cr7.eq=0";
209 return (cond
.test
== Pct_TRUE
) ? "cr7.gt=1" : "cr7.gt=0";
211 return (cond
.test
== Pct_TRUE
) ? "cr7.lt=1" : "cr7.lt=0";
214 default: vpanic("ppPPCCondCode");
218 /* construct condition code */
219 PPCCondCode
mk_PPCCondCode ( PPCCondTest test
, PPCCondFlag flag
)
224 if (test
== Pct_ALWAYS
) {
225 vassert(flag
== Pcf_NONE
);
227 vassert(flag
!= Pcf_NONE
);
232 /* false->true, true->false */
233 PPCCondTest
invertCondTest ( PPCCondTest ct
)
235 vassert(ct
!= Pct_ALWAYS
);
236 return (ct
== Pct_TRUE
) ? Pct_FALSE
: Pct_TRUE
;
240 /* --------- PPCAMode: memory address expressions. --------- */
242 PPCAMode
* PPCAMode_IR ( Int idx
, HReg base
) {
243 PPCAMode
* am
= LibVEX_Alloc_inline(sizeof(PPCAMode
));
244 vassert(idx
>= -0x8000 && idx
< 0x8000);
246 am
->Pam
.IR
.base
= base
;
247 am
->Pam
.IR
.index
= idx
;
250 PPCAMode
* PPCAMode_RR ( HReg idx
, HReg base
) {
251 PPCAMode
* am
= LibVEX_Alloc_inline(sizeof(PPCAMode
));
253 am
->Pam
.RR
.base
= base
;
254 am
->Pam
.RR
.index
= idx
;
258 PPCAMode
* dopyPPCAMode ( PPCAMode
* am
) {
261 return PPCAMode_IR( am
->Pam
.IR
.index
, am
->Pam
.IR
.base
);
263 return PPCAMode_RR( am
->Pam
.RR
.index
, am
->Pam
.RR
.base
);
265 vpanic("dopyPPCAMode");
269 void ppPPCAMode ( PPCAMode
* am
) {
272 if (am
->Pam
.IR
.index
== 0)
275 vex_printf("%d(", (Int
)am
->Pam
.IR
.index
);
276 ppHRegPPC(am
->Pam
.IR
.base
);
280 ppHRegPPC(am
->Pam
.RR
.base
);
282 ppHRegPPC(am
->Pam
.RR
.index
);
285 vpanic("ppPPCAMode");
289 static void addRegUsage_PPCAMode ( HRegUsage
* u
, PPCAMode
* am
) {
292 addHRegUse(u
, HRmRead
, am
->Pam
.IR
.base
);
295 addHRegUse(u
, HRmRead
, am
->Pam
.RR
.base
);
296 addHRegUse(u
, HRmRead
, am
->Pam
.RR
.index
);
299 vpanic("addRegUsage_PPCAMode");
303 static void mapRegs_PPCAMode ( HRegRemap
* m
, PPCAMode
* am
) {
306 am
->Pam
.IR
.base
= lookupHRegRemap(m
, am
->Pam
.IR
.base
);
309 am
->Pam
.RR
.base
= lookupHRegRemap(m
, am
->Pam
.RR
.base
);
310 am
->Pam
.RR
.index
= lookupHRegRemap(m
, am
->Pam
.RR
.index
);
313 vpanic("mapRegs_PPCAMode");
317 /* --------- Operand, which can be a reg or a u16/s16. --------- */
319 PPCRH
* PPCRH_Imm ( Bool syned
, UShort imm16
) {
320 PPCRH
* op
= LibVEX_Alloc_inline(sizeof(PPCRH
));
322 op
->Prh
.Imm
.syned
= syned
;
323 op
->Prh
.Imm
.imm16
= imm16
;
324 /* If this is a signed value, ensure it's not -32768, so that we
325 are guaranteed always to be able to negate if needed. */
327 vassert(imm16
!= 0x8000);
328 vassert(syned
== True
|| syned
== False
);
331 PPCRH
* PPCRH_Reg ( HReg reg
) {
332 PPCRH
* op
= LibVEX_Alloc_inline(sizeof(PPCRH
));
334 op
->Prh
.Reg
.reg
= reg
;
338 void ppPPCRH ( PPCRH
* op
) {
341 if (op
->Prh
.Imm
.syned
)
342 vex_printf("%d", (Int
)(Short
)op
->Prh
.Imm
.imm16
);
344 vex_printf("%u", (UInt
)(UShort
)op
->Prh
.Imm
.imm16
);
347 ppHRegPPC(op
->Prh
.Reg
.reg
);
354 /* An PPCRH can only be used in a "read" context (what would it mean
355 to write or modify a literal?) and so we enumerate its registers
357 static void addRegUsage_PPCRH ( HRegUsage
* u
, PPCRH
* op
) {
362 addHRegUse(u
, HRmRead
, op
->Prh
.Reg
.reg
);
365 vpanic("addRegUsage_PPCRH");
369 static void mapRegs_PPCRH ( HRegRemap
* m
, PPCRH
* op
) {
374 op
->Prh
.Reg
.reg
= lookupHRegRemap(m
, op
->Prh
.Reg
.reg
);
377 vpanic("mapRegs_PPCRH");
382 /* --------- Operand, which can be a reg or a u32/64. --------- */
384 PPCRI
* PPCRI_Imm ( ULong imm64
) {
385 PPCRI
* op
= LibVEX_Alloc_inline(sizeof(PPCRI
));
390 PPCRI
* PPCRI_Reg ( HReg reg
) {
391 PPCRI
* op
= LibVEX_Alloc_inline(sizeof(PPCRI
));
397 void ppPPCRI ( PPCRI
* dst
) {
400 vex_printf("0x%llx", dst
->Pri
.Imm
);
403 ppHRegPPC(dst
->Pri
.Reg
);
410 /* An PPCRI can only be used in a "read" context (what would it
411 mean to write or modify a literal?) and so we enumerate its
412 registers accordingly. */
413 static void addRegUsage_PPCRI ( HRegUsage
* u
, PPCRI
* dst
) {
418 addHRegUse(u
, HRmRead
, dst
->Pri
.Reg
);
421 vpanic("addRegUsage_PPCRI");
425 static void mapRegs_PPCRI ( HRegRemap
* m
, PPCRI
* dst
) {
430 dst
->Pri
.Reg
= lookupHRegRemap(m
, dst
->Pri
.Reg
);
433 vpanic("mapRegs_PPCRI");
438 /* --------- Operand, which can be a vector reg or a simm5. --------- */
440 PPCVI5s
* PPCVI5s_Imm ( Char simm5
) {
441 PPCVI5s
* op
= LibVEX_Alloc_inline(sizeof(PPCVI5s
));
443 op
->Pvi
.Imm5s
= simm5
;
444 vassert(simm5
>= -16 && simm5
<= 15);
447 PPCVI5s
* PPCVI5s_Reg ( HReg reg
) {
448 PPCVI5s
* op
= LibVEX_Alloc_inline(sizeof(PPCVI5s
));
451 vassert(hregClass(reg
) == HRcVec128
);
455 void ppPPCVI5s ( PPCVI5s
* src
) {
458 vex_printf("%d", (Int
)src
->Pvi
.Imm5s
);
461 ppHRegPPC(src
->Pvi
.Reg
);
468 /* An PPCVI5s can only be used in a "read" context (what would it
469 mean to write or modify a literal?) and so we enumerate its
470 registers accordingly. */
471 static void addRegUsage_PPCVI5s ( HRegUsage
* u
, PPCVI5s
* dst
) {
476 addHRegUse(u
, HRmRead
, dst
->Pvi
.Reg
);
479 vpanic("addRegUsage_PPCVI5s");
483 static void mapRegs_PPCVI5s ( HRegRemap
* m
, PPCVI5s
* dst
) {
488 dst
->Pvi
.Reg
= lookupHRegRemap(m
, dst
->Pvi
.Reg
);
491 vpanic("mapRegs_PPCVI5s");
496 /* --------- Instructions. --------- */
498 const HChar
* showPPCUnaryOp ( PPCUnaryOp op
) {
500 case Pun_NOT
: return "not";
501 case Pun_NEG
: return "neg";
502 case Pun_CLZ32
: return "cntlzw";
503 case Pun_CLZ64
: return "cntlzd";
504 case Pun_EXTSW
: return "extsw";
505 case Pun_POP32
: return "popcntw";
506 case Pun_POP64
: return "popcntd";
507 default: vpanic("showPPCUnaryOp");
511 const HChar
* showPPCAluOp ( PPCAluOp op
, Bool immR
) {
513 case Palu_ADD
: return immR
? "addi" : "add";
514 case Palu_SUB
: return immR
? "subi" : "sub";
515 case Palu_AND
: return immR
? "andi." : "and";
516 case Palu_OR
: return immR
? "ori" : "or";
517 case Palu_XOR
: return immR
? "xori" : "xor";
518 default: vpanic("showPPCAluOp");
522 const HChar
* showPPCShftOp ( PPCShftOp op
, Bool immR
, Bool sz32
) {
524 case Pshft_SHL
: return sz32
? (immR
? "slwi" : "slw") :
525 (immR
? "sldi" : "sld");
526 case Pshft_SHR
: return sz32
? (immR
? "srwi" : "srw") :
527 (immR
? "srdi" : "srd");
528 case Pshft_SAR
: return sz32
? (immR
? "srawi" : "sraw") :
529 (immR
? "sradi" : "srad");
530 default: vpanic("showPPCShftOp");
534 const HChar
* showPPCFpOp ( PPCFpOp op
) {
536 case Pfp_ADDD
: return "fadd";
537 case Pfp_SUBD
: return "fsub";
538 case Pfp_MULD
: return "fmul";
539 case Pfp_DIVD
: return "fdiv";
540 case Pfp_MADDD
: return "fmadd";
541 case Pfp_MSUBD
: return "fmsub";
542 case Pfp_MADDS
: return "fmadds";
543 case Pfp_MSUBS
: return "fmsubs";
544 case Pfp_ADDS
: return "fadds";
545 case Pfp_SUBS
: return "fsubs";
546 case Pfp_MULS
: return "fmuls";
547 case Pfp_DIVS
: return "fdivs";
548 case Pfp_SQRT
: return "fsqrt";
549 case Pfp_ABS
: return "fabs";
550 case Pfp_NEG
: return "fneg";
551 case Pfp_MOV
: return "fmr";
552 case Pfp_RES
: return "fres";
553 case Pfp_RSQRTE
: return "frsqrte";
554 case Pfp_FRIM
: return "frim";
555 case Pfp_FRIN
: return "frin";
556 case Pfp_FRIP
: return "frip";
557 case Pfp_FRIZ
: return "friz";
558 case Pfp_FPADDQ
: return "xsaddqp";
559 case Pfp_FPSUBQ
: return "xsubqp";
560 case Pfp_FPMULQ
: return "xsmulqp";
561 case Pfp_FPDIVQ
: return "xsdivqp";
562 case Pfp_FPMULADDQ
: return "xsmaddqp";
563 case Pfp_FPMULSUBQ
: return "xsmsubqp";
564 case Pfp_FPNEGMULADDQ
: return "xsnmaddqp";
565 case Pfp_FPNEGMULSUBQ
: return "xsnmsubqp";
566 case Pfp_FPADDQRNDODD
: return "xsaddqpo";
567 case Pfp_FPSUBQRNDODD
: return "xsubqpo";
568 case Pfp_FPMULQRNDODD
: return "xsmulqpo";
569 case Pfp_FPDIVQRNDODD
: return "xsaddqpo";
570 case Pfp_FPMULADDQRNDODD
: return "xsmaddqpo";
571 case Pfp_FPMULSUBQRNDODD
: return "xsmsubqpo";
572 case Pfp_FPNEGMULADDQRNDODD
: return "xsnmaddqpo";
573 case Pfp_FPNEGMULSUBQRNDODD
: return "xsnmsubqpo";
574 case Pfp_FPQTOD
: return "xscvqpdp";
575 case Pfp_FPQTODRNDODD
: return "xscvqpdpo";
576 case Pfp_FPDTOQ
: return "xscvdpqp";
577 case Pfp_IDSTOQ
: return "xscvsdqp";
578 case Pfp_IDUTOQ
: return "xscvudqp";
579 case Pfp_TRUNCFPQTOISD
: return "xscvqpsdz";
580 case Pfp_TRUNCFPQTOISW
: return "xscvqpswz";
581 case Pfp_TRUNCFPQTOIUD
: return "xscvqpudz";
582 case Pfp_TRUNCFPQTOIUW
: return "xscvqpuwz";
583 case Pfp_DFPADD
: return "dadd";
584 case Pfp_DFPADDQ
: return "daddq";
585 case Pfp_DFPSUB
: return "dsub";
586 case Pfp_DFPSUBQ
: return "dsubq";
587 case Pfp_DFPMUL
: return "dmul";
588 case Pfp_DFPMULQ
: return "dmulq";
589 case Pfp_DFPDIV
: return "ddivd";
590 case Pfp_DFPDIVQ
: return "ddivq";
591 case Pfp_DCTDP
: return "dctdp";
592 case Pfp_DRSP
: return "drsp";
593 case Pfp_DCTFIX
: return "dctfix";
594 case Pfp_DCFFIX
: return "dcffix";
595 case Pfp_DCTQPQ
: return "dctqpq";
596 case Pfp_DCFFIXQ
: return "dcffixq";
597 case Pfp_DQUA
: return "dqua";
598 case Pfp_DQUAQ
: return "dquaq";
599 case Pfp_DXEX
: return "dxex";
600 case Pfp_DXEXQ
: return "dxexq";
601 case Pfp_DIEX
: return "diex";
602 case Pfp_DIEXQ
: return "diexq";
603 case Pfp_RRDTR
: return "rrdtr";
604 default: vpanic("showPPCFpOp");
608 const HChar
* showPPCAvOp ( PPCAvOp op
) {
612 case Pav_MOV
: return "vmr"; /* Mov */
614 case Pav_AND
: return "vand"; /* Bitwise */
615 case Pav_OR
: return "vor";
616 case Pav_XOR
: return "vxor";
617 case Pav_NOT
: return "vnot";
619 case Pav_UNPCKH8S
: return "vupkhsb"; /* Unpack */
620 case Pav_UNPCKH16S
: return "vupkhsh";
621 case Pav_UNPCKL8S
: return "vupklsb";
622 case Pav_UNPCKL16S
: return "vupklsh";
623 case Pav_UNPCKHPIX
: return "vupkhpx";
624 case Pav_UNPCKLPIX
: return "vupklpx";
627 case Pav_ADDU
: return "vaddu_m"; // b,h,w,dw
628 case Pav_QADDU
: return "vaddu_s"; // b,h,w,dw
629 case Pav_QADDS
: return "vadds_s"; // b,h,w,dw
631 case Pav_SUBU
: return "vsubu_m"; // b,h,w,dw
632 case Pav_QSUBU
: return "vsubu_s"; // b,h,w,dw
633 case Pav_QSUBS
: return "vsubs_s"; // b,h,w,dw
635 case Pav_MULU
: return "vmulu"; // w
636 case Pav_OMULU
: return "vmulou"; // b,h,w
637 case Pav_OMULS
: return "vmulos"; // b,h,w
638 case Pav_EMULU
: return "vmuleu"; // b,h,w
639 case Pav_EMULS
: return "vmules"; // b,h,w
641 case Pav_AVGU
: return "vavgu"; // b,h,w
642 case Pav_AVGS
: return "vavgs"; // b,h,w
644 case Pav_MAXU
: return "vmaxu"; // b,h,w
645 case Pav_MAXS
: return "vmaxs"; // b,h,w
647 case Pav_MINU
: return "vminu"; // b,h,w
648 case Pav_MINS
: return "vmins"; // b,h,w
650 /* Compare (always affects CR field 6) */
651 case Pav_CMPEQU
: return "vcmpequ"; // b,h,w
652 case Pav_CMPGTU
: return "vcmpgtu"; // b,h,w
653 case Pav_CMPGTS
: return "vcmpgts"; // b,h,w
656 case Pav_SHL
: return "vsl"; // ' ',b,h,w,dw
657 case Pav_SHR
: return "vsr"; // ' ',b,h,w,dw
658 case Pav_SAR
: return "vsra"; // b,h,w,dw
659 case Pav_ROTL
: return "vrl"; // b,h,w,dw
662 case Pav_PACKUU
: return "vpku_um"; // h,w,dw
663 case Pav_QPACKUU
: return "vpku_us"; // h,w
664 case Pav_QPACKSU
: return "vpks_us"; // h,w
665 case Pav_QPACKSS
: return "vpks_ss"; // h,w
666 case Pav_PACKPXL
: return "vpkpx";
669 case Pav_MRGHI
: return "vmrgh"; // b,h,w
670 case Pav_MRGLO
: return "vmrgl"; // b,h,w
673 case Pav_CATODD
: return "vmrgow"; // w
674 case Pav_CATEVEN
: return "vmrgew"; // w
677 case Pav_SHA256
: return "vshasigmaw"; // w
678 case Pav_SHA512
: return "vshasigmaw"; // dw
681 case Pav_BCDAdd
: return "bcdadd."; // qw
682 case Pav_BCDSub
: return "bcdsub."; // qw
683 case Pav_I128StoBCD128
: return "bcdcfsq."; //qw
684 case Pav_BCD128toI128S
: return "bcdctsq."; //qw
686 /* I128 mult by 10 */
687 case Pav_MulI128by10
: return "vmul10uq"; //qw
688 case Pav_MulI128by10Carry
: return "vmul10cuq"; //qw
689 case Pav_MulI128by10E
: return "vmul10euq"; //qw
690 case Pav_MulI128by10ECarry
: return "vmul10ecuq"; //qw
692 /* F128 to I128 signed */
693 case Pav_F128toI128S
: return "xsrqpi|x"; //qw
695 /* F128 round to F128 */
696 case Pav_ROUNDFPQ
: return "xsrqpxp";
698 /* Polynomial arith */
699 case Pav_POLYMULADD
: return "vpmsum"; // b, h, w, d
702 case Pav_CIPHERV128
: case Pav_CIPHERLV128
:
703 case Pav_NCIPHERV128
: case Pav_NCIPHERLV128
:
704 case Pav_CIPHERSUBV128
: return "v_cipher_"; // qw
707 case Pav_ZEROCNTBYTE
: case Pav_ZEROCNTWORD
:
708 case Pav_ZEROCNTHALF
: case Pav_ZEROCNTDBL
:
709 return "vclz_"; // b, h, w, d
711 /* trailing zero count */
712 case Pav_TRAILINGZEROCNTBYTE
: case Pav_TRAILINGZEROCNTWORD
:
713 case Pav_TRAILINGZEROCNTHALF
: case Pav_TRAILINGZEROCNTDBL
:
714 return "vctz_"; // b, h, w, d
716 /* vector gather (byte-by-byte bit matrix transpose) */
717 case Pav_BITMTXXPOSE
:
720 /* Vector Half-precision format to single precision conversion */
724 /* Vector Single-precision format to Half-precision conversion */
728 /* Vector Half-precision format to Double precision conversion */
732 /* Vector Half-precision format to Double precision conversion */
736 default: vpanic("showPPCAvOp");
740 const HChar
* showPPCAvFpOp ( PPCAvFpOp op
) {
742 /* Floating Point Binary */
743 case Pavfp_ADDF
: return "vaddfp";
744 case Pavfp_SUBF
: return "vsubfp";
745 case Pavfp_MULF
: return "vmaddfp";
746 case Pavfp_MAXF
: return "vmaxfp";
747 case Pavfp_MINF
: return "vminfp";
748 case Pavfp_CMPEQF
: return "vcmpeqfp";
749 case Pavfp_CMPGTF
: return "vcmpgtfp";
750 case Pavfp_CMPGEF
: return "vcmpgefp";
752 /* Floating Point Unary */
753 case Pavfp_RCPF
: return "vrefp";
754 case Pavfp_RSQRTF
: return "vrsqrtefp";
755 case Pavfp_CVTU2F
: return "vcfux";
756 case Pavfp_CVTS2F
: return "vcfsx";
757 case Pavfp_QCVTF2U
: return "vctuxs";
758 case Pavfp_QCVTF2S
: return "vctsxs";
759 case Pavfp_ROUNDM
: return "vrfim";
760 case Pavfp_ROUNDP
: return "vrfip";
761 case Pavfp_ROUNDN
: return "vrfin";
762 case Pavfp_ROUNDZ
: return "vrfiz";
764 default: vpanic("showPPCAvFpOp");
768 PPCInstr
* PPCInstr_LI ( HReg dst
, ULong imm64
, Bool mode64
)
770 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
773 i
->Pin
.LI
.imm64
= imm64
;
775 vassert( (Long
)imm64
== (Long
)(Int
)(UInt
)imm64
);
778 PPCInstr
* PPCInstr_Alu ( PPCAluOp op
, HReg dst
,
779 HReg srcL
, PPCRH
* srcR
) {
780 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
783 i
->Pin
.Alu
.dst
= dst
;
784 i
->Pin
.Alu
.srcL
= srcL
;
785 i
->Pin
.Alu
.srcR
= srcR
;
788 PPCInstr
* PPCInstr_Shft ( PPCShftOp op
, Bool sz32
,
789 HReg dst
, HReg srcL
, PPCRH
* srcR
) {
790 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
793 i
->Pin
.Shft
.sz32
= sz32
;
794 i
->Pin
.Shft
.dst
= dst
;
795 i
->Pin
.Shft
.srcL
= srcL
;
796 i
->Pin
.Shft
.srcR
= srcR
;
799 PPCInstr
* PPCInstr_AddSubC ( Bool isAdd
, Bool setC
,
800 HReg dst
, HReg srcL
, HReg srcR
) {
801 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
802 i
->tag
= Pin_AddSubC
;
803 i
->Pin
.AddSubC
.isAdd
= isAdd
;
804 i
->Pin
.AddSubC
.setC
= setC
;
805 i
->Pin
.AddSubC
.dst
= dst
;
806 i
->Pin
.AddSubC
.srcL
= srcL
;
807 i
->Pin
.AddSubC
.srcR
= srcR
;
810 PPCInstr
* PPCInstr_Cmp ( Bool syned
, Bool sz32
,
811 UInt crfD
, HReg srcL
, PPCRH
* srcR
) {
812 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
814 i
->Pin
.Cmp
.syned
= syned
;
815 i
->Pin
.Cmp
.sz32
= sz32
;
816 i
->Pin
.Cmp
.crfD
= crfD
;
817 i
->Pin
.Cmp
.srcL
= srcL
;
818 i
->Pin
.Cmp
.srcR
= srcR
;
821 PPCInstr
* PPCInstr_Unary ( PPCUnaryOp op
, HReg dst
, HReg src
) {
822 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
824 i
->Pin
.Unary
.op
= op
;
825 i
->Pin
.Unary
.dst
= dst
;
826 i
->Pin
.Unary
.src
= src
;
829 PPCInstr
* PPCInstr_MulL ( Bool syned
, Bool hi
, Bool sz32
,
830 HReg dst
, HReg srcL
, HReg srcR
) {
831 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
833 i
->Pin
.MulL
.syned
= syned
;
835 i
->Pin
.MulL
.sz32
= sz32
;
836 i
->Pin
.MulL
.dst
= dst
;
837 i
->Pin
.MulL
.srcL
= srcL
;
838 i
->Pin
.MulL
.srcR
= srcR
;
839 /* if doing the low word, the signedness is irrelevant, but tie it
841 if (!hi
) vassert(!syned
);
844 PPCInstr
* PPCInstr_Div ( Bool extended
, Bool syned
, Bool sz32
,
845 HReg dst
, HReg srcL
, HReg srcR
) {
846 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
848 i
->Pin
.Div
.extended
= extended
;
849 i
->Pin
.Div
.syned
= syned
;
850 i
->Pin
.Div
.sz32
= sz32
;
851 i
->Pin
.Div
.dst
= dst
;
852 i
->Pin
.Div
.srcL
= srcL
;
853 i
->Pin
.Div
.srcR
= srcR
;
856 PPCInstr
* PPCInstr_Call ( PPCCondCode cond
,
857 Addr64 target
, UInt argiregs
, RetLoc rloc
) {
859 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
861 i
->Pin
.Call
.cond
= cond
;
862 i
->Pin
.Call
.target
= target
;
863 i
->Pin
.Call
.argiregs
= argiregs
;
864 i
->Pin
.Call
.rloc
= rloc
;
865 /* Only r3 .. r10 inclusive may be used as arg regs. Hence: */
866 mask
= (1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10);
867 vassert(0 == (argiregs
& ~mask
));
868 vassert(is_sane_RetLoc(rloc
));
871 PPCInstr
* PPCInstr_XDirect ( Addr64 dstGA
, PPCAMode
* amCIA
,
872 PPCCondCode cond
, Bool toFastEP
) {
873 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
874 i
->tag
= Pin_XDirect
;
875 i
->Pin
.XDirect
.dstGA
= dstGA
;
876 i
->Pin
.XDirect
.amCIA
= amCIA
;
877 i
->Pin
.XDirect
.cond
= cond
;
878 i
->Pin
.XDirect
.toFastEP
= toFastEP
;
881 PPCInstr
* PPCInstr_XIndir ( HReg dstGA
, PPCAMode
* amCIA
,
883 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
885 i
->Pin
.XIndir
.dstGA
= dstGA
;
886 i
->Pin
.XIndir
.amCIA
= amCIA
;
887 i
->Pin
.XIndir
.cond
= cond
;
890 PPCInstr
* PPCInstr_XAssisted ( HReg dstGA
, PPCAMode
* amCIA
,
891 PPCCondCode cond
, IRJumpKind jk
) {
892 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
893 i
->tag
= Pin_XAssisted
;
894 i
->Pin
.XAssisted
.dstGA
= dstGA
;
895 i
->Pin
.XAssisted
.amCIA
= amCIA
;
896 i
->Pin
.XAssisted
.cond
= cond
;
897 i
->Pin
.XAssisted
.jk
= jk
;
900 PPCInstr
* PPCInstr_CMov ( PPCCondCode cond
,
901 HReg dst
, PPCRI
* src
) {
902 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
904 i
->Pin
.CMov
.cond
= cond
;
905 i
->Pin
.CMov
.src
= src
;
906 i
->Pin
.CMov
.dst
= dst
;
907 vassert(cond
.test
!= Pct_ALWAYS
);
910 PPCInstr
* PPCInstr_Load ( UChar sz
,
911 HReg dst
, PPCAMode
* src
, Bool mode64
) {
912 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
915 i
->Pin
.Load
.src
= src
;
916 i
->Pin
.Load
.dst
= dst
;
917 vassert(sz
== 1 || sz
== 2 || sz
== 4 || sz
== 8);
918 if (sz
== 8) vassert(mode64
);
921 PPCInstr
* PPCInstr_LoadL ( UChar sz
,
922 HReg dst
, HReg src
, Bool mode64
)
924 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
926 i
->Pin
.LoadL
.sz
= sz
;
927 i
->Pin
.LoadL
.src
= src
;
928 i
->Pin
.LoadL
.dst
= dst
;
929 vassert(sz
== 1 || sz
== 2 || sz
== 4 || sz
== 8);
930 if (sz
== 8) vassert(mode64
);
933 PPCInstr
* PPCInstr_Store ( UChar sz
, PPCAMode
* dst
, HReg src
,
935 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
937 i
->Pin
.Store
.sz
= sz
;
938 i
->Pin
.Store
.src
= src
;
939 i
->Pin
.Store
.dst
= dst
;
940 vassert(sz
== 1 || sz
== 2 || sz
== 4 || sz
== 8);
941 if (sz
== 8) vassert(mode64
);
944 PPCInstr
* PPCInstr_StoreC ( UChar sz
, HReg dst
, HReg src
, Bool mode64
) {
945 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
947 i
->Pin
.StoreC
.sz
= sz
;
948 i
->Pin
.StoreC
.src
= src
;
949 i
->Pin
.StoreC
.dst
= dst
;
950 vassert(sz
== 1 || sz
== 2 || sz
== 4 || sz
== 8);
951 if (sz
== 8) vassert(mode64
);
954 PPCInstr
* PPCInstr_Set ( PPCCondCode cond
, HReg dst
) {
955 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
957 i
->Pin
.Set
.cond
= cond
;
958 i
->Pin
.Set
.dst
= dst
;
961 PPCInstr
* PPCInstr_MfCR ( HReg dst
)
963 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
965 i
->Pin
.MfCR
.dst
= dst
;
968 PPCInstr
* PPCInstr_MFence ( void )
970 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
975 PPCInstr
* PPCInstr_FpUnary ( PPCFpOp op
, HReg dst
, HReg src
) {
976 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
977 i
->tag
= Pin_FpUnary
;
978 i
->Pin
.FpUnary
.op
= op
;
979 i
->Pin
.FpUnary
.dst
= dst
;
980 i
->Pin
.FpUnary
.src
= src
;
983 PPCInstr
* PPCInstr_FpBinary ( PPCFpOp op
, HReg dst
,
984 HReg srcL
, HReg srcR
) {
985 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
986 i
->tag
= Pin_FpBinary
;
987 i
->Pin
.FpBinary
.op
= op
;
988 i
->Pin
.FpBinary
.dst
= dst
;
989 i
->Pin
.FpBinary
.srcL
= srcL
;
990 i
->Pin
.FpBinary
.srcR
= srcR
;
993 PPCInstr
* PPCInstr_Fp128Unary(PPCFpOp op
, HReg dst
, HReg src
) {
994 PPCInstr
* i
= LibVEX_Alloc_inline( sizeof(PPCInstr
) );
995 i
->tag
= Pin_Fp128Unary
;
996 i
->Pin
.Fp128Unary
.op
= op
;
997 i
->Pin
.Fp128Unary
.dst
= dst
;
998 i
->Pin
.Fp128Unary
.src
= src
;
1001 PPCInstr
* PPCInstr_Fp128Binary(PPCFpOp op
, HReg dst
, HReg srcL
, HReg srcR
) {
1002 PPCInstr
* i
= LibVEX_Alloc_inline( sizeof(PPCInstr
) );
1003 i
->tag
= Pin_Fp128Binary
;
1004 i
->Pin
.Fp128Binary
.op
= op
;
1005 i
->Pin
.Fp128Binary
.dst
= dst
;
1006 i
->Pin
.Fp128Binary
.srcL
= srcL
;
1007 i
->Pin
.Fp128Binary
.srcR
= srcR
;
1010 PPCInstr
* PPCInstr_Fp128Trinary(PPCFpOp op
, HReg dst
, HReg srcL
, HReg srcR
) {
1011 PPCInstr
* i
= LibVEX_Alloc_inline( sizeof(PPCInstr
) );
1012 i
->tag
= Pin_Fp128Trinary
;
1013 i
->Pin
.Fp128Trinary
.op
= op
;
1014 i
->Pin
.Fp128Trinary
.dst
= dst
;
1015 i
->Pin
.Fp128Trinary
.srcL
= srcL
;
1016 i
->Pin
.Fp128Trinary
.srcR
= srcR
;
1019 PPCInstr
* PPCInstr_FpMulAcc ( PPCFpOp op
, HReg dst
, HReg srcML
,
1020 HReg srcMR
, HReg srcAcc
)
1022 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1023 i
->tag
= Pin_FpMulAcc
;
1024 i
->Pin
.FpMulAcc
.op
= op
;
1025 i
->Pin
.FpMulAcc
.dst
= dst
;
1026 i
->Pin
.FpMulAcc
.srcML
= srcML
;
1027 i
->Pin
.FpMulAcc
.srcMR
= srcMR
;
1028 i
->Pin
.FpMulAcc
.srcAcc
= srcAcc
;
1031 PPCInstr
* PPCInstr_FpLdSt ( Bool isLoad
, UChar sz
,
1032 HReg reg
, PPCAMode
* addr
) {
1033 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1034 i
->tag
= Pin_FpLdSt
;
1035 i
->Pin
.FpLdSt
.isLoad
= isLoad
;
1036 i
->Pin
.FpLdSt
.sz
= sz
;
1037 i
->Pin
.FpLdSt
.reg
= reg
;
1038 i
->Pin
.FpLdSt
.addr
= addr
;
1039 vassert(sz
== 4 || sz
== 8);
1042 PPCInstr
* PPCInstr_FpSTFIW ( HReg addr
, HReg data
)
1044 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1045 i
->tag
= Pin_FpSTFIW
;
1046 i
->Pin
.FpSTFIW
.addr
= addr
;
1047 i
->Pin
.FpSTFIW
.data
= data
;
1050 PPCInstr
* PPCInstr_FpRSP ( HReg dst
, HReg src
) {
1051 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1053 i
->Pin
.FpRSP
.dst
= dst
;
1054 i
->Pin
.FpRSP
.src
= src
;
1057 PPCInstr
* PPCInstr_Dfp64Unary(PPCFpOp op
, HReg dst
, HReg src
) {
1058 PPCInstr
* i
= LibVEX_Alloc_inline( sizeof(PPCInstr
) );
1059 i
->tag
= Pin_Dfp64Unary
;
1060 i
->Pin
.Dfp64Unary
.op
= op
;
1061 i
->Pin
.Dfp64Unary
.dst
= dst
;
1062 i
->Pin
.Dfp64Unary
.src
= src
;
1065 PPCInstr
* PPCInstr_Dfp64Binary(PPCFpOp op
, HReg dst
, HReg srcL
, HReg srcR
) {
1066 PPCInstr
* i
= LibVEX_Alloc_inline( sizeof(PPCInstr
) );
1067 i
->tag
= Pin_Dfp64Binary
;
1068 i
->Pin
.Dfp64Binary
.op
= op
;
1069 i
->Pin
.Dfp64Binary
.dst
= dst
;
1070 i
->Pin
.Dfp64Binary
.srcL
= srcL
;
1071 i
->Pin
.Dfp64Binary
.srcR
= srcR
;
1074 PPCInstr
* PPCInstr_DfpShift ( PPCFpOp op
, HReg dst
, HReg src
, PPCRI
* shift
) {
1075 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1076 i
->tag
= Pin_DfpShift
;
1077 i
->Pin
.DfpShift
.op
= op
;
1078 i
->Pin
.DfpShift
.shift
= shift
;
1079 i
->Pin
.DfpShift
.src
= src
;
1080 i
->Pin
.DfpShift
.dst
= dst
;
1083 PPCInstr
* PPCInstr_Dfp128Unary(PPCFpOp op
, HReg dst_hi
, HReg dst_lo
,
1084 HReg src_hi
, HReg src_lo
) {
1085 PPCInstr
* i
= LibVEX_Alloc_inline( sizeof(PPCInstr
) );
1086 i
->tag
= Pin_Dfp128Unary
;
1087 i
->Pin
.Dfp128Unary
.op
= op
;
1088 i
->Pin
.Dfp128Unary
.dst_hi
= dst_hi
;
1089 i
->Pin
.Dfp128Unary
.dst_lo
= dst_lo
;
1090 i
->Pin
.Dfp128Unary
.src_hi
= src_hi
;
1091 i
->Pin
.Dfp128Unary
.src_lo
= src_lo
;
1094 PPCInstr
* PPCInstr_Dfp128Binary(PPCFpOp op
, HReg dst_hi
, HReg dst_lo
,
1095 HReg srcR_hi
, HReg srcR_lo
) {
1096 /* dst is used to pass the srcL argument and return the result */
1097 PPCInstr
* i
= LibVEX_Alloc_inline( sizeof(PPCInstr
) );
1098 i
->tag
= Pin_Dfp128Binary
;
1099 i
->Pin
.Dfp128Binary
.op
= op
;
1100 i
->Pin
.Dfp128Binary
.dst_hi
= dst_hi
;
1101 i
->Pin
.Dfp128Binary
.dst_lo
= dst_lo
;
1102 i
->Pin
.Dfp128Binary
.srcR_hi
= srcR_hi
;
1103 i
->Pin
.Dfp128Binary
.srcR_lo
= srcR_lo
;
1106 PPCInstr
* PPCInstr_DfpShift128 ( PPCFpOp op
, HReg dst_hi
, HReg dst_lo
,
1107 HReg src_hi
, HReg src_lo
,
1109 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1110 i
->tag
= Pin_DfpShift128
;
1111 i
->Pin
.DfpShift128
.op
= op
;
1112 i
->Pin
.DfpShift128
.shift
= shift
;
1113 i
->Pin
.DfpShift128
.src_hi
= src_hi
;
1114 i
->Pin
.DfpShift128
.src_lo
= src_lo
;
1115 i
->Pin
.DfpShift128
.dst_hi
= dst_hi
;
1116 i
->Pin
.DfpShift128
.dst_lo
= dst_lo
;
1119 PPCInstr
* PPCInstr_DfpRound ( HReg dst
, HReg src
, PPCRI
* r_rmc
) {
1120 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1121 i
->tag
= Pin_DfpRound
;
1122 i
->Pin
.DfpRound
.dst
= dst
;
1123 i
->Pin
.DfpRound
.src
= src
;
1124 i
->Pin
.DfpRound
.r_rmc
= r_rmc
;
1127 PPCInstr
* PPCInstr_DfpRound128 ( HReg dst_hi
, HReg dst_lo
, HReg src_hi
,
1128 HReg src_lo
, PPCRI
* r_rmc
) {
1129 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1130 i
->tag
= Pin_DfpRound128
;
1131 i
->Pin
.DfpRound128
.dst_hi
= dst_hi
;
1132 i
->Pin
.DfpRound128
.dst_lo
= dst_lo
;
1133 i
->Pin
.DfpRound128
.src_hi
= src_hi
;
1134 i
->Pin
.DfpRound128
.src_lo
= src_lo
;
1135 i
->Pin
.DfpRound128
.r_rmc
= r_rmc
;
1138 PPCInstr
* PPCInstr_DfpQuantize ( PPCFpOp op
, HReg dst
, HReg srcL
, HReg srcR
,
1140 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1141 i
->tag
= Pin_DfpQuantize
;
1142 i
->Pin
.DfpQuantize
.op
= op
;
1143 i
->Pin
.DfpQuantize
.dst
= dst
;
1144 i
->Pin
.DfpQuantize
.srcL
= srcL
;
1145 i
->Pin
.DfpQuantize
.srcR
= srcR
;
1146 i
->Pin
.DfpQuantize
.rmc
= rmc
;
1149 PPCInstr
* PPCInstr_DfpQuantize128 ( PPCFpOp op
, HReg dst_hi
, HReg dst_lo
,
1150 HReg src_hi
, HReg src_lo
, PPCRI
* rmc
) {
1151 /* dst is used to pass left operand in and return result */
1152 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1153 i
->tag
= Pin_DfpQuantize128
;
1154 i
->Pin
.DfpQuantize128
.op
= op
;
1155 i
->Pin
.DfpQuantize128
.dst_hi
= dst_hi
;
1156 i
->Pin
.DfpQuantize128
.dst_lo
= dst_lo
;
1157 i
->Pin
.DfpQuantize128
.src_hi
= src_hi
;
1158 i
->Pin
.DfpQuantize128
.src_lo
= src_lo
;
1159 i
->Pin
.DfpQuantize128
.rmc
= rmc
;
1162 PPCInstr
* PPCInstr_DfpD128toD64 ( PPCFpOp op
, HReg dst
,
1163 HReg src_hi
, HReg src_lo
) {
1164 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1165 i
->tag
= Pin_DfpD128toD64
;
1166 i
->Pin
.DfpD128toD64
.op
= op
;
1167 i
->Pin
.DfpD128toD64
.src_hi
= src_hi
;
1168 i
->Pin
.DfpD128toD64
.src_lo
= src_lo
;
1169 i
->Pin
.DfpD128toD64
.dst
= dst
;
1172 PPCInstr
* PPCInstr_DfpI64StoD128 ( PPCFpOp op
, HReg dst_hi
,
1173 HReg dst_lo
, HReg src
) {
1174 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1175 i
->tag
= Pin_DfpI64StoD128
;
1176 i
->Pin
.DfpI64StoD128
.op
= op
;
1177 i
->Pin
.DfpI64StoD128
.src
= src
;
1178 i
->Pin
.DfpI64StoD128
.dst_hi
= dst_hi
;
1179 i
->Pin
.DfpI64StoD128
.dst_lo
= dst_lo
;
1182 PPCInstr
* PPCInstr_ExtractExpD128 ( PPCFpOp op
, HReg dst
,
1183 HReg src_hi
, HReg src_lo
) {
1184 /* dst is used to pass the srcL argument */
1185 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1186 i
->tag
= Pin_ExtractExpD128
;
1187 i
->Pin
.ExtractExpD128
.op
= op
;
1188 i
->Pin
.ExtractExpD128
.dst
= dst
;
1189 i
->Pin
.ExtractExpD128
.src_hi
= src_hi
;
1190 i
->Pin
.ExtractExpD128
.src_lo
= src_lo
;
1193 PPCInstr
* PPCInstr_InsertExpD128 ( PPCFpOp op
, HReg dst_hi
, HReg dst_lo
,
1194 HReg srcL
, HReg srcR_hi
, HReg srcR_lo
) {
1195 /* dst is used to pass the srcL argument */
1196 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1197 i
->tag
= Pin_InsertExpD128
;
1198 i
->Pin
.InsertExpD128
.op
= op
;
1199 i
->Pin
.InsertExpD128
.dst_hi
= dst_hi
;
1200 i
->Pin
.InsertExpD128
.dst_lo
= dst_lo
;
1201 i
->Pin
.InsertExpD128
.srcL
= srcL
;
1202 i
->Pin
.InsertExpD128
.srcR_hi
= srcR_hi
;
1203 i
->Pin
.InsertExpD128
.srcR_lo
= srcR_lo
;
1206 PPCInstr
* PPCInstr_Dfp64Cmp (/* UInt crfD,*/ HReg dst
, HReg srcL
, HReg srcR
) {
1207 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1208 i
->tag
= Pin_Dfp64Cmp
;
1209 i
->Pin
.Dfp64Cmp
.dst
= dst
;
1210 i
->Pin
.Dfp64Cmp
.srcL
= srcL
;
1211 i
->Pin
.Dfp64Cmp
.srcR
= srcR
;
1214 PPCInstr
* PPCInstr_Dfp128Cmp ( HReg dst
, HReg srcL_hi
, HReg srcL_lo
,
1215 HReg srcR_hi
, HReg srcR_lo
) {
1216 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1217 i
->tag
= Pin_Dfp128Cmp
;
1218 i
->Pin
.Dfp128Cmp
.dst
= dst
;
1219 i
->Pin
.Dfp128Cmp
.srcL_hi
= srcL_hi
;
1220 i
->Pin
.Dfp128Cmp
.srcL_lo
= srcL_lo
;
1221 i
->Pin
.Dfp128Cmp
.srcR_hi
= srcR_hi
;
1222 i
->Pin
.Dfp128Cmp
.srcR_lo
= srcR_lo
;
1225 PPCInstr
* PPCInstr_EvCheck ( PPCAMode
* amCounter
,
1226 PPCAMode
* amFailAddr
) {
1227 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1228 i
->tag
= Pin_EvCheck
;
1229 i
->Pin
.EvCheck
.amCounter
= amCounter
;
1230 i
->Pin
.EvCheck
.amFailAddr
= amFailAddr
;
1233 PPCInstr
* PPCInstr_ProfInc ( void ) {
1234 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1235 i
->tag
= Pin_ProfInc
;
1240 Valid combo | fromI | int32 | syned | flt64 |
1241 --------------------------------------------
1243 --------------------------------------------
1244 F64->I64U | n n n y |
1245 --------------------------------------------
1247 --------------------------------------------
1248 F64->I64S | n n y y |
1249 --------------------------------------------
1251 --------------------------------------------
1252 F64->I32U | n y n y |
1253 --------------------------------------------
1255 --------------------------------------------
1256 F64->I32S | n y y y |
1257 --------------------------------------------
1258 I64U->F32 | y n n n |
1259 --------------------------------------------
1260 I64U->F64 | y n n y |
1261 --------------------------------------------
1263 --------------------------------------------
1264 I64S->F64 | y n y y |
1265 --------------------------------------------
1267 --------------------------------------------
1269 --------------------------------------------
1271 --------------------------------------------
1273 --------------------------------------------
1275 PPCInstr
* PPCInstr_FpCftI ( Bool fromI
, Bool int32
, Bool syned
,
1276 Bool flt64
, HReg dst
, HReg src
) {
1277 Bool tmp
= fromI
| int32
| syned
| flt64
;
1278 vassert(tmp
== True
|| tmp
== False
); // iow, no high bits set
1279 UShort conversion
= 0;
1280 conversion
= (fromI
<< 3) | (int32
<< 2) | (syned
<< 1) | flt64
;
1281 switch (conversion
) {
1282 // Supported conversion operations
1283 case 1: case 3: case 5: case 7:
1284 case 8: case 9: case 11:
1287 vpanic("PPCInstr_FpCftI(ppc_host)");
1289 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1290 i
->tag
= Pin_FpCftI
;
1291 i
->Pin
.FpCftI
.fromI
= fromI
;
1292 i
->Pin
.FpCftI
.int32
= int32
;
1293 i
->Pin
.FpCftI
.syned
= syned
;
1294 i
->Pin
.FpCftI
.flt64
= flt64
;
1295 i
->Pin
.FpCftI
.dst
= dst
;
1296 i
->Pin
.FpCftI
.src
= src
;
1299 PPCInstr
* PPCInstr_FpCMov ( PPCCondCode cond
, HReg dst
, HReg src
) {
1300 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1301 i
->tag
= Pin_FpCMov
;
1302 i
->Pin
.FpCMov
.cond
= cond
;
1303 i
->Pin
.FpCMov
.dst
= dst
;
1304 i
->Pin
.FpCMov
.src
= src
;
1305 vassert(cond
.test
!= Pct_ALWAYS
);
1308 PPCInstr
* PPCInstr_FpLdFPSCR ( HReg src
, Bool dfp_rm
) {
1309 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1310 i
->tag
= Pin_FpLdFPSCR
;
1311 i
->Pin
.FpLdFPSCR
.src
= src
;
1312 i
->Pin
.FpLdFPSCR
.dfp_rm
= dfp_rm
? 1 : 0;
1315 PPCInstr
* PPCInstr_FpCmp ( HReg dst
, HReg srcL
, HReg srcR
) {
1316 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1318 i
->Pin
.FpCmp
.dst
= dst
;
1319 i
->Pin
.FpCmp
.srcL
= srcL
;
1320 i
->Pin
.FpCmp
.srcR
= srcR
;
1324 /* Read/Write Link Register */
1325 PPCInstr
* PPCInstr_RdWrLR ( Bool wrLR
, HReg gpr
) {
1326 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1327 i
->tag
= Pin_RdWrLR
;
1328 i
->Pin
.RdWrLR
.wrLR
= wrLR
;
1329 i
->Pin
.RdWrLR
.gpr
= gpr
;
1334 PPCInstr
* PPCInstr_AvLdSt ( Bool isLoad
, UChar sz
,
1335 HReg reg
, PPCAMode
* addr
) {
1336 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1337 i
->tag
= Pin_AvLdSt
;
1338 i
->Pin
.AvLdSt
.isLoad
= isLoad
;
1339 i
->Pin
.AvLdSt
.sz
= sz
;
1340 i
->Pin
.AvLdSt
.reg
= reg
;
1341 i
->Pin
.AvLdSt
.addr
= addr
;
1344 PPCInstr
* PPCInstr_AvUnary ( PPCAvOp op
, HReg dst
, HReg src
) {
1345 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1346 i
->tag
= Pin_AvUnary
;
1347 i
->Pin
.AvUnary
.op
= op
;
1348 i
->Pin
.AvUnary
.dst
= dst
;
1349 i
->Pin
.AvUnary
.src
= src
;
1352 PPCInstr
* PPCInstr_AvBinary ( PPCAvOp op
, HReg dst
,
1353 HReg srcL
, HReg srcR
) {
1354 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1355 i
->tag
= Pin_AvBinary
;
1356 i
->Pin
.AvBinary
.op
= op
;
1357 i
->Pin
.AvBinary
.dst
= dst
;
1358 i
->Pin
.AvBinary
.srcL
= srcL
;
1359 i
->Pin
.AvBinary
.srcR
= srcR
;
1362 PPCInstr
* PPCInstr_AvBinaryInt ( PPCAvOp op
, HReg dst
,
1363 HReg src
, PPCRI
* val
) {
1364 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1365 i
->tag
= Pin_AvBinaryInt
;
1366 i
->Pin
.AvBinaryInt
.op
= op
;
1367 i
->Pin
.AvBinaryInt
.dst
= dst
;
1368 i
->Pin
.AvBinaryInt
.src
= src
;
1369 i
->Pin
.AvBinaryInt
.val
= val
;
1372 PPCInstr
* PPCInstr_AvBin8x16 ( PPCAvOp op
, HReg dst
,
1373 HReg srcL
, HReg srcR
) {
1374 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1375 i
->tag
= Pin_AvBin8x16
;
1376 i
->Pin
.AvBin8x16
.op
= op
;
1377 i
->Pin
.AvBin8x16
.dst
= dst
;
1378 i
->Pin
.AvBin8x16
.srcL
= srcL
;
1379 i
->Pin
.AvBin8x16
.srcR
= srcR
;
1382 PPCInstr
* PPCInstr_AvBin16x8 ( PPCAvOp op
, HReg dst
,
1383 HReg srcL
, HReg srcR
) {
1384 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1385 i
->tag
= Pin_AvBin16x8
;
1386 i
->Pin
.AvBin16x8
.op
= op
;
1387 i
->Pin
.AvBin16x8
.dst
= dst
;
1388 i
->Pin
.AvBin16x8
.srcL
= srcL
;
1389 i
->Pin
.AvBin16x8
.srcR
= srcR
;
1392 PPCInstr
* PPCInstr_AvBin32x4 ( PPCAvOp op
, HReg dst
,
1393 HReg srcL
, HReg srcR
) {
1394 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1395 i
->tag
= Pin_AvBin32x4
;
1396 i
->Pin
.AvBin32x4
.op
= op
;
1397 i
->Pin
.AvBin32x4
.dst
= dst
;
1398 i
->Pin
.AvBin32x4
.srcL
= srcL
;
1399 i
->Pin
.AvBin32x4
.srcR
= srcR
;
1402 PPCInstr
* PPCInstr_AvBin64x2 ( PPCAvOp op
, HReg dst
,
1403 HReg srcL
, HReg srcR
) {
1404 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1405 i
->tag
= Pin_AvBin64x2
;
1406 i
->Pin
.AvBin64x2
.op
= op
;
1407 i
->Pin
.AvBin64x2
.dst
= dst
;
1408 i
->Pin
.AvBin64x2
.srcL
= srcL
;
1409 i
->Pin
.AvBin64x2
.srcR
= srcR
;
1413 PPCInstr
* PPCInstr_AvBin32Fx4 ( PPCAvFpOp op
, HReg dst
,
1414 HReg srcL
, HReg srcR
) {
1415 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1416 i
->tag
= Pin_AvBin32Fx4
;
1417 i
->Pin
.AvBin32Fx4
.op
= op
;
1418 i
->Pin
.AvBin32Fx4
.dst
= dst
;
1419 i
->Pin
.AvBin32Fx4
.srcL
= srcL
;
1420 i
->Pin
.AvBin32Fx4
.srcR
= srcR
;
1423 PPCInstr
* PPCInstr_AvUn32Fx4 ( PPCAvFpOp op
, HReg dst
, HReg src
) {
1424 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1425 i
->tag
= Pin_AvUn32Fx4
;
1426 i
->Pin
.AvUn32Fx4
.op
= op
;
1427 i
->Pin
.AvUn32Fx4
.dst
= dst
;
1428 i
->Pin
.AvUn32Fx4
.src
= src
;
1431 PPCInstr
* PPCInstr_AvPerm ( HReg dst
, HReg srcL
, HReg srcR
, HReg ctl
) {
1432 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1433 i
->tag
= Pin_AvPerm
;
1434 i
->Pin
.AvPerm
.dst
= dst
;
1435 i
->Pin
.AvPerm
.srcL
= srcL
;
1436 i
->Pin
.AvPerm
.srcR
= srcR
;
1437 i
->Pin
.AvPerm
.ctl
= ctl
;
1441 PPCInstr
* PPCInstr_AvSel ( HReg ctl
, HReg dst
, HReg srcL
, HReg srcR
) {
1442 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1444 i
->Pin
.AvSel
.ctl
= ctl
;
1445 i
->Pin
.AvSel
.dst
= dst
;
1446 i
->Pin
.AvSel
.srcL
= srcL
;
1447 i
->Pin
.AvSel
.srcR
= srcR
;
1450 PPCInstr
* PPCInstr_AvSh ( Bool shLeft
, HReg dst
, PPCAMode
* addr
) {
1451 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1453 i
->Pin
.AvSh
.shLeft
= shLeft
;
1454 i
->Pin
.AvSh
.dst
= dst
;
1455 i
->Pin
.AvSh
.addr
= addr
;
1458 PPCInstr
* PPCInstr_AvShlDbl ( UChar shift
, HReg dst
,
1459 HReg srcL
, HReg srcR
) {
1460 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1461 i
->tag
= Pin_AvShlDbl
;
1462 i
->Pin
.AvShlDbl
.shift
= shift
;
1463 i
->Pin
.AvShlDbl
.dst
= dst
;
1464 i
->Pin
.AvShlDbl
.srcL
= srcL
;
1465 i
->Pin
.AvShlDbl
.srcR
= srcR
;
1468 PPCInstr
* PPCInstr_AvSplat ( UChar sz
, HReg dst
, PPCVI5s
* src
) {
1469 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1470 i
->tag
= Pin_AvSplat
;
1471 i
->Pin
.AvSplat
.sz
= sz
;
1472 i
->Pin
.AvSplat
.dst
= dst
;
1473 i
->Pin
.AvSplat
.src
= src
;
1476 PPCInstr
* PPCInstr_AvCMov ( PPCCondCode cond
, HReg dst
, HReg src
) {
1477 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1478 i
->tag
= Pin_AvCMov
;
1479 i
->Pin
.AvCMov
.cond
= cond
;
1480 i
->Pin
.AvCMov
.dst
= dst
;
1481 i
->Pin
.AvCMov
.src
= src
;
1482 vassert(cond
.test
!= Pct_ALWAYS
);
1485 PPCInstr
* PPCInstr_AvLdVSCR ( HReg src
) {
1486 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1487 i
->tag
= Pin_AvLdVSCR
;
1488 i
->Pin
.AvLdVSCR
.src
= src
;
1491 PPCInstr
* PPCInstr_AvCipherV128Unary ( PPCAvOp op
, HReg dst
, HReg src
) {
1492 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1493 i
->tag
= Pin_AvCipherV128Unary
;
1494 i
->Pin
.AvCipherV128Unary
.op
= op
;
1495 i
->Pin
.AvCipherV128Unary
.dst
= dst
;
1496 i
->Pin
.AvCipherV128Unary
.src
= src
;
1499 PPCInstr
* PPCInstr_AvCipherV128Binary ( PPCAvOp op
, HReg dst
,
1500 HReg srcL
, HReg srcR
) {
1501 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1502 i
->tag
= Pin_AvCipherV128Binary
;
1503 i
->Pin
.AvCipherV128Binary
.op
= op
;
1504 i
->Pin
.AvCipherV128Binary
.dst
= dst
;
1505 i
->Pin
.AvCipherV128Binary
.srcL
= srcL
;
1506 i
->Pin
.AvCipherV128Binary
.srcR
= srcR
;
1509 PPCInstr
* PPCInstr_AvHashV128Binary ( PPCAvOp op
, HReg dst
,
1510 HReg src
, PPCRI
* s_field
) {
1511 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1512 i
->tag
= Pin_AvHashV128Binary
;
1513 i
->Pin
.AvHashV128Binary
.op
= op
;
1514 i
->Pin
.AvHashV128Binary
.dst
= dst
;
1515 i
->Pin
.AvHashV128Binary
.src
= src
;
1516 i
->Pin
.AvHashV128Binary
.s_field
= s_field
;
1519 PPCInstr
* PPCInstr_AvBCDV128Binary ( PPCAvOp op
, HReg dst
,
1520 HReg src1
, HReg src2
) {
1521 PPCInstr
* i
= LibVEX_Alloc_inline(sizeof(PPCInstr
));
1522 i
->tag
= Pin_AvBCDV128Binary
;
1523 i
->Pin
.AvBCDV128Binary
.op
= op
;
1524 i
->Pin
.AvBCDV128Binary
.dst
= dst
;
1525 i
->Pin
.AvBCDV128Binary
.src1
= src1
;
1526 i
->Pin
.AvBCDV128Binary
.src2
= src2
;
1531 /* Pretty Print instructions */
1532 static void ppLoadImm ( HReg dst
, ULong imm
, Bool mode64
) {
1533 vex_printf("li_word ");
1536 vex_printf(",0x%08x", (UInt
)imm
);
1538 vex_printf(",0x%016llx", imm
);
1542 static void ppMovReg ( HReg dst
, HReg src
) {
1543 if (!sameHReg(dst
, src
)) {
1551 void ppPPCInstr ( const PPCInstr
* i
, Bool mode64
)
1555 ppLoadImm(i
->Pin
.LI
.dst
, i
->Pin
.LI
.imm64
, mode64
);
1558 HReg r_srcL
= i
->Pin
.Alu
.srcL
;
1559 PPCRH
* rh_srcR
= i
->Pin
.Alu
.srcR
;
1560 /* special-case "mr" */
1561 if (i
->Pin
.Alu
.op
== Palu_OR
&& // or Rd,Rs,Rs == mr Rd,Rs
1562 rh_srcR
->tag
== Prh_Reg
&&
1563 sameHReg(rh_srcR
->Prh
.Reg
.reg
, r_srcL
)) {
1565 ppHRegPPC(i
->Pin
.Alu
.dst
);
1570 /* special-case "li" */
1571 if (i
->Pin
.Alu
.op
== Palu_ADD
&& // addi Rd,0,imm == li Rd,imm
1572 rh_srcR
->tag
== Prh_Imm
&&
1573 hregEncoding(r_srcL
) == 0) {
1575 ppHRegPPC(i
->Pin
.Alu
.dst
);
1581 vex_printf("%s ", showPPCAluOp(i
->Pin
.Alu
.op
,
1582 toBool(rh_srcR
->tag
== Prh_Imm
)));
1583 ppHRegPPC(i
->Pin
.Alu
.dst
);
1591 HReg r_srcL
= i
->Pin
.Shft
.srcL
;
1592 PPCRH
* rh_srcR
= i
->Pin
.Shft
.srcR
;
1593 vex_printf("%s ", showPPCShftOp(i
->Pin
.Shft
.op
,
1594 toBool(rh_srcR
->tag
== Prh_Imm
),
1596 ppHRegPPC(i
->Pin
.Shft
.dst
);
1605 i
->Pin
.AddSubC
.isAdd
? "add" : "sub",
1606 i
->Pin
.AddSubC
.setC
? "c" : "e");
1607 ppHRegPPC(i
->Pin
.AddSubC
.dst
);
1609 ppHRegPPC(i
->Pin
.AddSubC
.srcL
);
1611 ppHRegPPC(i
->Pin
.AddSubC
.srcR
);
1614 vex_printf("%s%c%s %%cr%u,",
1615 i
->Pin
.Cmp
.syned
? "cmp" : "cmpl",
1616 i
->Pin
.Cmp
.sz32
? 'w' : 'd',
1617 i
->Pin
.Cmp
.srcR
->tag
== Prh_Imm
? "i" : "",
1619 ppHRegPPC(i
->Pin
.Cmp
.srcL
);
1621 ppPPCRH(i
->Pin
.Cmp
.srcR
);
1624 vex_printf("%s ", showPPCUnaryOp(i
->Pin
.Unary
.op
));
1625 ppHRegPPC(i
->Pin
.Unary
.dst
);
1627 ppHRegPPC(i
->Pin
.Unary
.src
);
1630 vex_printf("mul%c%c%s ",
1631 i
->Pin
.MulL
.hi
? 'h' : 'l',
1632 i
->Pin
.MulL
.sz32
? 'w' : 'd',
1633 i
->Pin
.MulL
.hi
? (i
->Pin
.MulL
.syned
? "s" : "u") : "");
1634 ppHRegPPC(i
->Pin
.MulL
.dst
);
1636 ppHRegPPC(i
->Pin
.MulL
.srcL
);
1638 ppHRegPPC(i
->Pin
.MulL
.srcR
);
1641 vex_printf("div%c%s%s ",
1642 i
->Pin
.Div
.sz32
? 'w' : 'd',
1643 i
->Pin
.Div
.extended
? "e" : "",
1644 i
->Pin
.Div
.syned
? "" : "u");
1645 ppHRegPPC(i
->Pin
.Div
.dst
);
1647 ppHRegPPC(i
->Pin
.Div
.srcL
);
1649 ppHRegPPC(i
->Pin
.Div
.srcR
);
1653 vex_printf("call: ");
1654 if (i
->Pin
.Call
.cond
.test
!= Pct_ALWAYS
) {
1655 vex_printf("if (%s) ", showPPCCondCode(i
->Pin
.Call
.cond
));
1658 ppLoadImm(hregPPC_GPR10(mode64
), i
->Pin
.Call
.target
, mode64
);
1659 vex_printf(" ; mtctr r10 ; bctrl [");
1660 for (n
= 0; n
< 32; n
++) {
1661 if (i
->Pin
.Call
.argiregs
& (1<<n
)) {
1662 vex_printf("r%d", n
);
1663 if ((i
->Pin
.Call
.argiregs
>> n
) > 1)
1668 ppRetLoc(i
->Pin
.Call
.rloc
);
1673 vex_printf("(xDirect) ");
1674 vex_printf("if (%s) { ",
1675 showPPCCondCode(i
->Pin
.XDirect
.cond
));
1677 vex_printf("imm64 r30,0x%llx; ", i
->Pin
.XDirect
.dstGA
);
1678 vex_printf("std r30,");
1680 vex_printf("imm32 r30,0x%llx; ", i
->Pin
.XDirect
.dstGA
);
1681 vex_printf("stw r30,");
1683 ppPPCAMode(i
->Pin
.XDirect
.amCIA
);
1686 vex_printf("imm64-fixed5 r30,$disp_cp_chain_me_to_%sEP; ",
1687 i
->Pin
.XDirect
.toFastEP
? "fast" : "slow");
1689 vex_printf("imm32-fixed2 r30,$disp_cp_chain_me_to_%sEP; ",
1690 i
->Pin
.XDirect
.toFastEP
? "fast" : "slow");
1692 vex_printf("mtctr r30; bctrl }");
1695 vex_printf("(xIndir) ");
1696 vex_printf("if (%s) { ",
1697 showPPCCondCode(i
->Pin
.XIndir
.cond
));
1698 vex_printf("%s ", mode64
? "std" : "stw");
1699 ppHRegPPC(i
->Pin
.XIndir
.dstGA
);
1701 ppPPCAMode(i
->Pin
.XIndir
.amCIA
);
1703 vex_printf("imm%s r30,$disp_cp_xindir; ", mode64
? "64" : "32");
1704 vex_printf("mtctr r30; bctr }");
1707 vex_printf("(xAssisted) ");
1708 vex_printf("if (%s) { ",
1709 showPPCCondCode(i
->Pin
.XAssisted
.cond
));
1710 vex_printf("%s ", mode64
? "std" : "stw");
1711 ppHRegPPC(i
->Pin
.XAssisted
.dstGA
);
1713 ppPPCAMode(i
->Pin
.XAssisted
.amCIA
);
1715 vex_printf("li r31,$IRJumpKind_to_TRCVAL(%d); ",
1716 (Int
)i
->Pin
.XAssisted
.jk
);
1717 vex_printf("imm%s r30,$disp_cp_xindir; ", mode64
? "64" : "32");
1718 vex_printf("mtctr r30; bctr }");
1721 vex_printf("cmov (%s) ", showPPCCondCode(i
->Pin
.CMov
.cond
));
1722 ppHRegPPC(i
->Pin
.CMov
.dst
);
1724 ppPPCRI(i
->Pin
.CMov
.src
);
1726 if (i
->Pin
.CMov
.cond
.test
!= Pct_ALWAYS
) {
1727 vex_printf("if (%s) ", showPPCCondCode(i
->Pin
.CMov
.cond
));
1730 if (i
->Pin
.CMov
.src
->tag
== Pri_Imm
) {
1731 ppLoadImm(i
->Pin
.CMov
.dst
, i
->Pin
.CMov
.src
->Pri
.Imm
, mode64
);
1733 ppMovReg(i
->Pin
.CMov
.dst
, i
->Pin
.CMov
.src
->Pri
.Reg
);
1738 Bool idxd
= toBool(i
->Pin
.Load
.src
->tag
== Pam_RR
);
1739 UChar sz
= i
->Pin
.Load
.sz
;
1740 HChar c_sz
= sz
==1 ? 'b' : sz
==2 ? 'h' : sz
==4 ? 'w' : 'd';
1741 vex_printf("l%c%s%s ", c_sz
, sz
==8 ? "" : "z", idxd
? "x" : "" );
1742 ppHRegPPC(i
->Pin
.Load
.dst
);
1744 ppPPCAMode(i
->Pin
.Load
.src
);
1748 UChar sz
= i
->Pin
.LoadL
.sz
;
1749 HChar c_sz
= sz
==1 ? 'b' : sz
==2 ? 'h' : sz
==4 ? 'w' : 'd';
1750 vex_printf("l%carx ", c_sz
);
1751 ppHRegPPC(i
->Pin
.LoadL
.dst
);
1752 vex_printf(",%%r0,");
1753 ppHRegPPC(i
->Pin
.LoadL
.src
);
1757 UChar sz
= i
->Pin
.Store
.sz
;
1758 Bool idxd
= toBool(i
->Pin
.Store
.dst
->tag
== Pam_RR
);
1759 HChar c_sz
= sz
==1 ? 'b' : sz
==2 ? 'h' : sz
==4 ? 'w' : /*8*/ 'd';
1760 vex_printf("st%c%s ", c_sz
, idxd
? "x" : "" );
1761 ppHRegPPC(i
->Pin
.Store
.src
);
1763 ppPPCAMode(i
->Pin
.Store
.dst
);
1767 UChar sz
= i
->Pin
.StoreC
.sz
;
1768 HChar c_sz
= sz
==1 ? 'b' : sz
==2 ? 'h' : sz
==4 ? 'w' : 'd';
1769 vex_printf("st%ccx. ", c_sz
);
1770 ppHRegPPC(i
->Pin
.StoreC
.src
);
1771 vex_printf(",%%r0,");
1772 ppHRegPPC(i
->Pin
.StoreC
.dst
);
1776 PPCCondCode cc
= i
->Pin
.Set
.cond
;
1777 vex_printf("set (%s),", showPPCCondCode(cc
));
1778 ppHRegPPC(i
->Pin
.Set
.dst
);
1779 if (cc
.test
== Pct_ALWAYS
) {
1780 vex_printf(": { li ");
1781 ppHRegPPC(i
->Pin
.Set
.dst
);
1784 vex_printf(": { mfcr r0 ; rlwinm ");
1785 ppHRegPPC(i
->Pin
.Set
.dst
);
1786 vex_printf(",r0,%u,31,31", cc
.flag
+1);
1787 if (cc
.test
== Pct_FALSE
) {
1788 vex_printf("; xori ");
1789 ppHRegPPC(i
->Pin
.Set
.dst
);
1791 ppHRegPPC(i
->Pin
.Set
.dst
);
1799 vex_printf("mfcr ");
1800 ppHRegPPC(i
->Pin
.MfCR
.dst
);
1803 vex_printf("mfence (=sync)");
1807 vex_printf("%s ", showPPCFpOp(i
->Pin
.FpUnary
.op
));
1808 ppHRegPPC(i
->Pin
.FpUnary
.dst
);
1810 ppHRegPPC(i
->Pin
.FpUnary
.src
);
1813 vex_printf("%s ", showPPCFpOp(i
->Pin
.FpBinary
.op
));
1814 ppHRegPPC(i
->Pin
.FpBinary
.dst
);
1816 ppHRegPPC(i
->Pin
.FpBinary
.srcL
);
1818 ppHRegPPC(i
->Pin
.FpBinary
.srcR
);
1820 case Pin_Fp128Unary
:
1821 vex_printf("%s ", showPPCFpOp(i
->Pin
.Fp128Unary
.op
));
1822 ppHRegPPC(i
->Pin
.Fp128Unary
.dst
);
1824 ppHRegPPC(i
->Pin
.Fp128Unary
.src
);
1826 case Pin_Fp128Binary
:
1827 vex_printf("%s ", showPPCFpOp(i
->Pin
.Fp128Binary
.op
));
1828 ppHRegPPC(i
->Pin
.Fp128Binary
.dst
);
1830 ppHRegPPC(i
->Pin
.Fp128Binary
.srcL
);
1832 ppHRegPPC(i
->Pin
.Fp128Binary
.srcR
);
1834 case Pin_Fp128Trinary
:
1835 vex_printf("%s ", showPPCFpOp(i
->Pin
.Fp128Trinary
.op
));
1836 ppHRegPPC(i
->Pin
.Fp128Trinary
.dst
);
1838 ppHRegPPC(i
->Pin
.Fp128Trinary
.srcL
);
1840 ppHRegPPC(i
->Pin
.Fp128Trinary
.srcR
);
1843 vex_printf("%s ", showPPCFpOp(i
->Pin
.FpMulAcc
.op
));
1844 ppHRegPPC(i
->Pin
.FpMulAcc
.dst
);
1846 ppHRegPPC(i
->Pin
.FpMulAcc
.srcML
);
1848 ppHRegPPC(i
->Pin
.FpMulAcc
.srcMR
);
1850 ppHRegPPC(i
->Pin
.FpMulAcc
.srcAcc
);
1853 UChar sz
= i
->Pin
.FpLdSt
.sz
;
1854 Bool idxd
= toBool(i
->Pin
.FpLdSt
.addr
->tag
== Pam_RR
);
1855 if (i
->Pin
.FpLdSt
.isLoad
) {
1856 vex_printf("lf%c%s ",
1857 (sz
==4 ? 's' : 'd'),
1859 ppHRegPPC(i
->Pin
.FpLdSt
.reg
);
1861 ppPPCAMode(i
->Pin
.FpLdSt
.addr
);
1863 vex_printf("stf%c%s ",
1864 (sz
==4 ? 's' : 'd'),
1866 ppHRegPPC(i
->Pin
.FpLdSt
.reg
);
1868 ppPPCAMode(i
->Pin
.FpLdSt
.addr
);
1873 vex_printf("stfiwz ");
1874 ppHRegPPC(i
->Pin
.FpSTFIW
.data
);
1876 ppHRegPPC(i
->Pin
.FpSTFIW
.addr
);
1880 vex_printf("frsp ");
1881 ppHRegPPC(i
->Pin
.FpRSP
.dst
);
1883 ppHRegPPC(i
->Pin
.FpRSP
.src
);
1886 const HChar
* str
= "fc?????";
1887 /* Note that "fcfids" is missing from below. That instruction would
1888 * satisfy the predicate:
1889 * (i->Pin.FpCftI.fromI == True && i->Pin.FpCftI.int32 == False)
1890 * which would go into a final "else" clause to make this if-else
1891 * block balanced. But we're able to implement fcfids by leveraging
1892 * the fcfid implementation, so it wasn't necessary to include it here.
1894 if (i
->Pin
.FpCftI
.fromI
== False
&& i
->Pin
.FpCftI
.int32
== False
)
1895 if (i
->Pin
.FpCftI
.syned
== True
)
1899 else if (i
->Pin
.FpCftI
.fromI
== False
&& i
->Pin
.FpCftI
.int32
== True
)
1900 if (i
->Pin
.FpCftI
.syned
== True
)
1904 else if (i
->Pin
.FpCftI
.fromI
== True
&& i
->Pin
.FpCftI
.int32
== False
) {
1905 if (i
->Pin
.FpCftI
.syned
== True
) {
1908 if (i
->Pin
.FpCftI
.flt64
== True
)
1914 vex_printf("%s ", str
);
1915 ppHRegPPC(i
->Pin
.FpCftI
.dst
);
1917 ppHRegPPC(i
->Pin
.FpCftI
.src
);
1921 vex_printf("fpcmov (%s) ", showPPCCondCode(i
->Pin
.FpCMov
.cond
));
1922 ppHRegPPC(i
->Pin
.FpCMov
.dst
);
1924 ppHRegPPC(i
->Pin
.FpCMov
.src
);
1926 vex_printf("if (fr_dst != fr_src) { ");
1927 if (i
->Pin
.FpCMov
.cond
.test
!= Pct_ALWAYS
) {
1928 vex_printf("if (%s) { ", showPPCCondCode(i
->Pin
.FpCMov
.cond
));
1931 ppHRegPPC(i
->Pin
.FpCMov
.dst
);
1933 ppHRegPPC(i
->Pin
.FpCMov
.src
);
1934 if (i
->Pin
.FpCMov
.cond
.test
!= Pct_ALWAYS
)
1939 vex_printf("mtfsf 0xFF,");
1940 ppHRegPPC(i
->Pin
.FpLdFPSCR
.src
);
1941 vex_printf(",0, %s", i
->Pin
.FpLdFPSCR
.dfp_rm
? "1" : "0");
1944 vex_printf("fcmpo %%cr1,");
1945 ppHRegPPC(i
->Pin
.FpCmp
.srcL
);
1947 ppHRegPPC(i
->Pin
.FpCmp
.srcR
);
1948 vex_printf("; mfcr ");
1949 ppHRegPPC(i
->Pin
.FpCmp
.dst
);
1950 vex_printf("; rlwinm ");
1951 ppHRegPPC(i
->Pin
.FpCmp
.dst
);
1953 ppHRegPPC(i
->Pin
.FpCmp
.dst
);
1954 vex_printf(",8,28,31");
1958 vex_printf("%s ", i
->Pin
.RdWrLR
.wrLR
? "mtlr" : "mflr");
1959 ppHRegPPC(i
->Pin
.RdWrLR
.gpr
);
1963 UChar sz
= i
->Pin
.AvLdSt
.sz
;
1964 const HChar
* str_size
;
1965 if (i
->Pin
.AvLdSt
.addr
->tag
== Pam_IR
) {
1966 ppLoadImm(hregPPC_GPR30(mode64
),
1967 i
->Pin
.AvLdSt
.addr
->Pam
.IR
.index
, mode64
);
1970 str_size
= sz
==1 ? "eb" : sz
==2 ? "eh" : sz
==4 ? "ew" : "";
1971 if (i
->Pin
.AvLdSt
.isLoad
)
1972 vex_printf("lv%sx ", str_size
);
1974 vex_printf("stv%sx ", str_size
);
1975 ppHRegPPC(i
->Pin
.AvLdSt
.reg
);
1977 if (i
->Pin
.AvLdSt
.addr
->tag
== Pam_IR
)
1978 vex_printf("%%r30");
1980 ppHRegPPC(i
->Pin
.AvLdSt
.addr
->Pam
.RR
.index
);
1982 ppHRegPPC(i
->Pin
.AvLdSt
.addr
->Pam
.RR
.base
);
1986 vex_printf("%s ", showPPCAvOp(i
->Pin
.AvUnary
.op
));
1987 ppHRegPPC(i
->Pin
.AvUnary
.dst
);
1989 ppHRegPPC(i
->Pin
.AvUnary
.src
);
1992 vex_printf("%s ", showPPCAvOp(i
->Pin
.AvBinary
.op
));
1993 ppHRegPPC(i
->Pin
.AvBinary
.dst
);
1995 ppHRegPPC(i
->Pin
.AvBinary
.srcL
);
1997 ppHRegPPC(i
->Pin
.AvBinary
.srcR
);
1999 case Pin_AvBinaryInt
:
2000 vex_printf("%s ", showPPCAvOp(i
->Pin
.AvBinaryInt
.op
));
2001 ppHRegPPC(i
->Pin
.AvBinaryInt
.dst
);
2003 ppHRegPPC(i
->Pin
.AvBinaryInt
.src
);
2005 ppPPCRI(i
->Pin
.AvBinaryInt
.val
);
2008 vex_printf("%s(b) ", showPPCAvOp(i
->Pin
.AvBin8x16
.op
));
2009 ppHRegPPC(i
->Pin
.AvBin8x16
.dst
);
2011 ppHRegPPC(i
->Pin
.AvBin8x16
.srcL
);
2013 ppHRegPPC(i
->Pin
.AvBin8x16
.srcR
);
2016 vex_printf("%s(h) ", showPPCAvOp(i
->Pin
.AvBin16x8
.op
));
2017 ppHRegPPC(i
->Pin
.AvBin16x8
.dst
);
2019 ppHRegPPC(i
->Pin
.AvBin16x8
.srcL
);
2021 ppHRegPPC(i
->Pin
.AvBin16x8
.srcR
);
2024 vex_printf("%s(w) ", showPPCAvOp(i
->Pin
.AvBin32x4
.op
));
2025 ppHRegPPC(i
->Pin
.AvBin32x4
.dst
);
2027 ppHRegPPC(i
->Pin
.AvBin32x4
.srcL
);
2029 ppHRegPPC(i
->Pin
.AvBin32x4
.srcR
);
2032 vex_printf("%s(w) ", showPPCAvOp(i
->Pin
.AvBin64x2
.op
));
2033 ppHRegPPC(i
->Pin
.AvBin64x2
.dst
);
2035 ppHRegPPC(i
->Pin
.AvBin64x2
.srcL
);
2037 ppHRegPPC(i
->Pin
.AvBin64x2
.srcR
);
2039 case Pin_AvBin32Fx4
:
2040 vex_printf("%s ", showPPCAvFpOp(i
->Pin
.AvBin32Fx4
.op
));
2041 ppHRegPPC(i
->Pin
.AvBin32Fx4
.dst
);
2043 ppHRegPPC(i
->Pin
.AvBin32Fx4
.srcL
);
2045 ppHRegPPC(i
->Pin
.AvBin32Fx4
.srcR
);
2048 vex_printf("%s ", showPPCAvFpOp(i
->Pin
.AvUn32Fx4
.op
));
2049 ppHRegPPC(i
->Pin
.AvUn32Fx4
.dst
);
2051 ppHRegPPC(i
->Pin
.AvUn32Fx4
.src
);
2054 vex_printf("vperm ");
2055 ppHRegPPC(i
->Pin
.AvPerm
.dst
);
2057 ppHRegPPC(i
->Pin
.AvPerm
.srcL
);
2059 ppHRegPPC(i
->Pin
.AvPerm
.srcR
);
2061 ppHRegPPC(i
->Pin
.AvPerm
.ctl
);
2065 vex_printf("vsel ");
2066 ppHRegPPC(i
->Pin
.AvSel
.dst
);
2068 ppHRegPPC(i
->Pin
.AvSel
.srcL
);
2070 ppHRegPPC(i
->Pin
.AvSel
.srcR
);
2072 ppHRegPPC(i
->Pin
.AvSel
.ctl
);
2076 /* This only generates the following instructions with RA
2077 * register number set to 0.
2079 if (i
->Pin
.AvSh
.addr
->tag
== Pam_IR
) {
2080 ppLoadImm(hregPPC_GPR30(mode64
),
2081 i
->Pin
.AvSh
.addr
->Pam
.IR
.index
, mode64
);
2085 if (i
->Pin
.AvSh
.shLeft
)
2086 vex_printf("lvsl ");
2088 vex_printf("lvsr ");
2090 ppHRegPPC(i
->Pin
.AvSh
.dst
);
2091 if (i
->Pin
.AvSh
.addr
->tag
== Pam_IR
)
2092 vex_printf("%%r30");
2094 ppHRegPPC(i
->Pin
.AvSh
.addr
->Pam
.RR
.index
);
2096 ppHRegPPC(i
->Pin
.AvSh
.addr
->Pam
.RR
.base
);
2100 vex_printf("vsldoi ");
2101 ppHRegPPC(i
->Pin
.AvShlDbl
.dst
);
2103 ppHRegPPC(i
->Pin
.AvShlDbl
.srcL
);
2105 ppHRegPPC(i
->Pin
.AvShlDbl
.srcR
);
2106 vex_printf(",%d", i
->Pin
.AvShlDbl
.shift
);
2110 UChar sz
= i
->Pin
.AvSplat
.sz
;
2111 HChar ch_sz
= toUChar( (sz
== 8) ? 'b' : (sz
== 16) ? 'h' : 'w' );
2112 vex_printf("vsplt%s%c ",
2113 i
->Pin
.AvSplat
.src
->tag
== Pvi_Imm
? "is" : "", ch_sz
);
2114 ppHRegPPC(i
->Pin
.AvSplat
.dst
);
2116 ppPPCVI5s(i
->Pin
.AvSplat
.src
);
2117 if (i
->Pin
.AvSplat
.src
->tag
== Pvi_Reg
)
2118 vex_printf(", %d", (128/sz
)-1); /* louis lane */
2123 vex_printf("avcmov (%s) ", showPPCCondCode(i
->Pin
.AvCMov
.cond
));
2124 ppHRegPPC(i
->Pin
.AvCMov
.dst
);
2126 ppHRegPPC(i
->Pin
.AvCMov
.src
);
2128 vex_printf("if (v_dst != v_src) { ");
2129 if (i
->Pin
.AvCMov
.cond
.test
!= Pct_ALWAYS
) {
2130 vex_printf("if (%s) { ", showPPCCondCode(i
->Pin
.AvCMov
.cond
));
2133 ppHRegPPC(i
->Pin
.AvCMov
.dst
);
2135 ppHRegPPC(i
->Pin
.AvCMov
.src
);
2136 if (i
->Pin
.FpCMov
.cond
.test
!= Pct_ALWAYS
)
2142 vex_printf("mtvscr ");
2143 ppHRegPPC(i
->Pin
.AvLdVSCR
.src
);
2146 case Pin_AvCipherV128Unary
:
2147 vex_printf("%s(w) ", showPPCAvOp(i
->Pin
.AvCipherV128Unary
.op
));
2148 ppHRegPPC(i
->Pin
.AvCipherV128Unary
.dst
);
2150 ppHRegPPC(i
->Pin
.AvCipherV128Unary
.src
);
2153 case Pin_AvCipherV128Binary
:
2154 vex_printf("%s(w) ", showPPCAvOp(i
->Pin
.AvCipherV128Binary
.op
));
2155 ppHRegPPC(i
->Pin
.AvCipherV128Binary
.dst
);
2157 ppHRegPPC(i
->Pin
.AvCipherV128Binary
.srcL
);
2159 ppHRegPPC(i
->Pin
.AvCipherV128Binary
.srcR
);
2162 case Pin_AvHashV128Binary
:
2163 vex_printf("%s(w) ", showPPCAvOp(i
->Pin
.AvHashV128Binary
.op
));
2164 ppHRegPPC(i
->Pin
.AvHashV128Binary
.dst
);
2166 ppHRegPPC(i
->Pin
.AvHashV128Binary
.src
);
2168 ppPPCRI(i
->Pin
.AvHashV128Binary
.s_field
);
2171 case Pin_AvBCDV128Binary
:
2172 vex_printf("%s(w) ", showPPCAvOp(i
->Pin
.AvBCDV128Binary
.op
));
2173 ppHRegPPC(i
->Pin
.AvBCDV128Binary
.dst
);
2175 ppHRegPPC(i
->Pin
.AvBCDV128Binary
.src1
);
2177 ppHRegPPC(i
->Pin
.AvBCDV128Binary
.src2
);
2180 case Pin_Dfp64Unary
:
2181 vex_printf("%s ", showPPCFpOp(i
->Pin
.Dfp64Unary
.op
));
2182 ppHRegPPC(i
->Pin
.Dfp64Unary
.dst
);
2184 ppHRegPPC(i
->Pin
.Dfp64Unary
.src
);
2187 case Pin_Dfp64Binary
:
2188 vex_printf("%s ", showPPCFpOp(i
->Pin
.Dfp64Binary
.op
));
2189 ppHRegPPC(i
->Pin
.Dfp64Binary
.dst
);
2191 ppHRegPPC(i
->Pin
.Dfp64Binary
.srcL
);
2193 ppHRegPPC(i
->Pin
.Dfp64Binary
.srcR
);
2197 vex_printf("%s ", showPPCFpOp(i
->Pin
.DfpShift
.op
));
2198 ppHRegPPC(i
->Pin
.DfpShift
.dst
);
2200 ppHRegPPC(i
->Pin
.DfpShift
.src
);
2202 ppPPCRI(i
->Pin
.DfpShift
.shift
);
2205 case Pin_Dfp128Unary
:
2206 vex_printf("%s ", showPPCFpOp(i
->Pin
.Dfp128Unary
.op
));
2207 ppHRegPPC(i
->Pin
.Dfp128Unary
.dst_hi
);
2209 ppHRegPPC(i
->Pin
.Dfp128Unary
.src_hi
);
2212 case Pin_Dfp128Binary
:
2213 vex_printf("%s ", showPPCFpOp(i
->Pin
.Dfp128Binary
.op
));
2214 ppHRegPPC(i
->Pin
.Dfp128Binary
.dst_hi
);
2216 ppHRegPPC(i
->Pin
.Dfp128Binary
.srcR_hi
);
2219 case Pin_DfpShift128
:
2220 vex_printf("%s ", showPPCFpOp(i
->Pin
.DfpShift128
.op
));
2221 ppHRegPPC(i
->Pin
.DfpShift128
.dst_hi
);
2223 ppHRegPPC(i
->Pin
.DfpShift128
.src_hi
);
2225 ppPPCRI(i
->Pin
.DfpShift128
.shift
);
2229 vex_printf("drintx ");
2230 ppHRegPPC(i
->Pin
.DfpRound
.dst
);
2232 ppHRegPPC(i
->Pin
.DfpRound
.src
);
2234 ppPPCRI(i
->Pin
.DfpRound
.r_rmc
); /* R in bit 3 and RMC in bits 2:0 */
2237 case Pin_DfpRound128
:
2238 vex_printf("drintxq ");
2239 ppHRegPPC(i
->Pin
.DfpRound128
.dst_hi
);
2241 ppHRegPPC(i
->Pin
.DfpRound128
.src_hi
);
2243 ppPPCRI(i
->Pin
.DfpRound128
.r_rmc
); /* R in bit 3 and RMC in bits 2:0 */
2246 case Pin_DfpQuantize
:
2247 vex_printf("%s ", showPPCFpOp(i
->Pin
.DfpQuantize
.op
));
2248 ppHRegPPC(i
->Pin
.DfpQuantize
.dst
);
2250 ppHRegPPC(i
->Pin
.DfpQuantize
.srcL
);
2252 ppHRegPPC(i
->Pin
.DfpQuantize
.srcR
);
2254 ppPPCRI(i
->Pin
.DfpQuantize
.rmc
);
2257 case Pin_DfpQuantize128
:
2258 /* Dst is used to pass in left source and return result */
2259 vex_printf("dquaq ");
2260 ppHRegPPC(i
->Pin
.DfpQuantize128
.dst_hi
);
2262 ppHRegPPC(i
->Pin
.DfpQuantize128
.dst_hi
);
2264 ppHRegPPC(i
->Pin
.DfpQuantize128
.src_hi
);
2266 ppPPCRI(i
->Pin
.DfpQuantize128
.rmc
);
2269 case Pin_DfpD128toD64
:
2270 vex_printf("%s ", showPPCFpOp(i
->Pin
.DfpD128toD64
.op
));
2271 ppHRegPPC(i
->Pin
.DfpD128toD64
.dst
);
2273 ppHRegPPC(i
->Pin
.DfpD128toD64
.src_hi
);
2277 case Pin_DfpI64StoD128
:
2278 vex_printf("%s ", showPPCFpOp(i
->Pin
.DfpI64StoD128
.op
));
2279 ppHRegPPC(i
->Pin
.DfpI64StoD128
.dst_hi
);
2281 ppHRegPPC(i
->Pin
.DfpI64StoD128
.src
);
2284 case Pin_ExtractExpD128
:
2285 vex_printf("dxexq ");
2286 ppHRegPPC(i
->Pin
.ExtractExpD128
.dst
);
2288 ppHRegPPC(i
->Pin
.ExtractExpD128
.src_hi
);
2290 case Pin_InsertExpD128
:
2291 vex_printf("diexq ");
2292 ppHRegPPC(i
->Pin
.InsertExpD128
.dst_hi
);
2294 ppHRegPPC(i
->Pin
.InsertExpD128
.srcL
);
2296 ppHRegPPC(i
->Pin
.InsertExpD128
.srcR_hi
);
2299 vex_printf("dcmpo %%cr1,");
2300 ppHRegPPC(i
->Pin
.Dfp64Cmp
.srcL
);
2302 ppHRegPPC(i
->Pin
.Dfp64Cmp
.srcR
);
2303 vex_printf("; mfcr ");
2304 ppHRegPPC(i
->Pin
.Dfp64Cmp
.dst
);
2305 vex_printf("; rlwinm ");
2306 ppHRegPPC(i
->Pin
.Dfp64Cmp
.dst
);
2308 ppHRegPPC(i
->Pin
.Dfp64Cmp
.dst
);
2309 vex_printf(",8,28,31");
2312 vex_printf("dcmpoq %%cr1,");
2313 ppHRegPPC(i
->Pin
.Dfp128Cmp
.srcL_hi
);
2315 ppHRegPPC(i
->Pin
.Dfp128Cmp
.srcR_hi
);
2316 vex_printf("; mfcr ");
2317 ppHRegPPC(i
->Pin
.Dfp128Cmp
.dst
);
2318 vex_printf("; rlwinm ");
2319 ppHRegPPC(i
->Pin
.Dfp128Cmp
.dst
);
2321 ppHRegPPC(i
->Pin
.Dfp128Cmp
.dst
);
2322 vex_printf(",8,28,31");
2325 /* Note that the counter dec is 32 bit even in 64-bit mode. */
2326 vex_printf("(evCheck) ");
2327 vex_printf("lwz r30,");
2328 ppPPCAMode(i
->Pin
.EvCheck
.amCounter
);
2329 vex_printf("; addic. r30,r30,-1; ");
2330 vex_printf("stw r30,");
2331 ppPPCAMode(i
->Pin
.EvCheck
.amCounter
);
2332 vex_printf("; bge nofail; lwz r30,");
2333 ppPPCAMode(i
->Pin
.EvCheck
.amFailAddr
);
2334 vex_printf("; mtctr r30; bctr; nofail:");
2338 vex_printf("(profInc) imm64-fixed5 r30,$NotKnownYet; ");
2339 vex_printf("ld r29,(r30); addi r29,r29,1; std r29,(r30)");
2341 vex_printf("(profInc) imm32-fixed2 r30,$NotKnownYet; ");
2342 vex_printf("lwz r29,4(r30); addic. r29,r29,1; stw r29,4(r30)");
2343 vex_printf("lwz r29,0(r30); addze r29,r29; stw r29,0(r30)");
2347 vex_printf("\nppPPCInstr: No such tag(%d)\n", (Int
)i
->tag
);
2348 vpanic("ppPPCInstr");
2352 /* --------- Helpers for register allocation. --------- */
2354 void getRegUsage_PPCInstr ( HRegUsage
* u
, const PPCInstr
* i
, Bool mode64
)
2359 addHRegUse(u
, HRmWrite
, i
->Pin
.LI
.dst
);
2362 addHRegUse(u
, HRmRead
, i
->Pin
.Alu
.srcL
);
2363 addRegUsage_PPCRH(u
, i
->Pin
.Alu
.srcR
);
2364 addHRegUse(u
, HRmWrite
, i
->Pin
.Alu
.dst
);
2366 // or Rd,Rs,Rs == mr Rd,Rs
2367 if ((i
->Pin
.Alu
.op
== Palu_OR
)
2368 && (i
->Pin
.Alu
.srcR
->tag
== Prh_Reg
)
2369 && sameHReg(i
->Pin
.Alu
.srcR
->Prh
.Reg
.reg
, i
->Pin
.Alu
.srcL
)) {
2370 u
->isRegRegMove
= True
;
2371 u
->regMoveSrc
= i
->Pin
.Alu
.srcL
;
2372 u
->regMoveDst
= i
->Pin
.Alu
.dst
;
2376 addHRegUse(u
, HRmRead
, i
->Pin
.Shft
.srcL
);
2377 addRegUsage_PPCRH(u
, i
->Pin
.Shft
.srcR
);
2378 addHRegUse(u
, HRmWrite
, i
->Pin
.Shft
.dst
);
2381 addHRegUse(u
, HRmWrite
, i
->Pin
.AddSubC
.dst
);
2382 addHRegUse(u
, HRmRead
, i
->Pin
.AddSubC
.srcL
);
2383 addHRegUse(u
, HRmRead
, i
->Pin
.AddSubC
.srcR
);
2386 addHRegUse(u
, HRmRead
, i
->Pin
.Cmp
.srcL
);
2387 addRegUsage_PPCRH(u
, i
->Pin
.Cmp
.srcR
);
2390 addHRegUse(u
, HRmWrite
, i
->Pin
.Unary
.dst
);
2391 addHRegUse(u
, HRmRead
, i
->Pin
.Unary
.src
);
2394 addHRegUse(u
, HRmWrite
, i
->Pin
.MulL
.dst
);
2395 addHRegUse(u
, HRmRead
, i
->Pin
.MulL
.srcL
);
2396 addHRegUse(u
, HRmRead
, i
->Pin
.MulL
.srcR
);
2399 addHRegUse(u
, HRmWrite
, i
->Pin
.Div
.dst
);
2400 addHRegUse(u
, HRmRead
, i
->Pin
.Div
.srcL
);
2401 addHRegUse(u
, HRmRead
, i
->Pin
.Div
.srcR
);
2405 /* This is a bit subtle. */
2406 /* First off, claim it trashes all the caller-saved regs
2407 which fall within the register allocator's jurisdiction.
2408 These I believe to be:
2412 /* XXXXXXXXXXXXXXXXX BUG! This doesn't say anything about the FP
2413 or Altivec registers. We get away with this ONLY because
2414 getAllocatableRegs_PPC gives the allocator callee-saved fp
2415 and Altivec regs, and no caller-save ones. */
2416 addHRegUse(u
, HRmWrite
, hregPPC_GPR3(mode64
));
2417 addHRegUse(u
, HRmWrite
, hregPPC_GPR4(mode64
));
2418 addHRegUse(u
, HRmWrite
, hregPPC_GPR5(mode64
));
2419 addHRegUse(u
, HRmWrite
, hregPPC_GPR6(mode64
));
2420 addHRegUse(u
, HRmWrite
, hregPPC_GPR7(mode64
));
2421 addHRegUse(u
, HRmWrite
, hregPPC_GPR8(mode64
));
2422 addHRegUse(u
, HRmWrite
, hregPPC_GPR9(mode64
));
2423 addHRegUse(u
, HRmWrite
, hregPPC_GPR10(mode64
));
2425 addHRegUse(u
, HRmWrite
, hregPPC_GPR11(mode64
));
2426 addHRegUse(u
, HRmWrite
, hregPPC_GPR12(mode64
));
2429 /* Now we have to state any parameter-carrying registers
2430 which might be read. This depends on the argiregs field. */
2431 argir
= i
->Pin
.Call
.argiregs
;
2432 if (argir
&(1<<10)) addHRegUse(u
, HRmRead
, hregPPC_GPR10(mode64
));
2433 if (argir
& (1<<9)) addHRegUse(u
, HRmRead
, hregPPC_GPR9(mode64
));
2434 if (argir
& (1<<8)) addHRegUse(u
, HRmRead
, hregPPC_GPR8(mode64
));
2435 if (argir
& (1<<7)) addHRegUse(u
, HRmRead
, hregPPC_GPR7(mode64
));
2436 if (argir
& (1<<6)) addHRegUse(u
, HRmRead
, hregPPC_GPR6(mode64
));
2437 if (argir
& (1<<5)) addHRegUse(u
, HRmRead
, hregPPC_GPR5(mode64
));
2438 if (argir
& (1<<4)) addHRegUse(u
, HRmRead
, hregPPC_GPR4(mode64
));
2439 if (argir
& (1<<3)) addHRegUse(u
, HRmRead
, hregPPC_GPR3(mode64
));
2441 vassert(0 == (argir
& ~((1<<3)|(1<<4)|(1<<5)|(1<<6)
2442 |(1<<7)|(1<<8)|(1<<9)|(1<<10))));
2444 /* Finally, there is the issue that the insn trashes a
2445 register because the literal target address has to be
2446 loaded into a register. %r10 seems a suitable victim.
2447 (Can't use %r0, as some insns interpret it as value zero). */
2448 addHRegUse(u
, HRmWrite
, hregPPC_GPR10(mode64
));
2449 /* Upshot of this is that the assembler really must use %r10,
2450 and no other, as a destination temporary. */
2453 /* XDirect/XIndir/XAssisted are also a bit subtle. They
2454 conditionally exit the block. Hence we only need to list (1)
2455 the registers that they read, and (2) the registers that they
2456 write in the case where the block is not exited. (2) is empty,
2457 hence only (1) is relevant here. */
2459 addRegUsage_PPCAMode(u
, i
->Pin
.XDirect
.amCIA
);
2462 addHRegUse(u
, HRmRead
, i
->Pin
.XIndir
.dstGA
);
2463 addRegUsage_PPCAMode(u
, i
->Pin
.XIndir
.amCIA
);
2466 addHRegUse(u
, HRmRead
, i
->Pin
.XAssisted
.dstGA
);
2467 addRegUsage_PPCAMode(u
, i
->Pin
.XAssisted
.amCIA
);
2470 addRegUsage_PPCRI(u
, i
->Pin
.CMov
.src
);
2471 addHRegUse(u
, HRmWrite
, i
->Pin
.CMov
.dst
);
2474 addRegUsage_PPCAMode(u
, i
->Pin
.Load
.src
);
2475 addHRegUse(u
, HRmWrite
, i
->Pin
.Load
.dst
);
2478 addHRegUse(u
, HRmRead
, i
->Pin
.LoadL
.src
);
2479 addHRegUse(u
, HRmWrite
, i
->Pin
.LoadL
.dst
);
2482 addHRegUse(u
, HRmRead
, i
->Pin
.Store
.src
);
2483 addRegUsage_PPCAMode(u
, i
->Pin
.Store
.dst
);
2486 addHRegUse(u
, HRmRead
, i
->Pin
.StoreC
.src
);
2487 addHRegUse(u
, HRmRead
, i
->Pin
.StoreC
.dst
);
2490 addHRegUse(u
, HRmWrite
, i
->Pin
.Set
.dst
);
2493 addHRegUse(u
, HRmWrite
, i
->Pin
.MfCR
.dst
);
2499 addHRegUse(u
, HRmWrite
, i
->Pin
.FpUnary
.dst
);
2500 addHRegUse(u
, HRmRead
, i
->Pin
.FpUnary
.src
);
2502 if (i
->Pin
.FpUnary
.op
== Pfp_MOV
) {
2503 u
->isRegRegMove
= True
;
2504 u
->regMoveSrc
= i
->Pin
.FpUnary
.src
;
2505 u
->regMoveDst
= i
->Pin
.FpUnary
.dst
;
2509 addHRegUse(u
, HRmWrite
, i
->Pin
.FpBinary
.dst
);
2510 addHRegUse(u
, HRmRead
, i
->Pin
.FpBinary
.srcL
);
2511 addHRegUse(u
, HRmRead
, i
->Pin
.FpBinary
.srcR
);
2514 case Pin_Fp128Unary
:
2515 addHRegUse(u
, HRmWrite
, i
->Pin
.Fp128Unary
.dst
);
2516 addHRegUse(u
, HRmRead
, i
->Pin
.Fp128Unary
.src
);
2518 case Pin_Fp128Binary
:
2519 addHRegUse(u
, HRmWrite
, i
->Pin
.Fp128Binary
.dst
);
2520 addHRegUse(u
, HRmRead
, i
->Pin
.Fp128Binary
.srcL
);
2521 addHRegUse(u
, HRmRead
, i
->Pin
.Fp128Binary
.srcR
);
2523 case Pin_Fp128Trinary
:
2524 addHRegUse(u
, HRmModify
, i
->Pin
.Fp128Trinary
.dst
);
2525 addHRegUse(u
, HRmRead
, i
->Pin
.Fp128Trinary
.srcL
);
2526 addHRegUse(u
, HRmRead
, i
->Pin
.Fp128Trinary
.srcR
);
2529 addHRegUse(u
, HRmWrite
, i
->Pin
.FpMulAcc
.dst
);
2530 addHRegUse(u
, HRmRead
, i
->Pin
.FpMulAcc
.srcML
);
2531 addHRegUse(u
, HRmRead
, i
->Pin
.FpMulAcc
.srcMR
);
2532 addHRegUse(u
, HRmRead
, i
->Pin
.FpMulAcc
.srcAcc
);
2535 addHRegUse(u
, (i
->Pin
.FpLdSt
.isLoad
? HRmWrite
: HRmRead
),
2537 addRegUsage_PPCAMode(u
, i
->Pin
.FpLdSt
.addr
);
2540 addHRegUse(u
, HRmRead
, i
->Pin
.FpSTFIW
.addr
);
2541 addHRegUse(u
, HRmRead
, i
->Pin
.FpSTFIW
.data
);
2544 addHRegUse(u
, HRmWrite
, i
->Pin
.FpRSP
.dst
);
2545 addHRegUse(u
, HRmRead
, i
->Pin
.FpRSP
.src
);
2548 addHRegUse(u
, HRmWrite
, i
->Pin
.FpCftI
.dst
);
2549 addHRegUse(u
, HRmRead
, i
->Pin
.FpCftI
.src
);
2552 addHRegUse(u
, HRmModify
, i
->Pin
.FpCMov
.dst
);
2553 addHRegUse(u
, HRmRead
, i
->Pin
.FpCMov
.src
);
2556 addHRegUse(u
, HRmRead
, i
->Pin
.FpLdFPSCR
.src
);
2559 addHRegUse(u
, HRmWrite
, i
->Pin
.FpCmp
.dst
);
2560 addHRegUse(u
, HRmRead
, i
->Pin
.FpCmp
.srcL
);
2561 addHRegUse(u
, HRmRead
, i
->Pin
.FpCmp
.srcR
);
2565 addHRegUse(u
, (i
->Pin
.RdWrLR
.wrLR
? HRmRead
: HRmWrite
),
2570 addHRegUse(u
, (i
->Pin
.AvLdSt
.isLoad
? HRmWrite
: HRmRead
),
2572 if (i
->Pin
.AvLdSt
.addr
->tag
== Pam_IR
)
2573 addHRegUse(u
, HRmWrite
, hregPPC_GPR30(mode64
));
2574 addRegUsage_PPCAMode(u
, i
->Pin
.AvLdSt
.addr
);
2577 addHRegUse(u
, HRmWrite
, i
->Pin
.AvUnary
.dst
);
2578 addHRegUse(u
, HRmRead
, i
->Pin
.AvUnary
.src
);
2581 if (i
->Pin
.AvBinary
.op
== Pav_XOR
2582 && sameHReg(i
->Pin
.AvBinary
.dst
, i
->Pin
.AvBinary
.srcL
)
2583 && sameHReg(i
->Pin
.AvBinary
.dst
, i
->Pin
.AvBinary
.srcR
)) {
2584 /* reg-alloc needs to understand 'xor r,r,r' as a write of r */
2585 /* (as opposed to a rite of passage :-) */
2586 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBinary
.dst
);
2588 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBinary
.dst
);
2589 addHRegUse(u
, HRmRead
, i
->Pin
.AvBinary
.srcL
);
2590 addHRegUse(u
, HRmRead
, i
->Pin
.AvBinary
.srcR
);
2593 case Pin_AvBinaryInt
:
2594 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBinaryInt
.dst
);
2595 addHRegUse(u
, HRmRead
, i
->Pin
.AvBinaryInt
.src
);
2598 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBin8x16
.dst
);
2599 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin8x16
.srcL
);
2600 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin8x16
.srcR
);
2603 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBin16x8
.dst
);
2604 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin16x8
.srcL
);
2605 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin16x8
.srcR
);
2608 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBin32x4
.dst
);
2609 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin32x4
.srcL
);
2610 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin32x4
.srcR
);
2613 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBin64x2
.dst
);
2614 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin64x2
.srcL
);
2615 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin64x2
.srcR
);
2617 case Pin_AvBin32Fx4
:
2618 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBin32Fx4
.dst
);
2619 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin32Fx4
.srcL
);
2620 addHRegUse(u
, HRmRead
, i
->Pin
.AvBin32Fx4
.srcR
);
2621 if (i
->Pin
.AvBin32Fx4
.op
== Pavfp_MULF
)
2622 addHRegUse(u
, HRmWrite
, hregPPC_VR29(mode64
));
2625 addHRegUse(u
, HRmWrite
, i
->Pin
.AvUn32Fx4
.dst
);
2626 addHRegUse(u
, HRmRead
, i
->Pin
.AvUn32Fx4
.src
);
2629 addHRegUse(u
, HRmWrite
, i
->Pin
.AvPerm
.dst
);
2630 addHRegUse(u
, HRmRead
, i
->Pin
.AvPerm
.srcL
);
2631 addHRegUse(u
, HRmRead
, i
->Pin
.AvPerm
.srcR
);
2632 addHRegUse(u
, HRmRead
, i
->Pin
.AvPerm
.ctl
);
2635 addHRegUse(u
, HRmWrite
, i
->Pin
.AvSel
.dst
);
2636 addHRegUse(u
, HRmRead
, i
->Pin
.AvSel
.ctl
);
2637 addHRegUse(u
, HRmRead
, i
->Pin
.AvSel
.srcL
);
2638 addHRegUse(u
, HRmRead
, i
->Pin
.AvSel
.srcR
);
2641 addHRegUse(u
, HRmWrite
, i
->Pin
.AvSh
.dst
);
2642 if (i
->Pin
.AvSh
.addr
->tag
== Pam_IR
)
2643 addHRegUse(u
, HRmWrite
, hregPPC_GPR30(mode64
));
2644 addRegUsage_PPCAMode(u
, i
->Pin
.AvSh
.addr
);
2647 addHRegUse(u
, HRmWrite
, i
->Pin
.AvShlDbl
.dst
);
2648 addHRegUse(u
, HRmRead
, i
->Pin
.AvShlDbl
.srcL
);
2649 addHRegUse(u
, HRmRead
, i
->Pin
.AvShlDbl
.srcR
);
2652 addHRegUse(u
, HRmWrite
, i
->Pin
.AvSplat
.dst
);
2653 addRegUsage_PPCVI5s(u
, i
->Pin
.AvSplat
.src
);
2656 addHRegUse(u
, HRmModify
, i
->Pin
.AvCMov
.dst
);
2657 addHRegUse(u
, HRmRead
, i
->Pin
.AvCMov
.src
);
2660 addHRegUse(u
, HRmRead
, i
->Pin
.AvLdVSCR
.src
);
2662 case Pin_AvCipherV128Unary
:
2663 addHRegUse(u
, HRmWrite
, i
->Pin
.AvCipherV128Unary
.dst
);
2664 addHRegUse(u
, HRmRead
, i
->Pin
.AvCipherV128Unary
.src
);
2666 case Pin_AvCipherV128Binary
:
2667 addHRegUse(u
, HRmWrite
, i
->Pin
.AvCipherV128Binary
.dst
);
2668 addHRegUse(u
, HRmRead
, i
->Pin
.AvCipherV128Binary
.srcL
);
2669 addHRegUse(u
, HRmRead
, i
->Pin
.AvCipherV128Binary
.srcR
);
2671 case Pin_AvHashV128Binary
:
2672 addHRegUse(u
, HRmWrite
, i
->Pin
.AvHashV128Binary
.dst
);
2673 addHRegUse(u
, HRmRead
, i
->Pin
.AvHashV128Binary
.src
);
2674 addRegUsage_PPCRI(u
, i
->Pin
.AvHashV128Binary
.s_field
);
2676 case Pin_AvBCDV128Binary
:
2677 addHRegUse(u
, HRmWrite
, i
->Pin
.AvBCDV128Binary
.dst
);
2678 addHRegUse(u
, HRmRead
, i
->Pin
.AvBCDV128Binary
.src1
);
2679 addHRegUse(u
, HRmRead
, i
->Pin
.AvBCDV128Binary
.src2
);
2681 case Pin_Dfp64Unary
:
2682 addHRegUse(u
, HRmWrite
, i
->Pin
.Dfp64Unary
.dst
);
2683 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp64Unary
.src
);
2685 case Pin_Dfp64Binary
:
2686 addHRegUse(u
, HRmWrite
, i
->Pin
.Dfp64Binary
.dst
);
2687 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp64Binary
.srcL
);
2688 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp64Binary
.srcR
);
2691 addRegUsage_PPCRI(u
, i
->Pin
.DfpShift
.shift
);
2692 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpShift
.src
);
2693 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpShift
.dst
);
2695 case Pin_Dfp128Unary
:
2696 addHRegUse(u
, HRmWrite
, i
->Pin
.Dfp128Unary
.dst_hi
);
2697 addHRegUse(u
, HRmWrite
, i
->Pin
.Dfp128Unary
.dst_lo
);
2698 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp128Unary
.src_hi
);
2699 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp128Unary
.src_lo
);
2701 case Pin_Dfp128Binary
:
2702 addHRegUse(u
, HRmWrite
, i
->Pin
.Dfp128Binary
.dst_hi
);
2703 addHRegUse(u
, HRmWrite
, i
->Pin
.Dfp128Binary
.dst_lo
);
2704 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp128Binary
.srcR_hi
);
2705 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp128Binary
.srcR_lo
);
2708 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpRound
.dst
);
2709 addHRegUse(u
, HRmRead
, i
->Pin
.DfpRound
.src
);
2711 case Pin_DfpRound128
:
2712 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpRound128
.dst_hi
);
2713 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpRound128
.dst_lo
);
2714 addHRegUse(u
, HRmRead
, i
->Pin
.DfpRound128
.src_hi
);
2715 addHRegUse(u
, HRmRead
, i
->Pin
.DfpRound128
.src_lo
);
2717 case Pin_DfpQuantize
:
2718 addRegUsage_PPCRI(u
, i
->Pin
.DfpQuantize
.rmc
);
2719 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpQuantize
.dst
);
2720 addHRegUse(u
, HRmRead
, i
->Pin
.DfpQuantize
.srcL
);
2721 addHRegUse(u
, HRmRead
, i
->Pin
.DfpQuantize
.srcR
);
2723 case Pin_DfpQuantize128
:
2724 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpQuantize128
.dst_hi
);
2725 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpQuantize128
.dst_lo
);
2726 addHRegUse(u
, HRmRead
, i
->Pin
.DfpQuantize128
.src_hi
);
2727 addHRegUse(u
, HRmRead
, i
->Pin
.DfpQuantize128
.src_lo
);
2729 case Pin_DfpShift128
:
2730 addRegUsage_PPCRI(u
, i
->Pin
.DfpShift128
.shift
);
2731 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpShift128
.src_hi
);
2732 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpShift128
.src_lo
);
2733 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpShift128
.dst_hi
);
2734 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpShift128
.dst_lo
);
2736 case Pin_DfpD128toD64
:
2737 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpD128toD64
.src_hi
);
2738 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpD128toD64
.src_lo
);
2739 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpD128toD64
.dst
);
2741 case Pin_DfpI64StoD128
:
2742 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpI64StoD128
.src
);
2743 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpI64StoD128
.dst_hi
);
2744 addHRegUse(u
, HRmWrite
, i
->Pin
.DfpI64StoD128
.dst_lo
);
2746 case Pin_ExtractExpD128
:
2747 addHRegUse(u
, HRmWrite
, i
->Pin
.ExtractExpD128
.dst
);
2748 addHRegUse(u
, HRmRead
, i
->Pin
.ExtractExpD128
.src_hi
);
2749 addHRegUse(u
, HRmRead
, i
->Pin
.ExtractExpD128
.src_lo
);
2751 case Pin_InsertExpD128
:
2752 addHRegUse(u
, HRmWrite
, i
->Pin
.InsertExpD128
.dst_hi
);
2753 addHRegUse(u
, HRmWrite
, i
->Pin
.InsertExpD128
.dst_lo
);
2754 addHRegUse(u
, HRmRead
, i
->Pin
.InsertExpD128
.srcL
);
2755 addHRegUse(u
, HRmRead
, i
->Pin
.InsertExpD128
.srcR_hi
);
2756 addHRegUse(u
, HRmRead
, i
->Pin
.InsertExpD128
.srcR_lo
);
2759 addHRegUse(u
, HRmWrite
, i
->Pin
.Dfp64Cmp
.dst
);
2760 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp64Cmp
.srcL
);
2761 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp64Cmp
.srcR
);
2764 addHRegUse(u
, HRmWrite
, i
->Pin
.Dfp128Cmp
.dst
);
2765 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp128Cmp
.srcL_hi
);
2766 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp128Cmp
.srcL_lo
);
2767 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp128Cmp
.srcR_hi
);
2768 addHRegUse(u
, HRmRead
, i
->Pin
.Dfp128Cmp
.srcR_lo
);
2771 /* We expect both amodes only to mention the GSP (r31), so this
2772 is in fact pointless, since GSP isn't allocatable, but
2774 addRegUsage_PPCAMode(u
, i
->Pin
.EvCheck
.amCounter
);
2775 addRegUsage_PPCAMode(u
, i
->Pin
.EvCheck
.amFailAddr
);
2776 addHRegUse(u
, HRmWrite
, hregPPC_GPR30(mode64
)); /* also unavail to RA */
2779 addHRegUse(u
, HRmWrite
, hregPPC_GPR29(mode64
));
2780 addHRegUse(u
, HRmWrite
, hregPPC_GPR30(mode64
));
2783 ppPPCInstr(i
, mode64
);
2784 vpanic("getRegUsage_PPCInstr");
2789 static void mapReg( HRegRemap
* m
, HReg
* r
)
2791 *r
= lookupHRegRemap(m
, *r
);
2794 void mapRegs_PPCInstr ( HRegRemap
* m
, PPCInstr
* i
, Bool mode64
)
2798 mapReg(m
, &i
->Pin
.LI
.dst
);
2801 mapReg(m
, &i
->Pin
.Alu
.dst
);
2802 mapReg(m
, &i
->Pin
.Alu
.srcL
);
2803 mapRegs_PPCRH(m
, i
->Pin
.Alu
.srcR
);
2806 mapReg(m
, &i
->Pin
.Shft
.dst
);
2807 mapReg(m
, &i
->Pin
.Shft
.srcL
);
2808 mapRegs_PPCRH(m
, i
->Pin
.Shft
.srcR
);
2811 mapReg(m
, &i
->Pin
.AddSubC
.dst
);
2812 mapReg(m
, &i
->Pin
.AddSubC
.srcL
);
2813 mapReg(m
, &i
->Pin
.AddSubC
.srcR
);
2816 mapReg(m
, &i
->Pin
.Cmp
.srcL
);
2817 mapRegs_PPCRH(m
, i
->Pin
.Cmp
.srcR
);
2820 mapReg(m
, &i
->Pin
.Unary
.dst
);
2821 mapReg(m
, &i
->Pin
.Unary
.src
);
2824 mapReg(m
, &i
->Pin
.MulL
.dst
);
2825 mapReg(m
, &i
->Pin
.MulL
.srcL
);
2826 mapReg(m
, &i
->Pin
.MulL
.srcR
);
2829 mapReg(m
, &i
->Pin
.Div
.dst
);
2830 mapReg(m
, &i
->Pin
.Div
.srcL
);
2831 mapReg(m
, &i
->Pin
.Div
.srcR
);
2836 mapRegs_PPCAMode(m
, i
->Pin
.XDirect
.amCIA
);
2839 mapReg(m
, &i
->Pin
.XIndir
.dstGA
);
2840 mapRegs_PPCAMode(m
, i
->Pin
.XIndir
.amCIA
);
2843 mapReg(m
, &i
->Pin
.XAssisted
.dstGA
);
2844 mapRegs_PPCAMode(m
, i
->Pin
.XAssisted
.amCIA
);
2847 mapRegs_PPCRI(m
, i
->Pin
.CMov
.src
);
2848 mapReg(m
, &i
->Pin
.CMov
.dst
);
2851 mapRegs_PPCAMode(m
, i
->Pin
.Load
.src
);
2852 mapReg(m
, &i
->Pin
.Load
.dst
);
2855 mapReg(m
, &i
->Pin
.LoadL
.src
);
2856 mapReg(m
, &i
->Pin
.LoadL
.dst
);
2859 mapReg(m
, &i
->Pin
.Store
.src
);
2860 mapRegs_PPCAMode(m
, i
->Pin
.Store
.dst
);
2863 mapReg(m
, &i
->Pin
.StoreC
.src
);
2864 mapReg(m
, &i
->Pin
.StoreC
.dst
);
2867 mapReg(m
, &i
->Pin
.Set
.dst
);
2870 mapReg(m
, &i
->Pin
.MfCR
.dst
);
2875 mapReg(m
, &i
->Pin
.FpUnary
.dst
);
2876 mapReg(m
, &i
->Pin
.FpUnary
.src
);
2879 mapReg(m
, &i
->Pin
.FpBinary
.dst
);
2880 mapReg(m
, &i
->Pin
.FpBinary
.srcL
);
2881 mapReg(m
, &i
->Pin
.FpBinary
.srcR
);
2883 case Pin_Fp128Unary
:
2884 mapReg(m
, &i
->Pin
.Fp128Unary
.dst
);
2885 mapReg(m
, &i
->Pin
.Fp128Unary
.src
);
2887 case Pin_Fp128Binary
:
2888 mapReg(m
, &i
->Pin
.Fp128Binary
.dst
);
2889 mapReg(m
, &i
->Pin
.Fp128Binary
.srcL
);
2890 mapReg(m
, &i
->Pin
.Fp128Binary
.srcR
);
2892 case Pin_Fp128Trinary
:
2893 mapReg(m
, &i
->Pin
.Fp128Trinary
.dst
);
2894 mapReg(m
, &i
->Pin
.Fp128Trinary
.srcL
);
2895 mapReg(m
, &i
->Pin
.Fp128Trinary
.srcR
);
2898 mapReg(m
, &i
->Pin
.FpMulAcc
.dst
);
2899 mapReg(m
, &i
->Pin
.FpMulAcc
.srcML
);
2900 mapReg(m
, &i
->Pin
.FpMulAcc
.srcMR
);
2901 mapReg(m
, &i
->Pin
.FpMulAcc
.srcAcc
);
2904 mapReg(m
, &i
->Pin
.FpLdSt
.reg
);
2905 mapRegs_PPCAMode(m
, i
->Pin
.FpLdSt
.addr
);
2908 mapReg(m
, &i
->Pin
.FpSTFIW
.addr
);
2909 mapReg(m
, &i
->Pin
.FpSTFIW
.data
);
2912 mapReg(m
, &i
->Pin
.FpRSP
.dst
);
2913 mapReg(m
, &i
->Pin
.FpRSP
.src
);
2916 mapReg(m
, &i
->Pin
.FpCftI
.dst
);
2917 mapReg(m
, &i
->Pin
.FpCftI
.src
);
2920 mapReg(m
, &i
->Pin
.FpCMov
.dst
);
2921 mapReg(m
, &i
->Pin
.FpCMov
.src
);
2924 mapReg(m
, &i
->Pin
.FpLdFPSCR
.src
);
2927 mapReg(m
, &i
->Pin
.FpCmp
.dst
);
2928 mapReg(m
, &i
->Pin
.FpCmp
.srcL
);
2929 mapReg(m
, &i
->Pin
.FpCmp
.srcR
);
2932 mapReg(m
, &i
->Pin
.RdWrLR
.gpr
);
2935 mapReg(m
, &i
->Pin
.AvLdSt
.reg
);
2936 mapRegs_PPCAMode(m
, i
->Pin
.AvLdSt
.addr
);
2939 mapReg(m
, &i
->Pin
.AvUnary
.dst
);
2940 mapReg(m
, &i
->Pin
.AvUnary
.src
);
2943 mapReg(m
, &i
->Pin
.AvBinary
.dst
);
2944 mapReg(m
, &i
->Pin
.AvBinary
.srcL
);
2945 mapReg(m
, &i
->Pin
.AvBinary
.srcR
);
2947 case Pin_AvBinaryInt
:
2948 mapReg(m
, &i
->Pin
.AvBinaryInt
.dst
);
2949 mapReg(m
, &i
->Pin
.AvBinaryInt
.src
);
2952 mapReg(m
, &i
->Pin
.AvBin8x16
.dst
);
2953 mapReg(m
, &i
->Pin
.AvBin8x16
.srcL
);
2954 mapReg(m
, &i
->Pin
.AvBin8x16
.srcR
);
2957 mapReg(m
, &i
->Pin
.AvBin16x8
.dst
);
2958 mapReg(m
, &i
->Pin
.AvBin16x8
.srcL
);
2959 mapReg(m
, &i
->Pin
.AvBin16x8
.srcR
);
2962 mapReg(m
, &i
->Pin
.AvBin32x4
.dst
);
2963 mapReg(m
, &i
->Pin
.AvBin32x4
.srcL
);
2964 mapReg(m
, &i
->Pin
.AvBin32x4
.srcR
);
2967 mapReg(m
, &i
->Pin
.AvBin64x2
.dst
);
2968 mapReg(m
, &i
->Pin
.AvBin64x2
.srcL
);
2969 mapReg(m
, &i
->Pin
.AvBin64x2
.srcR
);
2971 case Pin_AvBin32Fx4
:
2972 mapReg(m
, &i
->Pin
.AvBin32Fx4
.dst
);
2973 mapReg(m
, &i
->Pin
.AvBin32Fx4
.srcL
);
2974 mapReg(m
, &i
->Pin
.AvBin32Fx4
.srcR
);
2977 mapReg(m
, &i
->Pin
.AvUn32Fx4
.dst
);
2978 mapReg(m
, &i
->Pin
.AvUn32Fx4
.src
);
2981 mapReg(m
, &i
->Pin
.AvPerm
.dst
);
2982 mapReg(m
, &i
->Pin
.AvPerm
.srcL
);
2983 mapReg(m
, &i
->Pin
.AvPerm
.srcR
);
2984 mapReg(m
, &i
->Pin
.AvPerm
.ctl
);
2987 mapReg(m
, &i
->Pin
.AvSel
.dst
);
2988 mapReg(m
, &i
->Pin
.AvSel
.srcL
);
2989 mapReg(m
, &i
->Pin
.AvSel
.srcR
);
2990 mapReg(m
, &i
->Pin
.AvSel
.ctl
);
2993 mapReg(m
, &i
->Pin
.AvSh
.dst
);
2994 mapRegs_PPCAMode(m
, i
->Pin
.AvSh
.addr
);
2997 mapReg(m
, &i
->Pin
.AvShlDbl
.dst
);
2998 mapReg(m
, &i
->Pin
.AvShlDbl
.srcL
);
2999 mapReg(m
, &i
->Pin
.AvShlDbl
.srcR
);
3002 mapReg(m
, &i
->Pin
.AvSplat
.dst
);
3003 mapRegs_PPCVI5s(m
, i
->Pin
.AvSplat
.src
);
3006 mapReg(m
, &i
->Pin
.AvCMov
.dst
);
3007 mapReg(m
, &i
->Pin
.AvCMov
.src
);
3010 mapReg(m
, &i
->Pin
.AvLdVSCR
.src
);
3012 case Pin_AvCipherV128Unary
:
3013 mapReg(m
, &i
->Pin
.AvCipherV128Unary
.dst
);
3014 mapReg(m
, &i
->Pin
.AvCipherV128Unary
.src
);
3016 case Pin_AvCipherV128Binary
:
3017 mapReg(m
, &i
->Pin
.AvCipherV128Binary
.dst
);
3018 mapReg(m
, &i
->Pin
.AvCipherV128Binary
.srcL
);
3019 mapReg(m
, &i
->Pin
.AvCipherV128Binary
.srcR
);
3021 case Pin_AvHashV128Binary
:
3022 mapRegs_PPCRI(m
, i
->Pin
.AvHashV128Binary
.s_field
);
3023 mapReg(m
, &i
->Pin
.AvHashV128Binary
.dst
);
3024 mapReg(m
, &i
->Pin
.AvHashV128Binary
.src
);
3026 case Pin_AvBCDV128Binary
:
3027 mapReg(m
, &i
->Pin
.AvBCDV128Binary
.dst
);
3028 mapReg(m
, &i
->Pin
.AvBCDV128Binary
.src1
);
3029 mapReg(m
, &i
->Pin
.AvBCDV128Binary
.src2
);
3031 case Pin_Dfp64Unary
:
3032 mapReg(m
, &i
->Pin
.Dfp64Unary
.dst
);
3033 mapReg(m
, &i
->Pin
.Dfp64Unary
.src
);
3035 case Pin_Dfp64Binary
:
3036 mapReg(m
, &i
->Pin
.Dfp64Binary
.dst
);
3037 mapReg(m
, &i
->Pin
.Dfp64Binary
.srcL
);
3038 mapReg(m
, &i
->Pin
.Dfp64Binary
.srcR
);
3041 mapRegs_PPCRI(m
, i
->Pin
.DfpShift
.shift
);
3042 mapReg(m
, &i
->Pin
.DfpShift
.src
);
3043 mapReg(m
, &i
->Pin
.DfpShift
.dst
);
3045 case Pin_Dfp128Unary
:
3046 mapReg(m
, &i
->Pin
.Dfp128Unary
.dst_hi
);
3047 mapReg(m
, &i
->Pin
.Dfp128Unary
.dst_lo
);
3048 mapReg(m
, &i
->Pin
.Dfp128Unary
.src_hi
);
3049 mapReg(m
, &i
->Pin
.Dfp128Unary
.src_lo
);
3051 case Pin_Dfp128Binary
:
3052 mapReg(m
, &i
->Pin
.Dfp128Binary
.dst_hi
);
3053 mapReg(m
, &i
->Pin
.Dfp128Binary
.dst_lo
);
3054 mapReg(m
, &i
->Pin
.Dfp128Binary
.srcR_hi
);
3055 mapReg(m
, &i
->Pin
.Dfp128Binary
.srcR_lo
);
3057 case Pin_DfpShift128
:
3058 mapRegs_PPCRI(m
, i
->Pin
.DfpShift128
.shift
);
3059 mapReg(m
, &i
->Pin
.DfpShift128
.src_hi
);
3060 mapReg(m
, &i
->Pin
.DfpShift128
.src_lo
);
3061 mapReg(m
, &i
->Pin
.DfpShift128
.dst_hi
);
3062 mapReg(m
, &i
->Pin
.DfpShift128
.dst_lo
);
3065 mapReg(m
, &i
->Pin
.DfpRound
.dst
);
3066 mapReg(m
, &i
->Pin
.DfpRound
.src
);
3068 case Pin_DfpRound128
:
3069 mapReg(m
, &i
->Pin
.DfpRound128
.dst_hi
);
3070 mapReg(m
, &i
->Pin
.DfpRound128
.dst_lo
);
3071 mapReg(m
, &i
->Pin
.DfpRound128
.src_hi
);
3072 mapReg(m
, &i
->Pin
.DfpRound128
.src_lo
);
3074 case Pin_DfpQuantize
:
3075 mapRegs_PPCRI(m
, i
->Pin
.DfpQuantize
.rmc
);
3076 mapReg(m
, &i
->Pin
.DfpQuantize
.dst
);
3077 mapReg(m
, &i
->Pin
.DfpQuantize
.srcL
);
3078 mapReg(m
, &i
->Pin
.DfpQuantize
.srcR
);
3080 case Pin_DfpQuantize128
:
3081 mapRegs_PPCRI(m
, i
->Pin
.DfpQuantize128
.rmc
);
3082 mapReg(m
, &i
->Pin
.DfpQuantize128
.dst_hi
);
3083 mapReg(m
, &i
->Pin
.DfpQuantize128
.dst_lo
);
3084 mapReg(m
, &i
->Pin
.DfpQuantize128
.src_hi
);
3085 mapReg(m
, &i
->Pin
.DfpQuantize128
.src_lo
);
3087 case Pin_DfpD128toD64
:
3088 mapReg(m
, &i
->Pin
.DfpD128toD64
.src_hi
);
3089 mapReg(m
, &i
->Pin
.DfpD128toD64
.src_lo
);
3090 mapReg(m
, &i
->Pin
.DfpD128toD64
.dst
);
3092 case Pin_DfpI64StoD128
:
3093 mapReg(m
, &i
->Pin
.DfpI64StoD128
.src
);
3094 mapReg(m
, &i
->Pin
.DfpI64StoD128
.dst_hi
);
3095 mapReg(m
, &i
->Pin
.DfpI64StoD128
.dst_lo
);
3097 case Pin_ExtractExpD128
:
3098 mapReg(m
, &i
->Pin
.ExtractExpD128
.dst
);
3099 mapReg(m
, &i
->Pin
.ExtractExpD128
.src_hi
);
3100 mapReg(m
, &i
->Pin
.ExtractExpD128
.src_lo
);
3102 case Pin_InsertExpD128
:
3103 mapReg(m
, &i
->Pin
.InsertExpD128
.dst_hi
);
3104 mapReg(m
, &i
->Pin
.InsertExpD128
.dst_lo
);
3105 mapReg(m
, &i
->Pin
.InsertExpD128
.srcL
);
3106 mapReg(m
, &i
->Pin
.InsertExpD128
.srcR_hi
);
3107 mapReg(m
, &i
->Pin
.InsertExpD128
.srcR_lo
);
3110 mapReg(m
, &i
->Pin
.Dfp64Cmp
.dst
);
3111 mapReg(m
, &i
->Pin
.Dfp64Cmp
.srcL
);
3112 mapReg(m
, &i
->Pin
.Dfp64Cmp
.srcR
);
3115 mapReg(m
, &i
->Pin
.Dfp128Cmp
.dst
);
3116 mapReg(m
, &i
->Pin
.Dfp128Cmp
.srcL_hi
);
3117 mapReg(m
, &i
->Pin
.Dfp128Cmp
.srcL_lo
);
3118 mapReg(m
, &i
->Pin
.Dfp128Cmp
.srcR_hi
);
3119 mapReg(m
, &i
->Pin
.Dfp128Cmp
.srcR_lo
);
3122 /* We expect both amodes only to mention the GSP (r31), so this
3123 is in fact pointless, since GSP isn't allocatable, but
3125 mapRegs_PPCAMode(m
, i
->Pin
.EvCheck
.amCounter
);
3126 mapRegs_PPCAMode(m
, i
->Pin
.EvCheck
.amFailAddr
);
3129 /* hardwires r29 and r30 -- nothing to modify. */
3132 ppPPCInstr(i
, mode64
);
3133 vpanic("mapRegs_PPCInstr");
3137 /* Generate ppc spill/reload instructions under the direction of the
3138 register allocator. Note it's critical these don't write the
3141 void genSpill_PPC ( /*OUT*/HInstr
** i1
, /*OUT*/HInstr
** i2
,
3142 HReg rreg
, Int offsetB
, Bool mode64
)
3145 vassert(!hregIsVirtual(rreg
));
3147 am
= PPCAMode_IR( offsetB
, GuestStatePtr(mode64
) );
3148 switch (hregClass(rreg
)) {
3151 *i1
= PPCInstr_Store( 8, am
, rreg
, mode64
);
3155 *i1
= PPCInstr_Store( 4, am
, rreg
, mode64
);
3158 *i1
= PPCInstr_FpLdSt ( False
/*store*/, 8, rreg
, am
);
3161 // XXX: GPR30 used as spill register to kludge AltiVec
3163 *i1
= PPCInstr_AvLdSt ( False
/*store*/, 16, rreg
, am
);
3166 ppHRegClass(hregClass(rreg
));
3167 vpanic("genSpill_PPC: unimplemented regclass");
3171 void genReload_PPC ( /*OUT*/HInstr
** i1
, /*OUT*/HInstr
** i2
,
3172 HReg rreg
, Int offsetB
, Bool mode64
)
3175 vassert(!hregIsVirtual(rreg
));
3177 am
= PPCAMode_IR( offsetB
, GuestStatePtr(mode64
) );
3178 switch (hregClass(rreg
)) {
3181 *i1
= PPCInstr_Load( 8, rreg
, am
, mode64
);
3185 *i1
= PPCInstr_Load( 4, rreg
, am
, mode64
);
3188 *i1
= PPCInstr_FpLdSt ( True
/*load*/, 8, rreg
, am
);
3191 // XXX: GPR30 used as spill register to kludge AltiVec AMode_IR
3192 *i1
= PPCInstr_AvLdSt ( True
/*load*/, 16, rreg
, am
);
3195 ppHRegClass(hregClass(rreg
));
3196 vpanic("genReload_PPC: unimplemented regclass");
3200 PPCInstr
* genMove_PPC(HReg from
, HReg to
, Bool mode64
)
3202 switch (hregClass(from
)) {
3205 return PPCInstr_Alu(Palu_OR
, to
, from
, PPCRH_Reg(from
));
3207 return PPCInstr_FpUnary(Pfp_MOV
, to
, from
);
3209 ppHRegClass(hregClass(from
));
3210 vpanic("genMove_PPC: unimplemented regclass");
3215 /* --------- The ppc assembler (bleh.) --------- */
3217 inline static UInt
iregEnc ( HReg r
, Bool mode64
)
3220 vassert(hregClass(r
) == (mode64
? HRcInt64
: HRcInt32
));
3221 vassert(!hregIsVirtual(r
));
3222 n
= hregEncoding(r
);
3227 inline static UInt
fregEnc ( HReg fr
)
3230 vassert(hregClass(fr
) == HRcFlt64
);
3231 vassert(!hregIsVirtual(fr
));
3232 n
= hregEncoding(fr
);
3237 inline static UInt
vregEnc ( HReg v
)
3240 vassert(hregClass(v
) == HRcVec128
);
3241 vassert(!hregIsVirtual(v
));
3242 n
= hregEncoding(v
);
3247 /* Emit an instruction ppc-endianly */
3248 static UChar
* emit32 ( UChar
* p
, UInt w32
, VexEndness endness_host
)
3250 if (endness_host
== VexEndnessBE
) {
3251 *p
++ = toUChar((w32
>> 24) & 0x000000FF);
3252 *p
++ = toUChar((w32
>> 16) & 0x000000FF);
3253 *p
++ = toUChar((w32
>> 8) & 0x000000FF);
3254 *p
++ = toUChar((w32
) & 0x000000FF);
3256 *p
++ = toUChar((w32
) & 0x000000FF);
3257 *p
++ = toUChar((w32
>> 8) & 0x000000FF);
3258 *p
++ = toUChar((w32
>> 16) & 0x000000FF);
3259 *p
++ = toUChar((w32
>> 24) & 0x000000FF);
3264 /* Fetch an instruction ppc-endianly */
3265 static UInt
fetch32 ( UChar
* p
, VexEndness endness_host
)
3268 if (endness_host
== VexEndnessBE
) {
3269 w32
|= ((0xFF & (UInt
)p
[0]) << 24);
3270 w32
|= ((0xFF & (UInt
)p
[1]) << 16);
3271 w32
|= ((0xFF & (UInt
)p
[2]) << 8);
3272 w32
|= ((0xFF & (UInt
)p
[3]) << 0);
3274 w32
|= ((0xFF & (UInt
)p
[3]) << 24);
3275 w32
|= ((0xFF & (UInt
)p
[2]) << 16);
3276 w32
|= ((0xFF & (UInt
)p
[1]) << 8);
3277 w32
|= ((0xFF & (UInt
)p
[0]) << 0);
3282 /* The following mkForm[...] functions refer to ppc instruction forms
3286 static UChar
* mkFormD ( UChar
* p
, UInt opc1
,
3287 UInt r1
, UInt r2
, UInt imm
, VexEndness endness_host
)
3290 vassert(opc1
< 0x40);
3294 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) | (imm
));
3295 return emit32(p
, theInstr
, endness_host
);
3298 static UChar
* mkFormMD ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3299 UInt imm1
, UInt imm2
, UInt opc2
,
3300 VexEndness endness_host
)
3303 vassert(opc1
< 0x40);
3306 vassert(imm1
< 0x40);
3307 vassert(imm2
< 0x40);
3308 vassert(opc2
< 0x08);
3309 imm2
= ((imm2
& 0x1F) << 1) | (imm2
>> 5);
3310 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3311 ((imm1
& 0x1F)<<11) | (imm2
<<5) |
3312 (opc2
<<2) | ((imm1
>> 5)<<1));
3313 return emit32(p
, theInstr
, endness_host
);
3316 static UChar
* mkFormX ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3317 UInt r3
, UInt opc2
, UInt b0
, VexEndness endness_host
)
3320 vassert(opc1
< 0x40);
3324 vassert(opc2
< 0x400);
3326 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3327 (r3
<<11) | (opc2
<<1) | (b0
));
3328 return emit32(p
, theInstr
, endness_host
);
3331 static UChar
* mkFormXO ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3332 UInt r3
, UInt b10
, UInt opc2
, UInt b0
,
3333 VexEndness endness_host
)
3336 vassert(opc1
< 0x40);
3341 vassert(opc2
< 0x200);
3343 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3344 (r3
<<11) | (b10
<< 10) | (opc2
<<1) | (b0
));
3345 return emit32(p
, theInstr
, endness_host
);
3348 static UChar
* mkFormXL ( UChar
* p
, UInt opc1
, UInt f1
, UInt f2
,
3349 UInt f3
, UInt opc2
, UInt b0
, VexEndness endness_host
)
3352 vassert(opc1
< 0x40);
3356 vassert(opc2
< 0x400);
3358 theInstr
= ((opc1
<<26) | (f1
<<21) | (f2
<<16) |
3359 (f3
<<11) | (opc2
<<1) | (b0
));
3360 return emit32(p
, theInstr
, endness_host
);
3363 // Note: for split field ops, give mnemonic arg
3364 static UChar
* mkFormXFX ( UChar
* p
, UInt r1
, UInt f2
, UInt opc2
,
3365 VexEndness endness_host
)
3370 vassert(opc2
< 0x400);
3373 vassert(f2
< 0x100);
3379 vassert(f2
< 0x400);
3380 // re-arrange split field
3381 f2
= ((f2
>>5) & 0x1F) | ((f2
& 0x1F)<<5);
3383 default: vpanic("mkFormXFX(ppch)");
3385 theInstr
= ((31<<26) | (r1
<<21) | (f2
<<11) | (opc2
<<1));
3386 return emit32(p
, theInstr
, endness_host
);
3389 // Only used by mtfsf
3390 static UChar
* mkFormXFL ( UChar
* p
, UInt FM
, UInt freg
, UInt dfp_rm
,
3391 VexEndness endness_host
)
3394 vassert(FM
< 0x100);
3395 vassert(freg
< 0x20);
3396 theInstr
= ((63<<26) | (FM
<<17) | (dfp_rm
<<16) | (freg
<<11) | (711<<1));
3397 return emit32(p
, theInstr
, endness_host
);
3400 static UChar
* mkFormXS ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3401 UInt imm
, UInt opc2
, UInt b0
,
3402 VexEndness endness_host
)
3405 vassert(opc1
< 0x40);
3408 vassert(imm
< 0x40);
3409 vassert(opc2
< 0x400);
3411 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3412 ((imm
& 0x1F)<<11) | (opc2
<<2) | ((imm
>>5)<<1) | (b0
));
3413 return emit32(p
, theInstr
, endness_host
);
3419 static UChar
* mkFormI ( UChar
* p
, UInt LI
, UInt AA
, UInt LK
,
3420 VexEndness endness_host
)
3423 vassert(LI
< 0x1000000);
3426 theInstr
= ((18<<26) | (LI
<<2) | (AA
<<1) | (LK
));
3427 return emit32(p
, theInstr
, endness_host
);
3432 static UChar
* mkFormB ( UChar
* p
, UInt BO
, UInt BI
,
3433 UInt BD
, UInt AA
, UInt LK
, VexEndness endness_host
)
3438 vassert(BD
< 0x4000);
3441 theInstr
= ((16<<26) | (BO
<<21) | (BI
<<16) |
3442 (BD
<<2) | (AA
<<1) | (LK
));
3443 return emit32(p
, theInstr
, endness_host
);
3447 static UChar
* mkFormM ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3448 UInt f3
, UInt MB
, UInt ME
, UInt Rc
,
3449 VexEndness endness_host
)
3452 vassert(opc1
< 0x40);
3459 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3460 (f3
<<11) | (MB
<<6) | (ME
<<1) | (Rc
));
3461 return emit32(p
, theInstr
, endness_host
);
3464 static UChar
* mkFormA ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3465 UInt r3
, UInt r4
, UInt opc2
, UInt b0
,
3466 VexEndness endness_host
)
3469 vassert(opc1
< 0x40);
3474 vassert(opc2
< 0x20);
3476 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) | (r3
<<11) |
3477 (r4
<<6) | (opc2
<<1) | (b0
));
3478 return emit32(p
, theInstr
, endness_host
);
3481 static UChar
* mkFormZ22 ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3482 UInt constant
, UInt opc2
, UInt b0
,
3483 VexEndness endness_host
)
3486 vassert(opc1
< 0x40);
3489 vassert(constant
< 0x40); /* 6 bit constant */
3490 vassert(opc2
< 0x200); /* 9 bit field */
3492 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3493 (constant
<<10) | (opc2
<<1) | (b0
));
3494 return emit32(p
, theInstr
, endness_host
);
3497 static UChar
* mkFormZ23 ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3498 UInt r3
, UInt rmc
, UInt opc2
, UInt b0
,
3499 VexEndness endness_host
)
3502 vassert(opc1
< 0x40);
3507 vassert(opc2
< 0x100);
3509 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3510 (r3
<<11) | (rmc
<<9) | (opc2
<<1) | (b0
));
3511 return emit32(p
, theInstr
, endness_host
);
3514 static UChar
* doAMode_IR ( UChar
* p
, UInt opc1
, UInt rSD
,
3515 PPCAMode
* am
, Bool mode64
, VexEndness endness_host
)
3518 vassert(am
->tag
== Pam_IR
);
3519 vassert(am
->Pam
.IR
.index
< 0x10000);
3521 rA
= iregEnc(am
->Pam
.IR
.base
, mode64
);
3522 idx
= am
->Pam
.IR
.index
;
3524 if (opc1
== 58 || opc1
== 62) { // ld/std: mode64 only
3526 /* stay sane with DS form: lowest 2 bits must be 00. This
3527 should be guaranteed to us by iselWordExpr_AMode. */
3528 vassert(0 == (idx
& 3));
3530 p
= mkFormD(p
, opc1
, rSD
, rA
, idx
, endness_host
);
3534 static UChar
* doAMode_RR ( UChar
* p
, UInt opc1
, UInt opc2
,
3535 UInt rSD
, PPCAMode
* am
, Bool mode64
,
3536 VexEndness endness_host
)
3539 vassert(am
->tag
== Pam_RR
);
3541 rA
= iregEnc(am
->Pam
.RR
.base
, mode64
);
3542 rB
= iregEnc(am
->Pam
.RR
.index
, mode64
);
3544 p
= mkFormX(p
, opc1
, rSD
, rA
, rB
, opc2
, 0, endness_host
);
3549 /* Load imm to r_dst */
3550 static UChar
* mkLoadImm ( UChar
* p
, UInt r_dst
, ULong imm
, Bool mode64
,
3551 VexEndness endness_host
)
3553 vassert(r_dst
< 0x20);
3556 /* In 32-bit mode, make sure the top 32 bits of imm are a sign
3557 extension of the bottom 32 bits, so that the range tests
3558 below work correctly. */
3559 UInt u32
= (UInt
)imm
;
3561 Long s64
= (Long
)s32
;
3565 if (imm
>= 0xFFFFFFFFFFFF8000ULL
|| imm
< 0x8000) {
3566 // sign-extendable from 16 bits
3568 // addi r_dst,0,imm => li r_dst,imm
3569 p
= mkFormD(p
, 14, r_dst
, 0, imm
& 0xFFFF, endness_host
);
3571 if (imm
>= 0xFFFFFFFF80000000ULL
|| imm
< 0x80000000ULL
) {
3572 // sign-extendable from 32 bits
3574 // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16)
3575 p
= mkFormD(p
, 15, r_dst
, 0, (imm
>>16) & 0xFFFF, endness_host
);
3576 // ori r_dst, r_dst, (imm & 0xFFFF)
3577 p
= mkFormD(p
, 24, r_dst
, r_dst
, imm
& 0xFFFF, endness_host
);
3579 // full 64bit immediate load: 5 (five!) insns.
3584 // lis r_dst, (imm>>48) & 0xFFFF
3585 p
= mkFormD(p
, 15, r_dst
, 0, (imm
>>48) & 0xFFFF, endness_host
);
3587 // ori r_dst, r_dst, (imm>>32) & 0xFFFF
3588 if ((imm
>>32) & 0xFFFF)
3589 p
= mkFormD(p
, 24, r_dst
, r_dst
, (imm
>>32) & 0xFFFF, endness_host
);
3591 // shift r_dst low word to high word => rldicr
3592 p
= mkFormMD(p
, 30, r_dst
, r_dst
, 32, 31, 1, endness_host
);
3596 // oris r_dst, r_dst, (imm>>16) & 0xFFFF
3597 if ((imm
>>16) & 0xFFFF)
3598 p
= mkFormD(p
, 25, r_dst
, r_dst
, (imm
>>16) & 0xFFFF, endness_host
);
3600 // ori r_dst, r_dst, (imm) & 0xFFFF
3602 p
= mkFormD(p
, 24, r_dst
, r_dst
, imm
& 0xFFFF, endness_host
);
3608 /* A simplified version of mkLoadImm that always generates 2 or 5
3609 instructions (32 or 64 bits respectively) even if it could generate
3610 fewer. This is needed for generating fixed sized patchable
3612 static UChar
* mkLoadImm_EXACTLY2or5 ( UChar
* p
,
3613 UInt r_dst
, ULong imm
, Bool mode64
,
3614 VexEndness endness_host
)
3616 vassert(r_dst
< 0x20);
3619 /* In 32-bit mode, make sure the top 32 bits of imm are a sign
3620 extension of the bottom 32 bits. (Probably unnecessary.) */
3621 UInt u32
= (UInt
)imm
;
3623 Long s64
= (Long
)s32
;
3628 // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16)
3629 p
= mkFormD(p
, 15, r_dst
, 0, (imm
>>16) & 0xFFFF, endness_host
);
3630 // ori r_dst, r_dst, (imm & 0xFFFF)
3631 p
= mkFormD(p
, 24, r_dst
, r_dst
, imm
& 0xFFFF, endness_host
);
3634 // full 64bit immediate load: 5 (five!) insns.
3637 // lis r_dst, (imm>>48) & 0xFFFF
3638 p
= mkFormD(p
, 15, r_dst
, 0, (imm
>>48) & 0xFFFF, endness_host
);
3640 // ori r_dst, r_dst, (imm>>32) & 0xFFFF
3641 p
= mkFormD(p
, 24, r_dst
, r_dst
, (imm
>>32) & 0xFFFF, endness_host
);
3643 // shift r_dst low word to high word => rldicr
3644 p
= mkFormMD(p
, 30, r_dst
, r_dst
, 32, 31, 1, endness_host
);
3647 // oris r_dst, r_dst, (imm>>16) & 0xFFFF
3648 p
= mkFormD(p
, 25, r_dst
, r_dst
, (imm
>>16) & 0xFFFF, endness_host
);
3650 // ori r_dst, r_dst, (imm) & 0xFFFF
3651 p
= mkFormD(p
, 24, r_dst
, r_dst
, imm
& 0xFFFF, endness_host
);
3656 /* Checks whether the sequence of bytes at p was indeed created
3657 by mkLoadImm_EXACTLY2or5 with the given parameters. */
3658 static Bool
isLoadImm_EXACTLY2or5 ( UChar
* p_to_check
,
3659 UInt r_dst
, ULong imm
, Bool mode64
,
3660 VexEndness endness_host
)
3662 vassert(r_dst
< 0x20);
3665 /* In 32-bit mode, make sure the top 32 bits of imm are a sign
3666 extension of the bottom 32 bits. (Probably unnecessary.) */
3667 UInt u32
= (UInt
)imm
;
3669 Long s64
= (Long
)s32
;
3674 UInt expect
[2] = { 0, 0 };
3675 UChar
* p
= (UChar
*)&expect
[0];
3676 // addis r_dst,r0,(imm>>16) => lis r_dst, (imm>>16)
3677 p
= mkFormD(p
, 15, r_dst
, 0, (imm
>>16) & 0xFFFF, endness_host
);
3678 // ori r_dst, r_dst, (imm & 0xFFFF)
3679 p
= mkFormD(p
, 24, r_dst
, r_dst
, imm
& 0xFFFF, endness_host
);
3680 vassert(p
== (UChar
*)&expect
[2]);
3682 return fetch32(p_to_check
+ 0, endness_host
) == expect
[0]
3683 && fetch32(p_to_check
+ 4, endness_host
) == expect
[1];
3686 UInt expect
[5] = { 0, 0, 0, 0, 0 };
3687 UChar
* p
= (UChar
*)&expect
[0];
3688 // full 64bit immediate load: 5 (five!) insns.
3691 // lis r_dst, (imm>>48) & 0xFFFF
3692 p
= mkFormD(p
, 15, r_dst
, 0, (imm
>>48) & 0xFFFF, endness_host
);
3694 // ori r_dst, r_dst, (imm>>32) & 0xFFFF
3695 p
= mkFormD(p
, 24, r_dst
, r_dst
, (imm
>>32) & 0xFFFF, endness_host
);
3697 // shift r_dst low word to high word => rldicr
3698 p
= mkFormMD(p
, 30, r_dst
, r_dst
, 32, 31, 1, endness_host
);
3701 // oris r_dst, r_dst, (imm>>16) & 0xFFFF
3702 p
= mkFormD(p
, 25, r_dst
, r_dst
, (imm
>>16) & 0xFFFF, endness_host
);
3704 // ori r_dst, r_dst, (imm) & 0xFFFF
3705 p
= mkFormD(p
, 24, r_dst
, r_dst
, imm
& 0xFFFF, endness_host
);
3707 vassert(p
== (UChar
*)&expect
[5]);
3709 return fetch32(p_to_check
+ 0, endness_host
) == expect
[0]
3710 && fetch32(p_to_check
+ 4, endness_host
) == expect
[1]
3711 && fetch32(p_to_check
+ 8, endness_host
) == expect
[2]
3712 && fetch32(p_to_check
+ 12, endness_host
) == expect
[3]
3713 && fetch32(p_to_check
+ 16, endness_host
) == expect
[4];
3718 /* Generate a machine-word sized load or store. Simplified version of
3719 the Pin_Load and Pin_Store cases below. */
3720 static UChar
* do_load_or_store_machine_word (
3721 UChar
* p
, Bool isLoad
,
3722 UInt reg
, PPCAMode
* am
, Bool mode64
, VexEndness endness_host
)
3725 UInt opc1
, sz
= mode64
? 8 : 4;
3729 vassert(0 == (am
->Pam
.IR
.index
& 3));
3732 case 4: opc1
= 32; vassert(!mode64
); break;
3733 case 8: opc1
= 58; vassert(mode64
); break;
3734 default: vassert(0);
3736 p
= doAMode_IR(p
, opc1
, reg
, am
, mode64
, endness_host
);
3739 /* we could handle this case, but we don't expect to ever
3746 UInt opc1
, sz
= mode64
? 8 : 4;
3750 vassert(0 == (am
->Pam
.IR
.index
& 3));
3753 case 4: opc1
= 36; vassert(!mode64
); break;
3754 case 8: opc1
= 62; vassert(mode64
); break;
3755 default: vassert(0);
3757 p
= doAMode_IR(p
, opc1
, reg
, am
, mode64
, endness_host
);
3760 /* we could handle this case, but we don't expect to ever
3770 /* Generate a 32-bit sized load or store. Simplified version of
3771 do_load_or_store_machine_word above. */
3772 static UChar
* do_load_or_store_word32 (
3773 UChar
* p
, Bool isLoad
,
3774 UInt reg
, PPCAMode
* am
, Bool mode64
, VexEndness endness_host
)
3781 vassert(0 == (am
->Pam
.IR
.index
& 3));
3784 p
= doAMode_IR(p
, opc1
, reg
, am
, mode64
, endness_host
);
3787 /* we could handle this case, but we don't expect to ever
3798 vassert(0 == (am
->Pam
.IR
.index
& 3));
3801 p
= doAMode_IR(p
, opc1
, reg
, am
, mode64
, endness_host
);
3804 /* we could handle this case, but we don't expect to ever
3814 /* Move r_dst to r_src */
3815 static UChar
* mkMoveReg ( UChar
* p
, UInt r_dst
, UInt r_src
,
3816 VexEndness endness_host
)
3818 vassert(r_dst
< 0x20);
3819 vassert(r_src
< 0x20);
3821 if (r_dst
!= r_src
) {
3822 /* or r_dst, r_src, r_src */
3823 p
= mkFormX(p
, 31, r_src
, r_dst
, r_src
, 444, 0, endness_host
);
3828 static UChar
* mkFormVX ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3829 UInt r3
, UInt opc2
, VexEndness endness_host
)
3832 vassert(opc1
< 0x40);
3836 vassert(opc2
< 0x800);
3837 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) | (r3
<<11) | opc2
);
3838 return emit32(p
, theInstr
, endness_host
);
3841 static UChar
* mkFormVSXRND ( UChar
* p
, UInt opc1
, UInt R
, UInt r1
,
3842 UInt r2
, UInt RMC
, UInt opc2
, UChar EX
,
3843 VexEndness endness_host
)
3845 /* The register mapping is all done using VR register numbers for the
3846 * V128 support. This means that the operands for this instruction have
3847 * been loaded into a VR register. The 32 VR registers map to VSR registers
3848 * 32 to 63. For these instructions, the hardware adds 32 to the source
3849 * and destination register numbers. Do not need to adjust the register
3850 * numbers for these instructions.
3855 vassert(opc1
< 0x40);
3858 vassert(opc2
< 0x100);
3863 theInstr
= ((opc1
<<26) | (r1
<<21) | (R
<<16) | (r2
<<11) | (RMC
<<9) |
3865 return emit32(p
, theInstr
, endness_host
);
3868 static UChar
* mkFormVX_BX_TX ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3869 UInt r3
, UInt opc2
, VexEndness endness_host
)
3871 /* The register mapping is all done using VR register numbers for the
3872 * V128 support. This means that the operands for this instruction have
3873 * been loaded into a VR register. The 32 VR registers map to VSR registers
3874 * 32 to 63. So to make the issued instruction reference the
3875 * corresponding VR register we have to add 32 to the source and
3876 * destination operand numbers, then load the new operand number into the
3877 * correct bit fields.
3879 * r1 = 32xTX + T; r3 = 32xBX + B;
3880 * TX is bit 0, BX is bit 1, T is in bits [25:21], B is in bit [14:11]
3881 * opc2 is in bits [10:2]
3887 r1
+= 32; // adjust the VSR register number to map to the VR number
3890 vassert(opc1
< 0x40);
3894 vassert(opc2
< 0x800);
3900 theInstr
= ((opc1
<<26) | (T
<<21) | (r2
<<16) | (B
<<11) | (opc2
<<2)
3902 return emit32(p
, theInstr
, endness_host
);
3905 static UChar
* mkFormVXR0 ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3906 UInt r3
, UInt opc2
, UChar R0
,
3907 VexEndness endness_host
)
3909 /* The register mapping is all done using VR register numbers for the
3910 * V128 support. This means that the operands for this instruction have
3911 * been loaded into a VR register. The 32 VR registers map to VSR registers
3912 * 32 to 63. For these instructions, the hardware adds 32 to the source
3913 * and destination register numbers. Do not need to adjust the register
3914 * numbers for these instructions.
3919 vassert(opc1
< 0x40);
3920 vassert(r1
< 0x20); // register numbers are between 0 and 31 (5-bits)
3923 vassert(opc2
< 0x800);
3926 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) | (r3
<<11) | (opc2
<<1) | R0
);
3927 return emit32(p
, theInstr
, endness_host
);
3930 static UChar
* mkFormVXI ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3931 UInt r3
, UInt opc2
, VexEndness endness_host
)
3934 vassert(opc1
< 0x40);
3938 vassert(opc2
< 0x27);
3939 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) | (r3
<<11) | opc2
<<1);
3940 return emit32(p
, theInstr
, endness_host
);
3943 static UChar
* mkFormVXR ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3944 UInt r3
, UInt Rc
, UInt opc2
,
3945 VexEndness endness_host
)
3948 vassert(opc1
< 0x40);
3953 vassert(opc2
< 0x400);
3954 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3955 (r3
<<11) | (Rc
<<10) | opc2
);
3956 return emit32(p
, theInstr
, endness_host
);
3959 static UChar
* mkFormVA ( UChar
* p
, UInt opc1
, UInt r1
, UInt r2
,
3960 UInt r3
, UInt r4
, UInt opc2
, VexEndness endness_host
)
3963 vassert(opc1
< 0x40);
3968 vassert(opc2
< 0x40);
3969 theInstr
= ((opc1
<<26) | (r1
<<21) | (r2
<<16) |
3970 (r3
<<11) | (r4
<<6) | opc2
);
3971 return emit32(p
, theInstr
, endness_host
);
3976 /* Emit an instruction into buf and return the number of bytes used.
3977 Note that buf is not the insn's final place, and therefore it is
3978 imperative to emit position-independent code. If the emitted
3979 instruction was a profiler inc, set *is_profInc to True, else leave
3982 Int
emit_PPCInstr ( /*MB_MOD*/Bool
* is_profInc
,
3983 UChar
* buf
, Int nbuf
, const PPCInstr
* i
,
3984 Bool mode64
, VexEndness endness_host
,
3985 const void* disp_cp_chain_me_to_slowEP
,
3986 const void* disp_cp_chain_me_to_fastEP
,
3987 const void* disp_cp_xindir
,
3988 const void* disp_cp_xassisted
)
3991 vassert(nbuf
>= 32);
3994 vex_printf("asm ");ppPPCInstr(i
, mode64
); vex_printf("\n");
4000 p
= mkLoadImm(p
, iregEnc(i
->Pin
.LI
.dst
, mode64
),
4001 i
->Pin
.LI
.imm64
, mode64
, endness_host
);
4005 PPCRH
* srcR
= i
->Pin
.Alu
.srcR
;
4006 Bool immR
= toBool(srcR
->tag
== Prh_Imm
);
4007 UInt r_dst
= iregEnc(i
->Pin
.Alu
.dst
, mode64
);
4008 UInt r_srcL
= iregEnc(i
->Pin
.Alu
.srcL
, mode64
);
4009 UInt r_srcR
= immR
? (-1)/*bogus*/ :
4010 iregEnc(srcR
->Prh
.Reg
.reg
, mode64
);
4012 switch (i
->Pin
.Alu
.op
) {
4015 /* addi (PPC32 p350) */
4016 vassert(srcR
->Prh
.Imm
.syned
);
4017 vassert(srcR
->Prh
.Imm
.imm16
!= 0x8000);
4018 p
= mkFormD(p
, 14, r_dst
, r_srcL
, srcR
->Prh
.Imm
.imm16
, endness_host
);
4020 /* add (PPC32 p347) */
4021 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 266, 0, endness_host
);
4027 /* addi (PPC32 p350), but with negated imm */
4028 vassert(srcR
->Prh
.Imm
.syned
);
4029 vassert(srcR
->Prh
.Imm
.imm16
!= 0x8000);
4030 p
= mkFormD(p
, 14, r_dst
, r_srcL
, (- srcR
->Prh
.Imm
.imm16
),
4033 /* subf (PPC32 p537), with args the "wrong" way round */
4034 p
= mkFormXO(p
, 31, r_dst
, r_srcR
, r_srcL
, 0, 40, 0, endness_host
);
4040 /* andi. (PPC32 p358) */
4041 vassert(!srcR
->Prh
.Imm
.syned
);
4042 p
= mkFormD(p
, 28, r_srcL
, r_dst
, srcR
->Prh
.Imm
.imm16
, endness_host
);
4044 /* and (PPC32 p356) */
4045 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 28, 0, endness_host
);
4051 /* ori (PPC32 p497) */
4052 vassert(!srcR
->Prh
.Imm
.syned
);
4053 p
= mkFormD(p
, 24, r_srcL
, r_dst
, srcR
->Prh
.Imm
.imm16
, endness_host
);
4055 /* or (PPC32 p495) */
4056 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 444, 0, endness_host
);
4062 /* xori (PPC32 p550) */
4063 vassert(!srcR
->Prh
.Imm
.syned
);
4064 p
= mkFormD(p
, 26, r_srcL
, r_dst
, srcR
->Prh
.Imm
.imm16
, endness_host
);
4066 /* xor (PPC32 p549) */
4067 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 316, 0, endness_host
);
4078 PPCRH
* srcR
= i
->Pin
.Shft
.srcR
;
4079 Bool sz32
= i
->Pin
.Shft
.sz32
;
4080 Bool immR
= toBool(srcR
->tag
== Prh_Imm
);
4081 UInt r_dst
= iregEnc(i
->Pin
.Shft
.dst
, mode64
);
4082 UInt r_srcL
= iregEnc(i
->Pin
.Shft
.srcL
, mode64
);
4083 UInt r_srcR
= immR
? (-1)/*bogus*/ :
4084 iregEnc(srcR
->Prh
.Reg
.reg
, mode64
);
4088 switch (i
->Pin
.Shft
.op
) {
4092 /* rd = rs << n, 1 <= n <= 31
4094 rlwinm rd,rs,n,0,31-n (PPC32 p501)
4096 UInt n
= srcR
->Prh
.Imm
.imm16
;
4097 vassert(!srcR
->Prh
.Imm
.syned
);
4098 vassert(n
> 0 && n
< 32);
4099 p
= mkFormM(p
, 21, r_srcL
, r_dst
, n
, 0, 31-n
, 0, endness_host
);
4101 /* slw (PPC32 p505) */
4102 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 24, 0, endness_host
);
4106 /* rd = rs << n, 1 <= n <= 63
4108 rldicr rd,rs,n,63-n (PPC64 p559)
4110 UInt n
= srcR
->Prh
.Imm
.imm16
;
4111 vassert(!srcR
->Prh
.Imm
.syned
);
4112 vassert(n
> 0 && n
< 64);
4113 p
= mkFormMD(p
, 30, r_srcL
, r_dst
, n
, 63-n
, 1, endness_host
);
4115 /* sld (PPC64 p568) */
4116 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 27, 0, endness_host
);
4124 /* rd = rs >>u n, 1 <= n <= 31
4126 rlwinm rd,rs,32-n,n,31 (PPC32 p501)
4128 UInt n
= srcR
->Prh
.Imm
.imm16
;
4129 vassert(!srcR
->Prh
.Imm
.syned
);
4130 vassert(n
> 0 && n
< 32);
4131 p
= mkFormM(p
, 21, r_srcL
, r_dst
, 32-n
, n
, 31, 0, endness_host
);
4133 /* srw (PPC32 p508) */
4134 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 536, 0, endness_host
);
4138 /* rd = rs >>u n, 1 <= n <= 63
4140 rldicl rd,rs,64-n,n (PPC64 p558)
4142 UInt n
= srcR
->Prh
.Imm
.imm16
;
4143 vassert(!srcR
->Prh
.Imm
.syned
);
4144 vassert(n
> 0 && n
< 64);
4145 p
= mkFormMD(p
, 30, r_srcL
, r_dst
, 64-n
, n
, 0, endness_host
);
4147 /* srd (PPC64 p574) */
4148 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 539, 0, endness_host
);
4156 /* srawi (PPC32 p507) */
4157 UInt n
= srcR
->Prh
.Imm
.imm16
;
4158 vassert(!srcR
->Prh
.Imm
.syned
);
4159 /* In 64-bit mode, we allow right shifts by zero bits
4160 as that is a handy way to sign extend the lower 32
4161 bits into the upper 32 bits. */
4163 vassert(n
>= 0 && n
< 32);
4165 vassert(n
> 0 && n
< 32);
4166 p
= mkFormX(p
, 31, r_srcL
, r_dst
, n
, 824, 0, endness_host
);
4168 /* sraw (PPC32 p506) */
4169 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 792, 0, endness_host
);
4173 /* sradi (PPC64 p571) */
4174 UInt n
= srcR
->Prh
.Imm
.imm16
;
4175 vassert(!srcR
->Prh
.Imm
.syned
);
4176 vassert(n
> 0 && n
< 64);
4177 p
= mkFormXS(p
, 31, r_srcL
, r_dst
, n
, 413, 0, endness_host
);
4179 /* srad (PPC32 p570) */
4180 p
= mkFormX(p
, 31, r_srcL
, r_dst
, r_srcR
, 794, 0, endness_host
);
4192 Bool isAdd
= i
->Pin
.AddSubC
.isAdd
;
4193 Bool setC
= i
->Pin
.AddSubC
.setC
;
4194 UInt r_srcL
= iregEnc(i
->Pin
.AddSubC
.srcL
, mode64
);
4195 UInt r_srcR
= iregEnc(i
->Pin
.AddSubC
.srcR
, mode64
);
4196 UInt r_dst
= iregEnc(i
->Pin
.AddSubC
.dst
, mode64
);
4199 if (setC
) /* addc (PPC32 p348) */
4200 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 10, 0, endness_host
);
4201 else /* adde (PPC32 p349) */
4202 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 138, 0, endness_host
);
4204 /* subfX, with args the "wrong" way round */
4205 if (setC
) /* subfc (PPC32 p538) */
4206 p
= mkFormXO(p
, 31, r_dst
, r_srcR
, r_srcL
, 0, 8, 0, endness_host
);
4207 else /* subfe (PPC32 p539) */
4208 p
= mkFormXO(p
, 31, r_dst
, r_srcR
, r_srcL
, 0, 136, 0, endness_host
);
4214 Bool syned
= i
->Pin
.Cmp
.syned
;
4215 Bool sz32
= i
->Pin
.Cmp
.sz32
;
4216 UInt fld1
= i
->Pin
.Cmp
.crfD
<< 2;
4217 UInt r_srcL
= iregEnc(i
->Pin
.Cmp
.srcL
, mode64
);
4218 UInt r_srcR
, imm_srcR
;
4219 PPCRH
* srcR
= i
->Pin
.Cmp
.srcR
;
4221 if (!mode64
) // cmp double word invalid for mode32
4223 else if (!sz32
) // mode64 && cmp64: set L=1
4226 switch (srcR
->tag
) {
4228 vassert(syned
== srcR
->Prh
.Imm
.syned
);
4229 imm_srcR
= srcR
->Prh
.Imm
.imm16
;
4230 if (syned
) { // cmpw/di (signed) (PPC32 p368)
4231 vassert(imm_srcR
!= 0x8000);
4232 p
= mkFormD(p
, 11, fld1
, r_srcL
, imm_srcR
, endness_host
);
4233 } else { // cmplw/di (unsigned) (PPC32 p370)
4234 p
= mkFormD(p
, 10, fld1
, r_srcL
, imm_srcR
, endness_host
);
4238 r_srcR
= iregEnc(srcR
->Prh
.Reg
.reg
, mode64
);
4239 if (syned
) // cmpwi (signed) (PPC32 p367)
4240 p
= mkFormX(p
, 31, fld1
, r_srcL
, r_srcR
, 0, 0, endness_host
);
4241 else // cmplwi (unsigned) (PPC32 p379)
4242 p
= mkFormX(p
, 31, fld1
, r_srcL
, r_srcR
, 32, 0, endness_host
);
4251 UInt r_dst
= iregEnc(i
->Pin
.Unary
.dst
, mode64
);
4252 UInt r_src
= iregEnc(i
->Pin
.Unary
.src
, mode64
);
4254 switch (i
->Pin
.Unary
.op
) {
4255 case Pun_NOT
: // nor r_dst,r_src,r_src
4256 p
= mkFormX(p
, 31, r_src
, r_dst
, r_src
, 124, 0, endness_host
);
4258 case Pun_NEG
: // neg r_dst,r_src
4259 p
= mkFormXO(p
, 31, r_dst
, r_src
, 0, 0, 104, 0, endness_host
);
4261 case Pun_CLZ32
: // cntlzw r_dst, r_src
4262 p
= mkFormX(p
, 31, r_src
, r_dst
, 0, 26, 0, endness_host
);
4264 case Pun_CLZ64
: // cntlzd r_dst, r_src
4266 p
= mkFormX(p
, 31, r_src
, r_dst
, 0, 58, 0, endness_host
);
4268 case Pun_EXTSW
: // extsw r_dst, r_src
4270 p
= mkFormX(p
, 31, r_src
, r_dst
, 0, 986, 0, endness_host
);
4272 case Pun_POP32
: // popcntw r_dst, r_src
4273 p
= mkFormX(p
, 31, r_src
, r_dst
, 0, 378, 0, endness_host
);
4275 case Pun_POP64
: // popcntd r_dst, r_src
4277 p
= mkFormX(p
, 31, r_src
, r_dst
, 0, 506, 0, endness_host
);
4286 Bool syned
= i
->Pin
.MulL
.syned
;
4287 Bool sz32
= i
->Pin
.MulL
.sz32
;
4288 UInt r_dst
= iregEnc(i
->Pin
.MulL
.dst
, mode64
);
4289 UInt r_srcL
= iregEnc(i
->Pin
.MulL
.srcL
, mode64
);
4290 UInt r_srcR
= iregEnc(i
->Pin
.MulL
.srcR
, mode64
);
4295 if (i
->Pin
.MulL
.hi
) {
4296 // mul hi words, must consider sign
4298 if (syned
) // mulhw r_dst,r_srcL,r_srcR
4299 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 75, 0,
4301 else // mulhwu r_dst,r_srcL,r_srcR
4302 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 11, 0,
4305 if (syned
) // mulhd r_dst,r_srcL,r_srcR
4306 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 73, 0,
4308 else // mulhdu r_dst,r_srcL,r_srcR
4309 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 9, 0, endness_host
);
4312 // mul low word, sign is irrelevant
4313 vassert(!i
->Pin
.MulL
.syned
);
4314 if (sz32
) // mullw r_dst,r_srcL,r_srcR
4315 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 235, 0, endness_host
);
4316 else // mulld r_dst,r_srcL,r_srcR
4317 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 233, 0, endness_host
);
4323 Bool syned
= i
->Pin
.Div
.syned
;
4324 Bool sz32
= i
->Pin
.Div
.sz32
;
4325 UInt r_dst
= iregEnc(i
->Pin
.Div
.dst
, mode64
);
4326 UInt r_srcL
= iregEnc(i
->Pin
.Div
.srcL
, mode64
);
4327 UInt r_srcR
= iregEnc(i
->Pin
.Div
.srcR
, mode64
);
4332 if (i
->Pin
.Div
.extended
) {
4335 // divwe r_dst,r_srcL,r_srcR
4336 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 427, 0,
4339 // divweu r_dst,r_srcL,r_srcR
4340 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 395, 0,
4344 // divde r_dst,r_srcL,r_srcR
4345 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 425, 0,
4348 // divdeu r_dst,r_srcL,r_srcR
4349 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 393, 0,
4353 if (syned
) // divw r_dst,r_srcL,r_srcR
4354 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 491, 0, endness_host
);
4355 else // divwu r_dst,r_srcL,r_srcR
4356 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 459, 0, endness_host
);
4358 if (syned
) // divd r_dst,r_srcL,r_srcR
4359 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 489, 0, endness_host
);
4360 else // divdu r_dst,r_srcL,r_srcR
4361 p
= mkFormXO(p
, 31, r_dst
, r_srcL
, r_srcR
, 0, 457, 0, endness_host
);
4367 if (i
->Pin
.Call
.cond
.test
!= Pct_ALWAYS
4368 && i
->Pin
.Call
.rloc
.pri
!= RLPri_None
) {
4369 /* The call might not happen (it isn't unconditional) and it
4370 returns a result. In this case we will need to generate a
4371 control flow diamond to put 0x555..555 in the return
4372 register(s) in the case where the call doesn't happen. If
4373 this ever becomes necessary, maybe copy code from the ARM
4374 equivalent. Until that day, just give up. */
4377 PPCCondCode cond
= i
->Pin
.Call
.cond
;
4379 /* As per detailed comment for Pin_Call in
4380 getRegUsage_PPCInstr above, %r10 is used as an address temp */
4382 /* jump over the following insns if condition does not hold */
4384 if (cond
.test
!= Pct_ALWAYS
) {
4385 /* jmp fwds if !condition */
4386 /* don't know how many bytes to jump over yet...
4387 make space for a jump instruction and fill in later. */
4388 ptmp
= p
; /* fill in this bit later */
4392 /* load target to r_dst */ // p += 4|8|20
4393 p
= mkLoadImm(p
, r_dst
, i
->Pin
.Call
.target
, mode64
, endness_host
);
4395 /* mtspr 9,r_dst => move r_dst to count register */
4396 p
= mkFormXFX(p
, r_dst
, 9, 467, endness_host
); // p += 4
4398 /* bctrl => branch to count register (and save to lr) */
4399 p
= mkFormXL(p
, 19, Pct_ALWAYS
, 0, 0, 528, 1, endness_host
); // p += 4
4401 /* Fix up the conditional jump, if there was one. */
4402 if (cond
.test
!= Pct_ALWAYS
) {
4403 Int delta
= p
- ptmp
;
4404 vassert(delta
>= 16 && delta
<= 32);
4405 /* bc !ct,cf,delta */
4406 mkFormB(ptmp
, invertCondTest(cond
.test
),
4407 cond
.flag
, (delta
>>2), 0, 0, endness_host
);
4413 /* NB: what goes on here has to be very closely coordinated
4414 with the chainXDirect_PPC and unchainXDirect_PPC below. */
4415 /* We're generating chain-me requests here, so we need to be
4416 sure this is actually allowed -- no-redir translations
4417 can't use chain-me's. Hence: */
4418 vassert(disp_cp_chain_me_to_slowEP
!= NULL
);
4419 vassert(disp_cp_chain_me_to_fastEP
!= NULL
);
4421 /* First off, if this is conditional, create a conditional jump
4422 over the rest of it. Or at least, leave a space for it that
4423 we will shortly fill in. */
4425 if (i
->Pin
.XDirect
.cond
.test
!= Pct_ALWAYS
) {
4426 vassert(i
->Pin
.XDirect
.cond
.flag
!= Pcf_NONE
);
4430 vassert(i
->Pin
.XDirect
.cond
.flag
== Pcf_NONE
);
4433 /* Update the guest CIA. */
4434 /* imm32/64 r30, dstGA */
4435 if (!mode64
) vassert(0 == (((ULong
)i
->Pin
.XDirect
.dstGA
) >> 32));
4436 p
= mkLoadImm(p
, /*r*/30, (ULong
)i
->Pin
.XDirect
.dstGA
, mode64
,
4438 /* stw/std r30, amCIA */
4439 p
= do_load_or_store_machine_word(
4440 p
, False
/*!isLoad*/,
4441 /*r*/30, i
->Pin
.XDirect
.amCIA
, mode64
, endness_host
4444 /* --- FIRST PATCHABLE BYTE follows --- */
4445 /* VG_(disp_cp_chain_me_to_{slowEP,fastEP}) (where we're calling
4446 to) backs up the return address, so as to find the address of
4447 the first patchable byte. So: don't change the number of
4448 instructions (32-bit: 4, 64-bit: 7) below. */
4449 /* imm32/64-fixed r30, VG_(disp_cp_chain_me_to_{slowEP,fastEP} */
4450 const void* disp_cp_chain_me
4451 = i
->Pin
.XDirect
.toFastEP
? disp_cp_chain_me_to_fastEP
4452 : disp_cp_chain_me_to_slowEP
;
4453 p
= mkLoadImm_EXACTLY2or5(
4454 p
, /*r*/30, (Addr
)disp_cp_chain_me
, mode64
, endness_host
);
4456 p
= mkFormXFX(p
, /*r*/30, 9, 467, endness_host
);
4458 p
= mkFormXL(p
, 19, Pct_ALWAYS
, 0, 0, 528, 1, endness_host
);
4459 /* --- END of PATCHABLE BYTES --- */
4461 /* Fix up the conditional jump, if there was one. */
4462 if (i
->Pin
.XDirect
.cond
.test
!= Pct_ALWAYS
) {
4463 Int delta
= p
- ptmp
;
4464 vassert(delta
>= 16 && delta
<= 64 && 0 == (delta
& 3));
4465 /* bc !ct,cf,delta */
4466 mkFormB(ptmp
, invertCondTest(i
->Pin
.XDirect
.cond
.test
),
4467 i
->Pin
.XDirect
.cond
.flag
, (delta
>>2), 0, 0, endness_host
);
4473 /* We're generating transfers that could lead indirectly to a
4474 chain-me, so we need to be sure this is actually allowed --
4475 no-redir translations are not allowed to reach normal
4476 translations without going through the scheduler. That means
4477 no XDirects or XIndirs out from no-redir translations.
4479 vassert(disp_cp_xindir
!= NULL
);
4481 /* First off, if this is conditional, create a conditional jump
4482 over the rest of it. Or at least, leave a space for it that
4483 we will shortly fill in. */
4485 if (i
->Pin
.XIndir
.cond
.test
!= Pct_ALWAYS
) {
4486 vassert(i
->Pin
.XIndir
.cond
.flag
!= Pcf_NONE
);
4490 vassert(i
->Pin
.XIndir
.cond
.flag
== Pcf_NONE
);
4493 /* Update the guest CIA. */
4494 /* stw/std r-dstGA, amCIA */
4495 p
= do_load_or_store_machine_word(
4496 p
, False
/*!isLoad*/,
4497 iregEnc(i
->Pin
.XIndir
.dstGA
, mode64
),
4498 i
->Pin
.XIndir
.amCIA
, mode64
, endness_host
4501 /* imm32/64 r30, VG_(disp_cp_xindir) */
4502 p
= mkLoadImm(p
, /*r*/30, (ULong
)(Addr
)disp_cp_xindir
, mode64
,
4505 p
= mkFormXFX(p
, /*r*/30, 9, 467, endness_host
);
4507 p
= mkFormXL(p
, 19, Pct_ALWAYS
, 0, 0, 528, 0, endness_host
);
4509 /* Fix up the conditional jump, if there was one. */
4510 if (i
->Pin
.XIndir
.cond
.test
!= Pct_ALWAYS
) {
4511 Int delta
= p
- ptmp
;
4512 vassert(delta
>= 16 && delta
<= 32 && 0 == (delta
& 3));
4513 /* bc !ct,cf,delta */
4514 mkFormB(ptmp
, invertCondTest(i
->Pin
.XIndir
.cond
.test
),
4515 i
->Pin
.XIndir
.cond
.flag
, (delta
>>2), 0, 0, endness_host
);
4520 case Pin_XAssisted
: {
4521 /* First off, if this is conditional, create a conditional jump
4522 over the rest of it. Or at least, leave a space for it that
4523 we will shortly fill in. */
4525 if (i
->Pin
.XAssisted
.cond
.test
!= Pct_ALWAYS
) {
4526 vassert(i
->Pin
.XAssisted
.cond
.flag
!= Pcf_NONE
);
4530 vassert(i
->Pin
.XAssisted
.cond
.flag
== Pcf_NONE
);
4533 /* Update the guest CIA. */
4534 /* stw/std r-dstGA, amCIA */
4535 p
= do_load_or_store_machine_word(
4536 p
, False
/*!isLoad*/,
4537 iregEnc(i
->Pin
.XIndir
.dstGA
, mode64
),
4538 i
->Pin
.XIndir
.amCIA
, mode64
, endness_host
4541 /* imm32/64 r31, $magic_number */
4543 switch (i
->Pin
.XAssisted
.jk
) {
4544 case Ijk_ClientReq
: trcval
= VEX_TRC_JMP_CLIENTREQ
; break;
4545 case Ijk_Sys_syscall
: trcval
= VEX_TRC_JMP_SYS_SYSCALL
; break;
4546 //case Ijk_Sys_int128: trcval = VEX_TRC_JMP_SYS_INT128; break;
4547 //case Ijk_Yield: trcval = VEX_TRC_JMP_YIELD; break;
4548 case Ijk_EmWarn
: trcval
= VEX_TRC_JMP_EMWARN
; break;
4549 case Ijk_EmFail
: trcval
= VEX_TRC_JMP_EMFAIL
; break;
4550 //case Ijk_MapFail: trcval = VEX_TRC_JMP_MAPFAIL; break;
4551 case Ijk_NoDecode
: trcval
= VEX_TRC_JMP_NODECODE
; break;
4552 case Ijk_InvalICache
: trcval
= VEX_TRC_JMP_INVALICACHE
; break;
4553 case Ijk_NoRedir
: trcval
= VEX_TRC_JMP_NOREDIR
; break;
4554 case Ijk_SigTRAP
: trcval
= VEX_TRC_JMP_SIGTRAP
; break;
4555 //case Ijk_SigSEGV: trcval = VEX_TRC_JMP_SIGSEGV; break;
4556 case Ijk_SigBUS
: trcval
= VEX_TRC_JMP_SIGBUS
; break;
4557 case Ijk_Boring
: trcval
= VEX_TRC_JMP_BORING
; break;
4558 /* We don't expect to see the following being assisted. */
4563 ppIRJumpKind(i
->Pin
.XAssisted
.jk
);
4564 vpanic("emit_ARMInstr.Pin_XAssisted: unexpected jump kind");
4566 vassert(trcval
!= 0);
4567 p
= mkLoadImm(p
, /*r*/31, trcval
, mode64
, endness_host
);
4569 /* imm32/64 r30, VG_(disp_cp_xassisted) */
4570 p
= mkLoadImm(p
, /*r*/30,
4571 (ULong
)(Addr
)disp_cp_xassisted
, mode64
,
4574 p
= mkFormXFX(p
, /*r*/30, 9, 467, endness_host
);
4576 p
= mkFormXL(p
, 19, Pct_ALWAYS
, 0, 0, 528, 0, endness_host
);
4578 /* Fix up the conditional jump, if there was one. */
4579 if (i
->Pin
.XAssisted
.cond
.test
!= Pct_ALWAYS
) {
4580 Int delta
= p
- ptmp
;
4581 vassert(delta
>= 16 && delta
<= 32 && 0 == (delta
& 3));
4582 /* bc !ct,cf,delta */
4583 mkFormB(ptmp
, invertCondTest(i
->Pin
.XAssisted
.cond
.test
),
4584 i
->Pin
.XAssisted
.cond
.flag
, (delta
>>2), 0, 0, endness_host
);
4593 vassert(i
->Pin
.CMov
.cond
.test
!= Pct_ALWAYS
);
4595 r_dst
= iregEnc(i
->Pin
.CMov
.dst
, mode64
);
4596 cond
= i
->Pin
.CMov
.cond
;
4598 /* branch (if cond fails) over move instrs */
4600 if (cond
.test
!= Pct_ALWAYS
) {
4601 /* don't know how many bytes to jump over yet...
4602 make space for a jump instruction and fill in later. */
4603 ptmp
= p
; /* fill in this bit later */
4607 // cond true: move src => dst
4608 switch (i
->Pin
.CMov
.src
->tag
) {
4610 imm_src
= i
->Pin
.CMov
.src
->Pri
.Imm
;
4611 p
= mkLoadImm(p
, r_dst
, imm_src
, mode64
, endness_host
); // p += 4|8|20
4614 r_src
= iregEnc(i
->Pin
.CMov
.src
->Pri
.Reg
, mode64
);
4615 p
= mkMoveReg(p
, r_dst
, r_src
, endness_host
); // p += 4
4620 /* Fix up the conditional jump, if there was one. */
4621 if (cond
.test
!= Pct_ALWAYS
) {
4622 Int delta
= p
- ptmp
;
4623 vassert(delta
>= 8 && delta
<= 24);
4624 /* bc !ct,cf,delta */
4625 mkFormB(ptmp
, invertCondTest(cond
.test
),
4626 cond
.flag
, (delta
>>2), 0, 0, endness_host
);
4632 PPCAMode
* am_addr
= i
->Pin
.Load
.src
;
4633 UInt r_dst
= iregEnc(i
->Pin
.Load
.dst
, mode64
);
4634 UInt opc1
, opc2
, sz
= i
->Pin
.Load
.sz
;
4635 switch (am_addr
->tag
) {
4637 if (mode64
&& (sz
== 4 || sz
== 8)) {
4638 /* should be guaranteed to us by iselWordExpr_AMode */
4639 vassert(0 == (am_addr
->Pam
.IR
.index
& 3));
4642 case 1: opc1
= 34; break;
4643 case 2: opc1
= 40; break;
4644 case 4: opc1
= 32; break;
4645 case 8: opc1
= 58; vassert(mode64
); break;
4648 p
= doAMode_IR(p
, opc1
, r_dst
, am_addr
, mode64
, endness_host
);
4652 case 1: opc2
= 87; break;
4653 case 2: opc2
= 279; break;
4654 case 4: opc2
= 23; break;
4655 case 8: opc2
= 21; vassert(mode64
); break;
4658 p
= doAMode_RR(p
, 31, opc2
, r_dst
, am_addr
, mode64
, endness_host
);
4666 if (i
->Pin
.LoadL
.sz
== 1) {
4667 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.LoadL
.dst
, mode64
),
4668 0, iregEnc(i
->Pin
.LoadL
.src
, mode64
), 52, 0, endness_host
);
4671 if (i
->Pin
.LoadL
.sz
== 2) {
4672 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.LoadL
.dst
, mode64
),
4673 0, iregEnc(i
->Pin
.LoadL
.src
, mode64
), 116, 0, endness_host
);
4676 if (i
->Pin
.LoadL
.sz
== 4) {
4677 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.LoadL
.dst
, mode64
),
4678 0, iregEnc(i
->Pin
.LoadL
.src
, mode64
), 20, 0, endness_host
);
4681 if (i
->Pin
.LoadL
.sz
== 8 && mode64
) {
4682 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.LoadL
.dst
, mode64
),
4683 0, iregEnc(i
->Pin
.LoadL
.src
, mode64
), 84, 0, endness_host
);
4690 /* Make the destination register be 1 or 0, depending on whether
4691 the relevant condition holds. */
4692 UInt r_dst
= iregEnc(i
->Pin
.Set
.dst
, mode64
);
4693 PPCCondCode cond
= i
->Pin
.Set
.cond
;
4694 UInt rot_imm
, r_tmp
;
4696 if (cond
.test
== Pct_ALWAYS
) {
4697 // Just load 1 to dst => li dst,1
4698 p
= mkFormD(p
, 14, r_dst
, 0, 1, endness_host
);
4700 vassert(cond
.flag
!= Pcf_NONE
);
4701 rot_imm
= 1 + cond
.flag
;
4702 r_tmp
= 0; // Not set in getAllocable, so no need to declare.
4704 // r_tmp = CR => mfcr r_tmp
4705 p
= mkFormX(p
, 31, r_tmp
, 0, 0, 19, 0, endness_host
);
4707 // r_dst = flag (rotate left and mask)
4708 // => rlwinm r_dst,r_tmp,rot_imm,31,31
4709 p
= mkFormM(p
, 21, r_tmp
, r_dst
, rot_imm
, 31, 31, 0, endness_host
);
4711 if (cond
.test
== Pct_FALSE
) {
4712 // flip bit => xori r_dst,r_dst,1
4713 p
= mkFormD(p
, 26, r_dst
, r_dst
, 1, endness_host
);
4721 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.MfCR
.dst
, mode64
), 0, 0, 19, 0,
4726 p
= mkFormX(p
, 31, 0, 0, 0, 598, 0, endness_host
); // sync, PPC32 p616
4727 // CAB: Should this be isync?
4728 // p = mkFormXL(p, 19, 0, 0, 0, 150, 0); // isync, PPC32 p467
4733 PPCAMode
* am_addr
= i
->Pin
.Store
.dst
;
4734 UInt r_src
= iregEnc(i
->Pin
.Store
.src
, mode64
);
4735 UInt opc1
, opc2
, sz
= i
->Pin
.Store
.sz
;
4736 switch (i
->Pin
.Store
.dst
->tag
) {
4738 if (mode64
&& (sz
== 4 || sz
== 8)) {
4739 /* should be guaranteed to us by iselWordExpr_AMode */
4740 vassert(0 == (am_addr
->Pam
.IR
.index
& 3));
4743 case 1: opc1
= 38; break;
4744 case 2: opc1
= 44; break;
4745 case 4: opc1
= 36; break;
4746 case 8: vassert(mode64
);
4751 p
= doAMode_IR(p
, opc1
, r_src
, am_addr
, mode64
, endness_host
);
4755 case 1: opc2
= 215; break;
4756 case 2: opc2
= 407; break;
4757 case 4: opc2
= 151; break;
4758 case 8: vassert(mode64
);
4763 p
= doAMode_RR(p
, 31, opc2
, r_src
, am_addr
, mode64
, endness_host
);
4772 if (i
->Pin
.StoreC
.sz
== 1) {
4773 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.StoreC
.src
, mode64
),
4774 0, iregEnc(i
->Pin
.StoreC
.dst
, mode64
), 694, 1, endness_host
);
4777 if (i
->Pin
.StoreC
.sz
== 2) {
4778 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.StoreC
.src
, mode64
),
4779 0, iregEnc(i
->Pin
.StoreC
.dst
, mode64
), 726, 1, endness_host
);
4783 if (i
->Pin
.StoreC
.sz
== 4) {
4784 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.StoreC
.src
, mode64
),
4785 0, iregEnc(i
->Pin
.StoreC
.dst
, mode64
), 150, 1, endness_host
);
4788 if (i
->Pin
.StoreC
.sz
== 8 && mode64
) {
4789 p
= mkFormX(p
, 31, iregEnc(i
->Pin
.StoreC
.src
, mode64
),
4790 0, iregEnc(i
->Pin
.StoreC
.dst
, mode64
), 214, 1, endness_host
);
4797 UInt fr_dst
= fregEnc(i
->Pin
.FpUnary
.dst
);
4798 UInt fr_src
= fregEnc(i
->Pin
.FpUnary
.src
);
4799 switch (i
->Pin
.FpUnary
.op
) {
4800 case Pfp_RSQRTE
: // frsqrtre, PPC32 p424
4801 p
= mkFormA( p
, 63, fr_dst
, 0, fr_src
, 0, 26, 0, endness_host
);
4803 case Pfp_RES
: // fres, PPC32 p421
4804 p
= mkFormA( p
, 59, fr_dst
, 0, fr_src
, 0, 24, 0, endness_host
);
4806 case Pfp_SQRT
: // fsqrt, PPC32 p427
4807 p
= mkFormA( p
, 63, fr_dst
, 0, fr_src
, 0, 22, 0, endness_host
);
4809 case Pfp_ABS
: // fabs, PPC32 p399
4810 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 264, 0, endness_host
);
4812 case Pfp_NEG
: // fneg, PPC32 p416
4813 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 40, 0, endness_host
);
4815 case Pfp_MOV
: // fmr, PPC32 p410
4816 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 72, 0, endness_host
);
4818 case Pfp_FRIM
: // frim, PPC ISA 2.05 p137
4819 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 488, 0, endness_host
);
4821 case Pfp_FRIP
: // frip, PPC ISA 2.05 p137
4822 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 456, 0, endness_host
);
4824 case Pfp_FRIN
: // frin, PPC ISA 2.05 p137
4825 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 392, 0, endness_host
);
4827 case Pfp_FRIZ
: // friz, PPC ISA 2.05 p137
4828 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 424, 0, endness_host
);
4836 case Pin_FpBinary
: {
4837 UInt fr_dst
= fregEnc(i
->Pin
.FpBinary
.dst
);
4838 UInt fr_srcL
= fregEnc(i
->Pin
.FpBinary
.srcL
);
4839 UInt fr_srcR
= fregEnc(i
->Pin
.FpBinary
.srcR
);
4840 switch (i
->Pin
.FpBinary
.op
) {
4841 case Pfp_ADDD
: // fadd, PPC32 p400
4842 p
= mkFormA( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 0, 21, 0, endness_host
);
4844 case Pfp_ADDS
: // fadds, PPC32 p401
4845 p
= mkFormA( p
, 59, fr_dst
, fr_srcL
, fr_srcR
, 0, 21, 0, endness_host
);
4847 case Pfp_SUBD
: // fsub, PPC32 p429
4848 p
= mkFormA( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 0, 20, 0, endness_host
);
4850 case Pfp_SUBS
: // fsubs, PPC32 p430
4851 p
= mkFormA( p
, 59, fr_dst
, fr_srcL
, fr_srcR
, 0, 20, 0, endness_host
);
4853 case Pfp_MULD
: // fmul, PPC32 p413
4854 p
= mkFormA( p
, 63, fr_dst
, fr_srcL
, 0, fr_srcR
, 25, 0, endness_host
);
4856 case Pfp_MULS
: // fmuls, PPC32 p414
4857 p
= mkFormA( p
, 59, fr_dst
, fr_srcL
, 0, fr_srcR
, 25, 0, endness_host
);
4859 case Pfp_DIVD
: // fdiv, PPC32 p406
4860 p
= mkFormA( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 0, 18, 0, endness_host
);
4862 case Pfp_DIVS
: // fdivs, PPC32 p407
4863 p
= mkFormA( p
, 59, fr_dst
, fr_srcL
, fr_srcR
, 0, 18, 0, endness_host
);
4871 case Pin_Fp128Unary
: {
4872 /* Note Fp128 instructions use the vector scalar registers. The register
4873 * mapping for the V128 type assumes the a vector instruction. The
4874 * PPC hardware has a single register file that the vector scalar
4875 * registers and the vector registers map to. The 32 vector
4876 * registers instructions map to the same registers as the vector
4877 * scalar registers 32 to 63. mkFormVXR0 does the needed
4880 UInt fr_dst
= vregEnc(i
->Pin
.Fp128Unary
.dst
);
4881 UInt fr_src
= vregEnc(i
->Pin
.Fp128Unary
.src
);
4883 switch (i
->Pin
.Fp128Unary
.op
) {
4884 case Pfp_FPSQRTQ
: // xssqrtqp, use rounding specified by RN
4885 p
= mkFormVXR0( p
, 63, fr_dst
, 27, fr_src
, 804, 0, endness_host
);
4887 case Pfp_FPSQRTQRNDODD
: // xssqrtqpo, use rounding specified by RN
4888 p
= mkFormVXR0( p
, 63, fr_dst
, 27, fr_src
, 804, 1, endness_host
);
4890 case Pfp_FPQTOD
: // xscvqpdp, use rounding specified by RN
4891 p
= mkFormVXR0( p
, 63, fr_dst
, 20, fr_src
, 836, 0, endness_host
);
4893 case Pfp_FPQTODRNDODD
: // xscvqpdpo, use rounding specified by RN
4894 p
= mkFormVXR0( p
, 63, fr_dst
, 20, fr_src
, 836, 1, endness_host
);
4896 case Pfp_FPDTOQ
: // xscvdpqp
4897 p
= mkFormVXR0( p
, 63, fr_dst
, 22, fr_src
, 836, 0, endness_host
);
4899 case Pfp_IDSTOQ
: // xscvsdqp
4900 p
= mkFormVXR0( p
, 63, fr_dst
, 10, fr_src
, 836, 0, endness_host
);
4902 case Pfp_IDUTOQ
: // xscvudqp
4903 p
= mkFormVXR0( p
, 63, fr_dst
, 2, fr_src
, 836, 0, endness_host
);
4905 case Pfp_TRUNCFPQTOISD
: // xscvqpsdz
4906 p
= mkFormVXR0( p
, 63, fr_dst
, 25, fr_src
, 836, 0, endness_host
);
4908 case Pfp_TRUNCFPQTOISW
: // xscvqpswz
4909 p
= mkFormVXR0( p
, 63, fr_dst
, 9, fr_src
, 836, 0, endness_host
);
4911 case Pfp_TRUNCFPQTOIUD
: // xscvqpudz
4912 p
= mkFormVXR0( p
, 63, fr_dst
, 17, fr_src
, 836, 0, endness_host
);
4914 case Pfp_TRUNCFPQTOIUW
: // xscvqpuwz
4915 p
= mkFormVXR0( p
, 63, fr_dst
, 1, fr_src
, 836, 0, endness_host
);
4923 case Pin_Fp128Binary
: {
4924 /* Note Fp128 instructions use the vector registers */
4925 UInt fr_dst
= vregEnc(i
->Pin
.Fp128Binary
.dst
);
4926 UInt fr_srcL
= vregEnc(i
->Pin
.Fp128Binary
.srcL
);
4927 UInt fr_srcR
= vregEnc(i
->Pin
.Fp128Binary
.srcR
);
4929 /* Note this issues a Vector scalar instruction. The register
4930 * mapping for the V128 type assumes the a vector instruction. The
4931 * PPC hardware has a single register file that the vector scalar
4932 * registers and the vector registers map to. The 32 vector
4933 * registers instructions map to the same registers as the vector
4934 * scalar registers 32 to 63. For these instructions the HW adds
4935 * 32 to the register numbers to access the VSRR register. No need
4936 * to adjust the numbers to map to the VR register that contians the
4940 switch (i
->Pin
.Fp128Binary
.op
) {
4941 case Pfp_FPADDQ
: // xsaddqp, use rounding specified by RN
4942 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 4, 0, endness_host
);
4944 case Pfp_FPADDQRNDODD
: // xsaddqpo, round to odd
4945 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 4, 1, endness_host
);
4947 case Pfp_FPSUBQ
: // xssubqp, use rounding specified by RN
4948 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 516, 0, endness_host
);
4950 case Pfp_FPSUBQRNDODD
: // xssubqpo, round to odd
4951 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 516, 1, endness_host
);
4953 case Pfp_FPMULQ
: // xsmulqp, use rounding specified by RN
4954 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 36, 0, endness_host
);
4956 case Pfp_FPMULQRNDODD
: // xsmulqpo, round to odd
4957 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 36, 1, endness_host
);
4959 case Pfp_FPDIVQ
: // xsdivqp, use rounding specified by RN
4960 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 548, 0, endness_host
);
4962 case Pfp_FPDIVQRNDODD
: // xsdivqpo, round to odd
4963 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 548, 1, endness_host
);
4965 case Pfp_FPMULADDQ
: // xsmaddqp, use rounding specified by RN
4966 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 388, 0, endness_host
);
4968 case Pfp_FPMULADDQRNDODD
: // xsmaddqpo, round to odd
4969 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 388, 1, endness_host
);
4971 case Pfp_FPMULSUBQ
: // xsmsubqp, use rounding specified by RN
4972 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 420, 0, endness_host
);
4974 case Pfp_FPMULSUBQRNDODD
: // xsmsubsqpo, round to odd
4975 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 420, 1, endness_host
);
4977 case Pfp_FPNEGMULADDQ
: // xsnmaddqp, use rounding specified by RN
4978 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 452, 0, endness_host
);
4980 case Pfp_FPNEGMULADDQRNDODD
: // xsnmaddqpo, round to odd
4981 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 452, 1, endness_host
);
4983 case Pfp_FPNEGMULSUBQ
: // xsnmsubqp, use rounding specified by RN
4984 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 484, 0, endness_host
);
4986 case Pfp_FPNEGMULSUBQRNDODD
: // xsnmsubsqpo, round to odd
4987 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 484, 1, endness_host
);
4995 case Pin_Fp128Trinary
: {
4996 /* Note Fp128 instructions use the vector registers */
4997 UInt fr_dst
= vregEnc(i
->Pin
.Fp128Binary
.dst
);
4998 UInt fr_srcL
= vregEnc(i
->Pin
.Fp128Binary
.srcL
);
4999 UInt fr_srcR
= vregEnc(i
->Pin
.Fp128Binary
.srcR
);
5001 /* Note this issues a Vector scalar instruction. The register
5002 * mapping for the V128 type assumes the a vector instruction. The
5003 * PPC hardware has a single register file that the vector scalar
5004 * registers and the vector registers map to. The 32 vector
5005 * registers instructions map to the same registers as the vector
5006 * scalar registers 32 to 63. For these instructions the HW adds
5007 * 32 to the register numbers to access the VSRR register. No need
5008 * to adjust the numbers to map to the VR register that contians the
5012 switch (i
->Pin
.Fp128Binary
.op
) {
5013 case Pfp_FPMULADDQ
: // xsmaddqp, use rounding specified by RN
5014 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 388, 0, endness_host
);
5016 case Pfp_FPMULADDQRNDODD
: // xsmaddqpo, round to odd
5017 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 388, 1, endness_host
);
5019 case Pfp_FPMULSUBQ
: // xsmsubqp, use rounding specified by RN
5020 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 420, 0, endness_host
);
5022 case Pfp_FPMULSUBQRNDODD
: // xsmsubsqpo, round to odd
5023 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 420, 1, endness_host
);
5025 case Pfp_FPNEGMULADDQ
: // xsnmaddqp, use rounding specified by RN
5026 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 452, 0, endness_host
);
5028 case Pfp_FPNEGMULADDQRNDODD
: // xsnmaddqpo, round to odd
5029 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 452, 1, endness_host
);
5031 case Pfp_FPNEGMULSUBQ
: // xsnmsubqp, use rounding specified by RN
5032 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 484, 0, endness_host
);
5034 case Pfp_FPNEGMULSUBQRNDODD
: // xsnmsubsqpo, round to odd
5035 p
= mkFormVXR0( p
, 63, fr_dst
, fr_srcL
, fr_srcR
, 484, 1, endness_host
);
5043 case Pin_FpMulAcc
: {
5044 UInt fr_dst
= fregEnc(i
->Pin
.FpMulAcc
.dst
);
5045 UInt fr_srcML
= fregEnc(i
->Pin
.FpMulAcc
.srcML
);
5046 UInt fr_srcMR
= fregEnc(i
->Pin
.FpMulAcc
.srcMR
);
5047 UInt fr_srcAcc
= fregEnc(i
->Pin
.FpMulAcc
.srcAcc
);
5048 switch (i
->Pin
.FpMulAcc
.op
) {
5049 case Pfp_MADDD
: // fmadd, PPC32 p408
5050 p
= mkFormA( p
, 63, fr_dst
, fr_srcML
, fr_srcAcc
, fr_srcMR
, 29, 0,
5053 case Pfp_MADDS
: // fmadds, PPC32 p409
5054 p
= mkFormA( p
, 59, fr_dst
, fr_srcML
, fr_srcAcc
, fr_srcMR
, 29, 0,
5057 case Pfp_MSUBD
: // fmsub, PPC32 p411
5058 p
= mkFormA( p
, 63, fr_dst
, fr_srcML
, fr_srcAcc
, fr_srcMR
, 28, 0,
5061 case Pfp_MSUBS
: // fmsubs, PPC32 p412
5062 p
= mkFormA( p
, 59, fr_dst
, fr_srcML
, fr_srcAcc
, fr_srcMR
, 28, 0,
5072 PPCAMode
* am_addr
= i
->Pin
.FpLdSt
.addr
;
5073 UInt f_reg
= fregEnc(i
->Pin
.FpLdSt
.reg
);
5074 Bool idxd
= toBool(i
->Pin
.FpLdSt
.addr
->tag
== Pam_RR
);
5075 UChar sz
= i
->Pin
.FpLdSt
.sz
;
5077 vassert(sz
== 4 || sz
== 8);
5079 if (i
->Pin
.FpLdSt
.isLoad
) { // Load from memory
5080 if (idxd
) { // lf[s|d]x, PPC32 p444|440
5081 opc
= (sz
== 4) ? 535 : 599;
5082 p
= doAMode_RR(p
, 31, opc
, f_reg
, am_addr
, mode64
, endness_host
);
5083 } else { // lf[s|d], PPC32 p441|437
5084 opc
= (sz
== 4) ? 48 : 50;
5085 p
= doAMode_IR(p
, opc
, f_reg
, am_addr
, mode64
, endness_host
);
5087 } else { // Store to memory
5088 if (idxd
) { // stf[s|d]x, PPC32 p521|516
5089 opc
= (sz
== 4) ? 663 : 727;
5090 p
= doAMode_RR(p
, 31, opc
, f_reg
, am_addr
, mode64
, endness_host
);
5091 } else { // stf[s|d], PPC32 p518|513
5092 opc
= (sz
== 4) ? 52 : 54;
5093 p
= doAMode_IR(p
, opc
, f_reg
, am_addr
, mode64
, endness_host
);
5100 UInt ir_addr
= iregEnc(i
->Pin
.FpSTFIW
.addr
, mode64
);
5101 UInt fr_data
= fregEnc(i
->Pin
.FpSTFIW
.data
);
5102 // stfiwx (store fp64[lo32] as int32), PPC32 p517
5103 // Use rA==0, so that EA == rB == ir_addr
5104 p
= mkFormX(p
, 31, fr_data
, 0/*rA=0*/, ir_addr
, 983, 0, endness_host
);
5109 UInt fr_dst
= fregEnc(i
->Pin
.FpRSP
.dst
);
5110 UInt fr_src
= fregEnc(i
->Pin
.FpRSP
.src
);
5112 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 12, 0, endness_host
);
5117 UInt fr_dst
= fregEnc(i
->Pin
.FpCftI
.dst
);
5118 UInt fr_src
= fregEnc(i
->Pin
.FpCftI
.src
);
5119 if (i
->Pin
.FpCftI
.fromI
== False
&& i
->Pin
.FpCftI
.int32
== True
) {
5120 if (i
->Pin
.FpCftI
.syned
== True
) {
5121 // fctiw (conv f64 to i32), PPC32 p404
5122 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 14, 0, endness_host
);
5125 // fctiwu (conv f64 to u32)
5126 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 142, 0, endness_host
);
5130 if (i
->Pin
.FpCftI
.fromI
== False
&& i
->Pin
.FpCftI
.int32
== False
) {
5131 if (i
->Pin
.FpCftI
.syned
== True
) {
5132 // fctid (conv f64 to i64), PPC64 p437
5133 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 814, 0, endness_host
);
5136 // fctidu (conv f64 to u64)
5137 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 942, 0, endness_host
);
5141 if (i
->Pin
.FpCftI
.fromI
== True
&& i
->Pin
.FpCftI
.int32
== False
) {
5142 if (i
->Pin
.FpCftI
.syned
== True
) {
5143 // fcfid (conv i64 to f64), PPC64 p434
5144 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 846, 0, endness_host
);
5146 } else if (i
->Pin
.FpCftI
.flt64
== True
) {
5147 // fcfidu (conv u64 to f64)
5148 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 974, 0, endness_host
);
5151 // fcfidus (conv u64 to f32)
5152 p
= mkFormX(p
, 59, fr_dst
, 0, fr_src
, 974, 0, endness_host
);
5160 UInt fr_dst
= fregEnc(i
->Pin
.FpCMov
.dst
);
5161 UInt fr_src
= fregEnc(i
->Pin
.FpCMov
.src
);
5162 PPCCondCode cc
= i
->Pin
.FpCMov
.cond
;
5164 if (fr_dst
== fr_src
) goto done
;
5166 vassert(cc
.test
!= Pct_ALWAYS
);
5168 /* jmp fwds if !condition */
5169 if (cc
.test
!= Pct_ALWAYS
) {
5170 /* bc !ct,cf,n_bytes>>2 */
5171 p
= mkFormB(p
, invertCondTest(cc
.test
), cc
.flag
, 8>>2, 0, 0,
5176 p
= mkFormX(p
, 63, fr_dst
, 0, fr_src
, 72, 0, endness_host
);
5180 case Pin_FpLdFPSCR
: {
5181 UInt fr_src
= fregEnc(i
->Pin
.FpLdFPSCR
.src
);
5182 p
= mkFormXFL(p
, 0xFF, fr_src
, i
->Pin
.FpLdFPSCR
.dfp_rm
, endness_host
); // mtfsf, PPC32 p480
5188 UInt r_dst
= iregEnc(i
->Pin
.FpCmp
.dst
, mode64
);
5189 UInt fr_srcL
= fregEnc(i
->Pin
.FpCmp
.srcL
);
5190 UInt fr_srcR
= fregEnc(i
->Pin
.FpCmp
.srcR
);
5192 // fcmpo, PPC32 p402
5193 p
= mkFormX(p
, 63, crfD
<<2, fr_srcL
, fr_srcR
, 32, 0, endness_host
);
5195 // mfcr (mv CR to r_dst), PPC32 p467
5196 p
= mkFormX(p
, 31, r_dst
, 0, 0, 19, 0, endness_host
);
5198 // rlwinm r_dst,r_dst,8,28,31, PPC32 p501
5199 // => rotate field 1 to bottomw of word, masking out upper 28
5200 p
= mkFormM(p
, 21, r_dst
, r_dst
, 8, 28, 31, 0, endness_host
);
5205 UInt reg
= iregEnc(i
->Pin
.RdWrLR
.gpr
, mode64
);
5206 /* wrLR==True ? mtlr r4 : mflr r4 */
5207 p
= mkFormXFX(p
, reg
, 8, (i
->Pin
.RdWrLR
.wrLR
==True
) ? 467 : 339,
5215 UInt opc2
, v_reg
, r_idx
, r_base
;
5216 UChar sz
= i
->Pin
.AvLdSt
.sz
;
5217 Bool idxd
= toBool(i
->Pin
.AvLdSt
.addr
->tag
== Pam_RR
);
5218 vassert(sz
== 1 || sz
== 2 || sz
== 4 || sz
== 16);
5220 v_reg
= vregEnc(i
->Pin
.AvLdSt
.reg
);
5221 r_base
= iregEnc(i
->Pin
.AvLdSt
.addr
->Pam
.RR
.base
, mode64
);
5223 // Only have AltiVec AMode_RR: kludge AMode_IR
5225 r_idx
= 30; // XXX: Using r30 as temp
5226 p
= mkLoadImm(p
, r_idx
,
5227 i
->Pin
.AvLdSt
.addr
->Pam
.IR
.index
, mode64
, endness_host
);
5229 r_idx
= iregEnc(i
->Pin
.AvLdSt
.addr
->Pam
.RR
.index
, mode64
);
5232 if (i
->Pin
.FpLdSt
.isLoad
) { // Load from memory (1,2,4,16)
5233 opc2
= (sz
==1) ? 7 : (sz
==2) ? 39 : (sz
==4) ? 71 : 103;
5234 p
= mkFormX(p
, 31, v_reg
, r_idx
, r_base
, opc2
, 0, endness_host
);
5235 } else { // Store to memory (1,2,4,16)
5236 opc2
= (sz
==1) ? 135 : (sz
==2) ? 167 : (sz
==4) ? 199 : 231;
5237 p
= mkFormX(p
, 31, v_reg
, r_idx
, r_base
, opc2
, 0, endness_host
);
5243 UInt v_dst
= vregEnc(i
->Pin
.AvUnary
.dst
);
5244 UInt v_src
= vregEnc(i
->Pin
.AvUnary
.src
);
5245 UInt opc2
= 0xFFFFFFFF, opc3
= 0xFFFFFFFF; /* invalid */
5247 switch (i
->Pin
.AvUnary
.op
) {
5248 case Pav_MOV
: opc2
= 1156; break; // vor vD,vS,vS
5249 case Pav_NOT
: opc2
= 1284; break; // vnor vD,vS,vS
5250 case Pav_UNPCKH8S
: opc2
= 526; break; // vupkhsb
5251 case Pav_UNPCKH16S
: opc2
= 590; break; // vupkhsh
5252 case Pav_UNPCKL8S
: opc2
= 654; break; // vupklsb
5253 case Pav_UNPCKL16S
: opc2
= 718; break; // vupklsh
5254 case Pav_UNPCKHPIX
: opc2
= 846; break; // vupkhpx
5255 case Pav_UNPCKLPIX
: opc2
= 974; break; // vupklpx
5257 case Pav_ZEROCNTBYTE
: opc2
= 1794; break; // vclzb
5258 case Pav_ZEROCNTHALF
: opc2
= 1858; break; // vclzh
5259 case Pav_ZEROCNTWORD
: opc2
= 1922; break; // vclzw
5260 case Pav_ZEROCNTDBL
: opc2
= 1986; break; // vclzd
5261 case Pav_TRAILINGZEROCNTBYTE
: opc2
= 1538; break; // vctzb
5262 case Pav_TRAILINGZEROCNTHALF
: opc2
= 1538; break; // vctzh
5263 case Pav_TRAILINGZEROCNTWORD
: opc2
= 1538; break; // vctzw
5264 case Pav_TRAILINGZEROCNTDBL
: opc2
= 1538; break; // vctzd
5265 case Pav_BITMTXXPOSE
: opc2
= 1292; break; // vgbbd
5266 case Pav_BCD128toI128S
: opc2
= 385; break; //bcdctsq.
5267 case Pav_MulI128by10
: opc2
= 513; break; // vmul10uq
5268 case Pav_MulI128by10Carry
: opc2
= 1; break; // vmul10cuq
5269 case Pav_F16toF64x2
: opc2
= 347; opc3
= 16; break; // xvcvhpdp
5270 case Pav_F64toF16x2
: opc2
= 347; opc3
= 17; break; // xvcvdphp
5271 case Pav_F16toF32x4
: opc2
= 475; opc3
= 24; break; // xvcvhpsp
5272 case Pav_F32toF16x4
: opc2
= 475; opc3
= 25; break; // xvcvsphp
5277 switch (i
->Pin
.AvUnary
.op
) {
5280 p
= mkFormVX( p
, 4, v_dst
, v_src
, v_src
, opc2
, endness_host
);
5282 case Pav_F16toF32x4
:
5284 /* I64 source has four 16-bit float values in the upper 64-bit
5285 * of the source vector register, lower 64-bits are undefined.
5287 /* Scatter the four F16 values in the Vector register */
5288 p
= mkFormVX( p
, 4, v_dst
, 0, v_src
, 590, endness_host
);// vupkhsh
5290 /* The layout of the vector register is now: S0F0 S1F1 S2F2 S3F3
5291 * where S is the sign extension of the 16-bit F value. We don't
5292 * care about the extended signs.
5295 /* Input, in v_dst, is now correct for the xvcvhpsp instruction */
5296 p
= mkFormVX_BX_TX( p
, 60, v_dst
, opc3
, v_dst
, opc2
,
5300 case Pav_F64toF16x2
:
5301 case Pav_F16toF64x2
:
5302 case Pav_F32toF16x4
:
5303 /* Note this issues a Vector scalar instruction. The register
5304 * mapping for the V128 type assumes the a vector instruction. The
5305 * PPC hardware has a single register file that the vector scalar
5306 * registers and the vector registers map to. The 32 vector registers
5307 * instructions map to the same registers as the vector scalar
5308 * registers 32 to 63. mkFormVX_BX_TX does the needed adjustment.
5310 p
= mkFormVX_BX_TX( p
, 60, v_dst
, opc3
, v_src
, opc2
, endness_host
);
5312 case Pav_BCD128toI128S
: // bcdctsq
5313 p
= mkFormVX( p
, 4, v_dst
, 0, v_src
, (1<<10 | 385), endness_host
);
5315 case Pav_MulI128by10
:
5316 case Pav_MulI128by10Carry
:
5317 p
= mkFormVX( p
, 4, v_dst
, v_src
, 0, opc2
, endness_host
);
5319 case Pav_TRAILINGZEROCNTBYTE
:
5320 p
= mkFormVX( p
, 4, v_dst
, 28, v_src
, opc2
, endness_host
);
5322 case Pav_TRAILINGZEROCNTHALF
:
5323 p
= mkFormVX( p
, 4, v_dst
, 29, v_src
, opc2
, endness_host
);
5325 case Pav_TRAILINGZEROCNTWORD
:
5326 p
= mkFormVX( p
, 4, v_dst
, 30, v_src
, opc2
, endness_host
);
5328 case Pav_TRAILINGZEROCNTDBL
:
5329 p
= mkFormVX( p
, 4, v_dst
, 31, v_src
, opc2
, endness_host
);
5332 p
= mkFormVX( p
, 4, v_dst
, 0, v_src
, opc2
, endness_host
);
5338 case Pin_AvBinary
: {
5339 UInt v_dst
= vregEnc(i
->Pin
.AvBinary
.dst
);
5340 UInt v_srcL
= vregEnc(i
->Pin
.AvBinary
.srcL
);
5341 UInt v_srcR
= vregEnc(i
->Pin
.AvBinary
.srcR
);
5343 if (i
->Pin
.AvBinary
.op
== Pav_SHL
) {
5344 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, 1036, endness_host
); // vslo
5345 p
= mkFormVX( p
, 4, v_dst
, v_dst
, v_srcR
, 452, endness_host
); // vsl
5348 if (i
->Pin
.AvBinary
.op
== Pav_SHR
) {
5349 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, 1100, endness_host
); // vsro
5350 p
= mkFormVX( p
, 4, v_dst
, v_dst
, v_srcR
, 708, endness_host
); // vsr
5353 switch (i
->Pin
.AvBinary
.op
) {
5355 case Pav_AND
: opc2
= 1028; break; // vand
5356 case Pav_OR
: opc2
= 1156; break; // vor
5357 case Pav_XOR
: opc2
= 1220; break; // vxor
5359 case Pav_MulI128by10E
: opc2
= 577; break; // vmul10euq
5360 case Pav_MulI128by10ECarry
: opc2
= 65; break; // vmul10ecuq
5364 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, opc2
, endness_host
);
5368 case Pin_AvBinaryInt
: {
5369 UInt ps
= i
->Pin
.AvBinaryInt
.val
->Pri
.Imm
;
5370 UInt dst
= vregEnc(i
->Pin
.AvBinaryInt
.dst
);
5371 UInt src
= vregEnc(i
->Pin
.AvBinaryInt
.src
);
5373 switch (i
->Pin
.AvBinaryInt
.op
) {
5375 case Pav_I128StoBCD128
: // bcdcfsq
5377 /* v_srcR actually contains the value of the one-bit ps field */
5379 p
= mkFormVX( p
, 4, dst
, 2, src
,
5380 (1 << 10 | (ps
<< 9) | opc2
), endness_host
);
5384 case Pav_F128toI128S
: // xsrqpi, xsrqpix
5388 UInt R
= (ps
>> 3) & 0x1;
5389 UInt RMC
= (ps
>> 1) & 0x3;
5390 /* Note this issues a Vector scalar instruction. The register
5391 * mapping for the V128 type assumes the a vector instruction. The
5392 * PPC hardware has a single register file that the vector scalar
5393 * registers and the vector registers map to. The 32 vector
5394 * registers instructions map to the same registers as the vector
5395 * scalar registers 32 to 63. For these instructions the HW adds
5396 * 32 to the register numbers to access the VSRR register. No need
5397 * to adjust the numbers to map to the VR register that contians
5400 p
= mkFormVSXRND( p
, 63, R
, dst
, src
, RMC
, opc2
, EX
,
5405 case Pav_ROUNDFPQ
: // xsrqpxp
5409 UInt RMC
= (ps
>> 1) & 0x3;
5410 UInt R
= (ps
>> 3) & 0x1;
5411 p
= mkFormVSXRND( p
, 63, R
, dst
, src
, RMC
, opc2
, EX
,
5423 case Pin_AvBin8x16
: {
5424 UInt v_dst
= vregEnc(i
->Pin
.AvBin8x16
.dst
);
5425 UInt v_srcL
= vregEnc(i
->Pin
.AvBin8x16
.srcL
);
5426 UInt v_srcR
= vregEnc(i
->Pin
.AvBin8x16
.srcR
);
5428 switch (i
->Pin
.AvBin8x16
.op
) {
5430 case Pav_ADDU
: opc2
= 0; break; // vaddubm
5431 case Pav_QADDU
: opc2
= 512; break; // vaddubs
5432 case Pav_QADDS
: opc2
= 768; break; // vaddsbs
5434 case Pav_SUBU
: opc2
= 1024; break; // vsububm
5435 case Pav_QSUBU
: opc2
= 1536; break; // vsububs
5436 case Pav_QSUBS
: opc2
= 1792; break; // vsubsbs
5438 case Pav_OMULU
: opc2
= 8; break; // vmuloub
5439 case Pav_OMULS
: opc2
= 264; break; // vmulosb
5440 case Pav_EMULU
: opc2
= 520; break; // vmuleub
5441 case Pav_EMULS
: opc2
= 776; break; // vmulesb
5443 case Pav_AVGU
: opc2
= 1026; break; // vavgub
5444 case Pav_AVGS
: opc2
= 1282; break; // vavgsb
5445 case Pav_MAXU
: opc2
= 2; break; // vmaxub
5446 case Pav_MAXS
: opc2
= 258; break; // vmaxsb
5447 case Pav_MINU
: opc2
= 514; break; // vminub
5448 case Pav_MINS
: opc2
= 770; break; // vminsb
5450 case Pav_CMPEQU
: opc2
= 6; break; // vcmpequb
5451 case Pav_CMPGTU
: opc2
= 518; break; // vcmpgtub
5452 case Pav_CMPGTS
: opc2
= 774; break; // vcmpgtsb
5454 case Pav_SHL
: opc2
= 260; break; // vslb
5455 case Pav_SHR
: opc2
= 516; break; // vsrb
5456 case Pav_SAR
: opc2
= 772; break; // vsrab
5457 case Pav_ROTL
: opc2
= 4; break; // vrlb
5459 case Pav_MRGHI
: opc2
= 12; break; // vmrghb
5460 case Pav_MRGLO
: opc2
= 268; break; // vmrglb
5462 case Pav_POLYMULADD
: opc2
= 1032; break; // vpmsumb
5467 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, opc2
, endness_host
);
5471 case Pin_AvBin16x8
: {
5472 UInt v_dst
= vregEnc(i
->Pin
.AvBin16x8
.dst
);
5473 UInt v_srcL
= vregEnc(i
->Pin
.AvBin16x8
.srcL
);
5474 UInt v_srcR
= vregEnc(i
->Pin
.AvBin16x8
.srcR
);
5476 switch (i
->Pin
.AvBin16x8
.op
) {
5478 case Pav_ADDU
: opc2
= 64; break; // vadduhm
5479 case Pav_QADDU
: opc2
= 576; break; // vadduhs
5480 case Pav_QADDS
: opc2
= 832; break; // vaddshs
5482 case Pav_SUBU
: opc2
= 1088; break; // vsubuhm
5483 case Pav_QSUBU
: opc2
= 1600; break; // vsubuhs
5484 case Pav_QSUBS
: opc2
= 1856; break; // vsubshs
5486 case Pav_OMULU
: opc2
= 72; break; // vmulouh
5487 case Pav_OMULS
: opc2
= 328; break; // vmulosh
5488 case Pav_EMULU
: opc2
= 584; break; // vmuleuh
5489 case Pav_EMULS
: opc2
= 840; break; // vmulesh
5491 case Pav_AVGU
: opc2
= 1090; break; // vavguh
5492 case Pav_AVGS
: opc2
= 1346; break; // vavgsh
5493 case Pav_MAXU
: opc2
= 66; break; // vmaxuh
5494 case Pav_MAXS
: opc2
= 322; break; // vmaxsh
5495 case Pav_MINS
: opc2
= 834; break; // vminsh
5496 case Pav_MINU
: opc2
= 578; break; // vminuh
5498 case Pav_CMPEQU
: opc2
= 70; break; // vcmpequh
5499 case Pav_CMPGTU
: opc2
= 582; break; // vcmpgtuh
5500 case Pav_CMPGTS
: opc2
= 838; break; // vcmpgtsh
5502 case Pav_SHL
: opc2
= 324; break; // vslh
5503 case Pav_SHR
: opc2
= 580; break; // vsrh
5504 case Pav_SAR
: opc2
= 836; break; // vsrah
5505 case Pav_ROTL
: opc2
= 68; break; // vrlh
5507 case Pav_PACKUU
: opc2
= 14; break; // vpkuhum
5508 case Pav_QPACKUU
: opc2
= 142; break; // vpkuhus
5509 case Pav_QPACKSU
: opc2
= 270; break; // vpkshus
5510 case Pav_QPACKSS
: opc2
= 398; break; // vpkshss
5511 case Pav_PACKPXL
: opc2
= 782; break; // vpkpx
5513 case Pav_MRGHI
: opc2
= 76; break; // vmrghh
5514 case Pav_MRGLO
: opc2
= 332; break; // vmrglh
5516 case Pav_POLYMULADD
: opc2
= 1224; break; // vpmsumh
5521 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, opc2
, endness_host
);
5525 case Pin_AvBin32x4
: {
5526 UInt v_dst
= vregEnc(i
->Pin
.AvBin32x4
.dst
);
5527 UInt v_srcL
= vregEnc(i
->Pin
.AvBin32x4
.srcL
);
5528 UInt v_srcR
= vregEnc(i
->Pin
.AvBin32x4
.srcR
);
5530 switch (i
->Pin
.AvBin32x4
.op
) {
5532 case Pav_ADDU
: opc2
= 128; break; // vadduwm
5533 case Pav_QADDU
: opc2
= 640; break; // vadduws
5534 case Pav_QADDS
: opc2
= 896; break; // vaddsws
5536 case Pav_SUBU
: opc2
= 1152; break; // vsubuwm
5537 case Pav_QSUBU
: opc2
= 1664; break; // vsubuws
5538 case Pav_QSUBS
: opc2
= 1920; break; // vsubsws
5540 case Pav_MULU
: opc2
= 137; break; // vmuluwm
5541 case Pav_OMULU
: opc2
= 136; break; // vmulouw
5542 case Pav_OMULS
: opc2
= 392; break; // vmulosw
5543 case Pav_EMULU
: opc2
= 648; break; // vmuleuw
5544 case Pav_EMULS
: opc2
= 904; break; // vmulesw
5546 case Pav_AVGU
: opc2
= 1154; break; // vavguw
5547 case Pav_AVGS
: opc2
= 1410; break; // vavgsw
5549 case Pav_MAXU
: opc2
= 130; break; // vmaxuw
5550 case Pav_MAXS
: opc2
= 386; break; // vmaxsw
5552 case Pav_MINS
: opc2
= 898; break; // vminsw
5553 case Pav_MINU
: opc2
= 642; break; // vminuw
5555 case Pav_CMPEQU
: opc2
= 134; break; // vcmpequw
5556 case Pav_CMPGTS
: opc2
= 902; break; // vcmpgtsw
5557 case Pav_CMPGTU
: opc2
= 646; break; // vcmpgtuw
5559 case Pav_SHL
: opc2
= 388; break; // vslw
5560 case Pav_SHR
: opc2
= 644; break; // vsrw
5561 case Pav_SAR
: opc2
= 900; break; // vsraw
5562 case Pav_ROTL
: opc2
= 132; break; // vrlw
5564 case Pav_PACKUU
: opc2
= 78; break; // vpkuwum
5565 case Pav_QPACKUU
: opc2
= 206; break; // vpkuwus
5566 case Pav_QPACKSU
: opc2
= 334; break; // vpkswus
5567 case Pav_QPACKSS
: opc2
= 462; break; // vpkswss
5569 case Pav_MRGHI
: opc2
= 140; break; // vmrghw
5570 case Pav_MRGLO
: opc2
= 396; break; // vmrglw
5572 case Pav_CATODD
: opc2
= 1676; break; // vmrgow
5573 case Pav_CATEVEN
: opc2
= 1932; break; // vmrgew
5575 case Pav_POLYMULADD
: opc2
= 1160; break; // vpmsumw
5580 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, opc2
, endness_host
);
5584 case Pin_AvBin64x2
: {
5585 UInt v_dst
= vregEnc(i
->Pin
.AvBin64x2
.dst
);
5586 UInt v_srcL
= vregEnc(i
->Pin
.AvBin64x2
.srcL
);
5587 UInt v_srcR
= vregEnc(i
->Pin
.AvBin64x2
.srcR
);
5589 switch (i
->Pin
.AvBin64x2
.op
) {
5590 case Pav_ADDU
: opc2
= 192; break; // vaddudm vector double add
5591 case Pav_SUBU
: opc2
= 1216; break; // vsubudm vector double add
5592 case Pav_MAXU
: opc2
= 194; break; // vmaxud vector double max
5593 case Pav_MAXS
: opc2
= 450; break; // vmaxsd vector double max
5594 case Pav_MINU
: opc2
= 706; break; // vminud vector double min
5595 case Pav_MINS
: opc2
= 962; break; // vminsd vector double min
5596 case Pav_CMPEQU
: opc2
= 199; break; // vcmpequd vector double compare
5597 case Pav_CMPGTU
: opc2
= 711; break; // vcmpgtud vector double compare
5598 case Pav_CMPGTS
: opc2
= 967; break; // vcmpgtsd vector double compare
5599 case Pav_SHL
: opc2
= 1476; break; // vsld
5600 case Pav_SHR
: opc2
= 1732; break; // vsrd
5601 case Pav_SAR
: opc2
= 964; break; // vsrad
5602 case Pav_ROTL
: opc2
= 196; break; // vrld
5603 case Pav_PACKUU
: opc2
= 1102; break; // vpkudum
5604 case Pav_QPACKUU
: opc2
= 1230; break; // vpkudus, vpksdus (emulated)
5605 case Pav_QPACKSS
: opc2
= 1486; break; // vpksdsm
5606 case Pav_MRGHI
: opc2
= 1614; break; // vmrghw
5607 case Pav_MRGLO
: opc2
= 1742; break; // vmrglw
5608 case Pav_POLYMULADD
: opc2
= 1096; break; // vpmsumd
5612 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, opc2
, endness_host
);
5615 case Pin_AvCipherV128Unary
: {
5616 UInt v_dst
= vregEnc(i
->Pin
.AvCipherV128Unary
.dst
);
5617 UInt v_src
= vregEnc(i
->Pin
.AvCipherV128Unary
.src
);
5619 switch (i
->Pin
.AvCipherV128Unary
.op
) {
5620 case Pav_CIPHERSUBV128
: opc2
= 1480; break; // vsbox
5624 p
= mkFormVX( p
, 4, v_dst
, v_src
, 0, opc2
, endness_host
);
5627 case Pin_AvCipherV128Binary
: {
5628 UInt v_dst
= vregEnc(i
->Pin
.AvCipherV128Binary
.dst
);
5629 UInt v_srcL
= vregEnc(i
->Pin
.AvCipherV128Binary
.srcL
);
5630 UInt v_srcR
= vregEnc(i
->Pin
.AvCipherV128Binary
.srcR
);
5632 switch (i
->Pin
.AvCipherV128Binary
.op
) {
5633 case Pav_CIPHERV128
: opc2
= 1288; break; // vcipher
5634 case Pav_CIPHERLV128
: opc2
= 1289; break; // vcipherlast
5635 case Pav_NCIPHERV128
: opc2
= 1352; break; // vncipher
5636 case Pav_NCIPHERLV128
: opc2
= 1353; break; // vncipherlast
5640 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, opc2
, endness_host
);
5643 case Pin_AvHashV128Binary
: {
5644 UInt v_dst
= vregEnc(i
->Pin
.AvHashV128Binary
.dst
);
5645 UInt v_src
= vregEnc(i
->Pin
.AvHashV128Binary
.src
);
5646 PPCRI
* s_field
= i
->Pin
.AvHashV128Binary
.s_field
;
5648 switch (i
->Pin
.AvHashV128Binary
.op
) {
5649 case Pav_SHA256
: opc2
= 1666; break; // vshasigmaw
5650 case Pav_SHA512
: opc2
= 1730; break; // vshasigmad
5654 p
= mkFormVX( p
, 4, v_dst
, v_src
, s_field
->Pri
.Imm
, opc2
, endness_host
);
5657 case Pin_AvBCDV128Binary
: {
5658 UInt v_dst
= vregEnc(i
->Pin
.AvBCDV128Binary
.dst
);
5659 UInt v_src1
= vregEnc(i
->Pin
.AvBCDV128Binary
.src1
);
5660 UInt v_src2
= vregEnc(i
->Pin
.AvBCDV128Binary
.src2
);
5661 UInt ps
= 0; /* Issue the instruction with ps=0. The IR code will
5662 * fix up the result if ps=1.
5665 switch (i
->Pin
.AvBCDV128Binary
.op
) {
5666 case Pav_BCDAdd
: opc2
= 1; break; // bcdadd
5667 case Pav_BCDSub
: opc2
= 65; break; // bcdsub
5671 p
= mkFormVXR( p
, 4, v_dst
, v_src1
, v_src2
,
5672 0x1, ps
| opc2
, endness_host
);
5675 case Pin_AvBin32Fx4
: {
5676 UInt v_dst
= vregEnc(i
->Pin
.AvBin32Fx4
.dst
);
5677 UInt v_srcL
= vregEnc(i
->Pin
.AvBin32Fx4
.srcL
);
5678 UInt v_srcR
= vregEnc(i
->Pin
.AvBin32Fx4
.srcR
);
5679 switch (i
->Pin
.AvBin32Fx4
.op
) {
5682 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, 10, endness_host
); // vaddfp
5685 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, 74, endness_host
); // vsubfp
5688 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, 1034, endness_host
); // vmaxfp
5691 p
= mkFormVX( p
, 4, v_dst
, v_srcL
, v_srcR
, 1098, endness_host
); // vminfp
5695 /* Make a vmulfp from a vmaddfp:
5696 load -0.0 (0x8000_0000) to each 32-bit word of vB
5697 this makes the add a noop.
5699 UInt vB
= 29; // XXX: Using v29 for temp do not change
5700 // without also changing
5701 // getRegUsage_PPCInstr
5704 // Better way to load -0.0 (0x80000000) ?
5705 // vspltisw vB,0x1F (0x1F => each word of vB)
5706 p
= mkFormVX( p
, 4, vB
, konst
, 0, 908, endness_host
);
5708 // vslw vB,vB,vB (each word of vB = (0x1F << 0x1F) = 0x80000000
5709 p
= mkFormVX( p
, 4, vB
, vB
, vB
, 388, endness_host
);
5711 // Finally, do the multiply:
5712 p
= mkFormVA( p
, 4, v_dst
, v_srcL
, vB
, v_srcR
, 46, endness_host
);
5715 case Pavfp_CMPEQF
: // vcmpeqfp
5716 p
= mkFormVXR( p
, 4, v_dst
, v_srcL
, v_srcR
, 0, 198, endness_host
);
5718 case Pavfp_CMPGTF
: // vcmpgtfp
5719 p
= mkFormVXR( p
, 4, v_dst
, v_srcL
, v_srcR
, 0, 710, endness_host
);
5721 case Pavfp_CMPGEF
: // vcmpgefp
5722 p
= mkFormVXR( p
, 4, v_dst
, v_srcL
, v_srcR
, 0, 454, endness_host
);
5731 case Pin_AvUn32Fx4
: {
5732 UInt v_dst
= vregEnc(i
->Pin
.AvUn32Fx4
.dst
);
5733 UInt v_src
= vregEnc(i
->Pin
.AvUn32Fx4
.src
);
5735 switch (i
->Pin
.AvUn32Fx4
.op
) {
5736 case Pavfp_RCPF
: opc2
= 266; break; // vrefp
5737 case Pavfp_RSQRTF
: opc2
= 330; break; // vrsqrtefp
5738 case Pavfp_CVTU2F
: opc2
= 778; break; // vcfux
5739 case Pavfp_CVTS2F
: opc2
= 842; break; // vcfsx
5740 case Pavfp_QCVTF2U
: opc2
= 906; break; // vctuxs
5741 case Pavfp_QCVTF2S
: opc2
= 970; break; // vctsxs
5742 case Pavfp_ROUNDM
: opc2
= 714; break; // vrfim
5743 case Pavfp_ROUNDP
: opc2
= 650; break; // vrfip
5744 case Pavfp_ROUNDN
: opc2
= 522; break; // vrfin
5745 case Pavfp_ROUNDZ
: opc2
= 586; break; // vrfiz
5749 p
= mkFormVX( p
, 4, v_dst
, 0, v_src
, opc2
, endness_host
);
5753 case Pin_AvPerm
: { // vperm
5754 UInt v_dst
= vregEnc(i
->Pin
.AvPerm
.dst
);
5755 UInt v_srcL
= vregEnc(i
->Pin
.AvPerm
.srcL
);
5756 UInt v_srcR
= vregEnc(i
->Pin
.AvPerm
.srcR
);
5757 UInt v_ctl
= vregEnc(i
->Pin
.AvPerm
.ctl
);
5758 p
= mkFormVA( p
, 4, v_dst
, v_srcL
, v_srcR
, v_ctl
, 43, endness_host
);
5762 case Pin_AvSel
: { // vsel
5763 UInt v_ctl
= vregEnc(i
->Pin
.AvSel
.ctl
);
5764 UInt v_dst
= vregEnc(i
->Pin
.AvSel
.dst
);
5765 UInt v_srcL
= vregEnc(i
->Pin
.AvSel
.srcL
);
5766 UInt v_srcR
= vregEnc(i
->Pin
.AvSel
.srcR
);
5767 p
= mkFormVA( p
, 4, v_dst
, v_srcL
, v_srcR
, v_ctl
, 42, endness_host
);
5771 case Pin_AvSh
: { // vsl or vsr
5772 UInt v_dst
= vregEnc(i
->Pin
.AvSh
.dst
);
5773 Bool idxd
= toBool(i
->Pin
.AvSh
.addr
->tag
== Pam_RR
);
5776 r_base
= iregEnc(i
->Pin
.AvSh
.addr
->Pam
.RR
.base
, mode64
);
5779 r_idx
= 30; // XXX: Using r30 as temp
5780 p
= mkLoadImm(p
, r_idx
,
5781 i
->Pin
.AvSh
.addr
->Pam
.IR
.index
, mode64
, endness_host
);
5783 r_idx
= iregEnc(i
->Pin
.AvSh
.addr
->Pam
.RR
.index
, mode64
);
5786 if (i
->Pin
.AvSh
.shLeft
)
5788 p
= mkFormVXI( p
, 31, v_dst
, r_idx
, r_base
, 6, endness_host
);
5791 p
= mkFormVXI( p
, 31, v_dst
, r_idx
, r_base
, 38, endness_host
);
5795 case Pin_AvShlDbl
: { // vsldoi
5796 UInt shift
= i
->Pin
.AvShlDbl
.shift
;
5797 UInt v_dst
= vregEnc(i
->Pin
.AvShlDbl
.dst
);
5798 UInt v_srcL
= vregEnc(i
->Pin
.AvShlDbl
.srcL
);
5799 UInt v_srcR
= vregEnc(i
->Pin
.AvShlDbl
.srcR
);
5800 vassert(shift
<= 0xF);
5801 p
= mkFormVA( p
, 4, v_dst
, v_srcL
, v_srcR
, shift
, 44, endness_host
);
5805 case Pin_AvSplat
: { // vsplt(is)(b,h,w)
5806 UInt v_dst
= vregEnc(i
->Pin
.AvShlDbl
.dst
);
5807 UChar sz
= i
->Pin
.AvSplat
.sz
;
5809 vassert(sz
== 8 || sz
== 16 || sz
== 32);
5811 if (i
->Pin
.AvSplat
.src
->tag
== Pvi_Imm
) {
5813 opc2
= (sz
== 8) ? 780 : (sz
== 16) ? 844 : 908; // 8,16,32
5814 /* expects 5-bit-signed-imm */
5815 simm5
= i
->Pin
.AvSplat
.src
->Pvi
.Imm5s
;
5816 vassert(simm5
>= -16 && simm5
<= 15);
5817 simm5
= simm5
& 0x1F;
5818 p
= mkFormVX( p
, 4, v_dst
, (UInt
)simm5
, 0, opc2
, endness_host
);
5822 opc2
= (sz
== 8) ? 524 : (sz
== 16) ? 588 : 652; // 8,16,32
5823 vassert(hregClass(i
->Pin
.AvSplat
.src
->Pvi
.Reg
) == HRcVec128
);
5824 v_src
= vregEnc(i
->Pin
.AvSplat
.src
->Pvi
.Reg
);
5825 lowest_lane
= (128/sz
)-1;
5826 p
= mkFormVX( p
, 4, v_dst
, lowest_lane
, v_src
, opc2
, endness_host
);
5832 UInt v_dst
= vregEnc(i
->Pin
.AvCMov
.dst
);
5833 UInt v_src
= vregEnc(i
->Pin
.AvCMov
.src
);
5834 PPCCondCode cc
= i
->Pin
.AvCMov
.cond
;
5836 if (v_dst
== v_src
) goto done
;
5838 vassert(cc
.test
!= Pct_ALWAYS
);
5840 /* jmp fwds 2 insns if !condition */
5841 if (cc
.test
!= Pct_ALWAYS
) {
5842 /* bc !ct,cf,n_bytes>>2 */
5843 p
= mkFormB(p
, invertCondTest(cc
.test
), cc
.flag
, 8>>2, 0, 0,
5847 p
= mkFormVX( p
, 4, v_dst
, v_src
, v_src
, 1156, endness_host
);
5851 case Pin_AvLdVSCR
: { // mtvscr
5852 UInt v_src
= vregEnc(i
->Pin
.AvLdVSCR
.src
);
5853 p
= mkFormVX( p
, 4, 0, 0, v_src
, 1604, endness_host
);
5857 case Pin_Dfp64Unary
: {
5858 UInt fr_dst
= fregEnc( i
->Pin
.FpUnary
.dst
);
5859 UInt fr_src
= fregEnc( i
->Pin
.FpUnary
.src
);
5861 switch (i
->Pin
.Dfp64Unary
.op
) {
5862 case Pfp_MOV
: // fmr, PPC32 p410
5863 p
= mkFormX( p
, 63, fr_dst
, 0, fr_src
, 72, 0, endness_host
);
5865 case Pfp_DCTDP
: // D32 to D64
5866 p
= mkFormX( p
, 59, fr_dst
, 0, fr_src
, 258, 0, endness_host
);
5868 case Pfp_DRSP
: // D64 to D32
5869 p
= mkFormX( p
, 59, fr_dst
, 0, fr_src
, 770, 0, endness_host
);
5871 case Pfp_DCFFIX
: // I64 to D64 conversion
5872 /* ONLY WORKS ON POWER7 */
5873 p
= mkFormX( p
, 59, fr_dst
, 0, fr_src
, 802, 0, endness_host
);
5875 case Pfp_DCTFIX
: // D64 to I64 conversion
5876 p
= mkFormX( p
, 59, fr_dst
, 0, fr_src
, 290, 0, endness_host
);
5878 case Pfp_DXEX
: // Extract exponent
5879 p
= mkFormX( p
, 59, fr_dst
, 0, fr_src
, 354, 0, endness_host
);
5887 case Pin_Dfp64Binary
: {
5888 UInt fr_dst
= fregEnc( i
->Pin
.Dfp64Binary
.dst
);
5889 UInt fr_srcL
= fregEnc( i
->Pin
.Dfp64Binary
.srcL
);
5890 UInt fr_srcR
= fregEnc( i
->Pin
.Dfp64Binary
.srcR
);
5891 switch (i
->Pin
.Dfp64Binary
.op
) {
5892 case Pfp_DFPADD
: /* dadd, dfp add, use default RM from reg ignore mode
5893 * from the Iop instruction. */
5894 p
= mkFormX( p
, 59, fr_dst
, fr_srcL
, fr_srcR
, 2, 0, endness_host
);
5896 case Pfp_DFPSUB
: /* dsub, dfp subtract, use default RM from reg ignore
5897 * mode from the Iop instruction. */
5898 p
= mkFormX( p
, 59, fr_dst
, fr_srcL
, fr_srcR
, 514, 0, endness_host
);
5900 case Pfp_DFPMUL
: /* dmul, dfp multipy, use default RM from reg ignore
5901 * mode from the Iop instruction. */
5902 p
= mkFormX( p
, 59, fr_dst
, fr_srcL
, fr_srcR
, 34, 0, endness_host
);
5904 case Pfp_DFPDIV
: /* ddiv, dfp divide, use default RM from reg ignore
5905 * mode from the Iop instruction. */
5906 p
= mkFormX( p
, 59, fr_dst
, fr_srcL
, fr_srcR
, 546, 0, endness_host
);
5908 case Pfp_DIEX
: /* diex, insert exponent */
5909 p
= mkFormX( p
, 59, fr_dst
, fr_srcL
, fr_srcR
, 866, 0, endness_host
);
5917 case Pin_DfpShift
: {
5918 UInt fr_src
= fregEnc(i
->Pin
.DfpShift
.src
);
5919 UInt fr_dst
= fregEnc(i
->Pin
.DfpShift
.dst
);
5922 shift
= i
->Pin
.DfpShift
.shift
->Pri
.Imm
;
5924 switch (i
->Pin
.DfpShift
.op
) {
5925 case Pfp_DSCLI
: /* dscli, DFP shift left by fr_srcR */
5926 p
= mkFormZ22( p
, 59, fr_dst
, fr_src
, shift
, 66, 0, endness_host
);
5928 case Pfp_DSCRI
: /* dscri, DFP shift right by fr_srcR */
5929 p
= mkFormZ22( p
, 59, fr_dst
, fr_src
, shift
, 98, 0, endness_host
);
5932 vex_printf("ERROR: emit_PPCInstr default case\n");
5938 case Pin_ExtractExpD128
: {
5939 UInt fr_dst
= fregEnc(i
->Pin
.ExtractExpD128
.dst
);
5940 UInt fr_srcHi
= fregEnc(i
->Pin
.ExtractExpD128
.src_hi
);
5941 UInt fr_srcLo
= fregEnc(i
->Pin
.ExtractExpD128
.src_lo
);
5943 switch (i
->Pin
.ExtractExpD128
.op
) {
5945 /* Setup the upper and lower registers of the source operand
5948 p
= mkFormX( p
, 63, 12, 0, fr_srcHi
, 72, 0, endness_host
);
5949 p
= mkFormX( p
, 63, 13, 0, fr_srcLo
, 72, 0, endness_host
);
5950 p
= mkFormX( p
, 63, 10, 0, 12, 354, 0, endness_host
);
5952 /* The instruction will put the 64-bit result in
5955 p
= mkFormX(p
, 63, fr_dst
, 0, 10, 72, 0, endness_host
);
5958 vex_printf("Error: emit_PPCInstr case Pin_DfpExtractExp, case inst Default\n");
5963 case Pin_Dfp128Unary
: {
5964 UInt fr_dstHi
= fregEnc(i
->Pin
.Dfp128Unary
.dst_hi
);
5965 UInt fr_dstLo
= fregEnc(i
->Pin
.Dfp128Unary
.dst_lo
);
5966 UInt fr_srcLo
= fregEnc(i
->Pin
.Dfp128Unary
.src_lo
);
5968 /* Do instruction with 128-bit source operands in registers (10,11)
5971 switch (i
->Pin
.Dfp128Unary
.op
) {
5972 case Pfp_DCTQPQ
: // D64 to D128, srcLo holds 64 bit operand
5973 p
= mkFormX( p
, 63, 12, 0, fr_srcLo
, 72, 0, endness_host
);
5975 p
= mkFormX( p
, 63, 10, 0, 12, 258, 0, endness_host
);
5977 /* The instruction will put the 128-bit result in
5978 * registers (10,11). Note, the operand in the instruction only
5979 * reference the first of the two registers in the pair.
5981 p
= mkFormX(p
, 63, fr_dstHi
, 0, 10, 72, 0, endness_host
);
5982 p
= mkFormX(p
, 63, fr_dstLo
, 0, 11, 72, 0, endness_host
);
5985 vex_printf("Error: emit_PPCInstr case Pin_Dfp128Unary, case inst Default\
5992 case Pin_Dfp128Binary
: {
5993 /* dst is used to supply the left source operand and return
5996 UInt fr_dstHi
= fregEnc( i
->Pin
.Dfp128Binary
.dst_hi
);
5997 UInt fr_dstLo
= fregEnc( i
->Pin
.Dfp128Binary
.dst_lo
);
5998 UInt fr_srcRHi
= fregEnc( i
->Pin
.Dfp128Binary
.srcR_hi
);
5999 UInt fr_srcRLo
= fregEnc( i
->Pin
.Dfp128Binary
.srcR_lo
);
6001 /* Setup the upper and lower registers of the source operand
6004 p
= mkFormX( p
, 63, 10, 0, fr_dstHi
, 72, 0, endness_host
);
6005 p
= mkFormX( p
, 63, 11, 0, fr_dstLo
, 72, 0, endness_host
);
6006 p
= mkFormX( p
, 63, 12, 0, fr_srcRHi
, 72, 0, endness_host
);
6007 p
= mkFormX( p
, 63, 13, 0, fr_srcRLo
, 72, 0, endness_host
);
6009 /* Do instruction with 128-bit source operands in registers (10,11)
6012 switch (i
->Pin
.Dfp128Binary
.op
) {
6014 p
= mkFormX( p
, 63, 10, 10, 12, 2, 0, endness_host
);
6017 p
= mkFormX( p
, 63, 10, 10, 12, 514, 0, endness_host
);
6020 p
= mkFormX( p
, 63, 10, 10, 12, 34, 0, endness_host
);
6023 p
= mkFormX( p
, 63, 10, 10, 12, 546, 0, endness_host
);
6029 /* The instruction will put the 128-bit result in
6030 * registers (10,11). Note, the operand in the instruction only
6031 * reference the first of the two registers in the pair.
6033 p
= mkFormX(p
, 63, fr_dstHi
, 0, 10, 72, 0, endness_host
);
6034 p
= mkFormX(p
, 63, fr_dstLo
, 0, 11, 72, 0, endness_host
);
6038 case Pin_DfpShift128
: {
6039 UInt fr_src_hi
= fregEnc(i
->Pin
.DfpShift128
.src_hi
);
6040 UInt fr_src_lo
= fregEnc(i
->Pin
.DfpShift128
.src_lo
);
6041 UInt fr_dst_hi
= fregEnc(i
->Pin
.DfpShift128
.dst_hi
);
6042 UInt fr_dst_lo
= fregEnc(i
->Pin
.DfpShift128
.dst_lo
);
6045 shift
= i
->Pin
.DfpShift128
.shift
->Pri
.Imm
;
6047 /* setup source operand in register 12, 13 pair */
6048 p
= mkFormX(p
, 63, 12, 0, fr_src_hi
, 72, 0, endness_host
);
6049 p
= mkFormX(p
, 63, 13, 0, fr_src_lo
, 72, 0, endness_host
);
6051 /* execute instruction putting result in register 10, 11 pair */
6052 switch (i
->Pin
.DfpShift128
.op
) {
6053 case Pfp_DSCLIQ
: /* dscliq, DFP shift left, fr_srcR is the integer
6056 p
= mkFormZ22( p
, 63, 10, 12, shift
, 66, 0, endness_host
);
6058 case Pfp_DSCRIQ
: /* dscriq, DFP shift right, fr_srcR is the integer
6061 p
= mkFormZ22( p
, 63, 10, 12, shift
, 98, 0, endness_host
);
6064 vex_printf("ERROR: emit_PPCInstr quad default case %d \n",
6065 (Int
)i
->Pin
.DfpShift128
.op
);
6069 /* The instruction put the 128-bit result in registers (10,11).
6070 * Note, the operand in the instruction only reference the first of
6071 * the two registers in the pair.
6073 p
= mkFormX(p
, 63, fr_dst_hi
, 0, 10, 72, 0, endness_host
);
6074 p
= mkFormX(p
, 63, fr_dst_lo
, 0, 11, 72, 0, endness_host
);
6078 case Pin_DfpRound
: {
6079 UInt fr_dst
= fregEnc(i
->Pin
.DfpRound
.dst
);
6080 UInt fr_src
= fregEnc(i
->Pin
.DfpRound
.src
);
6083 r_rmc
= i
->Pin
.DfpRound
.r_rmc
->Pri
.Imm
;
6084 r
= (r_rmc
& 0x8) >> 3;
6088 p
= mkFormZ23(p
, 59, fr_dst
, r
, fr_src
, rmc
, 99, 0, endness_host
);
6092 case Pin_DfpRound128
: {
6093 UInt fr_dstHi
= fregEnc(i
->Pin
.DfpRound128
.dst_hi
);
6094 UInt fr_dstLo
= fregEnc(i
->Pin
.DfpRound128
.dst_lo
);
6095 UInt fr_srcHi
= fregEnc(i
->Pin
.DfpRound128
.src_hi
);
6096 UInt fr_srcLo
= fregEnc(i
->Pin
.DfpRound128
.src_lo
);
6099 r_rmc
= i
->Pin
.DfpRound128
.r_rmc
->Pri
.Imm
;
6100 r
= (r_rmc
& 0x8) >> 3;
6103 /* Setup the upper and lower registers of the source operand
6106 p
= mkFormX(p
, 63, 12, 0, fr_srcHi
, 72, 0, endness_host
);
6107 p
= mkFormX(p
, 63, 13, 0, fr_srcLo
, 72, 0, endness_host
);
6109 /* Do drintx instruction with 128-bit source operands in
6110 * registers (12,13).
6112 p
= mkFormZ23(p
, 63, 10, r
, 12, rmc
, 99, 0, endness_host
);
6114 /* The instruction will put the 128-bit result in
6115 * registers (10,11). Note, the operand in the instruction only
6116 * reference the first of the two registers in the pair.
6118 p
= mkFormX(p
, 63, fr_dstHi
, 0, 10, 72, 0, endness_host
);
6119 p
= mkFormX(p
, 63, fr_dstLo
, 0, 11, 72, 0, endness_host
);
6123 case Pin_DfpQuantize
: {
6124 UInt fr_dst
= fregEnc(i
->Pin
.DfpQuantize
.dst
);
6125 UInt fr_srcL
= fregEnc(i
->Pin
.DfpQuantize
.srcL
);
6126 UInt fr_srcR
= fregEnc(i
->Pin
.DfpQuantize
.srcR
);
6129 rmc
= i
->Pin
.DfpQuantize
.rmc
->Pri
.Imm
;
6131 switch (i
->Pin
.DfpQuantize
.op
) {
6133 p
= mkFormZ23(p
, 59, fr_dst
, fr_srcL
, fr_srcR
, rmc
, 3, 0, endness_host
);
6136 p
= mkFormZ23(p
, 59, fr_dst
, fr_srcL
, fr_srcR
, rmc
, 35, 0, endness_host
);
6144 case Pin_DfpQuantize128
: {
6145 UInt fr_dst_hi
= fregEnc(i
->Pin
.DfpQuantize128
.dst_hi
);
6146 UInt fr_dst_lo
= fregEnc(i
->Pin
.DfpQuantize128
.dst_lo
);
6147 UInt fr_src_hi
= fregEnc(i
->Pin
.DfpQuantize128
.src_hi
);
6148 UInt fr_src_lo
= fregEnc(i
->Pin
.DfpQuantize128
.src_lo
);
6151 rmc
= i
->Pin
.DfpQuantize128
.rmc
->Pri
.Imm
;
6152 /* Setup the upper and lower registers of the source operand
6153 * register pairs. Note, left source operand passed in via the
6154 * dst register pair.
6156 p
= mkFormX(p
, 63, 10, 0, fr_dst_hi
, 72, 0, endness_host
);
6157 p
= mkFormX(p
, 63, 11, 0, fr_dst_lo
, 72, 0, endness_host
);
6158 p
= mkFormX(p
, 63, 12, 0, fr_src_hi
, 72, 0, endness_host
);
6159 p
= mkFormX(p
, 63, 13, 0, fr_src_lo
, 72, 0, endness_host
);
6161 /* Do dquaq instruction with 128-bit source operands in
6162 * registers (12,13).
6164 switch (i
->Pin
.DfpQuantize128
.op
) {
6166 p
= mkFormZ23(p
, 63, 10, 10, 12, rmc
, 3, 0, endness_host
);
6169 p
= mkFormZ23(p
, 63, 10, 10, 12, rmc
, 35, 0, endness_host
);
6172 vpanic("Pin_DfpQuantize128: default case, couldn't find inst to issue \n");
6176 /* The instruction will put the 128-bit result in
6177 * registers (10,11). Note, the operand in the instruction only
6178 * reference the first of the two registers in the pair.
6180 p
= mkFormX(p
, 63, fr_dst_hi
, 0, 10, 72, 0, endness_host
);
6181 p
= mkFormX(p
, 63, fr_dst_lo
, 0, 11, 72, 0, endness_host
);
6185 case Pin_DfpD128toD64
: {
6186 UInt fr_dst
= fregEnc( i
->Pin
.DfpD128toD64
.dst
);
6187 UInt fr_srcHi
= fregEnc( i
->Pin
.DfpD128toD64
.src_hi
);
6188 UInt fr_srcLo
= fregEnc( i
->Pin
.DfpD128toD64
.src_lo
);
6190 /* Setup the upper and lower registers of the source operand
6193 p
= mkFormX( p
, 63, 10, 0, fr_dst
, 72, 0, endness_host
);
6194 p
= mkFormX( p
, 63, 12, 0, fr_srcHi
, 72, 0, endness_host
);
6195 p
= mkFormX( p
, 63, 13, 0, fr_srcLo
, 72, 0, endness_host
);
6197 /* Do instruction with 128-bit source operands in registers (10,11) */
6198 switch (i
->Pin
.Dfp128Binary
.op
) {
6200 p
= mkFormX( p
, 63, 10, 0, 12, 770, 0, endness_host
);
6203 p
= mkFormX( p
, 63, 10, 0, 12, 290, 0, endness_host
);
6209 /* The instruction will put the 64-bit result in registers 10. */
6210 p
= mkFormX(p
, 63, fr_dst
, 0, 10, 72, 0, endness_host
);
6214 case Pin_DfpI64StoD128
: {
6215 UInt fr_dstHi
= fregEnc( i
->Pin
.DfpI64StoD128
.dst_hi
);
6216 UInt fr_dstLo
= fregEnc( i
->Pin
.DfpI64StoD128
.dst_lo
);
6217 UInt fr_src
= fregEnc( i
->Pin
.DfpI64StoD128
.src
);
6219 switch (i
->Pin
.Dfp128Binary
.op
) {
6221 p
= mkFormX( p
, 63, 10, 11, fr_src
, 802, 0, endness_host
);
6227 /* The instruction will put the 64-bit result in registers 10, 11. */
6228 p
= mkFormX(p
, 63, fr_dstHi
, 0, 10, 72, 0, endness_host
);
6229 p
= mkFormX(p
, 63, fr_dstLo
, 0, 11, 72, 0, endness_host
);
6233 case Pin_InsertExpD128
: {
6234 UInt fr_dstHi
= fregEnc(i
->Pin
.InsertExpD128
.dst_hi
);
6235 UInt fr_dstLo
= fregEnc(i
->Pin
.InsertExpD128
.dst_lo
);
6236 UInt fr_srcL
= fregEnc(i
->Pin
.InsertExpD128
.srcL
);
6237 UInt fr_srcRHi
= fregEnc(i
->Pin
.InsertExpD128
.srcR_hi
);
6238 UInt fr_srcRLo
= fregEnc(i
->Pin
.InsertExpD128
.srcR_lo
);
6240 /* The left operand is a single F64 value, the right is an F128
6243 p
= mkFormX(p
, 63, 10, 0, fr_srcL
, 72, 0, endness_host
);
6244 p
= mkFormX(p
, 63, 12, 0, fr_srcRHi
, 72, 0, endness_host
);
6245 p
= mkFormX(p
, 63, 13, 0, fr_srcRLo
, 72, 0, endness_host
);
6246 p
= mkFormX(p
, 63, 10, 10, 12, 866, 0, endness_host
);
6248 /* The instruction will put the 128-bit result into
6249 * registers (10,11). Note, the operand in the instruction only
6250 * reference the first of the two registers in the pair.
6252 p
= mkFormX(p
, 63, fr_dstHi
, 0, 10, 72, 0, endness_host
);
6253 p
= mkFormX(p
, 63, fr_dstLo
, 0, 11, 72, 0, endness_host
);
6259 UInt r_dst
= iregEnc(i
->Pin
.Dfp64Cmp
.dst
, mode64
);
6260 UInt fr_srcL
= fregEnc(i
->Pin
.Dfp64Cmp
.srcL
);
6261 UInt fr_srcR
= fregEnc(i
->Pin
.Dfp64Cmp
.srcR
);
6264 p
= mkFormX(p
, 59, crfD
<<2, fr_srcL
, fr_srcR
, 130, 0, endness_host
);
6266 // mfcr (mv CR to r_dst)
6267 p
= mkFormX(p
, 31, r_dst
, 0, 0, 19, 0, endness_host
);
6269 // rlwinm r_dst,r_dst,8,28,31
6270 // => rotate field 1 to bottomw of word, masking out upper 28
6271 p
= mkFormM(p
, 21, r_dst
, r_dst
, 8, 28, 31, 0, endness_host
);
6275 case Pin_Dfp128Cmp
: {
6277 UInt r_dst
= iregEnc(i
->Pin
.Dfp128Cmp
.dst
, mode64
);
6278 UInt fr_srcL_hi
= fregEnc(i
->Pin
.Dfp128Cmp
.srcL_hi
);
6279 UInt fr_srcL_lo
= fregEnc(i
->Pin
.Dfp128Cmp
.srcL_lo
);
6280 UInt fr_srcR_hi
= fregEnc(i
->Pin
.Dfp128Cmp
.srcR_hi
);
6281 UInt fr_srcR_lo
= fregEnc(i
->Pin
.Dfp128Cmp
.srcR_lo
);
6284 /* Setup the upper and lower registers of the source operand
6287 p
= mkFormX(p
, 63, 10, 0, fr_srcL_hi
, 72, 0, endness_host
);
6288 p
= mkFormX(p
, 63, 11, 0, fr_srcL_lo
, 72, 0, endness_host
);
6289 p
= mkFormX(p
, 63, 12, 0, fr_srcR_hi
, 72, 0, endness_host
);
6290 p
= mkFormX(p
, 63, 13, 0, fr_srcR_lo
, 72, 0, endness_host
);
6292 p
= mkFormX(p
, 63, crfD
<<2, 10, 12, 130, 0, endness_host
);
6294 // mfcr (mv CR to r_dst)
6295 p
= mkFormX(p
, 31, r_dst
, 0, 0, 19, 0, endness_host
);
6297 // rlwinm r_dst,r_dst,8,28,31
6298 // => rotate field 1 to bottomw of word, masking out upper 28
6299 p
= mkFormM(p
, 21, r_dst
, r_dst
, 8, 28, 31, 0, endness_host
);
6304 /* This requires a 32-bit dec/test in both 32- and 64-bit
6311 lwz/ld r30, amFailAddr
6317 /* lwz r30, amCounter */
6318 p
= do_load_or_store_word32(p
, True
/*isLoad*/, /*r*/30,
6319 i
->Pin
.EvCheck
.amCounter
, mode64
,
6321 /* addic. r30,r30,-1 */
6322 p
= emit32(p
, 0x37DEFFFF, endness_host
);
6323 /* stw r30, amCounter */
6324 p
= do_load_or_store_word32(p
, False
/*!isLoad*/, /*r*/30,
6325 i
->Pin
.EvCheck
.amCounter
, mode64
,
6328 p
= emit32(p
, 0x40800010, endness_host
);
6329 /* lwz/ld r30, amFailAddr */
6330 p
= do_load_or_store_machine_word(p
, True
/*isLoad*/, /*r*/30,
6331 i
->Pin
.EvCheck
.amFailAddr
, mode64
,
6334 p
= mkFormXFX(p
, /*r*/30, 9, 467, endness_host
);
6336 p
= mkFormXL(p
, 19, Pct_ALWAYS
, 0, 0, 528, 0, endness_host
);
6340 vassert(evCheckSzB_PPC() == (UChar
*)p
- (UChar
*)p0
);
6346 (ctrP is unknown now, so use 0x65556555(65556555) in the
6347 expectation that a later call to LibVEX_patchProfCtr
6348 will be used to fill in the immediate fields once the
6349 right value is known.)
6351 imm32-exactly r30, 0x65556555
6359 imm64-exactly r30, 0x6555655565556555
6365 p
= mkLoadImm_EXACTLY2or5(
6366 p
, /*r*/30, 0x6555655565556555ULL
, True
/*mode64*/, endness_host
);
6367 p
= emit32(p
, 0xEBBE0000, endness_host
);
6368 p
= emit32(p
, 0x3BBD0001, endness_host
);
6369 p
= emit32(p
, 0xFBBE0000, endness_host
);
6371 p
= mkLoadImm_EXACTLY2or5(
6372 p
, /*r*/30, 0x65556555ULL
, False
/*!mode64*/, endness_host
);
6373 p
= emit32(p
, 0x83BE0004, endness_host
);
6374 p
= emit32(p
, 0x37BD0001, endness_host
);
6375 p
= emit32(p
, 0x93BE0004, endness_host
);
6376 p
= emit32(p
, 0x83BE0000, endness_host
);
6377 p
= emit32(p
, 0x7FBD0194, endness_host
);
6378 p
= emit32(p
, 0x93BE0000, endness_host
);
6380 /* Tell the caller .. */
6381 vassert(!(*is_profInc
));
6391 vex_printf("\n=> ");
6392 ppPPCInstr(i
, mode64
);
6393 vpanic("emit_PPCInstr");
6397 vassert(p
- &buf
[0] <= 64);
6402 /* How big is an event check? See case for Pin_EvCheck in
6403 emit_PPCInstr just above. That crosschecks what this returns, so
6404 we can tell if we're inconsistent. */
6405 Int
evCheckSzB_PPC (void)
6411 /* NB: what goes on here has to be very closely coordinated with the
6412 emitInstr case for XDirect, above. */
6413 VexInvalRange
chainXDirect_PPC ( VexEndness endness_host
,
6414 void* place_to_chain
,
6415 const void* disp_cp_chain_me_EXPECTED
,
6416 const void* place_to_jump_to
,
6420 vassert((endness_host
== VexEndnessBE
) ||
6421 (endness_host
== VexEndnessLE
));
6423 vassert(endness_host
== VexEndnessBE
);
6426 /* What we're expecting to see is:
6427 imm32/64-fixed r30, disp_cp_chain_me_to_EXPECTED
6431 <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5>
6435 UChar
* p
= (UChar
*)place_to_chain
;
6436 vassert(0 == (3 & (HWord
)p
));
6437 vassert(isLoadImm_EXACTLY2or5(p
, /*r*/30,
6438 (Addr
)disp_cp_chain_me_EXPECTED
,
6439 mode64
, endness_host
));
6440 vassert(fetch32(p
+ (mode64
? 20 : 8) + 0, endness_host
) == 0x7FC903A6);
6441 vassert(fetch32(p
+ (mode64
? 20 : 8) + 4, endness_host
) == 0x4E800421);
6442 /* And what we want to change it to is:
6443 imm32/64-fixed r30, place_to_jump_to
6447 <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5>
6450 The replacement has the same length as the original.
6452 p
= mkLoadImm_EXACTLY2or5(p
, /*r*/30,
6453 (Addr
)place_to_jump_to
, mode64
,
6455 p
= emit32(p
, 0x7FC903A6, endness_host
);
6456 p
= emit32(p
, 0x4E800420, endness_host
);
6458 Int len
= p
- (UChar
*)place_to_chain
;
6459 vassert(len
== (mode64
? 28 : 16)); /* stay sane */
6460 VexInvalRange vir
= {(HWord
)place_to_chain
, len
};
6465 /* NB: what goes on here has to be very closely coordinated with the
6466 emitInstr case for XDirect, above. */
6467 VexInvalRange
unchainXDirect_PPC ( VexEndness endness_host
,
6468 void* place_to_unchain
,
6469 const void* place_to_jump_to_EXPECTED
,
6470 const void* disp_cp_chain_me
,
6474 vassert((endness_host
== VexEndnessBE
) ||
6475 (endness_host
== VexEndnessLE
));
6477 vassert(endness_host
== VexEndnessBE
);
6480 /* What we're expecting to see is:
6481 imm32/64-fixed r30, place_to_jump_to_EXPECTED
6485 <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5>
6489 UChar
* p
= (UChar
*)place_to_unchain
;
6490 vassert(0 == (3 & (HWord
)p
));
6491 vassert(isLoadImm_EXACTLY2or5(p
, /*r*/30,
6492 (Addr
)place_to_jump_to_EXPECTED
,
6493 mode64
, endness_host
));
6494 vassert(fetch32(p
+ (mode64
? 20 : 8) + 0, endness_host
) == 0x7FC903A6);
6495 vassert(fetch32(p
+ (mode64
? 20 : 8) + 4, endness_host
) == 0x4E800420);
6496 /* And what we want to change it to is:
6497 imm32/64-fixed r30, disp_cp_chain_me
6501 <8 or 20 bytes generated by mkLoadImm_EXACTLY2or5>
6504 The replacement has the same length as the original.
6506 p
= mkLoadImm_EXACTLY2or5(p
, /*r*/30,
6507 (Addr
)disp_cp_chain_me
, mode64
,
6509 p
= emit32(p
, 0x7FC903A6, endness_host
);
6510 p
= emit32(p
, 0x4E800421, endness_host
);
6512 Int len
= p
- (UChar
*)place_to_unchain
;
6513 vassert(len
== (mode64
? 28 : 16)); /* stay sane */
6514 VexInvalRange vir
= {(HWord
)place_to_unchain
, len
};
6519 /* Patch the counter address into a profile inc point, as previously
6520 created by the Pin_ProfInc case for emit_PPCInstr. */
6521 VexInvalRange
patchProfInc_PPC ( VexEndness endness_host
,
6522 void* place_to_patch
,
6523 const ULong
* location_of_counter
,
6527 vassert((endness_host
== VexEndnessBE
) ||
6528 (endness_host
== VexEndnessLE
));
6530 vassert(endness_host
== VexEndnessBE
);
6533 UChar
* p
= (UChar
*)place_to_patch
;
6534 vassert(0 == (3 & (HWord
)p
));
6538 vassert(isLoadImm_EXACTLY2or5(p
, /*r*/30,
6539 0x6555655565556555ULL
, True
/*mode64*/,
6541 vassert(fetch32(p
+ 20, endness_host
) == 0xEBBE0000);
6542 vassert(fetch32(p
+ 24, endness_host
) == 0x3BBD0001);
6543 vassert(fetch32(p
+ 28, endness_host
) == 0xFBBE0000);
6544 p
= mkLoadImm_EXACTLY2or5(p
, /*r*/30,
6545 (Addr
)location_of_counter
,
6546 True
/*mode64*/, endness_host
);
6547 len
= p
- (UChar
*)place_to_patch
;
6550 vassert(isLoadImm_EXACTLY2or5(p
, /*r*/30,
6551 0x65556555ULL
, False
/*!mode64*/,
6553 vassert(fetch32(p
+ 8, endness_host
) == 0x83BE0004);
6554 vassert(fetch32(p
+ 12, endness_host
) == 0x37BD0001);
6555 vassert(fetch32(p
+ 16, endness_host
) == 0x93BE0004);
6556 vassert(fetch32(p
+ 20, endness_host
) == 0x83BE0000);
6557 vassert(fetch32(p
+ 24, endness_host
) == 0x7FBD0194);
6558 vassert(fetch32(p
+ 28, endness_host
) == 0x93BE0000);
6559 p
= mkLoadImm_EXACTLY2or5(p
, /*r*/30,
6560 (Addr
)location_of_counter
,
6561 False
/*!mode64*/, endness_host
);
6562 len
= p
- (UChar
*)place_to_patch
;
6565 VexInvalRange vir
= {(HWord
)place_to_patch
, len
};
6570 /*---------------------------------------------------------------*/
6571 /*--- end host_ppc_defs.c ---*/
6572 /*---------------------------------------------------------------*/