This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Specifying explicit parallel to define_insn of a named pattern.
- From: "venkat" <venkat at acmet dot com>
- To: <gcc-help at gcc dot gnu dot org>
- Date: Fri, 27 Mar 2009 12:14:18 +0530
- Subject: Specifying explicit parallel to define_insn of a named pattern.
I am working on porting GCC to a 32 bit RISC (based on MIPS).
In the machine descriptions, I have specified the division operation as
shown below.
(-----Cut-----)
(define_insn_and_split "<div_mod_optab_name>si3"
[(parallel[ <== *(1)
(set (match_operand:SI 0 "register_operand")
(any_div_op:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "register_operand")))
(clobber (reg:SI LO_REG_NUM))
(clobber (reg:SI HI_REG_NUM))
])
]
""
"#"
"reload_completed"
[(parallel[(set (match_dup 3)
(any_div_op:SI (match_dup 1)
(match_dup 2)))
(clobber (reg:SI HI_REG_NUM))])
(set (match_dup 0)
(match_dup 3))]
"
{ test();
operands[3] = gen_rtx_REG(SImode,LO_REG_NUM); }
"
)
(define_insn "*<div_mod_optab_name>si3"
[(parallel[
(set (match_operand:SI 0 "lo_register_operand" "=l")
(any_div_op:SI (match_operand:SI 1 "register_operand"
"=b")
(match_operand:SI 2 "register_operand" "
b")))
(clobber (reg:SI HI_REG_NUM))])]
""
{
output_check_div_by_zero(operands);
return "<div_mod_insn_name>\t%1,%2";
}
(-----Cut-----)
When I specify parallel explicitly *(1) as shown above, the 'genemit'
program generates the function 'add_clobbers' as shown below.
(-----Cut-----)
void
add_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number) {
switch (insn_code_number)
{
case 50:
XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 31);
break;
case 49:
case 48:
XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 31);
break;
case 8:
XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 32);
XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 33);
break;
default:
gcc_unreachable ();
}
}
(-----Cut-----)
In the above case clobber expressions are not recognized for division
operations (signed and unsigned division).
But, when I remove the explicit parallel from the machine description as
shown below,
(-----Cut-----)
(define_insn_and_split "<div_mod_optab_name>si3"
[
(set (match_operand:SI 0 "register_operand")
(any_div_op:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "register_operand")))
(clobber (reg:SI LO_REG_NUM))
(clobber (reg:SI HI_REG_NUM))
]
""
"#"
"reload_completed"
[(parallel[(set (match_dup 3)
(any_div_op:SI (match_dup 1)
(match_dup 2)))
(clobber (reg:SI HI_REG_NUM))])
(set (match_dup 0)
(match_dup 3))]
"
{ test();
operands[3] = gen_rtx_REG(SImode,LO_REG_NUM); }
"
)
(define_insn "*<div_mod_optab_name>si3"
[(parallel[
(set (match_operand:SI 0 "lo_register_operand" "=l")
(any_div_op:SI (match_operand:SI 1 "register_operand"
"=b")
(match_operand:SI 2 "register_operand" "
b")))
(clobber (reg:SI HI_REG_NUM))])]
""
{
output_check_div_by_zero(operands);
return "<div_mod_insn_name>\t%1,%2";
}
(-----Cut-----)
The 'genemit' program generates 'add_clobbers' as shown below.
(-----Cut-----)
void
add_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number) {
switch (insn_code_number)
{
case 50:
XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 31);
break;
case 49:
case 48:
XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 31);
break;
case 10: <== this was generated
for our division operation.
case 9:
XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 33);
XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 32);
break;
case 8:
XVECEXP (pattern, 0, 1) = gen_hard_reg_clobber (SImode, 32);
XVECEXP (pattern, 0, 2) = gen_hard_reg_clobber (SImode, 33);
break;
default:
gcc_unreachable ();
}
}
(-----Cut-----)
The clobbers defined in the machine descriptions are now recognized. The
additional case constructs are generated (case 9 and 10).
I checked the source code of the gen_emit program, specifically the function
'gen_insn (rtx insn, int lineno)' function.
When the vector read from machine description for division is
(-----Snip-----)
[
(set (match_operand:SI 0 "register_operand")
(any_div_op:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "register_operand")))
(clobber (reg:SI LO_REG_NUM))
(clobber (reg:SI HI_REG_NUM))
]
(-----Snip-----)
The check in <if (i != XVECLEN (insn, 1) - 1> returns 2. That means number
of expressions in the vector is 3.
But when the vector read from machine description for division is
(-----Snip-----)
[ (parallel [
(set (match_operand:SI 0 "register_operand")
(any_div_op:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "register_operand")))
(clobber (reg:SI LO_REG_NUM))
(clobber (reg:SI HI_REG_NUM))
])
]
(-----Snip-----)
The check (if (i != XVECLEN (insn, 1) - 1) returns 0. That means number of
expressions in the vector is 1.
>From seeing the source code, I believe the code for recognizing clobbers
will not work when we specify explicit parallel.
Please confirm my understanding.
Also I am also aware that GCC implicitly surrounds parallel when there are
multiple expressions in the template of 'define_insn'.
So specifying parallel at the start of 'define_insn' of a named pattern has
a different meaning?
In my case I feel explicit parallel is not needed and can be removed.
Please confirm.