]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_ppc_helpers.c
d3b046dfc9e6fc03d910d21d9d456299f82ad5bc
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / VEX / priv / guest_ppc_helpers.c
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. */
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) */
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) */
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) */
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) */
154 void ppc64g_dirtyhelper_LVS ( VexGuestPPC64State* gst,
155                               UInt vD_off, UInt sh, UInt shift_right )
156 {
157   static
158   UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
159                     0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
160                     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
161                     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
162   U128* pU128_src;
163   U128* pU128_dst;
164
165   vassert( vD_off       <= sizeof(VexGuestPPC64State)-8 );
166   vassert( sh           <= 15 );
167   vassert( shift_right  <=  1 );
168   if (shift_right)
169      sh = 16-sh;
170   /* else shift left  */
171
172   pU128_src = (U128*)&ref[sh];
173   pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
174
175   (*pU128_dst)[0] = (*pU128_src)[0];
176   (*pU128_dst)[1] = (*pU128_src)[1];
177   (*pU128_dst)[2] = (*pU128_src)[2];
178   (*pU128_dst)[3] = (*pU128_src)[3];
179 }
180
181
182 /* Helper-function specialiser. */
183
184 IRExpr* guest_ppc32_spechelper ( HChar* function_name,
185                                  IRExpr** args )
186 {
187    return NULL;
188 }
189
190 IRExpr* guest_ppc64_spechelper ( HChar* function_name,
191                                  IRExpr** args )
192 {
193    return NULL;
194 }
195
196
197 /*----------------------------------------------*/
198 /*--- The exported fns ..                    ---*/
199 /*----------------------------------------------*/
200
201 /* VISIBLE TO LIBVEX CLIENT */
202 UInt LibVEX_GuestPPC32_get_CR ( /*IN*/VexGuestPPC32State* vex_state )
203 {
204 #  define FIELD(_n)                                    \
205       ( ( (UInt)                                       \
206            ( (vex_state->guest_CR##_n##_321 & (7<<1))  \
207              | (vex_state->guest_CR##_n##_0 & 1)       \
208            )                                           \
209         )                                              \
210         << (4 * (7-(_n)))                              \
211       )
212
213    return 
214       FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
215       | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
216
217 #  undef FIELD
218 }
219
220
221 /* VISIBLE TO LIBVEX CLIENT */
222 /* Note: %CR is 32 bits even for ppc64 */
223 UInt LibVEX_GuestPPC64_get_CR ( /*IN*/VexGuestPPC64State* vex_state )
224 {
225 #  define FIELD(_n)                                    \
226       ( ( (UInt)                                       \
227            ( (vex_state->guest_CR##_n##_321 & (7<<1))  \
228              | (vex_state->guest_CR##_n##_0 & 1)       \
229            )                                           \
230         )                                              \
231         << (4 * (7-(_n)))                              \
232       )
233
234    return 
235       FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
236       | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
237
238 #  undef FIELD
239 }
240
241
242 /* VISIBLE TO LIBVEX CLIENT */
243 void LibVEX_GuestPPC32_put_CR ( UInt cr_native,
244                                 /*OUT*/VexGuestPPC32State* vex_state )
245 {
246    UInt t;
247
248 #  define FIELD(_n)                                           \
249       do {                                                    \
250          t = cr_native >> (4*(7-(_n)));                       \
251          vex_state->guest_CR##_n##_0 = toUChar(t & 1);        \
252          vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
253       } while (0)
254
255    FIELD(0);
256    FIELD(1);
257    FIELD(2);
258    FIELD(3);
259    FIELD(4);
260    FIELD(5);
261    FIELD(6);
262    FIELD(7);
263
264 #  undef FIELD
265 }
266
267
268 /* VISIBLE TO LIBVEX CLIENT */
269 /* Note: %CR is 32 bits even for ppc64 */
270 void LibVEX_GuestPPC64_put_CR ( UInt cr_native,
271                                 /*OUT*/VexGuestPPC64State* vex_state )
272 {
273    UInt t;
274
275 #  define FIELD(_n)                                           \
276       do {                                                    \
277          t = cr_native >> (4*(7-(_n)));                       \
278          vex_state->guest_CR##_n##_0 = toUChar(t & 1);        \
279          vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
280       } while (0)
281
282    FIELD(0);
283    FIELD(1);
284    FIELD(2);
285    FIELD(3);
286    FIELD(4);
287    FIELD(5);
288    FIELD(6);
289    FIELD(7);
290
291 #  undef FIELD
292 }
293
294
295 /* VISIBLE TO LIBVEX CLIENT */
296 UInt LibVEX_GuestPPC32_get_XER ( /*IN*/VexGuestPPC32State* vex_state )
297 {
298    UInt w = 0;
299    w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
300    w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
301    w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
302    w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
303    return w;
304 }
305
306
307 /* VISIBLE TO LIBVEX CLIENT */
308 /* Note: %XER is 32 bits even for ppc64 */
309 UInt LibVEX_GuestPPC64_get_XER ( /*IN*/VexGuestPPC64State* vex_state )
310 {
311    UInt w = 0;
312    w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
313    w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
314    w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
315    w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
316    return w;
317 }
318
319
320 /* VISIBLE TO LIBVEX CLIENT */
321 void LibVEX_GuestPPC32_put_XER ( UInt xer_native,
322                                  /*OUT*/VexGuestPPC32State* vex_state )
323 {
324    vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
325    vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
326    vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
327    vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
328 }
329
330 /* VISIBLE TO LIBVEX CLIENT */
331 /* Note: %XER is 32 bits even for ppc64 */
332 void LibVEX_GuestPPC64_put_XER ( UInt xer_native,
333                                  /*OUT*/VexGuestPPC64State* vex_state )
334 {
335    vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
336    vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
337    vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
338    vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
339 }
340
341 /* VISIBLE TO LIBVEX CLIENT */
342 void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state )
343 {
344    Int i;
345    vex_state->guest_GPR0  = 0;
346    vex_state->guest_GPR1  = 0;
347    vex_state->guest_GPR2  = 0;
348    vex_state->guest_GPR3  = 0;
349    vex_state->guest_GPR4  = 0;
350    vex_state->guest_GPR5  = 0;
351    vex_state->guest_GPR6  = 0;
352    vex_state->guest_GPR7  = 0;
353    vex_state->guest_GPR8  = 0;
354    vex_state->guest_GPR9  = 0;
355    vex_state->guest_GPR10 = 0;
356    vex_state->guest_GPR11 = 0;
357    vex_state->guest_GPR12 = 0;
358    vex_state->guest_GPR13 = 0;
359    vex_state->guest_GPR14 = 0;
360    vex_state->guest_GPR15 = 0;
361    vex_state->guest_GPR16 = 0;
362    vex_state->guest_GPR17 = 0;
363    vex_state->guest_GPR18 = 0;
364    vex_state->guest_GPR19 = 0;
365    vex_state->guest_GPR20 = 0;
366    vex_state->guest_GPR21 = 0;
367    vex_state->guest_GPR22 = 0;
368    vex_state->guest_GPR23 = 0;
369    vex_state->guest_GPR24 = 0;
370    vex_state->guest_GPR25 = 0;
371    vex_state->guest_GPR26 = 0;
372    vex_state->guest_GPR27 = 0;
373    vex_state->guest_GPR28 = 0;
374    vex_state->guest_GPR29 = 0;
375    vex_state->guest_GPR30 = 0;
376    vex_state->guest_GPR31 = 0;
377
378    vex_state->guest_FPR0  = 0;
379    vex_state->guest_FPR1  = 0;
380    vex_state->guest_FPR2  = 0;
381    vex_state->guest_FPR3  = 0;
382    vex_state->guest_FPR4  = 0;
383    vex_state->guest_FPR5  = 0;
384    vex_state->guest_FPR6  = 0;
385    vex_state->guest_FPR7  = 0;
386    vex_state->guest_FPR8  = 0;
387    vex_state->guest_FPR9  = 0;
388    vex_state->guest_FPR10 = 0;
389    vex_state->guest_FPR11 = 0;
390    vex_state->guest_FPR12 = 0;
391    vex_state->guest_FPR13 = 0;
392    vex_state->guest_FPR14 = 0;
393    vex_state->guest_FPR15 = 0;
394    vex_state->guest_FPR16 = 0;
395    vex_state->guest_FPR17 = 0;
396    vex_state->guest_FPR18 = 0;
397    vex_state->guest_FPR19 = 0;
398    vex_state->guest_FPR20 = 0;
399    vex_state->guest_FPR21 = 0;
400    vex_state->guest_FPR22 = 0;
401    vex_state->guest_FPR23 = 0;
402    vex_state->guest_FPR24 = 0;
403    vex_state->guest_FPR25 = 0;
404    vex_state->guest_FPR26 = 0;
405    vex_state->guest_FPR27 = 0;
406    vex_state->guest_FPR28 = 0;
407    vex_state->guest_FPR29 = 0;
408    vex_state->guest_FPR30 = 0;
409    vex_state->guest_FPR31 = 0;
410
411    /* Initialise the vector state. */
412 #  define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
413
414    VECZERO(vex_state->guest_VR0 );
415    VECZERO(vex_state->guest_VR1 );
416    VECZERO(vex_state->guest_VR2 );
417    VECZERO(vex_state->guest_VR3 );
418    VECZERO(vex_state->guest_VR4 );
419    VECZERO(vex_state->guest_VR5 );
420    VECZERO(vex_state->guest_VR6 );
421    VECZERO(vex_state->guest_VR7 );
422    VECZERO(vex_state->guest_VR8 );
423    VECZERO(vex_state->guest_VR9 );
424    VECZERO(vex_state->guest_VR10);
425    VECZERO(vex_state->guest_VR11);
426    VECZERO(vex_state->guest_VR12);
427    VECZERO(vex_state->guest_VR13);
428    VECZERO(vex_state->guest_VR14);
429    VECZERO(vex_state->guest_VR15);
430    VECZERO(vex_state->guest_VR16);
431    VECZERO(vex_state->guest_VR17);
432    VECZERO(vex_state->guest_VR18);
433    VECZERO(vex_state->guest_VR19);
434    VECZERO(vex_state->guest_VR20);
435    VECZERO(vex_state->guest_VR21);
436    VECZERO(vex_state->guest_VR22);
437    VECZERO(vex_state->guest_VR23);
438    VECZERO(vex_state->guest_VR24);
439    VECZERO(vex_state->guest_VR25);
440    VECZERO(vex_state->guest_VR26);
441    VECZERO(vex_state->guest_VR27);
442    VECZERO(vex_state->guest_VR28);
443    VECZERO(vex_state->guest_VR29);
444    VECZERO(vex_state->guest_VR30);
445    VECZERO(vex_state->guest_VR31);
446
447 #  undef VECZERO
448
449    vex_state->guest_CIA  = 0;
450    vex_state->guest_LR   = 0;
451    vex_state->guest_CTR  = 0;
452
453    vex_state->guest_XER_SO = 0;
454    vex_state->guest_XER_OV = 0;
455    vex_state->guest_XER_CA = 0;
456    vex_state->guest_XER_BC = 0;
457
458    vex_state->guest_CR0_321 = 0;
459    vex_state->guest_CR0_0   = 0;
460    vex_state->guest_CR1_321 = 0;
461    vex_state->guest_CR1_0   = 0;
462    vex_state->guest_CR2_321 = 0;
463    vex_state->guest_CR2_0   = 0;
464    vex_state->guest_CR3_321 = 0;
465    vex_state->guest_CR3_0   = 0;
466    vex_state->guest_CR4_321 = 0;
467    vex_state->guest_CR4_0   = 0;
468    vex_state->guest_CR5_321 = 0;
469    vex_state->guest_CR5_0   = 0;
470    vex_state->guest_CR6_321 = 0;
471    vex_state->guest_CR6_0   = 0;
472    vex_state->guest_CR7_321 = 0;
473    vex_state->guest_CR7_0   = 0;
474
475    vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST;
476
477    vex_state->guest_VRSAVE = 0;
478
479    vex_state->guest_VSCR = 0x0;  // Non-Java mode = 0
480
481    vex_state->guest_EMWARN = EmWarn_NONE;
482
483    vex_state->guest_TISTART = 0;
484    vex_state->guest_TILEN   = 0;
485
486    vex_state->guest_NRADDR = 0;
487    vex_state->guest_NRADDR_GPR2 = 0;
488
489    vex_state->guest_REDIR_SP = -1;
490    for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++)
491       vex_state->guest_REDIR_STACK[i] = 0;
492
493    vex_state->guest_IP_AT_SYSCALL = 0;
494    vex_state->guest_SPRG3_RO = 0;
495 }
496
497
498 /* VISIBLE TO LIBVEX CLIENT */
499 void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state )
500 {
501    Int i;
502    vex_state->guest_GPR0  = 0;
503    vex_state->guest_GPR1  = 0;
504    vex_state->guest_GPR2  = 0;
505    vex_state->guest_GPR3  = 0;
506    vex_state->guest_GPR4  = 0;
507    vex_state->guest_GPR5  = 0;
508    vex_state->guest_GPR6  = 0;
509    vex_state->guest_GPR7  = 0;
510    vex_state->guest_GPR8  = 0;
511    vex_state->guest_GPR9  = 0;
512    vex_state->guest_GPR10 = 0;
513    vex_state->guest_GPR11 = 0;
514    vex_state->guest_GPR12 = 0;
515    vex_state->guest_GPR13 = 0;
516    vex_state->guest_GPR14 = 0;
517    vex_state->guest_GPR15 = 0;
518    vex_state->guest_GPR16 = 0;
519    vex_state->guest_GPR17 = 0;
520    vex_state->guest_GPR18 = 0;
521    vex_state->guest_GPR19 = 0;
522    vex_state->guest_GPR20 = 0;
523    vex_state->guest_GPR21 = 0;
524    vex_state->guest_GPR22 = 0;
525    vex_state->guest_GPR23 = 0;
526    vex_state->guest_GPR24 = 0;
527    vex_state->guest_GPR25 = 0;
528    vex_state->guest_GPR26 = 0;
529    vex_state->guest_GPR27 = 0;
530    vex_state->guest_GPR28 = 0;
531    vex_state->guest_GPR29 = 0;
532    vex_state->guest_GPR30 = 0;
533    vex_state->guest_GPR31 = 0;
534
535    vex_state->guest_FPR0  = 0;
536    vex_state->guest_FPR1  = 0;
537    vex_state->guest_FPR2  = 0;
538    vex_state->guest_FPR3  = 0;
539    vex_state->guest_FPR4  = 0;
540    vex_state->guest_FPR5  = 0;
541    vex_state->guest_FPR6  = 0;
542    vex_state->guest_FPR7  = 0;
543    vex_state->guest_FPR8  = 0;
544    vex_state->guest_FPR9  = 0;
545    vex_state->guest_FPR10 = 0;
546    vex_state->guest_FPR11 = 0;
547    vex_state->guest_FPR12 = 0;
548    vex_state->guest_FPR13 = 0;
549    vex_state->guest_FPR14 = 0;
550    vex_state->guest_FPR15 = 0;
551    vex_state->guest_FPR16 = 0;
552    vex_state->guest_FPR17 = 0;
553    vex_state->guest_FPR18 = 0;
554    vex_state->guest_FPR19 = 0;
555    vex_state->guest_FPR20 = 0;
556    vex_state->guest_FPR21 = 0;
557    vex_state->guest_FPR22 = 0;
558    vex_state->guest_FPR23 = 0;
559    vex_state->guest_FPR24 = 0;
560    vex_state->guest_FPR25 = 0;
561    vex_state->guest_FPR26 = 0;
562    vex_state->guest_FPR27 = 0;
563    vex_state->guest_FPR28 = 0;
564    vex_state->guest_FPR29 = 0;
565    vex_state->guest_FPR30 = 0;
566    vex_state->guest_FPR31 = 0;
567
568    /* Initialise the vector state. */
569 #  define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
570
571    VECZERO(vex_state->guest_VR0 );
572    VECZERO(vex_state->guest_VR1 );
573    VECZERO(vex_state->guest_VR2 );
574    VECZERO(vex_state->guest_VR3 );
575    VECZERO(vex_state->guest_VR4 );
576    VECZERO(vex_state->guest_VR5 );
577    VECZERO(vex_state->guest_VR6 );
578    VECZERO(vex_state->guest_VR7 );
579    VECZERO(vex_state->guest_VR8 );
580    VECZERO(vex_state->guest_VR9 );
581    VECZERO(vex_state->guest_VR10);
582    VECZERO(vex_state->guest_VR11);
583    VECZERO(vex_state->guest_VR12);
584    VECZERO(vex_state->guest_VR13);
585    VECZERO(vex_state->guest_VR14);
586    VECZERO(vex_state->guest_VR15);
587    VECZERO(vex_state->guest_VR16);
588    VECZERO(vex_state->guest_VR17);
589    VECZERO(vex_state->guest_VR18);
590    VECZERO(vex_state->guest_VR19);
591    VECZERO(vex_state->guest_VR20);
592    VECZERO(vex_state->guest_VR21);
593    VECZERO(vex_state->guest_VR22);
594    VECZERO(vex_state->guest_VR23);
595    VECZERO(vex_state->guest_VR24);
596    VECZERO(vex_state->guest_VR25);
597    VECZERO(vex_state->guest_VR26);
598    VECZERO(vex_state->guest_VR27);
599    VECZERO(vex_state->guest_VR28);
600    VECZERO(vex_state->guest_VR29);
601    VECZERO(vex_state->guest_VR30);
602    VECZERO(vex_state->guest_VR31);
603
604 #  undef VECZERO
605
606    vex_state->guest_CIA  = 0;
607    vex_state->guest_LR   = 0;
608    vex_state->guest_CTR  = 0;
609
610    vex_state->guest_XER_SO = 0;
611    vex_state->guest_XER_OV = 0;
612    vex_state->guest_XER_CA = 0;
613    vex_state->guest_XER_BC = 0;
614
615    vex_state->guest_CR0_321 = 0;
616    vex_state->guest_CR0_0   = 0;
617    vex_state->guest_CR1_321 = 0;
618    vex_state->guest_CR1_0   = 0;
619    vex_state->guest_CR2_321 = 0;
620    vex_state->guest_CR2_0   = 0;
621    vex_state->guest_CR3_321 = 0;
622    vex_state->guest_CR3_0   = 0;
623    vex_state->guest_CR4_321 = 0;
624    vex_state->guest_CR4_0   = 0;
625    vex_state->guest_CR5_321 = 0;
626    vex_state->guest_CR5_0   = 0;
627    vex_state->guest_CR6_321 = 0;
628    vex_state->guest_CR6_0   = 0;
629    vex_state->guest_CR7_321 = 0;
630    vex_state->guest_CR7_0   = 0;
631
632    vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST;
633
634    vex_state->guest_VRSAVE = 0;
635
636    vex_state->guest_VSCR = 0x0;  // Non-Java mode = 0
637
638    vex_state->guest_EMWARN = EmWarn_NONE;
639
640    vex_state->padding = 0;
641
642    vex_state->guest_TISTART = 0;
643    vex_state->guest_TILEN   = 0;
644
645    vex_state->guest_NRADDR = 0;
646    vex_state->guest_NRADDR_GPR2 = 0;
647
648    vex_state->guest_REDIR_SP = -1;
649    for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
650       vex_state->guest_REDIR_STACK[i] = 0;
651
652    vex_state->guest_IP_AT_SYSCALL = 0;
653    vex_state->guest_SPRG3_RO = 0;
654
655    vex_state->padding2 = 0;
656 }
657
658
659 /*-----------------------------------------------------------*/
660 /*--- Describing the ppc guest state, for the benefit     ---*/
661 /*--- of iropt and instrumenters.                         ---*/
662 /*-----------------------------------------------------------*/
663
664 /* Figure out if any part of the guest state contained in minoff
665    .. maxoff requires precise memory exceptions.  If in doubt return
666    True (but this is generates significantly slower code).  
667
668    By default we enforce precise exns for guest R1 (stack pointer),
669    CIA (current insn address) and LR (link register).  These are the
670    minimum needed to extract correct stack backtraces from ppc
671    code. [[NB: not sure if keeping LR up to date is actually
672    necessary.]]
673 */
674 Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff, 
675                                                    Int maxoff )
676 {
677    Int lr_min  = offsetof(VexGuestPPC32State, guest_LR);
678    Int lr_max  = lr_min + 4 - 1;
679    Int r1_min  = offsetof(VexGuestPPC32State, guest_GPR1);
680    Int r1_max  = r1_min + 4 - 1;
681    Int cia_min = offsetof(VexGuestPPC32State, guest_CIA);
682    Int cia_max = cia_min + 4 - 1;
683
684    if (maxoff < lr_min || minoff > lr_max) {
685       /* no overlap with LR */
686    } else {
687       return True;
688    }
689
690    if (maxoff < r1_min || minoff > r1_max) {
691       /* no overlap with R1 */
692    } else {
693       return True;
694    }
695
696    if (maxoff < cia_min || minoff > cia_max) {
697       /* no overlap with CIA */
698    } else {
699       return True;
700    }
701
702    return False;
703 }
704
705 Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff, 
706                                                    Int maxoff )
707 {
708    /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems
709       prudent to be conservative with it, even though thus far there
710       is no evidence to suggest that it actually needs to be kept up
711       to date wrt possible exceptions. */
712    Int lr_min  = offsetof(VexGuestPPC64State, guest_LR);
713    Int lr_max  = lr_min + 8 - 1;
714    Int r1_min  = offsetof(VexGuestPPC64State, guest_GPR1);
715    Int r1_max  = r1_min + 8 - 1;
716    Int r2_min  = offsetof(VexGuestPPC64State, guest_GPR2);
717    Int r2_max  = r2_min + 8 - 1;
718    Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
719    Int cia_max = cia_min + 8 - 1;
720
721    if (maxoff < lr_min || minoff > lr_max) {
722       /* no overlap with LR */
723    } else {
724       return True;
725    }
726
727    if (maxoff < r1_min || minoff > r1_max) {
728       /* no overlap with R1 */
729    } else {
730       return True;
731    }
732
733    if (maxoff < r2_min || minoff > r2_max) {
734       /* no overlap with R2 */
735    } else {
736       return True;
737    }
738
739    if (maxoff < cia_min || minoff > cia_max) {
740       /* no overlap with CIA */
741    } else {
742       return True;
743    }
744
745    return False;
746 }
747
748
749 #define ALWAYSDEFD32(field)                           \
750     { offsetof(VexGuestPPC32State, field),            \
751       (sizeof ((VexGuestPPC32State*)0)->field) }
752
753 VexGuestLayout
754    ppc32Guest_layout 
755       = { 
756           /* Total size of the guest state, in bytes. */
757           .total_sizeB = sizeof(VexGuestPPC32State),
758
759           /* Describe the stack pointer. */
760           .offset_SP = offsetof(VexGuestPPC32State,guest_GPR1),
761           .sizeof_SP = 4,
762
763           /* Describe the frame pointer. */
764           .offset_FP = offsetof(VexGuestPPC32State,guest_GPR1),
765           .sizeof_FP = 4,
766
767           /* Describe the instruction pointer. */
768           .offset_IP = offsetof(VexGuestPPC32State,guest_CIA),
769           .sizeof_IP = 4,
770
771           /* Describe any sections to be regarded by Memcheck as
772              'always-defined'. */
773           .n_alwaysDefd = 11,
774
775           .alwaysDefd 
776           = { /*  0 */ ALWAYSDEFD32(guest_CIA),
777               /*  1 */ ALWAYSDEFD32(guest_EMWARN),
778               /*  2 */ ALWAYSDEFD32(guest_TISTART),
779               /*  3 */ ALWAYSDEFD32(guest_TILEN),
780               /*  4 */ ALWAYSDEFD32(guest_VSCR),
781               /*  5 */ ALWAYSDEFD32(guest_FPROUND),
782               /*  6 */ ALWAYSDEFD32(guest_NRADDR),
783               /*  7 */ ALWAYSDEFD32(guest_NRADDR_GPR2),
784               /*  8 */ ALWAYSDEFD32(guest_REDIR_SP),
785               /*  9 */ ALWAYSDEFD32(guest_REDIR_STACK),
786               /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL)
787             }
788         };
789
790 #define ALWAYSDEFD64(field)                           \
791     { offsetof(VexGuestPPC64State, field),            \
792       (sizeof ((VexGuestPPC64State*)0)->field) }
793
794 VexGuestLayout
795    ppc64Guest_layout 
796       = { 
797           /* Total size of the guest state, in bytes. */
798           .total_sizeB = sizeof(VexGuestPPC64State),
799
800           /* Describe the stack pointer. */
801           .offset_SP = offsetof(VexGuestPPC64State,guest_GPR1),
802           .sizeof_SP = 8,
803
804           /* Describe the frame pointer. */
805           .offset_FP = offsetof(VexGuestPPC64State,guest_GPR1),
806           .sizeof_FP = 8,
807
808           /* Describe the instruction pointer. */
809           .offset_IP = offsetof(VexGuestPPC64State,guest_CIA),
810           .sizeof_IP = 8,
811
812           /* Describe any sections to be regarded by Memcheck as
813              'always-defined'. */
814           .n_alwaysDefd = 11,
815
816           .alwaysDefd 
817           = { /*  0 */ ALWAYSDEFD64(guest_CIA),
818               /*  1 */ ALWAYSDEFD64(guest_EMWARN),
819               /*  2 */ ALWAYSDEFD64(guest_TISTART),
820               /*  3 */ ALWAYSDEFD64(guest_TILEN),
821               /*  4 */ ALWAYSDEFD64(guest_VSCR),
822               /*  5 */ ALWAYSDEFD64(guest_FPROUND),
823               /*  6 */ ALWAYSDEFD64(guest_NRADDR),
824               /*  7 */ ALWAYSDEFD64(guest_NRADDR_GPR2),
825               /*  8 */ ALWAYSDEFD64(guest_REDIR_SP),
826               /*  9 */ ALWAYSDEFD64(guest_REDIR_STACK),
827               /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL)
828             }
829         };
830
831 /*---------------------------------------------------------------*/
832 /*--- end                                 guest_ppc_helpers.c ---*/
833 /*---------------------------------------------------------------*/