blob: ca8f5bf21e4a979d020208bbae83600a39527048 [file] [log] [blame]
cerion85665ca2005-06-20 15:51:07 +00001
sewardj5d3a1c92005-12-15 21:40:34 +00002/*--------------------------------------------------------------------*/
3/*--- The core dispatch loop, for jumping to a code address. ---*/
sewardj0ddf76c2006-10-17 02:08:26 +00004/*--- dispatch-ppc32-linux.S ---*/
sewardj5d3a1c92005-12-15 21:40:34 +00005/*--------------------------------------------------------------------*/
cerion85665ca2005-06-20 15:51:07 +00006
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
sewardj4d474d02008-02-11 11:34:59 +000011 Copyright (C) 2005-2008 Cerion Armour-Brown <cerion@open-works.co.uk>
cerion85665ca2005-06-20 15:51:07 +000012
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., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
sewardj45f4e7c2005-09-27 19:20:21 +000031#include "pub_core_basics_asm.h"
cerion85665ca2005-06-20 15:51:07 +000032#include "pub_core_dispatch_asm.h"
33#include "pub_core_transtab_asm.h"
34#include "libvex_guest_offsets.h" /* for OFFSET_ppc32_CIA */
35
36
37/*------------------------------------------------------------*/
sewardja591a052006-01-12 14:04:46 +000038/*--- ---*/
39/*--- The dispatch loop. VG_(run_innerloop) is used to ---*/
40/*--- run all translations except no-redir ones. ---*/
41/*--- ---*/
cerion85665ca2005-06-20 15:51:07 +000042/*------------------------------------------------------------*/
43
sewardj5d3a1c92005-12-15 21:40:34 +000044/*----------------------------------------------------*/
45/*--- Preamble (set everything up) ---*/
46/*----------------------------------------------------*/
cerion85665ca2005-06-20 15:51:07 +000047
sewardj5d3a1c92005-12-15 21:40:34 +000048/* signature:
49UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
50*/
51.text
52.globl VG_(run_innerloop)
tom63c8de52006-05-01 09:28:39 +000053.type VG_(run_innerloop), @function
cerion85665ca2005-06-20 15:51:07 +000054VG_(run_innerloop):
sewardj5d3a1c92005-12-15 21:40:34 +000055 /* r3 holds guest_state */
56 /* r4 holds do_profiling */
cerion85665ca2005-06-20 15:51:07 +000057
sewardj5d3a1c92005-12-15 21:40:34 +000058 /* ----- entry point to VG_(run_innerloop) ----- */
cerion51ce7912005-11-11 01:00:36 +000059 /* For Linux/ppc32 we need the SysV ABI, which uses
60 LR->4(parent_sp), CR->anywhere.
cerion1ade6972005-12-20 20:48:50 +000061 (The AIX ABI, used on Darwin,
cerion51ce7912005-11-11 01:00:36 +000062 uses LR->8(prt_sp), CR->4(prt_sp))
63 */
64
cerion3e357562005-11-09 14:13:08 +000065 /* Save lr */
cerion85665ca2005-06-20 15:51:07 +000066 mflr 0
67 stw 0,4(1)
68
cerione51a42c2005-11-08 22:03:07 +000069 /* New stack frame */
cerion3e357562005-11-09 14:13:08 +000070 stwu 1,-496(1) /* sp should maintain 16-byte alignment */
cerione51a42c2005-11-08 22:03:07 +000071
cerion3e357562005-11-09 14:13:08 +000072 /* Save callee-saved registers... */
sewardj5d3a1c92005-12-15 21:40:34 +000073 /* r3, r4 are live here, so use r5 */
74 lis 5,VG_(machine_ppc32_has_FP)@ha
75 lwz 5,VG_(machine_ppc32_has_FP)@l(5)
76 cmplwi 5,0
sewardj2c36d422005-11-13 01:59:22 +000077 beq LafterFP1
cerione51a42c2005-11-08 22:03:07 +000078
cerion3e357562005-11-09 14:13:08 +000079 /* Floating-point reg save area : 144 bytes */
80 stfd 31,488(1)
81 stfd 30,480(1)
82 stfd 29,472(1)
83 stfd 28,464(1)
84 stfd 27,456(1)
85 stfd 26,448(1)
86 stfd 25,440(1)
87 stfd 24,432(1)
88 stfd 23,424(1)
89 stfd 22,416(1)
90 stfd 21,408(1)
91 stfd 20,400(1)
92 stfd 19,392(1)
93 stfd 18,384(1)
94 stfd 17,376(1)
95 stfd 16,368(1)
96 stfd 15,360(1)
97 stfd 14,352(1)
sewardj2c36d422005-11-13 01:59:22 +000098LafterFP1:
cerione51a42c2005-11-08 22:03:07 +000099
cerion3e357562005-11-09 14:13:08 +0000100 /* General reg save area : 72 bytes */
101 stw 31,348(1)
102 stw 30,344(1)
103 stw 29,340(1)
104 stw 28,336(1)
105 stw 27,332(1)
106 stw 26,328(1)
107 stw 25,324(1)
108 stw 24,320(1)
109 stw 23,316(1)
110 stw 22,312(1)
111 stw 21,308(1)
112 stw 20,304(1)
113 stw 19,300(1)
114 stw 18,296(1)
115 stw 17,292(1)
116 stw 16,288(1)
117 stw 15,284(1)
118 stw 14,280(1)
cerion51ce7912005-11-11 01:00:36 +0000119 /* Probably not necessary to save r13 (thread-specific ptr),
120 as VEX stays clear of it... but what the hey. */
cerion3e357562005-11-09 14:13:08 +0000121 stw 13,276(1)
122
cerion51ce7912005-11-11 01:00:36 +0000123 /* It's necessary to save/restore VRSAVE in the AIX / Darwin ABI.
124 The Linux kernel might not actually use VRSAVE for its intended
125 purpose, but it should be harmless to preserve anyway. */
cerion1ade6972005-12-20 20:48:50 +0000126 /* r3, r4 are live here, so use r5 */
sewardj5d3a1c92005-12-15 21:40:34 +0000127 lis 5,VG_(machine_ppc32_has_VMX)@ha
128 lwz 5,VG_(machine_ppc32_has_VMX)@l(5)
129 cmplwi 5,0
sewardj2c36d422005-11-13 01:59:22 +0000130 beq LafterVMX1
cerion51ce7912005-11-11 01:00:36 +0000131
cerion3e357562005-11-09 14:13:08 +0000132 /* VRSAVE save word : 32 bytes */
sewardj5d3a1c92005-12-15 21:40:34 +0000133 mfspr 5,256 /* vrsave reg is spr number 256 */
134 stw 5,244(1)
cerion3e357562005-11-09 14:13:08 +0000135
136 /* Alignment padding : 4 bytes */
137
138 /* Vector reg save area (quadword aligned) : 192 bytes */
sewardj5d3a1c92005-12-15 21:40:34 +0000139 li 5,224
140 stvx 31,5,1
141 li 5,208
142 stvx 30,5,1
143 li 5,192
144 stvx 29,5,1
145 li 5,176
146 stvx 28,5,1
147 li 5,160
148 stvx 27,5,1
149 li 5,144
150 stvx 26,5,1
151 li 5,128
152 stvx 25,5,1
153 li 5,112
154 stvx 25,5,1
155 li 5,96
156 stvx 23,5,1
157 li 5,80
158 stvx 22,5,1
159 li 5,64
160 stvx 21,5,1
161 li 5,48
162 stvx 20,5,1
sewardj2c36d422005-11-13 01:59:22 +0000163LafterVMX1:
cerion85665ca2005-06-20 15:51:07 +0000164
cerion3e357562005-11-09 14:13:08 +0000165 /* Save cr */
166 mfcr 0
cerion3d11e0e2005-11-16 20:22:11 +0000167 stw 0,44(1)
cerion3e357562005-11-09 14:13:08 +0000168
cerion51ce7912005-11-11 01:00:36 +0000169 /* Local variable space... */
170
cerion3d11e0e2005-11-16 20:22:11 +0000171 /* 32(sp) used later to check FPSCR[RM] */
172
cerion85665ca2005-06-20 15:51:07 +0000173 /* r3 holds guest_state */
sewardj5d3a1c92005-12-15 21:40:34 +0000174 /* r4 holds do_profiling */
175 mr 31,3 /* r31 (generated code gsp) = r3 */
176 stw 3,28(1) /* spill orig guest_state ptr */
cerion85665ca2005-06-20 15:51:07 +0000177
cerion3e357562005-11-09 14:13:08 +0000178 /* 24(sp) used later to stop ctr reg being clobbered */
ceriona5422db2005-12-01 19:05:41 +0000179 /* 20(sp) used later to load fpscr with zero */
180 /* 8:16(sp) free */
cerion1b6b2b32005-11-18 20:45:18 +0000181
cerion3e357562005-11-09 14:13:08 +0000182 /* Linkage Area (reserved)
cerion1b6b2b32005-11-18 20:45:18 +0000183 4(sp) : LR
cerion3e357562005-11-09 14:13:08 +0000184 0(sp) : back-chain
cerione51a42c2005-11-08 22:03:07 +0000185 */
186
sewardj5d3a1c92005-12-15 21:40:34 +0000187 /* CAB TODO: Use a caller-saved reg for orig guest_state ptr
188 - rem to set non-allocateable in isel.c */
cerion85665ca2005-06-20 15:51:07 +0000189
sewardj5ee49482005-12-16 01:08:22 +0000190 /* hold dispatch_ctr in r29 */
sewardj5d3a1c92005-12-15 21:40:34 +0000191 lis 5,VG_(dispatch_ctr)@ha
sewardj5ee49482005-12-16 01:08:22 +0000192 lwz 29,VG_(dispatch_ctr)@l(5)
cerion85665ca2005-06-20 15:51:07 +0000193
cerione51a42c2005-11-08 22:03:07 +0000194 /* set host FPU control word to the default mode expected
cerion1936d8d2005-07-05 18:24:22 +0000195 by VEX-generated code. See comments in libvex.h for
196 more info. */
sewardj5d3a1c92005-12-15 21:40:34 +0000197 lis 5,VG_(machine_ppc32_has_FP)@ha
198 lwz 5,VG_(machine_ppc32_has_FP)@l(5)
199 cmplwi 5,0
sewardj2c36d422005-11-13 01:59:22 +0000200 beq LafterFP2
cerion1b6b2b32005-11-18 20:45:18 +0000201
sewardj5d3a1c92005-12-15 21:40:34 +0000202 /* get zero into f3 (tedious) */
203 /* note: fsub 3,3,3 is not a reliable way to do this,
204 since if f3 holds a NaN or similar then we don't necessarily
205 wind up with zero. */
206 li 5,0
207 stw 5,20(1)
ceriona5422db2005-12-01 19:05:41 +0000208 lfs 3,20(1)
cerion21082042005-12-06 19:07:08 +0000209 mtfsf 0xFF,3 /* fpscr = f3 */
sewardj2c36d422005-11-13 01:59:22 +0000210LafterFP2:
cerion1936d8d2005-07-05 18:24:22 +0000211
cerione51a42c2005-11-08 22:03:07 +0000212 /* set host AltiVec control word to the default mode expected
213 by VEX-generated code. */
sewardj5d3a1c92005-12-15 21:40:34 +0000214 lis 5,VG_(machine_ppc32_has_VMX)@ha
215 lwz 5,VG_(machine_ppc32_has_VMX)@l(5)
216 cmplwi 5,0
sewardj2c36d422005-11-13 01:59:22 +0000217 beq LafterVMX2
cerion1b6b2b32005-11-18 20:45:18 +0000218
219 vspltisw 3,0x0 /* generate zero */
cerion1936d8d2005-07-05 18:24:22 +0000220 mtvscr 3
sewardj2c36d422005-11-13 01:59:22 +0000221LafterVMX2:
222
cerion85665ca2005-06-20 15:51:07 +0000223 /* make a stack frame for the code we are calling */
224 stwu 1,-16(1)
225
sewardj5d3a1c92005-12-15 21:40:34 +0000226 /* fetch %CIA into r3 */
227 lwz 3,OFFSET_ppc32_CIA(31)
cerion85665ca2005-06-20 15:51:07 +0000228
cerion1ade6972005-12-20 20:48:50 +0000229 /* fall into main loop (the right one) */
sewardj5d3a1c92005-12-15 21:40:34 +0000230 /* r4 = do_profiling. It's probably trashed after here,
231 but that's OK: we don't need it after here. */
232 cmplwi 4,0
233 beq VG_(run_innerloop__dispatch_unprofiled)
234 b VG_(run_innerloop__dispatch_profiled)
235 /*NOTREACHED*/
cerion85665ca2005-06-20 15:51:07 +0000236
sewardj5d3a1c92005-12-15 21:40:34 +0000237/*----------------------------------------------------*/
238/*--- NO-PROFILING (standard) dispatcher ---*/
239/*----------------------------------------------------*/
240
241.global VG_(run_innerloop__dispatch_unprofiled)
242VG_(run_innerloop__dispatch_unprofiled):
243 /* At entry: Live regs:
cerion1ade6972005-12-20 20:48:50 +0000244 r1 (=sp)
sewardj5d3a1c92005-12-15 21:40:34 +0000245 r3 (=CIA = next guest address)
sewardj5ee49482005-12-16 01:08:22 +0000246 r29 (=dispatch_ctr)
sewardj5d3a1c92005-12-15 21:40:34 +0000247 r31 (=guest_state)
sewardj5d3a1c92005-12-15 21:40:34 +0000248 Stack state:
249 44(r1) (=orig guest_state)
250 */
sewardj5f76de02007-02-11 05:08:06 +0000251 /* Has the guest state pointer been messed with? If yes, exit.
sewardj4994cc22007-02-11 09:09:20 +0000252 Also set up & VG_(tt_fast) early in an attempt at better
253 scheduling. */
sewardj5f76de02007-02-11 05:08:06 +0000254 lwz 9,44(1) /* original guest_state ptr */
255 lis 5,VG_(tt_fast)@ha
256 addi 5,5,VG_(tt_fast)@l /* & VG_(tt_fast) */
257 cmpw 9,31
sewardj5d3a1c92005-12-15 21:40:34 +0000258 bne gsp_changed
259
cerion85665ca2005-06-20 15:51:07 +0000260 /* save the jump address in the guest state */
sewardj5d3a1c92005-12-15 21:40:34 +0000261 stw 3,OFFSET_ppc32_CIA(31)
cerion85665ca2005-06-20 15:51:07 +0000262
263 /* Are we out of timeslice? If yes, defer to scheduler. */
cerion1ade6972005-12-20 20:48:50 +0000264 subi 29,29,1
sewardj5ee49482005-12-16 01:08:22 +0000265 cmplwi 29,0
266 beq counter_is_zero
cerion85665ca2005-06-20 15:51:07 +0000267
268 /* try a fast lookup in the translation cache */
sewardj4994cc22007-02-11 09:09:20 +0000269 /* r4 = VG_TT_FAST_HASH(addr) * sizeof(FastCacheEntry)
sewardj5f76de02007-02-11 05:08:06 +0000270 = ((r3 >>u 2) & VG_TT_FAST_MASK) << 3 */
271 rlwinm 4,3,1, 29-VG_TT_FAST_BITS, 28 /* entry# * 8 */
272 add 5,5,4 /* & VG_(tt_fast)[entry#] */
273 lwz 6,0(5) /* .guest */
274 lwz 7,4(5) /* .host */
sewardj5d3a1c92005-12-15 21:40:34 +0000275 cmpw 3,6
276 bne fast_lookup_failed
277
sewardj5f76de02007-02-11 05:08:06 +0000278 /* Found a match. Call .host. */
279 mtctr 7
sewardj0ddf76c2006-10-17 02:08:26 +0000280 bctrl
sewardj5d3a1c92005-12-15 21:40:34 +0000281
cerion1ade6972005-12-20 20:48:50 +0000282 /* On return from guest code:
283 r3 holds destination (original) address.
284 r31 may be unchanged (guest_state), or may indicate further
285 details of the control transfer requested to *r3.
286 */
sewardj5d3a1c92005-12-15 21:40:34 +0000287 /* start over */
288 b VG_(run_innerloop__dispatch_unprofiled)
289 /*NOTREACHED*/
290
291/*----------------------------------------------------*/
292/*--- PROFILING dispatcher (can be much slower) ---*/
293/*----------------------------------------------------*/
294
295.global VG_(run_innerloop__dispatch_profiled)
296VG_(run_innerloop__dispatch_profiled):
297 /* At entry: Live regs:
298 r1 (=sp)
299 r3 (=CIA = next guest address)
sewardj5ee49482005-12-16 01:08:22 +0000300 r29 (=dispatch_ctr)
sewardj5d3a1c92005-12-15 21:40:34 +0000301 r31 (=guest_state)
sewardj5d3a1c92005-12-15 21:40:34 +0000302 Stack state:
303 44(r1) (=orig guest_state)
304 */
sewardj5f76de02007-02-11 05:08:06 +0000305 /* Has the guest state pointer been messed with? If yes, exit.
sewardj4994cc22007-02-11 09:09:20 +0000306 Also set up & VG_(tt_fast) early in an attempt at better
307 scheduling. */
sewardj5f76de02007-02-11 05:08:06 +0000308 lwz 9,44(1) /* original guest_state ptr */
309 lis 5,VG_(tt_fast)@ha
310 addi 5,5,VG_(tt_fast)@l /* & VG_(tt_fast) */
311 cmpw 9,31
sewardj5d3a1c92005-12-15 21:40:34 +0000312 bne gsp_changed
313
314 /* save the jump address in the guest state */
315 stw 3,OFFSET_ppc32_CIA(31)
316
317 /* Are we out of timeslice? If yes, defer to scheduler. */
sewardj3387dda2005-12-26 17:58:58 +0000318 subi 29,29,1
319 cmplwi 29,0
sewardj5ee49482005-12-16 01:08:22 +0000320 beq counter_is_zero
sewardj5d3a1c92005-12-15 21:40:34 +0000321
322 /* try a fast lookup in the translation cache */
sewardj4994cc22007-02-11 09:09:20 +0000323 /* r4 = VG_TT_FAST_HASH(addr) * sizeof(FastCacheEntry)
sewardj5f76de02007-02-11 05:08:06 +0000324 = ((r3 >>u 2) & VG_TT_FAST_MASK) << 3 */
325 rlwinm 4,3,1, 29-VG_TT_FAST_BITS, 28 /* entry# * 8 */
326 add 5,5,4 /* & VG_(tt_fast)[entry#] */
327 lwz 6,0(5) /* .guest */
328 lwz 7,4(5) /* .host */
sewardj5d3a1c92005-12-15 21:40:34 +0000329 cmpw 3,6
cerione51a42c2005-11-08 22:03:07 +0000330 bne fast_lookup_failed
cerion85665ca2005-06-20 15:51:07 +0000331
332 /* increment bb profile counter */
sewardj4994cc22007-02-11 09:09:20 +0000333 srwi 4,4,1 /* entry# * sizeof(UInt*) */
cerion85665ca2005-06-20 15:51:07 +0000334 addis 6,4,VG_(tt_fastN)@ha
sewardj5f76de02007-02-11 05:08:06 +0000335 lwz 9,VG_(tt_fastN)@l(6)
336 lwz 8,0(9)
cerion85665ca2005-06-20 15:51:07 +0000337 addi 8,8,1
sewardj5f76de02007-02-11 05:08:06 +0000338 stw 8,0(9)
cerion85665ca2005-06-20 15:51:07 +0000339
sewardj5f76de02007-02-11 05:08:06 +0000340 /* Found a match. Call .host. */
341 mtctr 7
sewardj0ddf76c2006-10-17 02:08:26 +0000342 bctrl
cerion85665ca2005-06-20 15:51:07 +0000343
cerion1ade6972005-12-20 20:48:50 +0000344 /* On return from guest code:
345 r3 holds destination (original) address.
346 r31 may be unchanged (guest_state), or may indicate further
347 details of the control transfer requested to *r3.
348 */
sewardj5d3a1c92005-12-15 21:40:34 +0000349 /* start over */
350 b VG_(run_innerloop__dispatch_profiled)
351 /*NOTREACHED*/
cerion85665ca2005-06-20 15:51:07 +0000352
sewardj5d3a1c92005-12-15 21:40:34 +0000353/*----------------------------------------------------*/
354/*--- exit points ---*/
355/*----------------------------------------------------*/
356
357gsp_changed:
358 /* Someone messed with the gsp (in r31). Have to
359 defer to scheduler to resolve this. dispatch ctr
360 is not yet decremented, so no need to increment. */
361 /* %CIA is NOT up to date here. First, need to write
362 %r3 back to %CIA, but without trashing %r31 since
363 that holds the value we want to return to the scheduler.
364 Hence use %r5 transiently for the guest state pointer. */
365 lwz 5,44(1) /* original guest_state ptr */
366 stw 3,OFFSET_ppc32_CIA(5)
367 mr 3,31 /* r3 = new gsp value */
368 b run_innerloop_exit
369 /*NOTREACHED*/
370
371counter_is_zero:
372 /* %CIA is up to date */
373 /* back out decrement of the dispatch counter */
sewardj5ee49482005-12-16 01:08:22 +0000374 addi 29,29,1
sewardj5d3a1c92005-12-15 21:40:34 +0000375 li 3,VG_TRC_INNER_COUNTERZERO
376 b run_innerloop_exit
377
378fast_lookup_failed:
379 /* %CIA is up to date */
380 /* back out decrement of the dispatch counter */
sewardj5ee49482005-12-16 01:08:22 +0000381 addi 29,29,1
sewardj5d3a1c92005-12-15 21:40:34 +0000382 li 3,VG_TRC_INNER_FASTMISS
383 b run_innerloop_exit
384
385
cerion85665ca2005-06-20 15:51:07 +0000386
387/* All exits from the dispatcher go through here.
388 r3 holds the return value.
389*/
390run_innerloop_exit:
391 /* We're leaving. Check that nobody messed with
cerion3d11e0e2005-11-16 20:22:11 +0000392 VSCR or FPSCR. */
cerion85665ca2005-06-20 15:51:07 +0000393
cerion3d11e0e2005-11-16 20:22:11 +0000394 /* Using r10 - value used again further on, so don't trash! */
395 lis 10,VG_(machine_ppc32_has_FP)@ha
396 lwz 10,VG_(machine_ppc32_has_FP)@l(10)
397 cmplwi 10,0
398 beq LafterFP8
399
sewardje68ddf72006-02-06 05:14:31 +0000400 /* Set fpscr back to a known state, since vex-generated code
401 may have messed with fpscr[rm]. */
402 li 5,0
403 addi 1,1,-16
404 stw 5,0(1)
405 lfs 3,0(1)
406 addi 1,1,16
407 mtfsf 0xFF,3 /* fpscr = f3 */
cerion3d11e0e2005-11-16 20:22:11 +0000408LafterFP8:
409
410 /* Using r11 - value used again further on, so don't trash! */
411 lis 11,VG_(machine_ppc32_has_VMX)@ha
412 lwz 11,VG_(machine_ppc32_has_VMX)@l(11)
413 cmplwi 11,0
414 beq LafterVMX8
415
416 /* Check VSCR[NJ] == 1 */
417 /* first generate 4x 0x00010000 */
418 vspltisw 4,0x1 /* 4x 0x00000001 */
419 vspltisw 5,0x0 /* zero */
cerion1b6b2b32005-11-18 20:45:18 +0000420 vsldoi 6,4,5,0x2 /* <<2*8 => 4x 0x00010000 */
cerion3d11e0e2005-11-16 20:22:11 +0000421 /* retrieve VSCR and mask wanted bits */
422 mfvscr 7
cerion1b6b2b32005-11-18 20:45:18 +0000423 vand 7,7,6 /* gives NJ flag */
cerion3d11e0e2005-11-16 20:22:11 +0000424 vspltw 7,7,0x3 /* flags-word to all lanes */
cerion1b6b2b32005-11-18 20:45:18 +0000425 vcmpequw. 8,6,7 /* CR[24] = 1 if v6 == v7 */
426 bt 24,invariant_violation /* branch if all_equal */
cerion3d11e0e2005-11-16 20:22:11 +0000427LafterVMX8:
428
cerion85665ca2005-06-20 15:51:07 +0000429 /* otherwise we're OK */
430 b run_innerloop_exit_REALLY
431
432
433invariant_violation:
434 li 3,VG_TRC_INVARIANT_FAILED
435 b run_innerloop_exit_REALLY
436
437run_innerloop_exit_REALLY:
438 /* r3 holds VG_TRC_* value to return */
439
cerion3e357562005-11-09 14:13:08 +0000440 /* Return to parent stack */
cerion85665ca2005-06-20 15:51:07 +0000441 addi 1,1,16
442
cerion3e357562005-11-09 14:13:08 +0000443 /* Write ctr to VG(dispatch_ctr) */
sewardj5ee49482005-12-16 01:08:22 +0000444 lis 5,VG_(dispatch_ctr)@ha
445 stw 29,VG_(dispatch_ctr)@l(5)
cerion85665ca2005-06-20 15:51:07 +0000446
cerion3e357562005-11-09 14:13:08 +0000447 /* Restore cr */
cerion3d11e0e2005-11-16 20:22:11 +0000448 lwz 0,44(1)
cerion3e357562005-11-09 14:13:08 +0000449 mtcr 0
450
451 /* Restore callee-saved registers... */
452
cerion3d11e0e2005-11-16 20:22:11 +0000453 /* r10 already holds VG_(machine_ppc32_has_FP) value */
454 cmplwi 10,0
sewardj2c36d422005-11-13 01:59:22 +0000455 beq LafterFP9
456
cerion3e357562005-11-09 14:13:08 +0000457 /* Floating-point regs */
458 lfd 31,488(1)
459 lfd 30,480(1)
460 lfd 29,472(1)
461 lfd 28,464(1)
462 lfd 27,456(1)
463 lfd 26,448(1)
464 lfd 25,440(1)
465 lfd 24,432(1)
466 lfd 23,424(1)
467 lfd 22,416(1)
468 lfd 21,408(1)
469 lfd 20,400(1)
470 lfd 19,392(1)
471 lfd 18,384(1)
472 lfd 17,376(1)
473 lfd 16,368(1)
474 lfd 15,360(1)
475 lfd 14,352(1)
sewardj2c36d422005-11-13 01:59:22 +0000476LafterFP9:
cerion3e357562005-11-09 14:13:08 +0000477
478 /* General regs */
479 lwz 31,348(1)
480 lwz 30,344(1)
481 lwz 29,340(1)
482 lwz 28,336(1)
483 lwz 27,332(1)
484 lwz 26,328(1)
485 lwz 25,324(1)
486 lwz 24,320(1)
487 lwz 23,316(1)
488 lwz 22,312(1)
489 lwz 21,308(1)
490 lwz 20,304(1)
491 lwz 19,300(1)
492 lwz 18,296(1)
493 lwz 17,292(1)
494 lwz 16,288(1)
495 lwz 15,284(1)
496 lwz 14,280(1)
497 lwz 13,276(1)
498
cerion3d11e0e2005-11-16 20:22:11 +0000499 /* r11 already holds VG_(machine_ppc32_has_VMX) value */
500 cmplwi 11,0
sewardj2c36d422005-11-13 01:59:22 +0000501 beq LafterVMX9
502
cerion3e357562005-11-09 14:13:08 +0000503 /* VRSAVE */
504 lwz 4,244(1)
505 mfspr 4,256 /* VRSAVE reg is spr number 256 */
506
507 /* Vector regs */
508 li 4,224
509 lvx 31,4,1
510 li 4,208
cerione51a42c2005-11-08 22:03:07 +0000511 lvx 30,4,1
512 li 4,192
cerion3e357562005-11-09 14:13:08 +0000513 lvx 29,4,1
514 li 4,176
515 lvx 28,4,1
516 li 4,160
517 lvx 27,4,1
518 li 4,144
519 lvx 26,4,1
520 li 4,128
521 lvx 25,4,1
522 li 4,112
523 lvx 24,4,1
524 li 4,96
525 lvx 23,4,1
526 li 4,80
527 lvx 22,4,1
528 li 4,64
529 lvx 21,4,1
530 li 4,48
531 lvx 20,4,1
sewardj2c36d422005-11-13 01:59:22 +0000532LafterVMX9:
cerione51a42c2005-11-08 22:03:07 +0000533
534 /* reset lr & sp */
cerion3e357562005-11-09 14:13:08 +0000535 lwz 0,500(1) /* stack_size + 4 */
cerion85665ca2005-06-20 15:51:07 +0000536 mtlr 0
cerion3e357562005-11-09 14:13:08 +0000537 addi 1,1,496 /* stack_size */
cerion85665ca2005-06-20 15:51:07 +0000538 blr
tom63c8de52006-05-01 09:28:39 +0000539.size VG_(run_innerloop), .-VG_(run_innerloop)
cerion85665ca2005-06-20 15:51:07 +0000540
sewardja591a052006-01-12 14:04:46 +0000541
542/*------------------------------------------------------------*/
543/*--- ---*/
544/*--- A special dispatcher, for running no-redir ---*/
545/*--- translations. Just runs the given translation once. ---*/
546/*--- ---*/
547/*------------------------------------------------------------*/
548
549/* signature:
550void VG_(run_a_noredir_translation) ( UWord* argblock );
551*/
552
553/* Run a no-redir translation. argblock points to 4 UWords, 2 to carry args
554 and 2 to carry results:
555 0: input: ptr to translation
556 1: input: ptr to guest state
557 2: output: next guest PC
558 3: output: guest state pointer afterwards (== thread return code)
559*/
sewardja591a052006-01-12 14:04:46 +0000560.global VG_(run_a_noredir_translation)
tom63c8de52006-05-01 09:28:39 +0000561.type VG_(run_a_noredir_translation), @function
sewardja591a052006-01-12 14:04:46 +0000562VG_(run_a_noredir_translation):
563 /* save callee-save int regs, & lr */
564 stwu 1,-256(1)
565 stw 14,128(1)
566 stw 15,132(1)
567 stw 16,136(1)
568 stw 17,140(1)
569 stw 18,144(1)
570 stw 19,148(1)
571 stw 20,152(1)
572 stw 21,156(1)
573 stw 22,160(1)
574 stw 23,164(1)
575 stw 24,168(1)
576 stw 25,172(1)
577 stw 26,176(1)
578 stw 27,180(1)
579 stw 28,184(1)
580 stw 29,188(1)
581 stw 30,192(1)
582 stw 31,196(1)
583 mflr 31
584 stw 31,200(1)
585
586 stw 3,204(1)
587 lwz 31,4(3)
588 lwz 30,0(3)
589 mtlr 30
590 blrl
591
592 lwz 4,204(1)
593 stw 3, 8(4)
594 stw 31,12(4)
595
596 lwz 14,128(1)
597 lwz 15,132(1)
598 lwz 16,136(1)
599 lwz 17,140(1)
600 lwz 18,144(1)
601 lwz 19,148(1)
602 lwz 20,152(1)
603 lwz 21,156(1)
604 lwz 22,160(1)
605 lwz 23,164(1)
606 lwz 24,168(1)
607 lwz 25,172(1)
608 lwz 26,176(1)
609 lwz 27,180(1)
610 lwz 28,184(1)
611 lwz 29,188(1)
612 lwz 30,192(1)
613 lwz 31,200(1)
614 mtlr 31
615 lwz 31,196(1)
616 addi 1,1,256
617 blr
tom63c8de52006-05-01 09:28:39 +0000618.size VG_(run_a_noredir_translation), .-VG_(run_a_noredir_translation)
sewardja591a052006-01-12 14:04:46 +0000619
620
cerion85665ca2005-06-20 15:51:07 +0000621/* Let the linker know we don't need an executable stack */
622.section .note.GNU-stack,"",@progbits
623
sewardj5d3a1c92005-12-15 21:40:34 +0000624/*--------------------------------------------------------------------*/
625/*--- end ---*/
626/*--------------------------------------------------------------------*/