From 177d20a7329d24aec0f4a0cbbbd3fc803bcbba4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Fri, 17 Apr 2015 11:04:09 +0200 Subject: erts: Specialize compare instructions * i_is_lt for r, x registers and constants * i_is_ge for x registers and constants * i_is_exact_eq for r and x registers --- erts/emulator/beam/beam_emu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'erts/emulator/beam/beam_emu.c') diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index bb7b799950..aad76e9a93 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -662,6 +662,9 @@ void** beam_ops; #define EqualImmed(X, Y, Action) if (X != Y) { Action; } #define NotEqualImmed(X, Y, Action) if (X == Y) { Action; } +#define EqualExact(X, Y, Action) if (!EQ(X,Y)) { Action; } +#define IsLessThan(X, Y, Action) if (CMP_GE(X, Y)) { Action; } +#define IsGreaterEqual(X, Y, Action) if (CMP_LT(X, Y)) { Action; } #define IsFloat(Src, Fail) if (is_not_float(Src)) { Fail; } -- cgit v1.2.3 From 63949dcd13e24bdc73336b0f5e88d4f06cce56c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Mon, 15 Sep 2014 17:58:33 +0200 Subject: erts: Add instruction move3 for xy and xx --- erts/emulator/beam/beam_emu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam/beam_emu.c') diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index aad76e9a93..8b9e271068 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -562,7 +562,8 @@ void** beam_ops; Store(term, Dst); \ } while (0) -#define Move2(src1, dst1, src2, dst2) dst1 = (src1); dst2 = (src2) +#define Move2(S1, D1, S2, D2) D1 = (S1); D2 = (S2) +#define Move3(S1, D1, S2, D2, S3, D3) D1 = (S1); D2 = (S2); D3 = (S3) #define MoveGenDest(src, dstp) \ if ((dstp) == NULL) { r(0) = (src); } else { *(dstp) = src; } -- cgit v1.2.3 From d1321eaf9bd1e417561e3d70fd85749fe589143b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 22 Apr 2015 20:44:43 +0200 Subject: 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 --- erts/emulator/beam/beam_emu.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'erts/emulator/beam/beam_emu.c') 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); } -- cgit v1.2.3 From 38384c6c5f66cf52d24ae6f48cc71bbe52611aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 23 Apr 2015 17:24:18 +0200 Subject: erts: Batch loads and stores for move_window May lessen load/store latency. --- erts/emulator/beam/beam_emu.c | 48 +++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'erts/emulator/beam/beam_emu.c') diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index b9b2094e6c..beec8967fc 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1505,35 +1505,47 @@ void process_main(void) OpCase(move_window3_xxxy): { BeamInstr *next; - Eterm *y; + Eterm xt0, xt1, xt2; + Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(3))); 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)); + xt0 = xb(Arg(0)); + xt1 = xb(Arg(1)); + xt2 = xb(Arg(2)); + y[0] = xt0; + y[1] = xt1; + y[2] = xt2; NextPF(4, next); } OpCase(move_window4_xxxxy): { BeamInstr *next; - Eterm *y; + Eterm xt0, xt1, xt2, xt3; + Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(4))); 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)); + xt0 = xb(Arg(0)); + xt1 = xb(Arg(1)); + xt2 = xb(Arg(2)); + xt3 = xb(Arg(3)); + y[0] = xt0; + y[1] = xt1; + y[2] = xt2; + y[3] = xt3; NextPF(5, next); } OpCase(move_window5_xxxxxy): { BeamInstr *next; - Eterm *y; + Eterm xt0, xt1, xt2, xt3, xt4; + Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(5))); 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)); + xt0 = xb(Arg(0)); + xt1 = xb(Arg(1)); + xt2 = xb(Arg(2)); + xt3 = xb(Arg(3)); + xt4 = xb(Arg(4)); + y[0] = xt0; + y[1] = xt1; + y[2] = xt2; + y[3] = xt3; + y[4] = xt4; NextPF(6, next); } -- cgit v1.2.3 From 699ad918545ac7e716b77ea05a6a943434616020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 23 Apr 2015 19:06:03 +0200 Subject: erts: Specialize band instruction for common case * i_band specialization on x registers and constants --- erts/emulator/beam/beam_emu.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'erts/emulator/beam/beam_emu.c') 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; -- cgit v1.2.3 From b58b4718012cfb848dad3106b2ab22c08997c639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 23 Apr 2015 19:21:34 +0200 Subject: erts: Specialize rem instruction for common case * i_rem specialization on x registers --- erts/emulator/beam/beam_emu.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'erts/emulator/beam/beam_emu.c') diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index aca340db6b..f369d7b632 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -2902,6 +2902,19 @@ do { \ goto lb_Cl_error; \ } while(0) + OpCase(i_rem_jIxxd): + { + Eterm result; + + if (xb(Arg(3)) == SMALL_ZERO) { + goto badarith; + } else if (is_both_small(xb(Arg(2)), xb(Arg(3)))) { + result = make_small(signed_val(xb(Arg(2))) % signed_val(xb(Arg(3)))); + StoreBifResult(4, result); + } + DO_BIG_ARITH(ARITH_FUNC(int_rem),xb(Arg(2)),xb(Arg(3))); + } + OpCase(i_rem_jId): { Eterm result; -- cgit v1.2.3 From 979d05fc326d0f6cf7c1c4a5182bb33942852dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Fri, 24 Apr 2015 17:42:24 +0200 Subject: erts: Specialize minus and plus instruction Seen on SSL application where substraction with x registers were prevalent: * i_minus specialization on x registers * i_plus specialization on x registers --- erts/emulator/beam/beam_emu.c | 71 ++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 21 deletions(-) (limited to 'erts/emulator/beam/beam_emu.c') diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index f369d7b632..7dd7250e2f 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1393,7 +1393,39 @@ void process_main(void) ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue)); goto find_func_info; } - + +#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_plus_jIxxd): + { + Eterm result; + + if (is_both_small(xb(Arg(2)), xb(Arg(3)))) { + Sint i = signed_val(xb(Arg(2))) + signed_val(xb(Arg(3))); + ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i)); + if (MY_IS_SSMALL(i)) { + result = make_small(i); + StoreBifResult(4, result); + } + } + DO_BIG_ARITH(ARITH_FUNC(mixed_plus), xb(Arg(2)), xb(Arg(3))); + } + OpCase(i_plus_jId): { Eterm result; @@ -1405,12 +1437,26 @@ void process_main(void) result = make_small(i); STORE_ARITH_RESULT(result); } - } arith_func = ARITH_FUNC(mixed_plus); goto do_big_arith2; } + OpCase(i_minus_jIxxd): + { + Eterm result; + + if (is_both_small(xb(Arg(2)), xb(Arg(3)))) { + Sint i = signed_val(xb(Arg(2))) - signed_val(xb(Arg(3))); + ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i)); + if (MY_IS_SSMALL(i)) { + result = make_small(i); + StoreBifResult(4, result); + } + } + DO_BIG_ARITH(ARITH_FUNC(mixed_minus), xb(Arg(2)), xb(Arg(3))); + } + OpCase(i_minus_jId): { Eterm result; @@ -2885,23 +2931,6 @@ 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_jIxxd): { Eterm result; @@ -2944,8 +2973,6 @@ do { \ DO_BIG_ARITH(ARITH_FUNC(band),xb(Arg(2)),Arg(3)); } -#undef DO_BIG_ARITH - OpCase(i_band_jId): { Eterm result; @@ -2961,6 +2988,8 @@ do { \ goto do_big_arith2; } +#undef DO_BIG_ARITH + do_big_arith2: { Eterm result; -- cgit v1.2.3