diff options
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 62a6b4f180..9492b33527 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4909,8 +4909,10 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { 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); - AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, + unsigned ResOpType = SawEarlyClobber ? + 7 /* MEM OVERLAPS EARLYCLOBBER */ : + 4/*MEM*/; + AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType | (1<<3), TLI.getPointerTy())); AsmNodeOperands.push_back(OpInfo.CallOperand); break; @@ -4963,7 +4965,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getZExtValue(); assert(((NumOps & 7) == 2 /*REGDEF*/ || (NumOps & 7) == 6 /*EARLYCLOBBER REGDEF*/ || - (NumOps & 7) == 4 /*MEM*/) && + (NumOps & 7) == 4 /*MEM*/ || + (NumOps & 7) == 7 /*MEM OVERLAPS EARLYCLOBBER*/) && "Skipped past definitions?"); CurOp += (NumOps>>3)+1; } @@ -4985,14 +4988,17 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { // Use the produced MatchedRegs object to MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag); - MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands); + MatchedRegs.AddInlineAsmOperands(SawEarlyClobber ? + 1 /*REGUSE*/ : + 5 /*REGUSE OVERLAPS EARLYCLOBBER*/, + DAG, AsmNodeOperands); break; } else { - assert((NumOps & 7) == 4/*MEM*/ && "Unknown matching constraint!"); + assert(((NumOps & 7) == 7/*MEM OVERLAPS EARLYCLOBBER */ || + (NumOps & 7) == 4) && "Unknown matching constraint!"); assert((NumOps >> 3) == 1 && "Unexpected number of operands"); // Add information to the INLINEASM node to know about this input. - unsigned ResOpType = 4/*MEM*/ | (1 << 3); - AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, + AsmNodeOperands.push_back(DAG.getTargetConstant(NumOps, TLI.getPointerTy())); AsmNodeOperands.push_back(AsmNodeOperands[CurOp+1]); break; @@ -5024,8 +5030,10 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { "Memory operands expect pointer values"); // Add information to the INLINEASM node to know about this input. - unsigned ResOpType = 4/*MEM*/ | (1 << 3); - AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType, + unsigned ResOpType = SawEarlyClobber ? + 7 /* MEM OVERLAPS EARLYCLOBBER */ : + 4/*MEM*/; + AsmNodeOperands.push_back(DAG.getTargetConstant(ResOpType | (1<<3), TLI.getPointerTy())); AsmNodeOperands.push_back(InOperandVal); break; @@ -5043,16 +5051,18 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag); - OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG, - AsmNodeOperands); + OpInfo.AssignedRegs.AddInlineAsmOperands(SawEarlyClobber ? + 5 /*REGUSE OVERLAPS EARLYCLOBBER*/: + 1/*REGUSE*/, + DAG, AsmNodeOperands); break; } case InlineAsm::isClobber: { // 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, - AsmNodeOperands); + OpInfo.AssignedRegs.AddInlineAsmOperands(6 /* EARLYCLOBBER REGDEF */, + DAG, AsmNodeOperands); break; } } |