Add support for modulo (%) operations.

Only the slow path for now.
This commit is contained in:
Michael Munday 2016-12-20 14:54:26 -05:00
parent 419869b20e
commit e0e98f94d3

View File

@ -1081,15 +1081,24 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Math helper functions ---------------------------------------------- |//-- Math helper functions ----------------------------------------------
|//----------------------------------------------------------------------- |//-----------------------------------------------------------------------
| |
|.macro vm_round, name, mode, cond |// FP value rounding. Called by math.floor/math.ceil fast functions.
|// Value to round is in f0. May clobber f0-f7 and r0. Return address is r14.
|.macro vm_round, name, mask
|->name: |->name:
| stg r0, 0(r0) | // TODO: handle edge cases?
| lghi r0, 1
| cdfbr f1, r0
| didbr f0, f2, f1, mask // f0=remainder, f2=quotient.
| jnle >1
| ldr f0, f2
| br r14
|1: // partial remainder (sanity check)
| stg r0, 0(r0) | stg r0, 0(r0)
|.endmacro |.endmacro
| |
| vm_round vm_floor, 0, 1 | vm_round vm_floor, 7 // Round towards -inf.
| vm_round vm_ceil, 1, JIT | vm_round vm_ceil, 6 // Round towards +inf.
| vm_round vm_trunc, 2, JIT | vm_round vm_trunc, 5 // Round towards 0.
| |
|// FP modulo x%y. Called by BC_MOD* and vm_arith. |// FP modulo x%y. Called by BC_MOD* and vm_arith.
|->vm_mod: |->vm_mod:
@ -1335,13 +1344,16 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
case BC_DIVVN: case BC_DIVNV: case BC_DIVVV: case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
| ins_arithfp ddbr | ins_arithfp ddbr
break; break;
// TODO: implement fast mod operation.
// x86_64 does floating point mod, however it might be better to use integer mod.
case BC_MODVN: case BC_MODVN:
| stg r0, 0(r0) | j ->vmeta_arith_vno
| stg r0, 0(r0)
break; break;
case BC_MODNV: case BC_MODVV: case BC_MODNV:
| stg r0, 0(r0) | j ->vmeta_arith_nvo
| stg r0, 0(r0) break;
case BC_MODVV:
| j ->vmeta_arith_vvo
break; break;
case BC_POW: case BC_POW:
| stg r0, 0(r0) | stg r0, 0(r0)