From d713426e13894ce932eff5b89c509b1c4bd7f2dc Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Thu, 26 Feb 2015 19:43:54 +0000 Subject: [PATCH] re PR target/65192 ([avr-tiny] ICE in tiny_valid_direct_memory_access_range) PR target/65192 * config/avr/avr-protos.h (tiny_valid_direct_memory_access_range): Remove. * config/avr/avr.c: Same. (avr_legitimate_address_p) : Refuse any constant address not in 0..0xbf. * config/avr/avr.md (*mov, *movsf): Remove tiny_valid_direct_memory_access_range from insn conditions. (mov): Don't special-case expansion of avrtiny addresses. From-SVN: r221029 --- gcc/ChangeLog | 12 +++++++ gcc/config/avr/avr-protos.h | 1 - gcc/config/avr/avr.c | 41 ++++++------------------ gcc/config/avr/avr.md | 62 +++++-------------------------------- 4 files changed, 30 insertions(+), 86 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4e8f5478b46..40499826dc3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2015-02-26 Georg-Johann Lay + + PR target/65192 + * config/avr/avr-protos.h (tiny_valid_direct_memory_access_range): + Remove. + * config/avr/avr.c: Same. + (avr_legitimate_address_p) : + Refuse any constant address not in 0..0xbf. + * config/avr/avr.md (*mov, *movsf): Remove + tiny_valid_direct_memory_access_range from insn conditions. + (mov): Don't special-case expansion of avrtiny addresses. + 2015-02-26 Oleg Endo PR target/61142 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_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)) - { - 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)) - { - 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_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) - || reg_or_0_operand (operands[1], 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) + || reg_or_0_operand (operands[1], mode)" { return output_movqi (insn, operands, NULL); } @@ -812,13 +781,8 @@ (define_insn "*mov" [(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) - || reg_or_0_operand (operands[1], 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) + || reg_or_0_operand (operands[1], mode)" { return output_movhi (insn, operands, NULL); } @@ -966,13 +930,8 @@ (define_insn "*mov" [(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) - || reg_or_0_operand (operands[1], 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) + || reg_or_0_operand (operands[1], 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); } -- 2.30.2