hi,

i've added a new type of inline assembly operands called MEMUSE, for 'm'
constraints that only read from memory.

in addition, i created an enum - InlineAsmFlags - of all possible operand
types (REGUSE, REGDEF, IMMUSE. MEMUSE, MEMDEF) and two global constants
InlineAsmMask and InlineAsmShift to extract these flags and the machine
operand count.

i've tested it on a llvm 2.0 based private backend and a test
application with lots of inline assembly. i did not test llvm-trunk very
carefully because of lacking applications that use inline assembly - my
handcrafted test cases work though.

florian



Index: include/llvm/CodeGen/SelectionDAGNodes.h
===================================================================
--- include/llvm/CodeGen/SelectionDAGNodes.h	(revision 41044)
+++ include/llvm/CodeGen/SelectionDAGNodes.h	(working copy)
@@ -566,7 +566,39 @@
   bool isBuildVectorAllZeros(const SDNode *N);
   
   //===--------------------------------------------------------------------===//
-  /// MemIndexedMode enum - This enum defines the load / store indexed 
+  /// InlineAsmFlags enum - This enum defines the flags of inline assembly
+  /// operands.
+  ///   REGUSE    A use of a register.
+  ///   REGDEF    A def of a register.
+  ///   IMMUSE    An immediate operand
+  ///   MEMUSE    A memory load.
+  ///   MEMDEF    A memory store.
+  ///
+  /// The operand flags of inline assembly SDNodes (and later machine
+  /// instructions) consist of:
+  ///   * 3 flag bits.
+  ///   * The number of machine operands corresponding to an inline assembly
+  ///     operand.
+  ///
+  /// opflags = (flags | (#ops << InlineAsmShift))
+  ///
+  enum InlineAsmFlags {
+    REGUSE = 1,
+    REGDEF = 2,
+    IMMUSE = 3,
+    MEMUSE = 4,
+    MEMDEF = 5
+  };
+
+  /// InlineAsmMask - Mask to access the flags of inline assembly operands.
+  static const int InlineAsmMask = 7;
+
+  /// InlineAsmShift - Shift value to access the number of machine operand of an
+  /// inline assembly operand.
+  static const int InlineAsmShift = 3;
+  
+  //===--------------------------------------------------------------------===//
+  /// MemIndexedMode enum - This enum defines the load / store indexed
   /// addressing modes.
   ///
   /// UNINDEXED    "Normal" load / store. The effective address is already
Index: lib/CodeGen/AsmPrinter.cpp
===================================================================
--- lib/CodeGen/AsmPrinter.cpp	(revision 41044)
+++ lib/CodeGen/AsmPrinter.cpp	(working copy)
@@ -1076,7 +1076,7 @@
         for (; Val; --Val) {
           if (OpNo >= MI->getNumOperands()) break;
           unsigned OpFlags = MI->getOperand(OpNo).getImmedValue();
-          OpNo += (OpFlags >> 3) + 1;
+          OpNo += (OpFlags >> ISD::InlineAsmShift) + 1;
         }
 
         if (OpNo >= MI->getNumOperands()) {
@@ -1086,7 +1086,8 @@
           ++OpNo;  // Skip over the ID number.
 
           AsmPrinter *AP = const_cast<AsmPrinter*>(this);
-          if ((OpFlags & 7) == 4 /*ADDR MODE*/) {
+          if ((OpFlags & ISD::InlineAsmMask) == ISD::MEMUSE ||
+              (OpFlags & ISD::InlineAsmMask) == ISD::MEMDEF) {
             Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant,
                                               Modifier[0] ? Modifier : 0);
           } else {
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	(revision 41044)
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	(working copy)
@@ -3055,7 +3055,9 @@
 void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
                                         std::vector<SDOperand> &Ops) const {
   MVT::ValueType IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
-  Ops.push_back(DAG.getTargetConstant(Code | (Regs.size() << 3), IntPtrTy));
+  Ops.push_back(DAG.getTargetConstant(Code |
+                                        (Regs.size() << ISD::InlineAsmShift),
+                                      IntPtrTy));
   for (unsigned i = 0, e = Regs.size(); i != e; ++i)
     Ops.push_back(DAG.getRegister(Regs[i], RegVT));
 }
@@ -3532,7 +3534,7 @@
         assert(OpInfo.isIndirect && "Memory output must be indirect operand");
 
         // Add information to the INLINEASM node to know about this output.
-        unsigned ResOpType = 4/*MEM*/ | (1 << 3);
+        unsigned ResOpType = ISD::MEMDEF | (1 << ISD::InlineAsmShift);
         AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, 
                                                         TLI.getPointerTy()));
         AsmNodeOperands.push_back(OpInfo.CallOperand);
