diff options
author | Björn-Egil Dahlberg <[email protected]> | 2015-04-22 20:44:43 +0200 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2015-04-23 14:37:32 +0200 |
commit | d1321eaf9bd1e417561e3d70fd85749fe589143b (patch) | |
tree | 496c17fc81c8f98aa8ef6abfc9c068cb9934adf0 /erts | |
parent | 63949dcd13e24bdc73336b0f5e88d4f06cce56c1 (diff) | |
download | otp-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.c | 34 | ||||
-rw-r--r-- | erts/emulator/beam/ops.tab | 37 |
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 |