Add support for output memory constraints.
authorChris Lattner <sabre@nondot.org>
Mon, 27 Feb 2006 23:45:39 +0000 (23:45 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 27 Feb 2006 23:45:39 +0000 (23:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26410 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 6b93a703cf248929e9121575bc7570a099de3834..a57c01a5847c9024e454f9b70174b770179e8e44 100644 (file)
@@ -1420,8 +1420,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
         assert(I.getType() != Type::VoidTy && "Bad inline asm!");
         OpVT = TLI.getValueType(I.getType());
       } else {
-        Value *CallOperand = I.getOperand(OpNum);
-        const Type *OpTy = CallOperand->getType();
+        const Type *OpTy = I.getOperand(OpNum)->getType();
         OpVT = TLI.getValueType(cast<PointerType>(OpTy)->getElementType());
         OpNum++;  // Consumes a call operand.
       }
@@ -1479,6 +1478,40 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
 
     switch (Constraints[i].Type) {
     case InlineAsm::isOutput: {
+      TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass;
+      if (ConstraintCode.size() == 1)   // not a physreg name.
+        CTy = TLI.getConstraintType(ConstraintCode[0]);
+      
+      if (CTy == TargetLowering::C_Memory) {
+        // Memory output.
+        SDOperand InOperandVal = getValue(I.getOperand(OpNum));
+        
+        // Check that the operand (the address to store to) isn't a float.
+        if (!MVT::isInteger(InOperandVal.getValueType()))
+          assert(0 && "MATCH FAIL!");
+        
+        if (!Constraints[i].isIndirectOutput)
+          assert(0 && "MATCH FAIL!");
+
+        OpNum++;  // Consumes a call operand.
+        
+        // Extend/truncate to the right pointer type if needed.
+        MVT::ValueType PtrType = TLI.getPointerTy();
+        if (InOperandVal.getValueType() < PtrType)
+          InOperandVal = DAG.getNode(ISD::ZERO_EXTEND, PtrType, InOperandVal);
+        else if (InOperandVal.getValueType() > PtrType)
+          InOperandVal = DAG.getNode(ISD::TRUNCATE, PtrType, InOperandVal);
+        
+        // Add information to the INLINEASM node to know about this output.
+        unsigned ResOpType = 4/*MEM*/ | (1 << 3);
+        AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32));
+        AsmNodeOperands.push_back(InOperandVal);
+        break;
+      }
+
+      // Otherwise, this is a register output.
+      assert(CTy == TargetLowering::C_RegisterClass && "Unknown op type!");
+
       // If this is an early-clobber output, or if there is an input
       // constraint that matches this, we need to reserve the input register
       // so no other inputs allocate to it.
@@ -1500,8 +1533,8 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
         assert(I.getType() != Type::VoidTy && "Bad inline asm!");
         RetValRegs = Regs;
       } else {
-        Value *CallOperand = I.getOperand(OpNum);
-        IndirectStoresToEmit.push_back(std::make_pair(Regs, CallOperand));
+        IndirectStoresToEmit.push_back(std::make_pair(Regs, 
+                                                      I.getOperand(OpNum)));
         OpNum++;  // Consumes a call operand.
       }
       
@@ -1511,10 +1544,8 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
       break;
     }
     case InlineAsm::isInput: {
-      Value *CallOperand = I.getOperand(OpNum);
+      SDOperand InOperandVal = getValue(I.getOperand(OpNum));
       OpNum++;  // Consumes a call operand.
-
-      SDOperand InOperandVal = getValue(CallOperand);
       
       if (isdigit(ConstraintCode[0])) {    // Matching constraint?
         // If this is required to match an output register we have already set,