@@ -3562,7 +3564,7 @@
       
       // Add information to the INLINEASM node to know that this register is
       // set.
-      OpInfo.AssignedRegs.AddInlineAsmOperands(2 /*REGDEF*/, DAG,
+      OpInfo.AssignedRegs.AddInlineAsmOperands(ISD::REGDEF, DAG,
                                                AsmNodeOperands);
       break;
     }
@@ -3581,20 +3583,20 @@
           // Advance to the next operand.
           unsigned NumOps = 
             cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getValue();
-          assert(((NumOps & 7) == 2 /*REGDEF*/ ||
-                  (NumOps & 7) == 4 /*MEM*/) &&
+          assert(((NumOps & ISD::InlineAsmMask) == ISD::REGDEF ||
+                  (NumOps & ISD::InlineAsmMask) == ISD::MEMDEF) &&
                  "Skipped past definitions?");
-          CurOp += (NumOps>>3)+1;
+          CurOp += (NumOps >> ISD::InlineAsmShift) + 1;
         }
 
         unsigned NumOps = 
           cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getValue();
-        if ((NumOps & 7) == 2 /*REGDEF*/) {
-          // Add NumOps>>3 registers to MatchedRegs.
+        if ((NumOps & ISD::InlineAsmMask) == ISD::REGDEF) {
+          // Add NumOps>>ISD::InlineAsmShift registers to MatchedRegs.
           RegsForValue MatchedRegs;
           MatchedRegs.ValueVT = InOperandVal.getValueType();
           MatchedRegs.RegVT   = AsmNodeOperands[CurOp+1].getValueType();
-          for (unsigned i = 0, e = NumOps>>3; i != e; ++i) {
+          for (unsigned i = 0, e = NumOps>>ISD::InlineAsmShift; i != e; ++i) {
             unsigned Reg =
               cast<RegisterSDNode>(AsmNodeOperands[++CurOp])->getReg();
             MatchedRegs.Regs.push_back(Reg);
@@ -3602,10 +3604,11 @@
         
           // Use the produced MatchedRegs object to 
           MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
-          MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
+          MatchedRegs.AddInlineAsmOperands(ISD::REGUSE, DAG, AsmNodeOperands);
           break;
         } else {
-          assert((NumOps & 7) == 4/*MEM*/ && "Unknown matching constraint!");
+          assert((NumOps & ISD::InlineAsmMask) == ISD::MEMDEF && 
+		 "Unknown matching constraint!");
           assert(0 && "matching constraints for memory operands unimp");
         }
       }
@@ -3624,7 +3627,7 @@
         }
         
         // Add information to the INLINEASM node to know about this input.
-        unsigned ResOpType = 3 /*IMM*/ | (1 << 3);
+        unsigned ResOpType = ISD::IMMUSE | (1 << ISD::InlineAsmShift);
         AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, 
                                                         TLI.getPointerTy()));
         AsmNodeOperands.push_back(InOperandVal);
@@ -3635,7 +3638,7 @@
                "Memory operands expect pointer values");
                
         // Add information to the INLINEASM node to know about this input.
-        unsigned ResOpType = 4/*MEM*/ | (1 << 3);
+        unsigned ResOpType = ISD::MEMUSE | (1 << ISD::InlineAsmShift);
         AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType,
                                                         TLI.getPointerTy()));
         AsmNodeOperands.push_back(InOperandVal);
@@ -3654,7 +3657,7 @@
 
       OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
       
-      OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG,
+      OpInfo.AssignedRegs.AddInlineAsmOperands(ISD::REGUSE, DAG,
                                                AsmNodeOperands);
       break;
     }
@@ -3662,7 +3665,7 @@
       // Add the clobbered value to the operand list, so that the register
       // allocator is aware that the physreg got clobbered.
       if (!OpInfo.AssignedRegs.Regs.empty())
