Emulate i64 add with 3 instructions

Hello!

Is there a way to tell LLVM how to emulate an instruction with multiple others? Specifically, in our processor, there is no instruction for adding two i64s; it has to be done like this

dst_high32:dst_low32 = src1_low32 + src2_low32 (unsigned add; dst_high might contain the overflow bit)
dst_high32 = dst_high32 + src1_high32
dst_high32 = dst_high32 + src2_high32

I tried it with patterns like the following in InstrInfo.td (this is obviously wrong, but you have to start somewhere):

def : Pattern<(set LLRegs:$dst, (add LLRegs:$src1, LLRegs:$src2)), [(set LLRegs:$dst, (anyext (add (trunc LLRegs:$src1), (trunc LLRegs:$src2))))]>;

... but tablegen complains: "Cannot use 'add' in an output pattern!". Is this the right way to do it - that is, defining a pattern for an operation? ... Or better: What is the right way to do it?

Any help appreciated!

Thanks,
Johannes

you need to use machine instructions and not SDNodes in the pattern.

Here is an example from our backend:
// integer subtraction
// a - b ==> a + (-b)
def SUB_i8 : Pat<(sub GPRI8:$src0, GPRI8:$src1),
    (ADD_i8 GPRI8:$src0, (NEGATE_i8 GPRI8:$src1))>;

Where ADD_i8 and NEGATE_i8 are machine instructions.

Mica

Hi Johannes,

The usual way to achieve this is to use carry-setting / carry-using instructions, like addc/adde or subc/sube nodes in a dag.

Your target ISelLowering can use them to emulate an i64 unsupported add with 2 x i32 supported add.

You can look how this is done in the MSP430 or ARM backends for example.

Regards,