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]));

Reply via email to