Commit a01be1ae by Ian Bolton Committed by Ian Bolton

Optimise NotDI AND/OR ZeroExtendSI for ARMv7A

[gcc]
	* config/arm/arm.md (*anddi_notdi_zesidi): New pattern.
	* config/arm/thumb2.md (*iordi_notdi_zesidi): New pattern.

[gcc/testsuite]
	* gcc.target/arm/anddi_notdi-1.c: New test.
	* gcc.target/arm/iordi_notdi-1.c: New test case.

From-SVN: r209614
parent 80d3417b
2014-04-22 Ian Bolton <ian.bolton@arm.com> 2014-04-22 Ian Bolton <ian.bolton@arm.com>
* config/arm/arm.md (*anddi_notdi_zesidi): New pattern.
* config/arm/thumb2.md (*iordi_notdi_zesidi): New pattern.
2014-04-22 Ian Bolton <ian.bolton@arm.com>
* config/arm/thumb2.md (*iordi_notdi_di): New pattern. * config/arm/thumb2.md (*iordi_notdi_di): New pattern.
(*iordi_notzesidi_di): Likewise. (*iordi_notzesidi_di): Likewise.
(*iordi_notsesidi_di): Likewise. (*iordi_notsesidi_di): Likewise.
......
...@@ -2863,6 +2863,28 @@ ...@@ -2863,6 +2863,28 @@
(set_attr "type" "multiple")] (set_attr "type" "multiple")]
) )
(define_insn_and_split "*anddi_notdi_zesidi"
[(set (match_operand:DI 0 "s_register_operand" "=r")
(and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
(zero_extend:DI
(match_operand:SI 1 "s_register_operand" "r"))))]
"TARGET_32BIT"
"#"
"TARGET_32BIT && reload_completed"
[(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
(set (match_dup 3) (const_int 0))]
"
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type" "multiple")]
)
(define_insn_and_split "*anddi_notsesidi_di" (define_insn_and_split "*anddi_notsesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (not:DI (sign_extend:DI (and:DI (not:DI (sign_extend:DI
......
...@@ -1418,6 +1418,30 @@ ...@@ -1418,6 +1418,30 @@
(set_attr "type" "multiple")] (set_attr "type" "multiple")]
) )
(define_insn_and_split "*iordi_notdi_zesidi"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
(zero_extend:DI
(match_operand:SI 1 "s_register_operand" "r,r"))))]
"TARGET_THUMB2"
"#"
"TARGET_THUMB2 && reload_completed"
[(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
(set (match_dup 3) (not:SI (match_dup 4)))]
"
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[4] = gen_highpart (SImode, operands[2]);
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type" "multiple")]
)
(define_insn_and_split "*iordi_notsesidi_di" (define_insn_and_split "*iordi_notsesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (not:DI (sign_extend:DI (ior:DI (not:DI (sign_extend:DI
......
2014-04-22 Ian Bolton <ian.bolton@arm.com> 2014-04-22 Ian Bolton <ian.bolton@arm.com>
* gcc.target/arm/anddi_notdi-1.c: New test.
* gcc.target/arm/iordi_notdi-1.c: New test case.
2014-04-22 Ian Bolton <ian.bolton@arm.com>
* gcc.target/arm/iordi_notdi-1.c: New test. * gcc.target/arm/iordi_notdi-1.c: New test.
2014-04-22 Alex Velenko <Alex.Velenko@arm.com> 2014-04-22 Alex Velenko <Alex.Velenko@arm.com>
......
/* { dg-do run } */
/* { dg-options "-O2 -fno-inline --save-temps" } */
extern void abort (void);
typedef long long s64int;
typedef int s32int;
typedef unsigned long long u64int;
typedef unsigned int u32int;
s64int
anddi_di_notdi (s64int a, s64int b)
{
return (a & ~b);
}
s64int
anddi_di_notzesidi (s64int a, u32int b)
{
return (a & ~(u64int) b);
}
s64int
anddi_notdi_zesidi (s64int a, u32int b)
{
return (~a & (u64int) b);
}
s64int
anddi_di_notsesidi (s64int a, s32int b)
{
return (a & ~(s64int) b);
}
int main ()
{
s64int a64 = 0xdeadbeef0000ffffll;
s64int b64 = 0x000000005f470112ll;
s64int c64 = 0xdeadbeef300f0000ll;
u32int c32 = 0x01124f4f;
s32int d32 = 0xabbaface;
s64int z = anddi_di_notdi (c64, b64);
if (z != 0xdeadbeef20080000ll)
abort ();
z = anddi_di_notzesidi (a64, c32);
if (z != 0xdeadbeef0000b0b0ll)
abort ();
z = anddi_notdi_zesidi (c64, c32);
if (z != 0x0000000001104f4fll)
abort ();
z = anddi_di_notsesidi (a64, d32);
if (z != 0x0000000000000531ll)
abort ();
return 0;
}
/* { dg-final { scan-assembler-times "bic\t" 6 } } */
/* { dg-final { cleanup-saved-temps } } */
...@@ -9,19 +9,25 @@ typedef unsigned long long u64int; ...@@ -9,19 +9,25 @@ typedef unsigned long long u64int;
typedef unsigned int u32int; typedef unsigned int u32int;
s64int s64int
iordi_notdi (s64int a, s64int b) iordi_di_notdi (s64int a, s64int b)
{ {
return (a | ~b); return (a | ~b);
} }
s64int s64int
iordi_notzesidi (s64int a, u32int b) iordi_di_notzesidi (s64int a, u32int b)
{ {
return (a | ~(u64int) b); return (a | ~(u64int) b);
} }
s64int s64int
iordi_notsesidi (s64int a, s32int b) iordi_notdi_zesidi (s64int a, u32int b)
{
return (~a | (u64int) b);
}
s64int
iordi_di_notsesidi (s64int a, s32int b)
{ {
return (a | ~(s64int) b); return (a | ~(s64int) b);
} }
...@@ -30,25 +36,30 @@ int main () ...@@ -30,25 +36,30 @@ int main ()
{ {
s64int a64 = 0xdeadbeef00000000ll; s64int a64 = 0xdeadbeef00000000ll;
s64int b64 = 0x000000004f4f0112ll; s64int b64 = 0x000000004f4f0112ll;
s64int c64 = 0xdeadbeef000f0000ll;
u32int c32 = 0x01124f4f; u32int c32 = 0x01124f4f;
s32int d32 = 0xabbaface; s32int d32 = 0xabbaface;
s64int z = iordi_notdi (a64, b64); s64int z = iordi_di_notdi (a64, b64);
if (z != 0xffffffffb0b0feedll) if (z != 0xffffffffb0b0feedll)
abort (); abort ();
z = iordi_notzesidi (a64, c32); z = iordi_di_notzesidi (a64, c32);
if (z != 0xfffffffffeedb0b0ll) if (z != 0xfffffffffeedb0b0ll)
abort (); abort ();
z = iordi_notsesidi (a64, d32); z = iordi_notdi_zesidi (c64, c32);
if (z != 0x21524110fff2ffffll)
abort ();
z = iordi_di_notsesidi (a64, d32);
if (z != 0xdeadbeef54450531ll) if (z != 0xdeadbeef54450531ll)
abort (); abort ();
return 0; return 0;
} }
/* { dg-final { scan-assembler-times "orn\t" 5 { target arm_thumb2 } } } */ /* { dg-final { scan-assembler-times "orn\t" 6 { target arm_thumb2 } } } */
/* { dg-final { cleanup-saved-temps } } */ /* { dg-final { cleanup-saved-temps } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment