aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2012-06-13 02:32:24 +0200
committerMike Pall <mike>2012-06-13 02:32:24 +0200
commitca6bf2d9a41fb2c0c80bafdbaf2e29421b2cb55d (patch)
tree2489b763b62323fe844789f611325528c1806e82 /src
parent4f9db0fbc3368a7f78370c33740e34cb1d391383 (diff)
downloadluajit-ca6bf2d9a41fb2c0c80bafdbaf2e29421b2cb55d.tar.gz
luajit-ca6bf2d9a41fb2c0c80bafdbaf2e29421b2cb55d.tar.bz2
luajit-ca6bf2d9a41fb2c0c80bafdbaf2e29421b2cb55d.zip
CONSOLE: Handle P64, GPR64, TOC* and PPE (PS3) in PPC interpreter.
PS3 build command: make HOST_CC="gcc -m32" CROSS=ppu-lv2-
Diffstat (limited to 'src')
-rw-r--r--src/Makefile5
-rw-r--r--src/host/buildvm_asm.c9
-rw-r--r--src/lj_arch.h5
-rw-r--r--src/lj_frame.h11
-rw-r--r--src/vm_ppc.dasc610
5 files changed, 456 insertions, 184 deletions
diff --git a/src/Makefile b/src/Makefile
index 58dcdc01..c3aa2ca2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -404,8 +404,11 @@ ifeq (ppc,$(TARGET_LJARCH))
404 ifneq (,$(findstring LJ_ARCH_ROUND 1,$(TARGET_TESTARCH))) 404 ifneq (,$(findstring LJ_ARCH_ROUND 1,$(TARGET_TESTARCH)))
405 DASM_AFLAGS+= -D ROUND 405 DASM_AFLAGS+= -D ROUND
406 endif 406 endif
407 ifneq (,$(findstring LJ_ARCH_PPC64 1,$(TARGET_TESTARCH)))
408 DASM_AFLAGS+= -D GPR64
409 endif
407 ifeq (PS3,$(TARGET_SYS)) 410 ifeq (PS3,$(TARGET_SYS))
408 DASM_AFLAGS+= -D PS3 411 DASM_AFLAGS+= -D PPE -D TOC
409 endif 412 endif
410endif 413endif
411endif 414endif
diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c
index 992c3509..08264c8b 100644
--- a/src/host/buildvm_asm.c
+++ b/src/host/buildvm_asm.c
@@ -108,11 +108,16 @@ static void emit_asm_wordreloc(BuildCtx *ctx, uint8_t *p, int n,
108 exit(1); 108 exit(1);
109 } 109 }
110#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE 110#elif LJ_TARGET_PPC || LJ_TARGET_PPCSPE
111#if LJ_TARGET_PS3
112#define TOCPREFIX "."
113#else
114#define TOCPREFIX ""
115#endif
111 if ((ins >> 26) == 16) { 116 if ((ins >> 26) == 16) {
112 fprintf(ctx->fp, "\t%s %d, %d, %s\n", 117 fprintf(ctx->fp, "\t%s %d, %d, " TOCPREFIX "%s\n",
113 (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym); 118 (ins & 1) ? "bcl" : "bc", (ins >> 21) & 31, (ins >> 16) & 31, sym);
114 } else if ((ins >> 26) == 18) { 119 } else if ((ins >> 26) == 18) {
115 fprintf(ctx->fp, "\t%s %s\n", (ins & 1) ? "bl" : "b", sym); 120 fprintf(ctx->fp, "\t%s " TOCPREFIX "%s\n", (ins & 1) ? "bl" : "b", sym);
116 } else { 121 } else {
117 fprintf(stderr, 122 fprintf(stderr,
118 "Error: unsupported opcode %08x for %s symbol relocation.\n", 123 "Error: unsupported opcode %08x for %s symbol relocation.\n",
diff --git a/src/lj_arch.h b/src/lj_arch.h
index 7604d84b..c9e9b307 100644
--- a/src/lj_arch.h
+++ b/src/lj_arch.h
@@ -174,7 +174,11 @@
174#elif LUAJIT_TARGET == LUAJIT_ARCH_PPC 174#elif LUAJIT_TARGET == LUAJIT_ARCH_PPC
175 175
176#define LJ_ARCH_NAME "ppc" 176#define LJ_ARCH_NAME "ppc"
177#if _LP64
178#define LJ_ARCH_BITS 64
179#else
177#define LJ_ARCH_BITS 32 180#define LJ_ARCH_BITS 32
181#endif
178#define LJ_ARCH_ENDIAN LUAJIT_BE 182#define LJ_ARCH_ENDIAN LUAJIT_BE
179#define LJ_ARCH_HASFPU 1 183#define LJ_ARCH_HASFPU 1
180#define LJ_TARGET_PPC 1 184#define LJ_TARGET_PPC 1
@@ -200,6 +204,7 @@
200#endif 204#endif
201#if __PPC64__ || __powerpc64__ || LJ_TARGET_XBOX360 205#if __PPC64__ || __powerpc64__ || LJ_TARGET_XBOX360
202#define LJ_ARCH_PPC64 1 206#define LJ_ARCH_PPC64 1
207#define LJ_ARCH_NOFFI 1
203#endif 208#endif
204#if _ARCH_PPCSQ 209#if _ARCH_PPCSQ
205#define LJ_ARCH_SQRT 1 210#define LJ_ARCH_SQRT 1
diff --git a/src/lj_frame.h b/src/lj_frame.h
index e5a56897..b8429c2a 100644
--- a/src/lj_frame.h
+++ b/src/lj_frame.h
@@ -100,6 +100,16 @@ enum {
100#define CFRAME_SIZE 64 100#define CFRAME_SIZE 64
101#define CFRAME_SHIFT_MULTRES 3 101#define CFRAME_SHIFT_MULTRES 3
102#elif LJ_TARGET_PPC 102#elif LJ_TARGET_PPC
103#if LJ_ARCH_PPC64
104#define CFRAME_OFS_ERRF 472
105#define CFRAME_OFS_NRES 468
106#define CFRAME_OFS_PREV 448
107#define CFRAME_OFS_L 464
108#define CFRAME_OFS_PC 460
109#define CFRAME_OFS_MULTRES 456
110#define CFRAME_SIZE 400
111#define CFRAME_SHIFT_MULTRES 3
112#else
103#define CFRAME_OFS_ERRF 48 113#define CFRAME_OFS_ERRF 48
104#define CFRAME_OFS_NRES 44 114#define CFRAME_OFS_NRES 44
105#define CFRAME_OFS_PREV 40 115#define CFRAME_OFS_PREV 40
@@ -108,6 +118,7 @@ enum {
108#define CFRAME_OFS_MULTRES 28 118#define CFRAME_OFS_MULTRES 28
109#define CFRAME_SIZE 272 119#define CFRAME_SIZE 272
110#define CFRAME_SHIFT_MULTRES 3 120#define CFRAME_SHIFT_MULTRES 3
121#endif
111#elif LJ_TARGET_PPCSPE 122#elif LJ_TARGET_PPCSPE
112#define CFRAME_OFS_ERRF 28 123#define CFRAME_OFS_ERRF 28
113#define CFRAME_OFS_NRES 24 124#define CFRAME_OFS_NRES 24
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc
index db946190..b84a1fc2 100644
--- a/src/vm_ppc.dasc
+++ b/src/vm_ppc.dasc
@@ -15,6 +15,67 @@
15| 15|
16|//----------------------------------------------------------------------- 16|//-----------------------------------------------------------------------
17| 17|
18|// DynASM defines used by the PPC port:
19|//
20|// P64 64 bit pointers (only for GPR64 testing).
21|// Note: a full PPC64 _LP64 port is not planned.
22|// GPR64 64 bit registers (but possibly 32 bit pointers, e.g. PS3).
23|// Affects reg saves, stack layout, carry/overflow/dot flags etc.
24|// TOC Need table of contents (64 bit or 32 bit variant, e.g. PS3).
25|// Function pointers are really a struct: code, TOC, env (optional).
26|// TOCENV Function pointers have an environment pointer, too (not on PS3).
27|// PPE Power Processor Element of Cell (PS3) or Xenon (XBox 360).
28|// Must avoid (slow) micro-coded instructions.
29|
30|.if P64
31|.define TOC, 1
32|.define TOCENV, 1
33|.macro lpx, a, b, c; ldx a, b, c; .endmacro
34|.macro lp, a, b; ld a, b; .endmacro
35|.macro stp, a, b; std a, b; .endmacro
36|.define decode_OPP, decode_OP8
37|.else
38|.macro lpx, a, b, c; lwzx a, b, c; .endmacro
39|.macro lp, a, b; lwz a, b; .endmacro
40|.macro stp, a, b; stw a, b; .endmacro
41|.define decode_OPP, decode_OP4
42|.if FFI
43|// Missing: Calling conventions, 64 bit regs, TOC.
44|.error lib_ffi not yet implemented for PPC64
45|.endif
46|.endif
47|
48|// Convenience macros for TOC handling.
49|.if TOC
50|// Linker needs a TOC patch area for every external call relocation.
51|.macro blex, target; bl extern target; nop; .endmacro
52|.macro .toc, a, b; a, b; .endmacro
53|.if P64
54|.define TOC_OFS, 8
55|.define ENV_OFS, 16
56|.else
57|.define TOC_OFS, 4
58|.define ENV_OFS, 8
59|.endif
60|.else // No TOC.
61|.macro blex, target; bl extern target; .endmacro
62|.macro .toc, a, b; .endmacro
63|.endif
64|.macro .tocenv, a, b; .if TOCENV; a, b; .endif; .endmacro
65|
66|.macro .gpr64, a, b; .if GPR64; a, b; .endif; .endmacro
67|
68|.macro andix., y, a, i
69|.if PPE
70| rlwinm y, a, 0, 31-lj_fls(i), 31-lj_ffs(i)
71| cmpwi y, 0
72|.else
73| andi. y, a, i
74|.endif
75|.endmacro
76|
77|//-----------------------------------------------------------------------
78|
18|// Fixed register assignments for the interpreter. 79|// Fixed register assignments for the interpreter.
19|// Don't use: r1 = sp, r2 and r13 = reserved (TOC, TLS or SDATA) 80|// Don't use: r1 = sp, r2 and r13 = reserved (TOC, TLS or SDATA)
20| 81|
@@ -62,14 +123,47 @@
62|.define CRET1, r3 123|.define CRET1, r3
63|.define CRET2, r4 124|.define CRET2, r4
64| 125|
126|.define TOCREG, r2 // TOC register (only used by C code).
127|.define ENVREG, r11 // Environment pointer (nested C functions).
128|
65|// Stack layout while in interpreter. Must match with lj_frame.h. 129|// Stack layout while in interpreter. Must match with lj_frame.h.
130|.if GPR64
131|
132|// 508(sp) // \ 32 bit C frame info.
133|.define SAVE_ERRF, 472(sp) // |
134|.define SAVE_NRES, 468(sp) // |
135|.define SAVE_L, 464(sp) // > Parameter save area.
136|.define SAVE_PC, 460(sp) // |
137|.define SAVE_MULTRES, 456(sp) // |
138|.define SAVE_CFRAME, 448(sp) // / 64 bit C frame chain.
139|.define SAVE_LR, 416(sp)
140|.define CFRAME_SPACE, 400 // Delta for sp.
141|// Back chain for sp: 400(sp) <-- sp entering interpreter
142|.define SAVE_FPR_, 256 // .. 256+18*8: 64 bit FPR saves.
143|.define SAVE_GPR_, 112 // .. 112+18*8: 64 bit GPR saves.
144|// 48(sp) // Callee parameter save area (ABI mandated).
145|.define SAVE_TOC, 40(sp) // TOC save area.
146|.define TMPD_LO, 36(sp) // \ Link editor temp (ABI mandated).
147|.define TMPD_HI, 32(sp) // /
148|.define TONUM_LO, 28(sp) // \ Compiler temp (ABI mandated).
149|.define TONUM_HI, 24(sp) // /
150|// Next frame lr: 16(sp)
151|.define SAVE_CR, 8(sp) // 64 bit CR save.
152|// Back chain for sp: 0(sp) <-- sp while in interpreter
153|
154|.define TMPD_BLO, 39(sp)
155|.define TMPD, TMPD_HI
156|.define TONUM_D, TONUM_HI
157|
158|.else
159|
66|.define SAVE_LR, 276(sp) 160|.define SAVE_LR, 276(sp)
67|.define CFRAME_SPACE, 272 // Delta for sp. 161|.define CFRAME_SPACE, 272 // Delta for sp.
68|// Back chain for sp: 272(sp) <-- sp entering interpreter 162|// Back chain for sp: 272(sp) <-- sp entering interpreter
69|.define SAVE_FPR_, 128 // .. 128+18*8: 64 bit FPR saves. 163|.define SAVE_FPR_, 128 // .. 128+18*8: 64 bit FPR saves.
70|.define SAVE_GPR_, 56 // .. 56+18*4: 32 bit GPR saves. 164|.define SAVE_GPR_, 56 // .. 56+18*4: 32 bit GPR saves.
71|.define SAVE_CR, 52(sp) // 32 bit CR save. 165|.define SAVE_CR, 52(sp) // 32 bit CR save.
72|.define SAVE_ERRF, 48(sp) // 32 bit C frame info. 166|.define SAVE_ERRF, 48(sp) // 32 bit C frame info.
73|.define SAVE_NRES, 44(sp) 167|.define SAVE_NRES, 44(sp)
74|.define SAVE_CFRAME, 40(sp) 168|.define SAVE_CFRAME, 40(sp)
75|.define SAVE_L, 36(sp) 169|.define SAVE_L, 36(sp)
@@ -87,33 +181,63 @@
87|.define TMPD, TMPD_HI 181|.define TMPD, TMPD_HI
88|.define TONUM_D, TONUM_HI 182|.define TONUM_D, TONUM_HI
89| 183|
184|.endif
185|
90|.macro save_, reg 186|.macro save_, reg
187|.if GPR64
188| std r..reg, SAVE_GPR_+(reg-14)*8(sp)
189|.else
91| stw r..reg, SAVE_GPR_+(reg-14)*4(sp) 190| stw r..reg, SAVE_GPR_+(reg-14)*4(sp)
191|.endif
92| stfd f..reg, SAVE_FPR_+(reg-14)*8(sp) 192| stfd f..reg, SAVE_FPR_+(reg-14)*8(sp)
93|.endmacro 193|.endmacro
94|.macro rest_, reg 194|.macro rest_, reg
195|.if GPR64
196| ld r..reg, SAVE_GPR_+(reg-14)*8(sp)
197|.else
95| lwz r..reg, SAVE_GPR_+(reg-14)*4(sp) 198| lwz r..reg, SAVE_GPR_+(reg-14)*4(sp)
199|.endif
96| lfd f..reg, SAVE_FPR_+(reg-14)*8(sp) 200| lfd f..reg, SAVE_FPR_+(reg-14)*8(sp)
97|.endmacro 201|.endmacro
98| 202|
99|.macro saveregs 203|.macro saveregs
204|.if GPR64
205| stdu sp, -CFRAME_SPACE(sp)
206|.else
100| stwu sp, -CFRAME_SPACE(sp) 207| stwu sp, -CFRAME_SPACE(sp)
208|.endif
101| save_ 14; save_ 15; save_ 16 209| save_ 14; save_ 15; save_ 16
102| mflr r0 210| mflr r0
103| save_ 17; save_ 18; save_ 19; save_ 20; save_ 21; save_ 22 211| save_ 17; save_ 18; save_ 19; save_ 20; save_ 21; save_ 22
104| stw r0, SAVE_LR 212|.if GPR64
213| std r0, SAVE_LR
214|.else
215| stw r0, SAVE_LR
216|.endif
105| save_ 23; save_ 24; save_ 25 217| save_ 23; save_ 24; save_ 25
106| mfcr r0 218| mfcr r0
107| save_ 26; save_ 27; save_ 28; save_ 29; save_ 30; save_ 31 219| save_ 26; save_ 27; save_ 28; save_ 29; save_ 30; save_ 31
220|.if GPR64
221| std r0, SAVE_CR
222|.else
108| stw r0, SAVE_CR 223| stw r0, SAVE_CR
224|.endif
225| .toc std TOCREG, SAVE_TOC
109|.endmacro 226|.endmacro
110| 227|
111|.macro restoreregs 228|.macro restoreregs
229|.if GPR64
230| ld r0, SAVE_LR; ld r12, SAVE_CR
231|.else
112| lwz r0, SAVE_LR; lwz r12, SAVE_CR 232| lwz r0, SAVE_LR; lwz r12, SAVE_CR
233|.endif
113| rest_ 14; rest_ 15; rest_ 16; rest_ 17; rest_ 18; rest_ 19 234| rest_ 14; rest_ 15; rest_ 16; rest_ 17; rest_ 18; rest_ 19
114| mtlr r0; mtcrf 0x38, r12 235| mtlr r0;
236|.if PPE; mtocrf 0x20, r12; .else; mtcrf 0x38, r12; .endif
115| rest_ 20; rest_ 21; rest_ 22; rest_ 23; rest_ 24; rest_ 25 237| rest_ 20; rest_ 21; rest_ 22; rest_ 23; rest_ 24; rest_ 25
238|.if PPE; mtocrf 0x10, r12; .endif
116| rest_ 26; rest_ 27; rest_ 28; rest_ 29; rest_ 30; rest_ 31 239| rest_ 26; rest_ 27; rest_ 28; rest_ 29; rest_ 30; rest_ 31
240|.if PPE; mtocrf 0x08, r12; .endif
117| addi sp, sp, CFRAME_SPACE 241| addi sp, sp, CFRAME_SPACE
118|.endmacro 242|.endmacro
119| 243|
@@ -176,6 +300,7 @@
176| 300|
177|// Instruction decode. 301|// Instruction decode.
178|.macro decode_OP4, dst, ins; rlwinm dst, ins, 2, 22, 29; .endmacro 302|.macro decode_OP4, dst, ins; rlwinm dst, ins, 2, 22, 29; .endmacro
303|.macro decode_OP8, dst, ins; rlwinm dst, ins, 3, 21, 28; .endmacro
179|.macro decode_RA8, dst, ins; rlwinm dst, ins, 27, 21, 28; .endmacro 304|.macro decode_RA8, dst, ins; rlwinm dst, ins, 27, 21, 28; .endmacro
180|.macro decode_RB8, dst, ins; rlwinm dst, ins, 11, 21, 28; .endmacro 305|.macro decode_RB8, dst, ins; rlwinm dst, ins, 11, 21, 28; .endmacro
181|.macro decode_RC8, dst, ins; rlwinm dst, ins, 19, 21, 28; .endmacro 306|.macro decode_RC8, dst, ins; rlwinm dst, ins, 19, 21, 28; .endmacro
@@ -191,8 +316,8 @@
191|.endmacro 316|.endmacro
192|// Instruction decode+dispatch. Note: optimized for e300! 317|// Instruction decode+dispatch. Note: optimized for e300!
193|.macro ins_NEXT2 318|.macro ins_NEXT2
194| decode_OP4 TMP1, INS 319| decode_OPP TMP1, INS
195| lwzx TMP0, DISPATCH, TMP1 320| lpx TMP0, DISPATCH, TMP1
196| mtctr TMP0 321| mtctr TMP0
197| decode_RB8 RB, INS 322| decode_RB8 RB, INS
198| decode_RD8 RD, INS 323| decode_RD8 RD, INS
@@ -235,9 +360,9 @@
235| lwz PC, LFUNC:RB->pc 360| lwz PC, LFUNC:RB->pc
236| lwz INS, 0(PC) 361| lwz INS, 0(PC)
237| addi PC, PC, 4 362| addi PC, PC, 4
238| decode_OP4 TMP1, INS 363| decode_OPP TMP1, INS
239| decode_RA8 RA, INS 364| decode_RA8 RA, INS
240| lwzx TMP0, DISPATCH, TMP1 365| lpx TMP0, DISPATCH, TMP1
241| add RA, RA, BASE 366| add RA, RA, BASE
242| mtctr TMP0 367| mtctr TMP0
243| bctr 368| bctr
@@ -316,7 +441,7 @@ static void build_subroutines(BuildCtx *ctx)
316 | 441 |
317 |->vm_returnp: 442 |->vm_returnp:
318 | // See vm_return. Also: TMP2 = previous base. 443 | // See vm_return. Also: TMP2 = previous base.
319 | andi. TMP0, PC, FRAME_P 444 | andix. TMP0, PC, FRAME_P
320 | li TMP1, LJ_TTRUE 445 | li TMP1, LJ_TTRUE
321 | beq ->cont_dispatch 446 | beq ->cont_dispatch
322 | 447 |
@@ -327,7 +452,7 @@ static void build_subroutines(BuildCtx *ctx)
327 | stwu TMP1, FRAME_PC(RA) // Prepend true to results. 452 | stwu TMP1, FRAME_PC(RA) // Prepend true to results.
328 | 453 |
329 |->vm_returnc: 454 |->vm_returnc:
330 | andi. TMP0, PC, FRAME_TYPE 455 | andix. TMP0, PC, FRAME_TYPE
331 | addi RD, RD, 8 // RD = (nresults+1)*8. 456 | addi RD, RD, 8 // RD = (nresults+1)*8.
332 | mr MULTRES, RD 457 | mr MULTRES, RD
333 | beq ->BC_RET_Z // Handle regular return to Lua. 458 | beq ->BC_RET_Z // Handle regular return to Lua.
@@ -342,7 +467,7 @@ static void build_subroutines(BuildCtx *ctx)
342 | bney ->vm_returnp 467 | bney ->vm_returnp
343 | 468 |
344 | addic. TMP1, RD, -8 469 | addic. TMP1, RD, -8
345 | stw TMP2, L->base 470 | stp TMP2, L->base
346 | lwz TMP2, SAVE_NRES 471 | lwz TMP2, SAVE_NRES
347 | subi BASE, BASE, 8 472 | subi BASE, BASE, 8
348 | st_vmstate 473 | st_vmstate
@@ -360,12 +485,12 @@ static void build_subroutines(BuildCtx *ctx)
360 | cmpw TMP2, RD // More/less results wanted? 485 | cmpw TMP2, RD // More/less results wanted?
361 | bne >6 486 | bne >6
362 |3: 487 |3:
363 | stw BASE, L->top // Store new top. 488 | stp BASE, L->top // Store new top.
364 | 489 |
365 |->vm_leave_cp: 490 |->vm_leave_cp:
366 | lwz TMP0, SAVE_CFRAME // Restore previous C frame. 491 | lp TMP0, SAVE_CFRAME // Restore previous C frame.
367 | li CRET1, 0 // Ok return status for vm_pcall. 492 | li CRET1, 0 // Ok return status for vm_pcall.
368 | stw TMP0, L->cframe 493 | stp TMP0, L->cframe
369 | 494 |
370 |->vm_leave_unw: 495 |->vm_leave_unw:
371 | restoreregs 496 | restoreregs
@@ -395,7 +520,7 @@ static void build_subroutines(BuildCtx *ctx)
395 | // - A C function grows the stack (a lot). 520 | // - A C function grows the stack (a lot).
396 | // - The GC shrinks the stack in between. 521 | // - The GC shrinks the stack in between.
397 | // - A return back from a lua_call() with (high) nresults adjustment. 522 | // - A return back from a lua_call() with (high) nresults adjustment.
398 | stw BASE, L->top // Save current top held in BASE (yes). 523 | stp BASE, L->top // Save current top held in BASE (yes).
399 | mr SAVE0, RD 524 | mr SAVE0, RD
400 | mr CARG2, TMP2 525 | mr CARG2, TMP2
401 | mr CARG1, L 526 | mr CARG1, L
@@ -403,7 +528,7 @@ static void build_subroutines(BuildCtx *ctx)
403 | lwz TMP2, SAVE_NRES 528 | lwz TMP2, SAVE_NRES
404 | mr RD, SAVE0 529 | mr RD, SAVE0
405 | slwi TMP2, TMP2, 3 530 | slwi TMP2, TMP2, 3
406 | lwz BASE, L->top // Need the (realloced) L->top in BASE. 531 | lp BASE, L->top // Need the (realloced) L->top in BASE.
407 | b <2 532 | b <2
408 | 533 |
409 |->vm_unwind_c: // Unwind C stack, return from vm_pcall. 534 |->vm_unwind_c: // Unwind C stack, return from vm_pcall.
@@ -412,6 +537,7 @@ static void build_subroutines(BuildCtx *ctx)
412 | mr CRET1, CARG2 537 | mr CRET1, CARG2
413 |->vm_unwind_c_eh: // Landing pad for external unwinder. 538 |->vm_unwind_c_eh: // Landing pad for external unwinder.
414 | lwz L, SAVE_L 539 | lwz L, SAVE_L
540 | .toc ld TOCREG, SAVE_TOC
415 | li TMP0, ~LJ_VMST_C 541 | li TMP0, ~LJ_VMST_C
416 | lwz GL:TMP1, L->glref 542 | lwz GL:TMP1, L->glref
417 | stw TMP0, GL:TMP1->vmstate 543 | stw TMP0, GL:TMP1->vmstate
@@ -419,11 +545,16 @@ static void build_subroutines(BuildCtx *ctx)
419 | 545 |
420 |->vm_unwind_ff: // Unwind C stack, return from ff pcall. 546 |->vm_unwind_ff: // Unwind C stack, return from ff pcall.
421 | // (void *cframe) 547 | // (void *cframe)
548 |.if GPR64
549 | rldicr sp, CARG1, 0, 61
550 |.else
422 | rlwinm sp, CARG1, 0, 0, 29 551 | rlwinm sp, CARG1, 0, 0, 29
552 |.endif
423 |->vm_unwind_ff_eh: // Landing pad for external unwinder. 553 |->vm_unwind_ff_eh: // Landing pad for external unwinder.
424 | lwz L, SAVE_L 554 | lwz L, SAVE_L
555 | .toc ld TOCREG, SAVE_TOC
425 | li TISNUM, LJ_TISNUM // Setup type comparison constants. 556 | li TISNUM, LJ_TISNUM // Setup type comparison constants.
426 | lwz BASE, L->base 557 | lp BASE, L->base
427 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). 558 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
428 | lwz DISPATCH, L->glref // Setup pointer to dispatch table. 559 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
429 | li ZERO, 0 560 | li ZERO, 0
@@ -455,17 +586,17 @@ static void build_subroutines(BuildCtx *ctx)
455 | // BASE = new base, RA = BASE+framesize*8, RC = nargs*8, PC = first PC 586 | // BASE = new base, RA = BASE+framesize*8, RC = nargs*8, PC = first PC
456 | add RC, BASE, RC 587 | add RC, BASE, RC
457 | sub RA, RA, BASE 588 | sub RA, RA, BASE
458 | stw BASE, L->base 589 | stp BASE, L->base
459 | addi PC, PC, 4 // Must point after first instruction. 590 | addi PC, PC, 4 // Must point after first instruction.
460 | stw RC, L->top 591 | stp RC, L->top
461 | srwi CARG2, RA, 3 592 | srwi CARG2, RA, 3
462 |2: 593 |2:
463 | // L->base = new base, L->top = top 594 | // L->base = new base, L->top = top
464 | stw PC, SAVE_PC 595 | stw PC, SAVE_PC
465 | mr CARG1, L 596 | mr CARG1, L
466 | bl extern lj_state_growstack // (lua_State *L, int n) 597 | bl extern lj_state_growstack // (lua_State *L, int n)
467 | lwz BASE, L->base 598 | lp BASE, L->base
468 | lwz RC, L->top 599 | lp RC, L->top
469 | lwz LFUNC:RB, FRAME_FUNC(BASE) 600 | lwz LFUNC:RB, FRAME_FUNC(BASE)
470 | sub RC, RC, BASE 601 | sub RC, RC, BASE
471 | // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC 602 | // BASE = new base, RB = LFUNC/CFUNC, RC = nargs*8, FRAME_PC(BASE) = PC
@@ -489,16 +620,16 @@ static void build_subroutines(BuildCtx *ctx)
489 | stw CARG3, SAVE_NRES 620 | stw CARG3, SAVE_NRES
490 | cmplwi TMP1, 0 621 | cmplwi TMP1, 0
491 | stw CARG3, SAVE_ERRF 622 | stw CARG3, SAVE_ERRF
492 | stw TMP0, L->cframe 623 | stp TMP0, L->cframe
493 | stw CARG3, SAVE_CFRAME 624 | stp CARG3, SAVE_CFRAME
494 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok. 625 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
495 | beq >3 626 | beq >3
496 | 627 |
497 | // Resume after yield (like a return). 628 | // Resume after yield (like a return).
498 | mr RA, BASE 629 | mr RA, BASE
499 | lwz BASE, L->base 630 | lp BASE, L->base
500 | li TISNUM, LJ_TISNUM // Setup type comparison constants. 631 | li TISNUM, LJ_TISNUM // Setup type comparison constants.
501 | lwz TMP1, L->top 632 | lp TMP1, L->top
502 | lwz PC, FRAME_PC(BASE) 633 | lwz PC, FRAME_PC(BASE)
503 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). 634 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
504 | stb CARG3, L->status 635 | stb CARG3, L->status
@@ -513,7 +644,7 @@ static void build_subroutines(BuildCtx *ctx)
513 | li_vmstate INTERP 644 | li_vmstate INTERP
514 | li ZERO, 0 645 | li ZERO, 0
515 | st_vmstate 646 | st_vmstate
516 | andi. TMP0, PC, FRAME_TYPE 647 | andix. TMP0, PC, FRAME_TYPE
517 | mr MULTRES, RD 648 | mr MULTRES, RD
518 | lfs TONUM, TMPD 649 | lfs TONUM, TMPD
519 | li TISNIL, LJ_TNIL 650 | li TISNIL, LJ_TNIL
@@ -533,21 +664,21 @@ static void build_subroutines(BuildCtx *ctx)
533 | li PC, FRAME_C 664 | li PC, FRAME_C
534 | 665 |
535 |1: // Entry point for vm_pcall above (PC = ftype). 666 |1: // Entry point for vm_pcall above (PC = ftype).
536 | lwz TMP1, L:CARG1->cframe 667 | lp TMP1, L:CARG1->cframe
537 | stw CARG3, SAVE_NRES 668 | stw CARG3, SAVE_NRES
538 | mr L, CARG1 669 | mr L, CARG1
539 | stw CARG1, SAVE_L 670 | stw CARG1, SAVE_L
540 | mr BASE, CARG2 671 | mr BASE, CARG2
541 | stw sp, L->cframe // Add our C frame to cframe chain. 672 | stp sp, L->cframe // Add our C frame to cframe chain.
542 | lwz DISPATCH, L->glref // Setup pointer to dispatch table. 673 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
543 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok. 674 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
544 | stw TMP1, SAVE_CFRAME 675 | stp TMP1, SAVE_CFRAME
545 | addi DISPATCH, DISPATCH, GG_G2DISP 676 | addi DISPATCH, DISPATCH, GG_G2DISP
546 | 677 |
547 |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). 678 |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
548 | lwz TMP2, L->base // TMP2 = old base (used in vmeta_call). 679 | lp TMP2, L->base // TMP2 = old base (used in vmeta_call).
549 | li TISNUM, LJ_TISNUM // Setup type comparison constants. 680 | li TISNUM, LJ_TISNUM // Setup type comparison constants.
550 | lwz TMP1, L->top 681 | lp TMP1, L->top
551 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). 682 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
552 | add PC, PC, BASE 683 | add PC, PC, BASE
553 | stw TMP3, TMPD 684 | stw TMP3, TMPD
@@ -580,18 +711,24 @@ static void build_subroutines(BuildCtx *ctx)
580 | mr L, CARG1 711 | mr L, CARG1
581 | lwz TMP0, L:CARG1->stack 712 | lwz TMP0, L:CARG1->stack
582 | stw CARG1, SAVE_L 713 | stw CARG1, SAVE_L
583 | lwz TMP1, L->top 714 | lp TMP1, L->top
584 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok. 715 | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
585 | sub TMP0, TMP0, TMP1 // Compute -savestack(L, L->top). 716 | sub TMP0, TMP0, TMP1 // Compute -savestack(L, L->top).
586 | lwz TMP1, L->cframe 717 | lp TMP1, L->cframe
587 | stw sp, L->cframe // Add our C frame to cframe chain. 718 | stp sp, L->cframe // Add our C frame to cframe chain.
719 | .toc lp CARG4, 0(CARG4)
588 | li TMP2, 0 720 | li TMP2, 0
589 | stw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame. 721 | stw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame.
590 | stw TMP2, SAVE_ERRF // No error function. 722 | stw TMP2, SAVE_ERRF // No error function.
591 | stw TMP1, SAVE_CFRAME 723 | stp TMP1, SAVE_CFRAME
592 | mtctr CARG4 724 | mtctr CARG4
593 | bctrl // (lua_State *L, lua_CFunction func, void *ud) 725 | bctrl // (lua_State *L, lua_CFunction func, void *ud)
726 |.if PPE
727 | mr BASE, CRET1
728 | cmpwi CRET1, 0
729 |.else
594 | mr. BASE, CRET1 730 | mr. BASE, CRET1
731 |.endif
595 | lwz DISPATCH, L->glref // Setup pointer to dispatch table. 732 | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
596 | li PC, FRAME_CP 733 | li PC, FRAME_CP
597 | addi DISPATCH, DISPATCH, GG_G2DISP 734 | addi DISPATCH, DISPATCH, GG_G2DISP
@@ -643,7 +780,7 @@ static void build_subroutines(BuildCtx *ctx)
643 | decode_RB8 SAVE0, INS 780 | decode_RB8 SAVE0, INS
644 | lfd f0, 0(RA) 781 | lfd f0, 0(RA)
645 | add TMP1, BASE, SAVE0 782 | add TMP1, BASE, SAVE0
646 | stw BASE, L->base 783 | stp BASE, L->base
647 | cmplw TMP1, CARG2 784 | cmplw TMP1, CARG2
648 | sub CARG3, CARG2, TMP1 785 | sub CARG3, CARG2, TMP1
649 | decode_RA8 RA, INS 786 | decode_RA8 RA, INS
@@ -695,7 +832,7 @@ static void build_subroutines(BuildCtx *ctx)
695 | add CARG2, BASE, RB 832 | add CARG2, BASE, RB
696 | add CARG3, BASE, RC 833 | add CARG3, BASE, RC
697 |1: 834 |1:
698 | stw BASE, L->base 835 | stp BASE, L->base
699 | mr CARG1, L 836 | mr CARG1, L
700 | stw PC, SAVE_PC 837 | stw PC, SAVE_PC
701 | bl extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k) 838 | bl extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
@@ -710,7 +847,7 @@ static void build_subroutines(BuildCtx *ctx)
710 |3: // Call __index metamethod. 847 |3: // Call __index metamethod.
711 | // BASE = base, L->top = new base, stack = cont/func/t/k 848 | // BASE = base, L->top = new base, stack = cont/func/t/k
712 | subfic TMP1, BASE, FRAME_CONT 849 | subfic TMP1, BASE, FRAME_CONT
713 | lwz BASE, L->top 850 | lp BASE, L->top
714 | stw PC, -16(BASE) // [cont|PC] 851 | stw PC, -16(BASE) // [cont|PC]
715 | add PC, TMP1, BASE 852 | add PC, TMP1, BASE
716 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here. 853 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
@@ -760,7 +897,7 @@ static void build_subroutines(BuildCtx *ctx)
760 | add CARG2, BASE, RB 897 | add CARG2, BASE, RB
761 | add CARG3, BASE, RC 898 | add CARG3, BASE, RC
762 |1: 899 |1:
763 | stw BASE, L->base 900 | stp BASE, L->base
764 | mr CARG1, L 901 | mr CARG1, L
765 | stw PC, SAVE_PC 902 | stw PC, SAVE_PC
766 | bl extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k) 903 | bl extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
@@ -776,7 +913,7 @@ static void build_subroutines(BuildCtx *ctx)
776 |3: // Call __newindex metamethod. 913 |3: // Call __newindex metamethod.
777 | // BASE = base, L->top = new base, stack = cont/func/t/k/(v) 914 | // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
778 | subfic TMP1, BASE, FRAME_CONT 915 | subfic TMP1, BASE, FRAME_CONT
779 | lwz BASE, L->top 916 | lp BASE, L->top
780 | stw PC, -16(BASE) // [cont|PC] 917 | stw PC, -16(BASE) // [cont|PC]
781 | add PC, TMP1, BASE 918 | add PC, TMP1, BASE
782 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here. 919 | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here.
@@ -800,7 +937,7 @@ static void build_subroutines(BuildCtx *ctx)
800 |.else 937 |.else
801 | add CARG3, BASE, RD 938 | add CARG3, BASE, RD
802 |.endif 939 |.endif
803 | stw BASE, L->base 940 | stp BASE, L->base
804 | decode_OP1 CARG4, INS 941 | decode_OP1 CARG4, INS
805 | bl extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op) 942 | bl extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
806 | // Returns 0/1 or TValue * (metamethod). 943 | // Returns 0/1 or TValue * (metamethod).
@@ -827,6 +964,7 @@ static void build_subroutines(BuildCtx *ctx)
827 | 964 |
828 |->cont_condt: // RA = resultptr 965 |->cont_condt: // RA = resultptr
829 | lwz TMP0, 0(RA) 966 | lwz TMP0, 0(RA)
967 | .gpr64 extsw TMP0, TMP0
830 | subfic TMP0, TMP0, LJ_TTRUE // Branch if result is true. 968 | subfic TMP0, TMP0, LJ_TTRUE // Branch if result is true.
831 | subfe CRET1, CRET1, CRET1 969 | subfe CRET1, CRET1, CRET1
832 | not CRET1, CRET1 970 | not CRET1, CRET1
@@ -834,6 +972,7 @@ static void build_subroutines(BuildCtx *ctx)
834 | 972 |
835 |->cont_condf: // RA = resultptr 973 |->cont_condf: // RA = resultptr
836 | lwz TMP0, 0(RA) 974 | lwz TMP0, 0(RA)
975 | .gpr64 extsw TMP0, TMP0
837 | subfic TMP0, TMP0, LJ_TTRUE // Branch if result is false. 976 | subfic TMP0, TMP0, LJ_TTRUE // Branch if result is false.
838 | subfe CRET1, CRET1, CRET1 977 | subfe CRET1, CRET1, CRET1
839 | b <4 978 | b <4
@@ -841,7 +980,7 @@ static void build_subroutines(BuildCtx *ctx)
841 |->vmeta_equal: 980 |->vmeta_equal:
842 | // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV. 981 | // CARG2, CARG3, CARG4 are already set by BC_ISEQV/BC_ISNEV.
843 | subi PC, PC, 4 982 | subi PC, PC, 4
844 | stw BASE, L->base 983 | stp BASE, L->base
845 | mr CARG1, L 984 | mr CARG1, L
846 | stw PC, SAVE_PC 985 | stw PC, SAVE_PC
847 | bl extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne) 986 | bl extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
@@ -852,7 +991,7 @@ static void build_subroutines(BuildCtx *ctx)
852 |.if FFI 991 |.if FFI
853 | mr CARG2, INS 992 | mr CARG2, INS
854 | subi PC, PC, 4 993 | subi PC, PC, 4
855 | stw BASE, L->base 994 | stp BASE, L->base
856 | mr CARG1, L 995 | mr CARG1, L
857 | stw PC, SAVE_PC 996 | stw PC, SAVE_PC
858 | bl extern lj_meta_equal_cd // (lua_State *L, BCIns op) 997 | bl extern lj_meta_equal_cd // (lua_State *L, BCIns op)
@@ -897,7 +1036,7 @@ static void build_subroutines(BuildCtx *ctx)
897 |.endif 1036 |.endif
898 |1: 1037 |1:
899 | add CARG2, BASE, RA 1038 | add CARG2, BASE, RA
900 | stw BASE, L->base 1039 | stp BASE, L->base
901 | mr CARG1, L 1040 | mr CARG1, L
902 | stw PC, SAVE_PC 1041 | stw PC, SAVE_PC
903 | decode_OP1 CARG5, INS // Caveat: CARG5 overlaps INS. 1042 | decode_OP1 CARG5, INS // Caveat: CARG5 overlaps INS.
@@ -922,7 +1061,7 @@ static void build_subroutines(BuildCtx *ctx)
922 | mr SAVE0, CARG1 1061 | mr SAVE0, CARG1
923#endif 1062#endif
924 | mr CARG2, RD 1063 | mr CARG2, RD
925 | stw BASE, L->base 1064 | stp BASE, L->base
926 | mr CARG1, L 1065 | mr CARG1, L
927 | stw PC, SAVE_PC 1066 | stw PC, SAVE_PC
928 | bl extern lj_meta_len // (lua_State *L, TValue *o) 1067 | bl extern lj_meta_len // (lua_State *L, TValue *o)
@@ -941,7 +1080,7 @@ static void build_subroutines(BuildCtx *ctx)
941 |->vmeta_call: // Resolve and call __call metamethod. 1080 |->vmeta_call: // Resolve and call __call metamethod.
942 | // TMP2 = old base, BASE = new base, RC = nargs*8 1081 | // TMP2 = old base, BASE = new base, RC = nargs*8
943 | mr CARG1, L 1082 | mr CARG1, L
944 | stw TMP2, L->base // This is the callers base! 1083 | stp TMP2, L->base // This is the callers base!
945 | subi CARG2, BASE, 8 1084 | subi CARG2, BASE, 8
946 | stw PC, SAVE_PC 1085 | stw PC, SAVE_PC
947 | add CARG3, BASE, RC 1086 | add CARG3, BASE, RC
@@ -954,7 +1093,7 @@ static void build_subroutines(BuildCtx *ctx)
954 |->vmeta_callt: // Resolve __call for BC_CALLT. 1093 |->vmeta_callt: // Resolve __call for BC_CALLT.
955 | // BASE = old base, RA = new base, RC = nargs*8 1094 | // BASE = old base, RA = new base, RC = nargs*8
956 | mr CARG1, L 1095 | mr CARG1, L
957 | stw BASE, L->base 1096 | stp BASE, L->base
958 | subi CARG2, RA, 8 1097 | subi CARG2, RA, 8
959 | stw PC, SAVE_PC 1098 | stw PC, SAVE_PC
960 | add CARG3, RA, RC 1099 | add CARG3, RA, RC
@@ -969,7 +1108,7 @@ static void build_subroutines(BuildCtx *ctx)
969 | 1108 |
970 |->vmeta_for: 1109 |->vmeta_for:
971 | mr CARG1, L 1110 | mr CARG1, L
972 | stw BASE, L->base 1111 | stp BASE, L->base
973 | mr CARG2, RA 1112 | mr CARG2, RA
974 | stw PC, SAVE_PC 1113 | stw PC, SAVE_PC
975 | mr SAVE0, INS 1114 | mr SAVE0, INS
@@ -1068,6 +1207,7 @@ static void build_subroutines(BuildCtx *ctx)
1068 | cmplwi NARGS8:RC, 8 1207 | cmplwi NARGS8:RC, 8
1069 | lwz CARG1, 0(BASE) 1208 | lwz CARG1, 0(BASE)
1070 | blt ->fff_fallback 1209 | blt ->fff_fallback
1210 | .gpr64 extsw CARG1, CARG1
1071 | subfc TMP0, TISNUM, CARG1 1211 | subfc TMP0, TISNUM, CARG1
1072 | subfe TMP2, CARG1, CARG1 1212 | subfe TMP2, CARG1, CARG1
1073 | orc TMP1, TMP2, TMP0 1213 | orc TMP1, TMP2, TMP0
@@ -1118,6 +1258,7 @@ static void build_subroutines(BuildCtx *ctx)
1118 | 1258 |
1119 |6: 1259 |6:
1120 | cmpwi CARG3, LJ_TUDATA; beq <1 1260 | cmpwi CARG3, LJ_TUDATA; beq <1
1261 | .gpr64 extsw CARG3, CARG3
1121 | subfc TMP0, TISNUM, CARG3 1262 | subfc TMP0, TISNUM, CARG3
1122 | subfe TMP2, CARG3, CARG3 1263 | subfe TMP2, CARG3, CARG3
1123 | orc TMP1, TMP2, TMP0 1264 | orc TMP1, TMP2, TMP0
@@ -1135,7 +1276,7 @@ static void build_subroutines(BuildCtx *ctx)
1135 | cmplwi TAB:TMP1, 0 1276 | cmplwi TAB:TMP1, 0
1136 | lbz TMP3, TAB:CARG1->marked 1277 | lbz TMP3, TAB:CARG1->marked
1137 | bne ->fff_fallback 1278 | bne ->fff_fallback
1138 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table) 1279 | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
1139 | stw TAB:CARG2, TAB:CARG1->metatable 1280 | stw TAB:CARG2, TAB:CARG1->metatable
1140 | beq ->fff_restv 1281 | beq ->fff_restv
1141 | barrierback TAB:CARG1, TMP3, TMP0 1282 | barrierback TAB:CARG1, TMP3, TMP0
@@ -1174,7 +1315,7 @@ static void build_subroutines(BuildCtx *ctx)
1174 | lwz TMP0, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH) 1315 | lwz TMP0, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])(DISPATCH)
1175 | checknum CARG3 1316 | checknum CARG3
1176 | cmplwi cr1, TMP0, 0 1317 | cmplwi cr1, TMP0, 0
1177 | stw BASE, L->base // Add frame since C call can throw. 1318 | stp BASE, L->base // Add frame since C call can throw.
1178 | crorc 4*cr0+eq, 4*cr0+gt, 4*cr1+eq 1319 | crorc 4*cr0+eq, 4*cr0+gt, 4*cr1+eq
1179 | stw PC, SAVE_PC // Redundant (but a defined value). 1320 | stw PC, SAVE_PC // Redundant (but a defined value).
1180 | beq ->fff_fallback 1321 | beq ->fff_fallback
@@ -1201,9 +1342,9 @@ static void build_subroutines(BuildCtx *ctx)
1201 | checktab CARG1 1342 | checktab CARG1
1202 | lwz PC, FRAME_PC(BASE) 1343 | lwz PC, FRAME_PC(BASE)
1203 | bne ->fff_fallback 1344 | bne ->fff_fallback
1204 | stw BASE, L->base // Add frame since C call can throw. 1345 | stp BASE, L->base // Add frame since C call can throw.
1205 | mr CARG1, L 1346 | mr CARG1, L
1206 | stw BASE, L->top // Dummy frame length is ok. 1347 | stp BASE, L->top // Dummy frame length is ok.
1207 | la CARG3, 8(BASE) 1348 | la CARG3, 8(BASE)
1208 | stw PC, SAVE_PC 1349 | stw PC, SAVE_PC
1209 | bl extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key) 1350 | bl extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
@@ -1372,10 +1513,10 @@ static void build_subroutines(BuildCtx *ctx)
1372 | lwz L:CARG1, CFUNC:RB->upvalue[0].gcr 1513 | lwz L:CARG1, CFUNC:RB->upvalue[0].gcr
1373 |.endif 1514 |.endif
1374 | lbz TMP0, L:CARG1->status 1515 | lbz TMP0, L:CARG1->status
1375 | lwz TMP1, L:CARG1->cframe 1516 | lp TMP1, L:CARG1->cframe
1376 | lwz CARG2, L:CARG1->top 1517 | lp CARG2, L:CARG1->top
1377 | cmplwi cr0, TMP0, LUA_YIELD 1518 | cmplwi cr0, TMP0, LUA_YIELD
1378 | lwz TMP2, L:CARG1->base 1519 | lp TMP2, L:CARG1->base
1379 | cmplwi cr1, TMP1, 0 1520 | cmplwi cr1, TMP1, 0
1380 | lwz TMP0, L:CARG1->maxstack 1521 | lwz TMP0, L:CARG1->maxstack
1381 | cmplw cr7, CARG2, TMP2 1522 | cmplw cr7, CARG2, TMP2
@@ -1387,7 +1528,7 @@ static void build_subroutines(BuildCtx *ctx)
1387 | cror 4*cr6+lt, 4*cr6+lt, 4*cr6+gt 1528 | cror 4*cr6+lt, 4*cr6+lt, 4*cr6+gt
1388 | stw PC, SAVE_PC 1529 | stw PC, SAVE_PC
1389 | cror 4*cr6+lt, 4*cr6+lt, 4*cr1+gt // cond1 || cond2 || stackov 1530 | cror 4*cr6+lt, 4*cr6+lt, 4*cr1+gt // cond1 || cond2 || stackov
1390 | stw BASE, L->base 1531 | stp BASE, L->base
1391 | blt cr6, ->fff_fallback 1532 | blt cr6, ->fff_fallback
1392 |1: 1533 |1:
1393 |.if resume 1534 |.if resume
@@ -1395,9 +1536,9 @@ static void build_subroutines(BuildCtx *ctx)
1395 | subi NARGS8:RC, NARGS8:RC, 8 1536 | subi NARGS8:RC, NARGS8:RC, 8
1396 | subi TMP2, TMP2, 8 1537 | subi TMP2, TMP2, 8
1397 |.endif 1538 |.endif
1398 | stw TMP2, L:CARG1->top 1539 | stp TMP2, L:CARG1->top
1399 | li TMP1, 0 1540 | li TMP1, 0
1400 | stw BASE, L->top 1541 | stp BASE, L->top
1401 |2: // Move args to coroutine. 1542 |2: // Move args to coroutine.
1402 | cmpw TMP1, NARGS8:RC 1543 | cmpw TMP1, NARGS8:RC
1403 | lfdx f0, BASE, TMP1 1544 | lfdx f0, BASE, TMP1
@@ -1412,11 +1553,11 @@ static void build_subroutines(BuildCtx *ctx)
1412 | bl ->vm_resume // (lua_State *L, TValue *base, 0, 0) 1553 | bl ->vm_resume // (lua_State *L, TValue *base, 0, 0)
1413 | // Returns thread status. 1554 | // Returns thread status.
1414 |4: 1555 |4:
1415 | lwz TMP2, L:SAVE0->base 1556 | lp TMP2, L:SAVE0->base
1416 | cmplwi CRET1, LUA_YIELD 1557 | cmplwi CRET1, LUA_YIELD
1417 | lwz TMP3, L:SAVE0->top 1558 | lp TMP3, L:SAVE0->top
1418 | li_vmstate INTERP 1559 | li_vmstate INTERP
1419 | lwz BASE, L->base 1560 | lp BASE, L->base
1420 | st_vmstate 1561 | st_vmstate
1421 | bgt >8 1562 | bgt >8
1422 | sub RD, TMP3, TMP2 1563 | sub RD, TMP3, TMP2
@@ -1429,7 +1570,7 @@ static void build_subroutines(BuildCtx *ctx)
1429 | bgt >9 // Need to grow stack? 1570 | bgt >9 // Need to grow stack?
1430 | 1571 |
1431 | subi TMP3, RD, 8 1572 | subi TMP3, RD, 8
1432 | stw TMP2, L:SAVE0->top // Clear coroutine stack. 1573 | stp TMP2, L:SAVE0->top // Clear coroutine stack.
1433 |5: // Move results from coroutine. 1574 |5: // Move results from coroutine.
1434 | cmplw TMP1, TMP3 1575 | cmplw TMP1, TMP3
1435 | lfdx f0, TMP2, TMP1 1576 | lfdx f0, TMP2, TMP1
@@ -1437,7 +1578,7 @@ static void build_subroutines(BuildCtx *ctx)
1437 | addi TMP1, TMP1, 8 1578 | addi TMP1, TMP1, 8
1438 | bne <5 1579 | bne <5
1439 |6: 1580 |6:
1440 | andi. TMP0, PC, FRAME_TYPE 1581 | andix. TMP0, PC, FRAME_TYPE
1441 |.if resume 1582 |.if resume
1442 | li TMP1, LJ_TTRUE 1583 | li TMP1, LJ_TTRUE
1443 | la RA, -8(BASE) 1584 | la RA, -8(BASE)
@@ -1455,11 +1596,11 @@ static void build_subroutines(BuildCtx *ctx)
1455 | 1596 |
1456 |8: // Coroutine returned with error (at co->top-1). 1597 |8: // Coroutine returned with error (at co->top-1).
1457 |.if resume 1598 |.if resume
1458 | andi. TMP0, PC, FRAME_TYPE 1599 | andix. TMP0, PC, FRAME_TYPE
1459 | la TMP3, -8(TMP3) 1600 | la TMP3, -8(TMP3)
1460 | li TMP1, LJ_TFALSE 1601 | li TMP1, LJ_TFALSE
1461 | lfd f0, 0(TMP3) 1602 | lfd f0, 0(TMP3)
1462 | stw TMP3, L:SAVE0->top // Remove error from coroutine stack. 1603 | stp TMP3, L:SAVE0->top // Remove error from coroutine stack.
1463 | li RD, (2+1)*8 1604 | li RD, (2+1)*8
1464 | stw TMP1, -8(BASE) // Prepend false to results. 1605 | stw TMP1, -8(BASE) // Prepend false to results.
1465 | la RA, -8(BASE) 1606 | la RA, -8(BASE)
@@ -1483,14 +1624,14 @@ static void build_subroutines(BuildCtx *ctx)
1483 | coroutine_resume_wrap 0 // coroutine.wrap 1624 | coroutine_resume_wrap 0 // coroutine.wrap
1484 | 1625 |
1485 |.ffunc coroutine_yield 1626 |.ffunc coroutine_yield
1486 | lwz TMP0, L->cframe 1627 | lp TMP0, L->cframe
1487 | add TMP1, BASE, NARGS8:RC 1628 | add TMP1, BASE, NARGS8:RC
1488 | stw BASE, L->base 1629 | stp BASE, L->base
1489 | andi. TMP0, TMP0, CFRAME_RESUME 1630 | andix. TMP0, TMP0, CFRAME_RESUME
1490 | stw TMP1, L->top 1631 | stp TMP1, L->top
1491 | li CRET1, LUA_YIELD 1632 | li CRET1, LUA_YIELD
1492 | beq ->fff_fallback 1633 | beq ->fff_fallback
1493 | stw ZERO, L->cframe 1634 | stp ZERO, L->cframe
1494 | stb CRET1, L->status 1635 | stb CRET1, L->status
1495 | b ->vm_leave_unw 1636 | b ->vm_leave_unw
1496 | 1637 |
@@ -1502,8 +1643,15 @@ static void build_subroutines(BuildCtx *ctx)
1502 | bne >2 1643 | bne >2
1503 | srawi TMP1, CARG1, 31 1644 | srawi TMP1, CARG1, 31
1504 | xor TMP2, TMP1, CARG1 1645 | xor TMP2, TMP1, CARG1
1646 |.if GPR64
1647 | lus TMP0, 0x8000
1648 | sub CARG1, TMP2, TMP1
1649 | cmplw CARG1, TMP0
1650 | beq >1
1651 |.else
1505 | sub. CARG1, TMP2, TMP1 1652 | sub. CARG1, TMP2, TMP1
1506 | blt >1 1653 | blt >1
1654 |.endif
1507 |->fff_resi: 1655 |->fff_resi:
1508 | lwz PC, FRAME_PC(BASE) 1656 | lwz PC, FRAME_PC(BASE)
1509 | la RA, -8(BASE) 1657 | la RA, -8(BASE)
@@ -1531,7 +1679,7 @@ static void build_subroutines(BuildCtx *ctx)
1531 | li RD, (1+1)*8 1679 | li RD, (1+1)*8
1532 |->fff_res: 1680 |->fff_res:
1533 | // RA = results, RD = (nresults+1)*8, PC = return. 1681 | // RA = results, RD = (nresults+1)*8, PC = return.
1534 | andi. TMP0, PC, FRAME_TYPE 1682 | andix. TMP0, PC, FRAME_TYPE
1535 | mr MULTRES, RD 1683 | mr MULTRES, RD
1536 | bney ->vm_return 1684 | bney ->vm_return
1537 | lwz INS, -4(PC) 1685 | lwz INS, -4(PC)
@@ -1553,13 +1701,13 @@ static void build_subroutines(BuildCtx *ctx)
1553 | 1701 |
1554 |.macro math_extern, func 1702 |.macro math_extern, func
1555 | .ffunc_n math_ .. func 1703 | .ffunc_n math_ .. func
1556 | bl extern func 1704 | blex func
1557 | b ->fff_resn 1705 | b ->fff_resn
1558 |.endmacro 1706 |.endmacro
1559 | 1707 |
1560 |.macro math_extern2, func 1708 |.macro math_extern2, func
1561 | .ffunc_nn math_ .. func 1709 | .ffunc_nn math_ .. func
1562 | bl extern func 1710 | blex func
1563 | b ->fff_resn 1711 | b ->fff_resn
1564 |.endmacro 1712 |.endmacro
1565 | 1713 |
@@ -1580,14 +1728,14 @@ static void build_subroutines(BuildCtx *ctx)
1580 | slwi CARG2, CARG1, 11 1728 | slwi CARG2, CARG1, 11
1581 | bge cr1, >4 1729 | bge cr1, >4
1582 | slw TMP3, TMP1, TMP2 1730 | slw TMP3, TMP1, TMP2
1583 | srw CARG1, TMP1, TMP0 1731 | srw RD, TMP1, TMP0
1584 | or TMP3, TMP3, CARG2 1732 | or TMP3, TMP3, CARG2
1585 | srawi TMP2, CARG3, 31 1733 | srawi TMP2, CARG3, 31
1586 |.if "func" == "floor" 1734 |.if "func" == "floor"
1587 | and TMP1, TMP3, TMP2 1735 | and TMP1, TMP3, TMP2
1588 | addic TMP0, TMP1, -1 1736 | addic TMP0, TMP1, -1
1589 | subfe TMP1, TMP0, TMP1 1737 | subfe TMP1, TMP0, TMP1
1590 | add CARG1, CARG1, TMP1 1738 | add CARG1, RD, TMP1
1591 | xor CARG1, CARG1, TMP2 1739 | xor CARG1, CARG1, TMP2
1592 | sub CARG1, CARG1, TMP2 1740 | sub CARG1, CARG1, TMP2
1593 | b ->fff_resi 1741 | b ->fff_resi
@@ -1595,18 +1743,18 @@ static void build_subroutines(BuildCtx *ctx)
1595 | andc TMP1, TMP3, TMP2 1743 | andc TMP1, TMP3, TMP2
1596 | addic TMP0, TMP1, -1 1744 | addic TMP0, TMP1, -1
1597 | subfe TMP1, TMP0, TMP1 1745 | subfe TMP1, TMP0, TMP1
1598 | addo. CARG1, CARG1, TMP1 1746 | add CARG1, RD, TMP1
1747 | cmpw CARG1, RD
1599 | xor CARG1, CARG1, TMP2 1748 | xor CARG1, CARG1, TMP2
1600 | sub CARG1, CARG1, TMP2 1749 | sub CARG1, CARG1, TMP2
1601 | bns ->fff_resi 1750 | bge ->fff_resi
1602 | // Potential overflow. 1751 | // Overflow to 2^31.
1603 | mcrxr cr0; bley ->fff_resi // Ignore unrelated overflow.
1604 | lus CARG3, 0x41e0 // 2^31. 1752 | lus CARG3, 0x41e0 // 2^31.
1605 | li CARG1, 0 1753 | li CARG1, 0
1606 | b ->fff_restv 1754 | b ->fff_restv
1607 |.endif 1755 |.endif
1608 |3: // |x| < 1 1756 |3: // |x| < 1
1609 | add TMP2, CARG3, CARG3 1757 | slwi TMP2, CARG3, 1
1610 | srawi TMP1, CARG3, 31 1758 | srawi TMP1, CARG3, 31
1611 | or TMP2, CARG1, TMP2 // ztest = (hi+hi) | lo 1759 | or TMP2, CARG1, TMP2 // ztest = (hi+hi) | lo
1612 |.if "func" == "floor" 1760 |.if "func" == "floor"
@@ -1625,13 +1773,18 @@ static void build_subroutines(BuildCtx *ctx)
1625 |.if "func" == "floor" 1773 |.if "func" == "floor"
1626 | or TMP1, TMP1, CARG2 1774 | or TMP1, TMP1, CARG2
1627 |.endif 1775 |.endif
1776 |.if PPE
1777 | orc TMP1, TMP1, TMP2
1778 | cmpwi TMP1, 0
1779 |.else
1628 | orc. TMP1, TMP1, TMP2 1780 | orc. TMP1, TMP1, TMP2
1781 |.endif
1629 | crand 4*cr0+eq, 4*cr0+eq, 4*cr1+eq 1782 | crand 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
1630 | lus CARG1, 0x8000 // -(2^31). 1783 | lus CARG1, 0x8000 // -(2^31).
1631 | beqy ->fff_resi 1784 | beqy ->fff_resi
1632 |5: 1785 |5:
1633 | lfd FARG1, 0(BASE) 1786 | lfd FARG1, 0(BASE)
1634 | bl extern func 1787 | blex func
1635 | b ->fff_resn 1788 | b ->fff_resn
1636 |.endmacro 1789 |.endmacro
1637 | 1790 |
@@ -1644,7 +1797,13 @@ static void build_subroutines(BuildCtx *ctx)
1644 | math_extern ceil 1797 | math_extern ceil
1645 |.endif 1798 |.endif
1646 | 1799 |
1800 |.if SQRT
1801 |.ffunc_n math_sqrt
1802 | fsqrt FARG1, FARG1
1803 | b ->fff_resn
1804 |.else
1647 | math_extern sqrt 1805 | math_extern sqrt
1806 |.endif
1648 | math_extern log 1807 | math_extern log
1649 | math_extern log10 1808 | math_extern log10
1650 | math_extern exp 1809 | math_extern exp
@@ -1673,21 +1832,33 @@ static void build_subroutines(BuildCtx *ctx)
1673 | lwz CARG3, 0(BASE) 1832 | lwz CARG3, 0(BASE)
1674 | lfd FARG1, 0(BASE) 1833 | lfd FARG1, 0(BASE)
1675 | lwz CARG4, 8(BASE) 1834 | lwz CARG4, 8(BASE)
1835 |.if GPR64
1836 | lwz CARG2, 12(BASE)
1837 |.else
1676 | lwz CARG1, 12(BASE) 1838 | lwz CARG1, 12(BASE)
1839 |.endif
1677 | blt ->fff_fallback 1840 | blt ->fff_fallback
1678 | checknum CARG3; bge ->fff_fallback 1841 | checknum CARG3; bge ->fff_fallback
1679 | checknum CARG4; bne ->fff_fallback 1842 | checknum CARG4; bne ->fff_fallback
1680 |.else 1843 |.else
1681 |.ffunc_nn math_ldexp 1844 |.ffunc_nn math_ldexp
1845 |.if GPR64
1846 | toint CARG2, FARG2
1847 |.else
1682 | toint CARG1, FARG2 1848 | toint CARG1, FARG2
1683 |.endif 1849 |.endif
1684 | bl extern ldexp 1850 |.endif
1851 | blex ldexp
1685 | b ->fff_resn 1852 | b ->fff_resn
1686 | 1853 |
1687 |.ffunc_n math_frexp 1854 |.ffunc_n math_frexp
1855 |.if GPR64
1856 | la CARG2, DISPATCH_GL(tmptv)(DISPATCH)
1857 |.else
1688 | la CARG1, DISPATCH_GL(tmptv)(DISPATCH) 1858 | la CARG1, DISPATCH_GL(tmptv)(DISPATCH)
1859 |.endif
1689 | lwz PC, FRAME_PC(BASE) 1860 | lwz PC, FRAME_PC(BASE)
1690 | bl extern frexp 1861 | blex frexp
1691 | lwz TMP1, DISPATCH_GL(tmptv)(DISPATCH) 1862 | lwz TMP1, DISPATCH_GL(tmptv)(DISPATCH)
1692 | la RA, -8(BASE) 1863 | la RA, -8(BASE)
1693 |.if not DUALNUM 1864 |.if not DUALNUM
@@ -1704,9 +1875,13 @@ static void build_subroutines(BuildCtx *ctx)
1704 | b ->fff_res 1875 | b ->fff_res
1705 | 1876 |
1706 |.ffunc_n math_modf 1877 |.ffunc_n math_modf
1878 |.if GPR64
1879 | la CARG2, -8(BASE)
1880 |.else
1707 | la CARG1, -8(BASE) 1881 | la CARG1, -8(BASE)
1882 |.endif
1708 | lwz PC, FRAME_PC(BASE) 1883 | lwz PC, FRAME_PC(BASE)
1709 | bl extern modf 1884 | blex modf
1710 | la RA, -8(BASE) 1885 | la RA, -8(BASE)
1711 | stfd FARG1, 0(BASE) 1886 | stfd FARG1, 0(BASE)
1712 | li RD, (2+1)*8 1887 | li RD, (2+1)*8
@@ -1736,6 +1911,9 @@ static void build_subroutines(BuildCtx *ctx)
1736 | and TMP3, TMP3, TMP0 1911 | and TMP3, TMP3, TMP0
1737 |.endif 1912 |.endif
1738 | add CARG1, TMP3, CARG2 1913 | add CARG1, TMP3, CARG2
1914 |.if GPR64
1915 | rldicl CARG1, CARG1, 0, 32
1916 |.endif
1739 | addi TMP1, TMP1, 8 1917 | addi TMP1, TMP1, 8
1740 | b <1 1918 | b <1
1741 |3: 1919 |3:
@@ -1849,11 +2027,11 @@ static void build_subroutines(BuildCtx *ctx)
1849 | cmplwi TMP0, 255; bgt ->fff_fallback 2027 | cmplwi TMP0, 255; bgt ->fff_fallback
1850 |->fff_newstr: 2028 |->fff_newstr:
1851 | mr CARG1, L 2029 | mr CARG1, L
1852 | stw BASE, L->base 2030 | stp BASE, L->base
1853 | stw PC, SAVE_PC 2031 | stw PC, SAVE_PC
1854 | bl extern lj_str_new // (lua_State *L, char *str, size_t l) 2032 | bl extern lj_str_new // (lua_State *L, char *str, size_t l)
1855 | // Returns GCstr *. 2033 | // Returns GCstr *.
1856 | lwz BASE, L->base 2034 | lp BASE, L->base
1857 | li CARG3, LJ_TSTR 2035 | li CARG3, LJ_TSTR
1858 | b ->fff_restv 2036 | b ->fff_restv
1859 | 2037 |
@@ -1906,6 +2084,10 @@ static void build_subroutines(BuildCtx *ctx)
1906 | addi CARG3, CARG3, 1 2084 | addi CARG3, CARG3, 1
1907 | add CARG2, CARG2, TMP1 2085 | add CARG2, CARG2, TMP1
1908 | andc CARG3, CARG3, TMP0 2086 | andc CARG3, CARG3, TMP0
2087 |.if GPR64
2088 | rldicl CARG2, CARG2, 0, 32
2089 | rldicl CARG3, CARG3, 0, 32
2090 |.endif
1909 | b ->fff_newstr 2091 | b ->fff_newstr
1910 | 2092 |
1911 |5: // Negative end or overflow. 2093 |5: // Negative end or overflow.
@@ -1916,6 +2098,7 @@ static void build_subroutines(BuildCtx *ctx)
1916 | b <2 2098 | b <2
1917 | 2099 |
1918 |7: // Negative start or underflow. 2100 |7: // Negative start or underflow.
2101 | .gpr64 extsw TMP1, TMP1
1919 | addic CARG3, TMP1, -1 2102 | addic CARG3, TMP1, -1
1920 | subfe CARG3, CARG3, CARG3 2103 | subfe CARG3, CARG3, CARG3
1921 | srawi CARG2, TMP3, 31 // Note: modifies carry. 2104 | srawi CARG2, TMP3, 31 // Note: modifies carry.
@@ -1953,7 +2136,7 @@ static void build_subroutines(BuildCtx *ctx)
1953 | cmplw cr1, TMP1, CARG3 2136 | cmplw cr1, TMP1, CARG3
1954 | bne ->fff_fallback // Fallback for > 1-char strings. 2137 | bne ->fff_fallback // Fallback for > 1-char strings.
1955 | lbz TMP0, STR:CARG1[1] 2138 | lbz TMP0, STR:CARG1[1]
1956 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) 2139 | lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1957 | blt cr1, ->fff_fallback 2140 | blt cr1, ->fff_fallback
1958 |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?). 2141 |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
1959 | cmplwi TMP2, 0 2142 | cmplwi TMP2, 0
@@ -1977,7 +2160,7 @@ static void build_subroutines(BuildCtx *ctx)
1977 | bne ->fff_fallback 2160 | bne ->fff_fallback
1978 | lwz CARG3, STR:CARG1->len 2161 | lwz CARG3, STR:CARG1->len
1979 | la CARG1, #STR(STR:CARG1) 2162 | la CARG1, #STR(STR:CARG1)
1980 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) 2163 | lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1981 | li TMP2, 0 2164 | li TMP2, 0
1982 | cmplw TMP1, CARG3 2165 | cmplw TMP1, CARG3
1983 | subi TMP3, CARG3, 1 2166 | subi TMP3, CARG3, 1
@@ -2003,7 +2186,7 @@ static void build_subroutines(BuildCtx *ctx)
2003 | bne ->fff_fallback 2186 | bne ->fff_fallback
2004 | lwz CARG3, STR:CARG1->len 2187 | lwz CARG3, STR:CARG1->len
2005 | la CARG1, #STR(STR:CARG1) 2188 | la CARG1, #STR(STR:CARG1)
2006 | lwz CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) 2189 | lp CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
2007 | cmplw TMP1, CARG3 2190 | cmplw TMP1, CARG3
2008 | li TMP2, 0 2191 | li TMP2, 0
2009 | blt ->fff_fallback 2192 | blt ->fff_fallback
@@ -2015,7 +2198,7 @@ static void build_subroutines(BuildCtx *ctx)
2015 | xori TMP3, TMP1, 0x20 2198 | xori TMP3, TMP1, 0x20
2016 | addic TMP0, TMP0, -26 2199 | addic TMP0, TMP0, -26
2017 | subfe TMP3, TMP3, TMP3 2200 | subfe TMP3, TMP3, TMP3
2018 | andi. TMP3, TMP3, 0x20 2201 | rlwinm TMP3, TMP3, 0, 26, 26 // x &= 0x20.
2019 | xor TMP1, TMP1, TMP3 2202 | xor TMP1, TMP1, TMP3
2020 | stbx TMP1, CARG2, TMP2 2203 | stbx TMP1, CARG2, TMP2
2021 | addi TMP2, TMP2, 1 2204 | addi TMP2, TMP2, 1
@@ -2156,27 +2339,28 @@ static void build_subroutines(BuildCtx *ctx)
2156 | 2339 |
2157 |->fff_fallback: // Call fast function fallback handler. 2340 |->fff_fallback: // Call fast function fallback handler.
2158 | // BASE = new base, RB = CFUNC, RC = nargs*8 2341 | // BASE = new base, RB = CFUNC, RC = nargs*8
2159 | lwz TMP3, CFUNC:RB->f 2342 | lp TMP3, CFUNC:RB->f
2160 | add TMP1, BASE, NARGS8:RC 2343 | add TMP1, BASE, NARGS8:RC
2161 | lwz PC, FRAME_PC(BASE) // Fallback may overwrite PC. 2344 | lwz PC, FRAME_PC(BASE) // Fallback may overwrite PC.
2162 | addi TMP0, TMP1, 8*LUA_MINSTACK 2345 | addi TMP0, TMP1, 8*LUA_MINSTACK
2163 | lwz TMP2, L->maxstack 2346 | lwz TMP2, L->maxstack
2164 | stw PC, SAVE_PC // Redundant (but a defined value). 2347 | stw PC, SAVE_PC // Redundant (but a defined value).
2348 | .toc lp TMP3, 0(TMP3)
2165 | cmplw TMP0, TMP2 2349 | cmplw TMP0, TMP2
2166 | stw BASE, L->base 2350 | stp BASE, L->base
2167 | stw TMP1, L->top 2351 | stp TMP1, L->top
2168 | mr CARG1, L 2352 | mr CARG1, L
2169 | bgt >5 // Need to grow stack. 2353 | bgt >5 // Need to grow stack.
2170 | mtctr TMP3 2354 | mtctr TMP3
2171 | bctrl // (lua_State *L) 2355 | bctrl // (lua_State *L)
2172 | // Either throws an error, or recovers and returns -1, 0 or nresults+1. 2356 | // Either throws an error, or recovers and returns -1, 0 or nresults+1.
2173 | lwz BASE, L->base 2357 | lp BASE, L->base
2174 | cmpwi CRET1, 0 2358 | cmpwi CRET1, 0
2175 | slwi RD, CRET1, 3 2359 | slwi RD, CRET1, 3
2176 | la RA, -8(BASE) 2360 | la RA, -8(BASE)
2177 | bgt ->fff_res // Returned nresults+1? 2361 | bgt ->fff_res // Returned nresults+1?
2178 |1: // Returned 0 or -1: retry fast path. 2362 |1: // Returned 0 or -1: retry fast path.
2179 | lwz TMP0, L->top 2363 | lp TMP0, L->top
2180 | lwz LFUNC:RB, FRAME_FUNC(BASE) 2364 | lwz LFUNC:RB, FRAME_FUNC(BASE)
2181 | sub NARGS8:RC, TMP0, BASE 2365 | sub NARGS8:RC, TMP0, BASE
2182 | bne ->vm_call_tail // Returned -1? 2366 | bne ->vm_call_tail // Returned -1?
@@ -2184,7 +2368,7 @@ static void build_subroutines(BuildCtx *ctx)
2184 | 2368 |
2185 |// Reconstruct previous base for vmeta_call during tailcall. 2369 |// Reconstruct previous base for vmeta_call during tailcall.
2186 |->vm_call_tail: 2370 |->vm_call_tail:
2187 | andi. TMP0, PC, FRAME_TYPE 2371 | andix. TMP0, PC, FRAME_TYPE
2188 | rlwinm TMP1, PC, 0, 0, 28 2372 | rlwinm TMP1, PC, 0, 0, 28
2189 | bne >3 2373 | bne >3
2190 | lwz INS, -4(PC) 2374 | lwz INS, -4(PC)
@@ -2197,22 +2381,22 @@ static void build_subroutines(BuildCtx *ctx)
2197 |5: // Grow stack for fallback handler. 2381 |5: // Grow stack for fallback handler.
2198 | li CARG2, LUA_MINSTACK 2382 | li CARG2, LUA_MINSTACK
2199 | bl extern lj_state_growstack // (lua_State *L, int n) 2383 | bl extern lj_state_growstack // (lua_State *L, int n)
2200 | lwz BASE, L->base 2384 | lp BASE, L->base
2201 | cmpw TMP0, TMP0 // Set 4*cr0+eq to force retry. 2385 | cmpw TMP0, TMP0 // Set 4*cr0+eq to force retry.
2202 | b <1 2386 | b <1
2203 | 2387 |
2204 |->fff_gcstep: // Call GC step function. 2388 |->fff_gcstep: // Call GC step function.
2205 | // BASE = new base, RC = nargs*8 2389 | // BASE = new base, RC = nargs*8
2206 | mflr SAVE0 2390 | mflr SAVE0
2207 | stw BASE, L->base 2391 | stp BASE, L->base
2208 | add TMP0, BASE, NARGS8:RC 2392 | add TMP0, BASE, NARGS8:RC
2209 | stw PC, SAVE_PC // Redundant (but a defined value). 2393 | stw PC, SAVE_PC // Redundant (but a defined value).
2210 | stw TMP0, L->top 2394 | stp TMP0, L->top
2211 | mr CARG1, L 2395 | mr CARG1, L
2212 | bl extern lj_gc_step // (lua_State *L) 2396 | bl extern lj_gc_step // (lua_State *L)
2213 | lwz BASE, L->base 2397 | lp BASE, L->base
2214 | mtlr SAVE0 2398 | mtlr SAVE0
2215 | lwz TMP0, L->top 2399 | lp TMP0, L->top
2216 | sub NARGS8:RC, TMP0, BASE 2400 | sub NARGS8:RC, TMP0, BASE
2217 | lwz CFUNC:RB, FRAME_FUNC(BASE) 2401 | lwz CFUNC:RB, FRAME_FUNC(BASE)
2218 | blr 2402 | blr
@@ -2224,11 +2408,11 @@ static void build_subroutines(BuildCtx *ctx)
2224 |->vm_record: // Dispatch target for recording phase. 2408 |->vm_record: // Dispatch target for recording phase.
2225 |.if JIT 2409 |.if JIT
2226 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH) 2410 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
2227 | andi. TMP0, TMP3, HOOK_VMEVENT // No recording while in vmevent. 2411 | andix. TMP0, TMP3, HOOK_VMEVENT // No recording while in vmevent.
2228 | bne >5 2412 | bne >5
2229 | // Decrement the hookcount for consistency, but always do the call. 2413 | // Decrement the hookcount for consistency, but always do the call.
2230 | lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH) 2414 | lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH)
2231 | andi. TMP0, TMP3, HOOK_ACTIVE 2415 | andix. TMP0, TMP3, HOOK_ACTIVE
2232 | bne >1 2416 | bne >1
2233 | subi TMP2, TMP2, 1 2417 | subi TMP2, TMP2, 1
2234 | andi. TMP0, TMP3, LUA_MASKLINE|LUA_MASKCOUNT 2418 | andi. TMP0, TMP3, LUA_MASKLINE|LUA_MASKCOUNT
@@ -2239,18 +2423,18 @@ static void build_subroutines(BuildCtx *ctx)
2239 | 2423 |
2240 |->vm_rethook: // Dispatch target for return hooks. 2424 |->vm_rethook: // Dispatch target for return hooks.
2241 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH) 2425 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
2242 | andi. TMP0, TMP3, HOOK_ACTIVE // Hook already active? 2426 | andix. TMP0, TMP3, HOOK_ACTIVE // Hook already active?
2243 | beq >1 2427 | beq >1
2244 |5: // Re-dispatch to static ins. 2428 |5: // Re-dispatch to static ins.
2245 | addi TMP1, TMP1, GG_DISP2STATIC // Assumes decode_OP4 TMP1, INS. 2429 | addi TMP1, TMP1, GG_DISP2STATIC // Assumes decode_OPP TMP1, INS.
2246 | lwzx TMP0, DISPATCH, TMP1 2430 | lpx TMP0, DISPATCH, TMP1
2247 | mtctr TMP0 2431 | mtctr TMP0
2248 | bctr 2432 | bctr
2249 | 2433 |
2250 |->vm_inshook: // Dispatch target for instr/line hooks. 2434 |->vm_inshook: // Dispatch target for instr/line hooks.
2251 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH) 2435 | lbz TMP3, DISPATCH_GL(hookmask)(DISPATCH)
2252 | lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH) 2436 | lwz TMP2, DISPATCH_GL(hookcount)(DISPATCH)
2253 | andi. TMP0, TMP3, HOOK_ACTIVE // Hook already active? 2437 | andix. TMP0, TMP3, HOOK_ACTIVE // Hook already active?
2254 | rlwinm TMP0, TMP3, 31-LUA_HOOKLINE, 31, 0 2438 | rlwinm TMP0, TMP3, 31-LUA_HOOKLINE, 31, 0
2255 | bne <5 2439 | bne <5
2256 | 2440 |
@@ -2264,18 +2448,18 @@ static void build_subroutines(BuildCtx *ctx)
2264 | mr CARG1, L 2448 | mr CARG1, L
2265 | stw MULTRES, SAVE_MULTRES 2449 | stw MULTRES, SAVE_MULTRES
2266 | mr CARG2, PC 2450 | mr CARG2, PC
2267 | stw BASE, L->base 2451 | stp BASE, L->base
2268 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC. 2452 | // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
2269 | bl extern lj_dispatch_ins // (lua_State *L, const BCIns *pc) 2453 | bl extern lj_dispatch_ins // (lua_State *L, const BCIns *pc)
2270 |3: 2454 |3:
2271 | lwz BASE, L->base 2455 | lp BASE, L->base
2272 |4: // Re-dispatch to static ins. 2456 |4: // Re-dispatch to static ins.
2273 | lwz INS, -4(PC) 2457 | lwz INS, -4(PC)
2274 | decode_OP4 TMP1, INS 2458 | decode_OPP TMP1, INS
2275 | decode_RB8 RB, INS 2459 | decode_RB8 RB, INS
2276 | addi TMP1, TMP1, GG_DISP2STATIC 2460 | addi TMP1, TMP1, GG_DISP2STATIC
2277 | decode_RD8 RD, INS 2461 | decode_RD8 RD, INS
2278 | lwzx TMP0, DISPATCH, TMP1 2462 | lpx TMP0, DISPATCH, TMP1
2279 | decode_RA8 RA, INS 2463 | decode_RA8 RA, INS
2280 | decode_RC8 RC, INS 2464 | decode_RC8 RC, INS
2281 | mtctr TMP0 2465 | mtctr TMP0
@@ -2295,10 +2479,10 @@ static void build_subroutines(BuildCtx *ctx)
2295 | mr CARG2, PC 2479 | mr CARG2, PC
2296 | stw L, DISPATCH_J(L)(DISPATCH) 2480 | stw L, DISPATCH_J(L)(DISPATCH)
2297 | lbz TMP1, PC2PROTO(framesize)(TMP1) 2481 | lbz TMP1, PC2PROTO(framesize)(TMP1)
2298 | stw BASE, L->base 2482 | stp BASE, L->base
2299 | slwi TMP1, TMP1, 3 2483 | slwi TMP1, TMP1, 3
2300 | add TMP1, BASE, TMP1 2484 | add TMP1, BASE, TMP1
2301 | stw TMP1, L->top 2485 | stp TMP1, L->top
2302 | bl extern lj_trace_hot // (jit_State *J, const BCIns *pc) 2486 | bl extern lj_trace_hot // (jit_State *J, const BCIns *pc)
2303 | b <3 2487 | b <3
2304 |.endif 2488 |.endif
@@ -2317,13 +2501,13 @@ static void build_subroutines(BuildCtx *ctx)
2317 | add TMP0, BASE, RC 2501 | add TMP0, BASE, RC
2318 | stw PC, SAVE_PC 2502 | stw PC, SAVE_PC
2319 | mr CARG1, L 2503 | mr CARG1, L
2320 | stw BASE, L->base 2504 | stp BASE, L->base
2321 | sub RA, RA, BASE 2505 | sub RA, RA, BASE
2322 | stw TMP0, L->top 2506 | stp TMP0, L->top
2323 | bl extern lj_dispatch_call // (lua_State *L, const BCIns *pc) 2507 | bl extern lj_dispatch_call // (lua_State *L, const BCIns *pc)
2324 | // Returns ASMFunction. 2508 | // Returns ASMFunction.
2325 | lwz BASE, L->base 2509 | lp BASE, L->base
2326 | lwz TMP0, L->top 2510 | lp TMP0, L->top
2327 | stw ZERO, SAVE_PC // Invalidate for subsequent line hook. 2511 | stw ZERO, SAVE_PC // Invalidate for subsequent line hook.
2328 | sub NARGS8:RC, TMP0, BASE 2512 | sub NARGS8:RC, TMP0, BASE
2329 | add RA, BASE, RA 2513 | add RA, BASE, RA
@@ -2369,22 +2553,26 @@ static void build_subroutines(BuildCtx *ctx)
2369 | lwz L, DISPATCH_GL(jit_L)(DISPATCH) 2553 | lwz L, DISPATCH_GL(jit_L)(DISPATCH)
2370 | savex_ 28,29,30,31 2554 | savex_ 28,29,30,31
2371 | sub CARG3, TMP0, CARG3 // Compute exit number. 2555 | sub CARG3, TMP0, CARG3 // Compute exit number.
2372 | lwz BASE, DISPATCH_GL(jit_base)(DISPATCH) 2556 | lp BASE, DISPATCH_GL(jit_base)(DISPATCH)
2373 | srwi CARG3, CARG3, 2 2557 | srwi CARG3, CARG3, 2
2374 | stw L, DISPATCH_J(L)(DISPATCH) 2558 | stw L, DISPATCH_J(L)(DISPATCH)
2375 | subi CARG3, CARG3, 2 2559 | subi CARG3, CARG3, 2
2376 | stw TMP1, DISPATCH_GL(jit_L)(DISPATCH) 2560 | stw TMP1, DISPATCH_GL(jit_L)(DISPATCH)
2377 | stw CARG4, DISPATCH_J(parent)(DISPATCH) 2561 | stw CARG4, DISPATCH_J(parent)(DISPATCH)
2378 | stw BASE, L->base 2562 | stp BASE, L->base
2379 | addi CARG1, DISPATCH, GG_DISP2J 2563 | addi CARG1, DISPATCH, GG_DISP2J
2380 | stw CARG3, DISPATCH_J(exitno)(DISPATCH) 2564 | stw CARG3, DISPATCH_J(exitno)(DISPATCH)
2381 | addi CARG2, sp, 16 2565 | addi CARG2, sp, 16
2382 | bl extern lj_trace_exit // (jit_State *J, ExitState *ex) 2566 | bl extern lj_trace_exit // (jit_State *J, ExitState *ex)
2383 | // Returns MULTRES (unscaled) or negated error code. 2567 | // Returns MULTRES (unscaled) or negated error code.
2384 | lwz TMP1, L->cframe 2568 | lp TMP1, L->cframe
2385 | lwz TMP2, 0(sp) 2569 | lwz TMP2, 0(sp)
2386 | lwz BASE, L->base 2570 | lp BASE, L->base
2571 |.if GPR64
2572 | rldicr sp, TMP1, 0, 61
2573 |.else
2387 | rlwinm sp, TMP1, 0, 0, 29 2574 | rlwinm sp, TMP1, 0, 0, 29
2575 |.endif
2388 | lwz PC, SAVE_PC // Get SAVE_PC. 2576 | lwz PC, SAVE_PC // Get SAVE_PC.
2389 | stw TMP2, 0(sp) 2577 | stw TMP2, 0(sp)
2390 | stw L, SAVE_L // Set SAVE_L (on-trace resume/yield). 2578 | stw L, SAVE_L // Set SAVE_L (on-trace resume/yield).
@@ -2422,9 +2610,9 @@ static void build_subroutines(BuildCtx *ctx)
2422 | addi PC, PC, 4 2610 | addi PC, PC, 4
2423 | // Assumes TISNIL == ~LJ_VMST_INTERP == -1. 2611 | // Assumes TISNIL == ~LJ_VMST_INTERP == -1.
2424 | stw TISNIL, DISPATCH_GL(vmstate)(DISPATCH) 2612 | stw TISNIL, DISPATCH_GL(vmstate)(DISPATCH)
2425 | decode_OP4 TMP1, INS 2613 | decode_OPP TMP1, INS
2426 | decode_RA8 RA, INS 2614 | decode_RA8 RA, INS
2427 | lwzx TMP0, DISPATCH, TMP1 2615 | lpx TMP0, DISPATCH, TMP1
2428 | mtctr TMP0 2616 | mtctr TMP0
2429 | cmplwi TMP1, BC_FUNCF*4 // Function header? 2617 | cmplwi TMP1, BC_FUNCF*4 // Function header?
2430 | bge >2 2618 | bge >2
@@ -2452,7 +2640,12 @@ static void build_subroutines(BuildCtx *ctx)
2452 |->vm_modi: 2640 |->vm_modi:
2453 | divwo. TMP0, CARG1, CARG2 2641 | divwo. TMP0, CARG1, CARG2
2454 | bso >1 2642 | bso >1
2643 |.if GPR64
2644 | xor CARG3, CARG1, CARG2
2645 | cmpwi CARG3, 0
2646 |.else
2455 | xor. CARG3, CARG1, CARG2 2647 | xor. CARG3, CARG1, CARG2
2648 |.endif
2456 | mullw TMP0, TMP0, CARG2 2649 | mullw TMP0, TMP0, CARG2
2457 | sub CARG1, CARG1, TMP0 2650 | sub CARG1, CARG1, TMP0
2458 | bgelr 2651 | bgelr
@@ -2474,6 +2667,7 @@ static void build_subroutines(BuildCtx *ctx)
2474 |// Flush D-Cache and invalidate I-Cache. Assumes 32 byte cache line size. 2667 |// Flush D-Cache and invalidate I-Cache. Assumes 32 byte cache line size.
2475 |// This is a good lower bound, except for very ancient PPC models. 2668 |// This is a good lower bound, except for very ancient PPC models.
2476 |->vm_cachesync: 2669 |->vm_cachesync:
2670 |.if JIT or FFI
2477 | // Compute start of first cache line and number of cache lines. 2671 | // Compute start of first cache line and number of cache lines.
2478 | rlwinm CARG1, CARG1, 0, 0, 26 2672 | rlwinm CARG1, CARG1, 0, 0, 26
2479 | sub CARG2, CARG2, CARG1 2673 | sub CARG2, CARG2, CARG1
@@ -2494,6 +2688,7 @@ static void build_subroutines(BuildCtx *ctx)
2494 | bdnz <1 2688 | bdnz <1
2495 | isync 2689 | isync
2496 | blr 2690 | blr
2691 |.endif
2497 | 2692 |
2498 |//----------------------------------------------------------------------- 2693 |//-----------------------------------------------------------------------
2499 |//-- FFI helper functions ----------------------------------------------- 2694 |//-- FFI helper functions -----------------------------------------------
@@ -2530,9 +2725,9 @@ static void build_subroutines(BuildCtx *ctx)
2530 | mr CARG2, sp 2725 | mr CARG2, sp
2531 | bl extern lj_ccallback_enter // (CTState *cts, void *cf) 2726 | bl extern lj_ccallback_enter // (CTState *cts, void *cf)
2532 | // Returns lua_State *. 2727 | // Returns lua_State *.
2533 | lwz BASE, L:CRET1->base 2728 | lp BASE, L:CRET1->base
2534 | li TISNUM, LJ_TISNUM // Setup type comparison constants. 2729 | li TISNUM, LJ_TISNUM // Setup type comparison constants.
2535 | lwz RC, L:CRET1->top 2730 | lp RC, L:CRET1->top
2536 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). 2731 | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
2537 | li ZERO, 0 2732 | li ZERO, 0
2538 | mr L, CRET1 2733 | mr L, CRET1
@@ -2554,9 +2749,9 @@ static void build_subroutines(BuildCtx *ctx)
2554 |->cont_ffi_callback: // Return from FFI callback. 2749 |->cont_ffi_callback: // Return from FFI callback.
2555 |.if FFI 2750 |.if FFI
2556 | lwz CTSTATE, DISPATCH_GL(ctype_state)(DISPATCH) 2751 | lwz CTSTATE, DISPATCH_GL(ctype_state)(DISPATCH)
2557 | stw BASE, L->base 2752 | stp BASE, L->base
2558 | stw RB, L->top 2753 | stp RB, L->top
2559 | stw L, CTSTATE->L 2754 | stp L, CTSTATE->L
2560 | mr CARG1, CTSTATE 2755 | mr CARG1, CTSTATE
2561 | mr CARG2, RA 2756 | mr CARG2, RA
2562 | bl extern lj_ccallback_leave // (CTState *cts, TValue *o) 2757 | bl extern lj_ccallback_leave // (CTState *cts, TValue *o)
@@ -2604,7 +2799,7 @@ static void build_subroutines(BuildCtx *ctx)
2604 | lfd f7, CCSTATE->fpr[6] 2799 | lfd f7, CCSTATE->fpr[6]
2605 | lfd f8, CCSTATE->fpr[7] 2800 | lfd f8, CCSTATE->fpr[7]
2606 |3: 2801 |3:
2607 | lwz TMP0, CCSTATE->func 2802 | lp TMP0, CCSTATE->func
2608 | lwz CARG2, CCSTATE->gpr[1] 2803 | lwz CARG2, CCSTATE->gpr[1]
2609 | lwz CARG3, CCSTATE->gpr[2] 2804 | lwz CARG3, CCSTATE->gpr[2]
2610 | lwz CARG4, CCSTATE->gpr[3] 2805 | lwz CARG4, CCSTATE->gpr[3]
@@ -2832,7 +3027,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2832 | cmplwi TAB:TMP2, 0 3027 | cmplwi TAB:TMP2, 0
2833 | beq <1 // No metatable? 3028 | beq <1 // No metatable?
2834 | lbz TMP2, TAB:TMP2->nomm 3029 | lbz TMP2, TAB:TMP2->nomm
2835 | andi. TMP2, TMP2, 1<<MM_eq 3030 | andix. TMP2, TMP2, 1<<MM_eq
2836 | bne <1 // Or 'no __eq' flag set? 3031 | bne <1 // Or 'no __eq' flag set?
2837 | mr PC, SAVE0 // Restore old PC. 3032 | mr PC, SAVE0 // Restore old PC.
2838 | b ->vmeta_equal // Handle __eq metamethod. 3033 | b ->vmeta_equal // Handle __eq metamethod.
@@ -2851,6 +3046,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2851 | cmpwi TMP0, LJ_TCDATA 3046 | cmpwi TMP0, LJ_TCDATA
2852 |.endif 3047 |.endif
2853 | lwzx STR:TMP1, KBASE, RD // KBASE-4-str_const*4 3048 | lwzx STR:TMP1, KBASE, RD // KBASE-4-str_const*4
3049 | .gpr64 extsw TMP0, TMP0
2854 | subfic TMP0, TMP0, LJ_TSTR 3050 | subfic TMP0, TMP0, LJ_TSTR
2855 |.if FFI 3051 |.if FFI
2856 | beq ->vmeta_equal_cd 3052 | beq ->vmeta_equal_cd
@@ -2969,6 +3165,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2969 | beq ->vmeta_equal_cd 3165 | beq ->vmeta_equal_cd
2970 |.endif 3166 |.endif
2971 | decode_RD4 TMP2, TMP2 3167 | decode_RD4 TMP2, TMP2
3168 | .gpr64 extsw TMP0, TMP0
2972 | addic TMP0, TMP0, -1 3169 | addic TMP0, TMP0, -1
2973 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16) 3170 | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16)
2974 | subfe TMP1, TMP1, TMP1 3171 | subfe TMP1, TMP1, TMP1
@@ -2989,6 +3186,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2989 | lwz INS, 0(PC) 3186 | lwz INS, 0(PC)
2990 | addi PC, PC, 4 3187 | addi PC, PC, 4
2991 if (op == BC_IST || op == BC_ISF) { 3188 if (op == BC_IST || op == BC_ISF) {
3189 | .gpr64 extsw TMP0, TMP0
2992 | subfic TMP0, TMP0, LJ_TTRUE 3190 | subfic TMP0, TMP0, LJ_TTRUE
2993 | decode_RD4 TMP2, INS 3191 | decode_RD4 TMP2, INS
2994 | subfe TMP1, TMP1, TMP1 3192 | subfe TMP1, TMP1, TMP1
@@ -3030,6 +3228,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3030 | // RA = dst*8, RD = src*8 3228 | // RA = dst*8, RD = src*8
3031 | ins_next1 3229 | ins_next1
3032 | lwzx TMP0, BASE, RD 3230 | lwzx TMP0, BASE, RD
3231 | .gpr64 extsw TMP0, TMP0
3033 | subfic TMP1, TMP0, LJ_TTRUE 3232 | subfic TMP1, TMP0, LJ_TTRUE
3034 | adde TMP0, TMP0, TMP1 3233 | adde TMP0, TMP0, TMP1
3035 | stwx TMP0, BASE, RA 3234 | stwx TMP0, BASE, RA
@@ -3042,16 +3241,26 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3042 | checknum TMP1 3241 | checknum TMP1
3043 |.if DUALNUM 3242 |.if DUALNUM
3044 | bne >5 3243 | bne >5
3244 |.if GPR64
3245 | lus TMP2, 0x8000
3246 | neg TMP0, TMP0
3247 | cmplw TMP0, TMP2
3248 | beq >4
3249 |.else
3045 | nego. TMP0, TMP0 3250 | nego. TMP0, TMP0
3046 | bso >4 3251 | bso >4
3047 |1: 3252 |1:
3253 |.endif
3048 | ins_next1 3254 | ins_next1
3049 | stwux TISNUM, RA, BASE 3255 | stwux TISNUM, RA, BASE
3050 | stw TMP0, 4(RA) 3256 | stw TMP0, 4(RA)
3051 |3: 3257 |3:
3052 | ins_next2 3258 | ins_next2
3053 |4: // Potential overflow. 3259 |4:
3260 |.if not GPR64
3261 | // Potential overflow.
3054 | mcrxr cr0; bley <1 // Ignore unrelated overflow. 3262 | mcrxr cr0; bley <1 // Ignore unrelated overflow.
3263 |.endif
3055 | lus TMP1, 0x41e0 // 2^31. 3264 | lus TMP1, 0x41e0 // 2^31.
3056 | li TMP0, 0 3265 | li TMP0, 0
3057 | b >7 3266 | b >7
@@ -3101,7 +3310,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3101#ifdef LUAJIT_ENABLE_LUA52COMPAT 3310#ifdef LUAJIT_ENABLE_LUA52COMPAT
3102 |9: 3311 |9:
3103 | lbz TMP0, TAB:TMP2->nomm 3312 | lbz TMP0, TAB:TMP2->nomm
3104 | andi. TMP0, TMP0, 1<<MM_len 3313 | andix. TMP0, TMP0, 1<<MM_len
3105 | bne <3 // 'no __len' flag set: done. 3314 | bne <3 // 'no __len' flag set: done.
3106 | b ->vmeta_len 3315 | b ->vmeta_len
3107#endif 3316#endif
@@ -3180,7 +3389,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3180 |->BC_MODVN_Z: 3389 |->BC_MODVN_Z:
3181 | fdiv FARG1, b, c 3390 | fdiv FARG1, b, c
3182 | // NYI: Use internal implementation of floor. 3391 | // NYI: Use internal implementation of floor.
3183 | bl extern floor // floor(b/c) 3392 | blex floor // floor(b/c)
3184 | fmul a, FARG1, c 3393 | fmul a, FARG1, c
3185 | fsub a, b, a // b - floor(b/c)*c 3394 | fsub a, b, a // b - floor(b/c)*c
3186 |.endmacro 3395 |.endmacro
@@ -3267,10 +3476,32 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3267 |.endmacro 3476 |.endmacro
3268 3477
3269 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV: 3478 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
3479 |.if GPR64
3480 |.macro addo32., y, a, b
3481 | // Need to check overflow for (a<<32) + (b<<32).
3482 | rldicr TMP0, a, 32, 31
3483 | rldicr TMP3, b, 32, 31
3484 | addo. TMP0, TMP0, TMP3
3485 | add y, a, b
3486 |.endmacro
3487 | ins_arith addo32., fadd
3488 |.else
3270 | ins_arith addo., fadd 3489 | ins_arith addo., fadd
3490 |.endif
3271 break; 3491 break;
3272 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV: 3492 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
3493 |.if GPR64
3494 |.macro subo32., y, a, b
3495 | // Need to check overflow for (a<<32) - (b<<32).
3496 | rldicr TMP0, a, 32, 31
3497 | rldicr TMP3, b, 32, 31
3498 | subo. TMP0, TMP0, TMP3
3499 | sub y, a, b
3500 |.endmacro
3501 | ins_arith subo32., fsub
3502 |.else
3273 | ins_arith subo., fsub 3503 | ins_arith subo., fsub
3504 |.endif
3274 break; 3505 break;
3275 case BC_MULVN: case BC_MULNV: case BC_MULVV: 3506 case BC_MULVN: case BC_MULNV: case BC_MULVV:
3276 | ins_arith mullwo., fmul 3507 | ins_arith mullwo., fmul
@@ -3294,7 +3525,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3294 | checknum cr1, TMP2 3525 | checknum cr1, TMP2
3295 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt 3526 | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt
3296 | bge ->vmeta_arith_vv 3527 | bge ->vmeta_arith_vv
3297 | bl extern pow 3528 | blex pow
3298 | ins_next1 3529 | ins_next1
3299 | stfdx FARG1, BASE, RA 3530 | stfdx FARG1, BASE, RA
3300 | ins_next2 3531 | ins_next2
@@ -3303,7 +3534,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3303 case BC_CAT: 3534 case BC_CAT:
3304 | // RA = dst*8, RB = src_start*8, RC = src_end*8 3535 | // RA = dst*8, RB = src_start*8, RC = src_end*8
3305 | sub CARG3, RC, RB 3536 | sub CARG3, RC, RB
3306 | stw BASE, L->base 3537 | stp BASE, L->base
3307 | add CARG2, BASE, RC 3538 | add CARG2, BASE, RC
3308 | mr SAVE0, RB 3539 | mr SAVE0, RB
3309 |->BC_CAT_Z: 3540 |->BC_CAT_Z:
@@ -3313,7 +3544,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3313 | bl extern lj_meta_cat // (lua_State *L, TValue *top, int left) 3544 | bl extern lj_meta_cat // (lua_State *L, TValue *top, int left)
3314 | // Returns NULL (finished) or TValue * (metamethod). 3545 | // Returns NULL (finished) or TValue * (metamethod).
3315 | cmplwi CRET1, 0 3546 | cmplwi CRET1, 0
3316 | lwz BASE, L->base 3547 | lp BASE, L->base
3317 | bne ->vmeta_binop 3548 | bne ->vmeta_binop
3318 | ins_next1 3549 | ins_next1
3319 | lfdx f0, BASE, SAVE0 // Copy result from RB to RA. 3550 | lfdx f0, BASE, SAVE0 // Copy result from RB to RA.
@@ -3427,7 +3658,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3427 | lwzx UPVAL:RB, LFUNC:RB, RA 3658 | lwzx UPVAL:RB, LFUNC:RB, RA
3428 | lbz TMP3, UPVAL:RB->marked 3659 | lbz TMP3, UPVAL:RB->marked
3429 | lwz CARG2, UPVAL:RB->v 3660 | lwz CARG2, UPVAL:RB->v
3430 | andi. TMP3, TMP3, LJ_GC_BLACK // isblack(uv) 3661 | andix. TMP3, TMP3, LJ_GC_BLACK // isblack(uv)
3431 | lbz TMP0, UPVAL:RB->closed 3662 | lbz TMP0, UPVAL:RB->closed
3432 | lwz TMP2, 0(RD) 3663 | lwz TMP2, 0(RD)
3433 | stfd f0, 0(CARG2) 3664 | stfd f0, 0(CARG2)
@@ -3443,7 +3674,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3443 | cmplwi TMP2, LJ_TISGCV - (LJ_TISNUM+1) 3674 | cmplwi TMP2, LJ_TISGCV - (LJ_TISNUM+1)
3444 | bge <1 // tvisgcv(v) 3675 | bge <1 // tvisgcv(v)
3445 | lbz TMP3, GCOBJ:TMP1->gch.marked 3676 | lbz TMP3, GCOBJ:TMP1->gch.marked
3446 | andi. TMP3, TMP3, LJ_GC_WHITES // iswhite(v) 3677 | andix. TMP3, TMP3, LJ_GC_WHITES // iswhite(v)
3447 | la CARG1, GG_DISP2G(DISPATCH) 3678 | la CARG1, GG_DISP2G(DISPATCH)
3448 | // Crossed a write barrier. Move the barrier forward. 3679 | // Crossed a write barrier. Move the barrier forward.
3449 | beq <1 3680 | beq <1
@@ -3461,7 +3692,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3461 | lwzx UPVAL:RB, LFUNC:RB, RA 3692 | lwzx UPVAL:RB, LFUNC:RB, RA
3462 | lbz TMP3, UPVAL:RB->marked 3693 | lbz TMP3, UPVAL:RB->marked
3463 | lwz CARG2, UPVAL:RB->v 3694 | lwz CARG2, UPVAL:RB->v
3464 | andi. TMP3, TMP3, LJ_GC_BLACK // isblack(uv) 3695 | andix. TMP3, TMP3, LJ_GC_BLACK // isblack(uv)
3465 | lbz TMP3, STR:TMP1->marked 3696 | lbz TMP3, STR:TMP1->marked
3466 | lbz TMP2, UPVAL:RB->closed 3697 | lbz TMP2, UPVAL:RB->closed
3467 | li TMP0, LJ_TSTR 3698 | li TMP0, LJ_TSTR
@@ -3472,7 +3703,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3472 | ins_next 3703 | ins_next
3473 | 3704 |
3474 |2: // Check if string is white and ensure upvalue is closed. 3705 |2: // Check if string is white and ensure upvalue is closed.
3475 | andi. TMP3, TMP3, LJ_GC_WHITES // iswhite(str) 3706 | andix. TMP3, TMP3, LJ_GC_WHITES // iswhite(str)
3476 | cmplwi cr1, TMP2, 0 3707 | cmplwi cr1, TMP2, 0
3477 | cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq 3708 | cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq
3478 | la CARG1, GG_DISP2G(DISPATCH) 3709 | la CARG1, GG_DISP2G(DISPATCH)
@@ -3511,13 +3742,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3511 | // RA = level*8, RD = target 3742 | // RA = level*8, RD = target
3512 | lwz TMP1, L->openupval 3743 | lwz TMP1, L->openupval
3513 | branch_RD // Do this first since RD is not saved. 3744 | branch_RD // Do this first since RD is not saved.
3514 | stw BASE, L->base 3745 | stp BASE, L->base
3515 | cmplwi TMP1, 0 3746 | cmplwi TMP1, 0
3516 | mr CARG1, L 3747 | mr CARG1, L
3517 | beq >1 3748 | beq >1
3518 | add CARG2, BASE, RA 3749 | add CARG2, BASE, RA
3519 | bl extern lj_func_closeuv // (lua_State *L, TValue *level) 3750 | bl extern lj_func_closeuv // (lua_State *L, TValue *level)
3520 | lwz BASE, L->base 3751 | lp BASE, L->base
3521 |1: 3752 |1:
3522 | ins_next 3753 | ins_next
3523 break; 3754 break;
@@ -3525,7 +3756,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3525 case BC_FNEW: 3756 case BC_FNEW:
3526 | // RA = dst*8, RD = proto_const*8 (~) (holding function prototype) 3757 | // RA = dst*8, RD = proto_const*8 (~) (holding function prototype)
3527 | srwi TMP1, RD, 1 3758 | srwi TMP1, RD, 1
3528 | stw BASE, L->base 3759 | stp BASE, L->base
3529 | subfic TMP1, TMP1, -4 3760 | subfic TMP1, TMP1, -4
3530 | stw PC, SAVE_PC 3761 | stw PC, SAVE_PC
3531 | lwzx CARG2, KBASE, TMP1 // KBASE-4-tab_const*4 3762 | lwzx CARG2, KBASE, TMP1 // KBASE-4-tab_const*4
@@ -3534,7 +3765,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3534 | // (lua_State *L, GCproto *pt, GCfuncL *parent) 3765 | // (lua_State *L, GCproto *pt, GCfuncL *parent)
3535 | bl extern lj_func_newL_gc 3766 | bl extern lj_func_newL_gc
3536 | // Returns GCfuncL *. 3767 | // Returns GCfuncL *.
3537 | lwz BASE, L->base 3768 | lp BASE, L->base
3538 | li TMP0, LJ_TFUNC 3769 | li TMP0, LJ_TFUNC
3539 | stwux TMP0, RA, BASE 3770 | stwux TMP0, RA, BASE
3540 | stw LFUNC:CRET1, 4(RA) 3771 | stw LFUNC:CRET1, 4(RA)
@@ -3549,7 +3780,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3549 | lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH) 3780 | lwz TMP0, DISPATCH_GL(gc.total)(DISPATCH)
3550 | mr CARG1, L 3781 | mr CARG1, L
3551 | lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH) 3782 | lwz TMP1, DISPATCH_GL(gc.threshold)(DISPATCH)
3552 | stw BASE, L->base 3783 | stp BASE, L->base
3553 | cmplw TMP0, TMP1 3784 | cmplw TMP0, TMP1
3554 | stw PC, SAVE_PC 3785 | stw PC, SAVE_PC
3555 | bge >5 3786 | bge >5
@@ -3568,7 +3799,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3568 | bl extern lj_tab_dup // (lua_State *L, Table *kt) 3799 | bl extern lj_tab_dup // (lua_State *L, Table *kt)
3569 | // Returns Table *. 3800 | // Returns Table *.
3570 } 3801 }
3571 | lwz BASE, L->base 3802 | lp BASE, L->base
3572 | li TMP0, LJ_TTAB 3803 | li TMP0, LJ_TTAB
3573 | stwux TMP0, RA, BASE 3804 | stwux TMP0, RA, BASE
3574 | stw TAB:CRET1, 4(RA) 3805 | stw TAB:CRET1, 4(RA)
@@ -3650,7 +3881,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3650 | cmplwi TAB:TMP2, 0 3881 | cmplwi TAB:TMP2, 0
3651 | beq <1 // No metatable: done. 3882 | beq <1 // No metatable: done.
3652 | lbz TMP0, TAB:TMP2->nomm 3883 | lbz TMP0, TAB:TMP2->nomm
3653 | andi. TMP0, TMP0, 1<<MM_index 3884 | andix. TMP0, TMP0, 1<<MM_index
3654 | bne <1 // 'no __index' flag set: done. 3885 | bne <1 // 'no __index' flag set: done.
3655 | b ->vmeta_tgetv 3886 | b ->vmeta_tgetv
3656 | 3887 |
@@ -3705,7 +3936,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3705 | cmplwi TAB:TMP2, 0 3936 | cmplwi TAB:TMP2, 0
3706 | beq <3 // No metatable: done. 3937 | beq <3 // No metatable: done.
3707 | lbz TMP0, TAB:TMP2->nomm 3938 | lbz TMP0, TAB:TMP2->nomm
3708 | andi. TMP0, TMP0, 1<<MM_index 3939 | andix. TMP0, TMP0, 1<<MM_index
3709 | bne <3 // 'no __index' flag set: done. 3940 | bne <3 // 'no __index' flag set: done.
3710 | b ->vmeta_tgets 3941 | b ->vmeta_tgets
3711 break; 3942 break;
@@ -3731,7 +3962,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3731 | cmplwi TAB:TMP2, 0 3962 | cmplwi TAB:TMP2, 0
3732 | beq <1 // No metatable: done. 3963 | beq <1 // No metatable: done.
3733 | lbz TMP2, TAB:TMP2->nomm 3964 | lbz TMP2, TAB:TMP2->nomm
3734 | andi. TMP2, TMP2, 1<<MM_index 3965 | andix. TMP2, TMP2, 1<<MM_index
3735 | bne <1 // 'no __index' flag set: done. 3966 | bne <1 // 'no __index' flag set: done.
3736 | b ->vmeta_tgetb // Caveat: preserve TMP0! 3967 | b ->vmeta_tgetb // Caveat: preserve TMP0!
3737 break; 3968 break;
@@ -3776,7 +4007,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3776 | lfdx f14, BASE, RA 4007 | lfdx f14, BASE, RA
3777 | checknil TMP2; beq >3 4008 | checknil TMP2; beq >3
3778 |1: 4009 |1:
3779 | andi. TMP2, TMP3, LJ_GC_BLACK // isblack(table) 4010 | andix. TMP2, TMP3, LJ_GC_BLACK // isblack(table)
3780 | stfdx f14, TMP1, TMP0 4011 | stfdx f14, TMP1, TMP0
3781 | bne >7 4012 | bne >7
3782 |2: 4013 |2:
@@ -3787,7 +4018,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3787 | cmplwi TAB:TMP2, 0 4018 | cmplwi TAB:TMP2, 0
3788 | beq <1 // No metatable: done. 4019 | beq <1 // No metatable: done.
3789 | lbz TMP2, TAB:TMP2->nomm 4020 | lbz TMP2, TAB:TMP2->nomm
3790 | andi. TMP2, TMP2, 1<<MM_newindex 4021 | andix. TMP2, TMP2, 1<<MM_newindex
3791 | bne <1 // 'no __newindex' flag set: done. 4022 | bne <1 // 'no __newindex' flag set: done.
3792 | b ->vmeta_tsetv 4023 | b ->vmeta_tsetv
3793 | 4024 |
@@ -3833,7 +4064,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3833 | cmpw TMP0, STR:RC; bne >5 4064 | cmpw TMP0, STR:RC; bne >5
3834 | checknil CARG2; beq >4 // Key found, but nil value? 4065 | checknil CARG2; beq >4 // Key found, but nil value?
3835 |2: 4066 |2:
3836 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table) 4067 | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
3837 | stfd f14, NODE:TMP2->val 4068 | stfd f14, NODE:TMP2->val
3838 | bne >7 4069 | bne >7
3839 |3: 4070 |3:
@@ -3844,7 +4075,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3844 | cmplwi TAB:TMP1, 0 4075 | cmplwi TAB:TMP1, 0
3845 | beq <2 // No metatable: done. 4076 | beq <2 // No metatable: done.
3846 | lbz TMP0, TAB:TMP1->nomm 4077 | lbz TMP0, TAB:TMP1->nomm
3847 | andi. TMP0, TMP0, 1<<MM_newindex 4078 | andix. TMP0, TMP0, 1<<MM_newindex
3848 | bne <2 // 'no __newindex' flag set: done. 4079 | bne <2 // 'no __newindex' flag set: done.
3849 | b ->vmeta_tsets 4080 | b ->vmeta_tsets
3850 | 4081 |
@@ -3860,10 +4091,10 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3860 | stw PC, SAVE_PC 4091 | stw PC, SAVE_PC
3861 | mr CARG1, L 4092 | mr CARG1, L
3862 | cmplwi TAB:TMP1, 0 4093 | cmplwi TAB:TMP1, 0
3863 | stw BASE, L->base 4094 | stp BASE, L->base
3864 | beq >6 // No metatable: continue. 4095 | beq >6 // No metatable: continue.
3865 | lbz TMP0, TAB:TMP1->nomm 4096 | lbz TMP0, TAB:TMP1->nomm
3866 | andi. TMP0, TMP0, 1<<MM_newindex 4097 | andix. TMP0, TMP0, 1<<MM_newindex
3867 | beq ->vmeta_tsets // 'no __newindex' flag NOT set: check. 4098 | beq ->vmeta_tsets // 'no __newindex' flag NOT set: check.
3868 |6: 4099 |6:
3869 | li TMP0, LJ_TSTR 4100 | li TMP0, LJ_TSTR
@@ -3872,7 +4103,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3872 | stw TMP0, 0(CARG3) 4103 | stw TMP0, 0(CARG3)
3873 | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k) 4104 | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k)
3874 | // Returns TValue *. 4105 | // Returns TValue *.
3875 | lwz BASE, L->base 4106 | lp BASE, L->base
3876 | stfd f14, 0(CRET1) 4107 | stfd f14, 0(CRET1)
3877 | b <3 // No 2nd write barrier needed. 4108 | b <3 // No 2nd write barrier needed.
3878 | 4109 |
@@ -3895,7 +4126,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3895 | lwzx TMP1, TMP2, RC 4126 | lwzx TMP1, TMP2, RC
3896 | checknil TMP1; beq >5 4127 | checknil TMP1; beq >5
3897 |1: 4128 |1:
3898 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table) 4129 | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
3899 | stfdx f14, TMP2, RC 4130 | stfdx f14, TMP2, RC
3900 | bne >7 4131 | bne >7
3901 |2: 4132 |2:
@@ -3906,7 +4137,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3906 | cmplwi TAB:TMP1, 0 4137 | cmplwi TAB:TMP1, 0
3907 | beq <1 // No metatable: done. 4138 | beq <1 // No metatable: done.
3908 | lbz TMP1, TAB:TMP1->nomm 4139 | lbz TMP1, TAB:TMP1->nomm
3909 | andi. TMP1, TMP1, 1<<MM_newindex 4140 | andix. TMP1, TMP1, 1<<MM_newindex
3910 | bne <1 // 'no __newindex' flag set: done. 4141 | bne <1 // 'no __newindex' flag set: done.
3911 | b ->vmeta_tsetb // Caveat: preserve TMP0! 4142 | b ->vmeta_tsetb // Caveat: preserve TMP0!
3912 | 4143 |
@@ -3934,7 +4165,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3934 | lwz TMP0, TAB:CARG2->array 4165 | lwz TMP0, TAB:CARG2->array
3935 | bgt >5 4166 | bgt >5
3936 | add TMP1, TMP1, TMP0 4167 | add TMP1, TMP1, TMP0
3937 | andi. TMP0, TMP3, LJ_GC_BLACK // isblack(table) 4168 | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table)
3938 |3: // Copy result slots to table. 4169 |3: // Copy result slots to table.
3939 | lfd f0, 0(RA) 4170 | lfd f0, 0(RA)
3940 | addi RA, RA, 8 4171 | addi RA, RA, 8
@@ -3947,7 +4178,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3947 | ins_next 4178 | ins_next
3948 | 4179 |
3949 |5: // Need to resize array part. 4180 |5: // Need to resize array part.
3950 | stw BASE, L->base 4181 | stp BASE, L->base
3951 | mr CARG1, L 4182 | mr CARG1, L
3952 | stw PC, SAVE_PC 4183 | stw PC, SAVE_PC
3953 | mr SAVE0, RD 4184 | mr SAVE0, RD
@@ -3994,7 +4225,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3994 | addi RA, RA, 8 4225 | addi RA, RA, 8
3995 | bne ->vmeta_callt 4226 | bne ->vmeta_callt
3996 |->BC_CALLT_Z: 4227 |->BC_CALLT_Z:
3997 | andi. TMP0, TMP1, FRAME_TYPE // Caveat: preserve cr0 until the crand. 4228 | andix. TMP0, TMP1, FRAME_TYPE // Caveat: preserve cr0 until the crand.
3998 | lbz TMP3, LFUNC:RB->ffid 4229 | lbz TMP3, LFUNC:RB->ffid
3999 | xori TMP2, TMP1, FRAME_VARG 4230 | xori TMP2, TMP1, FRAME_VARG
4000 | cmplwi cr1, NARGS8:RC, 0 4231 | cmplwi cr1, NARGS8:RC, 0
@@ -4027,11 +4258,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4027 | b <4 4258 | b <4
4028 | 4259 |
4029 |7: // Tailcall from a vararg function. 4260 |7: // Tailcall from a vararg function.
4030 | andi. TMP0, TMP2, FRAME_TYPEP 4261 | andix. TMP0, TMP2, FRAME_TYPEP
4031 | bne <1 // Vararg frame below? 4262 | bne <1 // Vararg frame below?
4032 | sub BASE, BASE, TMP2 // Relocate BASE down. 4263 | sub BASE, BASE, TMP2 // Relocate BASE down.
4033 | lwz TMP1, FRAME_PC(BASE) 4264 | lwz TMP1, FRAME_PC(BASE)
4034 | andi. TMP0, TMP1, FRAME_TYPE 4265 | andix. TMP0, TMP1, FRAME_TYPE
4035 | b <1 4266 | b <1
4036 break; 4267 break;
4037 4268
@@ -4169,7 +4400,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4169 | sub RC, RC, TMP0 // RC = vbase 4400 | sub RC, RC, TMP0 // RC = vbase
4170 | // Note: RC may now be even _above_ BASE if nargs was < numparams. 4401 | // Note: RC may now be even _above_ BASE if nargs was < numparams.
4171 | cmplwi cr1, RB, 0 4402 | cmplwi cr1, RB, 0
4403 |.if PPE
4404 | sub TMP1, TMP3, RC
4405 | cmpwi TMP1, 0
4406 |.else
4172 | sub. TMP1, TMP3, RC 4407 | sub. TMP1, TMP3, RC
4408 |.endif
4173 | beq cr1, >5 // Copy all varargs? 4409 | beq cr1, >5 // Copy all varargs?
4174 | subi TMP2, TMP2, 16 4410 | subi TMP2, TMP2, 16
4175 | ble >2 // No vararg slots? 4411 | ble >2 // No vararg slots?
@@ -4209,14 +4445,14 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4209 | 4445 |
4210 |7: // Grow stack for varargs. 4446 |7: // Grow stack for varargs.
4211 | mr CARG1, L 4447 | mr CARG1, L
4212 | stw RA, L->top 4448 | stp RA, L->top
4213 | sub SAVE0, RC, BASE // Need delta, because BASE may change. 4449 | sub SAVE0, RC, BASE // Need delta, because BASE may change.
4214 | stw BASE, L->base 4450 | stp BASE, L->base
4215 | sub RA, RA, BASE 4451 | sub RA, RA, BASE
4216 | stw PC, SAVE_PC 4452 | stw PC, SAVE_PC
4217 | srwi CARG2, TMP1, 3 4453 | srwi CARG2, TMP1, 3
4218 | bl extern lj_state_growstack // (lua_State *L, int n) 4454 | bl extern lj_state_growstack // (lua_State *L, int n)
4219 | lwz BASE, L->base 4455 | lp BASE, L->base
4220 | add RA, BASE, RA 4456 | add RA, BASE, RA
4221 | add RC, BASE, SAVE0 4457 | add RC, BASE, SAVE0
4222 | subi TMP3, BASE, 8 4458 | subi TMP3, BASE, 8
@@ -4237,7 +4473,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4237 | add RA, BASE, RA 4473 | add RA, BASE, RA
4238 | mr MULTRES, RD 4474 | mr MULTRES, RD
4239 |1: 4475 |1:
4240 | andi. TMP0, PC, FRAME_TYPE 4476 | andix. TMP0, PC, FRAME_TYPE
4241 | xori TMP1, PC, FRAME_VARG 4477 | xori TMP1, PC, FRAME_VARG
4242 | bne ->BC_RETV_Z 4478 | bne ->BC_RETV_Z
4243 | 4479 |
@@ -4280,7 +4516,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4280 | b <5 4516 | b <5
4281 | 4517 |
4282 |->BC_RETV_Z: // Non-standard return case. 4518 |->BC_RETV_Z: // Non-standard return case.
4283 | andi. TMP2, TMP1, FRAME_TYPEP 4519 | andix. TMP2, TMP1, FRAME_TYPEP
4284 | bne ->vm_return 4520 | bne ->vm_return
4285 | // Return from vararg function: relocate BASE down. 4521 | // Return from vararg function: relocate BASE down.
4286 | sub BASE, BASE, TMP1 4522 | sub BASE, BASE, TMP1
@@ -4293,7 +4529,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4293 | lwz PC, FRAME_PC(BASE) 4529 | lwz PC, FRAME_PC(BASE)
4294 | add RA, BASE, RA 4530 | add RA, BASE, RA
4295 | mr MULTRES, RD 4531 | mr MULTRES, RD
4296 | andi. TMP0, PC, FRAME_TYPE 4532 | andix. TMP0, PC, FRAME_TYPE
4297 | xori TMP1, PC, FRAME_VARG 4533 | xori TMP1, PC, FRAME_VARG
4298 | bney ->BC_RETV_Z 4534 | bney ->BC_RETV_Z
4299 | 4535 |
@@ -4348,7 +4584,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4348 if (vk) { 4584 if (vk) {
4349 | lwz CARG3, FORL_STEP*8+4(RA) 4585 | lwz CARG3, FORL_STEP*8+4(RA)
4350 | bne >9 4586 | bne >9
4587 |.if GPR64
4588 | // Need to check overflow for (a<<32) + (b<<32).
4589 | rldicr TMP0, CARG1, 32, 31
4590 | rldicr TMP2, CARG3, 32, 31
4591 | add CARG1, CARG1, CARG3
4592 | addo. TMP0, TMP0, TMP2
4593 |.else
4351 | addo. CARG1, CARG1, CARG3 4594 | addo. CARG1, CARG1, CARG3
4595 |.endif
4352 | cmpwi cr6, CARG3, 0 4596 | cmpwi cr6, CARG3, 0
4353 | lwz CARG2, FORL_STOP*8+4(RA) 4597 | lwz CARG2, FORL_STOP*8+4(RA)
4354 | bso >6 4598 | bso >6
@@ -4536,7 +4780,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4536 | stw ZERO, DISPATCH_GL(vmstate)(DISPATCH) 4780 | stw ZERO, DISPATCH_GL(vmstate)(DISPATCH)
4537 | lwzx TRACE:TMP2, TMP1, RD 4781 | lwzx TRACE:TMP2, TMP1, RD
4538 | mcrxr cr0 // Clear SO flag. 4782 | mcrxr cr0 // Clear SO flag.
4539 | lwz TMP2, TRACE:TMP2->mcode 4783 | lp TMP2, TRACE:TMP2->mcode
4540 | stw BASE, DISPATCH_GL(jit_base)(DISPATCH) 4784 | stw BASE, DISPATCH_GL(jit_base)(DISPATCH)
4541 | mtctr TMP2 4785 | mtctr TMP2
4542 | stw L, DISPATCH_GL(jit_L)(DISPATCH) 4786 | stw L, DISPATCH_GL(jit_L)(DISPATCH)
@@ -4642,29 +4886,33 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4642 case BC_FUNCCW: 4886 case BC_FUNCCW:
4643 | // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8 4887 | // BASE = new base, RA = BASE+framesize*8, RB = CFUNC, RC = nargs*8
4644 if (op == BC_FUNCC) { 4888 if (op == BC_FUNCC) {
4645 | lwz TMP3, CFUNC:RB->f 4889 | lp RD, CFUNC:RB->f
4646 } else { 4890 } else {
4647 | lwz TMP3, DISPATCH_GL(wrapf)(DISPATCH) 4891 | lp RD, DISPATCH_GL(wrapf)(DISPATCH)
4648 } 4892 }
4649 | add TMP1, RA, NARGS8:RC 4893 | add TMP1, RA, NARGS8:RC
4650 | lwz TMP2, L->maxstack 4894 | lwz TMP2, L->maxstack
4895 | .toc lp TMP3, 0(RD)
4651 | add RC, BASE, NARGS8:RC 4896 | add RC, BASE, NARGS8:RC
4652 | stw BASE, L->base 4897 | stp BASE, L->base
4653 | cmplw TMP1, TMP2 4898 | cmplw TMP1, TMP2
4654 | stw RC, L->top 4899 | stp RC, L->top
4655 | li_vmstate C 4900 | li_vmstate C
4656 | mtctr TMP3 4901 | mtctr TMP3
4657 if (op == BC_FUNCCW) { 4902 if (op == BC_FUNCCW) {
4658 | lwz CARG2, CFUNC:RB->f 4903 | lp CARG2, CFUNC:RB->f
4659 } 4904 }
4660 | mr CARG1, L 4905 | mr CARG1, L
4661 | bgt ->vm_growstack_c // Need to grow stack. 4906 | bgt ->vm_growstack_c // Need to grow stack.
4907 | .toc lp TOCREG, TOC_OFS(RD)
4908 | .tocenv lp ENVREG, ENV_OFS(RD)
4662 | st_vmstate 4909 | st_vmstate
4663 | bctrl // (lua_State *L [, lua_CFunction f]) 4910 | bctrl // (lua_State *L [, lua_CFunction f])
4664 | // Returns nresults. 4911 | // Returns nresults.
4665 | lwz BASE, L->base 4912 | lp BASE, L->base
4913 | .toc ld TOCREG, SAVE_TOC
4666 | slwi RD, CRET1, 3 4914 | slwi RD, CRET1, 3
4667 | lwz TMP1, L->top 4915 | lp TMP1, L->top
4668 | li_vmstate INTERP 4916 | li_vmstate INTERP
4669 | lwz PC, FRAME_PC(BASE) // Fetch PC of caller. 4917 | lwz PC, FRAME_PC(BASE) // Fetch PC of caller.
4670 | sub RA, TMP1, RD // RA = L->top - nresults*8 4918 | sub RA, TMP1, RD // RA = L->top - nresults*8