-        OpInfo.AssignedRegs.AddInlineAsmOperands(2/*REGDEF*/, DAG,
+        OpInfo.AssignedRegs.AddInlineAsmOperands(ISD::REGDEF, DAG,
                                                  AsmNodeOperands);
       break;
     }
@@ -4898,12 +4901,15 @@
   
   while (i != e) {
     unsigned Flags = cast<ConstantSDNode>(InOps[i])->getValue();
-    if ((Flags & 7) != 4 /*MEM*/) {
+    if ((Flags & ISD::InlineAsmMask) != ISD::MEMDEF &&
+        (Flags & ISD::InlineAsmMask) != ISD::MEMUSE) {
       // Just skip over this operand, copying the operands verbatim.
-      Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+(Flags >> 3) + 1);
-      i += (Flags >> 3) + 1;
+      Ops.insert(Ops.end(), InOps.begin()+i, InOps.begin()+i+
+                                             (Flags >> ISD::InlineAsmShift) + 1);
+      i += (Flags >> ISD::InlineAsmShift) + 1;
     } else {
-      assert((Flags >> 3) == 1 && "Memory operand with multiple values?");
+      assert((Flags >> ISD::InlineAsmShift) == 1 &&
+             "Memory operand with multiple values?");
       // Otherwise, this is a memory operand.  Ask the target to select it.
       std::vector<SDOperand> SelOps;
       if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps, DAG)) {
@@ -4913,7 +4919,8 @@
       
       // Add this to the output node.
       MVT::ValueType IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
-      Ops.push_back(DAG.getTargetConstant(4/*MEM*/ | (SelOps.size() << 3),
+      Ops.push_back(DAG.getTargetConstant(Flags & ISD::InlineAsmMask |
+                                          (SelOps.size() << ISD::InlineAsmShift),
                                           IntPtrTy));
       Ops.insert(Ops.end(), SelOps.begin(), SelOps.end());
       i += 2;
Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	(revision 41044)
+++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	(working copy)
@@ -1406,7 +1406,8 @@
 
     bool HasInFlag = Ops.back().getValueType() == MVT::Flag;
     for (unsigned i = 2, e = Ops.size()-HasInFlag; i < e; ) {
-      unsigned NumVals = cast<ConstantSDNode>(Ops[i])->getValue() >> 3;
+      unsigned NumVals = cast<ConstantSDNode>(Ops[i])->getValue() >>
+                         ISD::InlineAsmShift;
       for (++i; NumVals; ++i, --NumVals) {
         SDOperand Op = LegalizeOp(Ops[i]);
         if (Op != Ops[i]) {
Index: lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/ScheduleDAG.cpp	(revision 41044)
+++ lib/CodeGen/SelectionDAG/ScheduleDAG.cpp	(working copy)
@@ -733,26 +733,26 @@
       // Add all of the operand registers to the instruction.
       for (unsigned i = 2; i != NumOps;) {
         unsigned Flags = cast<ConstantSDNode>(Node->getOperand(i))->getValue();
-        unsigned NumVals = Flags >> 3;
+        unsigned NumVals = Flags >> ISD::InlineAsmShift;
         
         MI->addImmOperand(Flags);
         ++i;  // Skip the ID value.
         
-        switch (Flags & 7) {
+        switch (Flags & ISD::InlineAsmMask) {
         default: assert(0 && "Bad flags!");
-        case 1:  // Use of register.
+        case ISD::REGUSE:  // Use of register.
           for (; NumVals; --NumVals, ++i) {
             unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
             MI->addRegOperand(Reg, false);
           }
           break;
-        case 2:   // Def of register.
+        case ISD::REGDEF:   // Def of register.
           for (; NumVals; --NumVals, ++i) {
             unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
             MI->addRegOperand(Reg, true);
           }
           break;
-        case 3: { // Immediate.
+        case ISD::IMMUSE: { // Immediate.
           assert(NumVals == 1 && "Unknown immediate value!");
           if (ConstantSDNode *CS=dyn_cast<ConstantSDNode>(Node->getOperand(i))){
             MI->addImmOperand(CS->getValue());
@@ -764,7 +764,8 @@
           ++i;
           break;
         }
-        case 4:  // Addressing mode.
+        case ISD::MEMUSE:  // Addressing mode.
+        case ISD::MEMDEF:  // Addressing mode.
           // The addressing mode has been selected, just add all of the
           // operands to the machine instruction.
           for (; NumVals; --NumVals, ++i)

_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to