mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +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_RB8, dst, ins; and dst, MASKR8, ins, lsr #21; .endmacro
|
||||||
|.macro decode_RC8, dst, ins; and dst, MASKR8, ins, lsr #13; .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_RD, dst, ins; lsr dst, ins, #16; .endmacro
|
||||||
|
|.macro decode_OP, dst, ins; and dst, ins, #255; .endmacro
|
||||||
|
|
|
|
||||||
|// Instruction fetch.
|
|// Instruction fetch.
|
||||||
|.macro ins_NEXT1
|
|.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. */
|
/* Generate subroutines used by opcodes and other parts of the VM. */
|
||||||
/* The .code_sub section should be last to help static branch prediction. */
|
/* The .code_sub section should be last to help static branch prediction. */
|
||||||
static void build_subroutines(BuildCtx *ctx)
|
static void build_subroutines(BuildCtx *ctx)
|
||||||
@ -417,7 +422,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| NYI
|
| NYI
|
||||||
|
|
|
|
||||||
|->cont_nop:
|
|->cont_nop:
|
||||||
| NYI
|
| ins_next
|
||||||
|
|
|
|
||||||
|->cont_ra: // RA = resultptr
|
|->cont_ra: // RA = resultptr
|
||||||
| NYI
|
| NYI
|
||||||
@ -434,18 +439,44 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|//-- Arithmetic metamethods ---------------------------------------------
|
|//-- Arithmetic metamethods ---------------------------------------------
|
||||||
|
|
|
|
||||||
|->vmeta_arith_vn:
|
|->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:
|
|->vmeta_arith_nv:
|
||||||
| NYI
|
| decode_RB8 RB, INS
|
||||||
|
| decode_RC8 RC, INS
|
||||||
|
| add CARG4, BASE, RB
|
||||||
|
| add CARG3, KBASE, RC
|
||||||
|
| b >1
|
||||||
|
|
|
|
||||||
|->vmeta_unm:
|
|->vmeta_unm:
|
||||||
| NYI
|
| add CARG3, BASE, RC
|
||||||
|
| add CARG4, BASE, RC
|
||||||
|
| b >1
|
||||||
|
|
|
|
||||||
|->vmeta_arith_vv:
|
|->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:
|
|->vmeta_binop:
|
||||||
|
| // BASE = old base, CRET1 = new base, stack = cont/func/o1/o2
|
||||||
| NYI
|
| NYI
|
||||||
|
|
|
|
||||||
|->vmeta_len:
|
|->vmeta_len:
|
||||||
@ -789,6 +820,9 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
#else
|
#else
|
||||||
|->vm_trunc:
|
|->vm_trunc:
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|->vm_mod:
|
||||||
|
| NYI
|
||||||
|
|
|
|
||||||
|->vm_powi:
|
|->vm_powi:
|
||||||
#if LJ_HASJIT
|
#if LJ_HASJIT
|
||||||
@ -804,7 +838,21 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
|
|// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
|
||||||
|// and basic math functions. ORDER ARITH
|
|// and basic math functions. ORDER ARITH
|
||||||
|->vm_foldarith:
|
|->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 --------------------------------------------
|
|//-- Miscellaneous functions --------------------------------------------
|
||||||
@ -925,33 +973,125 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| ins_next3
|
| ins_next3
|
||||||
|2:
|
|2:
|
||||||
| checktab CARG2, ->vmeta_len
|
| 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).
|
| // Returns uint32_t (but less than 2^31).
|
||||||
| b <1
|
| b <1
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* -- Binary ops -------------------------------------------------------- */
|
/* -- 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:
|
case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
|
||||||
| NYI
|
| ins_arithdn adds, extern __aeabi_dadd
|
||||||
break;
|
break;
|
||||||
case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
|
case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
|
||||||
| NYI
|
| ins_arithdn subs, extern __aeabi_dsub
|
||||||
break;
|
break;
|
||||||
case BC_MULVN: case BC_MULNV: case BC_MULVV:
|
case BC_MULVN: case BC_MULNV: case BC_MULVV:
|
||||||
| NYI
|
| ins_arithdn smull, extern __aeabi_dmul
|
||||||
break;
|
break;
|
||||||
case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
|
case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
|
||||||
| NYI
|
| ins_arithfp extern __aeabi_ddiv
|
||||||
break;
|
break;
|
||||||
case BC_MODVN:
|
case BC_MODVN:
|
||||||
| NYI
|
| // NYI: integer arithmetic.
|
||||||
|
| // Note: __aeabi_idivmod is unsuitable. It uses trunc, not floor.
|
||||||
|
| ins_arithfp ->vm_mod
|
||||||
break;
|
break;
|
||||||
case BC_MODNV: case BC_MODVV:
|
case BC_MODNV: case BC_MODVV:
|
||||||
| NYI
|
| ins_arithpre
|
||||||
|
| b ->BC_MODVN_Z
|
||||||
break;
|
break;
|
||||||
case BC_POW:
|
case BC_POW:
|
||||||
| NYI
|
| // NYI: (partial) integer arithmetic.
|
||||||
|
| ins_arithfp extern pow
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BC_CAT:
|
case BC_CAT:
|
||||||
|
Loading…
Reference in New Issue
Block a user