diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index cf12aceb5fde303c9762c3d08c05a718146fe876..0a26a07dabbb9aa0501ca139b1d8be866ae04ac7 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -31512,8 +31512,8 @@ arm_can_change_mode_class (machine_mode from, machine_mode to, { if (TARGET_BIG_END && !(GET_MODE_SIZE (from) == 16 && GET_MODE_SIZE (to) == 8) - && (GET_MODE_UNIT_SIZE (from) > UNITS_PER_WORD - || GET_MODE_UNIT_SIZE (to) > UNITS_PER_WORD) + && (GET_MODE_SIZE (from) > UNITS_PER_WORD + || GET_MODE_SIZE (to) > UNITS_PER_WORD) && reg_classes_intersect_p (VFP_REGS, rclass)) return false; return true; diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 1646b2172970acaaf949ba8b77d43ec72b688d73..db53ab0b8bfe7fce6e12ee6c0ec7c1cdb0cb6d41 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -113,6 +113,13 @@ (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*") (set_attr "neg_pool_range" "*,*,*,996,*,*,*,996,*")]) +/* We define these mov expanders to match the standard mov$a optab to prevent + the mid-end from trying to do a subreg for these modes which is the most + inefficient way to expand the move. Also big-endian subreg's aren't + allowed for a subset of modes, See TARGET_CAN_CHANGE_MODE_CLASS. + Without these RTL generation patterns the mid-end would attempt to take a + sub-reg and may ICE if it can't. */ + (define_expand "movti" [(set (match_operand:TI 0 "nonimmediate_operand" "") (match_operand:TI 1 "general_operand" ""))] @@ -137,33 +144,15 @@ } }) -(define_expand "movv4hf" - [(set (match_operand:V4HF 0 "s_register_operand") - (match_operand:V4HF 1 "s_register_operand"))] - "TARGET_NEON && TARGET_FP16" +(define_expand "mov" + [(set (match_operand:VH 0 "s_register_operand") + (match_operand:VH 1 "s_register_operand"))] + "TARGET_NEON" { - /* We need to use force_reg to avoid TARGET_CAN_CHANGE_MODE_CLASS - causing an ICE on big-endian because it cannot extract subregs in - this case. */ - if (can_create_pseudo_p ()) - { - if (!REG_P (operands[0])) - operands[1] = force_reg (V4HFmode, operands[1]); - } -}) - -(define_expand "movv8hf" - [(set (match_operand:V8HF 0 "") - (match_operand:V8HF 1 ""))] - "TARGET_NEON && TARGET_FP16" -{ - /* We need to use force_reg to avoid TARGET_CAN_CHANGE_MODE_CLASS - causing an ICE on big-endian because it cannot extract subregs in - this case. */ if (can_create_pseudo_p ()) { if (!REG_P (operands[0])) - operands[1] = force_reg (V8HFmode, operands[1]); + operands[1] = force_reg (mode, operands[1]); } })