From 8b0d23297f6b2270886219fcd3c6548c6b510c88 Mon Sep 17 00:00:00 2001 From: rin Date: Sat, 7 Oct 2023 12:10:59 +0000 Subject: [PATCH] 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) --- .../gpl3/gcc.old/dist/gcc/config/vax/vax.md | 192 ++++++++++++++---- 1 file changed, 155 insertions(+), 37 deletions(-) diff --git a/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md b/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md index 175013d5757e..e77733d44c7d 100644 --- a/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md +++ b/external/gpl3/gcc.old/dist/gcc/config/vax/vax.md @@ -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]) % 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]))))" + "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 (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); + if (rtx_equal_p (operands[0], operands[1])) + return \"\"; /* no-op */ + return \"movl %1,%0\"; +}") - if (INTVAL (operands[2]) == 8) - return \"movzbl %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 + && ! mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1]))" + "* +{ + operands[1] + = adjust_address (operands[1], + QImode, + INTVAL (operands[3]) / 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\";