summaryrefslogtreecommitdiff
path: root/gcc/config/avr
diff options
context:
space:
mode:
authorgjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2015-02-26 19:43:54 +0000
committergjl <gjl@138bc75d-0d04-0410-961f-82ee72b054a4>2015-02-26 19:43:54 +0000
commit8992f34878068dcdc7941ef488c9ce0da60afe76 (patch)
treebbd926f21a71406c266f8144795890b14470ff56 /gcc/config/avr
parentd84df4484389f3fa0060c41f6a84b25e0b46fb4a (diff)
downloadgcc-8992f34878068dcdc7941ef488c9ce0da60afe76.tar.gz
PR target/65192
* config/avr/avr-protos.h (tiny_valid_direct_memory_access_range): Remove. * config/avr/avr.c: Same. (avr_legitimate_address_p) <AVR_TINY, CONSTANT_ADDRESS_P>: Refuse any constant address not in 0..0xbf. * config/avr/avr.md (*mov<mode>, *movsf): Remove tiny_valid_direct_memory_access_range from insn conditions. (mov<mode>): Don't special-case expansion of avrtiny addresses. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221029 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/avr')
-rw-r--r--gcc/config/avr/avr-protos.h1
-rw-r--r--gcc/config/avr/avr.c41
-rw-r--r--gcc/config/avr/avr.md62
3 files changed, 18 insertions, 86 deletions
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 40f1486e1bf..b5de42709e5 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -46,7 +46,6 @@ extern void avr_init_cumulative_args (CUMULATIVE_ARGS*, tree, rtx, tree);
#ifdef RTX_CODE
extern int avr_hard_regno_call_part_clobbered (unsigned, machine_mode);
-extern bool tiny_valid_direct_memory_access_range(rtx, machine_mode);
extern const char *output_movqi (rtx_insn *insn, rtx operands[], int *l);
extern const char *output_movhi (rtx_insn *insn, rtx operands[], int *l);
extern const char *output_movsisf (rtx_insn *insn, rtx operands[], int *l);
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 7d0a13d79f0..07d7bafd54a 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -1823,6 +1823,16 @@ avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
break;
}
+ if (AVR_TINY
+ && CONSTANT_ADDRESS_P (x))
+ {
+ /* avrtiny's load / store instructions only cover addresses 0..0xbf:
+ IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf. */
+
+ ok = (CONST_INT_P (x)
+ && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode)));
+ }
+
if (avr_log.legitimate_address_p)
{
avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
@@ -3210,37 +3220,6 @@ avr_out_xload (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
}
-/* AVRTC-579
- If OP is a symbol or a constant expression with value > 0xbf
- return FALSE, otherwise TRUE.
- This check is used to avoid LDS / STS instruction with invalid memory
- access range (valid range 0x40..0xbf). For I/O operand range 0x0..0x3f,
- IN / OUT instruction will be generated. */
-
-bool
-tiny_valid_direct_memory_access_range (rtx op, machine_mode mode)
-{
- rtx x;
-
- if (!AVR_TINY)
- return true;
-
- x = XEXP (op,0);
-
- if (MEM_P (op) && x && GET_CODE (x) == SYMBOL_REF)
- {
- return false;
- }
-
- if (MEM_P (op) && x && (CONSTANT_ADDRESS_P (x))
- && !(IN_RANGE (INTVAL (x), 0, 0xC0 - GET_MODE_SIZE (mode))))
- {
- return false;
- }
-
- return true;
-}
-
const char*
output_movqi (rtx_insn *insn, rtx operands[], int *plen)
{
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index d6d930c74b6..1b39ddbd158 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -671,32 +671,6 @@
emit_insn (gen_load<mode>_libgcc (dest, src));
DONE;
}
-
- // AVRTC-579
- // If the source operand expression is out of range for LDS instruction
- // copy source operand expression to register.
- // For tiny core, LDS instruction's memory access range limited to 0x40..0xbf.
-
- if (!tiny_valid_direct_memory_access_range (src, <MODE>mode))
- {
- rtx srcx = XEXP (src, 0);
- operands[1] = src = replace_equiv_address (src, copy_to_mode_reg (GET_MODE (srcx), srcx));
- emit_move_insn (dest, src);
- DONE;
- }
-
- // AVRTC-579
- // If the destination operand expression is out of range for STS instruction
- // copy destination operand expression to register.
- // For tiny core, STS instruction's memory access range limited to 0x40..0xbf.
-
- if (!tiny_valid_direct_memory_access_range (dest, <MODE>mode))
- {
- rtx destx = XEXP (dest, 0);
- operands[0] = dest = replace_equiv_address (dest, copy_to_mode_reg (GET_MODE (destx), destx));
- emit_move_insn (dest, src);
- DONE;
- }
})
;;========================================================================
@@ -713,13 +687,8 @@
(define_insn "mov<mode>_insn"
[(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
(match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
- "(register_operand (operands[0], <MODE>mode)
- || reg_or_0_operand (operands[1], <MODE>mode))
- /* Skip if operands are out of lds/sts memory access range(0x40..0xbf)
- though access range is checked during define_expand, it is required
- here to avoid merging RTXes during combine pass. */
- && tiny_valid_direct_memory_access_range (operands[0], QImode)
- && tiny_valid_direct_memory_access_range (operands[1], QImode)"
+ "register_operand (operands[0], <MODE>mode)
+ || reg_or_0_operand (operands[1], <MODE>mode)"
{
return output_movqi (insn, operands, NULL);
}
@@ -812,13 +781,8 @@
(define_insn "*mov<mode>"
[(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
(match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
- "(register_operand (operands[0], <MODE>mode)
- || reg_or_0_operand (operands[1], <MODE>mode))
- /* Skip if operands are out of lds/sts memory access range(0x40..0xbf)
- though access range is checked during define_expand, it is required
- here to avoid merging RTXes during combine pass. */
- && tiny_valid_direct_memory_access_range (operands[0], HImode)
- && tiny_valid_direct_memory_access_range (operands[1], HImode)"
+ "register_operand (operands[0], <MODE>mode)
+ || reg_or_0_operand (operands[1], <MODE>mode)"
{
return output_movhi (insn, operands, NULL);
}
@@ -966,13 +930,8 @@
(define_insn "*mov<mode>"
[(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
(match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
- "(register_operand (operands[0], <MODE>mode)
- || reg_or_0_operand (operands[1], <MODE>mode))
- /* Skip if operands are out of lds/sts memory access range(0x40..0xbf)
- though access range is checked during define_expand, it is required
- here to avoid merging RTXes during combine pass. */
- && tiny_valid_direct_memory_access_range (operands[0], SImode)
- && tiny_valid_direct_memory_access_range (operands[1], SImode)"
+ "register_operand (operands[0], <MODE>mode)
+ || reg_or_0_operand (operands[1], <MODE>mode)"
{
return output_movsisf (insn, operands, NULL);
}
@@ -986,13 +945,8 @@
(define_insn "*movsf"
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
(match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
- "(register_operand (operands[0], SFmode)
- || reg_or_0_operand (operands[1], SFmode))
- /* Skip if operands are out of lds/sts memory access range(0x40..0xbf)
- though access range is checked during define_expand, it is required
- here to avoid merging rtls during combine pass. */
- && tiny_valid_direct_memory_access_range (operands[0], SFmode)
- && tiny_valid_direct_memory_access_range (operands[1], SFmode)"
+ "register_operand (operands[0], SFmode)
+ || reg_or_0_operand (operands[1], SFmode)"
{
return output_movsisf (insn, operands, NULL);
}