mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
AVR: target/87376 - Use nop_general_operand for DImode inputs.
The avr-dimode.md expanders have code like emit_move_insn(acc_a, operands[1])
where acc_a is a hard register and operands[1] might be a non-generic
address-space memory reference. Such loads may clobber hard regs since
some of them are implemented as libgcc calls /and/ 64-moves are
expanded as eight byte-moves, so that acc_a or acc_b might be clobbered
by such a load.
This patch simply denies non-generic address-space references by using
nop_general_operand for all avr-dimode.md input predicates.
With the patch, all memory loads that require library calls are issued
before the expander codes from avr-dimode.md are run.
PR target/87376
gcc/
* config/avr/avr-dimode.md: Use "nop_general_operand" instead
of "general_operand" as predicate for all input operands.
gcc/testsuite/
* gcc.target/avr/torture/pr87376.c: New test.
(cherry picked from commit 23a0935262
)
This commit is contained in:
parent
92a6ff14c4
commit
5f4a60c43d
@ -62,8 +62,8 @@
|
||||
;; "addta3" "adduta3"
|
||||
(define_expand "add<mode>3"
|
||||
[(parallel [(match_operand:ALL8 0 "general_operand" "")
|
||||
(match_operand:ALL8 1 "general_operand" "")
|
||||
(match_operand:ALL8 2 "general_operand" "")])]
|
||||
(match_operand:ALL8 1 "nop_general_operand")
|
||||
(match_operand:ALL8 2 "nop_general_operand")])]
|
||||
"avr_have_dimode"
|
||||
{
|
||||
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
|
||||
@ -178,8 +178,8 @@
|
||||
;; "subta3" "subuta3"
|
||||
(define_expand "sub<mode>3"
|
||||
[(parallel [(match_operand:ALL8 0 "general_operand" "")
|
||||
(match_operand:ALL8 1 "general_operand" "")
|
||||
(match_operand:ALL8 2 "general_operand" "")])]
|
||||
(match_operand:ALL8 1 "nop_general_operand")
|
||||
(match_operand:ALL8 2 "nop_general_operand")])]
|
||||
"avr_have_dimode"
|
||||
{
|
||||
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
|
||||
@ -259,8 +259,8 @@
|
||||
|
||||
(define_expand "<code_stdname><mode>3"
|
||||
[(set (match_operand:ALL8S 0 "general_operand" "")
|
||||
(ss_addsub:ALL8S (match_operand:ALL8S 1 "general_operand" "")
|
||||
(match_operand:ALL8S 2 "general_operand" "")))]
|
||||
(ss_addsub:ALL8S (match_operand:ALL8S 1 "nop_general_operand")
|
||||
(match_operand:ALL8S 2 "nop_general_operand")))]
|
||||
"avr_have_dimode"
|
||||
{
|
||||
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
|
||||
@ -332,8 +332,8 @@
|
||||
|
||||
(define_expand "<code_stdname><mode>3"
|
||||
[(set (match_operand:ALL8U 0 "general_operand" "")
|
||||
(us_addsub:ALL8U (match_operand:ALL8U 1 "general_operand" "")
|
||||
(match_operand:ALL8U 2 "general_operand" "")))]
|
||||
(us_addsub:ALL8U (match_operand:ALL8U 1 "nop_general_operand")
|
||||
(match_operand:ALL8U 2 "nop_general_operand")))]
|
||||
"avr_have_dimode"
|
||||
{
|
||||
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
|
||||
@ -405,7 +405,7 @@
|
||||
|
||||
(define_expand "negdi2"
|
||||
[(parallel [(match_operand:DI 0 "general_operand" "")
|
||||
(match_operand:DI 1 "general_operand" "")])]
|
||||
(match_operand:DI 1 "nop_general_operand")])]
|
||||
"avr_have_dimode"
|
||||
{
|
||||
rtx acc_a = gen_rtx_REG (DImode, ACC_A);
|
||||
@ -602,8 +602,8 @@
|
||||
;; "ashluta3" "ashruta3" "lshruta3" "rotluta3"
|
||||
(define_expand "<code_stdname><mode>3"
|
||||
[(parallel [(match_operand:ALL8 0 "general_operand" "")
|
||||
(di_shifts:ALL8 (match_operand:ALL8 1 "general_operand" "")
|
||||
(match_operand:QI 2 "general_operand" ""))])]
|
||||
(di_shifts:ALL8 (match_operand:ALL8 1 "nop_general_operand")
|
||||
(match_operand:QI 2 "nop_general_operand"))])]
|
||||
"avr_have_dimode"
|
||||
{
|
||||
rtx acc_a = gen_rtx_REG (<MODE>mode, ACC_A);
|
||||
@ -648,8 +648,8 @@
|
||||
;; "mulsidi3"
|
||||
(define_expand "<extend_u>mulsidi3"
|
||||
[(parallel [(match_operand:DI 0 "register_operand" "")
|
||||
(match_operand:SI 1 "general_operand" "")
|
||||
(match_operand:SI 2 "general_operand" "")
|
||||
(match_operand:SI 1 "nop_general_operand")
|
||||
(match_operand:SI 2 "nop_general_operand")
|
||||
;; Just to mention the iterator
|
||||
(clobber (any_extend:SI (match_dup 1)))])]
|
||||
"avr_have_dimode
|
||||
|
60
gcc/testsuite/gcc.target/avr/torture/pr87376.c
Normal file
60
gcc/testsuite/gcc.target/avr/torture/pr87376.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* { dg-do run { target { ! avr_tiny } } } */
|
||||
/* { dg-additional-options "-std=gnu99" } */
|
||||
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
extern const __memx uint64_t aa __asm ("real_aa");
|
||||
extern const uint64_t bb __asm ("real_bb");
|
||||
|
||||
const __memx uint64_t real_aa = 0x1122334455667788;
|
||||
const uint64_t real_bb = 0x0908070605040302;
|
||||
|
||||
__attribute__((noinline,noclone))
|
||||
uint64_t add1 (void)
|
||||
{
|
||||
return aa + bb;
|
||||
}
|
||||
|
||||
__attribute__((noinline,noclone))
|
||||
uint64_t add2 (void)
|
||||
{
|
||||
return bb + aa;
|
||||
}
|
||||
|
||||
__attribute__((noinline,noclone))
|
||||
uint64_t sub1 (void)
|
||||
{
|
||||
return aa - bb;
|
||||
}
|
||||
|
||||
__attribute__((noinline,noclone))
|
||||
uint64_t sub2 (void)
|
||||
{
|
||||
return bb - aa;
|
||||
}
|
||||
|
||||
__attribute__((noinline,noclone))
|
||||
uint64_t neg1 (void)
|
||||
{
|
||||
return -aa;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
if (neg1() != -real_aa)
|
||||
__builtin_exit (__LINE__);
|
||||
|
||||
if (add1() != real_aa + real_bb)
|
||||
__builtin_exit (__LINE__);
|
||||
|
||||
if (add2() != real_bb + real_aa)
|
||||
__builtin_exit (__LINE__);
|
||||
|
||||
if (sub1() != real_aa - real_bb)
|
||||
__builtin_exit (__LINE__);
|
||||
|
||||
if (sub2() != real_bb - real_aa)
|
||||
__builtin_exit (__LINE__);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user