diff options
Diffstat (limited to 'gcc/config/riscv/riscv.cc')
-rw-r--r-- | gcc/config/riscv/riscv.cc | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index a30c9f1..d5de76c 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -12641,6 +12641,13 @@ riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor, */ gcc_assert (i == 1); *factor = BYTES_PER_RISCV_VECTOR.coeffs[1]; + + /* The factor will be zero if vector is not enabled. That ultimately + causes problems in the dwarf2 emitter as the factor is used for + a division, causing a divide by zero. */ + if (*factor == 0) + *factor = 1; + *offset = 1; return RISCV_DWARF_VLENB; } @@ -15433,9 +15440,13 @@ synthesize_add (rtx operands[3]) ival -= saturated; - rtx x = gen_rtx_PLUS (word_mode, operands[1], GEN_INT (saturated)); + /* The first add may be an FP relative address during reload. FP + may be replaced with (sp + C). We don't want that to already + be saturated as (sp + C) would then exceed a simm12 field. So + emit the smaller offset first and the saturated constant last. */ + rtx x = gen_rtx_PLUS (word_mode, operands[1], GEN_INT (ival)); emit_insn (gen_rtx_SET (operands[0], x)); - rtx output = gen_rtx_PLUS (word_mode, operands[0], GEN_INT (ival)); + rtx output = gen_rtx_PLUS (word_mode, operands[0], GEN_INT (saturated)); emit_insn (gen_rtx_SET (operands[0], output)); return true; } @@ -15532,14 +15543,18 @@ synthesize_add_extended (rtx operands[3]) ival -= saturated; + /* The first add may be an FP relative address during reload. FP + may be replaced with (sp + C). We don't want that to already + be saturated as (sp + C) would then exceed a simm12 field. So + emit the smaller offset first and the saturated constant last. */ rtx temp = gen_reg_rtx (DImode); - emit_insn (gen_addsi3_extended (temp, operands[1], GEN_INT (saturated))); + emit_insn (gen_addsi3_extended (temp, operands[1], GEN_INT (ival))); temp = gen_lowpart (SImode, temp); SUBREG_PROMOTED_VAR_P (temp) = 1; SUBREG_PROMOTED_SET (temp, SRP_SIGNED); emit_insn (gen_rtx_SET (operands[0], temp)); rtx t = gen_reg_rtx (DImode); - emit_insn (gen_addsi3_extended (t, operands[0], GEN_INT (ival))); + emit_insn (gen_addsi3_extended (t, operands[0], GEN_INT (saturated))); t = gen_lowpart (SImode, t); SUBREG_PROMOTED_VAR_P (t) = 1; SUBREG_PROMOTED_SET (t, SRP_SIGNED); |