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\";