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