diff options
| author | Mike Pall <mike> | 2017-07-26 09:52:19 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2017-07-26 09:52:19 +0200 |
| commit | fd37da0d586c331b0008fbfd653a9659344fe76f (patch) | |
| tree | 2ae660cbdbe316ac4affecf5d4f4cf6e013f2b69 /src | |
| parent | 7e662e4f87134f1e84f7bea80933e033c5bf53a3 (diff) | |
| download | luajit-fd37da0d586c331b0008fbfd653a9659344fe76f.tar.gz luajit-fd37da0d586c331b0008fbfd653a9659344fe76f.tar.bz2 luajit-fd37da0d586c331b0008fbfd653a9659344fe76f.zip | |
PPC: Add soft-float support to interpreter.
Contributed by Djordje Kovacevic and Stefan Pejic from RT-RK.com.
Sponsored by Cisco Systems, Inc.
Diffstat (limited to 'src')
| -rw-r--r-- | src/host/buildvm_asm.c | 2 | ||||
| -rw-r--r-- | src/lj_arch.h | 29 | ||||
| -rw-r--r-- | src/lj_ccall.c | 38 | ||||
| -rw-r--r-- | src/lj_ccall.h | 4 | ||||
| -rw-r--r-- | src/lj_ccallback.c | 30 | ||||
| -rw-r--r-- | src/lj_frame.h | 2 | ||||
| -rw-r--r-- | src/lj_ircall.h | 2 | ||||
| -rw-r--r-- | src/vm_ppc.dasc | 1249 |
8 files changed, 1101 insertions, 255 deletions
diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c index ffd14903..43595b31 100644 --- a/src/host/buildvm_asm.c +++ b/src/host/buildvm_asm.c | |||
| @@ -338,7 +338,7 @@ void emit_asm(BuildCtx *ctx) | |||
| 338 | #if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) | 338 | #if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) |
| 339 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); | 339 | fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); |
| 340 | #endif | 340 | #endif |
| 341 | #if LJ_TARGET_PPC && !LJ_TARGET_PS3 | 341 | #if LJ_TARGET_PPC && !LJ_TARGET_PS3 && !LJ_ABI_SOFTFP |
| 342 | /* Hard-float ABI. */ | 342 | /* Hard-float ABI. */ |
| 343 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); | 343 | fprintf(ctx->fp, "\t.gnu_attribute 4, 1\n"); |
| 344 | #endif | 344 | #endif |
diff --git a/src/lj_arch.h b/src/lj_arch.h index b7705642..0145a7c0 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h | |||
| @@ -254,6 +254,29 @@ | |||
| 254 | #else | 254 | #else |
| 255 | #define LJ_ARCH_BITS 32 | 255 | #define LJ_ARCH_BITS 32 |
| 256 | #define LJ_ARCH_NAME "ppc" | 256 | #define LJ_ARCH_NAME "ppc" |
| 257 | |||
| 258 | #if !defined(LJ_ARCH_HASFPU) | ||
| 259 | #if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE) | ||
| 260 | #define LJ_ARCH_HASFPU 0 | ||
| 261 | #else | ||
| 262 | #define LJ_ARCH_HASFPU 1 | ||
| 263 | #endif | ||
| 264 | #endif | ||
| 265 | |||
| 266 | #if !defined(LJ_ABI_SOFTFP) | ||
| 267 | #if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE) | ||
| 268 | #define LJ_ABI_SOFTFP 1 | ||
| 269 | #else | ||
| 270 | #define LJ_ABI_SOFTFP 0 | ||
| 271 | #endif | ||
| 272 | #endif | ||
| 273 | #endif | ||
| 274 | |||
| 275 | #if LJ_ABI_SOFTFP | ||
| 276 | #define LJ_ARCH_NOJIT 1 /* NYI */ | ||
| 277 | #define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL | ||
| 278 | #else | ||
| 279 | #define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE | ||
| 257 | #endif | 280 | #endif |
| 258 | 281 | ||
| 259 | #define LJ_TARGET_PPC 1 | 282 | #define LJ_TARGET_PPC 1 |
| @@ -262,7 +285,6 @@ | |||
| 262 | #define LJ_TARGET_MASKSHIFT 0 | 285 | #define LJ_TARGET_MASKSHIFT 0 |
| 263 | #define LJ_TARGET_MASKROT 1 | 286 | #define LJ_TARGET_MASKROT 1 |
| 264 | #define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */ | 287 | #define LJ_TARGET_UNIFYROT 1 /* Want only IR_BROL. */ |
| 265 | #define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE | ||
| 266 | 288 | ||
| 267 | #if LJ_TARGET_CONSOLE | 289 | #if LJ_TARGET_CONSOLE |
| 268 | #define LJ_ARCH_PPC32ON64 1 | 290 | #define LJ_ARCH_PPC32ON64 1 |
| @@ -415,16 +437,13 @@ | |||
| 415 | #error "No support for ILP32 model on ARM64" | 437 | #error "No support for ILP32 model on ARM64" |
| 416 | #endif | 438 | #endif |
| 417 | #elif LJ_TARGET_PPC | 439 | #elif LJ_TARGET_PPC |
| 418 | #if defined(_SOFT_FLOAT) || defined(_SOFT_DOUBLE) | ||
| 419 | #error "No support for PowerPC CPUs without double-precision FPU" | ||
| 420 | #endif | ||
| 421 | #if !LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_LE | 440 | #if !LJ_ARCH_PPC64 && LJ_ARCH_ENDIAN == LUAJIT_LE |
| 422 | #error "No support for little-endian PPC32" | 441 | #error "No support for little-endian PPC32" |
| 423 | #endif | 442 | #endif |
| 424 | #if LJ_ARCH_PPC64 | 443 | #if LJ_ARCH_PPC64 |
| 425 | #error "No support for PowerPC 64 bit mode (yet)" | 444 | #error "No support for PowerPC 64 bit mode (yet)" |
| 426 | #endif | 445 | #endif |
| 427 | #ifdef __NO_FPRS__ | 446 | #if defined(__NO_FPRS__) && !defined(_SOFT_FLOAT) |
| 428 | #error "No support for PPC/e500 anymore (use LuaJIT 2.0)" | 447 | #error "No support for PPC/e500 anymore (use LuaJIT 2.0)" |
| 429 | #endif | 448 | #endif |
| 430 | #elif LJ_TARGET_MIPS32 | 449 | #elif LJ_TARGET_MIPS32 |
diff --git a/src/lj_ccall.c b/src/lj_ccall.c index 5c252e5b..799be487 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c | |||
| @@ -387,6 +387,24 @@ | |||
| 387 | #define CCALL_HANDLE_COMPLEXARG \ | 387 | #define CCALL_HANDLE_COMPLEXARG \ |
| 388 | /* Pass complex by value in 2 or 4 GPRs. */ | 388 | /* Pass complex by value in 2 or 4 GPRs. */ |
| 389 | 389 | ||
| 390 | #define CCALL_HANDLE_GPR \ | ||
| 391 | /* Try to pass argument in GPRs. */ \ | ||
| 392 | if (n > 1) { \ | ||
| 393 | lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \ | ||
| 394 | if (ctype_isinteger(d->info) || ctype_isfp(d->info)) \ | ||
| 395 | ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \ | ||
| 396 | else if (ngpr + n > maxgpr) \ | ||
| 397 | ngpr = maxgpr; /* Prevent reordering. */ \ | ||
| 398 | } \ | ||
| 399 | if (ngpr + n <= maxgpr) { \ | ||
| 400 | dp = &cc->gpr[ngpr]; \ | ||
| 401 | ngpr += n; \ | ||
| 402 | goto done; \ | ||
| 403 | } \ | ||
| 404 | |||
| 405 | #if LJ_ABI_SOFTFP | ||
| 406 | #define CCALL_HANDLE_REGARG CCALL_HANDLE_GPR | ||
| 407 | #else | ||
| 390 | #define CCALL_HANDLE_REGARG \ | 408 | #define CCALL_HANDLE_REGARG \ |
| 391 | if (isfp) { /* Try to pass argument in FPRs. */ \ | 409 | if (isfp) { /* Try to pass argument in FPRs. */ \ |
| 392 | if (nfpr + 1 <= CCALL_NARG_FPR) { \ | 410 | if (nfpr + 1 <= CCALL_NARG_FPR) { \ |
| @@ -395,24 +413,16 @@ | |||
| 395 | d = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \ | 413 | d = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \ |
| 396 | goto done; \ | 414 | goto done; \ |
| 397 | } \ | 415 | } \ |
| 398 | } else { /* Try to pass argument in GPRs. */ \ | 416 | } else { \ |
| 399 | if (n > 1) { \ | 417 | CCALL_HANDLE_GPR \ |
| 400 | lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \ | ||
| 401 | if (ctype_isinteger(d->info)) \ | ||
| 402 | ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \ | ||
| 403 | else if (ngpr + n > maxgpr) \ | ||
| 404 | ngpr = maxgpr; /* Prevent reordering. */ \ | ||
| 405 | } \ | ||
| 406 | if (ngpr + n <= maxgpr) { \ | ||
| 407 | dp = &cc->gpr[ngpr]; \ | ||
| 408 | ngpr += n; \ | ||
| 409 | goto done; \ | ||
| 410 | } \ | ||
| 411 | } | 418 | } |
| 419 | #endif | ||
| 412 | 420 | ||
| 421 | #if !LJ_ABI_SOFTFP | ||
| 413 | #define CCALL_HANDLE_RET \ | 422 | #define CCALL_HANDLE_RET \ |
| 414 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ | 423 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ |
| 415 | ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ | 424 | ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ |
| 425 | #endif | ||
| 416 | 426 | ||
| 417 | #elif LJ_TARGET_MIPS32 | 427 | #elif LJ_TARGET_MIPS32 |
| 418 | /* -- MIPS o32 calling conventions ---------------------------------------- */ | 428 | /* -- MIPS o32 calling conventions ---------------------------------------- */ |
| @@ -1080,7 +1090,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, | |||
| 1080 | } | 1090 | } |
| 1081 | if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */ | 1091 | if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */ |
| 1082 | 1092 | ||
| 1083 | #if LJ_TARGET_X64 || LJ_TARGET_PPC | 1093 | #if LJ_TARGET_X64 || (LJ_TARGET_PPC && !LJ_ABI_SOFTFP) |
| 1084 | cc->nfpr = nfpr; /* Required for vararg functions. */ | 1094 | cc->nfpr = nfpr; /* Required for vararg functions. */ |
| 1085 | #endif | 1095 | #endif |
| 1086 | cc->nsp = nsp; | 1096 | cc->nsp = nsp; |
diff --git a/src/lj_ccall.h b/src/lj_ccall.h index 59f66481..6efa48c7 100644 --- a/src/lj_ccall.h +++ b/src/lj_ccall.h | |||
| @@ -86,9 +86,9 @@ typedef union FPRArg { | |||
| 86 | #elif LJ_TARGET_PPC | 86 | #elif LJ_TARGET_PPC |
| 87 | 87 | ||
| 88 | #define CCALL_NARG_GPR 8 | 88 | #define CCALL_NARG_GPR 8 |
| 89 | #define CCALL_NARG_FPR 8 | 89 | #define CCALL_NARG_FPR (LJ_ABI_SOFTFP ? 0 : 8) |
| 90 | #define CCALL_NRET_GPR 4 /* For complex double. */ | 90 | #define CCALL_NRET_GPR 4 /* For complex double. */ |
| 91 | #define CCALL_NRET_FPR 1 | 91 | #define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 1) |
| 92 | #define CCALL_SPS_EXTRA 4 | 92 | #define CCALL_SPS_EXTRA 4 |
| 93 | #define CCALL_SPS_FREE 0 | 93 | #define CCALL_SPS_FREE 0 |
| 94 | 94 | ||
diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index 846827b1..03494a7a 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c | |||
| @@ -419,6 +419,23 @@ void lj_ccallback_mcode_free(CTState *cts) | |||
| 419 | 419 | ||
| 420 | #elif LJ_TARGET_PPC | 420 | #elif LJ_TARGET_PPC |
| 421 | 421 | ||
| 422 | #define CALLBACK_HANDLE_GPR \ | ||
| 423 | if (n > 1) { \ | ||
| 424 | lua_assert(((LJ_ABI_SOFTFP && ctype_isnum(cta->info)) || /* double. */ \ | ||
| 425 | ctype_isinteger(cta->info)) && n == 2); /* int64_t. */ \ | ||
| 426 | ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \ | ||
| 427 | } \ | ||
| 428 | if (ngpr + n <= maxgpr) { \ | ||
| 429 | sp = &cts->cb.gpr[ngpr]; \ | ||
| 430 | ngpr += n; \ | ||
| 431 | goto done; \ | ||
| 432 | } | ||
| 433 | |||
| 434 | #if LJ_ABI_SOFTFP | ||
| 435 | #define CALLBACK_HANDLE_REGARG \ | ||
| 436 | CALLBACK_HANDLE_GPR \ | ||
| 437 | UNUSED(isfp); | ||
| 438 | #else | ||
| 422 | #define CALLBACK_HANDLE_REGARG \ | 439 | #define CALLBACK_HANDLE_REGARG \ |
| 423 | if (isfp) { \ | 440 | if (isfp) { \ |
| 424 | if (nfpr + 1 <= CCALL_NARG_FPR) { \ | 441 | if (nfpr + 1 <= CCALL_NARG_FPR) { \ |
| @@ -427,20 +444,15 @@ void lj_ccallback_mcode_free(CTState *cts) | |||
| 427 | goto done; \ | 444 | goto done; \ |
| 428 | } \ | 445 | } \ |
| 429 | } else { /* Try to pass argument in GPRs. */ \ | 446 | } else { /* Try to pass argument in GPRs. */ \ |
| 430 | if (n > 1) { \ | 447 | CALLBACK_HANDLE_GPR \ |
| 431 | lua_assert(ctype_isinteger(cta->info) && n == 2); /* int64_t. */ \ | ||
| 432 | ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \ | ||
| 433 | } \ | ||
| 434 | if (ngpr + n <= maxgpr) { \ | ||
| 435 | sp = &cts->cb.gpr[ngpr]; \ | ||
| 436 | ngpr += n; \ | ||
| 437 | goto done; \ | ||
| 438 | } \ | ||
| 439 | } | 448 | } |
| 449 | #endif | ||
| 440 | 450 | ||
| 451 | #if !LJ_ABI_SOFTFP | ||
| 441 | #define CALLBACK_HANDLE_RET \ | 452 | #define CALLBACK_HANDLE_RET \ |
| 442 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ | 453 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ |
| 443 | *(double *)dp = *(float *)dp; /* FPRs always hold doubles. */ | 454 | *(double *)dp = *(float *)dp; /* FPRs always hold doubles. */ |
| 455 | #endif | ||
| 444 | 456 | ||
| 445 | #elif LJ_TARGET_MIPS32 | 457 | #elif LJ_TARGET_MIPS32 |
| 446 | 458 | ||
diff --git a/src/lj_frame.h b/src/lj_frame.h index 19c49a4a..04cb5a35 100644 --- a/src/lj_frame.h +++ b/src/lj_frame.h | |||
| @@ -226,7 +226,7 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ | |||
| 226 | #define CFRAME_OFS_L 36 | 226 | #define CFRAME_OFS_L 36 |
| 227 | #define CFRAME_OFS_PC 32 | 227 | #define CFRAME_OFS_PC 32 |
| 228 | #define CFRAME_OFS_MULTRES 28 | 228 | #define CFRAME_OFS_MULTRES 28 |
| 229 | #define CFRAME_SIZE 272 | 229 | #define CFRAME_SIZE (LJ_ARCH_HASFPU ? 272 : 128) |
| 230 | #define CFRAME_SHIFT_MULTRES 3 | 230 | #define CFRAME_SHIFT_MULTRES 3 |
| 231 | #endif | 231 | #endif |
| 232 | #elif LJ_TARGET_MIPS32 | 232 | #elif LJ_TARGET_MIPS32 |
diff --git a/src/lj_ircall.h b/src/lj_ircall.h index 73120065..9b3883b7 100644 --- a/src/lj_ircall.h +++ b/src/lj_ircall.h | |||
| @@ -287,7 +287,7 @@ LJ_DATA const CCallInfo lj_ir_callinfo[IRCALL__MAX+1]; | |||
| 287 | #define fp64_f2l __aeabi_f2lz | 287 | #define fp64_f2l __aeabi_f2lz |
| 288 | #define fp64_f2ul __aeabi_f2ulz | 288 | #define fp64_f2ul __aeabi_f2ulz |
| 289 | #endif | 289 | #endif |
| 290 | #elif LJ_TARGET_MIPS | 290 | #elif LJ_TARGET_MIPS || LJ_TARGET_PPC |
| 291 | #define softfp_add __adddf3 | 291 | #define softfp_add __adddf3 |
| 292 | #define softfp_sub __subdf3 | 292 | #define softfp_sub __subdf3 |
| 293 | #define softfp_mul __muldf3 | 293 | #define softfp_mul __muldf3 |
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc index b4260ebc..0839668c 100644 --- a/src/vm_ppc.dasc +++ b/src/vm_ppc.dasc | |||
| @@ -103,6 +103,18 @@ | |||
| 103 | |// Fixed register assignments for the interpreter. | 103 | |// Fixed register assignments for the interpreter. |
| 104 | |// Don't use: r1 = sp, r2 and r13 = reserved (TOC, TLS or SDATA) | 104 | |// Don't use: r1 = sp, r2 and r13 = reserved (TOC, TLS or SDATA) |
| 105 | | | 105 | | |
| 106 | |.macro .FPU, a, b | ||
| 107 | |.if FPU | ||
| 108 | | a, b | ||
| 109 | |.endif | ||
| 110 | |.endmacro | ||
| 111 | | | ||
| 112 | |.macro .FPU, a, b, c | ||
| 113 | |.if FPU | ||
| 114 | | a, b, c | ||
| 115 | |.endif | ||
| 116 | |.endmacro | ||
| 117 | | | ||
| 106 | |// The following must be C callee-save (but BASE is often refetched). | 118 | |// The following must be C callee-save (but BASE is often refetched). |
| 107 | |.define BASE, r14 // Base of current Lua stack frame. | 119 | |.define BASE, r14 // Base of current Lua stack frame. |
| 108 | |.define KBASE, r15 // Constants of current Lua function. | 120 | |.define KBASE, r15 // Constants of current Lua function. |
| @@ -116,8 +128,10 @@ | |||
| 116 | |.define TISNUM, r22 | 128 | |.define TISNUM, r22 |
| 117 | |.define TISNIL, r23 | 129 | |.define TISNIL, r23 |
| 118 | |.define ZERO, r24 | 130 | |.define ZERO, r24 |
| 131 | |.if FPU | ||
| 119 | |.define TOBIT, f30 // 2^52 + 2^51. | 132 | |.define TOBIT, f30 // 2^52 + 2^51. |
| 120 | |.define TONUM, f31 // 2^52 + 2^51 + 2^31. | 133 | |.define TONUM, f31 // 2^52 + 2^51 + 2^31. |
| 134 | |.endif | ||
| 121 | | | 135 | | |
| 122 | |// The following temporaries are not saved across C calls, except for RA. | 136 | |// The following temporaries are not saved across C calls, except for RA. |
| 123 | |.define RA, r20 // Callee-save. | 137 | |.define RA, r20 // Callee-save. |
| @@ -133,6 +147,7 @@ | |||
| 133 | | | 147 | | |
| 134 | |// Saved temporaries. | 148 | |// Saved temporaries. |
| 135 | |.define SAVE0, r21 | 149 | |.define SAVE0, r21 |
| 150 | |.define SAVE1, r25 | ||
| 136 | | | 151 | | |
| 137 | |// Calling conventions. | 152 | |// Calling conventions. |
| 138 | |.define CARG1, r3 | 153 | |.define CARG1, r3 |
| @@ -141,8 +156,10 @@ | |||
| 141 | |.define CARG4, r6 // Overlaps TMP3. | 156 | |.define CARG4, r6 // Overlaps TMP3. |
| 142 | |.define CARG5, r7 // Overlaps INS. | 157 | |.define CARG5, r7 // Overlaps INS. |
| 143 | | | 158 | | |
| 159 | |.if FPU | ||
| 144 | |.define FARG1, f1 | 160 | |.define FARG1, f1 |
| 145 | |.define FARG2, f2 | 161 | |.define FARG2, f2 |
| 162 | |.endif | ||
| 146 | | | 163 | | |
| 147 | |.define CRET1, r3 | 164 | |.define CRET1, r3 |
| 148 | |.define CRET2, r4 | 165 | |.define CRET2, r4 |
| @@ -213,10 +230,16 @@ | |||
| 213 | |.endif | 230 | |.endif |
| 214 | |.else | 231 | |.else |
| 215 | | | 232 | | |
| 233 | |.if FPU | ||
| 216 | |.define SAVE_LR, 276(sp) | 234 | |.define SAVE_LR, 276(sp) |
| 217 | |.define CFRAME_SPACE, 272 // Delta for sp. | 235 | |.define CFRAME_SPACE, 272 // Delta for sp. |
| 218 | |// Back chain for sp: 272(sp) <-- sp entering interpreter | 236 | |// Back chain for sp: 272(sp) <-- sp entering interpreter |
| 219 | |.define SAVE_FPR_, 128 // .. 128+18*8: 64 bit FPR saves. | 237 | |.define SAVE_FPR_, 128 // .. 128+18*8: 64 bit FPR saves. |
| 238 | |.else | ||
| 239 | |.define SAVE_LR, 132(sp) | ||
| 240 | |.define CFRAME_SPACE, 128 // Delta for sp. | ||
| 241 | |// Back chain for sp: 128(sp) <-- sp entering interpreter | ||
| 242 | |.endif | ||
| 220 | |.define SAVE_GPR_, 56 // .. 56+18*4: 32 bit GPR saves. | 243 | |.define SAVE_GPR_, 56 // .. 56+18*4: 32 bit GPR saves. |
| 221 | |.define SAVE_CR, 52(sp) // 32 bit CR save. | 244 | |.define SAVE_CR, 52(sp) // 32 bit CR save. |
| 222 | |.define SAVE_ERRF, 48(sp) // 32 bit C frame info. | 245 | |.define SAVE_ERRF, 48(sp) // 32 bit C frame info. |
| @@ -226,16 +249,25 @@ | |||
| 226 | |.define SAVE_PC, 32(sp) | 249 | |.define SAVE_PC, 32(sp) |
| 227 | |.define SAVE_MULTRES, 28(sp) | 250 | |.define SAVE_MULTRES, 28(sp) |
| 228 | |.define UNUSED1, 24(sp) | 251 | |.define UNUSED1, 24(sp) |
| 252 | |.if FPU | ||
| 229 | |.define TMPD_LO, 20(sp) | 253 | |.define TMPD_LO, 20(sp) |
| 230 | |.define TMPD_HI, 16(sp) | 254 | |.define TMPD_HI, 16(sp) |
| 231 | |.define TONUM_LO, 12(sp) | 255 | |.define TONUM_LO, 12(sp) |
| 232 | |.define TONUM_HI, 8(sp) | 256 | |.define TONUM_HI, 8(sp) |
| 257 | |.else | ||
| 258 | |.define SFSAVE_4, 20(sp) | ||
| 259 | |.define SFSAVE_3, 16(sp) | ||
| 260 | |.define SFSAVE_2, 12(sp) | ||
| 261 | |.define SFSAVE_1, 8(sp) | ||
| 262 | |.endif | ||
| 233 | |// Next frame lr: 4(sp) | 263 | |// Next frame lr: 4(sp) |
| 234 | |// Back chain for sp: 0(sp) <-- sp while in interpreter | 264 | |// Back chain for sp: 0(sp) <-- sp while in interpreter |
| 235 | | | 265 | | |
| 266 | |.if FPU | ||
| 236 | |.define TMPD_BLO, 23(sp) | 267 | |.define TMPD_BLO, 23(sp) |
| 237 | |.define TMPD, TMPD_HI | 268 | |.define TMPD, TMPD_HI |
| 238 | |.define TONUM_D, TONUM_HI | 269 | |.define TONUM_D, TONUM_HI |
| 270 | |.endif | ||
| 239 | | | 271 | | |
| 240 | |.endif | 272 | |.endif |
| 241 | | | 273 | | |
| @@ -245,7 +277,7 @@ | |||
| 245 | |.else | 277 | |.else |
| 246 | | stw r..reg, SAVE_GPR_+(reg-14)*4(sp) | 278 | | stw r..reg, SAVE_GPR_+(reg-14)*4(sp) |
| 247 | |.endif | 279 | |.endif |
| 248 | | stfd f..reg, SAVE_FPR_+(reg-14)*8(sp) | 280 | | .FPU stfd f..reg, SAVE_FPR_+(reg-14)*8(sp) |
| 249 | |.endmacro | 281 | |.endmacro |
| 250 | |.macro rest_, reg | 282 | |.macro rest_, reg |
| 251 | |.if GPR64 | 283 | |.if GPR64 |
| @@ -253,7 +285,7 @@ | |||
| 253 | |.else | 285 | |.else |
| 254 | | lwz r..reg, SAVE_GPR_+(reg-14)*4(sp) | 286 | | lwz r..reg, SAVE_GPR_+(reg-14)*4(sp) |
| 255 | |.endif | 287 | |.endif |
| 256 | | lfd f..reg, SAVE_FPR_+(reg-14)*8(sp) | 288 | | .FPU lfd f..reg, SAVE_FPR_+(reg-14)*8(sp) |
| 257 | |.endmacro | 289 | |.endmacro |
| 258 | | | 290 | | |
| 259 | |.macro saveregs | 291 | |.macro saveregs |
| @@ -323,6 +355,7 @@ | |||
| 323 | |// Trap for not-yet-implemented parts. | 355 | |// Trap for not-yet-implemented parts. |
| 324 | |.macro NYI; tw 4, sp, sp; .endmacro | 356 | |.macro NYI; tw 4, sp, sp; .endmacro |
| 325 | | | 357 | | |
| 358 | |.if FPU | ||
| 326 | |// int/FP conversions. | 359 | |// int/FP conversions. |
| 327 | |.macro tonum_i, freg, reg | 360 | |.macro tonum_i, freg, reg |
| 328 | | xoris reg, reg, 0x8000 | 361 | | xoris reg, reg, 0x8000 |
| @@ -346,6 +379,7 @@ | |||
| 346 | |.macro toint, reg, freg | 379 | |.macro toint, reg, freg |
| 347 | | toint reg, freg, freg | 380 | | toint reg, freg, freg |
| 348 | |.endmacro | 381 | |.endmacro |
| 382 | |.endif | ||
| 349 | | | 383 | | |
| 350 | |//----------------------------------------------------------------------- | 384 | |//----------------------------------------------------------------------- |
| 351 | | | 385 | | |
| @@ -533,9 +567,19 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 533 | | beq >2 | 567 | | beq >2 |
| 534 | |1: | 568 | |1: |
| 535 | | addic. TMP1, TMP1, -8 | 569 | | addic. TMP1, TMP1, -8 |
| 570 | |.if FPU | ||
| 536 | | lfd f0, 0(RA) | 571 | | lfd f0, 0(RA) |
| 572 | |.else | ||
| 573 | | lwz CARG1, 0(RA) | ||
| 574 | | lwz CARG2, 4(RA) | ||
| 575 | |.endif | ||
| 537 | | addi RA, RA, 8 | 576 | | addi RA, RA, 8 |
| 577 | |.if FPU | ||
| 538 | | stfd f0, 0(BASE) | 578 | | stfd f0, 0(BASE) |
| 579 | |.else | ||
| 580 | | stw CARG1, 0(BASE) | ||
| 581 | | stw CARG2, 4(BASE) | ||
| 582 | |.endif | ||
| 539 | | addi BASE, BASE, 8 | 583 | | addi BASE, BASE, 8 |
| 540 | | bney <1 | 584 | | bney <1 |
| 541 | | | 585 | | |
| @@ -613,23 +657,23 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 613 | | .toc ld TOCREG, SAVE_TOC | 657 | | .toc ld TOCREG, SAVE_TOC |
| 614 | | li TISNUM, LJ_TISNUM // Setup type comparison constants. | 658 | | li TISNUM, LJ_TISNUM // Setup type comparison constants. |
| 615 | | lp BASE, L->base | 659 | | lp BASE, L->base |
| 616 | | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | 660 | | .FPU lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). |
| 617 | | lwz DISPATCH, L->glref // Setup pointer to dispatch table. | 661 | | lwz DISPATCH, L->glref // Setup pointer to dispatch table. |
| 618 | | li ZERO, 0 | 662 | | li ZERO, 0 |
| 619 | | stw TMP3, TMPD | 663 | | .FPU stw TMP3, TMPD |
| 620 | | li TMP1, LJ_TFALSE | 664 | | li TMP1, LJ_TFALSE |
| 621 | | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). | 665 | | .FPU ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). |
| 622 | | li TISNIL, LJ_TNIL | 666 | | li TISNIL, LJ_TNIL |
| 623 | | li_vmstate INTERP | 667 | | li_vmstate INTERP |
| 624 | | lfs TOBIT, TMPD | 668 | | .FPU lfs TOBIT, TMPD |
| 625 | | lwz PC, FRAME_PC(BASE) // Fetch PC of previous frame. | 669 | | lwz PC, FRAME_PC(BASE) // Fetch PC of previous frame. |
| 626 | | la RA, -8(BASE) // Results start at BASE-8. | 670 | | la RA, -8(BASE) // Results start at BASE-8. |
| 627 | | stw TMP3, TMPD | 671 | | .FPU stw TMP3, TMPD |
| 628 | | addi DISPATCH, DISPATCH, GG_G2DISP | 672 | | addi DISPATCH, DISPATCH, GG_G2DISP |
| 629 | | stw TMP1, 0(RA) // Prepend false to error message. | 673 | | stw TMP1, 0(RA) // Prepend false to error message. |
| 630 | | li RD, 16 // 2 results: false + error message. | 674 | | li RD, 16 // 2 results: false + error message. |
| 631 | | st_vmstate | 675 | | st_vmstate |
| 632 | | lfs TONUM, TMPD | 676 | | .FPU lfs TONUM, TMPD |
| 633 | | b ->vm_returnc | 677 | | b ->vm_returnc |
| 634 | | | 678 | | |
| 635 | |//----------------------------------------------------------------------- | 679 | |//----------------------------------------------------------------------- |
| @@ -690,22 +734,22 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 690 | | li TISNUM, LJ_TISNUM // Setup type comparison constants. | 734 | | li TISNUM, LJ_TISNUM // Setup type comparison constants. |
| 691 | | lp TMP1, L->top | 735 | | lp TMP1, L->top |
| 692 | | lwz PC, FRAME_PC(BASE) | 736 | | lwz PC, FRAME_PC(BASE) |
| 693 | | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | 737 | | .FPU lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). |
| 694 | | stb CARG3, L->status | 738 | | stb CARG3, L->status |
| 695 | | stw TMP3, TMPD | 739 | | .FPU stw TMP3, TMPD |
| 696 | | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). | 740 | | .FPU ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). |
| 697 | | lfs TOBIT, TMPD | 741 | | .FPU lfs TOBIT, TMPD |
| 698 | | sub RD, TMP1, BASE | 742 | | sub RD, TMP1, BASE |
| 699 | | stw TMP3, TMPD | 743 | | .FPU stw TMP3, TMPD |
| 700 | | lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double) | 744 | | .FPU lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double) |
| 701 | | addi RD, RD, 8 | 745 | | addi RD, RD, 8 |
| 702 | | stw TMP0, TONUM_HI | 746 | | .FPU stw TMP0, TONUM_HI |
| 703 | | li_vmstate INTERP | 747 | | li_vmstate INTERP |
| 704 | | li ZERO, 0 | 748 | | li ZERO, 0 |
| 705 | | st_vmstate | 749 | | st_vmstate |
| 706 | | andix. TMP0, PC, FRAME_TYPE | 750 | | andix. TMP0, PC, FRAME_TYPE |
| 707 | | mr MULTRES, RD | 751 | | mr MULTRES, RD |
| 708 | | lfs TONUM, TMPD | 752 | | .FPU lfs TONUM, TMPD |
| 709 | | li TISNIL, LJ_TNIL | 753 | | li TISNIL, LJ_TNIL |
| 710 | | beq ->BC_RET_Z | 754 | | beq ->BC_RET_Z |
| 711 | | b ->vm_return | 755 | | b ->vm_return |
| @@ -739,19 +783,19 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 739 | | lp TMP2, L->base // TMP2 = old base (used in vmeta_call). | 783 | | lp TMP2, L->base // TMP2 = old base (used in vmeta_call). |
| 740 | | li TISNUM, LJ_TISNUM // Setup type comparison constants. | 784 | | li TISNUM, LJ_TISNUM // Setup type comparison constants. |
| 741 | | lp TMP1, L->top | 785 | | lp TMP1, L->top |
| 742 | | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | 786 | | .FPU lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). |
| 743 | | add PC, PC, BASE | 787 | | add PC, PC, BASE |
| 744 | | stw TMP3, TMPD | 788 | | .FPU stw TMP3, TMPD |
| 745 | | li ZERO, 0 | 789 | | li ZERO, 0 |
| 746 | | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). | 790 | | .FPU ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). |
| 747 | | lfs TOBIT, TMPD | 791 | | .FPU lfs TOBIT, TMPD |
| 748 | | sub PC, PC, TMP2 // PC = frame delta + frame type | 792 | | sub PC, PC, TMP2 // PC = frame delta + frame type |
| 749 | | stw TMP3, TMPD | 793 | | .FPU stw TMP3, TMPD |
| 750 | | lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double) | 794 | | .FPU lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double) |
| 751 | | sub NARGS8:RC, TMP1, BASE | 795 | | sub NARGS8:RC, TMP1, BASE |
| 752 | | stw TMP0, TONUM_HI | 796 | | .FPU stw TMP0, TONUM_HI |
| 753 | | li_vmstate INTERP | 797 | | li_vmstate INTERP |
| 754 | | lfs TONUM, TMPD | 798 | | .FPU lfs TONUM, TMPD |
| 755 | | li TISNIL, LJ_TNIL | 799 | | li TISNIL, LJ_TNIL |
| 756 | | st_vmstate | 800 | | st_vmstate |
| 757 | | | 801 | | |
| @@ -839,15 +883,30 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 839 | | lwz INS, -4(PC) | 883 | | lwz INS, -4(PC) |
| 840 | | subi CARG2, RB, 16 | 884 | | subi CARG2, RB, 16 |
| 841 | | decode_RB8 SAVE0, INS | 885 | | decode_RB8 SAVE0, INS |
| 886 | |.if FPU | ||
| 842 | | lfd f0, 0(RA) | 887 | | lfd f0, 0(RA) |
| 888 | |.else | ||
| 889 | | lwz TMP2, 0(RA) | ||
| 890 | | lwz TMP3, 4(RA) | ||
| 891 | |.endif | ||
| 843 | | add TMP1, BASE, SAVE0 | 892 | | add TMP1, BASE, SAVE0 |
| 844 | | stp BASE, L->base | 893 | | stp BASE, L->base |
| 845 | | cmplw TMP1, CARG2 | 894 | | cmplw TMP1, CARG2 |
| 846 | | sub CARG3, CARG2, TMP1 | 895 | | sub CARG3, CARG2, TMP1 |
| 847 | | decode_RA8 RA, INS | 896 | | decode_RA8 RA, INS |
| 897 | |.if FPU | ||
| 848 | | stfd f0, 0(CARG2) | 898 | | stfd f0, 0(CARG2) |
| 899 | |.else | ||
| 900 | | stw TMP2, 0(CARG2) | ||
| 901 | | stw TMP3, 4(CARG2) | ||
| 902 | |.endif | ||
| 849 | | bney ->BC_CAT_Z | 903 | | bney ->BC_CAT_Z |
| 904 | |.if FPU | ||
| 850 | | stfdx f0, BASE, RA | 905 | | stfdx f0, BASE, RA |
| 906 | |.else | ||
| 907 | | stwux TMP2, RA, BASE | ||
| 908 | | stw TMP3, 4(RA) | ||
| 909 | |.endif | ||
| 851 | | b ->cont_nop | 910 | | b ->cont_nop |
| 852 | | | 911 | | |
| 853 | |//-- Table indexing metamethods ----------------------------------------- | 912 | |//-- Table indexing metamethods ----------------------------------------- |
| @@ -900,9 +959,19 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 900 | | // Returns TValue * (finished) or NULL (metamethod). | 959 | | // Returns TValue * (finished) or NULL (metamethod). |
| 901 | | cmplwi CRET1, 0 | 960 | | cmplwi CRET1, 0 |
| 902 | | beq >3 | 961 | | beq >3 |
| 962 | |.if FPU | ||
| 903 | | lfd f0, 0(CRET1) | 963 | | lfd f0, 0(CRET1) |
| 964 | |.else | ||
| 965 | | lwz TMP0, 0(CRET1) | ||
| 966 | | lwz TMP1, 4(CRET1) | ||
| 967 | |.endif | ||
| 904 | | ins_next1 | 968 | | ins_next1 |
| 969 | |.if FPU | ||
| 905 | | stfdx f0, BASE, RA | 970 | | stfdx f0, BASE, RA |
| 971 | |.else | ||
| 972 | | stwux TMP0, RA, BASE | ||
| 973 | | stw TMP1, 4(RA) | ||
| 974 | |.endif | ||
| 906 | | ins_next2 | 975 | | ins_next2 |
| 907 | | | 976 | | |
| 908 | |3: // Call __index metamethod. | 977 | |3: // Call __index metamethod. |
| @@ -920,7 +989,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 920 | | // Returns cTValue * or NULL. | 989 | | // Returns cTValue * or NULL. |
| 921 | | cmplwi CRET1, 0 | 990 | | cmplwi CRET1, 0 |
| 922 | | beq >1 | 991 | | beq >1 |
| 992 | |.if FPU | ||
| 923 | | lfd f14, 0(CRET1) | 993 | | lfd f14, 0(CRET1) |
| 994 | |.else | ||
| 995 | | lwz SAVE0, 0(CRET1) | ||
| 996 | | lwz SAVE1, 4(CRET1) | ||
| 997 | |.endif | ||
| 924 | | b ->BC_TGETR_Z | 998 | | b ->BC_TGETR_Z |
| 925 | |1: | 999 | |1: |
| 926 | | stwx TISNIL, BASE, RA | 1000 | | stwx TISNIL, BASE, RA |
| @@ -975,11 +1049,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 975 | | bl extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k) | 1049 | | bl extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k) |
| 976 | | // Returns TValue * (finished) or NULL (metamethod). | 1050 | | // Returns TValue * (finished) or NULL (metamethod). |
| 977 | | cmplwi CRET1, 0 | 1051 | | cmplwi CRET1, 0 |
| 1052 | |.if FPU | ||
| 978 | | lfdx f0, BASE, RA | 1053 | | lfdx f0, BASE, RA |
| 1054 | |.else | ||
| 1055 | | lwzux TMP2, RA, BASE | ||
| 1056 | | lwz TMP3, 4(RA) | ||
| 1057 | |.endif | ||
| 979 | | beq >3 | 1058 | | beq >3 |
| 980 | | // NOBARRIER: lj_meta_tset ensures the table is not black. | 1059 | | // NOBARRIER: lj_meta_tset ensures the table is not black. |
| 981 | | ins_next1 | 1060 | | ins_next1 |
| 1061 | |.if FPU | ||
| 982 | | stfd f0, 0(CRET1) | 1062 | | stfd f0, 0(CRET1) |
| 1063 | |.else | ||
| 1064 | | stw TMP2, 0(CRET1) | ||
| 1065 | | stw TMP3, 4(CRET1) | ||
| 1066 | |.endif | ||
| 983 | | ins_next2 | 1067 | | ins_next2 |
| 984 | | | 1068 | | |
| 985 | |3: // Call __newindex metamethod. | 1069 | |3: // Call __newindex metamethod. |
| @@ -990,7 +1074,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 990 | | add PC, TMP1, BASE | 1074 | | add PC, TMP1, BASE |
| 991 | | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here. | 1075 | | lwz LFUNC:RB, FRAME_FUNC(BASE) // Guaranteed to be a function here. |
| 992 | | li NARGS8:RC, 24 // 3 args for func(t, k, v) | 1076 | | li NARGS8:RC, 24 // 3 args for func(t, k, v) |
| 1077 | |.if FPU | ||
| 993 | | stfd f0, 16(BASE) // Copy value to third argument. | 1078 | | stfd f0, 16(BASE) // Copy value to third argument. |
| 1079 | |.else | ||
| 1080 | | stw TMP2, 16(BASE) | ||
| 1081 | | stw TMP3, 20(BASE) | ||
| 1082 | |.endif | ||
| 994 | | b ->vm_call_dispatch_f | 1083 | | b ->vm_call_dispatch_f |
| 995 | | | 1084 | | |
| 996 | |->vmeta_tsetr: | 1085 | |->vmeta_tsetr: |
| @@ -998,7 +1087,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 998 | | stw PC, SAVE_PC | 1087 | | stw PC, SAVE_PC |
| 999 | | bl extern lj_tab_setinth // (lua_State *L, GCtab *t, int32_t key) | 1088 | | bl extern lj_tab_setinth // (lua_State *L, GCtab *t, int32_t key) |
| 1000 | | // Returns TValue *. | 1089 | | // Returns TValue *. |
| 1090 | |.if FPU | ||
| 1001 | | stfd f14, 0(CRET1) | 1091 | | stfd f14, 0(CRET1) |
| 1092 | |.else | ||
| 1093 | | stw SAVE0, 0(CRET1) | ||
| 1094 | | stw SAVE1, 4(CRET1) | ||
| 1095 | |.endif | ||
| 1002 | | b ->cont_nop | 1096 | | b ->cont_nop |
| 1003 | | | 1097 | | |
| 1004 | |//-- Comparison metamethods --------------------------------------------- | 1098 | |//-- Comparison metamethods --------------------------------------------- |
| @@ -1037,9 +1131,19 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1037 | | | 1131 | | |
| 1038 | |->cont_ra: // RA = resultptr | 1132 | |->cont_ra: // RA = resultptr |
| 1039 | | lwz INS, -4(PC) | 1133 | | lwz INS, -4(PC) |
| 1134 | |.if FPU | ||
| 1040 | | lfd f0, 0(RA) | 1135 | | lfd f0, 0(RA) |
| 1136 | |.else | ||
| 1137 | | lwz CARG1, 0(RA) | ||
| 1138 | | lwz CARG2, 4(RA) | ||
| 1139 | |.endif | ||
| 1041 | | decode_RA8 TMP1, INS | 1140 | | decode_RA8 TMP1, INS |
| 1141 | |.if FPU | ||
| 1042 | | stfdx f0, BASE, TMP1 | 1142 | | stfdx f0, BASE, TMP1 |
| 1143 | |.else | ||
| 1144 | | stwux CARG1, TMP1, BASE | ||
| 1145 | | stw CARG2, 4(TMP1) | ||
| 1146 | |.endif | ||
| 1043 | | b ->cont_nop | 1147 | | b ->cont_nop |
| 1044 | | | 1148 | | |
| 1045 | |->cont_condt: // RA = resultptr | 1149 | |->cont_condt: // RA = resultptr |
| @@ -1245,22 +1349,32 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1245 | |.macro .ffunc_n, name | 1349 | |.macro .ffunc_n, name |
| 1246 | |->ff_ .. name: | 1350 | |->ff_ .. name: |
| 1247 | | cmplwi NARGS8:RC, 8 | 1351 | | cmplwi NARGS8:RC, 8 |
| 1248 | | lwz CARG3, 0(BASE) | 1352 | | lwz CARG1, 0(BASE) |
| 1353 | |.if FPU | ||
| 1249 | | lfd FARG1, 0(BASE) | 1354 | | lfd FARG1, 0(BASE) |
| 1355 | |.else | ||
| 1356 | | lwz CARG2, 4(BASE) | ||
| 1357 | |.endif | ||
| 1250 | | blt ->fff_fallback | 1358 | | blt ->fff_fallback |
| 1251 | | checknum CARG3; bge ->fff_fallback | 1359 | | checknum CARG1; bge ->fff_fallback |
| 1252 | |.endmacro | 1360 | |.endmacro |
| 1253 | | | 1361 | | |
| 1254 | |.macro .ffunc_nn, name | 1362 | |.macro .ffunc_nn, name |
| 1255 | |->ff_ .. name: | 1363 | |->ff_ .. name: |
| 1256 | | cmplwi NARGS8:RC, 16 | 1364 | | cmplwi NARGS8:RC, 16 |
| 1257 | | lwz CARG3, 0(BASE) | 1365 | | lwz CARG1, 0(BASE) |
| 1366 | |.if FPU | ||
| 1258 | | lfd FARG1, 0(BASE) | 1367 | | lfd FARG1, 0(BASE) |
| 1259 | | lwz CARG4, 8(BASE) | 1368 | | lwz CARG3, 8(BASE) |
| 1260 | | lfd FARG2, 8(BASE) | 1369 | | lfd FARG2, 8(BASE) |
| 1370 | |.else | ||
| 1371 | | lwz CARG2, 4(BASE) | ||
| 1372 | | lwz CARG3, 8(BASE) | ||
| 1373 | | lwz CARG4, 12(BASE) | ||
| 1374 | |.endif | ||
| 1261 | | blt ->fff_fallback | 1375 | | blt ->fff_fallback |
| 1376 | | checknum CARG1; bge ->fff_fallback | ||
| 1262 | | checknum CARG3; bge ->fff_fallback | 1377 | | checknum CARG3; bge ->fff_fallback |
| 1263 | | checknum CARG4; bge ->fff_fallback | ||
| 1264 | |.endmacro | 1378 | |.endmacro |
| 1265 | | | 1379 | | |
| 1266 | |// Inlined GC threshold check. Caveat: uses TMP0 and TMP1. | 1380 | |// Inlined GC threshold check. Caveat: uses TMP0 and TMP1. |
| @@ -1281,14 +1395,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1281 | | bge cr1, ->fff_fallback | 1395 | | bge cr1, ->fff_fallback |
| 1282 | | stw CARG3, 0(RA) | 1396 | | stw CARG3, 0(RA) |
| 1283 | | addi RD, NARGS8:RC, 8 // Compute (nresults+1)*8. | 1397 | | addi RD, NARGS8:RC, 8 // Compute (nresults+1)*8. |
| 1398 | | addi TMP1, BASE, 8 | ||
| 1399 | | add TMP2, RA, NARGS8:RC | ||
| 1284 | | stw CARG1, 4(RA) | 1400 | | stw CARG1, 4(RA) |
| 1285 | | beq ->fff_res // Done if exactly 1 argument. | 1401 | | beq ->fff_res // Done if exactly 1 argument. |
| 1286 | | li TMP1, 8 | ||
| 1287 | | subi RC, RC, 8 | ||
| 1288 | |1: | 1402 | |1: |
| 1289 | | cmplw TMP1, RC | 1403 | | cmplw TMP1, TMP2 |
| 1290 | | lfdx f0, BASE, TMP1 | 1404 | |.if FPU |
| 1291 | | stfdx f0, RA, TMP1 | 1405 | | lfd f0, 0(TMP1) |
| 1406 | | stfd f0, 0(TMP1) | ||
| 1407 | |.else | ||
| 1408 | | lwz CARG1, 0(TMP1) | ||
| 1409 | | lwz CARG2, 4(TMP1) | ||
| 1410 | | stw CARG1, -8(TMP1) | ||
| 1411 | | stw CARG2, -4(TMP1) | ||
| 1412 | |.endif | ||
| 1292 | | addi TMP1, TMP1, 8 | 1413 | | addi TMP1, TMP1, 8 |
| 1293 | | bney <1 | 1414 | | bney <1 |
| 1294 | | b ->fff_res | 1415 | | b ->fff_res |
| @@ -1303,8 +1424,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1303 | | orc TMP1, TMP2, TMP0 | 1424 | | orc TMP1, TMP2, TMP0 |
| 1304 | | addi TMP1, TMP1, ~LJ_TISNUM+1 | 1425 | | addi TMP1, TMP1, ~LJ_TISNUM+1 |
| 1305 | | slwi TMP1, TMP1, 3 | 1426 | | slwi TMP1, TMP1, 3 |
| 1427 | |.if FPU | ||
| 1306 | | la TMP2, CFUNC:RB->upvalue | 1428 | | la TMP2, CFUNC:RB->upvalue |
| 1307 | | lfdx FARG1, TMP2, TMP1 | 1429 | | lfdx FARG1, TMP2, TMP1 |
| 1430 | |.else | ||
| 1431 | | add TMP1, CFUNC:RB, TMP1 | ||
| 1432 | | lwz CARG1, CFUNC:TMP1->upvalue[0].u32.hi | ||
| 1433 | | lwz CARG2, CFUNC:TMP1->upvalue[0].u32.lo | ||
| 1434 | |.endif | ||
| 1308 | | b ->fff_resn | 1435 | | b ->fff_resn |
| 1309 | | | 1436 | | |
| 1310 | |//-- Base library: getters and setters --------------------------------- | 1437 | |//-- Base library: getters and setters --------------------------------- |
| @@ -1382,7 +1509,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1382 | | mr CARG1, L | 1509 | | mr CARG1, L |
| 1383 | | bl extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key) | 1510 | | bl extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key) |
| 1384 | | // Returns cTValue *. | 1511 | | // Returns cTValue *. |
| 1512 | |.if FPU | ||
| 1385 | | lfd FARG1, 0(CRET1) | 1513 | | lfd FARG1, 0(CRET1) |
| 1514 | |.else | ||
| 1515 | | lwz CARG2, 4(CRET1) | ||
| 1516 | | lwz CARG1, 0(CRET1) // Caveat: CARG1 == CRET1. | ||
| 1517 | |.endif | ||
| 1386 | | b ->fff_resn | 1518 | | b ->fff_resn |
| 1387 | | | 1519 | | |
| 1388 | |//-- Base library: conversions ------------------------------------------ | 1520 | |//-- Base library: conversions ------------------------------------------ |
| @@ -1391,7 +1523,11 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1391 | | // Only handles the number case inline (without a base argument). | 1523 | | // Only handles the number case inline (without a base argument). |
| 1392 | | cmplwi NARGS8:RC, 8 | 1524 | | cmplwi NARGS8:RC, 8 |
| 1393 | | lwz CARG1, 0(BASE) | 1525 | | lwz CARG1, 0(BASE) |
| 1526 | |.if FPU | ||
| 1394 | | lfd FARG1, 0(BASE) | 1527 | | lfd FARG1, 0(BASE) |
| 1528 | |.else | ||
| 1529 | | lwz CARG2, 4(BASE) | ||
| 1530 | |.endif | ||
| 1395 | | bne ->fff_fallback // Exactly one argument. | 1531 | | bne ->fff_fallback // Exactly one argument. |
| 1396 | | checknum CARG1; bgt ->fff_fallback | 1532 | | checknum CARG1; bgt ->fff_fallback |
| 1397 | | b ->fff_resn | 1533 | | b ->fff_resn |
| @@ -1442,12 +1578,23 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1442 | | cmplwi CRET1, 0 | 1578 | | cmplwi CRET1, 0 |
| 1443 | | li CARG3, LJ_TNIL | 1579 | | li CARG3, LJ_TNIL |
| 1444 | | beq ->fff_restv // End of traversal: return nil. | 1580 | | beq ->fff_restv // End of traversal: return nil. |
| 1445 | | lfd f0, 8(BASE) // Copy key and value to results. | ||
| 1446 | | la RA, -8(BASE) | 1581 | | la RA, -8(BASE) |
| 1582 | |.if FPU | ||
| 1583 | | lfd f0, 8(BASE) // Copy key and value to results. | ||
| 1447 | | lfd f1, 16(BASE) | 1584 | | lfd f1, 16(BASE) |
| 1448 | | stfd f0, 0(RA) | 1585 | | stfd f0, 0(RA) |
| 1449 | | li RD, (2+1)*8 | ||
| 1450 | | stfd f1, 8(RA) | 1586 | | stfd f1, 8(RA) |
| 1587 | |.else | ||
| 1588 | | lwz CARG1, 8(BASE) | ||
| 1589 | | lwz CARG2, 12(BASE) | ||
| 1590 | | lwz CARG3, 16(BASE) | ||
| 1591 | | lwz CARG4, 20(BASE) | ||
| 1592 | | stw CARG1, 0(RA) | ||
| 1593 | | stw CARG2, 4(RA) | ||
| 1594 | | stw CARG3, 8(RA) | ||
| 1595 | | stw CARG4, 12(RA) | ||
| 1596 | |.endif | ||
| 1597 | | li RD, (2+1)*8 | ||
| 1451 | | b ->fff_res | 1598 | | b ->fff_res |
| 1452 | | | 1599 | | |
| 1453 | |.ffunc_1 pairs | 1600 | |.ffunc_1 pairs |
| @@ -1456,17 +1603,32 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1456 | | bne ->fff_fallback | 1603 | | bne ->fff_fallback |
| 1457 | #if LJ_52 | 1604 | #if LJ_52 |
| 1458 | | lwz TAB:TMP2, TAB:CARG1->metatable | 1605 | | lwz TAB:TMP2, TAB:CARG1->metatable |
| 1606 | |.if FPU | ||
| 1459 | | lfd f0, CFUNC:RB->upvalue[0] | 1607 | | lfd f0, CFUNC:RB->upvalue[0] |
| 1608 | |.else | ||
| 1609 | | lwz TMP0, CFUNC:RB->upvalue[0].u32.hi | ||
| 1610 | | lwz TMP1, CFUNC:RB->upvalue[0].u32.lo | ||
| 1611 | |.endif | ||
| 1460 | | cmplwi TAB:TMP2, 0 | 1612 | | cmplwi TAB:TMP2, 0 |
| 1461 | | la RA, -8(BASE) | 1613 | | la RA, -8(BASE) |
| 1462 | | bne ->fff_fallback | 1614 | | bne ->fff_fallback |
| 1463 | #else | 1615 | #else |
| 1616 | |.if FPU | ||
| 1464 | | lfd f0, CFUNC:RB->upvalue[0] | 1617 | | lfd f0, CFUNC:RB->upvalue[0] |
| 1618 | |.else | ||
| 1619 | | lwz TMP0, CFUNC:RB->upvalue[0].u32.hi | ||
| 1620 | | lwz TMP1, CFUNC:RB->upvalue[0].u32.lo | ||
| 1621 | |.endif | ||
| 1465 | | la RA, -8(BASE) | 1622 | | la RA, -8(BASE) |
| 1466 | #endif | 1623 | #endif |
| 1467 | | stw TISNIL, 8(BASE) | 1624 | | stw TISNIL, 8(BASE) |
| 1468 | | li RD, (3+1)*8 | 1625 | | li RD, (3+1)*8 |
| 1626 | |.if FPU | ||
| 1469 | | stfd f0, 0(RA) | 1627 | | stfd f0, 0(RA) |
| 1628 | |.else | ||
| 1629 | | stw TMP0, 0(RA) | ||
| 1630 | | stw TMP1, 4(RA) | ||
| 1631 | |.endif | ||
| 1470 | | b ->fff_res | 1632 | | b ->fff_res |
| 1471 | | | 1633 | | |
| 1472 | |.ffunc ipairs_aux | 1634 | |.ffunc ipairs_aux |
| @@ -1512,14 +1674,24 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1512 | | stfd FARG2, 0(RA) | 1674 | | stfd FARG2, 0(RA) |
| 1513 | |.endif | 1675 | |.endif |
| 1514 | | ble >2 // Not in array part? | 1676 | | ble >2 // Not in array part? |
| 1677 | |.if FPU | ||
| 1515 | | lwzx TMP2, TMP1, TMP3 | 1678 | | lwzx TMP2, TMP1, TMP3 |
| 1516 | | lfdx f0, TMP1, TMP3 | 1679 | | lfdx f0, TMP1, TMP3 |
| 1680 | |.else | ||
| 1681 | | lwzux TMP2, TMP1, TMP3 | ||
| 1682 | | lwz TMP3, 4(TMP1) | ||
| 1683 | |.endif | ||
| 1517 | |1: | 1684 | |1: |
| 1518 | | checknil TMP2 | 1685 | | checknil TMP2 |
| 1519 | | li RD, (0+1)*8 | 1686 | | li RD, (0+1)*8 |
| 1520 | | beq ->fff_res // End of iteration, return 0 results. | 1687 | | beq ->fff_res // End of iteration, return 0 results. |
| 1521 | | li RD, (2+1)*8 | 1688 | | li RD, (2+1)*8 |
| 1689 | |.if FPU | ||
| 1522 | | stfd f0, 8(RA) | 1690 | | stfd f0, 8(RA) |
| 1691 | |.else | ||
| 1692 | | stw TMP2, 8(RA) | ||
| 1693 | | stw TMP3, 12(RA) | ||
| 1694 | |.endif | ||
| 1523 | | b ->fff_res | 1695 | | b ->fff_res |
| 1524 | |2: // Check for empty hash part first. Otherwise call C function. | 1696 | |2: // Check for empty hash part first. Otherwise call C function. |
| 1525 | | lwz TMP0, TAB:CARG1->hmask | 1697 | | lwz TMP0, TAB:CARG1->hmask |
| @@ -1533,7 +1705,11 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1533 | | li RD, (0+1)*8 | 1705 | | li RD, (0+1)*8 |
| 1534 | | beq ->fff_res | 1706 | | beq ->fff_res |
| 1535 | | lwz TMP2, 0(CRET1) | 1707 | | lwz TMP2, 0(CRET1) |
| 1708 | |.if FPU | ||
| 1536 | | lfd f0, 0(CRET1) | 1709 | | lfd f0, 0(CRET1) |
| 1710 | |.else | ||
| 1711 | | lwz TMP3, 4(CRET1) | ||
| 1712 | |.endif | ||
| 1537 | | b <1 | 1713 | | b <1 |
| 1538 | | | 1714 | | |
| 1539 | |.ffunc_1 ipairs | 1715 | |.ffunc_1 ipairs |
| @@ -1542,12 +1718,22 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1542 | | bne ->fff_fallback | 1718 | | bne ->fff_fallback |
| 1543 | #if LJ_52 | 1719 | #if LJ_52 |
| 1544 | | lwz TAB:TMP2, TAB:CARG1->metatable | 1720 | | lwz TAB:TMP2, TAB:CARG1->metatable |
| 1721 | |.if FPU | ||
| 1545 | | lfd f0, CFUNC:RB->upvalue[0] | 1722 | | lfd f0, CFUNC:RB->upvalue[0] |
| 1723 | |.else | ||
| 1724 | | lwz TMP0, CFUNC:RB->upvalue[0].u32.hi | ||
| 1725 | | lwz TMP1, CFUNC:RB->upvalue[0].u32.lo | ||
| 1726 | |.endif | ||
| 1546 | | cmplwi TAB:TMP2, 0 | 1727 | | cmplwi TAB:TMP2, 0 |
| 1547 | | la RA, -8(BASE) | 1728 | | la RA, -8(BASE) |
| 1548 | | bne ->fff_fallback | 1729 | | bne ->fff_fallback |
| 1549 | #else | 1730 | #else |
| 1731 | |.if FPU | ||
| 1550 | | lfd f0, CFUNC:RB->upvalue[0] | 1732 | | lfd f0, CFUNC:RB->upvalue[0] |
| 1733 | |.else | ||
| 1734 | | lwz TMP0, CFUNC:RB->upvalue[0].u32.hi | ||
| 1735 | | lwz TMP1, CFUNC:RB->upvalue[0].u32.lo | ||
| 1736 | |.endif | ||
| 1551 | | la RA, -8(BASE) | 1737 | | la RA, -8(BASE) |
| 1552 | #endif | 1738 | #endif |
| 1553 | |.if DUALNUM | 1739 | |.if DUALNUM |
| @@ -1557,7 +1743,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1557 | |.endif | 1743 | |.endif |
| 1558 | | stw ZERO, 12(BASE) | 1744 | | stw ZERO, 12(BASE) |
| 1559 | | li RD, (3+1)*8 | 1745 | | li RD, (3+1)*8 |
| 1746 | |.if FPU | ||
| 1560 | | stfd f0, 0(RA) | 1747 | | stfd f0, 0(RA) |
| 1748 | |.else | ||
| 1749 | | stw TMP0, 0(RA) | ||
| 1750 | | stw TMP1, 4(RA) | ||
| 1751 | |.endif | ||
| 1561 | | b ->fff_res | 1752 | | b ->fff_res |
| 1562 | | | 1753 | | |
| 1563 | |//-- Base library: catch errors ---------------------------------------- | 1754 | |//-- Base library: catch errors ---------------------------------------- |
| @@ -1576,19 +1767,32 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1576 | | | 1767 | | |
| 1577 | |.ffunc xpcall | 1768 | |.ffunc xpcall |
| 1578 | | cmplwi NARGS8:RC, 16 | 1769 | | cmplwi NARGS8:RC, 16 |
| 1579 | | lwz CARG4, 8(BASE) | 1770 | | lwz CARG3, 8(BASE) |
| 1771 | |.if FPU | ||
| 1580 | | lfd FARG2, 8(BASE) | 1772 | | lfd FARG2, 8(BASE) |
| 1581 | | lfd FARG1, 0(BASE) | 1773 | | lfd FARG1, 0(BASE) |
| 1774 | |.else | ||
| 1775 | | lwz CARG1, 0(BASE) | ||
| 1776 | | lwz CARG2, 4(BASE) | ||
| 1777 | | lwz CARG4, 12(BASE) | ||
| 1778 | |.endif | ||
| 1582 | | blt ->fff_fallback | 1779 | | blt ->fff_fallback |
| 1583 | | lbz TMP1, DISPATCH_GL(hookmask)(DISPATCH) | 1780 | | lbz TMP1, DISPATCH_GL(hookmask)(DISPATCH) |
| 1584 | | mr TMP2, BASE | 1781 | | mr TMP2, BASE |
| 1585 | | checkfunc CARG4; bne ->fff_fallback // Traceback must be a function. | 1782 | | checkfunc CARG3; bne ->fff_fallback // Traceback must be a function. |
| 1586 | | la BASE, 16(BASE) | 1783 | | la BASE, 16(BASE) |
| 1587 | | // Remember active hook before pcall. | 1784 | | // Remember active hook before pcall. |
| 1588 | | rlwinm TMP1, TMP1, 32-HOOK_ACTIVE_SHIFT, 31, 31 | 1785 | | rlwinm TMP1, TMP1, 32-HOOK_ACTIVE_SHIFT, 31, 31 |
| 1786 | |.if FPU | ||
| 1589 | | stfd FARG2, 0(TMP2) // Swap function and traceback. | 1787 | | stfd FARG2, 0(TMP2) // Swap function and traceback. |
| 1590 | | subi NARGS8:RC, NARGS8:RC, 16 | ||
| 1591 | | stfd FARG1, 8(TMP2) | 1788 | | stfd FARG1, 8(TMP2) |
| 1789 | |.else | ||
| 1790 | | stw CARG3, 0(TMP2) | ||
| 1791 | | stw CARG4, 4(TMP2) | ||
| 1792 | | stw CARG1, 8(TMP2) | ||
| 1793 | | stw CARG2, 12(TMP2) | ||
| 1794 | |.endif | ||
| 1795 | | subi NARGS8:RC, NARGS8:RC, 16 | ||
| 1592 | | addi PC, TMP1, 16+FRAME_PCALL | 1796 | | addi PC, TMP1, 16+FRAME_PCALL |
| 1593 | | b ->vm_call_dispatch | 1797 | | b ->vm_call_dispatch |
| 1594 | | | 1798 | | |
| @@ -1631,9 +1835,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1631 | | stp BASE, L->top | 1835 | | stp BASE, L->top |
| 1632 | |2: // Move args to coroutine. | 1836 | |2: // Move args to coroutine. |
| 1633 | | cmpw TMP1, NARGS8:RC | 1837 | | cmpw TMP1, NARGS8:RC |
| 1838 | |.if FPU | ||
| 1634 | | lfdx f0, BASE, TMP1 | 1839 | | lfdx f0, BASE, TMP1 |
| 1840 | |.else | ||
| 1841 | | add CARG3, BASE, TMP1 | ||
| 1842 | | lwz TMP2, 0(CARG3) | ||
| 1843 | | lwz TMP3, 4(CARG3) | ||
| 1844 | |.endif | ||
| 1635 | | beq >3 | 1845 | | beq >3 |
| 1846 | |.if FPU | ||
| 1636 | | stfdx f0, CARG2, TMP1 | 1847 | | stfdx f0, CARG2, TMP1 |
| 1848 | |.else | ||
| 1849 | | add CARG3, CARG2, TMP1 | ||
| 1850 | | stw TMP2, 0(CARG3) | ||
| 1851 | | stw TMP3, 4(CARG3) | ||
| 1852 | |.endif | ||
| 1637 | | addi TMP1, TMP1, 8 | 1853 | | addi TMP1, TMP1, 8 |
| 1638 | | b <2 | 1854 | | b <2 |
| 1639 | |3: | 1855 | |3: |
| @@ -1664,8 +1880,17 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1664 | | stp TMP2, L:SAVE0->top // Clear coroutine stack. | 1880 | | stp TMP2, L:SAVE0->top // Clear coroutine stack. |
| 1665 | |5: // Move results from coroutine. | 1881 | |5: // Move results from coroutine. |
| 1666 | | cmplw TMP1, TMP3 | 1882 | | cmplw TMP1, TMP3 |
| 1883 | |.if FPU | ||
| 1667 | | lfdx f0, TMP2, TMP1 | 1884 | | lfdx f0, TMP2, TMP1 |
| 1668 | | stfdx f0, BASE, TMP1 | 1885 | | stfdx f0, BASE, TMP1 |
| 1886 | |.else | ||
| 1887 | | add CARG3, TMP2, TMP1 | ||
| 1888 | | lwz CARG1, 0(CARG3) | ||
| 1889 | | lwz CARG2, 4(CARG3) | ||
| 1890 | | add CARG3, BASE, TMP1 | ||
| 1891 | | stw CARG1, 0(CARG3) | ||
| 1892 | | stw CARG2, 4(CARG3) | ||
| 1893 | |.endif | ||
| 1669 | | addi TMP1, TMP1, 8 | 1894 | | addi TMP1, TMP1, 8 |
| 1670 | | bne <5 | 1895 | | bne <5 |
| 1671 | |6: | 1896 | |6: |
| @@ -1690,12 +1915,22 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1690 | | andix. TMP0, PC, FRAME_TYPE | 1915 | | andix. TMP0, PC, FRAME_TYPE |
| 1691 | | la TMP3, -8(TMP3) | 1916 | | la TMP3, -8(TMP3) |
| 1692 | | li TMP1, LJ_TFALSE | 1917 | | li TMP1, LJ_TFALSE |
| 1918 | |.if FPU | ||
| 1693 | | lfd f0, 0(TMP3) | 1919 | | lfd f0, 0(TMP3) |
| 1920 | |.else | ||
| 1921 | | lwz CARG1, 0(TMP3) | ||
| 1922 | | lwz CARG2, 4(TMP3) | ||
| 1923 | |.endif | ||
| 1694 | | stp TMP3, L:SAVE0->top // Remove error from coroutine stack. | 1924 | | stp TMP3, L:SAVE0->top // Remove error from coroutine stack. |
| 1695 | | li RD, (2+1)*8 | 1925 | | li RD, (2+1)*8 |
| 1696 | | stw TMP1, -8(BASE) // Prepend false to results. | 1926 | | stw TMP1, -8(BASE) // Prepend false to results. |
| 1697 | | la RA, -8(BASE) | 1927 | | la RA, -8(BASE) |
| 1928 | |.if FPU | ||
| 1698 | | stfd f0, 0(BASE) // Copy error message. | 1929 | | stfd f0, 0(BASE) // Copy error message. |
| 1930 | |.else | ||
| 1931 | | stw CARG1, 0(BASE) // Copy error message. | ||
| 1932 | | stw CARG2, 4(BASE) | ||
| 1933 | |.endif | ||
| 1699 | | b <7 | 1934 | | b <7 |
| 1700 | |.else | 1935 | |.else |
| 1701 | | mr CARG1, L | 1936 | | mr CARG1, L |
| @@ -1874,7 +2109,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1874 | | lus CARG1, 0x8000 // -(2^31). | 2109 | | lus CARG1, 0x8000 // -(2^31). |
| 1875 | | beqy ->fff_resi | 2110 | | beqy ->fff_resi |
| 1876 | |5: | 2111 | |5: |
| 2112 | |.if FPU | ||
| 1877 | | lfd FARG1, 0(BASE) | 2113 | | lfd FARG1, 0(BASE) |
| 2114 | |.else | ||
| 2115 | | lwz CARG1, 0(BASE) | ||
| 2116 | | lwz CARG2, 4(BASE) | ||
| 2117 | |.endif | ||
| 1878 | | blex func | 2118 | | blex func |
| 1879 | | b ->fff_resn | 2119 | | b ->fff_resn |
| 1880 | |.endmacro | 2120 | |.endmacro |
| @@ -1898,10 +2138,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1898 | | | 2138 | | |
| 1899 | |.ffunc math_log | 2139 | |.ffunc math_log |
| 1900 | | cmplwi NARGS8:RC, 8 | 2140 | | cmplwi NARGS8:RC, 8 |
| 1901 | | lwz CARG3, 0(BASE) | 2141 | | lwz CARG1, 0(BASE) |
| 1902 | | lfd FARG1, 0(BASE) | ||
| 1903 | | bne ->fff_fallback // Need exactly 1 argument. | 2142 | | bne ->fff_fallback // Need exactly 1 argument. |
| 1904 | | checknum CARG3; bge ->fff_fallback | 2143 | | checknum CARG1; bge ->fff_fallback |
| 2144 | |.if FPU | ||
| 2145 | | lfd FARG1, 0(BASE) | ||
| 2146 | |.else | ||
| 2147 | | lwz CARG2, 4(BASE) | ||
| 2148 | |.endif | ||
| 1905 | | blex log | 2149 | | blex log |
| 1906 | | b ->fff_resn | 2150 | | b ->fff_resn |
| 1907 | | | 2151 | | |
| @@ -1923,17 +2167,24 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1923 | |.if DUALNUM | 2167 | |.if DUALNUM |
| 1924 | |.ffunc math_ldexp | 2168 | |.ffunc math_ldexp |
| 1925 | | cmplwi NARGS8:RC, 16 | 2169 | | cmplwi NARGS8:RC, 16 |
| 1926 | | lwz CARG3, 0(BASE) | 2170 | | lwz TMP0, 0(BASE) |
| 2171 | |.if FPU | ||
| 1927 | | lfd FARG1, 0(BASE) | 2172 | | lfd FARG1, 0(BASE) |
| 1928 | | lwz CARG4, 8(BASE) | 2173 | |.else |
| 2174 | | lwz CARG1, 0(BASE) | ||
| 2175 | | lwz CARG2, 4(BASE) | ||
| 2176 | |.endif | ||
| 2177 | | lwz TMP1, 8(BASE) | ||
| 1929 | |.if GPR64 | 2178 | |.if GPR64 |
| 1930 | | lwz CARG2, 12(BASE) | 2179 | | lwz CARG2, 12(BASE) |
| 1931 | |.else | 2180 | |.elif FPU |
| 1932 | | lwz CARG1, 12(BASE) | 2181 | | lwz CARG1, 12(BASE) |
| 2182 | |.else | ||
| 2183 | | lwz CARG3, 12(BASE) | ||
| 1933 | |.endif | 2184 | |.endif |
| 1934 | | blt ->fff_fallback | 2185 | | blt ->fff_fallback |
| 1935 | | checknum CARG3; bge ->fff_fallback | 2186 | | checknum TMP0; bge ->fff_fallback |
| 1936 | | checknum CARG4; bne ->fff_fallback | 2187 | | checknum TMP1; bne ->fff_fallback |
| 1937 | |.else | 2188 | |.else |
| 1938 | |.ffunc_nn math_ldexp | 2189 | |.ffunc_nn math_ldexp |
| 1939 | |.if GPR64 | 2190 | |.if GPR64 |
| @@ -1948,8 +2199,10 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1948 | |.ffunc_n math_frexp | 2199 | |.ffunc_n math_frexp |
| 1949 | |.if GPR64 | 2200 | |.if GPR64 |
| 1950 | | la CARG2, DISPATCH_GL(tmptv)(DISPATCH) | 2201 | | la CARG2, DISPATCH_GL(tmptv)(DISPATCH) |
| 1951 | |.else | 2202 | |.elif FPU |
| 1952 | | la CARG1, DISPATCH_GL(tmptv)(DISPATCH) | 2203 | | la CARG1, DISPATCH_GL(tmptv)(DISPATCH) |
| 2204 | |.else | ||
| 2205 | | la CARG3, DISPATCH_GL(tmptv)(DISPATCH) | ||
| 1953 | |.endif | 2206 | |.endif |
| 1954 | | lwz PC, FRAME_PC(BASE) | 2207 | | lwz PC, FRAME_PC(BASE) |
| 1955 | | blex frexp | 2208 | | blex frexp |
| @@ -1958,7 +2211,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1958 | |.if not DUALNUM | 2211 | |.if not DUALNUM |
| 1959 | | tonum_i FARG2, TMP1 | 2212 | | tonum_i FARG2, TMP1 |
| 1960 | |.endif | 2213 | |.endif |
| 2214 | |.if FPU | ||
| 1961 | | stfd FARG1, 0(RA) | 2215 | | stfd FARG1, 0(RA) |
| 2216 | |.else | ||
| 2217 | | stw CRET1, 0(RA) | ||
| 2218 | | stw CRET2, 4(RA) | ||
| 2219 | |.endif | ||
| 1962 | | li RD, (2+1)*8 | 2220 | | li RD, (2+1)*8 |
| 1963 | |.if DUALNUM | 2221 | |.if DUALNUM |
| 1964 | | stw TISNUM, 8(RA) | 2222 | | stw TISNUM, 8(RA) |
| @@ -1971,13 +2229,20 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1971 | |.ffunc_n math_modf | 2229 | |.ffunc_n math_modf |
| 1972 | |.if GPR64 | 2230 | |.if GPR64 |
| 1973 | | la CARG2, -8(BASE) | 2231 | | la CARG2, -8(BASE) |
| 1974 | |.else | 2232 | |.elif FPU |
| 1975 | | la CARG1, -8(BASE) | 2233 | | la CARG1, -8(BASE) |
| 2234 | |.else | ||
| 2235 | | la CARG3, -8(BASE) | ||
| 1976 | |.endif | 2236 | |.endif |
| 1977 | | lwz PC, FRAME_PC(BASE) | 2237 | | lwz PC, FRAME_PC(BASE) |
| 1978 | | blex modf | 2238 | | blex modf |
| 1979 | | la RA, -8(BASE) | 2239 | | la RA, -8(BASE) |
| 2240 | |.if FPU | ||
| 1980 | | stfd FARG1, 0(BASE) | 2241 | | stfd FARG1, 0(BASE) |
| 2242 | |.else | ||
| 2243 | | stw CRET1, 0(BASE) | ||
| 2244 | | stw CRET2, 4(BASE) | ||
| 2245 | |.endif | ||
| 1981 | | li RD, (2+1)*8 | 2246 | | li RD, (2+1)*8 |
| 1982 | | b ->fff_res | 2247 | | b ->fff_res |
| 1983 | | | 2248 | | |
| @@ -1985,13 +2250,13 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 1985 | |.if DUALNUM | 2250 | |.if DUALNUM |
| 1986 | | .ffunc_1 name | 2251 | | .ffunc_1 name |
| 1987 | | checknum CARG3 | 2252 | | checknum CARG3 |
| 1988 | | addi TMP1, BASE, 8 | 2253 | | addi SAVE0, BASE, 8 |
| 1989 | | add TMP2, BASE, NARGS8:RC | 2254 | | add SAVE1, BASE, NARGS8:RC |
| 1990 | | bne >4 | 2255 | | bne >4 |
| 1991 | |1: // Handle integers. | 2256 | |1: // Handle integers. |
| 1992 | | lwz CARG4, 0(TMP1) | 2257 | | lwz CARG4, 0(SAVE0) |
| 1993 | | cmplw cr1, TMP1, TMP2 | 2258 | | cmplw cr1, SAVE0, SAVE1 |
| 1994 | | lwz CARG2, 4(TMP1) | 2259 | | lwz CARG2, 4(SAVE0) |
| 1995 | | bge cr1, ->fff_resi | 2260 | | bge cr1, ->fff_resi |
| 1996 | | checknum CARG4 | 2261 | | checknum CARG4 |
| 1997 | | xoris TMP0, CARG1, 0x8000 | 2262 | | xoris TMP0, CARG1, 0x8000 |
| @@ -2008,36 +2273,76 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2008 | |.if GPR64 | 2273 | |.if GPR64 |
| 2009 | | rldicl CARG1, CARG1, 0, 32 | 2274 | | rldicl CARG1, CARG1, 0, 32 |
| 2010 | |.endif | 2275 | |.endif |
| 2011 | | addi TMP1, TMP1, 8 | 2276 | | addi SAVE0, SAVE0, 8 |
| 2012 | | b <1 | 2277 | | b <1 |
| 2013 | |3: | 2278 | |3: |
| 2014 | | bge ->fff_fallback | 2279 | | bge ->fff_fallback |
| 2015 | | // Convert intermediate result to number and continue below. | 2280 | | // Convert intermediate result to number and continue below. |
| 2281 | |.if FPU | ||
| 2016 | | tonum_i FARG1, CARG1 | 2282 | | tonum_i FARG1, CARG1 |
| 2017 | | lfd FARG2, 0(TMP1) | 2283 | | lfd FARG2, 0(SAVE0) |
| 2284 | |.else | ||
| 2285 | | mr CARG2, CARG1 | ||
| 2286 | | bl ->vm_sfi2d_1 | ||
| 2287 | | lwz CARG3, 0(SAVE0) | ||
| 2288 | | lwz CARG4, 4(SAVE0) | ||
| 2289 | |.endif | ||
| 2018 | | b >6 | 2290 | | b >6 |
| 2019 | |4: | 2291 | |4: |
| 2292 | |.if FPU | ||
| 2020 | | lfd FARG1, 0(BASE) | 2293 | | lfd FARG1, 0(BASE) |
| 2294 | |.else | ||
| 2295 | | lwz CARG1, 0(BASE) | ||
| 2296 | | lwz CARG2, 4(BASE) | ||
| 2297 | |.endif | ||
| 2021 | | bge ->fff_fallback | 2298 | | bge ->fff_fallback |
| 2022 | |5: // Handle numbers. | 2299 | |5: // Handle numbers. |
| 2023 | | lwz CARG4, 0(TMP1) | 2300 | | lwz CARG3, 0(SAVE0) |
| 2024 | | cmplw cr1, TMP1, TMP2 | 2301 | | cmplw cr1, SAVE0, SAVE1 |
| 2025 | | lfd FARG2, 0(TMP1) | 2302 | |.if FPU |
| 2303 | | lfd FARG2, 0(SAVE0) | ||
| 2304 | |.else | ||
| 2305 | | lwz CARG4, 4(SAVE0) | ||
| 2306 | |.endif | ||
| 2026 | | bge cr1, ->fff_resn | 2307 | | bge cr1, ->fff_resn |
| 2027 | | checknum CARG4; bge >7 | 2308 | | checknum CARG3; bge >7 |
| 2028 | |6: | 2309 | |6: |
| 2310 | | addi SAVE0, SAVE0, 8 | ||
| 2311 | |.if FPU | ||
| 2029 | | fsub f0, FARG1, FARG2 | 2312 | | fsub f0, FARG1, FARG2 |
| 2030 | | addi TMP1, TMP1, 8 | ||
| 2031 | |.if ismax | 2313 | |.if ismax |
| 2032 | | fsel FARG1, f0, FARG1, FARG2 | 2314 | | fsel FARG1, f0, FARG1, FARG2 |
| 2033 | |.else | 2315 | |.else |
| 2034 | | fsel FARG1, f0, FARG2, FARG1 | 2316 | | fsel FARG1, f0, FARG2, FARG1 |
| 2035 | |.endif | 2317 | |.endif |
| 2318 | |.else | ||
| 2319 | | stw CARG1, SFSAVE_1 | ||
| 2320 | | stw CARG2, SFSAVE_2 | ||
| 2321 | | stw CARG3, SFSAVE_3 | ||
| 2322 | | stw CARG4, SFSAVE_4 | ||
| 2323 | | blex __ledf2 | ||
| 2324 | | cmpwi CRET1, 0 | ||
| 2325 | |.if ismax | ||
| 2326 | | blt >8 | ||
| 2327 | |.else | ||
| 2328 | | bge >8 | ||
| 2329 | |.endif | ||
| 2330 | | lwz CARG1, SFSAVE_1 | ||
| 2331 | | lwz CARG2, SFSAVE_2 | ||
| 2332 | | b <5 | ||
| 2333 | |8: | ||
| 2334 | | lwz CARG1, SFSAVE_3 | ||
| 2335 | | lwz CARG2, SFSAVE_4 | ||
| 2336 | |.endif | ||
| 2036 | | b <5 | 2337 | | b <5 |
| 2037 | |7: // Convert integer to number and continue above. | 2338 | |7: // Convert integer to number and continue above. |
| 2038 | | lwz CARG2, 4(TMP1) | 2339 | | lwz CARG3, 4(SAVE0) |
| 2039 | | bne ->fff_fallback | 2340 | | bne ->fff_fallback |
| 2040 | | tonum_i FARG2, CARG2 | 2341 | |.if FPU |
| 2342 | | tonum_i FARG2, CARG3 | ||
| 2343 | |.else | ||
| 2344 | | bl ->vm_sfi2d_2 | ||
| 2345 | |.endif | ||
| 2041 | | b <6 | 2346 | | b <6 |
| 2042 | |.else | 2347 | |.else |
| 2043 | | .ffunc_n name | 2348 | | .ffunc_n name |
| @@ -2237,28 +2542,37 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2237 | | | 2542 | | |
| 2238 | |.macro .ffunc_bit_op, name, ins | 2543 | |.macro .ffunc_bit_op, name, ins |
| 2239 | | .ffunc_bit name | 2544 | | .ffunc_bit name |
| 2240 | | addi TMP1, BASE, 8 | 2545 | | addi SAVE0, BASE, 8 |
| 2241 | | add TMP2, BASE, NARGS8:RC | 2546 | | add SAVE1, BASE, NARGS8:RC |
| 2242 | |1: | 2547 | |1: |
| 2243 | | lwz CARG4, 0(TMP1) | 2548 | | lwz CARG4, 0(SAVE0) |
| 2244 | | cmplw cr1, TMP1, TMP2 | 2549 | | cmplw cr1, SAVE0, SAVE1 |
| 2245 | |.if DUALNUM | 2550 | |.if DUALNUM |
| 2246 | | lwz CARG2, 4(TMP1) | 2551 | | lwz CARG2, 4(SAVE0) |
| 2247 | |.else | 2552 | |.else |
| 2248 | | lfd FARG1, 0(TMP1) | 2553 | | lfd FARG1, 0(SAVE0) |
| 2249 | |.endif | 2554 | |.endif |
| 2250 | | bgey cr1, ->fff_resi | 2555 | | bgey cr1, ->fff_resi |
| 2251 | | checknum CARG4 | 2556 | | checknum CARG4 |
| 2252 | |.if DUALNUM | 2557 | |.if DUALNUM |
| 2558 | |.if FPU | ||
| 2253 | | bnel ->fff_bitop_fb | 2559 | | bnel ->fff_bitop_fb |
| 2254 | |.else | 2560 | |.else |
| 2561 | | beq >3 | ||
| 2562 | | stw CARG1, SFSAVE_1 | ||
| 2563 | | bl ->fff_bitop_fb | ||
| 2564 | | mr CARG2, CARG1 | ||
| 2565 | | lwz CARG1, SFSAVE_1 | ||
| 2566 | |3: | ||
| 2567 | |.endif | ||
| 2568 | |.else | ||
| 2255 | | fadd FARG1, FARG1, TOBIT | 2569 | | fadd FARG1, FARG1, TOBIT |
| 2256 | | bge ->fff_fallback | 2570 | | bge ->fff_fallback |
| 2257 | | stfd FARG1, TMPD | 2571 | | stfd FARG1, TMPD |
| 2258 | | lwz CARG2, TMPD_LO | 2572 | | lwz CARG2, TMPD_LO |
| 2259 | |.endif | 2573 | |.endif |
| 2260 | | ins CARG1, CARG1, CARG2 | 2574 | | ins CARG1, CARG1, CARG2 |
| 2261 | | addi TMP1, TMP1, 8 | 2575 | | addi SAVE0, SAVE0, 8 |
| 2262 | | b <1 | 2576 | | b <1 |
| 2263 | |.endmacro | 2577 | |.endmacro |
| 2264 | | | 2578 | | |
| @@ -2280,7 +2594,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2280 | |.macro .ffunc_bit_sh, name, ins, shmod | 2594 | |.macro .ffunc_bit_sh, name, ins, shmod |
| 2281 | |.if DUALNUM | 2595 | |.if DUALNUM |
| 2282 | | .ffunc_2 bit_..name | 2596 | | .ffunc_2 bit_..name |
| 2597 | |.if FPU | ||
| 2283 | | checknum CARG3; bnel ->fff_tobit_fb | 2598 | | checknum CARG3; bnel ->fff_tobit_fb |
| 2599 | |.else | ||
| 2600 | | checknum CARG3; beq >1 | ||
| 2601 | | bl ->fff_tobit_fb | ||
| 2602 | | lwz CARG2, 12(BASE) // Conversion polluted CARG2. | ||
| 2603 | |1: | ||
| 2604 | |.endif | ||
| 2284 | | // Note: no inline conversion from number for 2nd argument! | 2605 | | // Note: no inline conversion from number for 2nd argument! |
| 2285 | | checknum CARG4; bne ->fff_fallback | 2606 | | checknum CARG4; bne ->fff_fallback |
| 2286 | |.else | 2607 | |.else |
| @@ -2317,27 +2638,77 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2317 | |->fff_resn: | 2638 | |->fff_resn: |
| 2318 | | lwz PC, FRAME_PC(BASE) | 2639 | | lwz PC, FRAME_PC(BASE) |
| 2319 | | la RA, -8(BASE) | 2640 | | la RA, -8(BASE) |
| 2641 | |.if FPU | ||
| 2320 | | stfd FARG1, -8(BASE) | 2642 | | stfd FARG1, -8(BASE) |
| 2643 | |.else | ||
| 2644 | | stw CARG1, -8(BASE) | ||
| 2645 | | stw CARG2, -4(BASE) | ||
| 2646 | |.endif | ||
| 2321 | | b ->fff_res1 | 2647 | | b ->fff_res1 |
| 2322 | | | 2648 | | |
| 2323 | |// Fallback FP number to bit conversion. | 2649 | |// Fallback FP number to bit conversion. |
| 2324 | |->fff_tobit_fb: | 2650 | |->fff_tobit_fb: |
| 2325 | |.if DUALNUM | 2651 | |.if DUALNUM |
| 2652 | |.if FPU | ||
| 2326 | | lfd FARG1, 0(BASE) | 2653 | | lfd FARG1, 0(BASE) |
| 2327 | | bgt ->fff_fallback | 2654 | | bgt ->fff_fallback |
| 2328 | | fadd FARG1, FARG1, TOBIT | 2655 | | fadd FARG1, FARG1, TOBIT |
| 2329 | | stfd FARG1, TMPD | 2656 | | stfd FARG1, TMPD |
| 2330 | | lwz CARG1, TMPD_LO | 2657 | | lwz CARG1, TMPD_LO |
| 2331 | | blr | 2658 | | blr |
| 2659 | |.else | ||
| 2660 | | bgt ->fff_fallback | ||
| 2661 | | mr CARG2, CARG1 | ||
| 2662 | | mr CARG1, CARG3 | ||
| 2663 | |// Modifies: CARG1, CARG2, TMP0, TMP1, TMP2. | ||
| 2664 | |->vm_tobit: | ||
| 2665 | | slwi TMP2, CARG1, 1 | ||
| 2666 | | addis TMP2, TMP2, 0x0020 | ||
| 2667 | | cmpwi TMP2, 0 | ||
| 2668 | | bge >2 | ||
| 2669 | | li TMP1, 0x3e0 | ||
| 2670 | | srawi TMP2, TMP2, 21 | ||
| 2671 | | not TMP1, TMP1 | ||
| 2672 | | sub. TMP2, TMP1, TMP2 | ||
| 2673 | | cmpwi cr7, CARG1, 0 | ||
| 2674 | | blt >1 | ||
| 2675 | | slwi TMP1, CARG1, 11 | ||
| 2676 | | srwi TMP0, CARG2, 21 | ||
| 2677 | | oris TMP1, TMP1, 0x8000 | ||
| 2678 | | or TMP1, TMP1, TMP0 | ||
| 2679 | | srw CARG1, TMP1, TMP2 | ||
| 2680 | | bclr 4, 28 // Return if cr7[lt] == 0, no hint. | ||
| 2681 | | neg CARG1, CARG1 | ||
| 2682 | | blr | ||
| 2683 | |1: | ||
| 2684 | | addi TMP2, TMP2, 21 | ||
| 2685 | | srw TMP1, CARG2, TMP2 | ||
| 2686 | | slwi CARG2, CARG1, 12 | ||
| 2687 | | subfic TMP2, TMP2, 20 | ||
| 2688 | | slw TMP0, CARG2, TMP2 | ||
| 2689 | | or CARG1, TMP1, TMP0 | ||
| 2690 | | bclr 4, 28 // Return if cr7[lt] == 0, no hint. | ||
| 2691 | | neg CARG1, CARG1 | ||
| 2692 | | blr | ||
| 2693 | |2: | ||
| 2694 | | li CARG1, 0 | ||
| 2695 | | blr | ||
| 2696 | |.endif | ||
| 2332 | |.endif | 2697 | |.endif |
| 2333 | |->fff_bitop_fb: | 2698 | |->fff_bitop_fb: |
| 2334 | |.if DUALNUM | 2699 | |.if DUALNUM |
| 2335 | | lfd FARG1, 0(TMP1) | 2700 | |.if FPU |
| 2701 | | lfd FARG1, 0(SAVE0) | ||
| 2336 | | bgt ->fff_fallback | 2702 | | bgt ->fff_fallback |
| 2337 | | fadd FARG1, FARG1, TOBIT | 2703 | | fadd FARG1, FARG1, TOBIT |
| 2338 | | stfd FARG1, TMPD | 2704 | | stfd FARG1, TMPD |
| 2339 | | lwz CARG2, TMPD_LO | 2705 | | lwz CARG2, TMPD_LO |
| 2340 | | blr | 2706 | | blr |
| 2707 | |.else | ||
| 2708 | | bgt ->fff_fallback | ||
| 2709 | | mr CARG1, CARG4 | ||
| 2710 | | b ->vm_tobit | ||
| 2711 | |.endif | ||
| 2341 | |.endif | 2712 | |.endif |
| 2342 | | | 2713 | | |
| 2343 | |//----------------------------------------------------------------------- | 2714 | |//----------------------------------------------------------------------- |
| @@ -2530,10 +2901,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2530 | | decode_RA8 RC, INS // Call base. | 2901 | | decode_RA8 RC, INS // Call base. |
| 2531 | | beq >2 | 2902 | | beq >2 |
| 2532 | |1: // Move results down. | 2903 | |1: // Move results down. |
| 2904 | |.if FPU | ||
| 2533 | | lfd f0, 0(RA) | 2905 | | lfd f0, 0(RA) |
| 2906 | |.else | ||
| 2907 | | lwz CARG1, 0(RA) | ||
| 2908 | | lwz CARG2, 4(RA) | ||
| 2909 | |.endif | ||
| 2534 | | addic. TMP1, TMP1, -8 | 2910 | | addic. TMP1, TMP1, -8 |
| 2535 | | addi RA, RA, 8 | 2911 | | addi RA, RA, 8 |
| 2912 | |.if FPU | ||
| 2536 | | stfdx f0, BASE, RC | 2913 | | stfdx f0, BASE, RC |
| 2914 | |.else | ||
| 2915 | | add CARG3, BASE, RC | ||
| 2916 | | stw CARG1, 0(CARG3) | ||
| 2917 | | stw CARG2, 4(CARG3) | ||
| 2918 | |.endif | ||
| 2537 | | addi RC, RC, 8 | 2919 | | addi RC, RC, 8 |
| 2538 | | bne <1 | 2920 | | bne <1 |
| 2539 | |2: | 2921 | |2: |
| @@ -2586,10 +2968,12 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2586 | |//----------------------------------------------------------------------- | 2968 | |//----------------------------------------------------------------------- |
| 2587 | | | 2969 | | |
| 2588 | |.macro savex_, a, b, c, d | 2970 | |.macro savex_, a, b, c, d |
| 2971 | |.if FPU | ||
| 2589 | | stfd f..a, 16+a*8(sp) | 2972 | | stfd f..a, 16+a*8(sp) |
| 2590 | | stfd f..b, 16+b*8(sp) | 2973 | | stfd f..b, 16+b*8(sp) |
| 2591 | | stfd f..c, 16+c*8(sp) | 2974 | | stfd f..c, 16+c*8(sp) |
| 2592 | | stfd f..d, 16+d*8(sp) | 2975 | | stfd f..d, 16+d*8(sp) |
| 2976 | |.endif | ||
| 2593 | |.endmacro | 2977 | |.endmacro |
| 2594 | | | 2978 | | |
| 2595 | |->vm_exit_handler: | 2979 | |->vm_exit_handler: |
| @@ -2661,16 +3045,16 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2661 | | lwz KBASE, PC2PROTO(k)(TMP1) | 3045 | | lwz KBASE, PC2PROTO(k)(TMP1) |
| 2662 | | // Setup type comparison constants. | 3046 | | // Setup type comparison constants. |
| 2663 | | li TISNUM, LJ_TISNUM | 3047 | | li TISNUM, LJ_TISNUM |
| 2664 | | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | 3048 | | .FPU lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). |
| 2665 | | stw TMP3, TMPD | 3049 | | .FPU stw TMP3, TMPD |
| 2666 | | li ZERO, 0 | 3050 | | li ZERO, 0 |
| 2667 | | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). | 3051 | | .FPU ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). |
| 2668 | | lfs TOBIT, TMPD | 3052 | | .FPU lfs TOBIT, TMPD |
| 2669 | | stw TMP3, TMPD | 3053 | | .FPU stw TMP3, TMPD |
| 2670 | | lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double) | 3054 | | .FPU lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double) |
| 2671 | | li TISNIL, LJ_TNIL | 3055 | | li TISNIL, LJ_TNIL |
| 2672 | | stw TMP0, TONUM_HI | 3056 | | .FPU stw TMP0, TONUM_HI |
| 2673 | | lfs TONUM, TMPD | 3057 | | .FPU lfs TONUM, TMPD |
| 2674 | | // Modified copy of ins_next which handles function header dispatch, too. | 3058 | | // Modified copy of ins_next which handles function header dispatch, too. |
| 2675 | | lwz INS, 0(PC) | 3059 | | lwz INS, 0(PC) |
| 2676 | | addi PC, PC, 4 | 3060 | | addi PC, PC, 4 |
| @@ -2715,7 +3099,35 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2715 | |//-- Math helper functions ---------------------------------------------- | 3099 | |//-- Math helper functions ---------------------------------------------- |
| 2716 | |//----------------------------------------------------------------------- | 3100 | |//----------------------------------------------------------------------- |
| 2717 | | | 3101 | | |
| 2718 | |// NYI: Use internal implementations of floor, ceil, trunc. | 3102 | |// NYI: Use internal implementations of floor, ceil, trunc, sfcmp. |
| 3103 | | | ||
| 3104 | |.macro sfi2d, AHI, ALO | ||
| 3105 | |.if not FPU | ||
| 3106 | | mr. AHI, ALO | ||
| 3107 | | bclr 12, 2 // Handle zero first. | ||
| 3108 | | srawi TMP0, ALO, 31 | ||
| 3109 | | xor TMP1, ALO, TMP0 | ||
| 3110 | | sub TMP1, TMP1, TMP0 // Absolute value in TMP1. | ||
| 3111 | | cntlzw AHI, TMP1 | ||
| 3112 | | andix. TMP0, TMP0, 0x800 // Mask sign bit. | ||
| 3113 | | slw TMP1, TMP1, AHI // Align mantissa left with leading 1. | ||
| 3114 | | subfic AHI, AHI, 0x3ff+31-1 // Exponent -1 in AHI. | ||
| 3115 | | slwi ALO, TMP1, 21 | ||
| 3116 | | or AHI, AHI, TMP0 // Sign | Exponent. | ||
| 3117 | | srwi TMP1, TMP1, 11 | ||
| 3118 | | slwi AHI, AHI, 20 // Align left. | ||
| 3119 | | add AHI, AHI, TMP1 // Add mantissa, increment exponent. | ||
| 3120 | | blr | ||
| 3121 | |.endif | ||
| 3122 | |.endmacro | ||
| 3123 | | | ||
| 3124 | |// Input: CARG2. Output: CARG1, CARG2. Temporaries: TMP0, TMP1. | ||
| 3125 | |->vm_sfi2d_1: | ||
| 3126 | | sfi2d CARG1, CARG2 | ||
| 3127 | | | ||
| 3128 | |// Input: CARG4. Output: CARG3, CARG4. Temporaries: TMP0, TMP1. | ||
| 3129 | |->vm_sfi2d_2: | ||
| 3130 | | sfi2d CARG3, CARG4 | ||
| 2719 | | | 3131 | | |
| 2720 | |->vm_modi: | 3132 | |->vm_modi: |
| 2721 | | divwo. TMP0, CARG1, CARG2 | 3133 | | divwo. TMP0, CARG1, CARG2 |
| @@ -2783,21 +3195,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2783 | | addi DISPATCH, r12, GG_G2DISP | 3195 | | addi DISPATCH, r12, GG_G2DISP |
| 2784 | | stw r11, CTSTATE->cb.slot | 3196 | | stw r11, CTSTATE->cb.slot |
| 2785 | | stw r3, CTSTATE->cb.gpr[0] | 3197 | | stw r3, CTSTATE->cb.gpr[0] |
| 2786 | | stfd f1, CTSTATE->cb.fpr[0] | 3198 | | .FPU stfd f1, CTSTATE->cb.fpr[0] |
| 2787 | | stw r4, CTSTATE->cb.gpr[1] | 3199 | | stw r4, CTSTATE->cb.gpr[1] |
| 2788 | | stfd f2, CTSTATE->cb.fpr[1] | 3200 | | .FPU stfd f2, CTSTATE->cb.fpr[1] |
| 2789 | | stw r5, CTSTATE->cb.gpr[2] | 3201 | | stw r5, CTSTATE->cb.gpr[2] |
| 2790 | | stfd f3, CTSTATE->cb.fpr[2] | 3202 | | .FPU stfd f3, CTSTATE->cb.fpr[2] |
| 2791 | | stw r6, CTSTATE->cb.gpr[3] | 3203 | | stw r6, CTSTATE->cb.gpr[3] |
| 2792 | | stfd f4, CTSTATE->cb.fpr[3] | 3204 | | .FPU stfd f4, CTSTATE->cb.fpr[3] |
| 2793 | | stw r7, CTSTATE->cb.gpr[4] | 3205 | | stw r7, CTSTATE->cb.gpr[4] |
| 2794 | | stfd f5, CTSTATE->cb.fpr[4] | 3206 | | .FPU stfd f5, CTSTATE->cb.fpr[4] |
| 2795 | | stw r8, CTSTATE->cb.gpr[5] | 3207 | | stw r8, CTSTATE->cb.gpr[5] |
| 2796 | | stfd f6, CTSTATE->cb.fpr[5] | 3208 | | .FPU stfd f6, CTSTATE->cb.fpr[5] |
| 2797 | | stw r9, CTSTATE->cb.gpr[6] | 3209 | | stw r9, CTSTATE->cb.gpr[6] |
| 2798 | | stfd f7, CTSTATE->cb.fpr[6] | 3210 | | .FPU stfd f7, CTSTATE->cb.fpr[6] |
| 2799 | | stw r10, CTSTATE->cb.gpr[7] | 3211 | | stw r10, CTSTATE->cb.gpr[7] |
| 2800 | | stfd f8, CTSTATE->cb.fpr[7] | 3212 | | .FPU stfd f8, CTSTATE->cb.fpr[7] |
| 2801 | | addi TMP0, sp, CFRAME_SPACE+8 | 3213 | | addi TMP0, sp, CFRAME_SPACE+8 |
| 2802 | | stw TMP0, CTSTATE->cb.stack | 3214 | | stw TMP0, CTSTATE->cb.stack |
| 2803 | | mr CARG1, CTSTATE | 3215 | | mr CARG1, CTSTATE |
| @@ -2808,21 +3220,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2808 | | lp BASE, L:CRET1->base | 3220 | | lp BASE, L:CRET1->base |
| 2809 | | li TISNUM, LJ_TISNUM // Setup type comparison constants. | 3221 | | li TISNUM, LJ_TISNUM // Setup type comparison constants. |
| 2810 | | lp RC, L:CRET1->top | 3222 | | lp RC, L:CRET1->top |
| 2811 | | lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | 3223 | | .FPU lus TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). |
| 2812 | | li ZERO, 0 | 3224 | | li ZERO, 0 |
| 2813 | | mr L, CRET1 | 3225 | | mr L, CRET1 |
| 2814 | | stw TMP3, TMPD | 3226 | | .FPU stw TMP3, TMPD |
| 2815 | | lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double) | 3227 | | .FPU lus TMP0, 0x4338 // Hiword of 2^52 + 2^51 (double) |
| 2816 | | lwz LFUNC:RB, FRAME_FUNC(BASE) | 3228 | | lwz LFUNC:RB, FRAME_FUNC(BASE) |
| 2817 | | ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). | 3229 | | .FPU ori TMP3, TMP3, 0x0004 // TONUM = 2^52 + 2^51 + 2^31 (float). |
| 2818 | | stw TMP0, TONUM_HI | 3230 | | .FPU stw TMP0, TONUM_HI |
| 2819 | | li TISNIL, LJ_TNIL | 3231 | | li TISNIL, LJ_TNIL |
| 2820 | | li_vmstate INTERP | 3232 | | li_vmstate INTERP |
| 2821 | | lfs TOBIT, TMPD | 3233 | | .FPU lfs TOBIT, TMPD |
| 2822 | | stw TMP3, TMPD | 3234 | | .FPU stw TMP3, TMPD |
| 2823 | | sub RC, RC, BASE | 3235 | | sub RC, RC, BASE |
| 2824 | | st_vmstate | 3236 | | st_vmstate |
| 2825 | | lfs TONUM, TMPD | 3237 | | .FPU lfs TONUM, TMPD |
| 2826 | | ins_callt | 3238 | | ins_callt |
| 2827 | |.endif | 3239 | |.endif |
| 2828 | | | 3240 | | |
| @@ -2836,7 +3248,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2836 | | mr CARG2, RA | 3248 | | mr CARG2, RA |
| 2837 | | bl extern lj_ccallback_leave // (CTState *cts, TValue *o) | 3249 | | bl extern lj_ccallback_leave // (CTState *cts, TValue *o) |
| 2838 | | lwz CRET1, CTSTATE->cb.gpr[0] | 3250 | | lwz CRET1, CTSTATE->cb.gpr[0] |
| 2839 | | lfd FARG1, CTSTATE->cb.fpr[0] | 3251 | | .FPU lfd FARG1, CTSTATE->cb.fpr[0] |
| 2840 | | lwz CRET2, CTSTATE->cb.gpr[1] | 3252 | | lwz CRET2, CTSTATE->cb.gpr[1] |
| 2841 | | b ->vm_leave_unw | 3253 | | b ->vm_leave_unw |
| 2842 | |.endif | 3254 | |.endif |
| @@ -2870,14 +3282,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2870 | | bge <1 | 3282 | | bge <1 |
| 2871 | |2: | 3283 | |2: |
| 2872 | | bney cr1, >3 | 3284 | | bney cr1, >3 |
| 2873 | | lfd f1, CCSTATE->fpr[0] | 3285 | | .FPU lfd f1, CCSTATE->fpr[0] |
| 2874 | | lfd f2, CCSTATE->fpr[1] | 3286 | | .FPU lfd f2, CCSTATE->fpr[1] |
| 2875 | | lfd f3, CCSTATE->fpr[2] | 3287 | | .FPU lfd f3, CCSTATE->fpr[2] |
| 2876 | | lfd f4, CCSTATE->fpr[3] | 3288 | | .FPU lfd f4, CCSTATE->fpr[3] |
| 2877 | | lfd f5, CCSTATE->fpr[4] | 3289 | | .FPU lfd f5, CCSTATE->fpr[4] |
| 2878 | | lfd f6, CCSTATE->fpr[5] | 3290 | | .FPU lfd f6, CCSTATE->fpr[5] |
| 2879 | | lfd f7, CCSTATE->fpr[6] | 3291 | | .FPU lfd f7, CCSTATE->fpr[6] |
| 2880 | | lfd f8, CCSTATE->fpr[7] | 3292 | | .FPU lfd f8, CCSTATE->fpr[7] |
| 2881 | |3: | 3293 | |3: |
| 2882 | | lp TMP0, CCSTATE->func | 3294 | | lp TMP0, CCSTATE->func |
| 2883 | | lwz CARG2, CCSTATE->gpr[1] | 3295 | | lwz CARG2, CCSTATE->gpr[1] |
| @@ -2894,7 +3306,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
| 2894 | | lwz TMP2, -4(r14) | 3306 | | lwz TMP2, -4(r14) |
| 2895 | | lwz TMP0, 4(r14) | 3307 | | lwz TMP0, 4(r14) |
| 2896 | | stw CARG1, CCSTATE:TMP1->gpr[0] | 3308 | | stw CARG1, CCSTATE:TMP1->gpr[0] |
| 2897 | | stfd FARG1, CCSTATE:TMP1->fpr[0] | 3309 | | .FPU stfd FARG1, CCSTATE:TMP1->fpr[0] |
| 2898 | | stw CARG2, CCSTATE:TMP1->gpr[1] | 3310 | | stw CARG2, CCSTATE:TMP1->gpr[1] |
| 2899 | | mtlr TMP0 | 3311 | | mtlr TMP0 |
| 2900 | | stw CARG3, CCSTATE:TMP1->gpr[2] | 3312 | | stw CARG3, CCSTATE:TMP1->gpr[2] |
| @@ -2923,19 +3335,19 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 2923 | case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: | 3335 | case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT: |
| 2924 | | // RA = src1*8, RD = src2*8, JMP with RD = target | 3336 | | // RA = src1*8, RD = src2*8, JMP with RD = target |
| 2925 | |.if DUALNUM | 3337 | |.if DUALNUM |
| 2926 | | lwzux TMP0, RA, BASE | 3338 | | lwzux CARG1, RA, BASE |
| 2927 | | addi PC, PC, 4 | 3339 | | addi PC, PC, 4 |
| 2928 | | lwz CARG2, 4(RA) | 3340 | | lwz CARG2, 4(RA) |
| 2929 | | lwzux TMP1, RD, BASE | 3341 | | lwzux CARG3, RD, BASE |
| 2930 | | lwz TMP2, -4(PC) | 3342 | | lwz TMP2, -4(PC) |
| 2931 | | checknum cr0, TMP0 | 3343 | | checknum cr0, CARG1 |
| 2932 | | lwz CARG3, 4(RD) | 3344 | | lwz CARG4, 4(RD) |
| 2933 | | decode_RD4 TMP2, TMP2 | 3345 | | decode_RD4 TMP2, TMP2 |
| 2934 | | checknum cr1, TMP1 | 3346 | | checknum cr1, CARG3 |
| 2935 | | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16) | 3347 | | addis SAVE0, TMP2, -(BCBIAS_J*4 >> 16) |
| 2936 | | bne cr0, >7 | 3348 | | bne cr0, >7 |
| 2937 | | bne cr1, >8 | 3349 | | bne cr1, >8 |
| 2938 | | cmpw CARG2, CARG3 | 3350 | | cmpw CARG2, CARG4 |
| 2939 | if (op == BC_ISLT) { | 3351 | if (op == BC_ISLT) { |
| 2940 | | bge >2 | 3352 | | bge >2 |
| 2941 | } else if (op == BC_ISGE) { | 3353 | } else if (op == BC_ISGE) { |
| @@ -2946,28 +3358,41 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 2946 | | ble >2 | 3358 | | ble >2 |
| 2947 | } | 3359 | } |
| 2948 | |1: | 3360 | |1: |
| 2949 | | add PC, PC, TMP2 | 3361 | | add PC, PC, SAVE0 |
| 2950 | |2: | 3362 | |2: |
| 2951 | | ins_next | 3363 | | ins_next |
| 2952 | | | 3364 | | |
| 2953 | |7: // RA is not an integer. | 3365 | |7: // RA is not an integer. |
| 2954 | | bgt cr0, ->vmeta_comp | 3366 | | bgt cr0, ->vmeta_comp |
| 2955 | | // RA is a number. | 3367 | | // RA is a number. |
| 2956 | | lfd f0, 0(RA) | 3368 | | .FPU lfd f0, 0(RA) |
| 2957 | | bgt cr1, ->vmeta_comp | 3369 | | bgt cr1, ->vmeta_comp |
| 2958 | | blt cr1, >4 | 3370 | | blt cr1, >4 |
| 2959 | | // RA is a number, RD is an integer. | 3371 | | // RA is a number, RD is an integer. |
| 2960 | | tonum_i f1, CARG3 | 3372 | |.if FPU |
| 3373 | | tonum_i f1, CARG4 | ||
| 3374 | |.else | ||
| 3375 | | bl ->vm_sfi2d_2 | ||
| 3376 | |.endif | ||
| 2961 | | b >5 | 3377 | | b >5 |
| 2962 | | | 3378 | | |
| 2963 | |8: // RA is an integer, RD is not an integer. | 3379 | |8: // RA is an integer, RD is not an integer. |
| 2964 | | bgt cr1, ->vmeta_comp | 3380 | | bgt cr1, ->vmeta_comp |
| 2965 | | // RA is an integer, RD is a number. | 3381 | | // RA is an integer, RD is a number. |
| 3382 | |.if FPU | ||
| 2966 | | tonum_i f0, CARG2 | 3383 | | tonum_i f0, CARG2 |
| 3384 | |.else | ||
| 3385 | | bl ->vm_sfi2d_1 | ||
| 3386 | |.endif | ||
| 2967 | |4: | 3387 | |4: |
| 2968 | | lfd f1, 0(RD) | 3388 | | .FPU lfd f1, 0(RD) |
| 2969 | |5: | 3389 | |5: |
| 3390 | |.if FPU | ||
| 2970 | | fcmpu cr0, f0, f1 | 3391 | | fcmpu cr0, f0, f1 |
| 3392 | |.else | ||
| 3393 | | blex __ledf2 | ||
| 3394 | | cmpwi CRET1, 0 | ||
| 3395 | |.endif | ||
| 2971 | if (op == BC_ISLT) { | 3396 | if (op == BC_ISLT) { |
| 2972 | | bge <2 | 3397 | | bge <2 |
| 2973 | } else if (op == BC_ISGE) { | 3398 | } else if (op == BC_ISGE) { |
| @@ -3015,42 +3440,42 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3015 | vk = op == BC_ISEQV; | 3440 | vk = op == BC_ISEQV; |
| 3016 | | // RA = src1*8, RD = src2*8, JMP with RD = target | 3441 | | // RA = src1*8, RD = src2*8, JMP with RD = target |
| 3017 | |.if DUALNUM | 3442 | |.if DUALNUM |
| 3018 | | lwzux TMP0, RA, BASE | 3443 | | lwzux CARG1, RA, BASE |
| 3019 | | addi PC, PC, 4 | 3444 | | addi PC, PC, 4 |
| 3020 | | lwz CARG2, 4(RA) | 3445 | | lwz CARG2, 4(RA) |
| 3021 | | lwzux TMP1, RD, BASE | 3446 | | lwzux CARG3, RD, BASE |
| 3022 | | checknum cr0, TMP0 | 3447 | | checknum cr0, CARG1 |
| 3023 | | lwz TMP2, -4(PC) | 3448 | | lwz SAVE0, -4(PC) |
| 3024 | | checknum cr1, TMP1 | 3449 | | checknum cr1, CARG3 |
| 3025 | | decode_RD4 TMP2, TMP2 | 3450 | | decode_RD4 SAVE0, SAVE0 |
| 3026 | | lwz CARG3, 4(RD) | 3451 | | lwz CARG4, 4(RD) |
| 3027 | | cror 4*cr7+gt, 4*cr0+gt, 4*cr1+gt | 3452 | | cror 4*cr7+gt, 4*cr0+gt, 4*cr1+gt |
| 3028 | | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16) | 3453 | | addis SAVE0, SAVE0, -(BCBIAS_J*4 >> 16) |
| 3029 | if (vk) { | 3454 | if (vk) { |
| 3030 | | ble cr7, ->BC_ISEQN_Z | 3455 | | ble cr7, ->BC_ISEQN_Z |
| 3031 | } else { | 3456 | } else { |
| 3032 | | ble cr7, ->BC_ISNEN_Z | 3457 | | ble cr7, ->BC_ISNEN_Z |
| 3033 | } | 3458 | } |
| 3034 | |.else | 3459 | |.else |
| 3035 | | lwzux TMP0, RA, BASE | 3460 | | lwzux CARG1, RA, BASE |
| 3036 | | lwz TMP2, 0(PC) | 3461 | | lwz SAVE0, 0(PC) |
| 3037 | | lfd f0, 0(RA) | 3462 | | lfd f0, 0(RA) |
| 3038 | | addi PC, PC, 4 | 3463 | | addi PC, PC, 4 |
| 3039 | | lwzux TMP1, RD, BASE | 3464 | | lwzux CARG3, RD, BASE |
| 3040 | | checknum cr0, TMP0 | 3465 | | checknum cr0, CARG1 |
| 3041 | | decode_RD4 TMP2, TMP2 | 3466 | | decode_RD4 SAVE0, SAVE0 |
| 3042 | | lfd f1, 0(RD) | 3467 | | lfd f1, 0(RD) |
| 3043 | | checknum cr1, TMP1 | 3468 | | checknum cr1, CARG3 |
| 3044 | | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16) | 3469 | | addis SAVE0, SAVE0, -(BCBIAS_J*4 >> 16) |
| 3045 | | bge cr0, >5 | 3470 | | bge cr0, >5 |
| 3046 | | bge cr1, >5 | 3471 | | bge cr1, >5 |
| 3047 | | fcmpu cr0, f0, f1 | 3472 | | fcmpu cr0, f0, f1 |
| 3048 | if (vk) { | 3473 | if (vk) { |
| 3049 | | bne >1 | 3474 | | bne >1 |
| 3050 | | add PC, PC, TMP2 | 3475 | | add PC, PC, SAVE0 |
| 3051 | } else { | 3476 | } else { |
| 3052 | | beq >1 | 3477 | | beq >1 |
| 3053 | | add PC, PC, TMP2 | 3478 | | add PC, PC, SAVE0 |
| 3054 | } | 3479 | } |
| 3055 | |1: | 3480 | |1: |
| 3056 | | ins_next | 3481 | | ins_next |
| @@ -3058,36 +3483,36 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3058 | |5: // Either or both types are not numbers. | 3483 | |5: // Either or both types are not numbers. |
| 3059 | |.if not DUALNUM | 3484 | |.if not DUALNUM |
| 3060 | | lwz CARG2, 4(RA) | 3485 | | lwz CARG2, 4(RA) |
| 3061 | | lwz CARG3, 4(RD) | 3486 | | lwz CARG4, 4(RD) |
| 3062 | |.endif | 3487 | |.endif |
| 3063 | |.if FFI | 3488 | |.if FFI |
| 3064 | | cmpwi cr7, TMP0, LJ_TCDATA | 3489 | | cmpwi cr7, CARG1, LJ_TCDATA |
| 3065 | | cmpwi cr5, TMP1, LJ_TCDATA | 3490 | | cmpwi cr5, CARG3, LJ_TCDATA |
| 3066 | |.endif | 3491 | |.endif |
| 3067 | | not TMP3, TMP0 | 3492 | | not TMP2, CARG1 |
| 3068 | | cmplw TMP0, TMP1 | 3493 | | cmplw CARG1, CARG3 |
| 3069 | | cmplwi cr1, TMP3, ~LJ_TISPRI // Primitive? | 3494 | | cmplwi cr1, TMP2, ~LJ_TISPRI // Primitive? |
| 3070 | |.if FFI | 3495 | |.if FFI |
| 3071 | | cror 4*cr7+eq, 4*cr7+eq, 4*cr5+eq | 3496 | | cror 4*cr7+eq, 4*cr7+eq, 4*cr5+eq |
| 3072 | |.endif | 3497 | |.endif |
| 3073 | | cmplwi cr6, TMP3, ~LJ_TISTABUD // Table or userdata? | 3498 | | cmplwi cr6, TMP2, ~LJ_TISTABUD // Table or userdata? |
| 3074 | |.if FFI | 3499 | |.if FFI |
| 3075 | | beq cr7, ->vmeta_equal_cd | 3500 | | beq cr7, ->vmeta_equal_cd |
| 3076 | |.endif | 3501 | |.endif |
| 3077 | | cmplw cr5, CARG2, CARG3 | 3502 | | cmplw cr5, CARG2, CARG4 |
| 3078 | | crandc 4*cr0+gt, 4*cr0+eq, 4*cr1+gt // 2: Same type and primitive. | 3503 | | crandc 4*cr0+gt, 4*cr0+eq, 4*cr1+gt // 2: Same type and primitive. |
| 3079 | | crorc 4*cr0+lt, 4*cr5+eq, 4*cr0+eq // 1: Same tv or different type. | 3504 | | crorc 4*cr0+lt, 4*cr5+eq, 4*cr0+eq // 1: Same tv or different type. |
| 3080 | | crand 4*cr0+eq, 4*cr0+eq, 4*cr5+eq // 0: Same type and same tv. | 3505 | | crand 4*cr0+eq, 4*cr0+eq, 4*cr5+eq // 0: Same type and same tv. |
| 3081 | | mr SAVE0, PC | 3506 | | mr SAVE1, PC |
| 3082 | | cror 4*cr0+eq, 4*cr0+eq, 4*cr0+gt // 0 or 2. | 3507 | | cror 4*cr0+eq, 4*cr0+eq, 4*cr0+gt // 0 or 2. |
| 3083 | | cror 4*cr0+lt, 4*cr0+lt, 4*cr0+gt // 1 or 2. | 3508 | | cror 4*cr0+lt, 4*cr0+lt, 4*cr0+gt // 1 or 2. |
| 3084 | if (vk) { | 3509 | if (vk) { |
| 3085 | | bne cr0, >6 | 3510 | | bne cr0, >6 |
| 3086 | | add PC, PC, TMP2 | 3511 | | add PC, PC, SAVE0 |
| 3087 | |6: | 3512 | |6: |
| 3088 | } else { | 3513 | } else { |
| 3089 | | beq cr0, >6 | 3514 | | beq cr0, >6 |
| 3090 | | add PC, PC, TMP2 | 3515 | | add PC, PC, SAVE0 |
| 3091 | |6: | 3516 | |6: |
| 3092 | } | 3517 | } |
| 3093 | |.if DUALNUM | 3518 | |.if DUALNUM |
| @@ -3102,6 +3527,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3102 | | | 3527 | | |
| 3103 | | // Different tables or userdatas. Need to check __eq metamethod. | 3528 | | // Different tables or userdatas. Need to check __eq metamethod. |
| 3104 | | // Field metatable must be at same offset for GCtab and GCudata! | 3529 | | // Field metatable must be at same offset for GCtab and GCudata! |
| 3530 | | mr CARG3, CARG4 | ||
| 3105 | | lwz TAB:TMP2, TAB:CARG2->metatable | 3531 | | lwz TAB:TMP2, TAB:CARG2->metatable |
| 3106 | | li CARG4, 1-vk // ne = 0 or 1. | 3532 | | li CARG4, 1-vk // ne = 0 or 1. |
| 3107 | | cmplwi TAB:TMP2, 0 | 3533 | | cmplwi TAB:TMP2, 0 |
| @@ -3109,7 +3535,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3109 | | lbz TMP2, TAB:TMP2->nomm | 3535 | | lbz TMP2, TAB:TMP2->nomm |
| 3110 | | andix. TMP2, TMP2, 1<<MM_eq | 3536 | | andix. TMP2, TMP2, 1<<MM_eq |
| 3111 | | bne <1 // Or 'no __eq' flag set? | 3537 | | bne <1 // Or 'no __eq' flag set? |
| 3112 | | mr PC, SAVE0 // Restore old PC. | 3538 | | mr PC, SAVE1 // Restore old PC. |
| 3113 | | b ->vmeta_equal // Handle __eq metamethod. | 3539 | | b ->vmeta_equal // Handle __eq metamethod. |
| 3114 | break; | 3540 | break; |
| 3115 | 3541 | ||
| @@ -3150,16 +3576,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3150 | vk = op == BC_ISEQN; | 3576 | vk = op == BC_ISEQN; |
| 3151 | | // RA = src*8, RD = num_const*8, JMP with RD = target | 3577 | | // RA = src*8, RD = num_const*8, JMP with RD = target |
| 3152 | |.if DUALNUM | 3578 | |.if DUALNUM |
| 3153 | | lwzux TMP0, RA, BASE | 3579 | | lwzux CARG1, RA, BASE |
| 3154 | | addi PC, PC, 4 | 3580 | | addi PC, PC, 4 |
| 3155 | | lwz CARG2, 4(RA) | 3581 | | lwz CARG2, 4(RA) |
| 3156 | | lwzux TMP1, RD, KBASE | 3582 | | lwzux CARG3, RD, KBASE |
| 3157 | | checknum cr0, TMP0 | 3583 | | checknum cr0, CARG1 |
| 3158 | | lwz TMP2, -4(PC) | 3584 | | lwz SAVE0, -4(PC) |
| 3159 | | checknum cr1, TMP1 | 3585 | | checknum cr1, CARG3 |
| 3160 | | decode_RD4 TMP2, TMP2 | 3586 | | decode_RD4 SAVE0, SAVE0 |
| 3161 | | lwz CARG3, 4(RD) | 3587 | | lwz CARG4, 4(RD) |
| 3162 | | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16) | 3588 | | addis SAVE0, SAVE0, -(BCBIAS_J*4 >> 16) |
| 3163 | if (vk) { | 3589 | if (vk) { |
| 3164 | |->BC_ISEQN_Z: | 3590 | |->BC_ISEQN_Z: |
| 3165 | } else { | 3591 | } else { |
| @@ -3167,7 +3593,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3167 | } | 3593 | } |
| 3168 | | bne cr0, >7 | 3594 | | bne cr0, >7 |
| 3169 | | bne cr1, >8 | 3595 | | bne cr1, >8 |
| 3170 | | cmpw CARG2, CARG3 | 3596 | | cmpw CARG2, CARG4 |
| 3171 | |4: | 3597 | |4: |
| 3172 | |.else | 3598 | |.else |
| 3173 | if (vk) { | 3599 | if (vk) { |
| @@ -3175,20 +3601,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3175 | } else { | 3601 | } else { |
| 3176 | |->BC_ISNEN_Z: // Dummy label. | 3602 | |->BC_ISNEN_Z: // Dummy label. |
| 3177 | } | 3603 | } |
| 3178 | | lwzx TMP0, BASE, RA | 3604 | | lwzx CARG1, BASE, RA |
| 3179 | | addi PC, PC, 4 | 3605 | | addi PC, PC, 4 |
| 3180 | | lfdx f0, BASE, RA | 3606 | | lfdx f0, BASE, RA |
| 3181 | | lwz TMP2, -4(PC) | 3607 | | lwz SAVE0, -4(PC) |
| 3182 | | lfdx f1, KBASE, RD | 3608 | | lfdx f1, KBASE, RD |
| 3183 | | decode_RD4 TMP2, TMP2 | 3609 | | decode_RD4 SAVE0, SAVE0 |
| 3184 | | checknum TMP0 | 3610 | | checknum CARG1 |
| 3185 | | addis TMP2, TMP2, -(BCBIAS_J*4 >> 16) | 3611 | | addis SAVE0, SAVE0, -(BCBIAS_J*4 >> 16) |
| 3186 | | bge >3 | 3612 | | bge >3 |
| 3187 | | fcmpu cr0, f0, f1 | 3613 | | fcmpu cr0, f0, f1 |
| 3188 | |.endif | 3614 | |.endif |
| 3189 | if (vk) { | 3615 | if (vk) { |
| 3190 | | bne >1 | 3616 | | bne >1 |
| 3191 | | add PC, PC, TMP2 | 3617 | | add PC, PC, SAVE0 |
| 3192 | |1: | 3618 | |1: |
| 3193 | |.if not FFI | 3619 | |.if not FFI |
| 3194 | |3: | 3620 | |3: |
| @@ -3199,13 +3625,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3199 | |.if not FFI | 3625 | |.if not FFI |
| 3200 | |3: | 3626 | |3: |
| 3201 | |.endif | 3627 | |.endif |
| 3202 | | add PC, PC, TMP2 | 3628 | | add PC, PC, SAVE0 |
| 3203 | |2: | 3629 | |2: |
| 3204 | } | 3630 | } |
| 3205 | | ins_next | 3631 | | ins_next |
| 3206 | |.if FFI | 3632 | |.if FFI |
| 3207 | |3: | 3633 | |3: |
| 3208 | | cmpwi TMP0, LJ_TCDATA | 3634 | | cmpwi CARG1, LJ_TCDATA |
| 3209 | | beq ->vmeta_equal_cd | 3635 | | beq ->vmeta_equal_cd |
| 3210 | | b <1 | 3636 | | b <1 |
| 3211 | |.endif | 3637 | |.endif |
| @@ -3213,18 +3639,31 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3213 | |7: // RA is not an integer. | 3639 | |7: // RA is not an integer. |
| 3214 | | bge cr0, <3 | 3640 | | bge cr0, <3 |
| 3215 | | // RA is a number. | 3641 | | // RA is a number. |
| 3216 | | lfd f0, 0(RA) | 3642 | | .FPU lfd f0, 0(RA) |
| 3217 | | blt cr1, >1 | 3643 | | blt cr1, >1 |
| 3218 | | // RA is a number, RD is an integer. | 3644 | | // RA is a number, RD is an integer. |
| 3219 | | tonum_i f1, CARG3 | 3645 | |.if FPU |
| 3646 | | tonum_i f1, CARG4 | ||
| 3647 | |.else | ||
| 3648 | | bl ->vm_sfi2d_2 | ||
| 3649 | |.endif | ||
| 3220 | | b >2 | 3650 | | b >2 |
| 3221 | | | 3651 | | |
| 3222 | |8: // RA is an integer, RD is a number. | 3652 | |8: // RA is an integer, RD is a number. |
| 3653 | |.if FPU | ||
| 3223 | | tonum_i f0, CARG2 | 3654 | | tonum_i f0, CARG2 |
| 3655 | |.else | ||
| 3656 | | bl ->vm_sfi2d_1 | ||
| 3657 | |.endif | ||
| 3224 | |1: | 3658 | |1: |
| 3225 | | lfd f1, 0(RD) | 3659 | | .FPU lfd f1, 0(RD) |
| 3226 | |2: | 3660 | |2: |
| 3661 | |.if FPU | ||
| 3227 | | fcmpu cr0, f0, f1 | 3662 | | fcmpu cr0, f0, f1 |
| 3663 | |.else | ||
| 3664 | | blex __ledf2 | ||
| 3665 | | cmpwi CRET1, 0 | ||
| 3666 | |.endif | ||
| 3228 | | b <4 | 3667 | | b <4 |
| 3229 | |.endif | 3668 | |.endif |
| 3230 | break; | 3669 | break; |
| @@ -3279,7 +3718,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3279 | | add PC, PC, TMP2 | 3718 | | add PC, PC, TMP2 |
| 3280 | } else { | 3719 | } else { |
| 3281 | | li TMP1, LJ_TFALSE | 3720 | | li TMP1, LJ_TFALSE |
| 3721 | |.if FPU | ||
| 3282 | | lfdx f0, BASE, RD | 3722 | | lfdx f0, BASE, RD |
| 3723 | |.else | ||
| 3724 | | lwzux CARG1, RD, BASE | ||
| 3725 | | lwz CARG2, 4(RD) | ||
| 3726 | |.endif | ||
| 3283 | | cmplw TMP0, TMP1 | 3727 | | cmplw TMP0, TMP1 |
| 3284 | if (op == BC_ISTC) { | 3728 | if (op == BC_ISTC) { |
| 3285 | | bge >1 | 3729 | | bge >1 |
| @@ -3288,7 +3732,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3288 | } | 3732 | } |
| 3289 | | addis PC, PC, -(BCBIAS_J*4 >> 16) | 3733 | | addis PC, PC, -(BCBIAS_J*4 >> 16) |
| 3290 | | decode_RD4 TMP2, INS | 3734 | | decode_RD4 TMP2, INS |
| 3735 | |.if FPU | ||
| 3291 | | stfdx f0, BASE, RA | 3736 | | stfdx f0, BASE, RA |
| 3737 | |.else | ||
| 3738 | | stwux CARG1, RA, BASE | ||
| 3739 | | stw CARG2, 4(RA) | ||
| 3740 | |.endif | ||
| 3292 | | add PC, PC, TMP2 | 3741 | | add PC, PC, TMP2 |
| 3293 | |1: | 3742 | |1: |
| 3294 | } | 3743 | } |
| @@ -3323,8 +3772,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3323 | case BC_MOV: | 3772 | case BC_MOV: |
| 3324 | | // RA = dst*8, RD = src*8 | 3773 | | // RA = dst*8, RD = src*8 |
| 3325 | | ins_next1 | 3774 | | ins_next1 |
| 3775 | |.if FPU | ||
| 3326 | | lfdx f0, BASE, RD | 3776 | | lfdx f0, BASE, RD |
| 3327 | | stfdx f0, BASE, RA | 3777 | | stfdx f0, BASE, RA |
| 3778 | |.else | ||
| 3779 | | lwzux TMP0, RD, BASE | ||
| 3780 | | lwz TMP1, 4(RD) | ||
| 3781 | | stwux TMP0, RA, BASE | ||
| 3782 | | stw TMP1, 4(RA) | ||
| 3783 | |.endif | ||
| 3328 | | ins_next2 | 3784 | | ins_next2 |
| 3329 | break; | 3785 | break; |
| 3330 | case BC_NOT: | 3786 | case BC_NOT: |
| @@ -3426,44 +3882,65 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3426 | ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN); | 3882 | ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN); |
| 3427 | ||switch (vk) { | 3883 | ||switch (vk) { |
| 3428 | ||case 0: | 3884 | ||case 0: |
| 3429 | | lwzx TMP1, BASE, RB | 3885 | | lwzx CARG1, BASE, RB |
| 3430 | | .if DUALNUM | 3886 | | .if DUALNUM |
| 3431 | | lwzx TMP2, KBASE, RC | 3887 | | lwzx CARG3, KBASE, RC |
| 3432 | | .endif | 3888 | | .endif |
| 3889 | | .if FPU | ||
| 3433 | | lfdx f14, BASE, RB | 3890 | | lfdx f14, BASE, RB |
| 3434 | | lfdx f15, KBASE, RC | 3891 | | lfdx f15, KBASE, RC |
| 3892 | | .else | ||
| 3893 | | add TMP1, BASE, RB | ||
| 3894 | | add TMP2, KBASE, RC | ||
| 3895 | | lwz CARG2, 4(TMP1) | ||
| 3896 | | lwz CARG4, 4(TMP2) | ||
| 3897 | | .endif | ||
| 3435 | | .if DUALNUM | 3898 | | .if DUALNUM |
| 3436 | | checknum cr0, TMP1 | 3899 | | checknum cr0, CARG1 |
| 3437 | | checknum cr1, TMP2 | 3900 | | checknum cr1, CARG3 |
| 3438 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt | 3901 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt |
| 3439 | | bge ->vmeta_arith_vn | 3902 | | bge ->vmeta_arith_vn |
| 3440 | | .else | 3903 | | .else |
| 3441 | | checknum TMP1; bge ->vmeta_arith_vn | 3904 | | checknum CARG1; bge ->vmeta_arith_vn |
| 3442 | | .endif | 3905 | | .endif |
| 3443 | || break; | 3906 | || break; |
| 3444 | ||case 1: | 3907 | ||case 1: |
| 3445 | | lwzx TMP1, BASE, RB | 3908 | | lwzx CARG1, BASE, RB |
| 3446 | | .if DUALNUM | 3909 | | .if DUALNUM |
| 3447 | | lwzx TMP2, KBASE, RC | 3910 | | lwzx CARG3, KBASE, RC |
| 3448 | | .endif | 3911 | | .endif |
| 3912 | | .if FPU | ||
| 3449 | | lfdx f15, BASE, RB | 3913 | | lfdx f15, BASE, RB |
| 3450 | | lfdx f14, KBASE, RC | 3914 | | lfdx f14, KBASE, RC |
| 3915 | | .else | ||
| 3916 | | add TMP1, BASE, RB | ||
| 3917 | | add TMP2, KBASE, RC | ||
| 3918 | | lwz CARG2, 4(TMP1) | ||
| 3919 | | lwz CARG4, 4(TMP2) | ||
| 3920 | | .endif | ||
| 3451 | | .if DUALNUM | 3921 | | .if DUALNUM |
| 3452 | | checknum cr0, TMP1 | 3922 | | checknum cr0, CARG1 |
| 3453 | | checknum cr1, TMP2 | 3923 | | checknum cr1, CARG3 |
| 3454 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt | 3924 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt |
| 3455 | | bge ->vmeta_arith_nv | 3925 | | bge ->vmeta_arith_nv |
| 3456 | | .else | 3926 | | .else |
| 3457 | | checknum TMP1; bge ->vmeta_arith_nv | 3927 | | checknum CARG1; bge ->vmeta_arith_nv |
| 3458 | | .endif | 3928 | | .endif |
| 3459 | || break; | 3929 | || break; |
| 3460 | ||default: | 3930 | ||default: |
| 3461 | | lwzx TMP1, BASE, RB | 3931 | | lwzx CARG1, BASE, RB |
| 3462 | | lwzx TMP2, BASE, RC | 3932 | | lwzx CARG3, BASE, RC |
| 3933 | | .if FPU | ||
| 3463 | | lfdx f14, BASE, RB | 3934 | | lfdx f14, BASE, RB |
| 3464 | | lfdx f15, BASE, RC | 3935 | | lfdx f15, BASE, RC |
| 3465 | | checknum cr0, TMP1 | 3936 | | .else |
| 3466 | | checknum cr1, TMP2 | 3937 | | add TMP1, BASE, RB |
| 3938 | | add TMP2, BASE, RC | ||
| 3939 | | lwz CARG2, 4(TMP1) | ||
| 3940 | | lwz CARG4, 4(TMP2) | ||
| 3941 | | .endif | ||
| 3942 | | checknum cr0, CARG1 | ||
| 3943 | | checknum cr1, CARG3 | ||
| 3467 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt | 3944 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt |
| 3468 | | bge ->vmeta_arith_vv | 3945 | | bge ->vmeta_arith_vv |
| 3469 | || break; | 3946 | || break; |
| @@ -3497,48 +3974,78 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3497 | | fsub a, b, a // b - floor(b/c)*c | 3974 | | fsub a, b, a // b - floor(b/c)*c |
| 3498 | |.endmacro | 3975 | |.endmacro |
| 3499 | | | 3976 | | |
| 3977 | |.macro sfpmod | ||
| 3978 | |->BC_MODVN_Z: | ||
| 3979 | | stw CARG1, SFSAVE_1 | ||
| 3980 | | stw CARG2, SFSAVE_2 | ||
| 3981 | | mr SAVE0, CARG3 | ||
| 3982 | | mr SAVE1, CARG4 | ||
| 3983 | | blex __divdf3 | ||
| 3984 | | blex floor | ||
| 3985 | | mr CARG3, SAVE0 | ||
| 3986 | | mr CARG4, SAVE1 | ||
| 3987 | | blex __muldf3 | ||
| 3988 | | mr CARG3, CRET1 | ||
| 3989 | | mr CARG4, CRET2 | ||
| 3990 | | lwz CARG1, SFSAVE_1 | ||
| 3991 | | lwz CARG2, SFSAVE_2 | ||
| 3992 | | blex __subdf3 | ||
| 3993 | |.endmacro | ||
| 3994 | | | ||
| 3500 | |.macro ins_arithfp, fpins | 3995 | |.macro ins_arithfp, fpins |
| 3501 | | ins_arithpre | 3996 | | ins_arithpre |
| 3502 | |.if "fpins" == "fpmod_" | 3997 | |.if "fpins" == "fpmod_" |
| 3503 | | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway. | 3998 | | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway. |
| 3504 | |.else | 3999 | |.elif FPU |
| 3505 | | fpins f0, f14, f15 | 4000 | | fpins f0, f14, f15 |
| 3506 | | ins_next1 | 4001 | | ins_next1 |
| 3507 | | stfdx f0, BASE, RA | 4002 | | stfdx f0, BASE, RA |
| 3508 | | ins_next2 | 4003 | | ins_next2 |
| 4004 | |.else | ||
| 4005 | | blex __divdf3 // Only soft-float div uses this macro. | ||
| 4006 | | ins_next1 | ||
| 4007 | | stwux CRET1, RA, BASE | ||
| 4008 | | stw CRET2, 4(RA) | ||
| 4009 | | ins_next2 | ||
| 3509 | |.endif | 4010 | |.endif |
| 3510 | |.endmacro | 4011 | |.endmacro |
| 3511 | | | 4012 | | |
| 3512 | |.macro ins_arithdn, intins, fpins | 4013 | |.macro ins_arithdn, intins, fpins, fpcall |
| 3513 | | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8 | 4014 | | // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8 |
| 3514 | ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN); | 4015 | ||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN); |
| 3515 | ||switch (vk) { | 4016 | ||switch (vk) { |
| 3516 | ||case 0: | 4017 | ||case 0: |
| 3517 | | lwzux TMP1, RB, BASE | 4018 | | lwzux CARG1, RB, BASE |
| 3518 | | lwzux TMP2, RC, KBASE | 4019 | | lwzux CARG3, RC, KBASE |
| 3519 | | lwz CARG1, 4(RB) | 4020 | | lwz CARG2, 4(RB) |
| 3520 | | checknum cr0, TMP1 | 4021 | | checknum cr0, CARG1 |
| 3521 | | lwz CARG2, 4(RC) | 4022 | | lwz CARG4, 4(RC) |
| 4023 | | checknum cr1, CARG3 | ||
| 3522 | || break; | 4024 | || break; |
| 3523 | ||case 1: | 4025 | ||case 1: |
| 3524 | | lwzux TMP1, RB, BASE | 4026 | | lwzux CARG3, RB, BASE |
| 3525 | | lwzux TMP2, RC, KBASE | 4027 | | lwzux CARG1, RC, KBASE |
| 3526 | | lwz CARG2, 4(RB) | 4028 | | lwz CARG4, 4(RB) |
| 3527 | | checknum cr0, TMP1 | 4029 | | checknum cr0, CARG3 |
| 3528 | | lwz CARG1, 4(RC) | 4030 | | lwz CARG2, 4(RC) |
| 4031 | | checknum cr1, CARG1 | ||
| 3529 | || break; | 4032 | || break; |
| 3530 | ||default: | 4033 | ||default: |
| 3531 | | lwzux TMP1, RB, BASE | 4034 | | lwzux CARG1, RB, BASE |
| 3532 | | lwzux TMP2, RC, BASE | 4035 | | lwzux CARG3, RC, BASE |
| 3533 | | lwz CARG1, 4(RB) | 4036 | | lwz CARG2, 4(RB) |
| 3534 | | checknum cr0, TMP1 | 4037 | | checknum cr0, CARG1 |
| 3535 | | lwz CARG2, 4(RC) | 4038 | | lwz CARG4, 4(RC) |
| 4039 | | checknum cr1, CARG3 | ||
| 3536 | || break; | 4040 | || break; |
| 3537 | ||} | 4041 | ||} |
| 3538 | | checknum cr1, TMP2 | ||
| 3539 | | bne >5 | 4042 | | bne >5 |
| 3540 | | bne cr1, >5 | 4043 | | bne cr1, >5 |
| 3541 | | intins CARG1, CARG1, CARG2 | 4044 | |.if "intins" == "intmod" |
| 4045 | | mr CARG1, CARG2 | ||
| 4046 | | mr CARG2, CARG4 | ||
| 4047 | |.endif | ||
| 4048 | | intins CARG1, CARG2, CARG4 | ||
| 3542 | | bso >4 | 4049 | | bso >4 |
| 3543 | |1: | 4050 | |1: |
| 3544 | | ins_next1 | 4051 | | ins_next1 |
| @@ -3550,29 +4057,40 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3550 | | checkov TMP0, <1 // Ignore unrelated overflow. | 4057 | | checkov TMP0, <1 // Ignore unrelated overflow. |
| 3551 | | ins_arithfallback b | 4058 | | ins_arithfallback b |
| 3552 | |5: // FP variant. | 4059 | |5: // FP variant. |
| 4060 | |.if FPU | ||
| 3553 | ||if (vk == 1) { | 4061 | ||if (vk == 1) { |
| 3554 | | lfd f15, 0(RB) | 4062 | | lfd f15, 0(RB) |
| 3555 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt | ||
| 3556 | | lfd f14, 0(RC) | 4063 | | lfd f14, 0(RC) |
| 3557 | ||} else { | 4064 | ||} else { |
| 3558 | | lfd f14, 0(RB) | 4065 | | lfd f14, 0(RB) |
| 3559 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt | ||
| 3560 | | lfd f15, 0(RC) | 4066 | | lfd f15, 0(RC) |
| 3561 | ||} | 4067 | ||} |
| 4068 | |.endif | ||
| 4069 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt | ||
| 3562 | | ins_arithfallback bge | 4070 | | ins_arithfallback bge |
| 3563 | |.if "fpins" == "fpmod_" | 4071 | |.if "fpins" == "fpmod_" |
| 3564 | | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway. | 4072 | | b ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway. |
| 3565 | |.else | 4073 | |.else |
| 4074 | |.if FPU | ||
| 3566 | | fpins f0, f14, f15 | 4075 | | fpins f0, f14, f15 |
| 3567 | | ins_next1 | ||
| 3568 | | stfdx f0, BASE, RA | 4076 | | stfdx f0, BASE, RA |
| 4077 | |.else | ||
| 4078 | |.if "fpcall" == "sfpmod" | ||
| 4079 | | sfpmod | ||
| 4080 | |.else | ||
| 4081 | | blex fpcall | ||
| 4082 | |.endif | ||
| 4083 | | stwux CRET1, RA, BASE | ||
| 4084 | | stw CRET2, 4(RA) | ||
| 4085 | |.endif | ||
| 4086 | | ins_next1 | ||
| 3569 | | b <2 | 4087 | | b <2 |
| 3570 | |.endif | 4088 | |.endif |
| 3571 | |.endmacro | 4089 | |.endmacro |
| 3572 | | | 4090 | | |
| 3573 | |.macro ins_arith, intins, fpins | 4091 | |.macro ins_arith, intins, fpins, fpcall |
| 3574 | |.if DUALNUM | 4092 | |.if DUALNUM |
| 3575 | | ins_arithdn intins, fpins | 4093 | | ins_arithdn intins, fpins, fpcall |
| 3576 | |.else | 4094 | |.else |
| 3577 | | ins_arithfp fpins | 4095 | | ins_arithfp fpins |
| 3578 | |.endif | 4096 | |.endif |
| @@ -3587,9 +4105,9 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3587 | | addo. TMP0, TMP0, TMP3 | 4105 | | addo. TMP0, TMP0, TMP3 |
| 3588 | | add y, a, b | 4106 | | add y, a, b |
| 3589 | |.endmacro | 4107 | |.endmacro |
| 3590 | | ins_arith addo32., fadd | 4108 | | ins_arith addo32., fadd, __adddf3 |
| 3591 | |.else | 4109 | |.else |
| 3592 | | ins_arith addo., fadd | 4110 | | ins_arith addo., fadd, __adddf3 |
| 3593 | |.endif | 4111 | |.endif |
| 3594 | break; | 4112 | break; |
| 3595 | case BC_SUBVN: case BC_SUBNV: case BC_SUBVV: | 4113 | case BC_SUBVN: case BC_SUBNV: case BC_SUBVV: |
| @@ -3601,36 +4119,48 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3601 | | subo. TMP0, TMP0, TMP3 | 4119 | | subo. TMP0, TMP0, TMP3 |
| 3602 | | sub y, a, b | 4120 | | sub y, a, b |
| 3603 | |.endmacro | 4121 | |.endmacro |
| 3604 | | ins_arith subo32., fsub | 4122 | | ins_arith subo32., fsub, __subdf3 |
| 3605 | |.else | 4123 | |.else |
| 3606 | | ins_arith subo., fsub | 4124 | | ins_arith subo., fsub, __subdf3 |
| 3607 | |.endif | 4125 | |.endif |
| 3608 | break; | 4126 | break; |
| 3609 | case BC_MULVN: case BC_MULNV: case BC_MULVV: | 4127 | case BC_MULVN: case BC_MULNV: case BC_MULVV: |
| 3610 | | ins_arith mullwo., fmul | 4128 | | ins_arith mullwo., fmul, __muldf3 |
| 3611 | break; | 4129 | break; |
| 3612 | case BC_DIVVN: case BC_DIVNV: case BC_DIVVV: | 4130 | case BC_DIVVN: case BC_DIVNV: case BC_DIVVV: |
| 3613 | | ins_arithfp fdiv | 4131 | | ins_arithfp fdiv |
| 3614 | break; | 4132 | break; |
| 3615 | case BC_MODVN: | 4133 | case BC_MODVN: |
| 3616 | | ins_arith intmod, fpmod | 4134 | | ins_arith intmod, fpmod, sfpmod |
| 3617 | break; | 4135 | break; |
| 3618 | case BC_MODNV: case BC_MODVV: | 4136 | case BC_MODNV: case BC_MODVV: |
| 3619 | | ins_arith intmod, fpmod_ | 4137 | | ins_arith intmod, fpmod_, sfpmod |
| 3620 | break; | 4138 | break; |
| 3621 | case BC_POW: | 4139 | case BC_POW: |
| 3622 | | // NYI: (partial) integer arithmetic. | 4140 | | // NYI: (partial) integer arithmetic. |
| 3623 | | lwzx TMP1, BASE, RB | 4141 | | lwzx CARG1, BASE, RB |
| 4142 | | lwzx CARG3, BASE, RC | ||
| 4143 | |.if FPU | ||
| 3624 | | lfdx FARG1, BASE, RB | 4144 | | lfdx FARG1, BASE, RB |
| 3625 | | lwzx TMP2, BASE, RC | ||
| 3626 | | lfdx FARG2, BASE, RC | 4145 | | lfdx FARG2, BASE, RC |
| 3627 | | checknum cr0, TMP1 | 4146 | |.else |
| 3628 | | checknum cr1, TMP2 | 4147 | | add TMP1, BASE, RB |
| 4148 | | add TMP2, BASE, RC | ||
| 4149 | | lwz CARG2, 4(TMP1) | ||
| 4150 | | lwz CARG4, 4(TMP2) | ||
| 4151 | |.endif | ||
| 4152 | | checknum cr0, CARG1 | ||
| 4153 | | checknum cr1, CARG3 | ||
| 3629 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt | 4154 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt |
| 3630 | | bge ->vmeta_arith_vv | 4155 | | bge ->vmeta_arith_vv |
| 3631 | | blex pow | 4156 | | blex pow |
| 3632 | | ins_next1 | 4157 | | ins_next1 |
| 4158 | |.if FPU | ||
| 3633 | | stfdx FARG1, BASE, RA | 4159 | | stfdx FARG1, BASE, RA |
| 4160 | |.else | ||
| 4161 | | stwux CARG1, RA, BASE | ||
| 4162 | | stw CARG2, 4(RA) | ||
| 4163 | |.endif | ||
| 3634 | | ins_next2 | 4164 | | ins_next2 |
| 3635 | break; | 4165 | break; |
| 3636 | 4166 | ||
| @@ -3650,8 +4180,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3650 | | lp BASE, L->base | 4180 | | lp BASE, L->base |
| 3651 | | bne ->vmeta_binop | 4181 | | bne ->vmeta_binop |
| 3652 | | ins_next1 | 4182 | | ins_next1 |
| 4183 | |.if FPU | ||
| 3653 | | lfdx f0, BASE, SAVE0 // Copy result from RB to RA. | 4184 | | lfdx f0, BASE, SAVE0 // Copy result from RB to RA. |
| 3654 | | stfdx f0, BASE, RA | 4185 | | stfdx f0, BASE, RA |
| 4186 | |.else | ||
| 4187 | | lwzux TMP0, SAVE0, BASE | ||
| 4188 | | lwz TMP1, 4(SAVE0) | ||
| 4189 | | stwux TMP0, RA, BASE | ||
| 4190 | | stw TMP1, 4(RA) | ||
| 4191 | |.endif | ||
| 3655 | | ins_next2 | 4192 | | ins_next2 |
| 3656 | break; | 4193 | break; |
| 3657 | 4194 | ||
| @@ -3714,8 +4251,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3714 | case BC_KNUM: | 4251 | case BC_KNUM: |
| 3715 | | // RA = dst*8, RD = num_const*8 | 4252 | | // RA = dst*8, RD = num_const*8 |
| 3716 | | ins_next1 | 4253 | | ins_next1 |
| 4254 | |.if FPU | ||
| 3717 | | lfdx f0, KBASE, RD | 4255 | | lfdx f0, KBASE, RD |
| 3718 | | stfdx f0, BASE, RA | 4256 | | stfdx f0, BASE, RA |
| 4257 | |.else | ||
| 4258 | | lwzux TMP0, RD, KBASE | ||
| 4259 | | lwz TMP1, 4(RD) | ||
| 4260 | | stwux TMP0, RA, BASE | ||
| 4261 | | stw TMP1, 4(RA) | ||
| 4262 | |.endif | ||
| 3719 | | ins_next2 | 4263 | | ins_next2 |
| 3720 | break; | 4264 | break; |
| 3721 | case BC_KPRI: | 4265 | case BC_KPRI: |
| @@ -3748,8 +4292,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3748 | | lwzx UPVAL:RB, LFUNC:RB, RD | 4292 | | lwzx UPVAL:RB, LFUNC:RB, RD |
| 3749 | | ins_next1 | 4293 | | ins_next1 |
| 3750 | | lwz TMP1, UPVAL:RB->v | 4294 | | lwz TMP1, UPVAL:RB->v |
| 4295 | |.if FPU | ||
| 3751 | | lfd f0, 0(TMP1) | 4296 | | lfd f0, 0(TMP1) |
| 3752 | | stfdx f0, BASE, RA | 4297 | | stfdx f0, BASE, RA |
| 4298 | |.else | ||
| 4299 | | lwz TMP2, 0(TMP1) | ||
| 4300 | | lwz TMP3, 4(TMP1) | ||
| 4301 | | stwux TMP2, RA, BASE | ||
| 4302 | | stw TMP3, 4(RA) | ||
| 4303 | |.endif | ||
| 3753 | | ins_next2 | 4304 | | ins_next2 |
| 3754 | break; | 4305 | break; |
| 3755 | case BC_USETV: | 4306 | case BC_USETV: |
| @@ -3757,14 +4308,24 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3757 | | lwz LFUNC:RB, FRAME_FUNC(BASE) | 4308 | | lwz LFUNC:RB, FRAME_FUNC(BASE) |
| 3758 | | srwi RA, RA, 1 | 4309 | | srwi RA, RA, 1 |
| 3759 | | addi RA, RA, offsetof(GCfuncL, uvptr) | 4310 | | addi RA, RA, offsetof(GCfuncL, uvptr) |
| 4311 | |.if FPU | ||
| 3760 | | lfdux f0, RD, BASE | 4312 | | lfdux f0, RD, BASE |
| 4313 | |.else | ||
| 4314 | | lwzux CARG1, RD, BASE | ||
| 4315 | | lwz CARG3, 4(RD) | ||
| 4316 | |.endif | ||
| 3761 | | lwzx UPVAL:RB, LFUNC:RB, RA | 4317 | | lwzx UPVAL:RB, LFUNC:RB, RA |
| 3762 | | lbz TMP3, UPVAL:RB->marked | 4318 | | lbz TMP3, UPVAL:RB->marked |
| 3763 | | lwz CARG2, UPVAL:RB->v | 4319 | | lwz CARG2, UPVAL:RB->v |
| 3764 | | andix. TMP3, TMP3, LJ_GC_BLACK // isblack(uv) | 4320 | | andix. TMP3, TMP3, LJ_GC_BLACK // isblack(uv) |
| 3765 | | lbz TMP0, UPVAL:RB->closed | 4321 | | lbz TMP0, UPVAL:RB->closed |
| 3766 | | lwz TMP2, 0(RD) | 4322 | | lwz TMP2, 0(RD) |
| 4323 | |.if FPU | ||
| 3767 | | stfd f0, 0(CARG2) | 4324 | | stfd f0, 0(CARG2) |
| 4325 | |.else | ||
| 4326 | | stw CARG1, 0(CARG2) | ||
| 4327 | | stw CARG3, 4(CARG2) | ||
| 4328 | |.endif | ||
| 3768 | | cmplwi cr1, TMP0, 0 | 4329 | | cmplwi cr1, TMP0, 0 |
| 3769 | | lwz TMP1, 4(RD) | 4330 | | lwz TMP1, 4(RD) |
| 3770 | | cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq | 4331 | | cror 4*cr0+eq, 4*cr0+eq, 4*cr1+eq |
| @@ -3820,11 +4381,21 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3820 | | lwz LFUNC:RB, FRAME_FUNC(BASE) | 4381 | | lwz LFUNC:RB, FRAME_FUNC(BASE) |
| 3821 | | srwi RA, RA, 1 | 4382 | | srwi RA, RA, 1 |
| 3822 | | addi RA, RA, offsetof(GCfuncL, uvptr) | 4383 | | addi RA, RA, offsetof(GCfuncL, uvptr) |
| 4384 | |.if FPU | ||
| 3823 | | lfdx f0, KBASE, RD | 4385 | | lfdx f0, KBASE, RD |
| 4386 | |.else | ||
| 4387 | | lwzux TMP2, RD, KBASE | ||
| 4388 | | lwz TMP3, 4(RD) | ||
| 4389 | |.endif | ||
| 3824 | | lwzx UPVAL:RB, LFUNC:RB, RA | 4390 | | lwzx UPVAL:RB, LFUNC:RB, RA |
| 3825 | | ins_next1 | 4391 | | ins_next1 |
| 3826 | | lwz TMP1, UPVAL:RB->v | 4392 | | lwz TMP1, UPVAL:RB->v |
| 4393 | |.if FPU | ||
| 3827 | | stfd f0, 0(TMP1) | 4394 | | stfd f0, 0(TMP1) |
| 4395 | |.else | ||
| 4396 | | stw TMP2, 0(TMP1) | ||
| 4397 | | stw TMP3, 4(TMP1) | ||
| 4398 | |.endif | ||
| 3828 | | ins_next2 | 4399 | | ins_next2 |
| 3829 | break; | 4400 | break; |
| 3830 | case BC_USETP: | 4401 | case BC_USETP: |
| @@ -3972,11 +4543,21 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 3972 | |.endif | 4543 | |.endif |
| 3973 | | ble ->vmeta_tgetv // Integer key and in array part? | 4544 | | ble ->vmeta_tgetv // Integer key and in array part? |
| 3974 | | lwzx TMP0, TMP1, TMP2 | 4545 | | lwzx TMP0, TMP1, TMP2 |
| 4546 | |.if FPU | ||
| 3975 | | lfdx f14, TMP1, TMP2 | 4547 | | lfdx f14, TMP1, TMP2 |
| 4548 | |.else | ||
| 4549 | | lwzux SAVE0, TMP1, TMP2 | ||
| 4550 | | lwz SAVE1, 4(TMP1) | ||
| 4551 | |.endif | ||
| 3976 | | checknil TMP0; beq >2 | 4552 | | checknil TMP0; beq >2 |
| 3977 | |1: | 4553 | |1: |
| 3978 | | ins_next1 | 4554 | | ins_next1 |
| 4555 | |.if FPU | ||
| 3979 | | stfdx f14, BASE, RA | 4556 | | stfdx f14, BASE, RA |
| 4557 | |.else | ||
| 4558 | | stwux SAVE0, RA, BASE | ||
| 4559 | | stw SAVE1, 4(RA) | ||
| 4560 | |.endif | ||
| 3980 | | ins_next2 | 4561 | | ins_next2 |
| 3981 | | | 4562 | | |
| 3982 | |2: // Check for __index if table value is nil. | 4563 | |2: // Check for __index if table value is nil. |
| @@ -4052,12 +4633,22 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4052 | | lwz TMP1, TAB:RB->asize | 4633 | | lwz TMP1, TAB:RB->asize |
| 4053 | | lwz TMP2, TAB:RB->array | 4634 | | lwz TMP2, TAB:RB->array |
| 4054 | | cmplw TMP0, TMP1; bge ->vmeta_tgetb | 4635 | | cmplw TMP0, TMP1; bge ->vmeta_tgetb |
| 4636 | |.if FPU | ||
| 4055 | | lwzx TMP1, TMP2, RC | 4637 | | lwzx TMP1, TMP2, RC |
| 4056 | | lfdx f0, TMP2, RC | 4638 | | lfdx f0, TMP2, RC |
| 4639 | |.else | ||
| 4640 | | lwzux TMP1, TMP2, RC | ||
| 4641 | | lwz TMP3, 4(TMP2) | ||
| 4642 | |.endif | ||
| 4057 | | checknil TMP1; beq >5 | 4643 | | checknil TMP1; beq >5 |
| 4058 | |1: | 4644 | |1: |
| 4059 | | ins_next1 | 4645 | | ins_next1 |
| 4646 | |.if FPU | ||
| 4060 | | stfdx f0, BASE, RA | 4647 | | stfdx f0, BASE, RA |
| 4648 | |.else | ||
| 4649 | | stwux TMP1, RA, BASE | ||
| 4650 | | stw TMP3, 4(RA) | ||
| 4651 | |.endif | ||
| 4061 | | ins_next2 | 4652 | | ins_next2 |
| 4062 | | | 4653 | | |
| 4063 | |5: // Check for __index if table value is nil. | 4654 | |5: // Check for __index if table value is nil. |
| @@ -4087,10 +4678,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4087 | | cmplw TMP0, CARG2 | 4678 | | cmplw TMP0, CARG2 |
| 4088 | | slwi TMP2, CARG2, 3 | 4679 | | slwi TMP2, CARG2, 3 |
| 4089 | | ble ->vmeta_tgetr // In array part? | 4680 | | ble ->vmeta_tgetr // In array part? |
| 4681 | |.if FPU | ||
| 4090 | | lfdx f14, TMP1, TMP2 | 4682 | | lfdx f14, TMP1, TMP2 |
| 4683 | |.else | ||
| 4684 | | lwzux SAVE0, TMP2, TMP1 | ||
| 4685 | | lwz SAVE1, 4(TMP2) | ||
| 4686 | |.endif | ||
| 4091 | |->BC_TGETR_Z: | 4687 | |->BC_TGETR_Z: |
| 4092 | | ins_next1 | 4688 | | ins_next1 |
| 4689 | |.if FPU | ||
| 4093 | | stfdx f14, BASE, RA | 4690 | | stfdx f14, BASE, RA |
| 4691 | |.else | ||
| 4692 | | stwux SAVE0, RA, BASE | ||
| 4693 | | stw SAVE1, 4(RA) | ||
| 4694 | |.endif | ||
| 4094 | | ins_next2 | 4695 | | ins_next2 |
| 4095 | break; | 4696 | break; |
| 4096 | 4697 | ||
| @@ -4131,11 +4732,22 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4131 | | ble ->vmeta_tsetv // Integer key and in array part? | 4732 | | ble ->vmeta_tsetv // Integer key and in array part? |
| 4132 | | lwzx TMP2, TMP1, TMP0 | 4733 | | lwzx TMP2, TMP1, TMP0 |
| 4133 | | lbz TMP3, TAB:RB->marked | 4734 | | lbz TMP3, TAB:RB->marked |
| 4735 | |.if FPU | ||
| 4134 | | lfdx f14, BASE, RA | 4736 | | lfdx f14, BASE, RA |
| 4737 | |.else | ||
| 4738 | | add SAVE1, BASE, RA | ||
| 4739 | | lwz SAVE0, 0(SAVE1) | ||
| 4740 | | lwz SAVE1, 4(SAVE1) | ||
| 4741 | |.endif | ||
| 4135 | | checknil TMP2; beq >3 | 4742 | | checknil TMP2; beq >3 |
| 4136 | |1: | 4743 | |1: |
| 4137 | | andix. TMP2, TMP3, LJ_GC_BLACK // isblack(table) | 4744 | | andix. TMP2, TMP3, LJ_GC_BLACK // isblack(table) |
| 4745 | |.if FPU | ||
| 4138 | | stfdx f14, TMP1, TMP0 | 4746 | | stfdx f14, TMP1, TMP0 |
| 4747 | |.else | ||
| 4748 | | stwux SAVE0, TMP1, TMP0 | ||
| 4749 | | stw SAVE1, 4(TMP1) | ||
| 4750 | |.endif | ||
| 4139 | | bne >7 | 4751 | | bne >7 |
| 4140 | |2: | 4752 | |2: |
| 4141 | | ins_next | 4753 | | ins_next |
| @@ -4176,7 +4788,13 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4176 | | lwz NODE:TMP2, TAB:RB->node | 4788 | | lwz NODE:TMP2, TAB:RB->node |
| 4177 | | stb ZERO, TAB:RB->nomm // Clear metamethod cache. | 4789 | | stb ZERO, TAB:RB->nomm // Clear metamethod cache. |
| 4178 | | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask | 4790 | | and TMP1, TMP1, TMP0 // idx = str->hash & tab->hmask |
| 4791 | |.if FPU | ||
| 4179 | | lfdx f14, BASE, RA | 4792 | | lfdx f14, BASE, RA |
| 4793 | |.else | ||
| 4794 | | add CARG2, BASE, RA | ||
| 4795 | | lwz SAVE0, 0(CARG2) | ||
| 4796 | | lwz SAVE1, 4(CARG2) | ||
| 4797 | |.endif | ||
| 4180 | | slwi TMP0, TMP1, 5 | 4798 | | slwi TMP0, TMP1, 5 |
| 4181 | | slwi TMP1, TMP1, 3 | 4799 | | slwi TMP1, TMP1, 3 |
| 4182 | | sub TMP1, TMP0, TMP1 | 4800 | | sub TMP1, TMP0, TMP1 |
| @@ -4192,7 +4810,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4192 | | checknil CARG2; beq >4 // Key found, but nil value? | 4810 | | checknil CARG2; beq >4 // Key found, but nil value? |
| 4193 | |2: | 4811 | |2: |
| 4194 | | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table) | 4812 | | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table) |
| 4813 | |.if FPU | ||
| 4195 | | stfd f14, NODE:TMP2->val | 4814 | | stfd f14, NODE:TMP2->val |
| 4815 | |.else | ||
| 4816 | | stw SAVE0, NODE:TMP2->val.u32.hi | ||
| 4817 | | stw SAVE1, NODE:TMP2->val.u32.lo | ||
| 4818 | |.endif | ||
| 4196 | | bne >7 | 4819 | | bne >7 |
| 4197 | |3: | 4820 | |3: |
| 4198 | | ins_next | 4821 | | ins_next |
| @@ -4231,7 +4854,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4231 | | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k) | 4854 | | bl extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k) |
| 4232 | | // Returns TValue *. | 4855 | | // Returns TValue *. |
| 4233 | | lp BASE, L->base | 4856 | | lp BASE, L->base |
| 4857 | |.if FPU | ||
| 4234 | | stfd f14, 0(CRET1) | 4858 | | stfd f14, 0(CRET1) |
| 4859 | |.else | ||
| 4860 | | stw SAVE0, 0(CRET1) | ||
| 4861 | | stw SAVE1, 4(CRET1) | ||
| 4862 | |.endif | ||
| 4235 | | b <3 // No 2nd write barrier needed. | 4863 | | b <3 // No 2nd write barrier needed. |
| 4236 | | | 4864 | | |
| 4237 | |7: // Possible table write barrier for the value. Skip valiswhite check. | 4865 | |7: // Possible table write barrier for the value. Skip valiswhite check. |
| @@ -4248,13 +4876,24 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4248 | | lwz TMP2, TAB:RB->array | 4876 | | lwz TMP2, TAB:RB->array |
| 4249 | | lbz TMP3, TAB:RB->marked | 4877 | | lbz TMP3, TAB:RB->marked |
| 4250 | | cmplw TMP0, TMP1 | 4878 | | cmplw TMP0, TMP1 |
| 4879 | |.if FPU | ||
| 4251 | | lfdx f14, BASE, RA | 4880 | | lfdx f14, BASE, RA |
| 4881 | |.else | ||
| 4882 | | add CARG2, BASE, RA | ||
| 4883 | | lwz SAVE0, 0(CARG2) | ||
| 4884 | | lwz SAVE1, 4(CARG2) | ||
| 4885 | |.endif | ||
| 4252 | | bge ->vmeta_tsetb | 4886 | | bge ->vmeta_tsetb |
| 4253 | | lwzx TMP1, TMP2, RC | 4887 | | lwzx TMP1, TMP2, RC |
| 4254 | | checknil TMP1; beq >5 | 4888 | | checknil TMP1; beq >5 |
| 4255 | |1: | 4889 | |1: |
| 4256 | | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table) | 4890 | | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table) |
| 4891 | |.if FPU | ||
| 4257 | | stfdx f14, TMP2, RC | 4892 | | stfdx f14, TMP2, RC |
| 4893 | |.else | ||
| 4894 | | stwux SAVE0, RC, TMP2 | ||
| 4895 | | stw SAVE1, 4(RC) | ||
| 4896 | |.endif | ||
| 4258 | | bne >7 | 4897 | | bne >7 |
| 4259 | |2: | 4898 | |2: |
| 4260 | | ins_next | 4899 | | ins_next |
| @@ -4294,10 +4933,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4294 | |2: | 4933 | |2: |
| 4295 | | cmplw TMP0, CARG3 | 4934 | | cmplw TMP0, CARG3 |
| 4296 | | slwi TMP2, CARG3, 3 | 4935 | | slwi TMP2, CARG3, 3 |
| 4936 | |.if FPU | ||
| 4297 | | lfdx f14, BASE, RA | 4937 | | lfdx f14, BASE, RA |
| 4938 | |.else | ||
| 4939 | | lwzux SAVE0, RA, BASE | ||
| 4940 | | lwz SAVE1, 4(RA) | ||
| 4941 | |.endif | ||
| 4298 | | ble ->vmeta_tsetr // In array part? | 4942 | | ble ->vmeta_tsetr // In array part? |
| 4299 | | ins_next1 | 4943 | | ins_next1 |
| 4944 | |.if FPU | ||
| 4300 | | stfdx f14, TMP1, TMP2 | 4945 | | stfdx f14, TMP1, TMP2 |
| 4946 | |.else | ||
| 4947 | | stwux SAVE0, TMP1, TMP2 | ||
| 4948 | | stw SAVE1, 4(TMP1) | ||
| 4949 | |.endif | ||
| 4301 | | ins_next2 | 4950 | | ins_next2 |
| 4302 | | | 4951 | | |
| 4303 | |7: // Possible table write barrier for the value. Skip valiswhite check. | 4952 | |7: // Possible table write barrier for the value. Skip valiswhite check. |
| @@ -4327,10 +4976,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4327 | | add TMP1, TMP1, TMP0 | 4976 | | add TMP1, TMP1, TMP0 |
| 4328 | | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table) | 4977 | | andix. TMP0, TMP3, LJ_GC_BLACK // isblack(table) |
| 4329 | |3: // Copy result slots to table. | 4978 | |3: // Copy result slots to table. |
| 4979 | |.if FPU | ||
| 4330 | | lfd f0, 0(RA) | 4980 | | lfd f0, 0(RA) |
| 4981 | |.else | ||
| 4982 | | lwz SAVE0, 0(RA) | ||
| 4983 | | lwz SAVE1, 4(RA) | ||
| 4984 | |.endif | ||
| 4331 | | addi RA, RA, 8 | 4985 | | addi RA, RA, 8 |
| 4332 | | cmpw cr1, RA, TMP2 | 4986 | | cmpw cr1, RA, TMP2 |
| 4987 | |.if FPU | ||
| 4333 | | stfd f0, 0(TMP1) | 4988 | | stfd f0, 0(TMP1) |
| 4989 | |.else | ||
| 4990 | | stw SAVE0, 0(TMP1) | ||
| 4991 | | stw SAVE1, 4(TMP1) | ||
| 4992 | |.endif | ||
| 4334 | | addi TMP1, TMP1, 8 | 4993 | | addi TMP1, TMP1, 8 |
| 4335 | | blt cr1, <3 | 4994 | | blt cr1, <3 |
| 4336 | | bne >7 | 4995 | | bne >7 |
| @@ -4397,9 +5056,20 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4397 | | beq cr1, >3 | 5056 | | beq cr1, >3 |
| 4398 | |2: | 5057 | |2: |
| 4399 | | addi TMP3, TMP2, 8 | 5058 | | addi TMP3, TMP2, 8 |
| 5059 | |.if FPU | ||
| 4400 | | lfdx f0, RA, TMP2 | 5060 | | lfdx f0, RA, TMP2 |
| 5061 | |.else | ||
| 5062 | | add CARG3, RA, TMP2 | ||
| 5063 | | lwz CARG1, 0(CARG3) | ||
| 5064 | | lwz CARG2, 4(CARG3) | ||
| 5065 | |.endif | ||
| 4401 | | cmplw cr1, TMP3, NARGS8:RC | 5066 | | cmplw cr1, TMP3, NARGS8:RC |
| 5067 | |.if FPU | ||
| 4402 | | stfdx f0, BASE, TMP2 | 5068 | | stfdx f0, BASE, TMP2 |
| 5069 | |.else | ||
| 5070 | | stwux CARG1, TMP2, BASE | ||
| 5071 | | stw CARG2, 4(TMP2) | ||
| 5072 | |.endif | ||
| 4403 | | mr TMP2, TMP3 | 5073 | | mr TMP2, TMP3 |
| 4404 | | bne cr1, <2 | 5074 | | bne cr1, <2 |
| 4405 | |3: | 5075 | |3: |
| @@ -4432,14 +5102,28 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4432 | | add BASE, BASE, RA | 5102 | | add BASE, BASE, RA |
| 4433 | | lwz TMP1, -24(BASE) | 5103 | | lwz TMP1, -24(BASE) |
| 4434 | | lwz LFUNC:RB, -20(BASE) | 5104 | | lwz LFUNC:RB, -20(BASE) |
| 5105 | |.if FPU | ||
| 4435 | | lfd f1, -8(BASE) | 5106 | | lfd f1, -8(BASE) |
| 4436 | | lfd f0, -16(BASE) | 5107 | | lfd f0, -16(BASE) |
| 5108 | |.else | ||
| 5109 | | lwz CARG1, -8(BASE) | ||
| 5110 | | lwz CARG2, -4(BASE) | ||
| 5111 | | lwz CARG3, -16(BASE) | ||
| 5112 | | lwz CARG4, -12(BASE) | ||
| 5113 | |.endif | ||
| 4437 | | stw TMP1, 0(BASE) // Copy callable. | 5114 | | stw TMP1, 0(BASE) // Copy callable. |
| 4438 | | stw LFUNC:RB, 4(BASE) | 5115 | | stw LFUNC:RB, 4(BASE) |
| 4439 | | checkfunc TMP1 | 5116 | | checkfunc TMP1 |
| 4440 | | stfd f1, 16(BASE) // Copy control var. | ||
| 4441 | | li NARGS8:RC, 16 // Iterators get 2 arguments. | 5117 | | li NARGS8:RC, 16 // Iterators get 2 arguments. |
| 5118 | |.if FPU | ||
| 5119 | | stfd f1, 16(BASE) // Copy control var. | ||
| 4442 | | stfdu f0, 8(BASE) // Copy state. | 5120 | | stfdu f0, 8(BASE) // Copy state. |
| 5121 | |.else | ||
| 5122 | | stw CARG1, 16(BASE) // Copy control var. | ||
| 5123 | | stw CARG2, 20(BASE) | ||
| 5124 | | stwu CARG3, 8(BASE) // Copy state. | ||
| 5125 | | stw CARG4, 4(BASE) | ||
| 5126 | |.endif | ||
| 4443 | | bne ->vmeta_call | 5127 | | bne ->vmeta_call |
| 4444 | | ins_call | 5128 | | ins_call |
| 4445 | break; | 5129 | break; |
| @@ -4460,7 +5144,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4460 | | slwi TMP3, RC, 3 | 5144 | | slwi TMP3, RC, 3 |
| 4461 | | bge >5 // Index points after array part? | 5145 | | bge >5 // Index points after array part? |
| 4462 | | lwzx TMP2, TMP1, TMP3 | 5146 | | lwzx TMP2, TMP1, TMP3 |
| 5147 | |.if FPU | ||
| 4463 | | lfdx f0, TMP1, TMP3 | 5148 | | lfdx f0, TMP1, TMP3 |
| 5149 | |.else | ||
| 5150 | | lwzux CARG1, TMP3, TMP1 | ||
| 5151 | | lwz CARG2, 4(TMP3) | ||
| 5152 | |.endif | ||
| 4464 | | checknil TMP2 | 5153 | | checknil TMP2 |
| 4465 | | lwz INS, -4(PC) | 5154 | | lwz INS, -4(PC) |
| 4466 | | beq >4 | 5155 | | beq >4 |
| @@ -4472,7 +5161,12 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4472 | |.endif | 5161 | |.endif |
| 4473 | | addi RC, RC, 1 | 5162 | | addi RC, RC, 1 |
| 4474 | | addis TMP3, PC, -(BCBIAS_J*4 >> 16) | 5163 | | addis TMP3, PC, -(BCBIAS_J*4 >> 16) |
| 5164 | |.if FPU | ||
| 4475 | | stfd f0, 8(RA) | 5165 | | stfd f0, 8(RA) |
| 5166 | |.else | ||
| 5167 | | stw CARG1, 8(RA) | ||
| 5168 | | stw CARG2, 12(RA) | ||
| 5169 | |.endif | ||
| 4476 | | decode_RD4 TMP1, INS | 5170 | | decode_RD4 TMP1, INS |
| 4477 | | stw RC, -4(RA) // Update control var. | 5171 | | stw RC, -4(RA) // Update control var. |
| 4478 | | add PC, TMP1, TMP3 | 5172 | | add PC, TMP1, TMP3 |
| @@ -4497,17 +5191,38 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4497 | | slwi RB, RC, 3 | 5191 | | slwi RB, RC, 3 |
| 4498 | | sub TMP3, TMP3, RB | 5192 | | sub TMP3, TMP3, RB |
| 4499 | | lwzx RB, TMP2, TMP3 | 5193 | | lwzx RB, TMP2, TMP3 |
| 5194 | |.if FPU | ||
| 4500 | | lfdx f0, TMP2, TMP3 | 5195 | | lfdx f0, TMP2, TMP3 |
| 5196 | |.else | ||
| 5197 | | add CARG3, TMP2, TMP3 | ||
| 5198 | | lwz CARG1, 0(CARG3) | ||
| 5199 | | lwz CARG2, 4(CARG3) | ||
| 5200 | |.endif | ||
| 4501 | | add NODE:TMP3, TMP2, TMP3 | 5201 | | add NODE:TMP3, TMP2, TMP3 |
| 4502 | | checknil RB | 5202 | | checknil RB |
| 4503 | | lwz INS, -4(PC) | 5203 | | lwz INS, -4(PC) |
| 4504 | | beq >7 | 5204 | | beq >7 |
| 5205 | |.if FPU | ||
| 4505 | | lfd f1, NODE:TMP3->key | 5206 | | lfd f1, NODE:TMP3->key |
| 5207 | |.else | ||
| 5208 | | lwz CARG3, NODE:TMP3->key.u32.hi | ||
| 5209 | | lwz CARG4, NODE:TMP3->key.u32.lo | ||
| 5210 | |.endif | ||
| 4506 | | addis TMP2, PC, -(BCBIAS_J*4 >> 16) | 5211 | | addis TMP2, PC, -(BCBIAS_J*4 >> 16) |
| 5212 | |.if FPU | ||
| 4507 | | stfd f0, 8(RA) | 5213 | | stfd f0, 8(RA) |
| 5214 | |.else | ||
| 5215 | | stw CARG1, 8(RA) | ||
| 5216 | | stw CARG2, 12(RA) | ||
| 5217 | |.endif | ||
| 4508 | | add RC, RC, TMP0 | 5218 | | add RC, RC, TMP0 |
| 4509 | | decode_RD4 TMP1, INS | 5219 | | decode_RD4 TMP1, INS |
| 5220 | |.if FPU | ||
| 4510 | | stfd f1, 0(RA) | 5221 | | stfd f1, 0(RA) |
| 5222 | |.else | ||
| 5223 | | stw CARG3, 0(RA) | ||
| 5224 | | stw CARG4, 4(RA) | ||
| 5225 | |.endif | ||
| 4511 | | addi RC, RC, 1 | 5226 | | addi RC, RC, 1 |
| 4512 | | add PC, TMP1, TMP2 | 5227 | | add PC, TMP1, TMP2 |
| 4513 | | stw RC, -4(RA) // Update control var. | 5228 | | stw RC, -4(RA) // Update control var. |
| @@ -4573,9 +5288,19 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4573 | | subi TMP2, TMP2, 16 | 5288 | | subi TMP2, TMP2, 16 |
| 4574 | | ble >2 // No vararg slots? | 5289 | | ble >2 // No vararg slots? |
| 4575 | |1: // Copy vararg slots to destination slots. | 5290 | |1: // Copy vararg slots to destination slots. |
| 5291 | |.if FPU | ||
| 4576 | | lfd f0, 0(RC) | 5292 | | lfd f0, 0(RC) |
| 5293 | |.else | ||
| 5294 | | lwz CARG1, 0(RC) | ||
| 5295 | | lwz CARG2, 4(RC) | ||
| 5296 | |.endif | ||
| 4577 | | addi RC, RC, 8 | 5297 | | addi RC, RC, 8 |
| 5298 | |.if FPU | ||
| 4578 | | stfd f0, 0(RA) | 5299 | | stfd f0, 0(RA) |
| 5300 | |.else | ||
| 5301 | | stw CARG1, 0(RA) | ||
| 5302 | | stw CARG2, 4(RA) | ||
| 5303 | |.endif | ||
| 4579 | | cmplw RA, TMP2 | 5304 | | cmplw RA, TMP2 |
| 4580 | | cmplw cr1, RC, TMP3 | 5305 | | cmplw cr1, RC, TMP3 |
| 4581 | | bge >3 // All destination slots filled? | 5306 | | bge >3 // All destination slots filled? |
| @@ -4598,9 +5323,19 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4598 | | addi MULTRES, TMP1, 8 | 5323 | | addi MULTRES, TMP1, 8 |
| 4599 | | bgt >7 | 5324 | | bgt >7 |
| 4600 | |6: | 5325 | |6: |
| 5326 | |.if FPU | ||
| 4601 | | lfd f0, 0(RC) | 5327 | | lfd f0, 0(RC) |
| 5328 | |.else | ||
| 5329 | | lwz CARG1, 0(RC) | ||
| 5330 | | lwz CARG2, 4(RC) | ||
| 5331 | |.endif | ||
| 4602 | | addi RC, RC, 8 | 5332 | | addi RC, RC, 8 |
| 5333 | |.if FPU | ||
| 4603 | | stfd f0, 0(RA) | 5334 | | stfd f0, 0(RA) |
| 5335 | |.else | ||
| 5336 | | stw CARG1, 0(RA) | ||
| 5337 | | stw CARG2, 4(RA) | ||
| 5338 | |.endif | ||
| 4604 | | cmplw RC, TMP3 | 5339 | | cmplw RC, TMP3 |
| 4605 | | addi RA, RA, 8 | 5340 | | addi RA, RA, 8 |
| 4606 | | blt <6 // More vararg slots? | 5341 | | blt <6 // More vararg slots? |
| @@ -4651,14 +5386,38 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4651 | | li TMP1, 0 | 5386 | | li TMP1, 0 |
| 4652 | |2: | 5387 | |2: |
| 4653 | | addi TMP3, TMP1, 8 | 5388 | | addi TMP3, TMP1, 8 |
| 5389 | |.if FPU | ||
| 4654 | | lfdx f0, RA, TMP1 | 5390 | | lfdx f0, RA, TMP1 |
| 5391 | |.else | ||
| 5392 | | add CARG3, RA, TMP1 | ||
| 5393 | | lwz CARG1, 0(CARG3) | ||
| 5394 | | lwz CARG2, 4(CARG3) | ||
| 5395 | |.endif | ||
| 4655 | | cmpw TMP3, RC | 5396 | | cmpw TMP3, RC |
| 5397 | |.if FPU | ||
| 4656 | | stfdx f0, TMP2, TMP1 | 5398 | | stfdx f0, TMP2, TMP1 |
| 5399 | |.else | ||
| 5400 | | add CARG3, TMP2, TMP1 | ||
| 5401 | | stw CARG1, 0(CARG3) | ||
| 5402 | | stw CARG2, 4(CARG3) | ||
| 5403 | |.endif | ||
| 4657 | | beq >3 | 5404 | | beq >3 |
| 4658 | | addi TMP1, TMP3, 8 | 5405 | | addi TMP1, TMP3, 8 |
| 5406 | |.if FPU | ||
| 4659 | | lfdx f1, RA, TMP3 | 5407 | | lfdx f1, RA, TMP3 |
| 5408 | |.else | ||
| 5409 | | add CARG3, RA, TMP3 | ||
| 5410 | | lwz CARG1, 0(CARG3) | ||
| 5411 | | lwz CARG2, 4(CARG3) | ||
| 5412 | |.endif | ||
| 4660 | | cmpw TMP1, RC | 5413 | | cmpw TMP1, RC |
| 5414 | |.if FPU | ||
| 4661 | | stfdx f1, TMP2, TMP3 | 5415 | | stfdx f1, TMP2, TMP3 |
| 5416 | |.else | ||
| 5417 | | add CARG3, TMP2, TMP3 | ||
| 5418 | | stw CARG1, 0(CARG3) | ||
| 5419 | | stw CARG2, 4(CARG3) | ||
| 5420 | |.endif | ||
| 4662 | | bne <2 | 5421 | | bne <2 |
| 4663 | |3: | 5422 | |3: |
| 4664 | |5: | 5423 | |5: |
| @@ -4700,8 +5459,15 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4700 | | subi TMP2, BASE, 8 | 5459 | | subi TMP2, BASE, 8 |
| 4701 | | decode_RB8 RB, INS | 5460 | | decode_RB8 RB, INS |
| 4702 | if (op == BC_RET1) { | 5461 | if (op == BC_RET1) { |
| 5462 | |.if FPU | ||
| 4703 | | lfd f0, 0(RA) | 5463 | | lfd f0, 0(RA) |
| 4704 | | stfd f0, 0(TMP2) | 5464 | | stfd f0, 0(TMP2) |
| 5465 | |.else | ||
| 5466 | | lwz CARG1, 0(RA) | ||
| 5467 | | lwz CARG2, 4(RA) | ||
| 5468 | | stw CARG1, 0(TMP2) | ||
| 5469 | | stw CARG2, 4(TMP2) | ||
| 5470 | |.endif | ||
| 4705 | } | 5471 | } |
| 4706 | |5: | 5472 | |5: |
| 4707 | | cmplw RB, RD | 5473 | | cmplw RB, RD |
| @@ -4762,11 +5528,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4762 | |4: | 5528 | |4: |
| 4763 | | stw CARG1, FORL_IDX*8+4(RA) | 5529 | | stw CARG1, FORL_IDX*8+4(RA) |
| 4764 | } else { | 5530 | } else { |
| 4765 | | lwz TMP3, FORL_STEP*8(RA) | 5531 | | lwz SAVE0, FORL_STEP*8(RA) |
| 4766 | | lwz CARG3, FORL_STEP*8+4(RA) | 5532 | | lwz CARG3, FORL_STEP*8+4(RA) |
| 4767 | | lwz TMP2, FORL_STOP*8(RA) | 5533 | | lwz TMP2, FORL_STOP*8(RA) |
| 4768 | | lwz CARG2, FORL_STOP*8+4(RA) | 5534 | | lwz CARG2, FORL_STOP*8+4(RA) |
| 4769 | | cmplw cr7, TMP3, TISNUM | 5535 | | cmplw cr7, SAVE0, TISNUM |
| 4770 | | cmplw cr1, TMP2, TISNUM | 5536 | | cmplw cr1, TMP2, TISNUM |
| 4771 | | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+eq | 5537 | | crand 4*cr0+eq, 4*cr0+eq, 4*cr7+eq |
| 4772 | | crand 4*cr0+eq, 4*cr0+eq, 4*cr1+eq | 5538 | | crand 4*cr0+eq, 4*cr0+eq, 4*cr1+eq |
| @@ -4809,41 +5575,80 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
| 4809 | if (vk) { | 5575 | if (vk) { |
| 4810 | |.if DUALNUM | 5576 | |.if DUALNUM |
| 4811 | |9: // FP loop. | 5577 | |9: // FP loop. |
| 5578 | |.if FPU | ||
| 4812 | | lfd f1, FORL_IDX*8(RA) | 5579 | | lfd f1, FORL_IDX*8(RA) |
| 4813 | |.else | 5580 | |.else |
| 5581 | | lwz CARG1, FORL_IDX*8(RA) | ||
| 5582 | | lwz CARG2, FORL_IDX*8+4(RA) | ||
| 5583 | |.endif | ||
| 5584 | |.else | ||
| 4814 | | lfdux f1, RA, BASE | 5585 | | lfdux f1, RA, BASE |
| 4815 | |.endif | 5586 | |.endif |
| 5587 | |.if FPU | ||
| 4816 | | lfd f3, FORL_STEP*8(RA) | 5588 | | lfd f3, FORL_STEP*8(RA) |
| 4817 | | lfd f2, FORL_STOP*8(RA) | 5589 | | lfd f2, FORL_STOP*8(RA) |
| 4818 | | lwz TMP3, FORL_STEP*8(RA) | ||
| 4819 | | fadd f1, f1, f3 | 5590 | | fadd f1, f1, f3 |
| 4820 | | stfd f1, FORL_IDX*8(RA) | 5591 | | stfd f1, FORL_IDX*8(RA) |
| 5592 | |.else | ||
| 5593 | | lwz CARG3, FORL_STEP*8(RA) | ||
| 5594 | | lwz CARG4, FORL_STEP*8+4(RA) | ||
| 5595 | | mr SAVE1, RD | ||
| 5596 | | blex __adddf3 | ||
| 5597 | | mr RD, SAVE1 | ||
| 5598 | | stw CRET1, FORL_IDX*8(RA) | ||
| 5599 | | stw CRET2, FORL_IDX*8+4(RA) | ||
| 5600 | | lwz CARG3, FORL_STOP*8(RA) | ||
| 5601 | | lwz CARG4, FORL_STOP*8+4(RA) | ||
| 5602 | |.endif | ||
| 5603 | | lwz SAVE0, FORL_STEP*8(RA) | ||
| 4821 | } else { | 5604 | } else { |
| 4822 | |.if DUALNUM | 5605 | |.if DUALNUM |
| 4823 | |9: // FP loop. | 5606 | |9: // FP loop. |
| 4824 | |.else | 5607 | |.else |
| 4825 | | lwzux TMP1, RA, BASE | 5608 | | lwzux TMP1, RA, BASE |
| 4826 | | lwz TMP3, FORL_STEP*8(RA) | 5609 | | lwz SAVE0, FORL_STEP*8(RA) |
| 4827 | | lwz TMP2, FORL_STOP*8(RA) | 5610 | | lwz TMP2, FORL_STOP*8(RA) |
| 4828 | | cmplw cr0, TMP1, TISNUM | 5611 | | cmplw cr0, TMP1, TISNUM |
| 4829 | | cmplw cr7, TMP3, TISNUM | 5612 | | cmplw cr7, SAVE0, TISNUM |
| 4830 | | cmplw cr1, TMP2, TISNUM | 5613 | | cmplw cr1, TMP2, TISNUM |
| 4831 | |.endif | 5614 | |.endif |
| 5615 | |.if FPU | ||
| 4832 | | lfd f1, FORL_IDX*8(RA) | 5616 | | lfd f1, FORL_IDX*8(RA) |
| 5617 | |.else | ||
| 5618 | | lwz CARG1, FORL_IDX*8(RA) | ||
| 5619 | | lwz CARG2, FORL_IDX*8+4(RA) | ||
| 5620 | |.endif | ||
| 4833 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr7+lt | 5621 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr7+lt |
| 4834 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt | 5622 | | crand 4*cr0+lt, 4*cr0+lt, 4*cr1+lt |
| 5623 | |.if FPU | ||
| 4835 | | lfd f2, FORL_STOP*8(RA) | 5624 | | lfd f2, FORL_STOP*8(RA) |
| 5625 | |.else | ||
| 5626 | | lwz CARG3, FORL_STOP*8(RA) | ||
| 5627 | | lwz CARG4, FORL_STOP*8+4(RA) | ||
| 5628 | |.endif | ||
| 4836 | | bge ->vmeta_for | 5629 | | bge ->vmeta_for |
| 4837 | } | 5630 | } |
| 4838 | | cmpwi cr6, TMP3, 0 | 5631 | | cmpwi cr6, SAVE0, 0 |
| 4839 | if (op != BC_JFORL) { | 5632 | if (op != BC_JFORL) { |
| 4840 | | srwi RD, RD, 1 | 5633 | | srwi RD, RD, 1 |
| 4841 | } | 5634 | } |
| 5635 | |.if FPU | ||
| 4842 | | stfd f1, FORL_EXT*8(RA) | 5636 | | stfd f1, FORL_EXT*8(RA) |
| 5637 | |.else | ||
| 5638 | | stw CARG1, FORL_EXT*8(RA) | ||
| 5639 | | stw CARG2, FORL_EXT*8+4(RA) | ||
| 5640 | |.endif | ||
| 4843 | if (op != BC_JFORL) { | 5641 | if (op != BC_JFORL) { |
| 4844 | | add RD, PC, RD | 5642 | | add RD, PC, RD |
| 4845 | } | 5643 | } |
| 5644 | |.if FPU | ||
| 4846 | | fcmpu cr0, f1, f2 | 5645 | | fcmpu cr0, f1, f2 |
| 5646 | |.else | ||
| 5647 | | mr SAVE1, RD | ||
| 5648 | | blex __ledf2 | ||
| 5649 | | cmpwi CRET1, 0 | ||
| 5650 | | mr RD, SAVE1 | ||
| 5651 | |.endif | ||
| 4847 | if (op == BC_JFORI) { | 5652 | if (op == BC_JFORI) { |
| 4848 | | addis PC, RD, -(BCBIAS_J*4 >> 16) | 5653 | | addis PC, RD, -(BCBIAS_J*4 >> 16) |
| 4849 | } | 5654 | } |
