aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2015-04-23 19:06:03 +0200
committerBjörn-Egil Dahlberg <[email protected]>2015-04-24 10:06:17 +0200
commit699ad918545ac7e716b77ea05a6a943434616020 (patch)
treebbde991f143318be7a3ab4c98b72b0c479d37342 /erts
parent38384c6c5f66cf52d24ae6f48cc71bbe52611aa9 (diff)
downloadotp-699ad918545ac7e716b77ea05a6a943434616020.tar.gz
otp-699ad918545ac7e716b77ea05a6a943434616020.tar.bz2
otp-699ad918545ac7e716b77ea05a6a943434616020.zip
erts: Specialize band instruction for common case
* i_band specialization on x registers and constants
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/beam/beam_emu.c33
-rw-r--r--erts/emulator/beam/ops.tab2
2 files changed, 35 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index beec8967fc..aca340db6b 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -2885,6 +2885,23 @@ do { \
goto do_big_arith2;
}
+#define DO_BIG_ARITH(Func,Arg1,Arg2) \
+ do { \
+ Uint live = Arg(1); \
+ SWAPOUT; \
+ reg[0] = r(0); \
+ reg[live] = (Arg1); \
+ reg[live+1] = (Arg2); \
+ result = (Func)(c_p, reg, live); \
+ r(0) = reg[0]; \
+ SWAPIN; \
+ ERTS_HOLE_CHECK(c_p); \
+ if (is_value(result)) { \
+ StoreBifResult(4,result); \
+ } \
+ goto lb_Cl_error; \
+ } while(0)
+
OpCase(i_rem_jId):
{
Eterm result;
@@ -2900,6 +2917,22 @@ do { \
}
}
+ OpCase(i_band_jIxcd):
+ {
+ Eterm result;
+
+ if (is_both_small(xb(Arg(2)), Arg(3))) {
+ /*
+ * No need to untag -- TAG & TAG == TAG.
+ */
+ result = xb(Arg(2)) & Arg(3);
+ StoreBifResult(4, result);
+ }
+ DO_BIG_ARITH(ARITH_FUNC(band),xb(Arg(2)),Arg(3));
+ }
+
+#undef DO_BIG_ARITH
+
OpCase(i_band_jId):
{
Eterm result;
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 3f7e69e07e..3436b664d9 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -1663,6 +1663,7 @@ gc_bif2 Fail I u$bif:erlang:rem/2 S1 S2 Dst=d => i_fetch S1 S2 | i_rem Fail I Ds
gc_bif2 Fail I u$bif:erlang:bsl/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bsl Fail I Dst
gc_bif2 Fail I u$bif:erlang:bsr/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bsr Fail I Dst
+gc_bif2 Fail I u$bif:erlang:band/2 S1=x S2=c Dst=d => i_band Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:band/2 S1 S2 Dst=d => i_fetch S1 S2 | i_band Fail I Dst
gc_bif2 Fail I u$bif:erlang:bor/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bor Fail I Dst
gc_bif2 Fail I u$bif:erlang:bxor/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bxor Fail I Dst
@@ -1686,6 +1687,7 @@ i_rem j I d
i_bsl j I d
i_bsr j I d
+i_band j I x c d
i_band j I d
i_bor j I d
i_bxor j I d