[aarch64-port-dev ] RFR: Minor optimisation for divide by 2
Edward Nevill
edward.nevill at linaro.org
Tue Apr 29 09:16:44 UTC 2014
Hi,
C2 currently generates
mov rdst, rsrc, asr #31
mov rdst, rdst, lsr #31
add rdst, rsrc, rdst
mov rdst, rdst, asr #1
for divide by 2. The following patch reduces this to
add rdst, rsrc, rsrc, lsr #31
mov rdst, rdst, asr #1
I know this is very minor, but it offends me:-)
OK?
Ed.
--- CUT HERE ---
# HG changeset patch
# User Edward Nevill edward.nevill at linaro.org
# Date 1398762402 -3600
# Tue Apr 29 10:06:42 2014 +0100
# Node ID 7f9ab7b86d7a690e04ffc6331c2b9519aae2a565
# Parent d9468835bc5160b7fac6709b0afbc751b2159fbb
Minor optimisation for divide by 2
diff -r d9468835bc51 -r 7f9ab7b86d7a src/cpu/aarch64/vm/aarch64.ad
--- a/src/cpu/aarch64/vm/aarch64.ad Thu Apr 10 06:50:43 2014 -0400
+++ b/src/cpu/aarch64/vm/aarch64.ad Tue Apr 29 10:06:42 2014 +0100
@@ -3356,6 +3356,16 @@
interface(CONST_INTER);
%}
+operand immI_31()
+%{
+ predicate(n->get_int() == 31);
+ match(ConI);
+
+ op_cost(0);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
operand immI_8()
%{
predicate(n->get_int() == 8);
@@ -7274,6 +7284,30 @@
ins_pipe(pipe_class_default);
%}
+instruct signExtract(iRegINoSp dst, iRegI src, immI_31 div1, immI_31 div2) %{
+ match(Set dst (URShiftI (RShiftI src div1) div2));
+ ins_cost(INSN_COST);
+ format %{ "lsrw $dst, $src, $div1" %}
+ ins_encode %{
+ __ lsrw(as_Register($dst$$reg), as_Register($src$$reg), 31);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+instruct div2Round(iRegINoSp dst, iRegI src, immI_31 div1, immI_31 div2) %{
+ match(Set dst (AddI src (URShiftI (RShiftI src div1) div2)));
+ ins_cost(INSN_COST);
+ format %{ "addw $dst, $src, $div1" %}
+
+ ins_encode %{
+ __ addw(as_Register($dst$$reg),
+ as_Register($src$$reg),
+ as_Register($src$$reg),
+ Assembler::LSR, 31);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
// Long Divide
instruct divL(iRegLNoSp dst, iRegL src1, iRegL src2) %{
--- CUT HERE ---
More information about the aarch64-port-dev
mailing list