Module Name: src
Committed By: rin
Date: Sat Oct 7 12:10:59 UTC 2023
Modified Files:
src/external/gpl3/gcc.old/dist/gcc/config/vax: vax.md
Log Message:
gcc.old: vax: PR port-vax/57646 patch provided by Kalvis Duckmanton [21/21]
Define separate instruction patterns for extzv for the cases where the fiel
d width and offset happen to be a multiple of a byte or word.
If in PIC mode, and the source operand to extzv is a memory
reference, and the address of the memory location is an external
symbol, load the address into a temporary register before expanding
the instruction.
Adjust the constraints to the zero_extract instruction pattern to
disallow indexed source operands, as the VAX extzv instruction
computes offsets based on the size of a byte (not a word or a
longword)
To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 \
src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md
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.old/dist/gcc/config/vax/vax.md
diff -u src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md:1.17 src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md:1.18
--- src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md:1.17 Sat Oct 7 12:10:38 2023
+++ src/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md Sat Oct 7 12:10:59 2023
@@ -827,32 +827,87 @@
return \"movw %3,%0\";
}")
-(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
- (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
+;;
+;; Register source, field width is either 8 or 16, field start
+;; is zero - simple, this is a mov[bl].
+;;
+(define_insn "*extzvQISI"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "const_int_operand" "n")
(match_operand:SI 3 "const_int_operand" "n")))]
- "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
+ "INTVAL (operands[3]) == 0
+ && INTVAL (operands[2]) == GET_MODE_BITSIZE ( QImode )"
+ "movzbl %1, %0"
+)
+
+(define_insn "*extzvHISI"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:QI 2 "const_int_operand" "n")
+ (match_operand:SI 3 "const_int_operand" "n")))]
+ "INTVAL (operands[3]) == 0
+ && INTVAL (operands[2]) == GET_MODE_BITSIZE ( HImode )"
+ "movzwl %1, %0"
+)
+
+;;
+;; Register source, field width is the entire register
+;;
+(define_insn "*extzvSISI"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:QI 2 "const_int_operand" "n")
+ (match_operand:SI 3 "const_int_operand" "n")
+
+ ))]
+ "INTVAL (operands[3]) == 0
+ && INTVAL (operands[2]) == GET_MODE_BITSIZE ( SImode )"
+ "*
+{
+ if (rtx_equal_p (operands[0], operands[1]))
+ return \"\"; /* no-op */
+ return \"movl %1,%0\";
+}")
+
+;; Register source, non-zero field start is handled elsewhere
+
+;; Offsettable memory, field width 8 or 16, field start on
+;; boundary matching the field width.
+
+(define_insn "*extzvQISI2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+ (zero_extract:SI (match_operand:SI 1 "memory_operand" "o")
+ (match_operand:QI 2 "const_int_operand" "n")
+ (match_operand:SI 3 "const_int_operand" "n")))]
+ "INTVAL (operands[2]) == 8
&& INTVAL (operands[3]) % INTVAL (operands[2]) == 0
- && (REG_P (operands[1])
- || (MEM_P (operands[1])
- && ! mode_dependent_address_p (XEXP (operands[1], 0),
- MEM_ADDR_SPACE (operands[1]))))"
+ && ! mode_dependent_address_p (XEXP (operands[1], 0),
+ MEM_ADDR_SPACE (operands[1]))"
"*
{
- if (REG_P (operands[1]))
- {
- if (INTVAL (operands[3]) != 0)
- return \"extzv %3,%2,%1,%0\";
- }
- else
- operands[1]
- = adjust_address (operands[1],
- INTVAL (operands[2]) == 8 ? QImode : HImode,
- INTVAL (operands[3]) / 8);
+ operands[1]
+ = adjust_address (operands[1],
+ QImode,
+ INTVAL (operands[3]) / 8);
+ return \"movzbl %1,%0\";
+}")
- if (INTVAL (operands[2]) == 8)
- return \"movzbl %1,%0\";
+(define_insn "*extzvHISI2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+ (zero_extract:SI (match_operand:SI 1 "memory_operand" "o")
+ (match_operand:QI 2 "const_int_operand" "n")
+ (match_operand:SI 3 "const_int_operand" "n")))]
+ "INTVAL (operands[2]) == 16
+ && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
+ && ! mode_dependent_address_p (XEXP (operands[1], 0),
+ MEM_ADDR_SPACE (operands[1]))"
+ "*
+{
+ operands[1]
+ = adjust_address (operands[1],
+ HImode,
+ INTVAL (operands[3]) / 8);
return \"movzwl %1,%0\";
}")
@@ -929,17 +984,26 @@
return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
}")
+;; When the field position and size are constant and the destination
+;; is a register, extv and extzv are much slower than a rotate followed
+;; by a bicl or sign extension. Because we might end up choosing ext[z]v
+;; anyway, we can't allow immediate values for the primary source operand.
+
+;; Because some of the instruction sequences generated by this pattern
+;; overwrite the output operand part way through, the output operand
+;; must be marked earlyclobber, may only be a register or memory
+;; operand and must not have any side effects (e.g. pre/post increment)
+;;
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
- (zero_extract:SI (match_operand:SI 1 "register_operand" "ro")
- (match_operand:QI 2 "general_operand" "g")
- (match_operand:SI 3 "general_operand" "nrmT")))]
- ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=&ro")
+ (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:QI 2 "const_int_operand" "n")
+ (match_operand:SI 3 "const_int_operand" "n")
+
+ ))]
+ "INTVAL (operands[3]) != 0"
"*
{
- if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
- || ! REG_P (operands[0]))
- return \"extzv %3,%2,%1,%0\";
if (INTVAL (operands[2]) == 8)
return \"rotl %R3,%1,%0\;movzbl %0,%0\";
if (INTVAL (operands[2]) == 16)
@@ -1041,13 +1105,70 @@
[(set (match_operand:SI 0 "general_operand" "")
(zero_extract:SI (match_operand:SI 1 "general_operand" "")
(match_operand:QI 2 "general_operand" "")
- (match_operand:SI 3 "general_operand" "")))]
+ (match_operand:SI 3 "general_operand" ""))
+ )]
""
- "")
+ "{
+ if (CONST_INT_P (operands[1]))
+ {
+ /*
+ * extzv of a constant doesn't work, so load the constant
+ * into a register.
+ */
+ rtx temp = gen_reg_rtx (SImode);
+ emit_move_insn (temp, operands[1]);
+ operands[1] = temp;
+ }
+
+
+ /*
+ * If the source operand is a memory reference, and the address
+ * is a symbol, and we're in PIC mode, load the address into a
+ * register. Don't evaluate the field start or width at this time.
+ */
+ if (flag_pic
+ /* && !reload_completed */
+ && MEM_P (operands[1])
+ && !mode_dependent_address_p (XEXP (operands[1], 0),
+ MEM_ADDR_SPACE (operands[1]))
+ && SYMBOL_REF_P (XEXP (operands[1], 0))
+ && !SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0))
+ )
+ {
+ rtx address = XEXP (operands[1], 0);
+ rtx temp = gen_reg_rtx (Pmode);
+ emit_move_insn (temp, address);
+ /* copy the original memory reference, replacing the address */
+ operands[1] = change_address (operands[1], VOIDmode, temp);
+ set_mem_align (operands[1], MEM_ALIGN (operands[1]));
+ }
+ else
+ if ((MEM_P (operands[1]) && !CONST_INT_P (operands[2]))
+ || SUBREG_P (operands[1])
+ )
+ {
+ /* Memory addresses for extzv are bytes, so load the source
+ operand into a register */
+ rtx temp = gen_reg_rtx (SImode);
+ emit_move_insn (temp, operands[1]);
+ operands[1] = temp;
+ }
+ else if (address_operand (operands[1], SImode))
+ {
+ operands[1] = force_reg (SImode, operands[1]);
+ }
+
+ }"
+)
+
+;;
+;; Operand 1 must not, under any circumstances, be an indexed operand
+;; as extzv computes indices based on the size of a byte.
+;;
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
- (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
+ (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "rQ")
(match_operand:QI 2 "general_operand" "g")
(match_operand:SI 3 "general_operand" "nrmT")))]
""
@@ -1056,10 +1177,7 @@
if (! REG_P (operands[0]) || ! CONST_INT_P (operands[2])
|| ! CONST_INT_P (operands[3])
|| INTVAL (operands[2]) + INTVAL (operands[3]) > 32
- || side_effects_p (operands[1])
- || (MEM_P (operands[1])
- && mode_dependent_address_p (XEXP (operands[1], 0),
- MEM_ADDR_SPACE (operands[1]))))
+ || side_effects_p (operands[1]))
return \"extzv %3,%2,%1,%0\";
if (INTVAL (operands[2]) == 8)
return \"rotl %R3,%1,%0\;movzbl %0,%0\";