i386.md splits II
Robert Lipe
robertl@dgii.com
Thu Oct 1 08:47:00 GMT 1998
Since Jan has told me in private mail that he didn't have access to the
testsuite, I thought I'd run it through the normal (no PIC) GCC-only
testsuite for him.
i686-pc-sco3.2v5.0.5 shows no regressions with this patch.
gcc.c-torture/compile/930217-1.c hangs during the compile, but it did
that before this patch was applied.
RJL
Jan Hubicka wrote:
> Hi
> I've found some more | I've overlooked in last mail, so sending it once
> again (and also because I am not sure, that I've sent the previous one :)
>
> I've also fixed the spacing problems I know of and changed | to || and found
> a bug in comment :)
>
> Changes:
> o Added patterns for (set edx (ashiftrt eax 31)) that is handled
> by cltd
> this constraint is used by sign_extend pattern, should be used
> by divmod patterns and surprisingly it match sometimes :)
> o Simplify extendsidi splits/pattern to use previous pattern
> now uses #, so some code duplication is gone
> o zero_extendsidi pattern now uses # and is handled by splits
> o Split trivial and most common case of movdi patterns
> (it also lets compiler clear register using xor etc.)
> o Added define_split for extendsidi pattern. It now uses combination of
> insn (ctld) and split. Split works just in case, that there is other
> register than eax after reload.
> Also extendsidi works at memory operands to let gcc zero extend value
> directly in stack (probably still faster than swap out registers, swap in
> value, extend value, swap out it and swap in registers)
> Also supports extending from one register/memory to another to avoid
> gcc moving extended value from register to register.
> Same for zero_extendsidi
> Sep 29 08:58:58 1998 Jan Hubicka <hubicka@freesoft.cz>
>
> * i386.md:
> (movdi): split the trivial (non-overlapping) case
> (zero_extendsidi2): split it, support extending from other
> register and to memory to avoid unnecesary moves of extended value
> Use # in pattern and handle completely by splits.
> (extendsidi2): likewise, don't generate cltd at pentium, added pattern
> for ashiftrt reg 31 from eax to edx that uses cltd instruction.
> extendsidi split uses it.
> (ashiftrt_32): New pattern
>
>
> *** gcc/config/i386/i386.md.old Thu Oct 1 13:32:25 1998
> --- gcc/config/i386/i386.md Thu Oct 1 13:36:20 1998
> ***************
> *** 1782,1787 ****
> --- 1782,1798 ----
> [(set_attr "type" "integer,memory")
> (set_attr "memory" "*,load")])
>
> + ;; Split the trivial (and common) case of movdi
> + (define_split
> + [(set (match_operand:DI 0 "general_operand" "or")
> + (match_operand:DI 1 "general_operand" "or"))]
> + "!reg_overlap_mentioned_p (operands[0], operands[1])
> + && (reload_completed || reload_in_progress)"
> + [(set (match_dup 3) (match_dup 5))
> + (set (match_dup 4) (match_dup 6))]
> + "split_di (&operands[0], 1, &operands[3], &operands[4]);
> + split_di (&operands[1], 1, &operands[5], &operands[6]);")
> +
>
> ;;- conversion instructions
> ;;- NONE
> ***************
> *** 2023,2080 ****
>
> (define_insn "zero_extendsidi2"
> [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
> ! (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
> ""
> ! "*
> ! {
> ! rtx high[2], low[2], xops[4];
> !
> ! if (REG_P (operands[0]) && REG_P (operands[1])
> ! && REGNO (operands[0]) == REGNO (operands[1]))
> ! {
> ! operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
> ! return AS2 (xor%L0,%0,%0);
> ! }
> !
> ! split_di (operands, 1, low, high);
> ! xops[0] = low[0];
> ! xops[1] = operands[1];
> ! xops[2] = high[0];
> ! xops[3] = const0_rtx;
> !
> ! output_asm_insn (AS2 (mov%L0,%1,%0), xops);
> ! if (GET_CODE (low[0]) == MEM)
> ! output_asm_insn (AS2 (mov%L2,%3,%2), xops);
> ! else
> ! output_asm_insn (AS2 (xor%L2,%2,%2), xops);
>
> ! RET;
> ! }")
>
> ;;- sign extension instructions
>
> (define_insn "extendsidi2"
> ! [(set (match_operand:DI 0 "register_operand" "=r")
> ! (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
> ""
> ! "*
> ! {
> ! if (REGNO (operands[0]) == 0)
> ! {
> ! /* This used to be cwtl, but that extends HI to SI somehow. */
> ! #ifdef INTEL_SYNTAX
> ! return \"cdq\";
> ! #else
> ! return \"cltd\";
> ! #endif
> ! }
>
> ! operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
> ! output_asm_insn (AS2 (mov%L0,%0,%1), operands);
> !
> ! operands[0] = GEN_INT (31);
> ! return AS2 (sar%L1,%0,%1);
> ! }")
>
> ;; Note that the i386 programmers' manual says that the opcodes
> ;; are named movsx..., but the assembler on Unix does not accept that.
> --- 2034,2097 ----
>
> (define_insn "zero_extendsidi2"
> [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
> ! (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
> ""
> ! "#")
>
> ! (define_split
> ! [(set (match_operand:DI 0 "nonimmediate_operand" "")
> ! (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
> ! "reload_completed || reload_in_progress"
> ! [(set (match_dup 3) (match_dup 1))
> ! (set (match_dup 4) (const_int 0))]
> ! "split_di (&operands[0], 1, &operands[3], &operands[4]);")
>
> ;;- sign extension instructions
>
> (define_insn "extendsidi2"
> ! [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,?o")
> ! (sign_extend:DI (match_operand:SI 1 "general_operand" "0,0,mr,r")))]
> ""
> ! "#")
>
> ! ;; When parameter is in register it is better to copy from it to avoid
> ! ;; dependencies
> ! (define_split
> ! [(set (match_operand:DI 0 "nonimmediate_operand" "or")
> ! (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
> ! "(reload_completed || reload_in_progress)
> ! && (!REG_P (operands[0]) || REGNO (operands[0]) != 0
> ! || (!optimize_size && ix86_cpu == PROCESSOR_PENTIUM))"
> ! [(set (match_dup 4) (match_dup 1))
> ! (set (match_dup 3) (match_dup 1))
> ! (set (match_dup 4)
> ! (ashiftrt:SI (match_dup 4) (const_int 31)))
> ! ]
> ! "split_di (&operands[0], 1, &operands[3], &operands[4]);")
> !
> ! ;; When parameter is in memory, copy it to destination and then again
> ! (define_split
> ! [(set (match_operand:DI 0 "nonimmediate_operand" "r")
> ! (sign_extend:DI (match_operand:SI 1 "general_operand" "mr")))]
> ! "(reload_completed || reload_in_progress)
> ! && (!REG_P (operands[0]) || REGNO (operands[0]) != 0
> ! || (!optimize_size && ix86_cpu==PROCESSOR_PENTIUM))"
> ! [(set (match_dup 3) (match_dup 1))
> ! (set (match_dup 4) (match_dup 3))
> ! (set (match_dup 4)
> ! (ashiftrt:SI (match_dup 4) (const_int 31)))
> ! ]
> ! "split_di (&operands[0], 1, &operands[3], &operands[4]);")
> !
> ! (define_split
> ! [(set (match_operand:DI 0 "register_operand" "A")
> ! (sign_extend:DI (match_operand:SI 1 "general_operand" "mr")))]
> ! "(reload_completed || reload_in_progress)
> ! && (optimize_size || ix86_cpu!=PROCESSOR_PENTIUM)"
> ! [(set (match_dup 3) (match_dup 1))
> ! (set (match_dup 4)
> ! (ashiftrt:SI (match_dup 3) (const_int 31)))]
> ! "split_di (&operands[0], 1, &operands[3], &operands[4]);")
>
> ;; Note that the i386 programmers' manual says that the opcodes
> ;; are named movsx..., but the assembler on Unix does not accept that.
> *************** byte_xor_operation:
> *** 4850,4855 ****
> --- 4867,4881 ----
>
> RET;
> }")
> +
> + (define_insn "ashrsi3_31"
> + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
> + (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
> + (const_int 31)))]
> + "ix86_cpu != PROCESSOR_PENTIUM || optimize_size"
> + "@
> + sar%L0 $31,%0
> + cltd")
>
> (define_insn "ashrsi3"
> [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
More information about the Gcc-patches
mailing list