This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: md description for intruction that modifies multiple operands
- From: fnf at intrinsity dot com (Fred Fish)
- To: Richard dot Earnshaw at arm dot com
- Cc: echristo at redhat dot com (Eric Christopher), fnf at intrinsity dot com,gcc at gcc dot gnu dot org
- Date: Thu, 29 May 2003 11:27:49 -0500 (CDT)
- Subject: Re: md description for intruction that modifies multiple operands
- Reply-to: fnf at intrinsity dot com
>> I don't think so. Though it looks like you might want to define a single
>> unspec number for the pattern and maybe use a parallel? *guesses*
I thought each unspec had to have a unique number.
Where are you suggesting placing a "parallel"?
> You are probably better off if you only use match_dup to match inputs to
> inputs and outputs to outputs. Use tied register allocation for inputs to
> outputs. Ties are best done using adjacent number pairs. Hence something
> like:
Thanks much for the example. I didn't see anything in the docs about
"tied register allocation". What specifically does this mean? Is it
a way to get registers allocated in sequence?
Perhaps I should give a more realistic code example and *.md entry.
The hardware handles vectors of 512 bits each, which can be organized as
a 4x4 matrix of 16 32-bit ints. We typedef a "matrix_t" to be a V16SI type.
Here is an actual code example:
typedef int matrix_t __attribute__((__mode__(V16SI)));
matrix_t foo (matrix_t t0, matrix_t t1, matrix_t t2, matrix_t t3)
{
__BLOCK4_M (t0, t1, t2, t3);
return (t0);
}
This example takes four matrix_t (V16SI) types as function arguments,
passed in hardware registers $m0, $m1, $m2, and $m3, for t0, t1, t2,
and t3 respectively. The __BLOCK4_M builtin takes four matrix_t
operands, does some matrix arithmetic on them, and returns the results
left in the four operands. One restriction is that the block4
operands have to be allocated to sequential hardware registers.
Here is the actual md file entry I put in based on your example:
(define_insn "fm_block4"
[(set (match_operand:V16SI 0 "register_operand" "=v")
(unspec:V16SI [(match_operand:V16SI 3 "register_operand" "2")
(match_operand:V16SI 5 "register_operand" "4")
(match_operand:V16SI 7 "register_operand" "6")] 460))
(set (match_operand:V16SI 2 "register_operand" "=v")
(unspec:V16SI [(match_operand:V16SI 1 "register_operand" "0")
(match_dup 5) (match_dup 7)] 461))
(set (match_operand:V16SI 4 "register_operand" "=v")
(unspec:V16SI [(match_dup 1) (match_dup 3) (match_dup 7)] 462))
(set (match_operand:V16SI 6 "register_operand" "=v")
(unspec:V16SI [(match_dup 1) (match_dup 3) (match_dup 7)] 463))]
"TARGET_FM"
"block4.m\\t%0,%2,%4,%6"
[(set_attr "type" "fm")])
For the above example, running "cc1 -da -O2 x.c" generates the
following rtl file and then the compiler gets a segfault due to the
set of a "(nil)". BTW, first matrix hardware register is 176, first
pseudo reg is 200. Note also I deleted some extraneous instructions
like NOTES:
(insn 3 2 4 (nil) (set (reg/v:V16SI 206 [ t0 ])
(reg:V16SI 176 $m0 [ t0 ])) -1 (nil)
(nil))
(insn 4 3 5 (nil) (set (reg/v:V16SI 207 [ t1 ])
(reg:V16SI 177 $m1 [ t1 ])) -1 (nil)
(nil))
(insn 5 4 6 (nil) (set (reg/v:V16SI 208 [ t2 ])
(reg:V16SI 178 $m2 [ t2 ])) -1 (nil)
(nil))
(insn 6 5 7 (nil) (set (reg/v:V16SI 209 [ t3 ])
(reg:V16SI 179 $m3 [ t3 ])) -1 (nil)
(nil))
(insn 12 10 14 (nil) (parallel [
(set (reg/v:V16SI 206 [ t0 ])
(unspec:V16SI [
(reg/v:V16SI 209 [ t3 ])
(reg/v:V16SI 209 [ t3 ])
(reg/v:V16SI 207 [ t1 ])
] 460))
(set (reg/v:V16SI 208 [ t2 ])
(unspec:V16SI [
(reg/v:V16SI 207 [ t1 ])
(reg/v:V16SI 209 [ t3 ])
(reg/v:V16SI 207 [ t1 ])
] 461))
(set (nil)
(unspec:V16SI [
(reg/v:V16SI 207 [ t1 ])
(reg/v:V16SI 209 [ t3 ])
(reg/v:V16SI 207 [ t1 ])
] 462))
(set (reg/v:V16SI 208 [ t2 ])
(unspec:V16SI [
(reg/v:V16SI 207 [ t1 ])
(reg/v:V16SI 209 [ t3 ])
(reg/v:V16SI 207 [ t1 ])
] 463))
]) -1 (nil)
(nil))
(insn 16 15 17 (nil) (set (reg:V16SI 205 [ <result> ])
(reg/v:V16SI 206 [ t0 ])) -1 (nil)
(nil))
(jump_insn 17 16 18 (nil) (set (pc)
(label_ref 22)) -1 (nil)
(nil))
I do much appreciate all the help. I've been a gdb hacker for the
last 14 years and a gcc hacker for all of about 2 months. :-)
-Fred