[LLVMdev] adde/addc

Richard Osborne rlsosborne at googlemail.com
Mon Sep 8 04:22:14 PDT 2008


Richard Pennington wrote:
> My target doesn't support 64 bit arithmetic, so I'd like to supply 
> definitions for adde/addc. The problem is I can't seem to figure out the 
> magic. Here's an example of what I need to generate:
>
> # two i64s in r5/r6 and r7/r8
> # result in r1/r2, carry in r3
>
> # adde
>     add r2, r6, r8
>     cmpltu r3, r2, r6	# compute carry
>
> # addc
>      add r1, r5, r7
>      add r1, zero, r3
>
> Is this possible given the current code generation stuff? Is there 
> another approach that I should consider?
>
> -Rich
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>   
I needed to do exactly the same for my target. I set ISD::ADD to be 
custom expanded (setOperationAction(ISD::ADD, MVT::i64, Custom)) and the 
same for ISD::SUB. I then added the following code to my target to do 
the expansion:

ExpandADDSUB(SDNode *N, SelectionDAG &DAG)
{
assert(N->getValueType(0) == MVT::i64 &&
(N->getOpcode() == ISD::ADD || N->getOpcode() == ISD::SUB) &&
"Unknown operand to lower!");

// Extract components
SDOperand LHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 
N->getOperand(0),
DAG.getConstant(0, MVT::i32));
SDOperand LHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 
N->getOperand(0),
DAG.getConstant(1, MVT::i32));
SDOperand RHSL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 
N->getOperand(1),
DAG.getConstant(0, MVT::i32));
SDOperand RHSH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 
N->getOperand(1),
DAG.getConstant(1, MVT::i32));

// Expand
SDOperand Lo = DAG.getNode(N->getOpcode(), MVT::i32, LHSL, RHSL);

ISD::CondCode CarryCC = (N->getOpcode() == ISD::ADD) ? ISD::SETULT : 
ISD::SETUGT;
SDOperand Carry = DAG.getSetCC(MVT::i32, Lo, LHSL, CarryCC);

SDOperand Hi = DAG.getNode(N->getOpcode(), MVT::i32, LHSH, Carry);
Hi = DAG.getNode(N->getOpcode(), MVT::i32, Hi, RHSH);
// Merge the pieces
return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi).Val;
}

In LowerOperation I lower add and sub using:

case ISD::ADD:
case ISD::SUB: return SDOperand(ExpandADDSUB(Op.Val, DAG),0);

This is for LLVM 2.3. I've haven't updated to the head recently so there 
might be additional changes needed for the new legalize types 
infrastructure. Hope this helps,

Richard



More information about the llvm-dev mailing list