mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 00:01:21 +08:00
rs6000.md (addti3, subti3): New.
* config/rs6000/rs6000.md (addti3, subti3): New. * gcc.target/powerpc/ti_math1.c: New. * gcc.target/powerpc/ti_math2.c: New. From-SVN: r209489
This commit is contained in:
parent
40ed344a3c
commit
32337f1014
@ -1,3 +1,7 @@
|
||||
2014-04-17 Pat Haugen <pthaugen@us.ibm.com>
|
||||
|
||||
* config/rs6000/rs6000.md (addti3, subti3): New.
|
||||
|
||||
2014-04-17 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/60863
|
||||
|
@ -6534,6 +6534,49 @@
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "fpload")])
|
||||
|
||||
;; Define the TImode operations that can be done in a small number
|
||||
;; of instructions. The & constraints are to prevent the register
|
||||
;; allocator from allocating registers that overlap with the inputs
|
||||
;; (for example, having an input in 7,8 and an output in 6,7). We
|
||||
;; also allow for the output being the same as one of the inputs.
|
||||
|
||||
(define_insn "addti3"
|
||||
[(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r")
|
||||
(plus:TI (match_operand:TI 1 "gpc_reg_operand" "%r,r,0,0")
|
||||
(match_operand:TI 2 "reg_or_short_operand" "r,I,r,I")))]
|
||||
"TARGET_64BIT"
|
||||
{
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
return (GET_CODE (operands[2])) != CONST_INT
|
||||
? \"addc %L0,%L1,%L2\;adde %0,%1,%2\"
|
||||
: \"addic %L0,%L1,%2\;add%G2e %0,%1\";
|
||||
else
|
||||
return (GET_CODE (operands[2])) != CONST_INT
|
||||
? \"addc %0,%1,%2\;adde %L0,%L1,%L2\"
|
||||
: \"addic %0,%1,%2\;add%G2e %L0,%L1\";
|
||||
}
|
||||
[(set_attr "type" "two")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn "subti3"
|
||||
[(set (match_operand:TI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
|
||||
(minus:TI (match_operand:TI 1 "reg_or_short_operand" "r,I,0,r,I")
|
||||
(match_operand:TI 2 "gpc_reg_operand" "r,r,r,0,0")))]
|
||||
"TARGET_64BIT"
|
||||
{
|
||||
if (WORDS_BIG_ENDIAN)
|
||||
return (GET_CODE (operands[1]) != CONST_INT)
|
||||
? \"subfc %L0,%L2,%L1\;subfe %0,%2,%1\"
|
||||
: \"subfic %L0,%L2,%1\;subf%G1e %0,%2\";
|
||||
else
|
||||
return (GET_CODE (operands[1]) != CONST_INT)
|
||||
? \"subfc %0,%2,%1\;subfe %L0,%L2,%L1\"
|
||||
: \"subfic %0,%2,%1\;subf%G1e %L0,%L2\";
|
||||
}
|
||||
[(set_attr "type" "two")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
|
||||
;; Define the DImode operations that can be done in a small number
|
||||
;; of instructions. The & constraints are to prevent the register
|
||||
;; allocator from allocating registers that overlap with the inputs
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-04-17 Pat Haugen <pthaugen@us.ibm.com>
|
||||
|
||||
* gcc.target/powerpc/ti_math1.c: New.
|
||||
* gcc.target/powerpc/ti_math2.c: New.
|
||||
|
||||
2014-04-17 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* gnat.dg/opt34.adb: New.
|
||||
|
20
gcc/testsuite/gcc.target/powerpc/ti_math1.c
Normal file
20
gcc/testsuite/gcc.target/powerpc/ti_math1.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-final { scan-assembler-times "addc" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "adde" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "subfc" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "subfe" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "subf " } } */
|
||||
|
||||
__int128
|
||||
add_128 (__int128 *ptr, __int128 val)
|
||||
{
|
||||
return (*ptr + val);
|
||||
}
|
||||
|
||||
__int128
|
||||
sub_128 (__int128 *ptr, __int128 val)
|
||||
{
|
||||
return (*ptr - val);
|
||||
}
|
||||
|
73
gcc/testsuite/gcc.target/powerpc/ti_math2.c
Normal file
73
gcc/testsuite/gcc.target/powerpc/ti_math2.c
Normal file
@ -0,0 +1,73 @@
|
||||
/* { dg-do run { target { powerpc*-*-* && lp64 } } } */
|
||||
/* { dg-options "-O2 -fno-inline" } */
|
||||
|
||||
union U {
|
||||
__int128 i128;
|
||||
struct {
|
||||
long l1;
|
||||
long l2;
|
||||
} s;
|
||||
};
|
||||
|
||||
union U u1,u2;
|
||||
|
||||
__int128
|
||||
create_128 (long most_sig, long least_sig)
|
||||
{
|
||||
union U u;
|
||||
|
||||
#if __LITTLE_ENDIAN__
|
||||
u.s.l1 = least_sig;
|
||||
u.s.l2 = most_sig;
|
||||
#else
|
||||
u.s.l1 = most_sig;
|
||||
u.s.l2 = least_sig;
|
||||
#endif
|
||||
return u.i128;
|
||||
}
|
||||
|
||||
long most_sig (union U * u)
|
||||
{
|
||||
#if __LITTLE_ENDIAN__
|
||||
return (*u).s.l2;
|
||||
#else
|
||||
return (*u).s.l1;
|
||||
#endif
|
||||
}
|
||||
|
||||
long least_sig (union U * u)
|
||||
{
|
||||
#if __LITTLE_ENDIAN__
|
||||
return (*u).s.l1;
|
||||
#else
|
||||
return (*u).s.l2;
|
||||
#endif
|
||||
}
|
||||
|
||||
__int128
|
||||
add_128 (__int128 *ptr, __int128 val)
|
||||
{
|
||||
return (*ptr + val);
|
||||
}
|
||||
|
||||
__int128
|
||||
sub_128 (__int128 *ptr, __int128 val)
|
||||
{
|
||||
return (*ptr - val);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Do a simple add/sub to make sure carry is happening between the dwords
|
||||
and that dwords are in correct endian order. */
|
||||
u1.i128 = create_128 (1, -1);
|
||||
u2.i128 = add_128 (&u1.i128, 1);
|
||||
if ((most_sig (&u2) != 2) || (least_sig (&u2) != 0))
|
||||
__builtin_abort ();
|
||||
u2.i128 = sub_128 (&u2.i128, 1);
|
||||
if ((most_sig (&u2) != 1) || (least_sig (&u2) != -1))
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user