This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Preventing scheduling of normal operations across calls to built-ins
Ayonam Ray <ayonam@gmail.com> writes:
> Here's the RTL:
>
> (define_insn "mvc_from_ccr"
> [(set (match_operand:SI 0 "register_operand" "=r")
> (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "Y")]
> UNSPEC_MVC_FROM_CCR))
> (set (reg:SI 0) (const_int 0))]
> ""
> "s2.mvc\t%1, %0"
> [(set_attr "length" "4")])
>
>
> (define_insn "mvc_to_ccr"
> [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "=Y")
> (match_operand:SI 1 "register_operand" "r")]
> UNSPEC_MVC_TO_CCR)
> (set (reg:SI 0) (const_int 0))]
> ""
> "s2.mvc\t%1, %0\;s1.nop"
> [(set_attr "length" "4")])
>
> (define_expand "addsi3"
> [(parallel [(set (match_operand:SI 0 "register_operand" "")
> (plus:SI (match_operand:SI 1 "nonmemory_operand" "")
> (match_operand:SI 2 "nonmemory_operand" "")))
> (use (reg:SI 0))])]
> ""
> {
> if (GET_CODE(operands[1]) != REG &&
> ( GET_CODE(operands[1]) != CONST_INT
> || ! satisfies_constraint_J(operands[1])))
> operands[1] = force_reg(SImode, operands[1]);
>
> if (GET_CODE(operands[2]) != REG &&
> ( GET_CODE(operands[2]) != CONST_INT
> || ! satisfies_constraint_J(operands[2])))
> operands[2] = force_reg(SImode, operands[2]);
> })
>
> (define_insn "*addsi3"
> [(set (match_operand:SI 0 "register_operand" "=r,r")
> (plus:SI (match_operand:SI 1 "register_or_const_int_operand" "%r,r")
> (match_operand:SI 2 "register_or_const_int_operand" "r,J")))
> (use (reg:SI 0))]
> ""
> "@
> add\t%1, %2, %0
> addi\t%1, %2, %0"
> [(set_attr "length" "4")])
>
>
> (define_insn "subsi3"
> [(set (match_operand:SI 0 "register_operand" "=r,r,r")
> (minus:SI (match_operand:SI 1 "nonmemory_operand" "r,r,J")
> (match_operand:SI 2 "nonmemory_operand" "r,J,r")))
> (use (reg:SI 0))]
> ""
> "@
> sub\t%1, %2, %0
> subi\t%1, %2, %0
> sub\tr0, %2, %0\;addi\t%0, %1, %0"
> [(set_attr "length" "4,8,8")
> ] )
Don't (set (reg:SI 0) (const_int 0)). The compiler is smart enough to
know that as long as the register is set to 0, it doesn't matter which
actual insn sets it. Instead, do something like
(set (reg:SI 0) (unspec_volatile UNSPEC_CCR))
If that doesn't help, show us the actual RTL from a dump file generated
by -da. Ideally the one before the scheduling pass which is messing
things up.
By the way, it's unusual to make register 0 a fixed register, although I
don't know of anything wrong with it. More typically you would use a
pseudo-reg number past all the normal registers.
Ian