Question on tablegen


I am trying to create a machine instruction for "extractelement". I
want to translate
r <- extractelement v, 0
mov r, v.x

I was looking at the dag I can use and I found vector_extract. The
inputs for this SDnode are a register and a iPtr constant. With that,
I need to create 4 separate def's to extract element 0, 1, 2, and 3
and translate to v.x, v.y, v.z, and v.w. I was wondering if I can use
the dag's 2nd input as an index into a list of strings and form the
assembly instruction, something like !strconcat("mov $dst, v.",
elemnames[$input]). I am still trying to learn the tablegen syntax and
semantics, so how to do this is not clear to me. I will appreciate any
suggestions on how to do this, or pointers to other places where
similar things are done.


One way to do this is to handle this in the AsmPrinter, with
operand modifiers.

For example, on x86 there are instructions with ${dst:call} in
their asm string. The "call" part is interpreted as an operand
modifier. The assembly printer looks for the "call" modifier
on MachineOperand::MO_Immediate operands
(in X86ATTAsmPrinter::printOperand), which lets it perform custom
printing for that type of operand. You could use a modifier which
tells the AsmPrinter to print an immediate as the appropriate



Thanks a lot. Using a modifier in the assembly string works for this
case. I am trying to solve a related problem. I am trying to print out
a set of "mov" ops for the vector_shuffle node. Since the source of
the "mov" is from one of the sources to vector_shuffle, depending on
the mask, I am not sure what assembly string to emit. For example, if
I have

d <- vector_shuffle s1, s2, <0,3>

I want to emit

mov d.x, s1.x
mov d.y, s2.y

For this, I need some thing like

"mov $d.x, <$src1 or $src2>.<something that depends on the mask>"

I can use the same modifier trick for which component of the source to
select, but I don't know how to select which of the sources to select
($src1 or $src2) depending on the mask. Do you have any suggestions?


I had a very similar problem and I solved it using a custom vector shuffle and addition instead of mov.

For example,
Vector_shuffle s1, s2, <0,3> is mapped to a custom instruction where I transform the swizzle to a 32bit integer mask and an inverted mask.

So I have dst, src0, src1, imm1, imm2
And I have my asm look similar to:
Add dst, src0.imm1, src1.imm2 and then in the asm printer I intercept vector_shuffle and I convert the integer to x,y,z,w, 0, 1 or _.
For example if the mask is to take x from s1 and yzw from s2, I would generate 0x1000 and 0x0234.
So my result looks like
Iadd d0, s1.x000, s2.0yzw

This allows you to do your vector shuffle in a single instruction.

It's not the cleanest approach but it works for me and I can encode up to 8 swizzle per immediate so works on vector sizes up to 8 in length.

Hope this helps,

I was wondering if there is a dag pattern for shuffle masks?