Implement bit operations.

See http://bitop.luajit.org/api.html for more information.

Bytecode listing is now supported, for example:

$ ./luajit -bl -e 'a=1'
-- BYTECODE -- "a=1":0-1
0001    KSHORT   0   1
0002    GSET     0   0      ; "a"
0003    RET0     0   1
This commit is contained in:
Michael Munday 2016-12-29 14:50:45 -05:00
parent e8ca7b8799
commit e6eb12b268

View File

@ -20,6 +20,8 @@
| |
|// Instructions used that are not in base z/Architecture: |// Instructions used that are not in base z/Architecture:
|// clfi (compare logical immediate) [requires z9-109] |// clfi (compare logical immediate) [requires z9-109]
|// ldgr (load FPR from GPR) [requires z9-109 GA3]
|// lgdr (load GPR from FPR) [requires z9-109 GA3]
|// TODO: alternative instructions? |// TODO: alternative instructions?
| |
|.arch s390x |.arch s390x
@ -283,6 +285,12 @@
| stg TMPR1, DISPATCH_GL(vmstate)(DISPATCH) | stg TMPR1, DISPATCH_GL(vmstate)(DISPATCH)
|.endmacro |.endmacro
| |
|// Synthesize binary floating-point constants.
|.macro bfpconst_tobit, reg, tmp // Synthesize 2^52 + 2^51.
| llihh tmp, 0x4338
| ldgr reg, tmp
|.endmacro
|
|// Move table write barrier back. Overwrites reg. |// Move table write barrier back. Overwrites reg.
|.macro barrierback, tab, reg |.macro barrierback, tab, reg
| // TODO: more efficient way? | // TODO: more efficient way?
@ -1114,9 +1122,25 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Math library ------------------------------------------------------- |//-- Math library -------------------------------------------------------
| |
|.ffunc_1 math_abs |.ffunc_1 math_abs
| lg RB, 0(BASE)
| checkint RB, >3
| lpr RB, RB; jo >2
|->fff_resbit: |->fff_resbit:
|->fff_resi: |->fff_resi:
| setint RB
|->fff_resRB: |->fff_resRB:
| lg PC, -8(BASE)
| stg RB, -16(BASE)
| j ->fff_res1
|2:
| llihh RB, 0x41e0 // 2^31
| j ->fff_resRB
|3:
| jh ->fff_fallback
| nihh RB, 0x7fff // Clear sign bit.
| lg PC, -8(BASE)
| stg RB, -16(BASE)
| j ->fff_res1
| |
|.ffunc_n math_sqrt, sqrtsd |.ffunc_n math_sqrt, sqrtsd
|->fff_resxmm0: |->fff_resxmm0:
@ -1295,6 +1319,26 @@ static void build_subroutines(BuildCtx *ctx)
| |
|.macro .ffunc_bit, name, kind, fdef |.macro .ffunc_bit, name, kind, fdef
| fdef name | fdef name
|.if kind == 2
| bfpconst_tobit f1, RB
|.endif
| lg RB, 0(BASE)
| ld f0, 0(BASE)
| checkint RB, >1
|.if kind > 0
| j >2
|.else
| j ->fff_resbit
|.endif
|1:
| jh ->fff_fallback
|.if kind < 2
| bfpconst_tobit f1, RB
|.endif
| adbr f0, f1
| lgdr RB, f0
| llgfr RB, RB
|2:
|.endmacro |.endmacro
| |
|.macro .ffunc_bit, name, kind |.macro .ffunc_bit, name, kind
@ -1302,33 +1346,81 @@ static void build_subroutines(BuildCtx *ctx)
|.endmacro |.endmacro
| |
|.ffunc_bit bit_tobit, 0 |.ffunc_bit bit_tobit, 0
| j ->fff_resbit
| |
|.macro .ffunc_bit_op, name, ins |.macro .ffunc_bit_op, name, ins
| .ffunc_bit name, 2 | .ffunc_bit name, 2
| lgr TMPR1, NARGS:RD // Save for fallback.
| sllg RD, NARGS:RD, 3(r0)
| lay RD, -16(RD, BASE)
|1:
| clgr RD, BASE
| jle ->fff_resbit
| lg RA, 0(RD)
| checkint RA, >2
| ins RB, RA
| aghi RD, -8
| j <1
|2:
| jh ->fff_fallback_bit_op
| ldgr f0, RA
| adbr f0, f1
| lgdr RA, f0
| ins RB, RA
| aghi RD, -8
| j <1
|.endmacro |.endmacro
| |
|.ffunc_bit_op bit_band, and |.ffunc_bit_op bit_band, nr
|.ffunc_bit_op bit_bor, or |.ffunc_bit_op bit_bor, or
|.ffunc_bit_op bit_bxor, xor |.ffunc_bit_op bit_bxor, xr
| |
|.ffunc_bit bit_bswap, 1 |.ffunc_bit bit_bswap, 1
| lrvr RB, RB
| j ->fff_resbit
| |
|.ffunc_bit bit_bnot, 1 |.ffunc_bit bit_bnot, 1
|->fff_resbit: | lhi TMPR2, -1
| xr RB, TMPR2 // TODO: use xilf on newer models?
| j ->fff_resbit
| |
|->fff_fallback_bit_op: |->fff_fallback_bit_op:
| lgr NARGS:RD, TMPR1 // Restore for fallback
| j ->fff_fallback
| |
|.macro .ffunc_bit_sh, name, ins |.macro .ffunc_bit_sh, name, ins
| .ffunc_bit name, 1, .ffunc_2 | .ffunc_bit name, 1, .ffunc_2
| stg r0, 0(r0) | // Note: no inline conversion from number for 2nd argument!
| stg r0, 0(r0) | lg RA, 8(BASE)
| checkint RA, ->fff_fallback
| nill RA, 0x1f // Limit shift to 5-bits.
| ins RB, r0, 0(RA) // TODO: fix shift args in DynASM.
| j ->fff_resbit
|.endmacro |.endmacro
| |
|.ffunc_bit_sh bit_lshift, shl |.ffunc_bit_sh bit_lshift, sll
|.ffunc_bit_sh bit_rshift, shr |.ffunc_bit_sh bit_rshift, srl
|.ffunc_bit_sh bit_arshift, sar |.ffunc_bit_sh bit_arshift, sra
|.ffunc_bit_sh bit_rol, rol |
|.ffunc_bit_sh bit_ror, ror |.ffunc_bit bit_rol, 1, .ffunc_2
| // Note: no inline conversion from number for 2nd argument!
| lg RA, 8(BASE)
| checkint RA, ->fff_fallback
| // Note: no need to limit rotate to 5-bits (wraps).
| rll RB, RB, 0(RA)
| j ->fff_resbit
|
|.ffunc_bit bit_ror, 1, .ffunc_2
| // Note: no inline conversion from number for 2nd argument!
| lg RA, 8(BASE)
| checkint RA, ->fff_fallback
| // TODO: shorter sequence of instructions to convert right rotate into left rotate.
| nill RA, 0x1f
| lghi TMPR2, 32
| sr TMPR2, RA
| lr RA, TMPR2
| rll RB, RB, 0(RA)
| j ->fff_resbit
| |
|//----------------------------------------------------------------------- |//-----------------------------------------------------------------------
| |