[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