diff options
author | Michał Muskała <[email protected]> | 2018-12-13 16:26:11 +0100 |
---|---|---|
committer | Michał Muskała <[email protected]> | 2018-12-17 13:25:28 +0100 |
commit | 12f831fd482b5677aff5529374b55c73757f5246 (patch) | |
tree | 83ce66fa3c10a8ada16cea2b7db6c0045df18387 /erts/emulator/beam/bif_instrs.tab | |
parent | 472b0669788e155f28851999b4e60bf8302ca2d5 (diff) | |
download | otp-12f831fd482b5677aff5529374b55c73757f5246.tar.gz otp-12f831fd482b5677aff5529374b55c73757f5246.tar.bz2 otp-12f831fd482b5677aff5529374b55c73757f5246.zip |
Use microops for BIFs
This allows bif1/2/3 to share the main part of the code.
The price is that we always need to copy all three temporary registers
when error handling in bodies, but that should be infrequent.
Additionally it makes it a bit harder to read the disasembly since now
the arguments to BIFs are in the reverse order.
Diffstat (limited to 'erts/emulator/beam/bif_instrs.tab')
-rw-r--r-- | erts/emulator/beam/bif_instrs.tab | 101 |
1 files changed, 34 insertions, 67 deletions
diff --git a/erts/emulator/beam/bif_instrs.tab b/erts/emulator/beam/bif_instrs.tab index 3abd062552..99abe662d5 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; |