mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-03 14:21:30 +00:00 
			
		
		
		
	Rewrite a bunch of the CBE's inline asm code, giving it the
ability to handle indirect input operands. This fixes PR2407. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51952 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		@@ -2956,10 +2956,6 @@ static std::string gccifyAsm(std::string asmstr) {
 | 
				
			|||||||
void CWriter::visitInlineAsm(CallInst &CI) {
 | 
					void CWriter::visitInlineAsm(CallInst &CI) {
 | 
				
			||||||
  InlineAsm* as = cast<InlineAsm>(CI.getOperand(0));
 | 
					  InlineAsm* as = cast<InlineAsm>(CI.getOperand(0));
 | 
				
			||||||
  std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints();
 | 
					  std::vector<InlineAsm::ConstraintInfo> Constraints = as->ParseConstraints();
 | 
				
			||||||
  std::vector<std::pair<std::string, Value*> > Input;
 | 
					 | 
				
			||||||
  std::vector<std::pair<std::string, std::pair<Value*, int> > > Output;
 | 
					 | 
				
			||||||
  std::string Clobber;
 | 
					 | 
				
			||||||
  unsigned ValueCount = 0;
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  std::vector<std::pair<Value*, int> > ResultVals;
 | 
					  std::vector<std::pair<Value*, int> > ResultVals;
 | 
				
			||||||
  if (CI.getType() == Type::VoidTy)
 | 
					  if (CI.getType() == Type::VoidTy)
 | 
				
			||||||
@@ -2971,61 +2967,103 @@ void CWriter::visitInlineAsm(CallInst &CI) {
 | 
				
			|||||||
    ResultVals.push_back(std::make_pair(&CI, -1));
 | 
					    ResultVals.push_back(std::make_pair(&CI, -1));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  // Fix up the asm string for gcc and emit it.
 | 
				
			||||||
 | 
					  Out << "__asm__ volatile (\"" << gccifyAsm(as->getAsmString()) << "\"\n";
 | 
				
			||||||
 | 
					  Out << "        :";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  unsigned ValueCount = 0;
 | 
				
			||||||
 | 
					  bool IsFirst = true;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Convert over all the output constraints.
 | 
				
			||||||
  for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),
 | 
					  for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),
 | 
				
			||||||
       E = Constraints.end(); I != E; ++I) {
 | 
					       E = Constraints.end(); I != E; ++I) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (I->Type != InlineAsm::isOutput) {
 | 
				
			||||||
 | 
					      ++ValueCount;
 | 
				
			||||||
 | 
					      continue;  // Ignore non-output constraints.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
 | 
					    assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
 | 
				
			||||||
    std::string C = InterpretASMConstraint(*I);
 | 
					    std::string C = InterpretASMConstraint(*I);
 | 
				
			||||||
    if (C.empty()) continue;
 | 
					    if (C.empty()) continue;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    switch (I->Type) {
 | 
					    if (!IsFirst) {
 | 
				
			||||||
    default: assert(0 && "Unknown asm constraint");
 | 
					 | 
				
			||||||
    case InlineAsm::isInput: {
 | 
					 | 
				
			||||||
      assert(ValueCount >= ResultVals.size() && "Input can't refer to result");
 | 
					 | 
				
			||||||
      Value *V = CI.getOperand(ValueCount-ResultVals.size()+1);
 | 
					 | 
				
			||||||
      Input.push_back(std::make_pair(C, V));
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    case InlineAsm::isOutput: {
 | 
					 | 
				
			||||||
      std::pair<Value*, int> V;
 | 
					 | 
				
			||||||
      if (ValueCount < ResultVals.size())
 | 
					 | 
				
			||||||
        V = ResultVals[ValueCount];
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        V = std::make_pair(CI.getOperand(ValueCount-ResultVals.size()+1), -1);
 | 
					 | 
				
			||||||
      Output.push_back(std::make_pair("="+((I->isEarlyClobber ? "&" : "")+C),
 | 
					 | 
				
			||||||
                                      V));
 | 
					 | 
				
			||||||
      break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    case InlineAsm::isClobber:
 | 
					 | 
				
			||||||
      Clobber += ",\"" + C + "\"";
 | 
					 | 
				
			||||||
      continue;  // Not an actual argument.
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    ++ValueCount; // Consumes an argument.
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  // Fix up the asm string for gcc.
 | 
					 | 
				
			||||||
  std::string asmstr = gccifyAsm(as->getAsmString());
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  Out << "__asm__ volatile (\"" << asmstr << "\"\n";
 | 
					 | 
				
			||||||
  Out << "        :";
 | 
					 | 
				
			||||||
  for (unsigned i = 0, e = Output.size(); i != e; ++i) {
 | 
					 | 
				
			||||||
    if (i)
 | 
					 | 
				
			||||||
      Out << ", ";
 | 
					      Out << ", ";
 | 
				
			||||||
    Out << "\"" << Output[i].first << "\"("
 | 
					      IsFirst = false;
 | 
				
			||||||
        << GetValueName(Output[i].second.first);
 | 
					 | 
				
			||||||
    if (Output[i].second.second != -1)
 | 
					 | 
				
			||||||
      Out << ".field" << Output[i].second.second; // Multiple retvals.
 | 
					 | 
				
			||||||
    Out << ")";
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Unpack the dest.
 | 
				
			||||||
 | 
					    Value *DestVal;
 | 
				
			||||||
 | 
					    int DestValNo = -1;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (ValueCount < ResultVals.size()) {
 | 
				
			||||||
 | 
					      DestVal = ResultVals[ValueCount].first;
 | 
				
			||||||
 | 
					      DestValNo = ResultVals[ValueCount].second;
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					      DestVal = CI.getOperand(ValueCount-ResultVals.size()+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (I->isEarlyClobber)
 | 
				
			||||||
 | 
					      C = "&"+C;
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					    Out << "\"=" << C << "\"(" << GetValueName(DestVal);
 | 
				
			||||||
 | 
					    if (DestValNo != -1)
 | 
				
			||||||
 | 
					      Out << ".field" << DestValNo; // Multiple retvals.
 | 
				
			||||||
 | 
					    Out << ")";
 | 
				
			||||||
 | 
					    ++ValueCount;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Convert over all the input constraints.
 | 
				
			||||||
  Out << "\n        :";
 | 
					  Out << "\n        :";
 | 
				
			||||||
  for (unsigned i = 0, e = Input.size(); i != e; ++i) {
 | 
					  IsFirst = true;
 | 
				
			||||||
    if (i)
 | 
					  ValueCount = 0;
 | 
				
			||||||
 | 
					  for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),
 | 
				
			||||||
 | 
					       E = Constraints.end(); I != E; ++I) {
 | 
				
			||||||
 | 
					    if (I->Type != InlineAsm::isInput) {
 | 
				
			||||||
 | 
					      ++ValueCount;
 | 
				
			||||||
 | 
					      continue;  // Ignore non-input constraints.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
 | 
				
			||||||
 | 
					    std::string C = InterpretASMConstraint(*I);
 | 
				
			||||||
 | 
					    if (C.empty()) continue;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!IsFirst) {
 | 
				
			||||||
      Out << ", ";
 | 
					      Out << ", ";
 | 
				
			||||||
    Out << "\"" << Input[i].first << "\"(";
 | 
					      IsFirst = false;
 | 
				
			||||||
    writeOperand(Input[i].second);
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    assert(ValueCount >= ResultVals.size() && "Input can't refer to result");
 | 
				
			||||||
 | 
					    Value *SrcVal = CI.getOperand(ValueCount-ResultVals.size()+1);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Out << "\"" << C << "\"(";
 | 
				
			||||||
 | 
					    if (!I->isIndirect)
 | 
				
			||||||
 | 
					      writeOperand(SrcVal);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      writeOperandDeref(SrcVal);
 | 
				
			||||||
    Out << ")";
 | 
					    Out << ")";
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (Clobber.size())
 | 
					  
 | 
				
			||||||
    Out << "\n        :" << Clobber.substr(1);
 | 
					  // Convert over the clobber constraints.
 | 
				
			||||||
 | 
					  IsFirst = true;
 | 
				
			||||||
 | 
					  ValueCount = 0;
 | 
				
			||||||
 | 
					  for (std::vector<InlineAsm::ConstraintInfo>::iterator I = Constraints.begin(),
 | 
				
			||||||
 | 
					       E = Constraints.end(); I != E; ++I) {
 | 
				
			||||||
 | 
					    if (I->Type != InlineAsm::isClobber)
 | 
				
			||||||
 | 
					      continue;  // Ignore non-input constraints.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(I->Codes.size() == 1 && "Too many asm constraint codes to handle");
 | 
				
			||||||
 | 
					    std::string C = InterpretASMConstraint(*I);
 | 
				
			||||||
 | 
					    if (C.empty()) continue;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!IsFirst) {
 | 
				
			||||||
 | 
					      Out << ", ";
 | 
				
			||||||
 | 
					      IsFirst = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Out << '\"' << C << '"';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  Out << ")";
 | 
					  Out << ")";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								test/CodeGen/CBackend/2008-06-04-IndirectMem.ll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								test/CodeGen/CBackend/2008-06-04-IndirectMem.ll
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					; RUN: llvm-as < %s | llc -march=c | grep {"m"(llvm_cbe_newcw))}
 | 
				
			||||||
 | 
					; PR2407
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
 | 
				
			||||||
 | 
					target triple = "i386-pc-linux-gnu"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define void @foo() {
 | 
				
			||||||
 | 
					  %newcw = alloca i16             ; <i16*> [#uses=2]
 | 
				
			||||||
 | 
					  call void asm sideeffect "fldcw $0", "*m,~{dirflag},~{fpsr},~{flags}"( i16*
 | 
				
			||||||
 | 
					%newcw ) nounwind 
 | 
				
			||||||
 | 
					  ret void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user