blob: c7f322fca47bebc82ea74cf52da250652c6d8284 [file] [log] [blame]
sewardj2c48c7b2005-11-29 13:05:56 +00001
cerion1ade6972005-12-20 20:48:50 +00002/*--------------------------------------------------------------------*/
3/*--- The core dispatch loop, for jumping to a code address. ---*/
sewardj0ddf76c2006-10-17 02:08:26 +00004/*--- dispatch-ppc64-linux.S ---*/
cerion1ade6972005-12-20 20:48:50 +00005/*--------------------------------------------------------------------*/
sewardj2c48c7b2005-11-29 13:05:56 +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>
sewardj2c48c7b2005-11-29 13:05:56 +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
31#include "pub_core_basics_asm.h"
32#include "pub_core_dispatch_asm.h"
33#include "pub_core_transtab_asm.h"
34#include "libvex_guest_offsets.h" /* for OFFSET_ppc64_CIA */
35
36
37/* References to globals via the TOC */
38
cerion21082042005-12-06 19:07:08 +000039/*
40 .globl vgPlain_tt_fast
41 .lcomm vgPlain_tt_fast,4,4
42 .type vgPlain_tt_fast, @object
43*/
44 .section ".toc","aw"
45.tocent__vgPlain_tt_fast:
46 .tc vgPlain_tt_fast[TC],vgPlain_tt_fast
cerion1ade6972005-12-20 20:48:50 +000047.tocent__vgPlain_tt_fastN:
48 .tc vgPlain_tt_fastN[TC],vgPlain_tt_fastN
cerion21082042005-12-06 19:07:08 +000049.tocent__vgPlain_dispatch_ctr:
50 .tc vgPlain_dispatch_ctr[TC],vgPlain_dispatch_ctr
51.tocent__vgPlain_machine_ppc64_has_VMX:
52 .tc vgPlain_machine_ppc64_has_VMX[TC],vgPlain_machine_ppc64_has_VMX
sewardj2c48c7b2005-11-29 13:05:56 +000053
54/*------------------------------------------------------------*/
sewardj1a85f4f2006-01-12 21:15:35 +000055/*--- ---*/
56/*--- The dispatch loop. VG_(run_innerloop) is used to ---*/
57/*--- run all translations except no-redir ones. ---*/
58/*--- ---*/
sewardj2c48c7b2005-11-29 13:05:56 +000059/*------------------------------------------------------------*/
60
cerion1ade6972005-12-20 20:48:50 +000061/*----------------------------------------------------*/
62/*--- Preamble (set everything up) ---*/
63/*----------------------------------------------------*/
sewardj2c48c7b2005-11-29 13:05:56 +000064
cerion1ade6972005-12-20 20:48:50 +000065/* signature:
66UWord VG_(run_innerloop) ( void* guest_state, UWord do_profiling );
67*/
68
69.section ".text"
70.align 2
71.globl VG_(run_innerloop)
72.section ".opd","aw"
73.align 3
cerion21082042005-12-06 19:07:08 +000074VG_(run_innerloop):
cerion1ade6972005-12-20 20:48:50 +000075.quad .VG_(run_innerloop),.TOC.@tocbase,0
76.previous
77.type .VG_(run_innerloop),@function
78.globl .VG_(run_innerloop)
sewardj2c48c7b2005-11-29 13:05:56 +000079.VG_(run_innerloop):
cerion1ade6972005-12-20 20:48:50 +000080 /* r3 holds guest_state */
81 /* r4 holds do_profiling */
sewardj2c48c7b2005-11-29 13:05:56 +000082
cerion1ade6972005-12-20 20:48:50 +000083 /* ----- entry point to VG_(run_innerloop) ----- */
cerion21082042005-12-06 19:07:08 +000084 /* PPC64 ABI saves LR->16(prt_sp), CR->8(prt_sp)) */
cerion1ade6972005-12-20 20:48:50 +000085
cerion21082042005-12-06 19:07:08 +000086 /* Save lr, cr */
sewardj2c48c7b2005-11-29 13:05:56 +000087 mflr 0
cerion21082042005-12-06 19:07:08 +000088 std 0,16(1)
89 mfcr 0
90 std 0,8(1)
sewardj2c48c7b2005-11-29 13:05:56 +000091
92 /* New stack frame */
cerion21082042005-12-06 19:07:08 +000093 stdu 1,-624(1) /* sp should maintain 16-byte alignment */
sewardj2c48c7b2005-11-29 13:05:56 +000094
95 /* Save callee-saved registers... */
96
97 /* Floating-point reg save area : 144 bytes */
98 stfd 31,616(1)
99 stfd 30,608(1)
100 stfd 29,600(1)
101 stfd 28,592(1)
102 stfd 27,584(1)
103 stfd 26,576(1)
104 stfd 25,568(1)
105 stfd 24,560(1)
106 stfd 23,552(1)
107 stfd 22,544(1)
108 stfd 21,536(1)
109 stfd 20,528(1)
110 stfd 19,520(1)
111 stfd 18,512(1)
112 stfd 17,504(1)
113 stfd 16,496(1)
114 stfd 15,488(1)
115 stfd 14,480(1)
116
117 /* General reg save area : 144 bytes */
cerion21082042005-12-06 19:07:08 +0000118 std 31,472(1)
119 std 30,464(1)
120 std 29,456(1)
121 std 28,448(1)
122 std 27,440(1)
123 std 26,432(1)
124 std 25,424(1)
125 std 24,416(1)
126 std 23,408(1)
127 std 22,400(1)
128 std 21,392(1)
129 std 20,384(1)
130 std 19,376(1)
131 std 18,368(1)
132 std 17,360(1)
133 std 16,352(1)
134 std 15,344(1)
135 std 14,336(1)
sewardj2c48c7b2005-11-29 13:05:56 +0000136 /* Probably not necessary to save r13 (thread-specific ptr),
137 as VEX stays clear of it... but what the hey. */
cerion21082042005-12-06 19:07:08 +0000138 std 13,328(1)
sewardj2c48c7b2005-11-29 13:05:56 +0000139
140 /* It's necessary to save/restore VRSAVE in the AIX / Darwin ABI.
141 The Linux kernel might not actually use VRSAVE for its intended
142 purpose, but it should be harmless to preserve anyway. */
cerion1ade6972005-12-20 20:48:50 +0000143 /* r3, r4 are live here, so use r5 */
144 ld 5,.tocent__vgPlain_machine_ppc64_has_VMX@toc(2)
145 ld 5,0(5)
146 cmpldi 5,0
cerion21082042005-12-06 19:07:08 +0000147 beq .LafterVMX1
sewardj2c48c7b2005-11-29 13:05:56 +0000148
149 /* VRSAVE save word : 32 bytes */
cerion1ade6972005-12-20 20:48:50 +0000150 mfspr 5,256 /* vrsave reg is spr number 256 */
151 stw 5,324(1)
sewardj2c48c7b2005-11-29 13:05:56 +0000152
153 /* Alignment padding : 4 bytes */
154
155 /* Vector reg save area (quadword aligned) : 192 bytes */
cerion1ade6972005-12-20 20:48:50 +0000156 li 5,304
157 stvx 31,5,1
158 li 5,288
159 stvx 30,5,1
160 li 5,272
161 stvx 29,5,1
162 li 5,256
163 stvx 28,5,1
164 li 5,240
165 stvx 27,5,1
166 li 5,224
167 stvx 26,5,1
168 li 5,208
169 stvx 25,5,1
170 li 5,192
171 stvx 24,5,1
172 li 5,176
173 stvx 23,5,1
174 li 5,160
175 stvx 22,5,1
176 li 5,144
177 stvx 21,5,1
178 li 5,128
179 stvx 20,5,1
cerion21082042005-12-06 19:07:08 +0000180.LafterVMX1:
sewardj2c48c7b2005-11-29 13:05:56 +0000181
182 /* Local variable space... */
183
184 /* r3 holds guest_state */
cerion1ade6972005-12-20 20:48:50 +0000185 /* r4 holds do_profiling */
sewardj2c48c7b2005-11-29 13:05:56 +0000186 mr 31,3
cerion21082042005-12-06 19:07:08 +0000187 std 3,104(1) /* spill orig guest_state ptr */
sewardj2c48c7b2005-11-29 13:05:56 +0000188
189 /* 96(sp) used later to check FPSCR[RM] */
cerion1ade6972005-12-20 20:48:50 +0000190 /* 88(sp) used later to load fpscr with zero */
191 /* 48:87(sp) free */
sewardj2c48c7b2005-11-29 13:05:56 +0000192
193 /* Linkage Area (reserved)
194 40(sp) : TOC
195 32(sp) : link editor doubleword
196 24(sp) : compiler doubleword
197 16(sp) : LR
198 8(sp) : CR
199 0(sp) : back-chain
200 */
201
202// CAB TODO: Use a caller-saved reg for orig guest_state ptr
203// - rem to set non-allocateable in isel.c
204
cerion1ade6972005-12-20 20:48:50 +0000205 /* hold dispatch_ctr (=32bit value) in r29 */
206 ld 29,.tocent__vgPlain_dispatch_ctr@toc(2)
sewardj73735822007-02-20 19:23:19 +0000207 lwz 29,0(29) /* 32-bit zero-extending load */
sewardj2c48c7b2005-11-29 13:05:56 +0000208
209 /* set host FPU control word to the default mode expected
210 by VEX-generated code. See comments in libvex.h for
211 more info. */
cerion21082042005-12-06 19:07:08 +0000212 /* => get zero into f3 (tedious)
213 fsub 3,3,3 is not a reliable way to do this, since if
214 f3 holds a NaN or similar then we don't necessarily
215 wind up with zero. */
cerion1ade6972005-12-20 20:48:50 +0000216 li 5,0
217 stw 5,88(1)
218 lfs 3,88(1)
cerion21082042005-12-06 19:07:08 +0000219 mtfsf 0xFF,3 /* fpscr = lo32 of f3 */
sewardj2c48c7b2005-11-29 13:05:56 +0000220
221 /* set host AltiVec control word to the default mode expected
222 by VEX-generated code. */
cerion1ade6972005-12-20 20:48:50 +0000223 ld 5,.tocent__vgPlain_machine_ppc64_has_VMX@toc(2)
224 ld 5,0(5)
225 cmpldi 5,0
cerion21082042005-12-06 19:07:08 +0000226 beq .LafterVMX2
sewardj2c48c7b2005-11-29 13:05:56 +0000227
228 vspltisw 3,0x0 /* generate zero */
229 mtvscr 3
cerion21082042005-12-06 19:07:08 +0000230.LafterVMX2:
sewardj2c48c7b2005-11-29 13:05:56 +0000231
232 /* make a stack frame for the code we are calling */
cerion21082042005-12-06 19:07:08 +0000233 stdu 1,-48(1)
sewardj2c48c7b2005-11-29 13:05:56 +0000234
cerion1ade6972005-12-20 20:48:50 +0000235 /* fetch %CIA into r3 */
236 ld 3,OFFSET_ppc64_CIA(31)
sewardj2c48c7b2005-11-29 13:05:56 +0000237
cerion1ade6972005-12-20 20:48:50 +0000238 /* fall into main loop (the right one) */
239 /* r4 = do_profiling. It's probably trashed after here,
240 but that's OK: we don't need it after here. */
241 cmplwi 4,0
242 beq .VG_(run_innerloop__dispatch_unprofiled)
243 b .VG_(run_innerloop__dispatch_profiled)
244 /*NOTREACHED*/
sewardj2c48c7b2005-11-29 13:05:56 +0000245
cerion1ade6972005-12-20 20:48:50 +0000246
247/*----------------------------------------------------*/
248/*--- NO-PROFILING (standard) dispatcher ---*/
249/*----------------------------------------------------*/
250
251 .section ".text"
252 .align 2
253 .globl VG_(run_innerloop__dispatch_unprofiled)
254 .section ".opd","aw"
255 .align 3
256VG_(run_innerloop__dispatch_unprofiled):
257 .quad .VG_(run_innerloop__dispatch_unprofiled),.TOC.@tocbase,0
258 .previous
259 .type .VG_(run_innerloop__dispatch_unprofiled),@function
260 .globl .VG_(run_innerloop__dispatch_unprofiled)
261.VG_(run_innerloop__dispatch_unprofiled):
262 /* At entry: Live regs:
263 r1 (=sp)
264 r2 (toc pointer)
265 r3 (=CIA = next guest address)
266 r29 (=dispatch_ctr)
267 r31 (=guest_state)
268 Stack state:
269 152(r1) (=orig guest_state)
270 144(r1) (=var space for FPSCR[RM])
271 */
sewardj4994cc22007-02-11 09:09:20 +0000272 /* Has the guest state pointer been messed with? If yes, exit.
273 Also set up & VG_(tt_fast) early in an attempt at better
274 scheduling. */
275 ld 9,152(1) /* original guest_state ptr */
276 ld 5, .tocent__vgPlain_tt_fast@toc(2) /* &VG_(tt_fast) */
277 cmpd 9,31
cerion1ade6972005-12-20 20:48:50 +0000278 bne .gsp_changed
279
sewardj2c48c7b2005-11-29 13:05:56 +0000280 /* save the jump address in the guest state */
cerion1ade6972005-12-20 20:48:50 +0000281 std 3,OFFSET_ppc64_CIA(31)
sewardj2c48c7b2005-11-29 13:05:56 +0000282
283 /* Are we out of timeslice? If yes, defer to scheduler. */
cerion1ade6972005-12-20 20:48:50 +0000284 subi 29,29,1
285 cmpldi 29,0
286 beq .counter_is_zero
sewardj2c48c7b2005-11-29 13:05:56 +0000287
288 /* try a fast lookup in the translation cache */
sewardj4994cc22007-02-11 09:09:20 +0000289 /* r4 = VG_TT_FAST_HASH(addr) * sizeof(FastCacheEntry)
290 = ((r3 >>u 2) & VG_TT_FAST_MASK) << 4 */
291 rldicl 4,3, 62, 64-VG_TT_FAST_BITS /* entry# */
292 sldi 4,4,4 /* entry# * sizeof(FastCacheEntry) */
293 add 5,5,4 /* & VG_(tt_fast)[entry#] */
294 ld 6,0(5) /* .guest */
295 ld 7,8(5) /* .host */
cerion1ade6972005-12-20 20:48:50 +0000296 cmpd 3,6
297 bne .fast_lookup_failed
298
sewardj4994cc22007-02-11 09:09:20 +0000299 /* Found a match. Call .host. */
300 mtctr 7
sewardj0ddf76c2006-10-17 02:08:26 +0000301 bctrl
cerion1ade6972005-12-20 20:48:50 +0000302
303 /* On return from guest code:
304 r3 holds destination (original) address.
305 r31 may be unchanged (guest_state), or may indicate further
306 details of the control transfer requested to *r3.
307 */
cerion1ade6972005-12-20 20:48:50 +0000308 /* start over */
309 b .VG_(run_innerloop__dispatch_unprofiled)
310 /*NOTREACHED*/
tom63c8de52006-05-01 09:28:39 +0000311 .size VG_(run_innerloop), .-VG_(run_innerloop)
cerion1ade6972005-12-20 20:48:50 +0000312
313
314/*----------------------------------------------------*/
315/*--- PROFILING dispatcher (can be much slower) ---*/
316/*----------------------------------------------------*/
317
318 .section ".text"
319 .align 2
320 .globl VG_(run_innerloop__dispatch_profiled)
321 .section ".opd","aw"
322 .align 3
323VG_(run_innerloop__dispatch_profiled):
324 .quad .VG_(run_innerloop__dispatch_profiled),.TOC.@tocbase,0
325 .previous
326 .type .VG_(run_innerloop__dispatch_profiled),@function
327 .globl .VG_(run_innerloop__dispatch_profiled)
328.VG_(run_innerloop__dispatch_profiled):
329 /* At entry: Live regs:
330 r1 (=sp)
331 r2 (toc pointer)
332 r3 (=CIA = next guest address)
333 r29 (=dispatch_ctr)
334 r31 (=guest_state)
335 Stack state:
336 152(r1) (=orig guest_state)
337 144(r1) (=var space for FPSCR[RM])
338 */
sewardj4994cc22007-02-11 09:09:20 +0000339 /* Has the guest state pointer been messed with? If yes, exit.
340 Also set up & VG_(tt_fast) early in an attempt at better
341 scheduling. */
342 ld 9,152(1) /* original guest_state ptr */
343 ld 5, .tocent__vgPlain_tt_fast@toc(2) /* &VG_(tt_fast) */
344 cmpd 9,31
cerion1ade6972005-12-20 20:48:50 +0000345 bne .gsp_changed
346
347 /* save the jump address in the guest state */
348 std 3,OFFSET_ppc64_CIA(31)
349
350 /* Are we out of timeslice? If yes, defer to scheduler. */
cerion1ade6972005-12-20 20:48:50 +0000351 subi 29,29,1
352 cmpldi 29,0
353 beq .counter_is_zero
354
355 /* try a fast lookup in the translation cache */
sewardj4994cc22007-02-11 09:09:20 +0000356 /* r4 = VG_TT_FAST_HASH(addr) * sizeof(FastCacheEntry)
357 = ((r3 >>u 2) & VG_TT_FAST_MASK) << 4 */
358 rldicl 4,3, 62, 64-VG_TT_FAST_BITS /* entry# */
359 sldi 4,4,4 /* entry# * sizeof(FastCacheEntry) */
360 add 5,5,4 /* & VG_(tt_fast)[entry#] */
361 ld 6,0(5) /* .guest */
362 ld 7,8(5) /* .host */
cerion1ade6972005-12-20 20:48:50 +0000363 cmpd 3,6
cerion21082042005-12-06 19:07:08 +0000364 bne .fast_lookup_failed
sewardj2c48c7b2005-11-29 13:05:56 +0000365
cerion21082042005-12-06 19:07:08 +0000366 /* increment bb profile counter VG_(tt_fastN)[x] (=32bit val) */
sewardj4994cc22007-02-11 09:09:20 +0000367 ld 9, .tocent__vgPlain_tt_fastN@toc(2)
368 srdi 4, 4,1 /* entry# * sizeof(UInt*) */
369 ldx 9, 9,4 /* r7 = VG_(tt_fastN)[VG_TT_HASH(addr)] */
370 lwz 6, 0(9) /* *(UInt*)r7 ++ */
sewardj2c48c7b2005-11-29 13:05:56 +0000371 addi 6, 6,1
sewardj4994cc22007-02-11 09:09:20 +0000372 stw 6, 0(9)
sewardj2c48c7b2005-11-29 13:05:56 +0000373
sewardj4994cc22007-02-11 09:09:20 +0000374 /* Found a match. Call .host. */
375 mtctr 7
sewardj0ddf76c2006-10-17 02:08:26 +0000376 bctrl
sewardj2c48c7b2005-11-29 13:05:56 +0000377
sewardj2c48c7b2005-11-29 13:05:56 +0000378 /* On return from guest code:
cerion1ade6972005-12-20 20:48:50 +0000379 r3 holds destination (original) address.
sewardj2c48c7b2005-11-29 13:05:56 +0000380 r31 may be unchanged (guest_state), or may indicate further
381 details of the control transfer requested to *r3.
sewardj2c48c7b2005-11-29 13:05:56 +0000382 */
cerion1ade6972005-12-20 20:48:50 +0000383 /* start over */
384 b .VG_(run_innerloop__dispatch_profiled)
385 /*NOTREACHED*/
tom63c8de52006-05-01 09:28:39 +0000386 .size VG_(run_a_noredir_translation), .-VG_(run_a_noredir_translation)
sewardj2c48c7b2005-11-29 13:05:56 +0000387
sewardj2c48c7b2005-11-29 13:05:56 +0000388
cerion1ade6972005-12-20 20:48:50 +0000389/*----------------------------------------------------*/
390/*--- exit points ---*/
391/*----------------------------------------------------*/
392
393.gsp_changed:
394 /* Someone messed with the gsp (in r31). Have to
395 defer to scheduler to resolve this. dispatch ctr
396 is not yet decremented, so no need to increment. */
397 /* %CIA is NOT up to date here. First, need to write
398 %r3 back to %CIA, but without trashing %r31 since
399 that holds the value we want to return to the scheduler.
400 Hence use %r5 transiently for the guest state pointer. */
401 ld 5,152(1) /* original guest_state ptr */
sewardj0d8ef0b2005-12-22 03:33:16 +0000402 std 3,OFFSET_ppc64_CIA(5)
cerion1ade6972005-12-20 20:48:50 +0000403 mr 3,31 /* r3 = new gsp value */
404 b .run_innerloop_exit
405 /*NOTREACHED*/
406
407.counter_is_zero:
408 /* %CIA is up to date */
409 /* back out decrement of the dispatch counter */
410 addi 29,29,1
411 li 3,VG_TRC_INNER_COUNTERZERO
412 b .run_innerloop_exit
413
414.fast_lookup_failed:
415 /* %CIA is up to date */
416 /* back out decrement of the dispatch counter */
417 addi 29,29,1
418 li 3,VG_TRC_INNER_FASTMISS
419 b .run_innerloop_exit
420
421
sewardj2c48c7b2005-11-29 13:05:56 +0000422
423/* All exits from the dispatcher go through here.
424 r3 holds the return value.
425*/
cerion21082042005-12-06 19:07:08 +0000426.run_innerloop_exit:
sewardj2c48c7b2005-11-29 13:05:56 +0000427 /* We're leaving. Check that nobody messed with
428 VSCR or FPSCR. */
429
sewardjfdac02c2006-02-06 05:31:37 +0000430 /* Set fpscr back to a known state, since vex-generated code
431 may have messed with fpscr[rm]. */
432 li 5,0
433 addi 1,1,-16
434 stw 5,0(1)
435 lfs 3,0(1)
436 addi 1,1,16
437 mtfsf 0xFF,3 /* fpscr = f3 */
438
sewardj2c48c7b2005-11-29 13:05:56 +0000439 /* Using r11 - value used again further on, so don't trash! */
cerion1ade6972005-12-20 20:48:50 +0000440 ld 11,.tocent__vgPlain_machine_ppc64_has_VMX@toc(2)
441 ld 11,0(11)
cerion21082042005-12-06 19:07:08 +0000442 cmpldi 11,0
443 beq .LafterVMX8
sewardj2c48c7b2005-11-29 13:05:56 +0000444
445 /* Check VSCR[NJ] == 1 */
446 /* first generate 4x 0x00010000 */
447 vspltisw 4,0x1 /* 4x 0x00000001 */
448 vspltisw 5,0x0 /* zero */
449 vsldoi 6,4,5,0x2 /* <<2*8 => 4x 0x00010000 */
450 /* retrieve VSCR and mask wanted bits */
451 mfvscr 7
452 vand 7,7,6 /* gives NJ flag */
453 vspltw 7,7,0x3 /* flags-word to all lanes */
454 vcmpequw. 8,6,7 /* CR[24] = 1 if v6 == v7 */
cerion21082042005-12-06 19:07:08 +0000455 bt 24,.invariant_violation /* branch if all_equal */
456.LafterVMX8:
sewardj2c48c7b2005-11-29 13:05:56 +0000457
458 /* otherwise we're OK */
cerion21082042005-12-06 19:07:08 +0000459 b .run_innerloop_exit_REALLY
sewardj2c48c7b2005-11-29 13:05:56 +0000460
461
cerion21082042005-12-06 19:07:08 +0000462.invariant_violation:
sewardj2c48c7b2005-11-29 13:05:56 +0000463 li 3,VG_TRC_INVARIANT_FAILED
cerion21082042005-12-06 19:07:08 +0000464 b .run_innerloop_exit_REALLY
sewardj2c48c7b2005-11-29 13:05:56 +0000465
cerion21082042005-12-06 19:07:08 +0000466.run_innerloop_exit_REALLY:
sewardj2c48c7b2005-11-29 13:05:56 +0000467 /* r3 holds VG_TRC_* value to return */
468
469 /* Return to parent stack */
470 addi 1,1,48
471
cerion21082042005-12-06 19:07:08 +0000472 /* Write ctr to VG_(dispatch_ctr) (=32bit value) */
cerion1ade6972005-12-20 20:48:50 +0000473 ld 5,.tocent__vgPlain_dispatch_ctr@toc(2)
474 stw 29,0(5)
475
476 /* Restore cr */
477 lwz 0,44(1)
478 mtcr 0
sewardj2c48c7b2005-11-29 13:05:56 +0000479
480 /* Restore callee-saved registers... */
481
482 /* Floating-point regs */
cerion21082042005-12-06 19:07:08 +0000483 lfd 31,616(1)
484 lfd 30,608(1)
485 lfd 29,600(1)
486 lfd 28,592(1)
487 lfd 27,584(1)
488 lfd 26,576(1)
489 lfd 25,568(1)
490 lfd 24,560(1)
491 lfd 23,552(1)
492 lfd 22,544(1)
493 lfd 21,536(1)
494 lfd 20,528(1)
495 lfd 19,520(1)
496 lfd 18,512(1)
497 lfd 17,504(1)
498 lfd 16,496(1)
499 lfd 15,488(1)
500 lfd 14,480(1)
sewardj2c48c7b2005-11-29 13:05:56 +0000501
502 /* General regs */
cerion21082042005-12-06 19:07:08 +0000503 ld 31,472(1)
504 ld 30,464(1)
505 ld 29,456(1)
506 ld 28,448(1)
507 ld 27,440(1)
508 ld 26,432(1)
509 ld 25,424(1)
510 ld 24,416(1)
511 ld 23,408(1)
512 ld 22,400(1)
513 ld 21,392(1)
514 ld 20,384(1)
515 ld 19,376(1)
516 ld 18,368(1)
517 ld 17,360(1)
518 ld 16,352(1)
519 ld 15,344(1)
520 ld 14,336(1)
521 ld 13,328(1)
sewardj2c48c7b2005-11-29 13:05:56 +0000522
523 /* r11 already holds VG_(machine_ppc64_has_VMX) value */
cerion21082042005-12-06 19:07:08 +0000524 cmpldi 11,0
525 beq .LafterVMX9
sewardj2c48c7b2005-11-29 13:05:56 +0000526
527 /* VRSAVE */
528 lwz 4,324(1)
529 mfspr 4,256 /* VRSAVE reg is spr number 256 */
530
531 /* Vector regs */
532 li 4,304
533 lvx 31,4,1
534 li 4,288
535 lvx 30,4,1
536 li 4,272
537 lvx 29,4,1
538 li 4,256
539 lvx 28,4,1
540 li 4,240
541 lvx 27,4,1
542 li 4,224
543 lvx 26,4,1
544 li 4,208
545 lvx 25,4,1
546 li 4,192
547 lvx 24,4,1
548 li 4,176
549 lvx 23,4,1
550 li 4,160
551 lvx 22,4,1
552 li 4,144
553 lvx 21,4,1
554 li 4,128
555 lvx 20,4,1
cerion21082042005-12-06 19:07:08 +0000556.LafterVMX9:
sewardj2c48c7b2005-11-29 13:05:56 +0000557
cerion21082042005-12-06 19:07:08 +0000558 /* reset cr, lr, sp */
559 ld 0,632(1) /* stack_size + 8 */
560 mtcr 0
561 ld 0,640(1) /* stack_size + 16 */
sewardj2c48c7b2005-11-29 13:05:56 +0000562 mtlr 0
563 addi 1,1,624 /* stack_size */
564 blr
565
566
sewardj1a85f4f2006-01-12 21:15:35 +0000567/*------------------------------------------------------------*/
568/*--- ---*/
569/*--- A special dispatcher, for running no-redir ---*/
570/*--- translations. Just runs the given translation once. ---*/
571/*--- ---*/
572/*------------------------------------------------------------*/
573
574/* signature:
575void VG_(run_a_noredir_translation) ( UWord* argblock );
576*/
577
578/* Run a no-redir translation. argblock points to 4 UWords, 2 to carry args
579 and 2 to carry results:
580 0: input: ptr to translation
581 1: input: ptr to guest state
582 2: output: next guest PC
583 3: output: guest state pointer afterwards (== thread return code)
584*/
585.section ".text"
586.align 2
587.globl VG_(run_a_noredir_translation)
588.section ".opd","aw"
589.align 3
590VG_(run_a_noredir_translation):
591.quad .VG_(run_a_noredir_translation),.TOC.@tocbase,0
592.previous
593.type .VG_(run_a_noredir_translation),@function
594.globl .VG_(run_a_noredir_translation)
595.VG_(run_a_noredir_translation):
596 /* save callee-save int regs, & lr */
597 stdu 1,-512(1)
598 std 14,256(1)
599 std 15,264(1)
600 std 16,272(1)
601 std 17,280(1)
602 std 18,288(1)
603 std 19,296(1)
604 std 20,304(1)
605 std 21,312(1)
606 std 22,320(1)
607 std 23,328(1)
608 std 24,336(1)
609 std 25,344(1)
610 std 26,352(1)
611 std 27,360(1)
612 std 28,368(1)
613 std 29,376(1)
614 std 30,384(1)
615 std 31,392(1)
616 mflr 31
617 std 31,400(1)
618 std 2,408(1) /* also preserve R2, just in case .. */
619
sewardj641a5cb2006-01-17 01:59:43 +0000620 std 3,416(1)
621 ld 31,8(3)
622 ld 30,0(3)
sewardj1a85f4f2006-01-12 21:15:35 +0000623 mtlr 30
624 blrl
625
sewardj641a5cb2006-01-17 01:59:43 +0000626 ld 4,416(1)
627 std 3, 16(4)
628 std 31,24(4)
sewardj1a85f4f2006-01-12 21:15:35 +0000629
630 ld 14,256(1)
631 ld 15,264(1)
632 ld 16,272(1)
633 ld 17,280(1)
634 ld 18,288(1)
635 ld 19,296(1)
636 ld 20,304(1)
637 ld 21,312(1)
638 ld 22,320(1)
639 ld 23,328(1)
640 ld 24,336(1)
641 ld 25,344(1)
642 ld 26,352(1)
643 ld 27,360(1)
644 ld 28,368(1)
645 ld 29,376(1)
646 ld 30,384(1)
647 ld 31,400(1)
648 mtlr 31
649 ld 31,392(1)
650 ld 2,408(1) /* also preserve R2, just in case .. */
651
652 addi 1,1,512
653 blr
654
655
sewardj2c48c7b2005-11-29 13:05:56 +0000656/* Let the linker know we don't need an executable stack */
657.section .note.GNU-stack,"",@progbits
658
cerion1ade6972005-12-20 20:48:50 +0000659/*--------------------------------------------------------------------*/
660/*--- end ---*/
661/*--------------------------------------------------------------------*/