aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2015-04-22 20:44:43 +0200
committerBjörn-Egil Dahlberg <[email protected]>2015-04-23 14:37:32 +0200
commitd1321eaf9bd1e417561e3d70fd85749fe589143b (patch)
tree496c17fc81c8f98aa8ef6abfc9c068cb9934adf0 /erts
parent63949dcd13e24bdc73336b0f5e88d4f06cce56c1 (diff)
downloadotp-d1321eaf9bd1e417561e3d70fd85749fe589143b.tar.gz
otp-d1321eaf9bd1e417561e3d70fd85749fe589143b.tar.bz2
otp-d1321eaf9bd1e417561e3d70fd85749fe589143b.zip
erts: Add move window instruction
Move an entire region of x registers to the stack. This reduces the dispatch pressure of move instructions. Also introduce a move2 specialization for some common move patterns: move r y | move x y -> move2 : As above, moving regions to the stack move x r | move x y -> move2 : A seemingly common pattern
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/beam/beam_emu.c34
-rw-r--r--erts/emulator/beam/ops.tab37
2 files changed, 71 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 8b9e271068..b9b2094e6c 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1503,6 +1503,40 @@ void process_main(void)
Next(2);
}
+ OpCase(move_window3_xxxy): {
+ BeamInstr *next;
+ Eterm *y;
+ PreFetch(4, next);
+ y = (Eterm *)(((unsigned char *)E) + (Arg(3)));
+ y[0] = xb(Arg(0));
+ y[1] = xb(Arg(1));
+ y[2] = xb(Arg(2));
+ NextPF(4, next);
+ }
+ OpCase(move_window4_xxxxy): {
+ BeamInstr *next;
+ Eterm *y;
+ PreFetch(5, next);
+ y = (Eterm *)(((unsigned char *)E) + (Arg(4)));
+ y[0] = xb(Arg(0));
+ y[1] = xb(Arg(1));
+ y[2] = xb(Arg(2));
+ y[3] = xb(Arg(3));
+ NextPF(5, next);
+ }
+ OpCase(move_window5_xxxxxy): {
+ BeamInstr *next;
+ Eterm *y;
+ PreFetch(6, next);
+ y = (Eterm *)(((unsigned char *)E) + (Arg(5)));
+ y[0] = xb(Arg(0));
+ y[1] = xb(Arg(1));
+ y[2] = xb(Arg(2));
+ y[3] = xb(Arg(3));
+ y[4] = xb(Arg(4));
+ NextPF(6, next);
+ }
+
OpCase(i_move_call_only_fcr): {
r(0) = Arg(1);
}
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 66339f8ace..3f7e69e07e 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -298,12 +298,44 @@ move_jump f c
move_jump f x
move_jump f y
+
+# Movement to and from the stack is common
+# Try to pack as much as we can into one instruction
+
+# Window move
+move_window/5
+move_window/6
+
+# x -> y
+
+move S1=r S2=y | move X1=x Y1=y => move2 S1 S2 X1 Y1
+
+move X1=x Y1=y | move X2=x Y2=y | move X3=x Y3=y | succ(Y1,Y2) | succ(Y2,Y3) => \
+ move_window X1 X2 X3 Y1 Y3
+
+move_window X1=x X2=x X3=x Y1=y Y3=y | move X4=x Y4=y | succ(Y3,Y4) => \
+ move_window X1 X2 X3 X4 Y1 Y4
+
+move_window X1=x X2=x X3=x X4=x Y1=y Y4=y | move X5=x Y5=y | succ(Y4,Y5) => \
+ move_window5 X1 X2 X3 X4 X5 Y1
+
+move_window X1=x X2=x X3=x Y1=y Y3=y => move_window3 X1 X2 X3 Y1
+move_window X1=x X2=x X3=x X4=x Y1=y Y4=y => move_window4 X1 X2 X3 X4 Y1
+
+move_window3 x x x y
+move_window4 x x x x y
+move_window5 x x x x x y
+
move X1=x Y1=y | move X2=x Y2=y => move2 X1 Y1 X2 Y2
move Y1=y X1=x | move Y2=y X2=x => move2 Y1 X1 Y2 X2
move X1=x X2=x | move X3=x X4=x => move2 X1 X2 X3 X4
+move S1=x S2=r | move X1=x Y1=y => move2 S1 S2 X1 Y1
+move S1=y S2=r | move X1=x Y1=y => move2 S1 S2 X1 Y1
+
move2 X1=x Y1=y X2=x Y2=y | move X3=x Y3=y => move3 X1 Y1 X2 Y2 X3 Y3
move2 Y1=y X1=x Y2=y X2=x | move Y3=y X3=x => move3 Y1 X1 Y2 X2 Y3 X3
+move2 X1=x X2=x X3=x X4=x | move X5=x X6=x => move3 X1 X2 X3 X4 X5 X6
move C=aiq X=x==1 => move_x1 C
move C=aiq X=x==2 => move_x2 C
@@ -316,6 +348,11 @@ move2 x y x y
move2 y x y x
move2 x x x x
+move2 x r x y
+move2 r y x y
+move2 y r x y
+
+
%macro: move3 Move3
move3 x y x y x y
move3 y x y x y x