mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-25 00:29:20 +00:00
Back out r131444 and r131438; they're breaking nightly tests. I'll look into
it more tomorrow. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131451 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b70eac42e7
commit
c93943b6fe
@ -1414,6 +1414,14 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
|
||||
if (Subtarget->IsCalleePop(isVarArg, CC))
|
||||
return false;
|
||||
|
||||
// Handle *simple* calls for now.
|
||||
const Type *RetTy = CS.getType();
|
||||
MVT RetVT;
|
||||
if (RetTy->isVoidTy())
|
||||
RetVT = MVT::isVoid;
|
||||
else if (!isTypeLegal(RetTy, RetVT, true))
|
||||
return false;
|
||||
|
||||
// Materialize callee address in a register. FIXME: GV address can be
|
||||
// handled with a CALLpcrel32 instead.
|
||||
X86AddressMode CalleeAM;
|
||||
@ -1428,6 +1436,13 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
|
||||
} else
|
||||
return false;
|
||||
|
||||
// Allow calls which produce i1 results.
|
||||
bool AndToI1 = false;
|
||||
if (RetVT == MVT::i1) {
|
||||
RetVT = MVT::i8;
|
||||
AndToI1 = true;
|
||||
}
|
||||
|
||||
// Deal with call operands first.
|
||||
SmallVector<const Value *, 8> ArgVals;
|
||||
SmallVector<unsigned, 8> Args;
|
||||
@ -1682,72 +1697,62 @@ bool X86FastISel::X86SelectCall(const Instruction *I) {
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(AdjStackUp))
|
||||
.addImm(NumBytes).addImm(NumBytesCallee);
|
||||
|
||||
// Build info for return calling conv lowering code.
|
||||
// FIXME: This is practically a copy-paste from TargetLowering::LowerCallTo.
|
||||
SmallVector<ISD::InputArg, 32> Ins;
|
||||
SmallVector<EVT, 4> RetTys;
|
||||
ComputeValueVTs(TLI, I->getType(), RetTys);
|
||||
for (unsigned i = 0, e = RetTys.size(); i != e; ++i) {
|
||||
EVT VT = RetTys[i];
|
||||
EVT RegisterVT = TLI.getRegisterType(I->getParent()->getContext(), VT);
|
||||
unsigned NumRegs = TLI.getNumRegisters(I->getParent()->getContext(), VT);
|
||||
for (unsigned j = 0; j != NumRegs; ++j) {
|
||||
ISD::InputArg MyFlags;
|
||||
MyFlags.VT = RegisterVT.getSimpleVT();
|
||||
MyFlags.Used = !CS.getInstruction()->use_empty();
|
||||
if (CS.paramHasAttr(0, Attribute::SExt))
|
||||
MyFlags.Flags.setSExt();
|
||||
if (CS.paramHasAttr(0, Attribute::ZExt))
|
||||
MyFlags.Flags.setZExt();
|
||||
if (CS.paramHasAttr(0, Attribute::InReg))
|
||||
MyFlags.Flags.setInReg();
|
||||
Ins.push_back(MyFlags);
|
||||
}
|
||||
}
|
||||
|
||||
// Now handle call return values.
|
||||
// Now handle call return value (if any).
|
||||
SmallVector<unsigned, 4> UsedRegs;
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
CCState CCRetInfo(CC, false, TM, RVLocs, I->getParent()->getContext());
|
||||
unsigned ResultReg = FuncInfo.CreateRegs(I->getType());
|
||||
CCRetInfo.AnalyzeCallResult(Ins, RetCC_X86);
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i) {
|
||||
EVT CopyVT = RVLocs[i].getValVT();
|
||||
unsigned CopyReg = ResultReg + i;
|
||||
if (RetVT != MVT::isVoid) {
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
CCState CCInfo(CC, false, TM, RVLocs, I->getParent()->getContext());
|
||||
CCInfo.AnalyzeCallResult(RetVT, RetCC_X86);
|
||||
|
||||
// Copy all of the result registers out of their specified physreg.
|
||||
assert(RVLocs.size() == 1 && "Can't handle multi-value calls!");
|
||||
EVT CopyVT = RVLocs[0].getValVT();
|
||||
TargetRegisterClass* DstRC = TLI.getRegClassFor(CopyVT);
|
||||
|
||||
// If this is a call to a function that returns an fp value on the x87 fp
|
||||
// stack, but where we prefer to use the value in xmm registers, copy it
|
||||
// out as F80 and use a truncate to move it from fp stack reg to xmm reg.
|
||||
if ((RVLocs[i].getLocReg() == X86::ST0 ||
|
||||
RVLocs[i].getLocReg() == X86::ST1) &&
|
||||
if ((RVLocs[0].getLocReg() == X86::ST0 ||
|
||||
RVLocs[0].getLocReg() == X86::ST1) &&
|
||||
isScalarFPTypeInSSEReg(RVLocs[0].getValVT())) {
|
||||
CopyVT = MVT::f80;
|
||||
CopyReg = createResultReg(X86::RFP80RegisterClass);
|
||||
DstRC = X86::RFP80RegisterClass;
|
||||
}
|
||||
|
||||
unsigned ResultReg = createResultReg(DstRC);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
|
||||
ResultReg+i).addReg(RVLocs[i].getLocReg());
|
||||
UsedRegs.push_back(RVLocs[i].getLocReg());
|
||||
ResultReg).addReg(RVLocs[0].getLocReg());
|
||||
UsedRegs.push_back(RVLocs[0].getLocReg());
|
||||
|
||||
if (CopyVT != RVLocs[i].getValVT()) {
|
||||
if (CopyVT != RVLocs[0].getValVT()) {
|
||||
// Round the F80 the right size, which also moves to the appropriate xmm
|
||||
// register. This is accomplished by storing the F80 value in memory and
|
||||
// then loading it back. Ewww...
|
||||
EVT ResVT = RVLocs[i].getValVT();
|
||||
EVT ResVT = RVLocs[0].getValVT();
|
||||
unsigned Opc = ResVT == MVT::f32 ? X86::ST_Fp80m32 : X86::ST_Fp80m64;
|
||||
unsigned MemSize = ResVT.getSizeInBits()/8;
|
||||
int FI = MFI.CreateStackObject(MemSize, MemSize, false);
|
||||
addFrameReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(Opc)), FI)
|
||||
.addReg(CopyReg);
|
||||
.addReg(ResultReg);
|
||||
DstRC = ResVT == MVT::f32
|
||||
? X86::FR32RegisterClass : X86::FR64RegisterClass;
|
||||
Opc = ResVT == MVT::f32 ? X86::MOVSSrm : X86::MOVSDrm;
|
||||
ResultReg = createResultReg(DstRC);
|
||||
addFrameReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(Opc), ResultReg + i), FI);
|
||||
TII.get(Opc), ResultReg), FI);
|
||||
}
|
||||
}
|
||||
|
||||
if (RVLocs.size())
|
||||
UpdateValueMap(I, ResultReg, RVLocs.size());
|
||||
if (AndToI1) {
|
||||
// Mask out all but lowest bit for some call which produces an i1.
|
||||
unsigned AndResult = createResultReg(X86::GR8RegisterClass);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
|
||||
TII.get(X86::AND8ri), AndResult).addReg(ResultReg).addImm(1);
|
||||
ResultReg = AndResult;
|
||||
}
|
||||
|
||||
UpdateValueMap(I, ResultReg);
|
||||
}
|
||||
|
||||
// Set all unused physreg defs as dead.
|
||||
static_cast<MachineInstr *>(MIB)->setPhysRegsDeadExcept(UsedRegs, TRI);
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llc < %s -fast-isel -march=x86 | FileCheck %s
|
||||
; RUN: llc < %s -fast-isel -march=x86 | grep and
|
||||
|
||||
define i32 @t() nounwind {
|
||||
tak:
|
||||
@ -8,8 +8,6 @@ BB1:
|
||||
ret i32 1
|
||||
BB2:
|
||||
ret i32 0
|
||||
; CHECK: calll
|
||||
; CHECK-NEXT: testb $1
|
||||
}
|
||||
|
||||
declare i1 @foo() zeroext nounwind
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llc < %s -mtriple x86_64-apple-darwin11 -O0 -fast-isel-abort | FileCheck %s
|
||||
; RUN: llc < %s -mtriple x86_64-apple-darwin11 -O0 | FileCheck %s
|
||||
|
||||
%struct.x = type { i64, i64 }
|
||||
%addovf = type { i32, i1 }
|
||||
|
Loading…
Reference in New Issue
Block a user