21164 compare+branch optimization
Richard Henderson
rth@cygnus.com
Mon Sep 29 13:04:00 GMT 1997
On the 21164, there exists a special bypass whereby logical insns
and conditional insns can dual-issue despite a data dependancy.
This is not the case with arithmetic insns.
So prefer cmpeq+bne over plus+beq, but don't needlessly reload small
integers.
r~
Mon Sep 29 12:53:41 1997 Richard Henderson <rth@cygnus.com>
* alpha.md (beq): For registers and ints 0-255, use cmpeq+bne, since
that pair will dual-issue on the 21164 and plus+beq won't.
(bne): Likewise for cmpeq+beq.
--- config/alpha/alpha.md.cmp Mon Sep 15 16:45:55 1997
+++ config/alpha/alpha.md Mon Sep 29 12:49:47 1997
@@ -2478,16 +2478,23 @@
"
{
enum machine_mode mode;
- enum rtx_code compare_code, branch_code;
+ enum rtx_code compare_code = EQ, branch_code = NE;
if (alpha_compare_fp_p)
- mode = DFmode, compare_code = EQ, branch_code = NE;
+ mode = DFmode;
else
{
- mode = DImode, compare_code = MINUS, branch_code = EQ;
- if (GET_CODE (alpha_compare_op1) == CONST_INT)
+ mode = DImode;
+ /* We want to use cmpeq/bne when we can, since there is a zero-delay
+ bypass between logicals and br/cmov on the 21164. But we don't
+ want to force valid immediate constants into registers needlessly. */
+ if (GET_CODE (alpha_compare_op1) == CONST_INT
+ && ((INTVAL (alpha_compare_op1) >= -0x8000
+ && INTVAL (alpha_compare_op1) < 0)
+ || (INTVAL (alpha_compare_op1) > 0xff
+ && INTVAL (alpha_compare_op1) < 0x8000)))
{
- compare_code = PLUS;
+ compare_code = PLUS, branch_code = EQ;
alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
}
}
@@ -2509,16 +2516,23 @@
"
{
enum machine_mode mode;
- enum rtx_code compare_code, branch_code;
+ enum rtx_code compare_code = EQ, branch_code = EQ;
if (alpha_compare_fp_p)
- mode = DFmode, compare_code = EQ, branch_code = EQ;
+ mode = DFmode;
else
{
- mode = DImode, compare_code = MINUS, branch_code = NE;
- if (GET_CODE (alpha_compare_op1) == CONST_INT)
+ mode = DImode;
+ /* We want to use cmpeq/bne when we can, since there is a zero-delay
+ bypass between logicals and br/cmov on the 21164. But we don't
+ want to force valid immediate constants into registers needlessly. */
+ if (GET_CODE (alpha_compare_op1) == CONST_INT
+ && ((INTVAL (alpha_compare_op1) >= -0x8000
+ && INTVAL (alpha_compare_op1) < 0)
+ || (INTVAL (alpha_compare_op1) > 0xff
+ && INTVAL (alpha_compare_op1) < 0x8000)))
{
- compare_code = PLUS;
+ compare_code = PLUS, branch_code = NE;
alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
}
}
More information about the Gcc
mailing list