From b4e8a3003fbd33ff6e48543b81d7249797ca035c Mon Sep 17 00:00:00 2001 From: rearnsha Date: Sat, 13 Mar 2004 11:19:23 +0000 Subject: [PATCH] * arm.c (arm_legitimate_address_p): New argument, OUTER. Pass through to arm_legitimate_index_p. Update all callers with SET as default value. (arm_legitimate_index_p): New argument, OUTER. Restrict the index range if OUTER is a sign-extend operation on QImode. Correctly reject shift operations on sign-extended QImode addresses. (bad_signed_byte_operand): Delete. (arm_extendqisi_mem_op): New function. * arm.h (EXTRA_CONSTRAINT_ARM): Delete. Replace with... (EXTRA_CONSTRAINT_STR_ARM): ... this. Handle extended address constraints. (CONSTRAINT_LEN): New. (EXTRA_CONSTRAINT): Delete. Replace with... (EXTRA_CONSTRAINT_STR): ... this. (PREDICATE_CODES): Remove bad_signed_byte_operand. * arm.md (extendqihi_insn): Use new constraint Uq. Rework. Length is now always default. (define_splits for bad sign-extend loads): Delete. (arm_extendqisi, arm_extendqisi_v5): Likewise. * arm/vfp.md (arm_movsi_vfp, arm_movdi_vfp, movsf_vfp, movdf_vfp): Rework 'U' constraint to 'Uv'. * arm-protos.h: Remove bad_signed_byte_operand. Add arm_extendqisi_mem_op. * doc/md.texi (ARM constraints): Rename VFP constraint (now Uv). Add Uq constraint. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@79440 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 28 +++++++++++ gcc/config/arm/arm-protos.h | 4 +- gcc/config/arm/arm.c | 115 +++++++++++++++++++------------------------- gcc/config/arm/arm.h | 34 +++++++------ gcc/config/arm/arm.md | 109 ++++------------------------------------- gcc/config/arm/vfp.md | 16 +++--- gcc/doc/md.texi | 5 +- 7 files changed, 121 insertions(+), 190 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f1300ce026..e9d55382308 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2004-03-13 Richard Earnshaw + + * arm.c (arm_legitimate_address_p): New argument, OUTER. Pass through + to arm_legitimate_index_p. Update all callers with SET as default + value. + (arm_legitimate_index_p): New argument, OUTER. Restrict the index + range if OUTER is a sign-extend operation on QImode. Correctly + reject shift operations on sign-extended QImode addresses. + (bad_signed_byte_operand): Delete. + (arm_extendqisi_mem_op): New function. + * arm.h (EXTRA_CONSTRAINT_ARM): Delete. Replace with... + (EXTRA_CONSTRAINT_STR_ARM): ... this. Handle extended address + constraints. + (CONSTRAINT_LEN): New. + (EXTRA_CONSTRAINT): Delete. Replace with... + (EXTRA_CONSTRAINT_STR): ... this. + (PREDICATE_CODES): Remove bad_signed_byte_operand. + * arm.md (extendqihi_insn): Use new constraint Uq. Rework. Length + is now always default. + (define_splits for bad sign-extend loads): Delete. + (arm_extendqisi, arm_extendqisi_v5): Likewise. + * arm/vfp.md (arm_movsi_vfp, arm_movdi_vfp, movsf_vfp, movdf_vfp): + Rework 'U' constraint to 'Uv'. + * arm-protos.h: Remove bad_signed_byte_operand. Add + arm_extendqisi_mem_op. + * doc/md.texi (ARM constraints): Rename VFP constraint (now Uv). + Add Uq constraint. + 2004-03-13 Alan Modra * config/rs6000/rs6000.c (rs6000_va_arg): Replace SPLIT_COMPLEX_ARGS diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 4c0575d5664..47503fd58f5 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -50,7 +50,7 @@ extern int arm_split_constant (RTX_CODE, enum machine_mode, HOST_WIDE_INT, rtx, extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *); extern int legitimate_pic_operand_p (rtx); extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); -extern int arm_legitimate_address_p (enum machine_mode, rtx, int); +extern int arm_legitimate_address_p (enum machine_mode, rtx, RTX_CODE, int); extern int thumb_legitimate_address_p (enum machine_mode, rtx, int); extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT); extern rtx arm_legitimize_address (rtx, rtx, enum machine_mode); @@ -71,9 +71,9 @@ extern int arm_rhsm_operand (rtx, enum machine_mode); extern int arm_add_operand (rtx, enum machine_mode); extern int arm_addimm_operand (rtx, enum machine_mode); extern int arm_not_operand (rtx, enum machine_mode); +extern int arm_extendqisi_mem_op (rtx, enum machine_mode); extern int offsettable_memory_operand (rtx, enum machine_mode); extern int alignable_memory_operand (rtx, enum machine_mode); -extern int bad_signed_byte_operand (rtx, enum machine_mode); extern int arm_float_rhs_operand (rtx, enum machine_mode); extern int arm_float_add_operand (rtx, enum machine_mode); extern int power_of_two_operand (rtx, enum machine_mode); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index aa249ff92e0..4cada0c10eb 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -64,7 +64,7 @@ static int arm_gen_constant (enum rtx_code, enum machine_mode, HOST_WIDE_INT, rtx, rtx, int, int); static unsigned bit_count (unsigned long); static int arm_address_register_rtx_p (rtx, int); -static int arm_legitimate_index_p (enum machine_mode, rtx, int); +static int arm_legitimate_index_p (enum machine_mode, rtx, RTX_CODE, int); static int thumb_base_register_rtx_p (rtx, enum machine_mode, int); inline static int thumb_index_register_rtx_p (rtx, int); static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code); @@ -2719,7 +2719,7 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg) { /* The base register doesn't really matter, we only want to test the index for the appropriate mode. */ - if (!arm_legitimate_index_p (mode, offset, 0)) + if (!arm_legitimate_index_p (mode, offset, SET, 0)) { if (!no_new_pseudos) offset = force_reg (Pmode, offset); @@ -2824,7 +2824,8 @@ arm_address_register_rtx_p (rtx x, int strict_p) /* Return nonzero if X is a valid ARM state address operand. */ int -arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) +arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer, + int strict_p) { if (arm_address_register_rtx_p (x, strict_p)) return 1; @@ -2837,7 +2838,8 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) && arm_address_register_rtx_p (XEXP (x, 0), strict_p) && GET_CODE (XEXP (x, 1)) == PLUS && XEXP (XEXP (x, 1), 0) == XEXP (x, 0)) - return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), strict_p); + return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), outer, + strict_p); /* After reload constants split into minipools will have addresses from a LABEL_REF. */ @@ -2889,9 +2891,9 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) rtx xop1 = XEXP (x, 1); return ((arm_address_register_rtx_p (xop0, strict_p) - && arm_legitimate_index_p (mode, xop1, strict_p)) + && arm_legitimate_index_p (mode, xop1, outer, strict_p)) || (arm_address_register_rtx_p (xop1, strict_p) - && arm_legitimate_index_p (mode, xop0, strict_p))); + && arm_legitimate_index_p (mode, xop0, outer, strict_p))); } #if 0 @@ -2902,7 +2904,7 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) rtx xop1 = XEXP (x, 1); return (arm_address_register_rtx_p (xop0, strict_p) - && arm_legitimate_index_p (mode, xop1, strict_p)); + && arm_legitimate_index_p (mode, xop1, outer, strict_p)); } #endif @@ -2924,7 +2926,8 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) /* Return nonzero if INDEX is valid for an address index operand in ARM state. */ static int -arm_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p) +arm_legitimate_index_p (enum machine_mode mode, rtx index, RTX_CODE outer, + int strict_p) { HOST_WIDE_INT range; enum rtx_code code = GET_CODE (index); @@ -2949,38 +2952,42 @@ arm_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p) && INTVAL (index) < 256 && INTVAL (index) > -256); - /* XXX What about ldrsb? */ - if (GET_MODE_SIZE (mode) <= 4 && code == MULT - && (!arm_arch4 || (mode) != HImode)) - { - rtx xiop0 = XEXP (index, 0); - rtx xiop1 = XEXP (index, 1); - - return ((arm_address_register_rtx_p (xiop0, strict_p) - && power_of_two_operand (xiop1, SImode)) - || (arm_address_register_rtx_p (xiop1, strict_p) - && power_of_two_operand (xiop0, SImode))); - } - if (GET_MODE_SIZE (mode) <= 4 - && (code == LSHIFTRT || code == ASHIFTRT - || code == ASHIFT || code == ROTATERT) - && (!arm_arch4 || (mode) != HImode)) + && ! (arm_arch4 + && (mode == HImode + || (mode == QImode && outer == SIGN_EXTEND)))) { - rtx op = XEXP (index, 1); + if (code == MULT) + { + rtx xiop0 = XEXP (index, 0); + rtx xiop1 = XEXP (index, 1); + + return ((arm_address_register_rtx_p (xiop0, strict_p) + && power_of_two_operand (xiop1, SImode)) + || (arm_address_register_rtx_p (xiop1, strict_p) + && power_of_two_operand (xiop0, SImode))); + } + else if (code == LSHIFTRT || code == ASHIFTRT + || code == ASHIFT || code == ROTATERT) + { + rtx op = XEXP (index, 1); - return (arm_address_register_rtx_p (XEXP (index, 0), strict_p) - && GET_CODE (op) == CONST_INT - && INTVAL (op) > 0 - && INTVAL (op) <= 31); + return (arm_address_register_rtx_p (XEXP (index, 0), strict_p) + && GET_CODE (op) == CONST_INT + && INTVAL (op) > 0 + && INTVAL (op) <= 31); + } } - /* XXX For ARM v4 we may be doing a sign-extend operation during the - load, but that has a restricted addressing range and we are unable - to tell here whether that is the case. To be safe we restrict all - loads to that range. */ + /* For ARM v4 we may be doing a sign-extend operation during the + load. */ if (arm_arch4) - range = (mode == HImode || mode == QImode) ? 256 : 4096; + { + if (mode == HImode || (outer == SIGN_EXTEND && mode == QImode)) + range = 256; + else + range = 4096; + } else range = (mode == HImode) ? 4095 : 4096; @@ -4211,37 +4218,6 @@ arm_reload_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) && REGNO (op) >= FIRST_PSEUDO_REGISTER))); } -/* Return 1 if OP is a valid memory address, but not valid for a signed byte - memory access (architecture V4). - MODE is QImode if called when computing constraints, or VOIDmode when - emitting patterns. In this latter case we cannot use memory_operand() - because it will fail on badly formed MEMs, which is precisely what we are - trying to catch. */ -int -bad_signed_byte_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) -{ - if (GET_CODE (op) != MEM) - return 0; - - op = XEXP (op, 0); - - /* A sum of anything more complex than reg + reg or reg + const is bad. */ - if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS) - && (!s_register_operand (XEXP (op, 0), VOIDmode) - || (!s_register_operand (XEXP (op, 1), VOIDmode) - && GET_CODE (XEXP (op, 1)) != CONST_INT))) - return 1; - - /* Big constants are also bad. */ - if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT - && (INTVAL (XEXP (op, 1)) > 0xff - || -INTVAL (XEXP (op, 1)) > 0xff)) - return 1; - - /* Everything else is good, or can will automatically be made so. */ - return 0; -} - /* Return TRUE for valid operands for the rhs of an ARM instruction. */ int arm_rhs_operand (rtx op, enum machine_mode mode) @@ -4434,6 +4410,15 @@ cirrus_memory_offset (rtx op) return 0; } +int +arm_extendqisi_mem_op (rtx op, enum machine_mode mode) +{ + if (!memory_operand (op, mode)) + return 0; + + return arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND, 0); +} + /* Return nonzero if OP is a Cirrus or general register. */ int cirrus_register_operand (rtx op, enum machine_mode mode) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 4ca25a62dcb..86c6f1403e2 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1471,23 +1471,30 @@ enum reg_class accessed without using a load. 'U' is an address valid for VFP load/store insns. */ -#define EXTRA_CONSTRAINT_ARM(OP, C) \ - ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG : \ - (C) == 'R' ? (GET_CODE (OP) == MEM \ - && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \ - && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \ - (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \ - (C) == 'T' ? cirrus_memory_offset (OP) : \ - (C) == 'U' ? vfp_mem_operand (OP) : \ - 0) +#define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR) \ + (((C) == 'Q') ? (GET_CODE (OP) == MEM \ + && GET_CODE (XEXP (OP, 0)) == REG) : \ + ((C) == 'R') ? (GET_CODE (OP) == MEM \ + && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \ + && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \ + ((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \ + ((C) == 'T') ? cirrus_memory_offset (OP) : \ + ((C) == 'U' && (STR)[1] == 'v') ? vfp_mem_operand (OP) : \ + ((C) == 'U' && (STR)[1] == 'q') \ + ? arm_extendqisi_mem_op (OP, GET_MODE (OP)) \ + : 0) + +#define CONSTRAINT_LEN(C,STR) \ + ((C) == 'U' ? 2 : DEFAULT_CONSTRAINT_LEN (C, STR)) #define EXTRA_CONSTRAINT_THUMB(X, C) \ ((C) == 'Q' ? (GET_CODE (X) == MEM \ && GET_CODE (XEXP (X, 0)) == LABEL_REF) : 0) -#define EXTRA_CONSTRAINT(X, C) \ - (TARGET_ARM ? \ - EXTRA_CONSTRAINT_ARM (X, C) : EXTRA_CONSTRAINT_THUMB (X, C)) +#define EXTRA_CONSTRAINT_STR(X, C, STR) \ + (TARGET_ARM \ + ? EXTRA_CONSTRAINT_STR_ARM (X, C, STR) \ + : EXTRA_CONSTRAINT_THUMB (X, C)) #define EXTRA_MEMORY_CONSTRAINT(C, STR) ((C) == 'U') @@ -2336,7 +2343,7 @@ typedef struct #define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN) \ { \ - if (arm_legitimate_address_p (MODE, X, REG_STRICT_P)) \ + if (arm_legitimate_address_p (MODE, X, SET, REG_STRICT_P)) \ goto WIN; \ } @@ -2817,7 +2824,6 @@ extern int making_const_table; {"thumb_cmpneg_operand", {CONST_INT}}, \ {"thumb_cbrch_target_operand", {SUBREG, REG, MEM}}, \ {"offsettable_memory_operand", {MEM}}, \ - {"bad_signed_byte_operand", {MEM}}, \ {"alignable_memory_operand", {MEM}}, \ {"shiftable_operator", {PLUS, MINUS, AND, IOR, XOR}}, \ {"minmax_operator", {SMIN, SMAX, UMIN, UMAX}}, \ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index ff9eb5ae477..253fe11aeab 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3748,59 +3748,17 @@ }" ) -; Rather than restricting all byte accesses to memory addresses that ldrsb -; can handle, we fix up the ones that ldrsb can't grok with a split. (define_insn "*extendqihi_insn" - [(set (match_operand:HI 0 "s_register_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] + [(set (match_operand:HI 0 "s_register_operand" "=r") + (sign_extend:HI (match_operand:QI 1 "memory_operand" "Uq")))] "TARGET_ARM && arm_arch4" - "* - /* If the address is invalid, this will split the instruction into two. */ - if (bad_signed_byte_operand (operands[1], VOIDmode)) - return \"#\"; - return \"ldr%?sb\\t%0, %1\"; - " + "ldr%?sb\\t%0, %1" [(set_attr "type" "load_byte") (set_attr "predicable" "yes") - (set_attr "length" "8") (set_attr "pool_range" "256") (set_attr "neg_pool_range" "244")] ) -(define_split - [(set (match_operand:HI 0 "s_register_operand" "") - (sign_extend:HI (match_operand:QI 1 "bad_signed_byte_operand" "")))] - "TARGET_ARM && arm_arch4 && reload_completed" - [(set (match_dup 3) (match_dup 1)) - (set (match_dup 0) (sign_extend:HI (match_dup 2)))] - " - { - HOST_WIDE_INT offset; - - operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); - operands[2] = gen_rtx_MEM (QImode, operands[3]); - MEM_COPY_ATTRIBUTES (operands[2], operands[1]); - operands[1] = XEXP (operands[1], 0); - if (GET_CODE (operands[1]) == PLUS - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && !(const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1))) - || const_ok_for_arm (-offset))) - { - HOST_WIDE_INT low = (offset > 0 - ? (offset & 0xff) : -((-offset) & 0xff)); - XEXP (operands[2], 0) = plus_constant (operands[3], low); - operands[1] = plus_constant (XEXP (operands[1], 0), offset - low); - } - /* Ensure the sum is in correct canonical form. */ - else if (GET_CODE (operands[1]) == PLUS - && GET_CODE (XEXP (operands[1], 1)) != CONST_INT - && !s_register_operand (XEXP (operands[1], 1), VOIDmode)) - operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), - XEXP (operands[1], 1), - XEXP (operands[1], 0)); - }" -) - (define_expand "extendqisi2" [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "general_operand" "") @@ -3833,42 +3791,26 @@ }" ) -; Rather than restricting all byte accesses to memory addresses that ldrsb -; can handle, we fix up the ones that ldrsb can't grok with a split. (define_insn "*arm_extendqisi" [(set (match_operand:SI 0 "s_register_operand" "=r") - (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] + (sign_extend:SI (match_operand:QI 1 "memory_operand" "Uq")))] "TARGET_ARM && arm_arch4 && !arm_arch6" - "* - /* If the address is invalid, this will split the instruction into two. */ - if (bad_signed_byte_operand (operands[1], VOIDmode)) - return \"#\"; - return \"ldr%?sb\\t%0, %1\"; - " + "ldr%?sb\\t%0, %1" [(set_attr "type" "load_byte") (set_attr "predicable" "yes") - (set_attr "length" "8") (set_attr "pool_range" "256") (set_attr "neg_pool_range" "244")] ) (define_insn "*arm_extendqisi_v6" [(set (match_operand:SI 0 "s_register_operand" "=r,r") - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uq")))] "TARGET_ARM && arm_arch6" - "* - if (which_alternative == 0) - return \"sxtb%?\\t%0, %1\"; - - /* If the address is invalid, this will split the instruction into two. */ - if (bad_signed_byte_operand (operands[1], VOIDmode)) - return \"#\"; - - return \"ldr%?sb\\t%0, %1\"; - " + "@ + sxtb%?\\t%0, %1 + ldr%?sb\\t%0, %1" [(set_attr "type" "alu_shift,load_byte") (set_attr "predicable" "yes") - (set_attr "length" "4,8") (set_attr "pool_range" "*,256") (set_attr "neg_pool_range" "*,244")] ) @@ -3883,39 +3825,6 @@ (set_attr "predicable" "yes")] ) -(define_split - [(set (match_operand:SI 0 "s_register_operand" "") - (sign_extend:SI (match_operand:QI 1 "bad_signed_byte_operand" "")))] - "TARGET_ARM && arm_arch4 && reload_completed" - [(set (match_dup 0) (match_dup 1)) - (set (match_dup 0) (sign_extend:SI (match_dup 2)))] - " - { - HOST_WIDE_INT offset; - - operands[2] = gen_rtx_MEM (QImode, operands[0]); - MEM_COPY_ATTRIBUTES (operands[2], operands[1]); - operands[1] = XEXP (operands[1], 0); - if (GET_CODE (operands[1]) == PLUS - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && !(const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1))) - || const_ok_for_arm (-offset))) - { - HOST_WIDE_INT low = (offset > 0 - ? (offset & 0xff) : -((-offset) & 0xff)); - XEXP (operands[2], 0) = plus_constant (operands[0], low); - operands[1] = plus_constant (XEXP (operands[1], 0), offset - low); - } - /* Ensure the sum is in correct canonical form. */ - else if (GET_CODE (operands[1]) == PLUS - && GET_CODE (XEXP (operands[1], 1)) != CONST_INT - && !s_register_operand (XEXP (operands[1], 1), VOIDmode)) - operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), - XEXP (operands[1], 1), - XEXP (operands[1], 0)); - }" -) - (define_insn "*thumb_extendqisi2" [(set (match_operand:SI 0 "register_operand" "=l,l") (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))] diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index 5ae6c41f75a..dd313a9bdca 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -111,8 +111,8 @@ ;; ??? For now do not allow loading constants into vfp regs. This causes ;; problems because small constants get converted into adds. (define_insn "*arm_movsi_vfp" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,!w,r,!w,!w, U") - (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,!w,!w,Ui,!w"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,!w,r,!w,!w, Uv") + (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,!w,!w,Uvi,!w"))] "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT && ( s_register_operand (operands[0], SImode) || s_register_operand (operands[1], SImode))" @@ -136,8 +136,8 @@ ;; DImode moves (define_insn "*arm_movdi_vfp" - [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,o<>,w,r,w,w ,U") - (match_operand:DI 1 "di_operand" "rIK,mi,r ,r,w,w,Ui,w"))] + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,o<>,w,r,w,w ,Uv") + (match_operand:DI 1 "di_operand" "rIK,mi,r ,r,w,w,Uvi,w"))] "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP" "* switch (which_alternative) @@ -168,8 +168,8 @@ ;; SFmode moves (define_insn "*movsf_vfp" - [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,U,r ,m,w,r") - (match_operand:SF 1 "general_operand" " r,w,UE,w,mE,r,w,r"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,Uv,r ,m,w,r") + (match_operand:SF 1 "general_operand" " r,w,UvE,w, mE,r,w,r"))] "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP && ( s_register_operand (operands[0], SFmode) || s_register_operand (operands[1], SFmode))" @@ -192,8 +192,8 @@ ;; DFmode moves (define_insn "*movdf_vfp" - [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,U,w,r") - (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UF,w,w,r"))] + [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,Uv,w,r") + (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UvF,w, w,r"))] "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP" "* { diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 47c33608e40..a543080967c 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -1360,9 +1360,12 @@ An item in the constant pool A symbol in the text segment of the current file @end table -@item U +@item Uv A memory reference suitable for VFP load/store insns (reg+constant offset) +@item Uq +A memory reference suitable for for the ARMv4 ldrsb instruction. + @item AVR family---@file{avr.h} @table @code @item l -- 2.11.4.GIT