From a8a3b539f8b6ff903fcac75f7dd01ee1b1654c6e Mon Sep 17 00:00:00 2001 From: pbrook Date: Wed, 5 May 2004 23:11:55 +0000 Subject: [PATCH] * config/arm/arm-protots.h (vfp_mem_operand): Rename ... (arm_coproc_mem_operand): ... To this. * config/arm/arm.c (arm_legitimate_address_p): Allow ldrd modes. (arm_legitimate_index_p): Ditto. (vfp_mem_operand): Rename ... (arm_coproc_mem_operand): ... To this. Handle writeback modes. (vfp_secondary_reload_class): Use it. (output_move_double): Use doubleword load/store instructions. (arm_hard_regno_mode_ok): Only allow even reg pairs for ldrd. * config/arm/arm.h (TARGET_LDRD): Define. (EXTRA_CONSTRAINT_STR_ARM): Add 'Uy'. * config/gcc/arm/arm.md (arm_movdi): Allow all valid memory operands. New splitter for invalid doubleword loads. * config/arm/iwmmxt.md (iwmmxt_arm_movdi): Use Uy constraint. * config/arm/vfp.md (arm_movdi_vfp): Allow all valid memory operands. * doc/md.texi: Document Uy constraint. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@81543 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 19 +++ gcc/config/arm/arm-protos.h | 2 +- gcc/config/arm/arm.c | 281 ++++++++++++++++++++++++++++++-------------- gcc/config/arm/arm.h | 5 +- gcc/config/arm/arm.md | 22 +++- gcc/config/arm/iwmmxt.md | 4 +- gcc/config/arm/vfp.md | 4 +- gcc/doc/md.texi | 3 + 8 files changed, 245 insertions(+), 95 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 44e58d7c240..05aa794899c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2004-05-06 Paul Brook + + * config/arm/arm-protots.h (vfp_mem_operand): Rename ... + (arm_coproc_mem_operand): ... To this. + * config/arm/arm.c (arm_legitimate_address_p): Allow ldrd modes. + (arm_legitimate_index_p): Ditto. + (vfp_mem_operand): Rename ... + (arm_coproc_mem_operand): ... To this. Handle writeback modes. + (vfp_secondary_reload_class): Use it. + (output_move_double): Use doubleword load/store instructions. + (arm_hard_regno_mode_ok): Only allow even reg pairs for ldrd. + * config/arm/arm.h (TARGET_LDRD): Define. + (EXTRA_CONSTRAINT_STR_ARM): Add 'Uy'. + * config/gcc/arm/arm.md (arm_movdi): Allow all valid memory operands. + New splitter for invalid doubleword loads. + * config/arm/iwmmxt.md (iwmmxt_arm_movdi): Use Uy constraint. + * config/arm/vfp.md (arm_movdi_vfp): Allow all valid memory operands. + * doc/md.texi: Document Uy constraint. + 2004-05-05 Jan Hubicka PR opt/14980 diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 0359fe77116..0605803a3fe 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -100,7 +100,7 @@ extern int cirrus_general_operand (rtx, enum machine_mode); extern int cirrus_register_operand (rtx, enum machine_mode); extern int cirrus_shift_const (rtx, enum machine_mode); extern int cirrus_memory_offset (rtx); -extern int vfp_mem_operand (rtx); +extern int arm_coproc_mem_operand (rtx, bool); extern int vfp_compare_operand (rtx, enum machine_mode); extern int arm_float_compare_operand (rtx, enum machine_mode); extern int arm_no_early_store_addr_dep (rtx, rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 02864fb28ea..961dff2278e 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2983,25 +2983,44 @@ int arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer, int strict_p) { + bool use_ldrd; + enum rtx_code code = GET_CODE (x); + if (arm_address_register_rtx_p (x, strict_p)) return 1; - else if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC) + use_ldrd = (TARGET_LDRD + && (mode == DImode + || (mode == DFmode && (TARGET_SOFT_FLOAT || TARGET_VFP)))); + + if (code == POST_INC || code == PRE_DEC + || ((code == PRE_INC || code == POST_DEC) + && (use_ldrd || GET_MODE_SIZE (mode) <= 4))) return arm_address_register_rtx_p (XEXP (x, 0), strict_p); - else if ((GET_CODE (x) == POST_MODIFY || GET_CODE (x) == PRE_MODIFY) - && GET_MODE_SIZE (mode) <= 4 + else if ((code == POST_MODIFY || code == PRE_MODIFY) && arm_address_register_rtx_p (XEXP (x, 0), strict_p) && GET_CODE (XEXP (x, 1)) == PLUS && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0))) - return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), outer, - strict_p); + { + rtx addend = XEXP (XEXP (x, 1), 1); + + /* Don't allow ldrd post increment by register becuase it's hard + to fixup invalid register choices. */ + if (use_ldrd + && GET_CODE (x) == POST_MODIFY + && GET_CODE (addend) == REG) + return 0; + + return ((use_ldrd || GET_MODE_SIZE (mode) <= 4) + && arm_legitimate_index_p (mode, addend, outer, strict_p)); + } /* After reload constants split into minipools will have addresses from a LABEL_REF. */ else if (reload_completed - && (GET_CODE (x) == LABEL_REF - || (GET_CODE (x) == CONST + && (code == LABEL_REF + || (code == CONST && GET_CODE (XEXP (x, 0)) == PLUS && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))) @@ -3010,38 +3029,7 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer, else if (mode == TImode) return 0; - else if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode)) - { - if (GET_CODE (x) == PLUS - && arm_address_register_rtx_p (XEXP (x, 0), strict_p) - && GET_CODE (XEXP (x, 1)) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); - - if (val == 4 || val == -4 || val == -8) - return 1; - } - } - - else if (TARGET_HARD_FLOAT && TARGET_VFP && mode == DFmode) - { - if (GET_CODE (x) == PLUS - && arm_address_register_rtx_p (XEXP (x, 0), strict_p) - && GET_CODE (XEXP (x, 1)) == CONST_INT) - { - HOST_WIDE_INT val = INTVAL (XEXP (x, 1)); - - /* ??? valid arm offsets are a subset of VFP offsets. - For now only allow this subset. Proper fix is to add an - additional memory constraint for arm address modes. - Alternatively allow full vfp addressing and let - output_move_double fix it up with a sub-optimal sequence. */ - if (val == 4 || val == -4 || val == -8) - return 1; - } - } - - else if (GET_CODE (x) == PLUS) + else if (code == PLUS) { rtx xop0 = XEXP (x, 0); rtx xop1 = XEXP (x, 1); @@ -3065,17 +3053,12 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer, #endif else if (GET_MODE_CLASS (mode) != MODE_FLOAT - && GET_CODE (x) == SYMBOL_REF + && code == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x) && ! (flag_pic && symbol_mentioned_p (get_pool_constant (x)))) return 1; - else if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_DEC) - && (GET_MODE_SIZE (mode) <= 4) - && arm_address_register_rtx_p (XEXP (x, 0), strict_p)) - return 1; - return 0; } @@ -3097,16 +3080,31 @@ arm_legitimate_index_p (enum machine_mode mode, rtx index, RTX_CODE outer, && INTVAL (index) > -1024 && (INTVAL (index) & 3) == 0); - if (arm_address_register_rtx_p (index, strict_p) - && GET_MODE_SIZE (mode) <= 4) - return 1; - if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode)) return (code == CONST_INT && INTVAL (index) < 1024 && INTVAL (index) > -1024 && (INTVAL (index) & 3) == 0); + if (arm_address_register_rtx_p (index, strict_p) + && (GET_MODE_SIZE (mode) <= 4)) + return 1; + + if (mode == DImode || mode == DFmode) + { + if (code == CONST_INT) + { + HOST_WIDE_INT val = INTVAL (index); + + if (TARGET_LDRD) + return val > -256 && val < 256; + else + return val == 4 || val == -4 || val == -8; + } + + return TARGET_LDRD && arm_address_register_rtx_p (index, strict_p); + } + if (GET_MODE_SIZE (mode) <= 4 && ! (arm_arch4 && (mode == HImode @@ -4614,14 +4612,15 @@ cirrus_shift_const (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) } -/* Return TRUE if OP is a valid VFP memory address pattern. */ -/* Copied from cirrus_memory_offset but with restricted offset range. */ +/* Return TRUE if OP is a valid VFP memory address pattern. + WB if true if writeback address modes are allowed. */ int -vfp_mem_operand (rtx op) +arm_coproc_mem_operand (rtx op, bool wb) { - /* Reject eliminable registers. */ + rtx ind; + /* Reject eliminable registers. */ if (! (reload_in_progress || reload_completed) && ( reg_mentioned_p (frame_pointer_rtx, op) || reg_mentioned_p (arg_pointer_rtx, op) @@ -4632,35 +4631,49 @@ vfp_mem_operand (rtx op) return FALSE; /* Constants are converted into offsets from labels. */ - if (GET_CODE (op) == MEM) - { - rtx ind; - - ind = XEXP (op, 0); + if (GET_CODE (op) != MEM) + return FALSE; - if (reload_completed - && (GET_CODE (ind) == LABEL_REF - || (GET_CODE (ind) == CONST - && GET_CODE (XEXP (ind, 0)) == PLUS - && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF - && GET_CODE (XEXP (XEXP (ind, 0), 1)) == CONST_INT))) - return TRUE; + ind = XEXP (op, 0); - /* Match: (mem (reg)). */ - if (GET_CODE (ind) == REG) - return arm_address_register_rtx_p (ind, 0); + if (reload_completed + && (GET_CODE (ind) == LABEL_REF + || (GET_CODE (ind) == CONST + && GET_CODE (XEXP (ind, 0)) == PLUS + && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF + && GET_CODE (XEXP (XEXP (ind, 0), 1)) == CONST_INT))) + return TRUE; - /* Match: - (mem (plus (reg) - (const))). */ - if (GET_CODE (ind) == PLUS - && GET_CODE (XEXP (ind, 0)) == REG - && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode) - && GET_CODE (XEXP (ind, 1)) == CONST_INT - && INTVAL (XEXP (ind, 1)) > -1024 - && INTVAL (XEXP (ind, 1)) < 1024) - return TRUE; - } + /* Match: (mem (reg)). */ + if (GET_CODE (ind) == REG) + return arm_address_register_rtx_p (ind, 0); + + /* Autoincremment addressing modes. */ + if (wb + && (GET_CODE (ind) == PRE_INC + || GET_CODE (ind) == POST_INC + || GET_CODE (ind) == PRE_DEC + || GET_CODE (ind) == POST_DEC)) + return arm_address_register_rtx_p (XEXP (ind, 0), 0); + + if (wb + && (GET_CODE (ind) == POST_MODIFY || GET_CODE (ind) == PRE_MODIFY) + && arm_address_register_rtx_p (XEXP (ind, 0), 0) + && GET_CODE (XEXP (ind, 1)) == PLUS + && rtx_equal_p (XEXP (XEXP (ind, 1), 0), XEXP (ind, 0))) + ind = XEXP (ind, 1); + + /* Match: + (plus (reg) + (const)). */ + if (GET_CODE (ind) == PLUS + && GET_CODE (XEXP (ind, 0)) == REG + && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode) + && GET_CODE (XEXP (ind, 1)) == CONST_INT + && INTVAL (XEXP (ind, 1)) > -1024 + && INTVAL (XEXP (ind, 1)) < 1024 + && (INTVAL (XEXP (ind, 1)) & 3) == 0) + return TRUE; return FALSE; } @@ -4684,7 +4697,7 @@ vfp_compare_operand (rtx op, enum machine_mode mode) enum reg_class vfp_secondary_reload_class (enum machine_mode mode, rtx x) { - if (vfp_mem_operand (x) || s_register_operand (x, mode)) + if (arm_coproc_mem_operand (x, FALSE) || s_register_operand (x, mode)) return NO_REGS; return GENERAL_REGS; @@ -8384,7 +8397,9 @@ output_move_double (rtx *operands) break; case PRE_INC: - abort (); /* Should never happen now. */ + if (!TARGET_LDRD) + abort (); /* Should never happen now. */ + output_asm_insn ("ldr%?d\t%0, [%m1, #8]!", operands); break; case PRE_DEC: @@ -8396,7 +8411,33 @@ output_move_double (rtx *operands) break; case POST_DEC: - abort (); /* Should never happen now. */ + if (!TARGET_LDRD) + abort (); /* Should never happen now. */ + output_asm_insn ("ldr%?d\t%0, [%m1], #-8", operands); + break; + + case PRE_MODIFY: + case POST_MODIFY: + otherops[0] = operands[0]; + otherops[1] = XEXP (XEXP (XEXP (operands[1], 0), 1), 0); + otherops[2] = XEXP (XEXP (XEXP (operands[1], 0), 1), 1); + + if (GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY) + { + if (reg_overlap_mentioned_p (otherops[0], otherops[2])) + { + /* Registers overlap so split out the increment. */ + output_asm_insn ("add%?\t%1, %1, %2", otherops); + output_asm_insn ("ldr%?d\t%0, [%1] @split", otherops); + } + else + output_asm_insn ("ldr%?d\t%0, [%1, %2]!", otherops); + } + else + { + /* We only allow constant increments, so this is safe. */ + output_asm_insn ("ldr%?d\t%0, [%1], %2", otherops); + } break; case LABEL_REF: @@ -8429,7 +8470,41 @@ output_move_double (rtx *operands) output_asm_insn ("ldm%?ib\t%1, %M0", otherops); return ""; } - + } + if (TARGET_LDRD + && (GET_CODE (otherops[2]) == REG + || (GET_CODE (otherops[2]) == CONST_INT + && INTVAL (otherops[2]) > -256 + && INTVAL (otherops[2]) < 256))) + { + if (reg_overlap_mentioned_p (otherops[0], + otherops[2])) + { + /* Swap base and index registers over to + avoid a conflict. */ + otherops[1] = XEXP (XEXP (operands[1], 0), 1); + otherops[2] = XEXP (XEXP (operands[1], 0), 0); + + } + /* If both registers conflict, it will usually + have been fixed by a splitter. */ + if (reg_overlap_mentioned_p (otherops[0], + otherops[2])) + { + output_asm_insn ("add%?\t%1, %1, %2", otherops); + output_asm_insn ("ldr%?d\t%0, [%1]", + otherops); + return ""; + } + else + { + output_asm_insn ("ldr%?d\t%0, [%1, %2]", + otherops); + return ""; + } + } + if (GET_CODE (otherops[2]) == CONST_INT) + { if (!(const_ok_for_arm (INTVAL (otherops[2])))) output_asm_insn ("sub%?\t%0, %1, #%n2", otherops); else @@ -8475,7 +8550,9 @@ output_move_double (rtx *operands) break; case PRE_INC: - abort (); /* Should never happen now. */ + if (!TARGET_LDRD) + abort (); /* Should never happen now. */ + output_asm_insn ("str%?d\t%1, [%m0, #8]!", operands); break; case PRE_DEC: @@ -8487,11 +8564,26 @@ output_move_double (rtx *operands) break; case POST_DEC: - abort (); /* Should never happen now. */ + if (!TARGET_LDRD) + abort (); /* Should never happen now. */ + output_asm_insn ("str%?d\t%1, [%m0], #-8", operands); + break; + + case PRE_MODIFY: + case POST_MODIFY: + otherops[0] = operands[1]; + otherops[1] = XEXP (XEXP (XEXP (operands[0], 0), 1), 0); + otherops[2] = XEXP (XEXP (XEXP (operands[0], 0), 1), 1); + + if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY) + output_asm_insn ("str%?d\t%0, [%1, %2]!", otherops); + else + output_asm_insn ("str%?d\t%0, [%1], %2", otherops); break; case PLUS: - if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT) + otherops[2] = XEXP (XEXP (operands[0], 0), 1); + if (GET_CODE (otherops[2]) == CONST_INT) { switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1))) { @@ -8508,6 +8600,17 @@ output_move_double (rtx *operands) return ""; } } + if (TARGET_LDRD + && (GET_CODE (otherops[2]) == REG + || (GET_CODE (otherops[2]) == CONST_INT + && INTVAL (otherops[2]) > -256 + && INTVAL (otherops[2]) < 256))) + { + otherops[0] = operands[1]; + otherops[1] = XEXP (XEXP (operands[0], 0), 0); + output_asm_insn ("str%?d\t%0, [%1, %2]", otherops); + return ""; + } /* Fall through */ default: @@ -11393,9 +11496,11 @@ arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) if (IS_IWMMXT_REGNUM (regno)) return VALID_IWMMXT_REG_MODE (mode); + /* We allow any value to be stored in the general registers. + Restrict doubleword quantities to even register pairs so that we can + use ldrd. */ if (regno <= LAST_ARM_REGNUM) - /* We allow any value to be stored in the general registers. */ - return 1; + return !(TARGET_LDRD && GET_MODE_SIZE (mode) > 4 && (regno & 1) != 0); if ( regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM) diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index f64d3381b5e..c870af0052f 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -306,6 +306,7 @@ extern GTY(()) rtx aof_pic_label; ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \ : (target_flags & THUMB_FLAG_BACKTRACE)) #define TARGET_CIRRUS_FIX_INVALID_INSNS (target_flags & CIRRUS_FIX_INVALID_INSNS) +#define TARGET_LDRD (arm_arch5e && ARM_DOUBLEWORD_ALIGN) /* SUBTARGET_SWITCHES is used to add flags on a per-config basis. */ #ifndef SUBTARGET_SWITCHES @@ -1292,6 +1293,7 @@ enum reg_class accessed without using a load. 'U' Prefixes an extended memory constraint where: 'Uv' is an address valid for VFP load/store insns. + 'Uy' is an address valid for iwmmxt load/store insns. 'Uq' is an address valid for ldrsb. */ #define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR) \ @@ -1302,7 +1304,8 @@ enum reg_class && 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] == 'v') ? arm_coproc_mem_operand (OP, FALSE) : \ + ((C) == 'U' && (STR)[1] == 'y') ? arm_coproc_mem_operand (OP, TRUE) : \ ((C) == 'U' && (STR)[1] == 'q') \ ? arm_extendqisi_mem_op (OP, GET_MODE (OP)) \ : 0) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 7255b325997..554b332283b 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4073,7 +4073,7 @@ ) (define_insn "*arm_movdi" - [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>") + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r ,m") (match_operand:DI 1 "di_operand" "rIK,mi,r"))] "TARGET_ARM && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP)) @@ -4087,6 +4087,26 @@ (set_attr "neg_pool_range" "*,1008,*")] ) +;; We can't actually do base+index doubleword loads if the index and +;; destination overlap. Split here so that we at least have chance to +;; schedule. +(define_split + [(set (match_operand:DI 0 "s_register_operand" "") + (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "") + (match_operand:SI 2 "s_register_operand" ""))))] + "TARGET_LDRD + && reg_overlap_mentioned_p (operands[0], operands[1]) + && reg_overlap_mentioned_p (operands[0], operands[2])" + [(set (match_dup 4) + (plus:SI (match_dup 1) + (match_dup 2))) + (set (match_dup 0) + (mem:DI (match_dup 4)))] + " + operands[4] = gen_rtx_REG (SImode, REGNO(operands[0])); + " +) + ;;; ??? This should have alternatives for constants. ;;; ??? This was originally identical to the movdf_insn pattern. ;;; ??? The 'i' constraint looks funny, but it should always be replaced by diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md index e1b00538c1f..758847fd547 100644 --- a/gcc/config/arm/iwmmxt.md +++ b/gcc/config/arm/iwmmxt.md @@ -64,8 +64,8 @@ [(set_attr "predicable" "yes")]) (define_insn "*iwmmxt_arm_movdi" - [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>,y,y,yr,y,yrm") - (match_operand:DI 1 "di_operand" "rIK,mi,r ,y,yr,y,yrm,y"))] + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, m,y,y,yr,y,yrUy") + (match_operand:DI 1 "di_operand" "rIK,mi,r,y,yr,y,yrUy,y"))] "TARGET_REALLY_IWMMXT" "* { diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md index 6f7e2a7a639..7008ab40c76 100644 --- a/gcc/config/arm/vfp.md +++ b/gcc/config/arm/vfp.md @@ -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 ,Uv") - (match_operand:DI 1 "di_operand" "rIK,mi,r ,r,w,w,Uvi,w"))] + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,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) diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 5cff95bd2c2..b29f8b55fbc 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -1363,6 +1363,9 @@ A symbol in the text segment of the current file @item Uv A memory reference suitable for VFP load/store insns (reg+constant offset) +@item Uy +A memory reference suitable for iWMMXt load/store instructions. + @item Uq A memory reference suitable for for the ARMv4 ldrsb instruction. -- 2.11.4.GIT