diff options
author | Björn Gustavsson <[email protected]> | 2019-01-07 14:40:51 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-01-07 14:40:51 +0100 |
commit | 3db7e967cf21af1f42febff4293274b84c7bd6b4 (patch) | |
tree | 346ee643baaa95f78288a6a74378f2e3ce2624d0 | |
parent | 3f5c2d32d325668534beedea7d7b7accf0b30066 (diff) | |
parent | 12f831fd482b5677aff5529374b55c73757f5246 (diff) | |
download | otp-3db7e967cf21af1f42febff4293274b84c7bd6b4.tar.gz otp-3db7e967cf21af1f42febff4293274b84c7bd6b4.tar.bz2 otp-3db7e967cf21af1f42febff4293274b84c7bd6b4.zip |
Merge pull request #2059 from michalmuskala/mm/bif-microops
Use microops for BIFs
-rw-r--r-- | erts/emulator/beam/bif_instrs.tab | 101 | ||||
-rw-r--r-- | erts/emulator/beam/ops.tab | 32 |
2 files changed, 50 insertions, 83 deletions
diff --git a/erts/emulator/beam/bif_instrs.tab b/erts/emulator/beam/bif_instrs.tab index ce9e61a838..418bbe2b23 100644 --- a/erts/emulator/beam/bif_instrs.tab +++ b/erts/emulator/beam/bif_instrs.tab @@ -58,103 +58,70 @@ CALL_GUARD_BIF(BF, TmpReg, Dst) { } } -// Guard BIF in head. On failure, ignore the error and jump -// to the code for the next clause. We don't support tracing +// Guard BIF in head. On failure, ignore the error and jump +// to the code for the next clause. We don't support tracing // of guard BIFs. -i_bif1(Fail, Bif, Src, Dst) { +i_bif1 := i_bif.fetch0.call; +i_bif2 := i_bif.fetch1.fetch0.call; +i_bif3 := i_bif.fetch2.fetch1.fetch0.call; + +i_bif.head() { ErtsBifFunc bf; - Eterm tmp_reg[1]; + Eterm tmp_reg[3]; +} +i_bif.fetch0(Src) { tmp_reg[0] = $Src; - bf = (BifFunction) $Bif; - $CALL_GUARD_BIF(bf, tmp_reg, $Dst); - - $FAIL($Fail); } -// -// Guard BIF in body. It can fail like any BIF. No trace support. -// +i_bif.fetch1(Src) { + tmp_reg[1] = $Src; +} -i_bif1_body(Bif, Src, Dst) { - ErtsBifFunc bf; - Eterm tmp_reg[1]; +i_bif.fetch2(Src) { + tmp_reg[2] = $Src; +} - tmp_reg[0] = $Src; +i_bif.call(Fail, Bif, Dst) { bf = (BifFunction) $Bif; $CALL_GUARD_BIF(bf, tmp_reg, $Dst); - reg[0] = tmp_reg[0]; - SWAPOUT; - I = handle_error(c_p, I, reg, ubif2mfa((void *) bf)); - goto post_error_handling; -} - -// -// Guard bif in guard with two arguments ('and'/2, 'or'/2, 'xor'/2). -// - -i_bif2(Fail, Bif, Src1, Src2, Dst) { - Eterm tmp_reg[2]; - ErtsBifFunc bf; - - tmp_reg[0] = $Src1; - tmp_reg[1] = $Src2; - bf = (ErtsBifFunc) $Bif; - $CALL_GUARD_BIF(bf, tmp_reg, $Dst); $FAIL($Fail); } // -// Guard bif in body with two arguments ('and'/2, 'or'/2, 'xor'/2). +// Guard BIF in body. It can fail like any BIF. No trace support. // -i_bif2_body(Bif, Src1, Src2, Dst) { - Eterm tmp_reg[2]; - ErtsBifFunc bf; - - tmp_reg[0] = $Src1; - tmp_reg[1] = $Src2; - bf = (ErtsBifFunc) $Bif; - $CALL_GUARD_BIF(bf, tmp_reg, $Dst); - reg[0] = tmp_reg[0]; - reg[1] = tmp_reg[1]; - SWAPOUT; - I = handle_error(c_p, I, reg, ubif2mfa((void *) bf)); - goto post_error_handling; -} - -// Guard BIF in head (binary_part/3). On failure, ignore the error -// and jump to the code for the next clause. We don't support tracing -// of guard BIFs. +i_bif1_body := i_bif_body.fetch0.call; +i_bif2_body := i_bif_body.fetch1.fetch0.call; +i_bif3_body := i_bif_body.fetch2.fetch1.fetch0.call; -i_bif3(Fail, Bif, Src1, Src2, Src3, Dst) { +i_bif_body.head() { ErtsBifFunc bf; Eterm tmp_reg[3]; +} - tmp_reg[0] = $Src1; - tmp_reg[1] = $Src2; - tmp_reg[2] = $Src3; - bf = (BifFunction) $Bif; - $CALL_GUARD_BIF(bf, tmp_reg, $Dst); - - $FAIL($Fail); +i_bif_body.fetch0(Src) { + tmp_reg[0] = $Src; } -// Guard BIF in body with three arguments (binary_part/3). +i_bif_body.fetch1(Src) { + tmp_reg[1] = $Src; +} -i_bif3_body(Bif, Src1, Src2, Src3, Dst) { - ErtsBifFunc bf; - Eterm tmp_reg[3]; +i_bif_body.fetch2(Src) { + tmp_reg[2] = $Src; +} - tmp_reg[0] = $Src1; - tmp_reg[1] = $Src2; - tmp_reg[2] = $Src3; +i_bif_body.call(Bif, Dst) { bf = (BifFunction) $Bif; $CALL_GUARD_BIF(bf, tmp_reg, $Dst); + reg[0] = tmp_reg[0]; reg[1] = tmp_reg[1]; + reg[2] = tmp_reg[2]; SWAPOUT; I = handle_error(c_p, I, reg, ubif2mfa((void *) bf)); goto post_error_handling; diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index cb414143fc..ee99c9e563 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -1002,11 +1002,11 @@ bif1 Fail Bif=u$bif:erlang:get/1 Src=s Dst=d => gen_get(Src, Dst) bif2 Jump=j u$bif:erlang:element/2 S1=s S2=xy Dst=d => gen_element(Jump, S1, S2, Dst) -bif1 p Bif S1 Dst => i_bif1_body Bif S1 Dst -bif1 Fail=f Bif S1 Dst => i_bif1 Fail Bif S1 Dst +bif1 p Bif S1 Dst => i_bif1_body S1 Bif Dst +bif1 Fail=f Bif S1 Dst => i_bif1 S1 Fail Bif Dst -bif2 p Bif S1 S2 Dst => i_bif2_body Bif S1 S2 Dst -bif2 Fail=f Bif S1 S2 Dst => i_bif2 Fail Bif S1 S2 Dst +bif2 p Bif S1 S2 Dst => i_bif2_body S2 S1 Bif Dst +bif2 Fail=f Bif S1 S2 Dst => i_bif2 S2 S1 Fail Bif Dst i_get_hash c I d i_get s d @@ -1024,12 +1024,12 @@ i_fast_element xy j? I d i_element xy j? s d -i_bif1 f? b s d -i_bif1_body b s d -i_bif2 f? b s s d -i_bif2_body b s s d -i_bif3 f? b s s s d -i_bif3_body b s s s d +i_bif1 s f? b d +i_bif1_body s b d +i_bif2 s s f? b d +i_bif2_body s s b d +i_bif3 s s s f? b d +i_bif3_body s s s b d # # Internal calls. @@ -1601,14 +1601,14 @@ i_length j? t d # # Guard BIFs. # -gc_bif1 p Live Bif Src Dst => i_bif1_body Bif Src Dst -gc_bif1 Fail=f Live Bif Src Dst => i_bif1 Fail Bif Src Dst +gc_bif1 p Live Bif Src Dst => i_bif1_body Src Bif Dst +gc_bif1 Fail=f Live Bif Src Dst => i_bif1 Src Fail Bif Dst -gc_bif2 p Live Bif S1 S2 Dst => i_bif2_body Bif S1 S2 Dst -gc_bif2 Fail=f Live Bif S1 S2 Dst => i_bif2 Fail Bif S1 S2 Dst +gc_bif2 p Live Bif S1 S2 Dst => i_bif2_body S2 S1 Bif Dst +gc_bif2 Fail=f Live Bif S1 S2 Dst => i_bif2 S2 S1 Fail Bif Dst -gc_bif3 p Live Bif S1 S2 S3 Dst => i_bif3_body Bif S1 S2 S3 Dst -gc_bif3 Fail=f Live Bif S1 S2 S3 Dst => i_bif3 Fail Bif S1 S2 S3 Dst +gc_bif3 p Live Bif S1 S2 S3 Dst => i_bif3_body S3 S2 S1 Bif Dst +gc_bif3 Fail=f Live Bif S1 S2 S3 Dst => i_bif3 S3 S2 S1 Fail Bif Dst # # The following instruction is specially handled in beam_load.c |