• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*---------------------------------------------------------------*/
3 /*--- begin                               guest_ppc_helpers.c ---*/
4 /*---------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2004-2012 OpenWorks LLP
11       info@open-works.net
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 
30    Neither the names of the U.S. Department of Energy nor the
31    University of California nor the names of its contributors may be
32    used to endorse or promote products derived from this software
33    without prior written permission.
34 */
35 
36 #include "libvex_basictypes.h"
37 #include "libvex_emwarn.h"
38 #include "libvex_guest_ppc32.h"
39 #include "libvex_guest_ppc64.h"
40 #include "libvex_ir.h"
41 #include "libvex.h"
42 
43 #include "main_util.h"
44 #include "guest_generic_bb_to_IR.h"
45 #include "guest_ppc_defs.h"
46 
47 
48 /* This file contains helper functions for ppc32 and ppc64 guest code.
49    Calls to these functions are generated by the back end.  These
50    calls are of course in the host machine code and this file will be
51    compiled to host machine code, so that all makes sense.
52 
53    Only change the signatures of these helper functions very
54    carefully.  If you change the signature here, you'll have to change
55    the parameters passed to it in the IR calls constructed by
56    guest-ppc/toIR.c.
57 */
58 
59 
60 /*---------------------------------------------------------------*/
61 /*--- Misc integer helpers.                                   ---*/
62 /*---------------------------------------------------------------*/
63 
64 /* CALLED FROM GENERATED CODE */
65 /* DIRTY HELPER (non-referentially-transparent) */
66 /* Horrible hack.  On non-ppc platforms, return 1. */
67 /* Reads a complete, consistent 64-bit TB value. */
ppcg_dirtyhelper_MFTB(void)68 ULong ppcg_dirtyhelper_MFTB ( void )
69 {
70 #  if defined(__powerpc__) || defined(_AIX)
71    ULong res;
72    UInt  lo, hi1, hi2;
73    while (1) {
74       __asm__ __volatile__ ("\n"
75          "\tmftbu %0\n"
76          "\tmftb %1\n"
77          "\tmftbu %2\n"
78          : "=r" (hi1), "=r" (lo), "=r" (hi2)
79       );
80       if (hi1 == hi2) break;
81    }
82    res = ((ULong)hi1) << 32;
83    res |= (ULong)lo;
84    return res;
85 #  else
86    return 1ULL;
87 #  endif
88 }
89 
90 
91 /* CALLED FROM GENERATED CODE */
92 /* DIRTY HELPER (non-referentially transparent) */
ppc32g_dirtyhelper_MFSPR_268_269(UInt r269)93 UInt ppc32g_dirtyhelper_MFSPR_268_269 ( UInt r269 )
94 {
95 #  if defined(__powerpc__) || defined(_AIX)
96    UInt spr;
97    if (r269) {
98       __asm__ __volatile__("mfspr %0,269" : "=b"(spr));
99    } else {
100       __asm__ __volatile__("mfspr %0,268" : "=b"(spr));
101    }
102    return spr;
103 #  else
104    return 0;
105 #  endif
106 }
107 
108 
109 /* CALLED FROM GENERATED CODE */
110 /* DIRTY HELPER (I'm not really sure what the side effects are) */
ppc32g_dirtyhelper_MFSPR_287(void)111 UInt ppc32g_dirtyhelper_MFSPR_287 ( void )
112 {
113 #  if defined(__powerpc__) || defined(_AIX)
114    UInt spr;
115    __asm__ __volatile__("mfspr %0,287" : "=b"(spr));
116    return spr;
117 #  else
118    return 0;
119 #  endif
120 }
121 
122 
123 /* CALLED FROM GENERATED CODE */
124 /* DIRTY HELPER (reads guest state, writes guest mem) */
ppc32g_dirtyhelper_LVS(VexGuestPPC32State * gst,UInt vD_off,UInt sh,UInt shift_right)125 void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst,
126                               UInt vD_off, UInt sh, UInt shift_right )
127 {
128   static
129   UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
130                     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
131                     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
132                     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
133   U128* pU128_src;
134   U128* pU128_dst;
135 
136   vassert( vD_off       <= sizeof(VexGuestPPC32State)-8 );
137   vassert( sh           <= 15 );
138   vassert( shift_right  <=  1 );
139   if (shift_right)
140      sh = 16-sh;
141   /* else shift left  */
142 
143   pU128_src = (U128*)&ref[sh];
144   pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
145 
146   (*pU128_dst)[0] = (*pU128_src)[0];
147   (*pU128_dst)[1] = (*pU128_src)[1];
148   (*pU128_dst)[2] = (*pU128_src)[2];
149   (*pU128_dst)[3] = (*pU128_src)[3];
150 }
151 
152 /* CALLED FROM GENERATED CODE */
153 /* DIRTY HELPER (reads guest state, writes guest mem) */
ppc64g_dirtyhelper_LVS(VexGuestPPC64State * gst,UInt vD_off,UInt sh,UInt shift_right)154 void ppc64g_dirtyhelper_LVS ( VexGuestPPC64State* gst,
155                               UInt vD_off, UInt sh, UInt shift_right )
156 {
157   UChar ref[32];
158   ULong i;
159   /* ref[] used to be a static const array, but this doesn't work on
160      ppc64 because VEX doesn't load the TOC pointer for the call here,
161      and so we wind up picking up some totally random other data.
162      (It's a wonder we don't segfault.)  So, just to be clear, this
163      "fix" (vex r2073) is really a kludgearound for the fact that
164      VEX's 64-bit ppc code generation doesn't provide a valid TOC
165      pointer for helper function calls.  Ick.  (Bug 250038) */
166   for (i = 0; i < 32; i++) ref[i] = i;
167 
168   U128* pU128_src;
169   U128* pU128_dst;
170 
171   vassert( vD_off       <= sizeof(VexGuestPPC64State)-8 );
172   vassert( sh           <= 15 );
173   vassert( shift_right  <=  1 );
174   if (shift_right)
175      sh = 16-sh;
176   /* else shift left  */
177 
178   pU128_src = (U128*)&ref[sh];
179   pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
180 
181   (*pU128_dst)[0] = (*pU128_src)[0];
182   (*pU128_dst)[1] = (*pU128_src)[1];
183   (*pU128_dst)[2] = (*pU128_src)[2];
184   (*pU128_dst)[3] = (*pU128_src)[3];
185 }
186 
187 
188 /* Helper-function specialiser. */
189 
guest_ppc32_spechelper(HChar * function_name,IRExpr ** args,IRStmt ** precedingStmts,Int n_precedingStmts)190 IRExpr* guest_ppc32_spechelper ( HChar* function_name,
191                                  IRExpr** args,
192                                  IRStmt** precedingStmts,
193                                  Int      n_precedingStmts )
194 {
195    return NULL;
196 }
197 
guest_ppc64_spechelper(HChar * function_name,IRExpr ** args,IRStmt ** precedingStmts,Int n_precedingStmts)198 IRExpr* guest_ppc64_spechelper ( HChar* function_name,
199                                  IRExpr** args,
200                                  IRStmt** precedingStmts,
201                                  Int      n_precedingStmts )
202 {
203    return NULL;
204 }
205 
206 
207 /*----------------------------------------------*/
208 /*--- The exported fns ..                    ---*/
209 /*----------------------------------------------*/
210 
211 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_get_CR(VexGuestPPC32State * vex_state)212 UInt LibVEX_GuestPPC32_get_CR ( /*IN*/VexGuestPPC32State* vex_state )
213 {
214 #  define FIELD(_n)                                    \
215       ( ( (UInt)                                       \
216            ( (vex_state->guest_CR##_n##_321 & (7<<1))  \
217              | (vex_state->guest_CR##_n##_0 & 1)       \
218            )                                           \
219         )                                              \
220         << (4 * (7-(_n)))                              \
221       )
222 
223    return
224       FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
225       | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
226 
227 #  undef FIELD
228 }
229 
230 
231 /* VISIBLE TO LIBVEX CLIENT */
232 /* Note: %CR is 32 bits even for ppc64 */
LibVEX_GuestPPC64_get_CR(VexGuestPPC64State * vex_state)233 UInt LibVEX_GuestPPC64_get_CR ( /*IN*/VexGuestPPC64State* vex_state )
234 {
235 #  define FIELD(_n)                                    \
236       ( ( (UInt)                                       \
237            ( (vex_state->guest_CR##_n##_321 & (7<<1))  \
238              | (vex_state->guest_CR##_n##_0 & 1)       \
239            )                                           \
240         )                                              \
241         << (4 * (7-(_n)))                              \
242       )
243 
244    return
245       FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
246       | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
247 
248 #  undef FIELD
249 }
250 
251 
252 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_put_CR(UInt cr_native,VexGuestPPC32State * vex_state)253 void LibVEX_GuestPPC32_put_CR ( UInt cr_native,
254                                 /*OUT*/VexGuestPPC32State* vex_state )
255 {
256    UInt t;
257 
258 #  define FIELD(_n)                                           \
259       do {                                                    \
260          t = cr_native >> (4*(7-(_n)));                       \
261          vex_state->guest_CR##_n##_0 = toUChar(t & 1);        \
262          vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
263       } while (0)
264 
265    FIELD(0);
266    FIELD(1);
267    FIELD(2);
268    FIELD(3);
269    FIELD(4);
270    FIELD(5);
271    FIELD(6);
272    FIELD(7);
273 
274 #  undef FIELD
275 }
276 
277 
278 /* VISIBLE TO LIBVEX CLIENT */
279 /* Note: %CR is 32 bits even for ppc64 */
LibVEX_GuestPPC64_put_CR(UInt cr_native,VexGuestPPC64State * vex_state)280 void LibVEX_GuestPPC64_put_CR ( UInt cr_native,
281                                 /*OUT*/VexGuestPPC64State* vex_state )
282 {
283    UInt t;
284 
285 #  define FIELD(_n)                                           \
286       do {                                                    \
287          t = cr_native >> (4*(7-(_n)));                       \
288          vex_state->guest_CR##_n##_0 = toUChar(t & 1);        \
289          vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
290       } while (0)
291 
292    FIELD(0);
293    FIELD(1);
294    FIELD(2);
295    FIELD(3);
296    FIELD(4);
297    FIELD(5);
298    FIELD(6);
299    FIELD(7);
300 
301 #  undef FIELD
302 }
303 
304 
305 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_get_XER(VexGuestPPC32State * vex_state)306 UInt LibVEX_GuestPPC32_get_XER ( /*IN*/VexGuestPPC32State* vex_state )
307 {
308    UInt w = 0;
309    w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
310    w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
311    w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
312    w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
313    return w;
314 }
315 
316 
317 /* VISIBLE TO LIBVEX CLIENT */
318 /* Note: %XER is 32 bits even for ppc64 */
LibVEX_GuestPPC64_get_XER(VexGuestPPC64State * vex_state)319 UInt LibVEX_GuestPPC64_get_XER ( /*IN*/VexGuestPPC64State* vex_state )
320 {
321    UInt w = 0;
322    w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
323    w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
324    w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
325    w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
326    return w;
327 }
328 
329 
330 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_put_XER(UInt xer_native,VexGuestPPC32State * vex_state)331 void LibVEX_GuestPPC32_put_XER ( UInt xer_native,
332                                  /*OUT*/VexGuestPPC32State* vex_state )
333 {
334    vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
335    vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
336    vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
337    vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
338 }
339 
340 /* VISIBLE TO LIBVEX CLIENT */
341 /* Note: %XER is 32 bits even for ppc64 */
LibVEX_GuestPPC64_put_XER(UInt xer_native,VexGuestPPC64State * vex_state)342 void LibVEX_GuestPPC64_put_XER ( UInt xer_native,
343                                  /*OUT*/VexGuestPPC64State* vex_state )
344 {
345    vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
346    vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
347    vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
348    vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
349 }
350 
351 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_initialise(VexGuestPPC32State * vex_state)352 void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state )
353 {
354    Int i;
355    vex_state->host_EvC_FAILADDR = 0;
356    vex_state->host_EvC_COUNTER  = 0;
357    vex_state->pad3 = 0;
358    vex_state->pad4 = 0;
359 
360    vex_state->guest_GPR0  = 0;
361    vex_state->guest_GPR1  = 0;
362    vex_state->guest_GPR2  = 0;
363    vex_state->guest_GPR3  = 0;
364    vex_state->guest_GPR4  = 0;
365    vex_state->guest_GPR5  = 0;
366    vex_state->guest_GPR6  = 0;
367    vex_state->guest_GPR7  = 0;
368    vex_state->guest_GPR8  = 0;
369    vex_state->guest_GPR9  = 0;
370    vex_state->guest_GPR10 = 0;
371    vex_state->guest_GPR11 = 0;
372    vex_state->guest_GPR12 = 0;
373    vex_state->guest_GPR13 = 0;
374    vex_state->guest_GPR14 = 0;
375    vex_state->guest_GPR15 = 0;
376    vex_state->guest_GPR16 = 0;
377    vex_state->guest_GPR17 = 0;
378    vex_state->guest_GPR18 = 0;
379    vex_state->guest_GPR19 = 0;
380    vex_state->guest_GPR20 = 0;
381    vex_state->guest_GPR21 = 0;
382    vex_state->guest_GPR22 = 0;
383    vex_state->guest_GPR23 = 0;
384    vex_state->guest_GPR24 = 0;
385    vex_state->guest_GPR25 = 0;
386    vex_state->guest_GPR26 = 0;
387    vex_state->guest_GPR27 = 0;
388    vex_state->guest_GPR28 = 0;
389    vex_state->guest_GPR29 = 0;
390    vex_state->guest_GPR30 = 0;
391    vex_state->guest_GPR31 = 0;
392 
393    /* Initialise the vector state. */
394 #  define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
395 
396    VECZERO(vex_state->guest_VSR0 );
397    VECZERO(vex_state->guest_VSR1 );
398    VECZERO(vex_state->guest_VSR2 );
399    VECZERO(vex_state->guest_VSR3 );
400    VECZERO(vex_state->guest_VSR4 );
401    VECZERO(vex_state->guest_VSR5 );
402    VECZERO(vex_state->guest_VSR6 );
403    VECZERO(vex_state->guest_VSR7 );
404    VECZERO(vex_state->guest_VSR8 );
405    VECZERO(vex_state->guest_VSR9 );
406    VECZERO(vex_state->guest_VSR10);
407    VECZERO(vex_state->guest_VSR11);
408    VECZERO(vex_state->guest_VSR12);
409    VECZERO(vex_state->guest_VSR13);
410    VECZERO(vex_state->guest_VSR14);
411    VECZERO(vex_state->guest_VSR15);
412    VECZERO(vex_state->guest_VSR16);
413    VECZERO(vex_state->guest_VSR17);
414    VECZERO(vex_state->guest_VSR18);
415    VECZERO(vex_state->guest_VSR19);
416    VECZERO(vex_state->guest_VSR20);
417    VECZERO(vex_state->guest_VSR21);
418    VECZERO(vex_state->guest_VSR22);
419    VECZERO(vex_state->guest_VSR23);
420    VECZERO(vex_state->guest_VSR24);
421    VECZERO(vex_state->guest_VSR25);
422    VECZERO(vex_state->guest_VSR26);
423    VECZERO(vex_state->guest_VSR27);
424    VECZERO(vex_state->guest_VSR28);
425    VECZERO(vex_state->guest_VSR29);
426    VECZERO(vex_state->guest_VSR30);
427    VECZERO(vex_state->guest_VSR31);
428    VECZERO(vex_state->guest_VSR32);
429    VECZERO(vex_state->guest_VSR33);
430    VECZERO(vex_state->guest_VSR34);
431    VECZERO(vex_state->guest_VSR35);
432    VECZERO(vex_state->guest_VSR36);
433    VECZERO(vex_state->guest_VSR37);
434    VECZERO(vex_state->guest_VSR38);
435    VECZERO(vex_state->guest_VSR39);
436    VECZERO(vex_state->guest_VSR40);
437    VECZERO(vex_state->guest_VSR41);
438    VECZERO(vex_state->guest_VSR42);
439    VECZERO(vex_state->guest_VSR43);
440    VECZERO(vex_state->guest_VSR44);
441    VECZERO(vex_state->guest_VSR45);
442    VECZERO(vex_state->guest_VSR46);
443    VECZERO(vex_state->guest_VSR47);
444    VECZERO(vex_state->guest_VSR48);
445    VECZERO(vex_state->guest_VSR49);
446    VECZERO(vex_state->guest_VSR50);
447    VECZERO(vex_state->guest_VSR51);
448    VECZERO(vex_state->guest_VSR52);
449    VECZERO(vex_state->guest_VSR53);
450    VECZERO(vex_state->guest_VSR54);
451    VECZERO(vex_state->guest_VSR55);
452    VECZERO(vex_state->guest_VSR56);
453    VECZERO(vex_state->guest_VSR57);
454    VECZERO(vex_state->guest_VSR58);
455    VECZERO(vex_state->guest_VSR59);
456    VECZERO(vex_state->guest_VSR60);
457    VECZERO(vex_state->guest_VSR61);
458    VECZERO(vex_state->guest_VSR62);
459    VECZERO(vex_state->guest_VSR63);
460 
461 #  undef VECZERO
462 
463    vex_state->guest_CIA  = 0;
464    vex_state->guest_LR   = 0;
465    vex_state->guest_CTR  = 0;
466 
467    vex_state->guest_XER_SO = 0;
468    vex_state->guest_XER_OV = 0;
469    vex_state->guest_XER_CA = 0;
470    vex_state->guest_XER_BC = 0;
471 
472    vex_state->guest_CR0_321 = 0;
473    vex_state->guest_CR0_0   = 0;
474    vex_state->guest_CR1_321 = 0;
475    vex_state->guest_CR1_0   = 0;
476    vex_state->guest_CR2_321 = 0;
477    vex_state->guest_CR2_0   = 0;
478    vex_state->guest_CR3_321 = 0;
479    vex_state->guest_CR3_0   = 0;
480    vex_state->guest_CR4_321 = 0;
481    vex_state->guest_CR4_0   = 0;
482    vex_state->guest_CR5_321 = 0;
483    vex_state->guest_CR5_0   = 0;
484    vex_state->guest_CR6_321 = 0;
485    vex_state->guest_CR6_0   = 0;
486    vex_state->guest_CR7_321 = 0;
487    vex_state->guest_CR7_0   = 0;
488 
489    vex_state->guest_FPROUND  = PPCrm_NEAREST;
490    vex_state->guest_DFPROUND = PPCrm_NEAREST;
491    vex_state->pad1 = 0;
492    vex_state->pad2 = 0;
493 
494    vex_state->guest_VRSAVE = 0;
495 
496    vex_state->guest_VSCR = 0x0;  // Non-Java mode = 0
497 
498    vex_state->guest_EMWARN = EmWarn_NONE;
499 
500    vex_state->guest_TISTART = 0;
501    vex_state->guest_TILEN   = 0;
502 
503    vex_state->guest_NRADDR = 0;
504    vex_state->guest_NRADDR_GPR2 = 0;
505 
506    vex_state->guest_REDIR_SP = -1;
507    for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++)
508       vex_state->guest_REDIR_STACK[i] = 0;
509 
510    vex_state->guest_IP_AT_SYSCALL = 0;
511    vex_state->guest_SPRG3_RO = 0;
512 
513    vex_state->padding = 0;
514 }
515 
516 
517 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC64_initialise(VexGuestPPC64State * vex_state)518 void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state )
519 {
520    Int i;
521    vex_state->host_EvC_FAILADDR = 0;
522    vex_state->host_EvC_COUNTER = 0;
523    vex_state->pad0 = 0;
524    vex_state->guest_GPR0  = 0;
525    vex_state->guest_GPR1  = 0;
526    vex_state->guest_GPR2  = 0;
527    vex_state->guest_GPR3  = 0;
528    vex_state->guest_GPR4  = 0;
529    vex_state->guest_GPR5  = 0;
530    vex_state->guest_GPR6  = 0;
531    vex_state->guest_GPR7  = 0;
532    vex_state->guest_GPR8  = 0;
533    vex_state->guest_GPR9  = 0;
534    vex_state->guest_GPR10 = 0;
535    vex_state->guest_GPR11 = 0;
536    vex_state->guest_GPR12 = 0;
537    vex_state->guest_GPR13 = 0;
538    vex_state->guest_GPR14 = 0;
539    vex_state->guest_GPR15 = 0;
540    vex_state->guest_GPR16 = 0;
541    vex_state->guest_GPR17 = 0;
542    vex_state->guest_GPR18 = 0;
543    vex_state->guest_GPR19 = 0;
544    vex_state->guest_GPR20 = 0;
545    vex_state->guest_GPR21 = 0;
546    vex_state->guest_GPR22 = 0;
547    vex_state->guest_GPR23 = 0;
548    vex_state->guest_GPR24 = 0;
549    vex_state->guest_GPR25 = 0;
550    vex_state->guest_GPR26 = 0;
551    vex_state->guest_GPR27 = 0;
552    vex_state->guest_GPR28 = 0;
553    vex_state->guest_GPR29 = 0;
554    vex_state->guest_GPR30 = 0;
555    vex_state->guest_GPR31 = 0;
556 
557    /* Initialise the vector state. */
558 #  define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
559 
560    VECZERO(vex_state->guest_VSR0 );
561    VECZERO(vex_state->guest_VSR1 );
562    VECZERO(vex_state->guest_VSR2 );
563    VECZERO(vex_state->guest_VSR3 );
564    VECZERO(vex_state->guest_VSR4 );
565    VECZERO(vex_state->guest_VSR5 );
566    VECZERO(vex_state->guest_VSR6 );
567    VECZERO(vex_state->guest_VSR7 );
568    VECZERO(vex_state->guest_VSR8 );
569    VECZERO(vex_state->guest_VSR9 );
570    VECZERO(vex_state->guest_VSR10);
571    VECZERO(vex_state->guest_VSR11);
572    VECZERO(vex_state->guest_VSR12);
573    VECZERO(vex_state->guest_VSR13);
574    VECZERO(vex_state->guest_VSR14);
575    VECZERO(vex_state->guest_VSR15);
576    VECZERO(vex_state->guest_VSR16);
577    VECZERO(vex_state->guest_VSR17);
578    VECZERO(vex_state->guest_VSR18);
579    VECZERO(vex_state->guest_VSR19);
580    VECZERO(vex_state->guest_VSR20);
581    VECZERO(vex_state->guest_VSR21);
582    VECZERO(vex_state->guest_VSR22);
583    VECZERO(vex_state->guest_VSR23);
584    VECZERO(vex_state->guest_VSR24);
585    VECZERO(vex_state->guest_VSR25);
586    VECZERO(vex_state->guest_VSR26);
587    VECZERO(vex_state->guest_VSR27);
588    VECZERO(vex_state->guest_VSR28);
589    VECZERO(vex_state->guest_VSR29);
590    VECZERO(vex_state->guest_VSR30);
591    VECZERO(vex_state->guest_VSR31);
592    VECZERO(vex_state->guest_VSR32);
593    VECZERO(vex_state->guest_VSR33);
594    VECZERO(vex_state->guest_VSR34);
595    VECZERO(vex_state->guest_VSR35);
596    VECZERO(vex_state->guest_VSR36);
597    VECZERO(vex_state->guest_VSR37);
598    VECZERO(vex_state->guest_VSR38);
599    VECZERO(vex_state->guest_VSR39);
600    VECZERO(vex_state->guest_VSR40);
601    VECZERO(vex_state->guest_VSR41);
602    VECZERO(vex_state->guest_VSR42);
603    VECZERO(vex_state->guest_VSR43);
604    VECZERO(vex_state->guest_VSR44);
605    VECZERO(vex_state->guest_VSR45);
606    VECZERO(vex_state->guest_VSR46);
607    VECZERO(vex_state->guest_VSR47);
608    VECZERO(vex_state->guest_VSR48);
609    VECZERO(vex_state->guest_VSR49);
610    VECZERO(vex_state->guest_VSR50);
611    VECZERO(vex_state->guest_VSR51);
612    VECZERO(vex_state->guest_VSR52);
613    VECZERO(vex_state->guest_VSR53);
614    VECZERO(vex_state->guest_VSR54);
615    VECZERO(vex_state->guest_VSR55);
616    VECZERO(vex_state->guest_VSR56);
617    VECZERO(vex_state->guest_VSR57);
618    VECZERO(vex_state->guest_VSR58);
619    VECZERO(vex_state->guest_VSR59);
620    VECZERO(vex_state->guest_VSR60);
621    VECZERO(vex_state->guest_VSR61);
622    VECZERO(vex_state->guest_VSR62);
623    VECZERO(vex_state->guest_VSR63);
624 
625 #  undef VECZERO
626 
627    vex_state->guest_CIA  = 0;
628    vex_state->guest_LR   = 0;
629    vex_state->guest_CTR  = 0;
630 
631    vex_state->guest_XER_SO = 0;
632    vex_state->guest_XER_OV = 0;
633    vex_state->guest_XER_CA = 0;
634    vex_state->guest_XER_BC = 0;
635 
636    vex_state->guest_CR0_321 = 0;
637    vex_state->guest_CR0_0   = 0;
638    vex_state->guest_CR1_321 = 0;
639    vex_state->guest_CR1_0   = 0;
640    vex_state->guest_CR2_321 = 0;
641    vex_state->guest_CR2_0   = 0;
642    vex_state->guest_CR3_321 = 0;
643    vex_state->guest_CR3_0   = 0;
644    vex_state->guest_CR4_321 = 0;
645    vex_state->guest_CR4_0   = 0;
646    vex_state->guest_CR5_321 = 0;
647    vex_state->guest_CR5_0   = 0;
648    vex_state->guest_CR6_321 = 0;
649    vex_state->guest_CR6_0   = 0;
650    vex_state->guest_CR7_321 = 0;
651    vex_state->guest_CR7_0   = 0;
652 
653    vex_state->guest_FPROUND  = PPCrm_NEAREST;
654    vex_state->guest_DFPROUND = PPCrm_NEAREST;
655    vex_state->pad1 = 0;
656    vex_state->pad2 = 0;
657 
658    vex_state->guest_VRSAVE = 0;
659 
660    vex_state->guest_VSCR = 0x0;  // Non-Java mode = 0
661 
662    vex_state->guest_EMWARN = EmWarn_NONE;
663 
664    vex_state->padding = 0;
665 
666    vex_state->guest_TISTART = 0;
667    vex_state->guest_TILEN   = 0;
668 
669    vex_state->guest_NRADDR = 0;
670    vex_state->guest_NRADDR_GPR2 = 0;
671 
672    vex_state->guest_REDIR_SP = -1;
673    for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
674       vex_state->guest_REDIR_STACK[i] = 0;
675 
676    vex_state->guest_IP_AT_SYSCALL = 0;
677    vex_state->guest_SPRG3_RO = 0;
678 
679    vex_state->padding2 = 0;
680    vex_state->padding3 = 0;
681    vex_state->padding4 = 0;
682 }
683 
684 
685 /*-----------------------------------------------------------*/
686 /*--- Describing the ppc guest state, for the benefit     ---*/
687 /*--- of iropt and instrumenters.                         ---*/
688 /*-----------------------------------------------------------*/
689 
690 /* Figure out if any part of the guest state contained in minoff
691    .. maxoff requires precise memory exceptions.  If in doubt return
692    True (but this is generates significantly slower code).
693 
694    By default we enforce precise exns for guest R1 (stack pointer),
695    CIA (current insn address) and LR (link register).  These are the
696    minimum needed to extract correct stack backtraces from ppc
697    code. [[NB: not sure if keeping LR up to date is actually
698    necessary.]]
699 */
guest_ppc32_state_requires_precise_mem_exns(Int minoff,Int maxoff)700 Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff,
701                                                    Int maxoff )
702 {
703    Int lr_min  = offsetof(VexGuestPPC32State, guest_LR);
704    Int lr_max  = lr_min + 4 - 1;
705    Int r1_min  = offsetof(VexGuestPPC32State, guest_GPR1);
706    Int r1_max  = r1_min + 4 - 1;
707    Int cia_min = offsetof(VexGuestPPC32State, guest_CIA);
708    Int cia_max = cia_min + 4 - 1;
709 
710    if (maxoff < lr_min || minoff > lr_max) {
711       /* no overlap with LR */
712    } else {
713       return True;
714    }
715 
716    if (maxoff < r1_min || minoff > r1_max) {
717       /* no overlap with R1 */
718    } else {
719       return True;
720    }
721 
722    if (maxoff < cia_min || minoff > cia_max) {
723       /* no overlap with CIA */
724    } else {
725       return True;
726    }
727 
728    return False;
729 }
730 
guest_ppc64_state_requires_precise_mem_exns(Int minoff,Int maxoff)731 Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,
732                                                    Int maxoff )
733 {
734    /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems
735       prudent to be conservative with it, even though thus far there
736       is no evidence to suggest that it actually needs to be kept up
737       to date wrt possible exceptions. */
738    Int lr_min  = offsetof(VexGuestPPC64State, guest_LR);
739    Int lr_max  = lr_min + 8 - 1;
740    Int r1_min  = offsetof(VexGuestPPC64State, guest_GPR1);
741    Int r1_max  = r1_min + 8 - 1;
742    Int r2_min  = offsetof(VexGuestPPC64State, guest_GPR2);
743    Int r2_max  = r2_min + 8 - 1;
744    Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
745    Int cia_max = cia_min + 8 - 1;
746 
747    if (maxoff < lr_min || minoff > lr_max) {
748       /* no overlap with LR */
749    } else {
750       return True;
751    }
752 
753    if (maxoff < r1_min || minoff > r1_max) {
754       /* no overlap with R1 */
755    } else {
756       return True;
757    }
758 
759    if (maxoff < r2_min || minoff > r2_max) {
760       /* no overlap with R2 */
761    } else {
762       return True;
763    }
764 
765    if (maxoff < cia_min || minoff > cia_max) {
766       /* no overlap with CIA */
767    } else {
768       return True;
769    }
770 
771    return False;
772 }
773 
774 
775 #define ALWAYSDEFD32(field)                           \
776     { offsetof(VexGuestPPC32State, field),            \
777       (sizeof ((VexGuestPPC32State*)0)->field) }
778 
779 VexGuestLayout
780    ppc32Guest_layout
781       = {
782           /* Total size of the guest state, in bytes. */
783           .total_sizeB = sizeof(VexGuestPPC32State),
784 
785           /* Describe the stack pointer. */
786           .offset_SP = offsetof(VexGuestPPC32State,guest_GPR1),
787           .sizeof_SP = 4,
788 
789           /* Describe the frame pointer. */
790           .offset_FP = offsetof(VexGuestPPC32State,guest_GPR1),
791           .sizeof_FP = 4,
792 
793           /* Describe the instruction pointer. */
794           .offset_IP = offsetof(VexGuestPPC32State,guest_CIA),
795           .sizeof_IP = 4,
796 
797           /* Describe any sections to be regarded by Memcheck as
798              'always-defined'. */
799           .n_alwaysDefd = 11,
800 
801           .alwaysDefd
802 	  = { /*  0 */ ALWAYSDEFD32(guest_CIA),
803 	      /*  1 */ ALWAYSDEFD32(guest_EMWARN),
804 	      /*  2 */ ALWAYSDEFD32(guest_TISTART),
805 	      /*  3 */ ALWAYSDEFD32(guest_TILEN),
806 	      /*  4 */ ALWAYSDEFD32(guest_VSCR),
807 	      /*  5 */ ALWAYSDEFD32(guest_FPROUND),
808               /*  6 */ ALWAYSDEFD32(guest_NRADDR),
809 	      /*  7 */ ALWAYSDEFD32(guest_NRADDR_GPR2),
810 	      /*  8 */ ALWAYSDEFD32(guest_REDIR_SP),
811 	      /*  9 */ ALWAYSDEFD32(guest_REDIR_STACK),
812 	      /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL)
813             }
814         };
815 
816 #define ALWAYSDEFD64(field)                           \
817     { offsetof(VexGuestPPC64State, field),            \
818       (sizeof ((VexGuestPPC64State*)0)->field) }
819 
820 VexGuestLayout
821    ppc64Guest_layout
822       = {
823           /* Total size of the guest state, in bytes. */
824           .total_sizeB = sizeof(VexGuestPPC64State),
825 
826           /* Describe the stack pointer. */
827           .offset_SP = offsetof(VexGuestPPC64State,guest_GPR1),
828           .sizeof_SP = 8,
829 
830           /* Describe the frame pointer. */
831           .offset_FP = offsetof(VexGuestPPC64State,guest_GPR1),
832           .sizeof_FP = 8,
833 
834           /* Describe the instruction pointer. */
835           .offset_IP = offsetof(VexGuestPPC64State,guest_CIA),
836           .sizeof_IP = 8,
837 
838           /* Describe any sections to be regarded by Memcheck as
839              'always-defined'. */
840           .n_alwaysDefd = 11,
841 
842           .alwaysDefd
843 	  = { /*  0 */ ALWAYSDEFD64(guest_CIA),
844 	      /*  1 */ ALWAYSDEFD64(guest_EMWARN),
845 	      /*  2 */ ALWAYSDEFD64(guest_TISTART),
846 	      /*  3 */ ALWAYSDEFD64(guest_TILEN),
847 	      /*  4 */ ALWAYSDEFD64(guest_VSCR),
848 	      /*  5 */ ALWAYSDEFD64(guest_FPROUND),
849 	      /*  6 */ ALWAYSDEFD64(guest_NRADDR),
850 	      /*  7 */ ALWAYSDEFD64(guest_NRADDR_GPR2),
851 	      /*  8 */ ALWAYSDEFD64(guest_REDIR_SP),
852 	      /*  9 */ ALWAYSDEFD64(guest_REDIR_STACK),
853 	      /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL)
854             }
855         };
856 
857 /*---------------------------------------------------------------*/
858 /*--- end                                 guest_ppc_helpers.c ---*/
859 /*---------------------------------------------------------------*/
860