mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
ARM: Add binary arithmetic instructions.
This commit is contained in:
parent
a0e4711055
commit
5b06b298a2
@ -92,6 +92,7 @@
|
||||
|.macro decode_RB8, dst, ins; and dst, MASKR8, ins, lsr #21; .endmacro
|
||||
|.macro decode_RC8, dst, ins; and dst, MASKR8, ins, lsr #13; .endmacro
|
||||
|.macro decode_RD, dst, ins; lsr dst, ins, #16; .endmacro
|
||||
|.macro decode_OP, dst, ins; and dst, ins, #255; .endmacro
|
||||
|
|
||||
|// Instruction fetch.
|
||||
|.macro ins_NEXT1
|
||||
@ -189,6 +190,10 @@
|
||||
|
|
||||
|//-----------------------------------------------------------------------
|
||||
|
||||
#if !LJ_DUALNUM
|
||||
#error "Only dual-number mode supported for ARM target"
|
||||
#endif
|
||||
|
||||
/* Generate subroutines used by opcodes and other parts of the VM. */
|
||||
/* The .code_sub section should be last to help static branch prediction. */
|
||||
static void build_subroutines(BuildCtx *ctx)
|
||||
@ -417,7 +422,7 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| NYI
|
||||
|
|
||||
|->cont_nop:
|
||||
| NYI
|
||||
| ins_next
|
||||
|
|
||||
|->cont_ra: // RA = resultptr
|
||||
| NYI
|
||||
@ -434,18 +439,44 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|//-- Arithmetic metamethods ---------------------------------------------
|
||||
|
|
||||
|->vmeta_arith_vn:
|
||||
| NYI
|
||||
| decode_RB8 RB, INS
|
||||
| decode_RC8 RC, INS
|
||||
| add CARG3, BASE, RB
|
||||
| add CARG4, KBASE, RC
|
||||
| b >1
|
||||
|
|
||||
|->vmeta_arith_nv:
|
||||
| NYI
|
||||
| decode_RB8 RB, INS
|
||||
| decode_RC8 RC, INS
|
||||
| add CARG4, BASE, RB
|
||||
| add CARG3, KBASE, RC
|
||||
| b >1
|
||||
|
|
||||
|->vmeta_unm:
|
||||
| NYI
|
||||
| add CARG3, BASE, RC
|
||||
| add CARG4, BASE, RC
|
||||
| b >1
|
||||
|
|
||||
|->vmeta_arith_vv:
|
||||
| NYI
|
||||
| decode_RB8 RB, INS
|
||||
| decode_RC8 RC, INS
|
||||
| add CARG3, BASE, RB
|
||||
| add CARG4, BASE, RC
|
||||
|1:
|
||||
| decode_OP OP, INS
|
||||
| add CARG2, BASE, RA
|
||||
| str BASE, L->base
|
||||
| mov CARG1, L
|
||||
| str PC, SAVE_PC
|
||||
| str OP, ARG5
|
||||
| bl extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
|
||||
| // Returns NULL (finished) or TValue * (metamethod).
|
||||
| cmp CRET1, #0
|
||||
| beq ->cont_nop
|
||||
|
|
||||
| // Call metamethod for binary op.
|
||||
|->vmeta_binop:
|
||||
| // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2
|
||||
| NYI
|
||||
|
|
||||
|->vmeta_len:
|
||||
@ -789,6 +820,9 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
#else
|
||||
|->vm_trunc:
|
||||
#endif
|
||||
|
|
||||
|->vm_mod:
|
||||
| NYI
|
||||
|
|
||||
|->vm_powi:
|
||||
#if LJ_HASJIT
|
||||
@ -804,7 +838,21 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
|
||||
|// and basic math functions. ORDER ARITH
|
||||
|->vm_foldarith:
|
||||
| NYI
|
||||
| ldr OP, [sp]
|
||||
| cmp OP, #1
|
||||
| blo extern __aeabi_dadd
|
||||
| beq extern __aeabi_dsub
|
||||
| cmp OP, #3
|
||||
| blo extern __aeabi_dmul
|
||||
| beq extern __aeabi_ddiv
|
||||
| cmp OP, #5
|
||||
| blo ->vm_mod
|
||||
| beq extern pow
|
||||
| cmp OP, #7
|
||||
| eorlo CARG2, CARG2, #0x80000000
|
||||
| biceq CARG2, CARG2, #0x80000000
|
||||
| bxls lr
|
||||
| NYI // Other operations only needed by JIT compiler.
|
||||
|
|
||||
|//-----------------------------------------------------------------------
|
||||
|//-- Miscellaneous functions --------------------------------------------
|
||||
@ -925,33 +973,125 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| ins_next3
|
||||
|2:
|
||||
| checktab CARG2, ->vmeta_len
|
||||
| blx extern lj_tab_len // (GCtab *t)
|
||||
| bl extern lj_tab_len // (GCtab *t)
|
||||
| // Returns uint32_t (but less than 2^31).
|
||||
| b <1
|
||||
break;
|
||||
|
||||
/* -- Binary ops -------------------------------------------------------- */
|
||||
|
||||
|.macro ins_arithcheck, cond, ncond, target
|
||||
||if (vk == 1) {
|
||||
| cmn CARG4, #-LJ_TISNUM
|
||||
| cmn..cond CARG2, #-LJ_TISNUM
|
||||
||} else {
|
||||
| cmn CARG2, #-LJ_TISNUM
|
||||
| cmn..cond CARG4, #-LJ_TISNUM
|
||||
||}
|
||||
| b..ncond target
|
||||
|.endmacro
|
||||
|.macro ins_arithcheck_int, target
|
||||
| ins_arithcheck eq, ne, target
|
||||
|.endmacro
|
||||
|.macro ins_arithcheck_num, target
|
||||
| ins_arithcheck lo, hs, target
|
||||
|.endmacro
|
||||
|
|
||||
|.macro ins_arithpre
|
||||
| decode_RB8 RB, INS
|
||||
| decode_RC8 RC, INS
|
||||
| // RA = dst*8, RB = src1*8, RC = src2*8 | num_const*8
|
||||
||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
|
||||
||switch (vk) {
|
||||
||case 0:
|
||||
| ldrd CARG12, [BASE, RB]
|
||||
| ldrd CARG34, [KBASE, RC]
|
||||
|| break;
|
||||
||case 1:
|
||||
| ldrd CARG34, [BASE, RB]
|
||||
| ldrd CARG12, [KBASE, RC]
|
||||
|| break;
|
||||
||default:
|
||||
| ldrd CARG12, [BASE, RB]
|
||||
| ldrd CARG34, [BASE, RC]
|
||||
|| break;
|
||||
||}
|
||||
|.endmacro
|
||||
|
|
||||
|.macro ins_arithfallback, ins
|
||||
||switch (vk) {
|
||||
||case 0:
|
||||
| ins ->vmeta_arith_vn
|
||||
|| break;
|
||||
||case 1:
|
||||
| ins ->vmeta_arith_nv
|
||||
|| break;
|
||||
||default:
|
||||
| ins ->vmeta_arith_vv
|
||||
|| break;
|
||||
||}
|
||||
|.endmacro
|
||||
|
|
||||
|.macro ins_arithdn, intins, fpcall
|
||||
| ins_arithpre
|
||||
| ins_next1
|
||||
| ins_arithcheck_int >5
|
||||
|.if "intins" == "smull"
|
||||
| smull CARG1, RC, CARG3, CARG1
|
||||
| cmp RC, CARG1, asr #31
|
||||
| ins_arithfallback bne
|
||||
|.else
|
||||
| intins CARG1, CARG1, CARG3
|
||||
| ins_arithfallback bvs
|
||||
|.endif
|
||||
|4:
|
||||
| ins_next2
|
||||
| strd CARG12, [BASE, RA]
|
||||
| ins_next3
|
||||
|5: // FP variant.
|
||||
| ins_arithfallback ins_arithcheck_num
|
||||
| bl fpcall
|
||||
| ins_next1
|
||||
| b <4
|
||||
|.endmacro
|
||||
|
|
||||
|.macro ins_arithfp, fpcall
|
||||
| ins_arithpre
|
||||
||if (op == BC_MODVN) {
|
||||
| ->BC_MODVN_Z:
|
||||
||}
|
||||
| ins_arithfallback ins_arithcheck_num
|
||||
| bl fpcall
|
||||
| ins_next1
|
||||
| ins_next2
|
||||
| strd CARG12, [BASE, RA]
|
||||
| ins_next3
|
||||
|.endmacro
|
||||
|
||||
case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
|
||||
| NYI
|
||||
| ins_arithdn adds, extern __aeabi_dadd
|
||||
break;
|
||||
case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
|
||||
| NYI
|
||||
| ins_arithdn subs, extern __aeabi_dsub
|
||||
break;
|
||||
case BC_MULVN: case BC_MULNV: case BC_MULVV:
|
||||
| NYI
|
||||
| ins_arithdn smull, extern __aeabi_dmul
|
||||
break;
|
||||
case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
|
||||
| NYI
|
||||
| ins_arithfp extern __aeabi_ddiv
|
||||
break;
|
||||
case BC_MODVN:
|
||||
| NYI
|
||||
| // NYI: integer arithmetic.
|
||||
| // Note: __aeabi_idivmod is unsuitable. It uses trunc, not floor.
|
||||
| ins_arithfp ->vm_mod
|
||||
break;
|
||||
case BC_MODNV: case BC_MODVV:
|
||||
| NYI
|
||||
| ins_arithpre
|
||||
| b ->BC_MODVN_Z
|
||||
break;
|
||||
case BC_POW:
|
||||
| NYI
|
||||
| // NYI: (partial) integer arithmetic.
|
||||
| ins_arithfp extern pow
|
||||
break;
|
||||
|
||||
case BC_CAT:
|
||||
|
Loading…
Reference in New Issue
Block a user