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