Module Name: src
Committed By: kalvisd
Date: Sun Sep 29 09:32:36 UTC 2024
Modified Files:
src/external/gpl3/gcc/dist/gcc/config/vax: vax.cc
Log Message:
gcc: vax: Allow 64 bit operands addressed using post-increment addressing
to be negated
OK rin@
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc
diff -u src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc:1.6 src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc:1.7
--- src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc:1.6 Sun Sep 29 04:36:29 2024
+++ src/external/gpl3/gcc/dist/gcc/config/vax/vax.cc Sun Sep 29 09:32:36 2024
@@ -1694,13 +1694,67 @@ vax_output_int_subtract (rtx_insn *insn,
{
/* Negation is tricky. It's basically complement and increment.
Negate hi, then lo, and subtract the carry back. */
- if ((MEM_P (low[0]) && GET_CODE (XEXP (low[0], 0)) == POST_INC)
- || (MEM_P (operands[0])
- && GET_CODE (XEXP (operands[0], 0)) == POST_INC))
- fatal_insn ("illegal operand detected", insn);
- output_asm_insn ("mnegl %2,%0", operands);
+
+ /*
+ * If the source *or* the destination operands are
+ * indirect memory references with post-increment
+ * addressing, an memory reference using the base
+ * register plus an offset must be constructed to
+ * address the high word of the source or result.
+ *
+ * pre-decrement memory references are rejected by the
+ * illegal_addsub_di_memory_operand predicate
+ */
+
+ rtx earlyhiw[3];
+
+ /* high word - destination */
+ if (MEM_P (operands[0])
+ && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
+ {
+ const enum machine_mode mode = GET_MODE (operands[0]);
+ rtx x = XEXP (XEXP (operands[0], 0), 0);
+ x = plus_constant (Pmode, x, GET_MODE_SIZE (mode));
+ x = gen_rtx_MEM (mode, x);
+ earlyhiw[0] = x;
+ }
+ else
+ earlyhiw[0] = operands[0];
+
+ earlyhiw[1] = operands[1]; /* easy, this is const0_rtx */
+
+ /* high word - source */
+ if (MEM_P (operands[2])
+ && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
+ {
+ const enum machine_mode mode = GET_MODE (operands[2]);
+ rtx x = XEXP (XEXP (operands[2], 0), 0);
+ x = plus_constant (Pmode, x, GET_MODE_SIZE (mode));
+ x = gen_rtx_MEM (mode, x);
+ earlyhiw[2] = x;
+ }
+ else
+ earlyhiw[2] = operands[2];
+
+ output_asm_insn ("mnegl %2,%0", earlyhiw);
output_asm_insn ("mnegl %2,%0", low);
- return "sbwc $0,%0";
+
+ if (earlyhiw[2] != operands[2])
+ {
+ rtx ops[3];
+ const enum machine_mode mode = GET_MODE (operands[2]);
+
+ output_asm_insn ("sbwc $0,%0", operands);
+ /* update the source operand's base register to
+ point to the following word */
+ ops[0] = XEXP (XEXP (operands[2], 0), 0);
+ ops[1] = const0_rtx;
+ ops[2] = gen_int_mode (GET_MODE_SIZE (mode), SImode);
+ output_asm_insn ("addl2 %2,%0", ops);
+ return "";
+ }
+ else
+ return "sbwc $0,%0";
}
gcc_assert (rtx_equal_p (operands[0], operands[1]));
gcc_assert (rtx_equal_p (low[0], low[1]));