guest_ppc_helpers.c revision e739ac0589b4fb43561f801c4faba8c1b89f8680
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-2010 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. */
68ULong 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) */
93UInt 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) */
111UInt 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) */
125void 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) */
154void 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
190IRExpr* guest_ppc32_spechelper ( HChar* function_name,
191                                 IRExpr** args,
192                                 IRStmt** precedingStmts,
193                                 Int      n_precedingStmts )
194{
195   return NULL;
196}
197
198IRExpr* 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 */
212UInt 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 */
233UInt 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 */
253void 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 */
280void 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 */
306UInt 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 */
319UInt 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 */
331void 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 */
342void 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 */
352void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state )
353{
354   Int i;
355   vex_state->guest_GPR0  = 0;
356   vex_state->guest_GPR1  = 0;
357   vex_state->guest_GPR2  = 0;
358   vex_state->guest_GPR3  = 0;
359   vex_state->guest_GPR4  = 0;
360   vex_state->guest_GPR5  = 0;
361   vex_state->guest_GPR6  = 0;
362   vex_state->guest_GPR7  = 0;
363   vex_state->guest_GPR8  = 0;
364   vex_state->guest_GPR9  = 0;
365   vex_state->guest_GPR10 = 0;
366   vex_state->guest_GPR11 = 0;
367   vex_state->guest_GPR12 = 0;
368   vex_state->guest_GPR13 = 0;
369   vex_state->guest_GPR14 = 0;
370   vex_state->guest_GPR15 = 0;
371   vex_state->guest_GPR16 = 0;
372   vex_state->guest_GPR17 = 0;
373   vex_state->guest_GPR18 = 0;
374   vex_state->guest_GPR19 = 0;
375   vex_state->guest_GPR20 = 0;
376   vex_state->guest_GPR21 = 0;
377   vex_state->guest_GPR22 = 0;
378   vex_state->guest_GPR23 = 0;
379   vex_state->guest_GPR24 = 0;
380   vex_state->guest_GPR25 = 0;
381   vex_state->guest_GPR26 = 0;
382   vex_state->guest_GPR27 = 0;
383   vex_state->guest_GPR28 = 0;
384   vex_state->guest_GPR29 = 0;
385   vex_state->guest_GPR30 = 0;
386   vex_state->guest_GPR31 = 0;
387
388   vex_state->guest_FPR0  = 0;
389   vex_state->guest_FPR1  = 0;
390   vex_state->guest_FPR2  = 0;
391   vex_state->guest_FPR3  = 0;
392   vex_state->guest_FPR4  = 0;
393   vex_state->guest_FPR5  = 0;
394   vex_state->guest_FPR6  = 0;
395   vex_state->guest_FPR7  = 0;
396   vex_state->guest_FPR8  = 0;
397   vex_state->guest_FPR9  = 0;
398   vex_state->guest_FPR10 = 0;
399   vex_state->guest_FPR11 = 0;
400   vex_state->guest_FPR12 = 0;
401   vex_state->guest_FPR13 = 0;
402   vex_state->guest_FPR14 = 0;
403   vex_state->guest_FPR15 = 0;
404   vex_state->guest_FPR16 = 0;
405   vex_state->guest_FPR17 = 0;
406   vex_state->guest_FPR18 = 0;
407   vex_state->guest_FPR19 = 0;
408   vex_state->guest_FPR20 = 0;
409   vex_state->guest_FPR21 = 0;
410   vex_state->guest_FPR22 = 0;
411   vex_state->guest_FPR23 = 0;
412   vex_state->guest_FPR24 = 0;
413   vex_state->guest_FPR25 = 0;
414   vex_state->guest_FPR26 = 0;
415   vex_state->guest_FPR27 = 0;
416   vex_state->guest_FPR28 = 0;
417   vex_state->guest_FPR29 = 0;
418   vex_state->guest_FPR30 = 0;
419   vex_state->guest_FPR31 = 0;
420
421   /* Initialise the vector state. */
422#  define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
423
424   VECZERO(vex_state->guest_VR0 );
425   VECZERO(vex_state->guest_VR1 );
426   VECZERO(vex_state->guest_VR2 );
427   VECZERO(vex_state->guest_VR3 );
428   VECZERO(vex_state->guest_VR4 );
429   VECZERO(vex_state->guest_VR5 );
430   VECZERO(vex_state->guest_VR6 );
431   VECZERO(vex_state->guest_VR7 );
432   VECZERO(vex_state->guest_VR8 );
433   VECZERO(vex_state->guest_VR9 );
434   VECZERO(vex_state->guest_VR10);
435   VECZERO(vex_state->guest_VR11);
436   VECZERO(vex_state->guest_VR12);
437   VECZERO(vex_state->guest_VR13);
438   VECZERO(vex_state->guest_VR14);
439   VECZERO(vex_state->guest_VR15);
440   VECZERO(vex_state->guest_VR16);
441   VECZERO(vex_state->guest_VR17);
442   VECZERO(vex_state->guest_VR18);
443   VECZERO(vex_state->guest_VR19);
444   VECZERO(vex_state->guest_VR20);
445   VECZERO(vex_state->guest_VR21);
446   VECZERO(vex_state->guest_VR22);
447   VECZERO(vex_state->guest_VR23);
448   VECZERO(vex_state->guest_VR24);
449   VECZERO(vex_state->guest_VR25);
450   VECZERO(vex_state->guest_VR26);
451   VECZERO(vex_state->guest_VR27);
452   VECZERO(vex_state->guest_VR28);
453   VECZERO(vex_state->guest_VR29);
454   VECZERO(vex_state->guest_VR30);
455   VECZERO(vex_state->guest_VR31);
456
457#  undef VECZERO
458
459   vex_state->guest_CIA  = 0;
460   vex_state->guest_LR   = 0;
461   vex_state->guest_CTR  = 0;
462
463   vex_state->guest_XER_SO = 0;
464   vex_state->guest_XER_OV = 0;
465   vex_state->guest_XER_CA = 0;
466   vex_state->guest_XER_BC = 0;
467
468   vex_state->guest_CR0_321 = 0;
469   vex_state->guest_CR0_0   = 0;
470   vex_state->guest_CR1_321 = 0;
471   vex_state->guest_CR1_0   = 0;
472   vex_state->guest_CR2_321 = 0;
473   vex_state->guest_CR2_0   = 0;
474   vex_state->guest_CR3_321 = 0;
475   vex_state->guest_CR3_0   = 0;
476   vex_state->guest_CR4_321 = 0;
477   vex_state->guest_CR4_0   = 0;
478   vex_state->guest_CR5_321 = 0;
479   vex_state->guest_CR5_0   = 0;
480   vex_state->guest_CR6_321 = 0;
481   vex_state->guest_CR6_0   = 0;
482   vex_state->guest_CR7_321 = 0;
483   vex_state->guest_CR7_0   = 0;
484
485   vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST;
486
487   vex_state->guest_VRSAVE = 0;
488
489   vex_state->guest_VSCR = 0x0;  // Non-Java mode = 0
490
491   vex_state->guest_EMWARN = EmWarn_NONE;
492
493   vex_state->guest_TISTART = 0;
494   vex_state->guest_TILEN   = 0;
495
496   vex_state->guest_NRADDR = 0;
497   vex_state->guest_NRADDR_GPR2 = 0;
498
499   vex_state->guest_REDIR_SP = -1;
500   for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++)
501      vex_state->guest_REDIR_STACK[i] = 0;
502
503   vex_state->guest_IP_AT_SYSCALL = 0;
504   vex_state->guest_SPRG3_RO = 0;
505}
506
507
508/* VISIBLE TO LIBVEX CLIENT */
509void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state )
510{
511   Int i;
512   vex_state->guest_GPR0  = 0;
513   vex_state->guest_GPR1  = 0;
514   vex_state->guest_GPR2  = 0;
515   vex_state->guest_GPR3  = 0;
516   vex_state->guest_GPR4  = 0;
517   vex_state->guest_GPR5  = 0;
518   vex_state->guest_GPR6  = 0;
519   vex_state->guest_GPR7  = 0;
520   vex_state->guest_GPR8  = 0;
521   vex_state->guest_GPR9  = 0;
522   vex_state->guest_GPR10 = 0;
523   vex_state->guest_GPR11 = 0;
524   vex_state->guest_GPR12 = 0;
525   vex_state->guest_GPR13 = 0;
526   vex_state->guest_GPR14 = 0;
527   vex_state->guest_GPR15 = 0;
528   vex_state->guest_GPR16 = 0;
529   vex_state->guest_GPR17 = 0;
530   vex_state->guest_GPR18 = 0;
531   vex_state->guest_GPR19 = 0;
532   vex_state->guest_GPR20 = 0;
533   vex_state->guest_GPR21 = 0;
534   vex_state->guest_GPR22 = 0;
535   vex_state->guest_GPR23 = 0;
536   vex_state->guest_GPR24 = 0;
537   vex_state->guest_GPR25 = 0;
538   vex_state->guest_GPR26 = 0;
539   vex_state->guest_GPR27 = 0;
540   vex_state->guest_GPR28 = 0;
541   vex_state->guest_GPR29 = 0;
542   vex_state->guest_GPR30 = 0;
543   vex_state->guest_GPR31 = 0;
544
545   vex_state->guest_FPR0  = 0;
546   vex_state->guest_FPR1  = 0;
547   vex_state->guest_FPR2  = 0;
548   vex_state->guest_FPR3  = 0;
549   vex_state->guest_FPR4  = 0;
550   vex_state->guest_FPR5  = 0;
551   vex_state->guest_FPR6  = 0;
552   vex_state->guest_FPR7  = 0;
553   vex_state->guest_FPR8  = 0;
554   vex_state->guest_FPR9  = 0;
555   vex_state->guest_FPR10 = 0;
556   vex_state->guest_FPR11 = 0;
557   vex_state->guest_FPR12 = 0;
558   vex_state->guest_FPR13 = 0;
559   vex_state->guest_FPR14 = 0;
560   vex_state->guest_FPR15 = 0;
561   vex_state->guest_FPR16 = 0;
562   vex_state->guest_FPR17 = 0;
563   vex_state->guest_FPR18 = 0;
564   vex_state->guest_FPR19 = 0;
565   vex_state->guest_FPR20 = 0;
566   vex_state->guest_FPR21 = 0;
567   vex_state->guest_FPR22 = 0;
568   vex_state->guest_FPR23 = 0;
569   vex_state->guest_FPR24 = 0;
570   vex_state->guest_FPR25 = 0;
571   vex_state->guest_FPR26 = 0;
572   vex_state->guest_FPR27 = 0;
573   vex_state->guest_FPR28 = 0;
574   vex_state->guest_FPR29 = 0;
575   vex_state->guest_FPR30 = 0;
576   vex_state->guest_FPR31 = 0;
577
578   /* Initialise the vector state. */
579#  define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
580
581   VECZERO(vex_state->guest_VR0 );
582   VECZERO(vex_state->guest_VR1 );
583   VECZERO(vex_state->guest_VR2 );
584   VECZERO(vex_state->guest_VR3 );
585   VECZERO(vex_state->guest_VR4 );
586   VECZERO(vex_state->guest_VR5 );
587   VECZERO(vex_state->guest_VR6 );
588   VECZERO(vex_state->guest_VR7 );
589   VECZERO(vex_state->guest_VR8 );
590   VECZERO(vex_state->guest_VR9 );
591   VECZERO(vex_state->guest_VR10);
592   VECZERO(vex_state->guest_VR11);
593   VECZERO(vex_state->guest_VR12);
594   VECZERO(vex_state->guest_VR13);
595   VECZERO(vex_state->guest_VR14);
596   VECZERO(vex_state->guest_VR15);
597   VECZERO(vex_state->guest_VR16);
598   VECZERO(vex_state->guest_VR17);
599   VECZERO(vex_state->guest_VR18);
600   VECZERO(vex_state->guest_VR19);
601   VECZERO(vex_state->guest_VR20);
602   VECZERO(vex_state->guest_VR21);
603   VECZERO(vex_state->guest_VR22);
604   VECZERO(vex_state->guest_VR23);
605   VECZERO(vex_state->guest_VR24);
606   VECZERO(vex_state->guest_VR25);
607   VECZERO(vex_state->guest_VR26);
608   VECZERO(vex_state->guest_VR27);
609   VECZERO(vex_state->guest_VR28);
610   VECZERO(vex_state->guest_VR29);
611   VECZERO(vex_state->guest_VR30);
612   VECZERO(vex_state->guest_VR31);
613
614#  undef VECZERO
615
616   vex_state->guest_CIA  = 0;
617   vex_state->guest_LR   = 0;
618   vex_state->guest_CTR  = 0;
619
620   vex_state->guest_XER_SO = 0;
621   vex_state->guest_XER_OV = 0;
622   vex_state->guest_XER_CA = 0;
623   vex_state->guest_XER_BC = 0;
624
625   vex_state->guest_CR0_321 = 0;
626   vex_state->guest_CR0_0   = 0;
627   vex_state->guest_CR1_321 = 0;
628   vex_state->guest_CR1_0   = 0;
629   vex_state->guest_CR2_321 = 0;
630   vex_state->guest_CR2_0   = 0;
631   vex_state->guest_CR3_321 = 0;
632   vex_state->guest_CR3_0   = 0;
633   vex_state->guest_CR4_321 = 0;
634   vex_state->guest_CR4_0   = 0;
635   vex_state->guest_CR5_321 = 0;
636   vex_state->guest_CR5_0   = 0;
637   vex_state->guest_CR6_321 = 0;
638   vex_state->guest_CR6_0   = 0;
639   vex_state->guest_CR7_321 = 0;
640   vex_state->guest_CR7_0   = 0;
641
642   vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST;
643
644   vex_state->guest_VRSAVE = 0;
645
646   vex_state->guest_VSCR = 0x0;  // Non-Java mode = 0
647
648   vex_state->guest_EMWARN = EmWarn_NONE;
649
650   vex_state->padding = 0;
651
652   vex_state->guest_TISTART = 0;
653   vex_state->guest_TILEN   = 0;
654
655   vex_state->guest_NRADDR = 0;
656   vex_state->guest_NRADDR_GPR2 = 0;
657
658   vex_state->guest_REDIR_SP = -1;
659   for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
660      vex_state->guest_REDIR_STACK[i] = 0;
661
662   vex_state->guest_IP_AT_SYSCALL = 0;
663   vex_state->guest_SPRG3_RO = 0;
664
665   vex_state->padding2 = 0;
666}
667
668
669/*-----------------------------------------------------------*/
670/*--- Describing the ppc guest state, for the benefit     ---*/
671/*--- of iropt and instrumenters.                         ---*/
672/*-----------------------------------------------------------*/
673
674/* Figure out if any part of the guest state contained in minoff
675   .. maxoff requires precise memory exceptions.  If in doubt return
676   True (but this is generates significantly slower code).
677
678   By default we enforce precise exns for guest R1 (stack pointer),
679   CIA (current insn address) and LR (link register).  These are the
680   minimum needed to extract correct stack backtraces from ppc
681   code. [[NB: not sure if keeping LR up to date is actually
682   necessary.]]
683*/
684Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff,
685                                                   Int maxoff )
686{
687   Int lr_min  = offsetof(VexGuestPPC32State, guest_LR);
688   Int lr_max  = lr_min + 4 - 1;
689   Int r1_min  = offsetof(VexGuestPPC32State, guest_GPR1);
690   Int r1_max  = r1_min + 4 - 1;
691   Int cia_min = offsetof(VexGuestPPC32State, guest_CIA);
692   Int cia_max = cia_min + 4 - 1;
693
694   if (maxoff < lr_min || minoff > lr_max) {
695      /* no overlap with LR */
696   } else {
697      return True;
698   }
699
700   if (maxoff < r1_min || minoff > r1_max) {
701      /* no overlap with R1 */
702   } else {
703      return True;
704   }
705
706   if (maxoff < cia_min || minoff > cia_max) {
707      /* no overlap with CIA */
708   } else {
709      return True;
710   }
711
712   return False;
713}
714
715Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,
716                                                   Int maxoff )
717{
718   /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems
719      prudent to be conservative with it, even though thus far there
720      is no evidence to suggest that it actually needs to be kept up
721      to date wrt possible exceptions. */
722   Int lr_min  = offsetof(VexGuestPPC64State, guest_LR);
723   Int lr_max  = lr_min + 8 - 1;
724   Int r1_min  = offsetof(VexGuestPPC64State, guest_GPR1);
725   Int r1_max  = r1_min + 8 - 1;
726   Int r2_min  = offsetof(VexGuestPPC64State, guest_GPR2);
727   Int r2_max  = r2_min + 8 - 1;
728   Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
729   Int cia_max = cia_min + 8 - 1;
730
731   if (maxoff < lr_min || minoff > lr_max) {
732      /* no overlap with LR */
733   } else {
734      return True;
735   }
736
737   if (maxoff < r1_min || minoff > r1_max) {
738      /* no overlap with R1 */
739   } else {
740      return True;
741   }
742
743   if (maxoff < r2_min || minoff > r2_max) {
744      /* no overlap with R2 */
745   } else {
746      return True;
747   }
748
749   if (maxoff < cia_min || minoff > cia_max) {
750      /* no overlap with CIA */
751   } else {
752      return True;
753   }
754
755   return False;
756}
757
758
759#define ALWAYSDEFD32(field)                           \
760    { offsetof(VexGuestPPC32State, field),            \
761      (sizeof ((VexGuestPPC32State*)0)->field) }
762
763VexGuestLayout
764   ppc32Guest_layout
765      = {
766          /* Total size of the guest state, in bytes. */
767          .total_sizeB = sizeof(VexGuestPPC32State),
768
769          /* Describe the stack pointer. */
770          .offset_SP = offsetof(VexGuestPPC32State,guest_GPR1),
771          .sizeof_SP = 4,
772
773          /* Describe the frame pointer. */
774          .offset_FP = offsetof(VexGuestPPC32State,guest_GPR1),
775          .sizeof_FP = 4,
776
777          /* Describe the instruction pointer. */
778          .offset_IP = offsetof(VexGuestPPC32State,guest_CIA),
779          .sizeof_IP = 4,
780
781          /* Describe any sections to be regarded by Memcheck as
782             'always-defined'. */
783          .n_alwaysDefd = 11,
784
785          .alwaysDefd
786	  = { /*  0 */ ALWAYSDEFD32(guest_CIA),
787	      /*  1 */ ALWAYSDEFD32(guest_EMWARN),
788	      /*  2 */ ALWAYSDEFD32(guest_TISTART),
789	      /*  3 */ ALWAYSDEFD32(guest_TILEN),
790	      /*  4 */ ALWAYSDEFD32(guest_VSCR),
791	      /*  5 */ ALWAYSDEFD32(guest_FPROUND),
792              /*  6 */ ALWAYSDEFD32(guest_NRADDR),
793	      /*  7 */ ALWAYSDEFD32(guest_NRADDR_GPR2),
794	      /*  8 */ ALWAYSDEFD32(guest_REDIR_SP),
795	      /*  9 */ ALWAYSDEFD32(guest_REDIR_STACK),
796	      /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL)
797            }
798        };
799
800#define ALWAYSDEFD64(field)                           \
801    { offsetof(VexGuestPPC64State, field),            \
802      (sizeof ((VexGuestPPC64State*)0)->field) }
803
804VexGuestLayout
805   ppc64Guest_layout
806      = {
807          /* Total size of the guest state, in bytes. */
808          .total_sizeB = sizeof(VexGuestPPC64State),
809
810          /* Describe the stack pointer. */
811          .offset_SP = offsetof(VexGuestPPC64State,guest_GPR1),
812          .sizeof_SP = 8,
813
814          /* Describe the frame pointer. */
815          .offset_FP = offsetof(VexGuestPPC64State,guest_GPR1),
816          .sizeof_FP = 8,
817
818          /* Describe the instruction pointer. */
819          .offset_IP = offsetof(VexGuestPPC64State,guest_CIA),
820          .sizeof_IP = 8,
821
822          /* Describe any sections to be regarded by Memcheck as
823             'always-defined'. */
824          .n_alwaysDefd = 11,
825
826          .alwaysDefd
827	  = { /*  0 */ ALWAYSDEFD64(guest_CIA),
828	      /*  1 */ ALWAYSDEFD64(guest_EMWARN),
829	      /*  2 */ ALWAYSDEFD64(guest_TISTART),
830	      /*  3 */ ALWAYSDEFD64(guest_TILEN),
831	      /*  4 */ ALWAYSDEFD64(guest_VSCR),
832	      /*  5 */ ALWAYSDEFD64(guest_FPROUND),
833	      /*  6 */ ALWAYSDEFD64(guest_NRADDR),
834	      /*  7 */ ALWAYSDEFD64(guest_NRADDR_GPR2),
835	      /*  8 */ ALWAYSDEFD64(guest_REDIR_SP),
836	      /*  9 */ ALWAYSDEFD64(guest_REDIR_STACK),
837	      /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL)
838            }
839        };
840
841/*---------------------------------------------------------------*/
842/*--- end                                 guest_ppc_helpers.c ---*/
843/*---------------------------------------------------------------*/
844