diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index c833e11a9f4223a5e6254b50a1598549e9d69693..39e11f7292c627c795f0cb66ffa20bcb579ff85e 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -849,7 +849,7 @@ reg_not_elim_operand (op, mode) return register_operand (op, mode); } -/* Return 1 is OP is a memory location that is not an reference (using +/* Return 1 is OP is a memory location that is not a reference (using an AND) to an unaligned location. Take into account what reload will do. */ @@ -871,6 +871,20 @@ normal_memory_operand (op, mode) return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND; } + +/* Accept a register, but not a subreg of any kind. This allows us to + avoid pathological cases in reload wrt data movement common in + int->fp conversion. */ + +int +reg_no_subreg_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + if (GET_CODE (op) == SUBREG) + return 0; + return register_operand (op, mode); +} /* Return 1 if this function can directly return via $26. */ diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 4587bbf96f0d708dbeb868f2fb27921a0cebd067..c2eecefe9b460793f8499990d85c8fc46fa01889 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -2321,7 +2321,8 @@ do { \ {"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \ {"any_memory_operand", {MEM}}, \ {"hard_fp_register_operand", {SUBREG, REG}}, \ - {"reg_not_elim_operand", {SUBREG, REG}}, + {"reg_not_elim_operand", {SUBREG, REG}}, \ + {"reg_no_subreg_operand", {REG}}, /* Tell collect that the object format is ECOFF. */ #define OBJECT_FORMAT_COFF diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 55bdc11c5513d554cf50a46efb55faf0e645d436..838cff0a998c2dc10ac0d35f97ad623af0c42805 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -1988,7 +1988,7 @@ (define_insn "" [(set (match_operand:SF 0 "register_operand" "=&f") - (float:SF (match_operand:DI 1 "register_operand" "f")))] + (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] "TARGET_FP && alpha_tp == ALPHA_TP_INSN" "cvtq%,%+%& %1,%0" [(set_attr "type" "fadd") @@ -1996,7 +1996,7 @@ (define_insn "floatdisf2" [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "register_operand" "f")))] + (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] "TARGET_FP" "cvtq%,%+%& %1,%0" [(set_attr "type" "fadd") @@ -2004,7 +2004,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=&f") - (float:DF (match_operand:DI 1 "register_operand" "f")))] + (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] "TARGET_FP && alpha_tp == ALPHA_TP_INSN" "cvtq%-%+%& %1,%0" [(set_attr "type" "fadd") @@ -2012,7 +2012,7 @@ (define_insn "floatdidf2" [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "register_operand" "f")))] + (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] "TARGET_FP" "cvtq%-%+%& %1,%0" [(set_attr "type" "fadd")