Upgrade our copy of llvm/clang to 3.0 release. Release notes can be
found at: http://llvm.org/releases/3.0/docs/ReleaseNotes.html MFC after: 1 week
This commit is contained in:
commit
f8254f43c5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=228379
@ -527,18 +527,20 @@ bool CompileUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
|
||||
|
||||
// Get the raw data form of the large APInt.
|
||||
const APInt Val = CI->getValue();
|
||||
const char *Ptr = (const char*)Val.getRawData();
|
||||
const uint64_t *Ptr64 = Val.getRawData();
|
||||
|
||||
int NumBytes = Val.getBitWidth() / 8; // 8 bits per byte.
|
||||
bool LittleEndian = Asm->getTargetData().isLittleEndian();
|
||||
int Incr = (LittleEndian ? 1 : -1);
|
||||
int Start = (LittleEndian ? 0 : NumBytes - 1);
|
||||
int Stop = (LittleEndian ? NumBytes : -1);
|
||||
|
||||
// Output the constant to DWARF one byte at a time.
|
||||
for (; Start != Stop; Start += Incr)
|
||||
addUInt(Block, 0, dwarf::DW_FORM_data1,
|
||||
(unsigned char)0xFF & Ptr[Start]);
|
||||
for (int i = 0; i < NumBytes; i++) {
|
||||
uint8_t c;
|
||||
if (LittleEndian)
|
||||
c = Ptr64[i / 8] >> (8 * (i & 7));
|
||||
else
|
||||
c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
|
||||
addUInt(Block, 0, dwarf::DW_FORM_data1, c);
|
||||
}
|
||||
|
||||
addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
|
||||
return true;
|
||||
|
@ -119,7 +119,8 @@ LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple,
|
||||
// we'll crash later.
|
||||
// Provide the user with a useful error message about what's wrong.
|
||||
assert(AsmInfo && "MCAsmInfo not initialized."
|
||||
"Make sure you include the correct TargetSelect.h!");
|
||||
"Make sure you include the correct TargetSelect.h"
|
||||
"and that InitializeAllTargetMCs() is being invoked!");
|
||||
}
|
||||
|
||||
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
|
||||
|
@ -2034,14 +2034,17 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec &CR,
|
||||
return false;
|
||||
|
||||
APInt Range = ComputeRange(First, Last);
|
||||
double Density = TSize.roundToDouble() / Range.roundToDouble();
|
||||
if (Density < 0.4)
|
||||
// The density is TSize / Range. Require at least 40%.
|
||||
// It should not be possible for IntTSize to saturate for sane code, but make
|
||||
// sure we handle Range saturation correctly.
|
||||
uint64_t IntRange = Range.getLimitedValue(UINT64_MAX/10);
|
||||
uint64_t IntTSize = TSize.getLimitedValue(UINT64_MAX/10);
|
||||
if (IntTSize * 10 < IntRange * 4)
|
||||
return false;
|
||||
|
||||
DEBUG(dbgs() << "Lowering jump table\n"
|
||||
<< "First entry: " << First << ". Last entry: " << Last << '\n'
|
||||
<< "Range: " << Range
|
||||
<< ". Size: " << TSize << ". Density: " << Density << "\n\n");
|
||||
<< "Range: " << Range << ". Size: " << TSize << ".\n\n");
|
||||
|
||||
// Get the MachineFunction which holds the current MBB. This is used when
|
||||
// inserting any additional MBBs necessary to represent the switch.
|
||||
|
@ -506,7 +506,9 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
|
||||
// Add information about the stub reference to MachOMMI so that the stub
|
||||
// gets emitted by the asmprinter.
|
||||
MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym =
|
||||
GV->hasHiddenVisibility() ? MachOMMI.getHiddenGVStubEntry(SSym) :
|
||||
MachOMMI.getGVStubEntry(SSym);
|
||||
if (StubSym.getPointer() == 0) {
|
||||
MCSymbol *Sym = Mang->getSymbol(GV);
|
||||
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
|
||||
@ -534,7 +536,9 @@ getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang,
|
||||
// Add information about the stub reference to MachOMMI so that the stub
|
||||
// gets emitted by the asmprinter.
|
||||
MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
|
||||
MachineModuleInfoImpl::StubValueTy &StubSym =
|
||||
GV->hasHiddenVisibility() ? MachOMMI.getHiddenGVStubEntry(SSym) :
|
||||
MachOMMI.getGVStubEntry(SSym);
|
||||
if (StubSym.getPointer() == 0) {
|
||||
MCSymbol *Sym = Mang->getSymbol(GV);
|
||||
StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
|
||||
|
@ -63,6 +63,13 @@ ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
|
||||
|
||||
const unsigned*
|
||||
ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||
bool ghcCall = false;
|
||||
|
||||
if (MF) {
|
||||
const Function *F = MF->getFunction();
|
||||
ghcCall = (F ? F->getCallingConv() == CallingConv::GHC : false);
|
||||
}
|
||||
|
||||
static const unsigned CalleeSavedRegs[] = {
|
||||
ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
|
||||
ARM::R7, ARM::R6, ARM::R5, ARM::R4,
|
||||
@ -82,7 +89,13 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||
ARM::D11, ARM::D10, ARM::D9, ARM::D8,
|
||||
0
|
||||
};
|
||||
return STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
|
||||
|
||||
static const unsigned GhcCalleeSavedRegs[] = {
|
||||
0
|
||||
};
|
||||
|
||||
return ghcCall ? GhcCalleeSavedRegs :
|
||||
STI.isTargetDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
|
||||
}
|
||||
|
||||
BitVector ARMBaseRegisterInfo::
|
||||
|
@ -82,6 +82,25 @@ def RetFastCC_ARM_APCS : CallingConv<[
|
||||
CCDelegateTo<RetCC_ARM_APCS>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM APCS Calling Convention for GHC
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def CC_ARM_APCS_GHC : CallingConv<[
|
||||
// Handle all vector types as either f64 or v2f64.
|
||||
CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType<f64>>,
|
||||
CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType<v2f64>>,
|
||||
|
||||
CCIfType<[v2f64], CCAssignToReg<[Q4, Q5]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[D8, D9, D10, D11]>>,
|
||||
CCIfType<[f32], CCAssignToReg<[S16, S17, S18, S19, S20, S21, S22, S23]>>,
|
||||
|
||||
// Promote i8/i16 arguments to i32.
|
||||
CCIfType<[i8, i16], CCPromoteToType<i32>>,
|
||||
|
||||
// Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, SpLim
|
||||
CCIfType<[i32], CCAssignToReg<[R4, R5, R6, R7, R8, R9, R10, R11]>>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM AAPCS (EABI) Calling Convention, common parts
|
||||
|
@ -1548,6 +1548,11 @@ CCAssignFn *ARMFastISel::CCAssignFnForCall(CallingConv::ID CC, bool Return) {
|
||||
return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
|
||||
case CallingConv::ARM_APCS:
|
||||
return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
|
||||
case CallingConv::GHC:
|
||||
if (Return)
|
||||
llvm_unreachable("Can't return in GHC call convention");
|
||||
else
|
||||
return CC_ARM_APCS_GHC;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "ARMBaseInstrInfo.h"
|
||||
#include "ARMBaseRegisterInfo.h"
|
||||
#include "ARMMachineFunctionInfo.h"
|
||||
#include "llvm/CallingConv.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "MCTargetDesc/ARMAddressingModes.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
@ -139,6 +141,10 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
|
||||
int FramePtrSpillFI = 0;
|
||||
|
||||
// All calls are tail calls in GHC calling conv, and functions have no prologue/epilogue.
|
||||
if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
|
||||
return;
|
||||
|
||||
// Allocate the vararg register save area. This is not counted in NumBytes.
|
||||
if (VARegSaveSize)
|
||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -VARegSaveSize,
|
||||
@ -326,6 +332,10 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
int NumBytes = (int)MFI->getStackSize();
|
||||
unsigned FramePtr = RegInfo->getFrameRegister(MF);
|
||||
|
||||
// All calls are tail calls in GHC calling conv, and functions have no prologue/epilogue.
|
||||
if (MF.getFunction()->getCallingConv() == CallingConv::GHC)
|
||||
return;
|
||||
|
||||
if (!AFI->hasStackFrame()) {
|
||||
if (NumBytes != 0)
|
||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
||||
|
@ -1091,6 +1091,8 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
|
||||
return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
|
||||
case CallingConv::ARM_APCS:
|
||||
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS);
|
||||
case CallingConv::GHC:
|
||||
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1538,8 +1538,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
|
||||
let Inst{21} = 0; // No writeback
|
||||
let Inst{20} = L_bit;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15} = 0;
|
||||
let Inst{14-0} = regs{14-0};
|
||||
let Inst{15-0} = regs;
|
||||
}
|
||||
def IA_UPD :
|
||||
T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
|
||||
@ -1554,8 +1553,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
|
||||
let Inst{21} = 1; // Writeback
|
||||
let Inst{20} = L_bit;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15} = 0;
|
||||
let Inst{14-0} = regs{14-0};
|
||||
let Inst{15-0} = regs;
|
||||
}
|
||||
def DB :
|
||||
T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
|
||||
@ -1570,8 +1568,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
|
||||
let Inst{21} = 0; // No writeback
|
||||
let Inst{20} = L_bit;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15} = 0;
|
||||
let Inst{14-0} = regs{14-0};
|
||||
let Inst{15-0} = regs;
|
||||
}
|
||||
def DB_UPD :
|
||||
T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
|
||||
@ -1586,8 +1583,7 @@ multiclass thumb2_ld_mult<string asm, InstrItinClass itin,
|
||||
let Inst{21} = 1; // Writeback
|
||||
let Inst{20} = L_bit;
|
||||
let Inst{19-16} = Rn;
|
||||
let Inst{15} = 0;
|
||||
let Inst{14-0} = regs{14-0};
|
||||
let Inst{15-0} = regs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1016,6 +1016,27 @@ std::string CppWriter::getOpName(const Value* V) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static StringRef ConvertAtomicOrdering(AtomicOrdering Ordering) {
|
||||
switch (Ordering) {
|
||||
case NotAtomic: return "NotAtomic";
|
||||
case Unordered: return "Unordered";
|
||||
case Monotonic: return "Monotonic";
|
||||
case Acquire: return "Acquire";
|
||||
case Release: return "Release";
|
||||
case AcquireRelease: return "AcquireRelease";
|
||||
case SequentiallyConsistent: return "SequentiallyConsistent";
|
||||
}
|
||||
llvm_unreachable("Unknown ordering");
|
||||
}
|
||||
|
||||
static StringRef ConvertAtomicSynchScope(SynchronizationScope SynchScope) {
|
||||
switch (SynchScope) {
|
||||
case SingleThread: return "SingleThread";
|
||||
case CrossThread: return "CrossThread";
|
||||
}
|
||||
llvm_unreachable("Unknown synch scope");
|
||||
}
|
||||
|
||||
// printInstruction - This member is called for each Instruction in a function.
|
||||
void CppWriter::printInstruction(const Instruction *I,
|
||||
const std::string& bbname) {
|
||||
@ -1237,15 +1258,33 @@ void CppWriter::printInstruction(const Instruction *I,
|
||||
printEscapedString(load->getName());
|
||||
Out << "\", " << (load->isVolatile() ? "true" : "false" )
|
||||
<< ", " << bbname << ");";
|
||||
if (load->getAlignment())
|
||||
nl(Out) << iName << "->setAlignment("
|
||||
<< load->getAlignment() << ");";
|
||||
if (load->isAtomic()) {
|
||||
StringRef Ordering = ConvertAtomicOrdering(load->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(load->getSynchScope());
|
||||
nl(Out) << iName << "->setAtomic("
|
||||
<< Ordering << ", " << CrossThread << ");";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::Store: {
|
||||
const StoreInst* store = cast<StoreInst>(I);
|
||||
Out << " new StoreInst("
|
||||
Out << "StoreInst* " << iName << " = new StoreInst("
|
||||
<< opNames[0] << ", "
|
||||
<< opNames[1] << ", "
|
||||
<< (store->isVolatile() ? "true" : "false")
|
||||
<< ", " << bbname << ");";
|
||||
if (store->getAlignment())
|
||||
nl(Out) << iName << "->setAlignment("
|
||||
<< store->getAlignment() << ");";
|
||||
if (store->isAtomic()) {
|
||||
StringRef Ordering = ConvertAtomicOrdering(store->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(store->getSynchScope());
|
||||
nl(Out) << iName << "->setAtomic("
|
||||
<< Ordering << ", " << CrossThread << ");";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::GetElementPtr: {
|
||||
@ -1447,6 +1486,60 @@ void CppWriter::printInstruction(const Instruction *I,
|
||||
Out << "\", " << bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Fence: {
|
||||
const FenceInst *fi = cast<FenceInst>(I);
|
||||
StringRef Ordering = ConvertAtomicOrdering(fi->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(fi->getSynchScope());
|
||||
Out << "FenceInst* " << iName
|
||||
<< " = new FenceInst(mod->getContext(), "
|
||||
<< Ordering << ", " << CrossThread << ", " << bbname
|
||||
<< ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::AtomicCmpXchg: {
|
||||
const AtomicCmpXchgInst *cxi = cast<AtomicCmpXchgInst>(I);
|
||||
StringRef Ordering = ConvertAtomicOrdering(cxi->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(cxi->getSynchScope());
|
||||
Out << "AtomicCmpXchgInst* " << iName
|
||||
<< " = new AtomicCmpXchgInst("
|
||||
<< opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", "
|
||||
<< Ordering << ", " << CrossThread << ", " << bbname
|
||||
<< ");";
|
||||
nl(Out) << iName << "->setName(\"";
|
||||
printEscapedString(cxi->getName());
|
||||
Out << "\");";
|
||||
break;
|
||||
}
|
||||
case Instruction::AtomicRMW: {
|
||||
const AtomicRMWInst *rmwi = cast<AtomicRMWInst>(I);
|
||||
StringRef Ordering = ConvertAtomicOrdering(rmwi->getOrdering());
|
||||
StringRef CrossThread = ConvertAtomicSynchScope(rmwi->getSynchScope());
|
||||
StringRef Operation;
|
||||
switch (rmwi->getOperation()) {
|
||||
case AtomicRMWInst::Xchg: Operation = "AtomicRMWInst::Xchg"; break;
|
||||
case AtomicRMWInst::Add: Operation = "AtomicRMWInst::Add"; break;
|
||||
case AtomicRMWInst::Sub: Operation = "AtomicRMWInst::Sub"; break;
|
||||
case AtomicRMWInst::And: Operation = "AtomicRMWInst::And"; break;
|
||||
case AtomicRMWInst::Nand: Operation = "AtomicRMWInst::Nand"; break;
|
||||
case AtomicRMWInst::Or: Operation = "AtomicRMWInst::Or"; break;
|
||||
case AtomicRMWInst::Xor: Operation = "AtomicRMWInst::Xor"; break;
|
||||
case AtomicRMWInst::Max: Operation = "AtomicRMWInst::Max"; break;
|
||||
case AtomicRMWInst::Min: Operation = "AtomicRMWInst::Min"; break;
|
||||
case AtomicRMWInst::UMax: Operation = "AtomicRMWInst::UMax"; break;
|
||||
case AtomicRMWInst::UMin: Operation = "AtomicRMWInst::UMin"; break;
|
||||
case AtomicRMWInst::BAD_BINOP: llvm_unreachable("Bad atomic operation");
|
||||
}
|
||||
Out << "AtomicRMWInst* " << iName
|
||||
<< " = new AtomicRMWInst("
|
||||
<< Operation << ", "
|
||||
<< opNames[0] << ", " << opNames[1] << ", "
|
||||
<< Ordering << ", " << CrossThread << ", " << bbname
|
||||
<< ");";
|
||||
nl(Out) << iName << "->setName(\"";
|
||||
printEscapedString(rmwi->getName());
|
||||
Out << "\");";
|
||||
break;
|
||||
}
|
||||
}
|
||||
DefinedValues.insert(I);
|
||||
nl(Out);
|
||||
@ -1623,7 +1716,9 @@ void CppWriter::printFunctionBody(const Function *F) {
|
||||
Out << "Value* " << getCppName(AI) << " = args++;";
|
||||
nl(Out);
|
||||
if (AI->hasName()) {
|
||||
Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");";
|
||||
Out << getCppName(AI) << "->setName(\"";
|
||||
printEscapedString(AI->getName());
|
||||
Out << "\");";
|
||||
nl(Out);
|
||||
}
|
||||
}
|
||||
|
@ -39,51 +39,51 @@ def imm32_63 : ImmLeaf<i64,
|
||||
// Shifts
|
||||
class LogicR_shift_rotate_imm64<bits<6> func, bits<5> _rs, string instr_asm,
|
||||
SDNode OpNode, PatFrag PF>:
|
||||
FR<0x00, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$b, shamt_64:$c),
|
||||
!strconcat(instr_asm, "\t$dst, $b, $c"),
|
||||
[(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, (i64 PF:$c)))],
|
||||
FR<0x00, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rt, shamt_64:$shamt),
|
||||
!strconcat(instr_asm, "\t$rd, $rt, $shamt"),
|
||||
[(set CPU64Regs:$rd, (OpNode CPU64Regs:$rt, (i64 PF:$shamt)))],
|
||||
IIAlu> {
|
||||
let rs = _rs;
|
||||
}
|
||||
|
||||
class LogicR_shift_rotate_reg64<bits<6> func, bits<5> _shamt, string instr_asm,
|
||||
SDNode OpNode>:
|
||||
FR<0x00, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$c, CPU64Regs:$b),
|
||||
!strconcat(instr_asm, "\t$dst, $b, $c"),
|
||||
[(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, CPU64Regs:$c))], IIAlu> {
|
||||
FR<0x00, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rs, CPU64Regs:$rt),
|
||||
!strconcat(instr_asm, "\t$rd, $rt, $rs"),
|
||||
[(set CPU64Regs:$rd, (OpNode CPU64Regs:$rt, CPU64Regs:$rs))], IIAlu> {
|
||||
let shamt = _shamt;
|
||||
}
|
||||
|
||||
// Mul, Div
|
||||
let Defs = [HI64, LO64] in {
|
||||
let rd = 0, shamt = 0, Defs = [HI64, LO64] in {
|
||||
let isCommutable = 1 in
|
||||
class Mul64<bits<6> func, string instr_asm, InstrItinClass itin>:
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b),
|
||||
!strconcat(instr_asm, "\t$a, $b"), [], itin>;
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$rs, CPU64Regs:$rt),
|
||||
!strconcat(instr_asm, "\t$rs, $rt"), [], itin>;
|
||||
|
||||
class Div64<SDNode op, bits<6> func, string instr_asm, InstrItinClass itin>:
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b),
|
||||
!strconcat(instr_asm, "\t$$zero, $a, $b"),
|
||||
[(op CPU64Regs:$a, CPU64Regs:$b)], itin>;
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$rs, CPU64Regs:$rt),
|
||||
!strconcat(instr_asm, "\t$$zero, $rs, $rt"),
|
||||
[(op CPU64Regs:$rs, CPU64Regs:$rt)], itin>;
|
||||
}
|
||||
|
||||
// Move from Hi/Lo
|
||||
let shamt = 0 in {
|
||||
let rs = 0, rt = 0 in
|
||||
class MoveFromLOHI64<bits<6> func, string instr_asm>:
|
||||
FR<0x00, func, (outs CPU64Regs:$dst), (ins),
|
||||
!strconcat(instr_asm, "\t$dst"), [], IIHiLo>;
|
||||
FR<0x00, func, (outs CPU64Regs:$rd), (ins),
|
||||
!strconcat(instr_asm, "\t$rd"), [], IIHiLo>;
|
||||
|
||||
let rt = 0, rd = 0 in
|
||||
class MoveToLOHI64<bits<6> func, string instr_asm>:
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$src),
|
||||
!strconcat(instr_asm, "\t$src"), [], IIHiLo>;
|
||||
FR<0x00, func, (outs), (ins CPU64Regs:$rs),
|
||||
!strconcat(instr_asm, "\t$rs"), [], IIHiLo>;
|
||||
}
|
||||
|
||||
// Count Leading Ones/Zeros in Word
|
||||
class CountLeading64<bits<6> func, string instr_asm, list<dag> pattern>:
|
||||
FR<0x1c, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$src),
|
||||
!strconcat(instr_asm, "\t$dst, $src"), pattern, IIAlu>,
|
||||
FR<0x1c, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rs),
|
||||
!strconcat(instr_asm, "\t$rd, $rs"), pattern, IIAlu>,
|
||||
Requires<[HasBitCount]> {
|
||||
let shamt = 0;
|
||||
let rt = rd;
|
||||
@ -180,9 +180,9 @@ let Uses = [LO64] in
|
||||
|
||||
/// Count Leading
|
||||
def DCLZ : CountLeading64<0x24, "dclz",
|
||||
[(set CPU64Regs:$dst, (ctlz CPU64Regs:$src))]>;
|
||||
[(set CPU64Regs:$rd, (ctlz CPU64Regs:$rs))]>;
|
||||
def DCLO : CountLeading64<0x25, "dclo",
|
||||
[(set CPU64Regs:$dst, (ctlz (not CPU64Regs:$src)))]>;
|
||||
[(set CPU64Regs:$rd, (ctlz (not CPU64Regs:$rs)))]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Arbitrary patterns that map to one or more instructions
|
||||
|
@ -105,6 +105,9 @@ class MipsCodeEmitter : public MachineFunctionPass {
|
||||
unsigned getRelocation(const MachineInstr &MI,
|
||||
const MachineOperand &MO) const;
|
||||
|
||||
unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
};
|
||||
}
|
||||
|
||||
@ -153,6 +156,28 @@ unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
|
||||
return Mips::reloc_mips_lo;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
|
||||
assert(MI.getOperand(OpNo).isReg());
|
||||
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
|
||||
return
|
||||
(getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// size is encoded as size-1.
|
||||
return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
// size is encoded as pos+size-1.
|
||||
return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
|
||||
getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
||||
}
|
||||
|
||||
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
||||
/// operand requires relocation, record the relocation and return zero.
|
||||
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
||||
@ -238,8 +263,4 @@ FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
||||
return new MipsCodeEmitter(TM, JCE);
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {
|
||||
// this function will be automatically generated by the CodeEmitterGenerator
|
||||
// using TableGen
|
||||
return 0;
|
||||
}
|
||||
#include "MipsGenCodeEmitter.inc"
|
||||
|
@ -76,14 +76,16 @@ def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">;
|
||||
// FP load.
|
||||
class FPLoad<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
|
||||
Operand MemOpnd>:
|
||||
FFI<op, (outs RC:$ft), (ins MemOpnd:$base),
|
||||
!strconcat(opstr, "\t$ft, $base"), [(set RC:$ft, (FOp addr:$base))]>;
|
||||
FMem<op, (outs RC:$ft), (ins MemOpnd:$addr),
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(set RC:$ft, (FOp addr:$addr))],
|
||||
IILoad>;
|
||||
|
||||
// FP store.
|
||||
class FPStore<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
|
||||
Operand MemOpnd>:
|
||||
FFI<op, (outs), (ins RC:$ft, MemOpnd:$base),
|
||||
!strconcat(opstr, "\t$ft, $base"), [(store RC:$ft, addr:$base)]>;
|
||||
FMem<op, (outs), (ins RC:$ft, MemOpnd:$addr),
|
||||
!strconcat(opstr, "\t$ft, $addr"), [(store RC:$ft, addr:$addr)],
|
||||
IIStore>;
|
||||
|
||||
// Instructions that convert an FP value to 32-bit fixed point.
|
||||
multiclass FFR1_W_M<bits<6> funct, string opstr> {
|
||||
@ -158,22 +160,28 @@ defm FSQRT : FFR1P_M<0x4, "sqrt", fsqrt>;
|
||||
// stores, and moves between floating-point and integer registers.
|
||||
// When defining instructions, we reference all 32-bit registers,
|
||||
// regardless of register aliasing.
|
||||
let fd = 0 in {
|
||||
/// Move Control Registers From/To CPU Registers
|
||||
def CFC1 : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs),
|
||||
|
||||
class FFRGPR<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
FFR<0x11, 0x0, _fmt, outs, ins, asmstr, pattern> {
|
||||
bits<5> rt;
|
||||
let ft = rt;
|
||||
let fd = 0;
|
||||
}
|
||||
|
||||
/// Move Control Registers From/To CPU Registers
|
||||
def CFC1 : FFRGPR<0x2, (outs CPURegs:$rt), (ins CCR:$fs),
|
||||
"cfc1\t$rt, $fs", []>;
|
||||
|
||||
def CTC1 : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs),
|
||||
"ctc1\t$fs, $rt", []>;
|
||||
def CTC1 : FFRGPR<0x6, (outs CCR:$fs), (ins CPURegs:$rt),
|
||||
"ctc1\t$rt, $fs", []>;
|
||||
|
||||
def MFC1 : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
|
||||
def MFC1 : FFRGPR<0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
|
||||
"mfc1\t$rt, $fs",
|
||||
[(set CPURegs:$rt, (bitconvert FGR32:$fs))]>;
|
||||
|
||||
def MTC1 : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
|
||||
def MTC1 : FFRGPR<0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
|
||||
"mtc1\t$rt, $fs",
|
||||
[(set FGR32:$fs, (bitconvert CPURegs:$rt))]>;
|
||||
}
|
||||
|
||||
def FMOV_S : FFR1<0x6, 16, "mov", "s", FGR32, FGR32>;
|
||||
def FMOV_D32 : FFR1<0x6, 17, "mov", "d", AFGR64, AFGR64>,
|
||||
@ -203,7 +211,7 @@ let Predicates = [NotN64] in {
|
||||
}
|
||||
|
||||
/// Floating-point Aritmetic
|
||||
defm FADD : FFR2P_M<0x10, "add", fadd, 1>;
|
||||
defm FADD : FFR2P_M<0x00, "add", fadd, 1>;
|
||||
defm FDIV : FFR2P_M<0x03, "div", fdiv>;
|
||||
defm FMUL : FFR2P_M<0x02, "mul", fmul, 1>;
|
||||
defm FSUB : FFR2P_M<0x01, "sub", fsub>;
|
||||
@ -218,12 +226,16 @@ def MIPS_BRANCH_T : PatLeaf<(i32 1)>;
|
||||
|
||||
/// Floating Point Branch of False/True (Likely)
|
||||
let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in
|
||||
class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs),
|
||||
(ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
|
||||
[(MipsFPBrcond op, bb:$dst)]>;
|
||||
class FBRANCH<bits<1> nd, bits<1> tf, PatLeaf op, string asmstr> :
|
||||
FFI<0x11, (outs), (ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
|
||||
[(MipsFPBrcond op, bb:$dst)]> {
|
||||
let Inst{20-18} = 0;
|
||||
let Inst{17} = nd;
|
||||
let Inst{16} = tf;
|
||||
}
|
||||
|
||||
def BC1F : FBRANCH<MIPS_BRANCH_F, "bc1f">;
|
||||
def BC1T : FBRANCH<MIPS_BRANCH_T, "bc1t">;
|
||||
def BC1F : FBRANCH<0, 0, MIPS_BRANCH_F, "bc1f">;
|
||||
def BC1T : FBRANCH<0, 1, MIPS_BRANCH_T, "bc1t">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Floating Point Flag Conditions
|
||||
@ -249,11 +261,11 @@ def MIPS_FCOND_NGT : PatLeaf<(i32 15)>;
|
||||
|
||||
/// Floating Point Compare
|
||||
let Defs=[FCR31] in {
|
||||
def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
|
||||
def FCMP_S32 : FCC<0x10, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
|
||||
"c.$cc.s\t$fs, $ft",
|
||||
[(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc)]>;
|
||||
|
||||
def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
|
||||
def FCMP_D32 : FCC<0x11, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
|
||||
"c.$cc.d\t$fs, $ft",
|
||||
[(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc)]>,
|
||||
Requires<[NotFP64bit]>;
|
||||
@ -287,7 +299,8 @@ let Predicates = [NotFP64bit] in {
|
||||
defm : MovnPats<AFGR64, MOVN_D>;
|
||||
}
|
||||
|
||||
let usesCustomInserter = 1, Uses = [FCR31], Constraints = "$F = $dst" in {
|
||||
let cc = 0, usesCustomInserter = 1, Uses = [FCR31],
|
||||
Constraints = "$F = $dst" in {
|
||||
// flag:float, data:int
|
||||
class CondMovFPInt<SDNode cmov, bits<1> tf, string instr_asm> :
|
||||
FCMOV<tf, (outs CPURegs:$dst), (ins CPURegs:$T, CPURegs:$F),
|
||||
@ -295,6 +308,7 @@ class CondMovFPInt<SDNode cmov, bits<1> tf, string instr_asm> :
|
||||
[(set CPURegs:$dst, (cmov CPURegs:$T, CPURegs:$F))]>;
|
||||
|
||||
// flag:float, data:float
|
||||
let cc = 0 in
|
||||
class CondMovFPFP<RegisterClass RC, SDNode cmov, bits<5> fmt, bits<1> tf,
|
||||
string instr_asm> :
|
||||
FFCMOV<fmt, tf, (outs RC:$dst), (ins RC:$T, RC:$F),
|
||||
|
@ -21,30 +21,55 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Format specifies the encoding used by the instruction. This is part of the
|
||||
// ad-hoc solution used to emit machine instruction encodings by our machine
|
||||
// code emitter.
|
||||
class Format<bits<4> val> {
|
||||
bits<4> Value = val;
|
||||
}
|
||||
|
||||
def Pseudo : Format<0>;
|
||||
def FrmR : Format<1>;
|
||||
def FrmI : Format<2>;
|
||||
def FrmJ : Format<3>;
|
||||
def FrmFR : Format<4>;
|
||||
def FrmFI : Format<5>;
|
||||
def FrmOther : Format<6>; // Instruction w/ a custom format
|
||||
|
||||
// Generic Mips Format
|
||||
class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: Instruction
|
||||
InstrItinClass itin, Format f>: Instruction
|
||||
{
|
||||
field bits<32> Inst;
|
||||
Format Form = f;
|
||||
|
||||
let Namespace = "Mips";
|
||||
|
||||
bits<6> opcode;
|
||||
bits<6> Opcode = 0;
|
||||
|
||||
// Top 5 bits are the 'opcode' field
|
||||
let Inst{31-26} = opcode;
|
||||
// Top 6 bits are the 'opcode' field
|
||||
let Inst{31-26} = Opcode;
|
||||
|
||||
dag OutOperandList = outs;
|
||||
dag InOperandList = ins;
|
||||
let OutOperandList = outs;
|
||||
let InOperandList = ins;
|
||||
|
||||
let AsmString = asmstr;
|
||||
let Pattern = pattern;
|
||||
let Itinerary = itin;
|
||||
|
||||
//
|
||||
// Attributes specific to Mips instructions...
|
||||
//
|
||||
bits<4> FormBits = Form.Value;
|
||||
|
||||
// TSFlags layout should be kept in sync with MipsInstrInfo.h.
|
||||
let TSFlags{3-0} = FormBits;
|
||||
}
|
||||
|
||||
// Mips Pseudo Instructions Format
|
||||
class MipsPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
MipsInst<outs, ins, asmstr, pattern, IIPseudo> {
|
||||
MipsInst<outs, ins, asmstr, pattern, IIPseudo, Pseudo> {
|
||||
let isCodeGenOnly = 1;
|
||||
let isPseudo = 1;
|
||||
}
|
||||
|
||||
@ -54,7 +79,7 @@ class MipsPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
|
||||
class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern, InstrItinClass itin>:
|
||||
MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
MipsInst<outs, ins, asmstr, pattern, itin, FrmR>
|
||||
{
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
@ -62,7 +87,7 @@ class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
bits<5> shamt;
|
||||
bits<6> funct;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
let funct = _funct;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
@ -77,13 +102,13 @@ class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin, FrmI>
|
||||
{
|
||||
bits<5> rt;
|
||||
bits<5> rs;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
@ -92,13 +117,13 @@ class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
|
||||
class CBranchBase<bits<6> op, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern, InstrItinClass itin>:
|
||||
MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
MipsInst<outs, ins, asmstr, pattern, itin, FrmI>
|
||||
{
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
@ -110,11 +135,11 @@ class CBranchBase<bits<6> op, dag outs, dag ins, string asmstr,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin>
|
||||
InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin, FrmJ>
|
||||
{
|
||||
bits<26> addr;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-0} = addr;
|
||||
}
|
||||
@ -138,7 +163,7 @@ class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
|
||||
class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
string asmstr, list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmFR>
|
||||
{
|
||||
bits<5> fd;
|
||||
bits<5> fs;
|
||||
@ -146,7 +171,7 @@ class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
bits<5> fmt;
|
||||
bits<6> funct;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
let funct = _funct;
|
||||
let fmt = _fmt;
|
||||
|
||||
@ -162,13 +187,13 @@ class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FFI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmFI>
|
||||
{
|
||||
bits<5> ft;
|
||||
bits<5> base;
|
||||
bits<16> imm16;
|
||||
|
||||
let opcode = op;
|
||||
let Opcode = op;
|
||||
|
||||
let Inst{25-21} = base;
|
||||
let Inst{20-16} = ft;
|
||||
@ -180,14 +205,14 @@ class FFI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>:
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class FCC<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> fs;
|
||||
bits<5> ft;
|
||||
bits<4> cc;
|
||||
bits<5> fmt;
|
||||
|
||||
let opcode = 0x11;
|
||||
let Opcode = 0x11;
|
||||
let fmt = _fmt;
|
||||
|
||||
let Inst{25-21} = fmt;
|
||||
@ -201,18 +226,18 @@ class FCC<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern> :
|
||||
|
||||
class FCMOV<bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<3> N;
|
||||
bits<3> cc;
|
||||
bits<1> tf;
|
||||
|
||||
let opcode = 0;
|
||||
let Opcode = 0;
|
||||
let tf = _tf;
|
||||
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-18} = N;
|
||||
let Inst{20-18} = cc;
|
||||
let Inst{17} = 0;
|
||||
let Inst{16} = tf;
|
||||
let Inst{15-11} = rd;
|
||||
@ -222,20 +247,20 @@ class FCMOV<bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
|
||||
class FFCMOV<bits<5> _fmt, bits<1> _tf, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern> :
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary>
|
||||
MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
|
||||
{
|
||||
bits<5> fd;
|
||||
bits<5> fs;
|
||||
bits<3> N;
|
||||
bits<3> cc;
|
||||
bits<5> fmt;
|
||||
bits<1> tf;
|
||||
|
||||
let opcode = 17;
|
||||
let Opcode = 17;
|
||||
let fmt = _fmt;
|
||||
let tf = _tf;
|
||||
|
||||
let Inst{25-21} = fmt;
|
||||
let Inst{20-18} = N;
|
||||
let Inst{20-18} = cc;
|
||||
let Inst{17} = 0;
|
||||
let Inst{16} = tf;
|
||||
let Inst{15-11} = fs;
|
||||
|
@ -153,6 +153,7 @@ def uimm16 : Operand<i32> {
|
||||
def mem : Operand<i32> {
|
||||
let PrintMethod = "printMemOperand";
|
||||
let MIOperandInfo = (ops CPURegs, simm16);
|
||||
let EncoderMethod = "getMemEncoding";
|
||||
}
|
||||
|
||||
def mem64 : Operand<i64> {
|
||||
@ -163,6 +164,17 @@ def mem64 : Operand<i64> {
|
||||
def mem_ea : Operand<i32> {
|
||||
let PrintMethod = "printMemOperandEA";
|
||||
let MIOperandInfo = (ops CPURegs, simm16);
|
||||
let EncoderMethod = "getMemEncoding";
|
||||
}
|
||||
|
||||
// size operand of ext instruction
|
||||
def size_ext : Operand<i32> {
|
||||
let EncoderMethod = "getSizeExtEncoding";
|
||||
}
|
||||
|
||||
// size operand of ins instruction
|
||||
def size_ins : Operand<i32> {
|
||||
let EncoderMethod = "getSizeInsEncoding";
|
||||
}
|
||||
|
||||
// Transformation Function - get the lower 16 bits.
|
||||
@ -271,14 +283,14 @@ class ArithOverflowR<bits<6> op, bits<6> func, string instr_asm,
|
||||
// Arithmetic and logical instructions with 2 register operands.
|
||||
class ArithLogicI<bits<6> op, string instr_asm, SDNode OpNode,
|
||||
Operand Od, PatLeaf imm_type, RegisterClass RC> :
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $i"),
|
||||
[(set RC:$rt, (OpNode RC:$rs, imm_type:$i))], IIAlu>;
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"),
|
||||
[(set RC:$rt, (OpNode RC:$rs, imm_type:$imm16))], IIAlu>;
|
||||
|
||||
class ArithOverflowI<bits<6> op, string instr_asm, SDNode OpNode,
|
||||
Operand Od, PatLeaf imm_type, RegisterClass RC> :
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $i"), [], IIAlu>;
|
||||
FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"), [], IIAlu>;
|
||||
|
||||
// Arithmetic Multiply ADD/SUB
|
||||
let rd = 0, shamt = 0, Defs = [HI, LO], Uses = [HI, LO] in
|
||||
@ -319,16 +331,23 @@ class LogicR_shift_rotate_reg<bits<6> func, bits<5> isRotate, string instr_asm,
|
||||
|
||||
// Load Upper Imediate
|
||||
class LoadUpper<bits<6> op, string instr_asm>:
|
||||
FI<op, (outs CPURegs:$rt), (ins uimm16:$imm),
|
||||
!strconcat(instr_asm, "\t$rt, $imm"), [], IIAlu> {
|
||||
FI<op, (outs CPURegs:$rt), (ins uimm16:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $imm16"), [], IIAlu> {
|
||||
let rs = 0;
|
||||
}
|
||||
|
||||
class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
InstrItinClass itin>: FFI<op, outs, ins, asmstr, pattern> {
|
||||
bits<21> addr;
|
||||
let Inst{25-21} = addr{20-16};
|
||||
let Inst{15-0} = addr{15-0};
|
||||
}
|
||||
|
||||
// Memory Load/Store
|
||||
let canFoldAsLoad = 1 in
|
||||
class LoadM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
Operand MemOpnd, bit Pseudo>:
|
||||
FI<op, (outs RC:$rt), (ins MemOpnd:$addr),
|
||||
FMem<op, (outs RC:$rt), (ins MemOpnd:$addr),
|
||||
!strconcat(instr_asm, "\t$rt, $addr"),
|
||||
[(set RC:$rt, (OpNode addr:$addr))], IILoad> {
|
||||
let isPseudo = Pseudo;
|
||||
@ -336,7 +355,7 @@ class LoadM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
|
||||
class StoreM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
|
||||
Operand MemOpnd, bit Pseudo>:
|
||||
FI<op, (outs), (ins RC:$rt, MemOpnd:$addr),
|
||||
FMem<op, (outs), (ins RC:$rt, MemOpnd:$addr),
|
||||
!strconcat(instr_asm, "\t$rt, $addr"),
|
||||
[(OpNode RC:$rt, addr:$addr)], IIStore> {
|
||||
let isPseudo = Pseudo;
|
||||
@ -380,9 +399,9 @@ multiclass StoreM64<bits<6> op, string instr_asm, PatFrag OpNode,
|
||||
|
||||
// Conditional Branch
|
||||
class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
|
||||
CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$offset),
|
||||
!strconcat(instr_asm, "\t$rs, $rt, $offset"),
|
||||
[(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch> {
|
||||
CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$imm16),
|
||||
!strconcat(instr_asm, "\t$rs, $rt, $imm16"),
|
||||
[(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$imm16)], IIBranch> {
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
let hasDelaySlot = 1;
|
||||
@ -390,9 +409,9 @@ class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
|
||||
|
||||
class CBranchZero<bits<6> op, bits<5> _rt, string instr_asm, PatFrag cond_op,
|
||||
RegisterClass RC>:
|
||||
CBranchBase<op, (outs), (ins RC:$rs, brtarget:$offset),
|
||||
!strconcat(instr_asm, "\t$rs, $offset"),
|
||||
[(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch> {
|
||||
CBranchBase<op, (outs), (ins RC:$rs, brtarget:$imm16),
|
||||
!strconcat(instr_asm, "\t$rs, $imm16"),
|
||||
[(brcond (i32 (cond_op RC:$rs, 0)), bb:$imm16)], IIBranch> {
|
||||
let rt = _rt;
|
||||
let isBranch = 1;
|
||||
let isTerminator = 1;
|
||||
@ -411,9 +430,9 @@ class SetCC_R<bits<6> op, bits<6> func, string instr_asm, PatFrag cond_op,
|
||||
|
||||
class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op, Operand Od,
|
||||
PatLeaf imm_type, RegisterClass RC>:
|
||||
FI<op, (outs CPURegs:$rd), (ins RC:$rs, Od:$i),
|
||||
!strconcat(instr_asm, "\t$rd, $rs, $i"),
|
||||
[(set CPURegs:$rd, (cond_op RC:$rs, imm_type:$i))],
|
||||
FI<op, (outs CPURegs:$rt), (ins RC:$rs, Od:$imm16),
|
||||
!strconcat(instr_asm, "\t$rt, $rs, $imm16"),
|
||||
[(set CPURegs:$rt, (cond_op RC:$rs, imm_type:$imm16))],
|
||||
IIAlu>;
|
||||
|
||||
// Unconditional branch
|
||||
@ -450,10 +469,8 @@ let isCall=1, hasDelaySlot=1,
|
||||
}
|
||||
|
||||
class BranchLink<string instr_asm>:
|
||||
FI<0x1, (outs), (ins CPURegs:$rs, brtarget:$target, variable_ops),
|
||||
!strconcat(instr_asm, "\t$rs, $target"), [], IIBranch> {
|
||||
let rt = 0;
|
||||
}
|
||||
FI<0x1, (outs), (ins CPURegs:$rs, brtarget:$imm16, variable_ops),
|
||||
!strconcat(instr_asm, "\t$rs, $imm16"), [], IIBranch>;
|
||||
}
|
||||
|
||||
// Mul, Div
|
||||
@ -493,7 +510,7 @@ class MoveToLOHI<bits<6> func, string instr_asm>:
|
||||
}
|
||||
|
||||
class EffectiveAddress<string instr_asm> :
|
||||
FI<0x09, (outs CPURegs:$rt), (ins mem_ea:$addr),
|
||||
FMem<0x09, (outs CPURegs:$rt), (ins mem_ea:$addr),
|
||||
instr_asm, [(set CPURegs:$rt, addr:$addr)], IIAlu>;
|
||||
|
||||
// Count Leading Ones/Zeros in Word
|
||||
@ -507,7 +524,7 @@ class CountLeading<bits<6> func, string instr_asm, list<dag> pattern>:
|
||||
|
||||
// Sign Extend in Register.
|
||||
class SignExtInReg<bits<5> sa, string instr_asm, ValueType vt>:
|
||||
FR<0x3f, 0x20, (outs CPURegs:$rd), (ins CPURegs:$rt),
|
||||
FR<0x1f, 0x20, (outs CPURegs:$rd), (ins CPURegs:$rt),
|
||||
!strconcat(instr_asm, "\t$rd, $rt"),
|
||||
[(set CPURegs:$rd, (sext_inreg CPURegs:$rt, vt))], NoItinerary> {
|
||||
let rs = 0;
|
||||
@ -685,20 +702,22 @@ defm USW : StoreM32<0x2b, "usw", store_u, 1>;
|
||||
|
||||
let hasSideEffects = 1 in
|
||||
def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype",
|
||||
[(MipsSync imm:$stype)], NoItinerary>
|
||||
[(MipsSync imm:$stype)], NoItinerary, FrmOther>
|
||||
{
|
||||
let opcode = 0;
|
||||
bits<5> stype;
|
||||
let Opcode = 0;
|
||||
let Inst{25-11} = 0;
|
||||
let Inst{10-6} = stype;
|
||||
let Inst{5-0} = 15;
|
||||
}
|
||||
|
||||
/// Load-linked, Store-conditional
|
||||
let mayLoad = 1 in
|
||||
def LL : FI<0x30, (outs CPURegs:$dst), (ins mem:$addr),
|
||||
"ll\t$dst, $addr", [], IILoad>;
|
||||
let mayStore = 1, Constraints = "$src = $dst" in
|
||||
def SC : FI<0x38, (outs CPURegs:$dst), (ins CPURegs:$src, mem:$addr),
|
||||
"sc\t$src, $addr", [], IIStore>;
|
||||
def LL : FMem<0x30, (outs CPURegs:$rt), (ins mem:$addr),
|
||||
"ll\t$rt, $addr", [], IILoad>;
|
||||
let mayStore = 1, Constraints = "$rt = $dst" in
|
||||
def SC : FMem<0x38, (outs CPURegs:$dst), (ins CPURegs:$rt, mem:$addr),
|
||||
"sc\t$rt, $addr", [], IIStore>;
|
||||
|
||||
/// Jump and Branch Instructions
|
||||
def J : JumpFJ<0x02, "j">;
|
||||
@ -710,15 +729,17 @@ def BEQ : CBranch<0x04, "beq", seteq, CPURegs>;
|
||||
def BNE : CBranch<0x05, "bne", setne, CPURegs>;
|
||||
def BGEZ : CBranchZero<0x01, 1, "bgez", setge, CPURegs>;
|
||||
def BGTZ : CBranchZero<0x07, 0, "bgtz", setgt, CPURegs>;
|
||||
def BLEZ : CBranchZero<0x07, 0, "blez", setle, CPURegs>;
|
||||
def BLEZ : CBranchZero<0x06, 0, "blez", setle, CPURegs>;
|
||||
def BLTZ : CBranchZero<0x01, 0, "bltz", setlt, CPURegs>;
|
||||
|
||||
def BGEZAL : BranchLink<"bgezal">;
|
||||
def BLTZAL : BranchLink<"bltzal">;
|
||||
let rt=0x11 in
|
||||
def BGEZAL : BranchLink<"bgezal">;
|
||||
let rt=0x10 in
|
||||
def BLTZAL : BranchLink<"bltzal">;
|
||||
|
||||
let isReturn=1, isTerminator=1, hasDelaySlot=1,
|
||||
isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
|
||||
def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
|
||||
isBarrier=1, hasCtrlDep=1, rd=0, rt=0, shamt=0 in
|
||||
def RET : FR <0x00, 0x08, (outs), (ins CPURegs:$target),
|
||||
"jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>;
|
||||
|
||||
/// Multiply and Divide Instructions.
|
||||
@ -797,14 +818,14 @@ def MUL : ArithLogicR<0x1c, 0x02, "mul", mul, IIImul, CPURegs, 1>,
|
||||
def RDHWR : ReadHardware;
|
||||
|
||||
def EXT : ExtIns<0, "ext", (outs CPURegs:$rt),
|
||||
(ins CPURegs:$rs, uimm16:$pos, uimm16:$sz),
|
||||
(ins CPURegs:$rs, uimm16:$pos, size_ext:$sz),
|
||||
[(set CPURegs:$rt,
|
||||
(MipsExt CPURegs:$rs, immZExt5:$pos, immZExt5:$sz))],
|
||||
NoItinerary>;
|
||||
|
||||
let Constraints = "$src = $rt" in
|
||||
def INS : ExtIns<4, "ins", (outs CPURegs:$rt),
|
||||
(ins CPURegs:$rs, uimm16:$pos, uimm16:$sz, CPURegs:$src),
|
||||
(ins CPURegs:$rs, uimm16:$pos, size_ins:$sz, CPURegs:$src),
|
||||
[(set CPURegs:$rt,
|
||||
(MipsIns CPURegs:$rs, immZExt5:$pos, immZExt5:$sz,
|
||||
CPURegs:$src))],
|
||||
|
@ -57,11 +57,11 @@ void MipsCompilationCallback();
|
||||
".globl " ASMPREFIX "MipsCompilationCallback\n"
|
||||
ASMPREFIX "MipsCompilationCallback:\n"
|
||||
".ent " ASMPREFIX "MipsCompilationCallback\n"
|
||||
".frame $29, 32, $31\n"
|
||||
".frame $sp, 32, $ra\n"
|
||||
".set noreorder\n"
|
||||
".cpload $t9\n"
|
||||
|
||||
"addiu $sp, $sp, -60\n"
|
||||
"addiu $sp, $sp, -64\n"
|
||||
".cprestore 16\n"
|
||||
|
||||
// Save argument registers a0, a1, a2, a3, f12, f14 since they may contain
|
||||
@ -76,8 +76,8 @@ void MipsCompilationCallback();
|
||||
"sw $a3, 32($sp)\n"
|
||||
"sw $ra, 36($sp)\n"
|
||||
"sw $t8, 40($sp)\n"
|
||||
"sdc1 $f12, 44($sp)\n"
|
||||
"sdc1 $f14, 52($sp)\n"
|
||||
"sdc1 $f12, 48($sp)\n"
|
||||
"sdc1 $f14, 56($sp)\n"
|
||||
|
||||
// t8 points at the end of function stub. Pass the beginning of the stub
|
||||
// to the MipsCompilationCallbackC.
|
||||
@ -92,9 +92,9 @@ void MipsCompilationCallback();
|
||||
"lw $a3, 32($sp)\n"
|
||||
"lw $ra, 36($sp)\n"
|
||||
"lw $t8, 40($sp)\n"
|
||||
"ldc1 $f12, 44($sp)\n"
|
||||
"ldc1 $f14, 52($sp)\n"
|
||||
"addiu $sp, $sp, 60\n"
|
||||
"ldc1 $f12, 48($sp)\n"
|
||||
"ldc1 $f14, 56($sp)\n"
|
||||
"addiu $sp, $sp, 64\n"
|
||||
|
||||
// Jump to the (newly modified) stub to invoke the real function.
|
||||
"addiu $t8, $t8, -16\n"
|
||||
|
@ -490,10 +490,8 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
|
||||
// This is a bit of a hack: CR2LT, CR2GT, CR2EQ and CR2UN are just
|
||||
// subregisters of CR2. We just need to emit a move of CR2.
|
||||
if (Reg == PPC::CR2LT || Reg == PPC::CR2GT || Reg == PPC::CR2EQ)
|
||||
if (PPC::CRBITRCRegisterClass->contains(Reg))
|
||||
continue;
|
||||
if (Reg == PPC::CR2UN)
|
||||
Reg = PPC::CR2;
|
||||
|
||||
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
|
||||
MachineLocation CSSrc(Reg);
|
||||
|
@ -589,6 +589,13 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
|
||||
}
|
||||
}
|
||||
|
||||
static const MCInstrDesc *UpdateOp(MachineInstr &MI, const X86InstrInfo *II,
|
||||
unsigned Opcode) {
|
||||
const MCInstrDesc *Desc = &II->get(Opcode);
|
||||
MI.setDesc(*Desc);
|
||||
return Desc;
|
||||
}
|
||||
|
||||
template<class CodeEmitter>
|
||||
void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
|
||||
const MCInstrDesc *Desc) {
|
||||
@ -596,15 +603,23 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
|
||||
|
||||
// If this is a pseudo instruction, lower it.
|
||||
switch (Desc->getOpcode()) {
|
||||
case X86::ADD16rr_DB: Desc = &II->get(X86::OR16rr); MI.setDesc(*Desc);break;
|
||||
case X86::ADD32rr_DB: Desc = &II->get(X86::OR32rr); MI.setDesc(*Desc);break;
|
||||
case X86::ADD64rr_DB: Desc = &II->get(X86::OR64rr); MI.setDesc(*Desc);break;
|
||||
case X86::ADD16ri_DB: Desc = &II->get(X86::OR16ri); MI.setDesc(*Desc);break;
|
||||
case X86::ADD32ri_DB: Desc = &II->get(X86::OR32ri); MI.setDesc(*Desc);break;
|
||||
case X86::ADD64ri32_DB:Desc = &II->get(X86::OR64ri32);MI.setDesc(*Desc);break;
|
||||
case X86::ADD16ri8_DB: Desc = &II->get(X86::OR16ri8);MI.setDesc(*Desc);break;
|
||||
case X86::ADD32ri8_DB: Desc = &II->get(X86::OR32ri8);MI.setDesc(*Desc);break;
|
||||
case X86::ADD64ri8_DB: Desc = &II->get(X86::OR64ri8);MI.setDesc(*Desc);break;
|
||||
case X86::ADD16rr_DB: Desc = UpdateOp(MI, II, X86::OR16rr); break;
|
||||
case X86::ADD32rr_DB: Desc = UpdateOp(MI, II, X86::OR32rr); break;
|
||||
case X86::ADD64rr_DB: Desc = UpdateOp(MI, II, X86::OR64rr); break;
|
||||
case X86::ADD16ri_DB: Desc = UpdateOp(MI, II, X86::OR16ri); break;
|
||||
case X86::ADD32ri_DB: Desc = UpdateOp(MI, II, X86::OR32ri); break;
|
||||
case X86::ADD64ri32_DB: Desc = UpdateOp(MI, II, X86::OR64ri32); break;
|
||||
case X86::ADD16ri8_DB: Desc = UpdateOp(MI, II, X86::OR16ri8); break;
|
||||
case X86::ADD32ri8_DB: Desc = UpdateOp(MI, II, X86::OR32ri8); break;
|
||||
case X86::ADD64ri8_DB: Desc = UpdateOp(MI, II, X86::OR64ri8); break;
|
||||
case X86::ACQUIRE_MOV8rm: Desc = UpdateOp(MI, II, X86::MOV8rm); break;
|
||||
case X86::ACQUIRE_MOV16rm: Desc = UpdateOp(MI, II, X86::MOV16rm); break;
|
||||
case X86::ACQUIRE_MOV32rm: Desc = UpdateOp(MI, II, X86::MOV32rm); break;
|
||||
case X86::ACQUIRE_MOV64rm: Desc = UpdateOp(MI, II, X86::MOV64rm); break;
|
||||
case X86::RELEASE_MOV8mr: Desc = UpdateOp(MI, II, X86::MOV8mr); break;
|
||||
case X86::RELEASE_MOV16mr: Desc = UpdateOp(MI, II, X86::MOV16mr); break;
|
||||
case X86::RELEASE_MOV32mr: Desc = UpdateOp(MI, II, X86::MOV32mr); break;
|
||||
case X86::RELEASE_MOV64mr: Desc = UpdateOp(MI, II, X86::MOV64mr); break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2025,9 +2025,10 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
|
||||
BasicBlock *InstParent = I->getParent();
|
||||
BasicBlock::iterator InsertPos = I;
|
||||
|
||||
if (!isa<PHINode>(Result)) // If combining a PHI, don't insert
|
||||
while (isa<PHINode>(InsertPos)) // middle of a block of PHIs.
|
||||
++InsertPos;
|
||||
// If we replace a PHI with something that isn't a PHI, fix up the
|
||||
// insertion point.
|
||||
if (!isa<PHINode>(Result) && isa<PHINode>(InsertPos))
|
||||
InsertPos = InstParent->getFirstInsertionPt();
|
||||
|
||||
InstParent->getInstList().insert(InsertPos, Result);
|
||||
|
||||
|
@ -644,6 +644,17 @@ def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"<directory>">,
|
||||
def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">,MetaVarName<"<directory>">,
|
||||
HelpText<"Add directory to SYSTEM include search path, "
|
||||
"absolute paths are relative to -isysroot">;
|
||||
def internal_isystem : JoinedOrSeparate<"-internal-isystem">,
|
||||
MetaVarName<"<directory>">,
|
||||
HelpText<"Add directory to the internal system include search path; these "
|
||||
"are assumed to not be user-provided and are used to model system "
|
||||
"and standard headers' paths.">;
|
||||
def internal_externc_isystem : JoinedOrSeparate<"-internal-externc-isystem">,
|
||||
MetaVarName<"<directory>">,
|
||||
HelpText<"Add directory to the internal system include search path with "
|
||||
"implicit extern \"C\" semantics; these are assumed to not be "
|
||||
"user-provided and are used to model system and standard headers' "
|
||||
"paths.">;
|
||||
def iprefix : JoinedOrSeparate<"-iprefix">, MetaVarName<"<prefix>">,
|
||||
HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">;
|
||||
def iwithprefix : JoinedOrSeparate<"-iwithprefix">, MetaVarName<"<dir>">,
|
||||
|
@ -195,15 +195,21 @@ class ToolChain {
|
||||
/// FIXME: this really belongs on some sort of DeploymentTarget abstraction
|
||||
virtual bool hasBlocksRuntime() const { return true; }
|
||||
|
||||
/// \brief Add the clang cc1 arguments for system include paths.
|
||||
///
|
||||
/// This routine is responsible for adding the necessary cc1 arguments to
|
||||
/// include headers from standard system header directories.
|
||||
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const;
|
||||
|
||||
// GetCXXStdlibType - Determine the C++ standard library type to use with the
|
||||
// given compilation arguments.
|
||||
virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const;
|
||||
|
||||
/// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
|
||||
/// the include paths to use for the given C++ standard library type.
|
||||
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs,
|
||||
bool ObjCXXAutoRefCount) const;
|
||||
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const;
|
||||
|
||||
/// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
|
||||
/// for the given C++ standard library type.
|
||||
|
@ -49,10 +49,24 @@ class HeaderSearchOptions {
|
||||
/// path.
|
||||
unsigned IgnoreSysRoot : 1;
|
||||
|
||||
/// \brief True if this entry is an internal search path.
|
||||
///
|
||||
/// This typically indicates that users didn't directly provide it, but
|
||||
/// instead it was provided by a compatibility layer for a particular
|
||||
/// system. This isn't redundant with IsUserSupplied (even though perhaps
|
||||
/// it should be) because that is false for user provided '-iwithprefix'
|
||||
/// header search entries.
|
||||
unsigned IsInternal : 1;
|
||||
|
||||
/// \brief True if this entry's headers should be wrapped in extern "C".
|
||||
unsigned ImplicitExternC : 1;
|
||||
|
||||
Entry(StringRef path, frontend::IncludeDirGroup group,
|
||||
bool isUserSupplied, bool isFramework, bool ignoreSysRoot)
|
||||
bool isUserSupplied, bool isFramework, bool ignoreSysRoot,
|
||||
bool isInternal, bool implicitExternC)
|
||||
: Path(path), Group(group), IsUserSupplied(isUserSupplied),
|
||||
IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot) {}
|
||||
IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot),
|
||||
IsInternal(isInternal), ImplicitExternC(implicitExternC) {}
|
||||
};
|
||||
|
||||
/// If non-empty, the directory to use as a "virtual system root" for include
|
||||
@ -98,9 +112,10 @@ class HeaderSearchOptions {
|
||||
|
||||
/// AddPath - Add the \arg Path path to the specified \arg Group list.
|
||||
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
|
||||
bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot) {
|
||||
bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot,
|
||||
bool IsInternal = false, bool ImplicitExternC = false) {
|
||||
UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework,
|
||||
IgnoreSysRoot));
|
||||
IgnoreSysRoot, IsInternal, ImplicitExternC));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -32,7 +32,7 @@ std::string getClangRepositoryPath() {
|
||||
|
||||
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
|
||||
// pick up a tag in an SVN export, for example.
|
||||
static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/branches/release_30/lib/Basic/Version.cpp $");
|
||||
static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_30/final/lib/Basic/Version.cpp $");
|
||||
if (URL.empty()) {
|
||||
URL = SVNRepository.slice(SVNRepository.find(':'),
|
||||
SVNRepository.find("/lib/Basic"));
|
||||
|
@ -538,11 +538,12 @@ class CGObjCGCC : public CGObjCGNU {
|
||||
llvm::Value *cmd,
|
||||
llvm::MDNode *node) {
|
||||
CGBuilderTy &Builder = CGF.Builder;
|
||||
llvm::Value *imp = Builder.CreateCall2(MsgLookupFn,
|
||||
EnforceType(Builder, Receiver, IdTy),
|
||||
EnforceType(Builder, cmd, SelectorTy));
|
||||
cast<llvm::CallInst>(imp)->setMetadata(msgSendMDKind, node);
|
||||
return imp;
|
||||
llvm::Value *args[] = {
|
||||
EnforceType(Builder, Receiver, IdTy),
|
||||
EnforceType(Builder, cmd, SelectorTy) };
|
||||
llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args);
|
||||
imp->setMetadata(msgSendMDKind, node);
|
||||
return imp.getInstruction();
|
||||
}
|
||||
virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
|
||||
llvm::Value *ObjCSuper,
|
||||
@ -597,16 +598,17 @@ class CGObjCGNUstep : public CGObjCGNU {
|
||||
// The lookup function is guaranteed not to capture the receiver pointer.
|
||||
LookupFn->setDoesNotCapture(1);
|
||||
|
||||
llvm::CallInst *slot =
|
||||
Builder.CreateCall3(LookupFn,
|
||||
EnforceType(Builder, ReceiverPtr, PtrToIdTy),
|
||||
EnforceType(Builder, cmd, SelectorTy),
|
||||
EnforceType(Builder, self, IdTy));
|
||||
slot->setOnlyReadsMemory();
|
||||
llvm::Value *args[] = {
|
||||
EnforceType(Builder, ReceiverPtr, PtrToIdTy),
|
||||
EnforceType(Builder, cmd, SelectorTy),
|
||||
EnforceType(Builder, self, IdTy) };
|
||||
llvm::CallSite slot = CGF.EmitCallOrInvoke(LookupFn, args);
|
||||
slot.setOnlyReadsMemory();
|
||||
slot->setMetadata(msgSendMDKind, node);
|
||||
|
||||
// Load the imp from the slot
|
||||
llvm::Value *imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
|
||||
llvm::Value *imp =
|
||||
Builder.CreateLoad(Builder.CreateStructGEP(slot.getInstruction(), 4));
|
||||
|
||||
// The lookup function may have changed the receiver, so make sure we use
|
||||
// the new one.
|
||||
@ -1361,8 +1363,8 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure(
|
||||
LongTy, // abi_version
|
||||
IvarOffsets->getType(), // ivar_offsets
|
||||
Properties->getType(), // properties
|
||||
Int64Ty, // strong_pointers
|
||||
Int64Ty, // weak_pointers
|
||||
IntPtrTy, // strong_pointers
|
||||
IntPtrTy, // weak_pointers
|
||||
NULL);
|
||||
llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
|
||||
// Fill in the structure
|
||||
@ -1723,12 +1725,14 @@ void CGObjCGNU::GenerateProtocolHolderCategory(void) {
|
||||
/// bitfield / with the 63rd bit set will be 1<<64.
|
||||
llvm::Constant *CGObjCGNU::MakeBitField(llvm::SmallVectorImpl<bool> &bits) {
|
||||
int bitCount = bits.size();
|
||||
if (bitCount < 64) {
|
||||
int ptrBits =
|
||||
(TheModule.getPointerSize() == llvm::Module::Pointer32) ? 32 : 64;
|
||||
if (bitCount < ptrBits) {
|
||||
uint64_t val = 1;
|
||||
for (int i=0 ; i<bitCount ; ++i) {
|
||||
if (bits[i]) val |= 1ULL<<(i+1);
|
||||
}
|
||||
return llvm::ConstantInt::get(Int64Ty, val);
|
||||
return llvm::ConstantInt::get(IntPtrTy, val);
|
||||
}
|
||||
llvm::SmallVector<llvm::Constant*, 8> values;
|
||||
int v=0;
|
||||
@ -1748,8 +1752,6 @@ llvm::Constant *CGObjCGNU::MakeBitField(llvm::SmallVectorImpl<bool> &bits) {
|
||||
llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
|
||||
NULL), fields);
|
||||
llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
|
||||
if (IntPtrTy != Int64Ty)
|
||||
ptr = llvm::ConstantExpr::getZExt(ptr, Int64Ty);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -2073,12 +2075,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
|
||||
}
|
||||
++ivarIndex;
|
||||
}
|
||||
llvm::Constant *Zero64 = llvm::ConstantInt::get(Int64Ty, 0);
|
||||
llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
|
||||
//Generate metaclass for class methods
|
||||
llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
|
||||
NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList(
|
||||
empty, empty, empty), ClassMethodList, NULLPtr,
|
||||
NULLPtr, NULLPtr, Zero64, Zero64, true);
|
||||
NULLPtr, NULLPtr, ZeroPtr, ZeroPtr, true);
|
||||
|
||||
// Generate the class structure
|
||||
llvm::Constant *ClassStruct =
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/Mangle.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
@ -858,6 +859,59 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct FunctionIsDirectlyRecursive :
|
||||
public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
|
||||
const StringRef Name;
|
||||
bool Result;
|
||||
FunctionIsDirectlyRecursive(const FunctionDecl *F) :
|
||||
Name(F->getName()), Result(false) {
|
||||
}
|
||||
typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;
|
||||
|
||||
bool TraverseCallExpr(CallExpr *E) {
|
||||
const Decl *D = E->getCalleeDecl();
|
||||
if (!D)
|
||||
return true;
|
||||
AsmLabelAttr *Attr = D->getAttr<AsmLabelAttr>();
|
||||
if (!Attr)
|
||||
return true;
|
||||
if (Name == Attr->getLabel()) {
|
||||
Result = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// isTriviallyRecursiveViaAsm - Check if this function calls another
|
||||
// decl that, because of the asm attribute, ends up pointing to itself.
|
||||
bool
|
||||
CodeGenModule::isTriviallyRecursiveViaAsm(const FunctionDecl *F) {
|
||||
if (getCXXABI().getMangleContext().shouldMangleDeclName(F))
|
||||
return false;
|
||||
|
||||
FunctionIsDirectlyRecursive Walker(F);
|
||||
Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(F));
|
||||
return Walker.Result;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
|
||||
if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage)
|
||||
return true;
|
||||
if (CodeGenOpts.OptimizationLevel == 0 &&
|
||||
!F->hasAttr<AlwaysInlineAttr>())
|
||||
return false;
|
||||
// PR9614. Avoid cases where the source code is lying to us. An available
|
||||
// externally function should have an equivalent function somewhere else,
|
||||
// but a function that calls itself is clearly not equivalent to the real
|
||||
// implementation.
|
||||
// This happens in glibc's btowc and in some configure checks.
|
||||
return !isTriviallyRecursiveViaAsm(F);
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
|
||||
const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
|
||||
|
||||
@ -868,10 +922,7 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
|
||||
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
|
||||
// At -O0, don't generate IR for functions with available_externally
|
||||
// linkage.
|
||||
if (CodeGenOpts.OptimizationLevel == 0 &&
|
||||
!Function->hasAttr<AlwaysInlineAttr>() &&
|
||||
getFunctionLinkage(Function)
|
||||
== llvm::Function::AvailableExternallyLinkage)
|
||||
if (!shouldEmitFunction(Function))
|
||||
return;
|
||||
|
||||
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
|
||||
|
@ -324,6 +324,8 @@ class CodeGenModule : public CodeGenTypeCache {
|
||||
void createOpenCLRuntime();
|
||||
void createCUDARuntime();
|
||||
|
||||
bool isTriviallyRecursiveViaAsm(const FunctionDecl *F);
|
||||
bool shouldEmitFunction(const FunctionDecl *F);
|
||||
llvm::LLVMContext &VMContext;
|
||||
|
||||
/// @name Cache for Blocks Runtime Globals
|
||||
|
@ -211,6 +211,11 @@ std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
|
||||
return ComputeLLVMTriple(Args, InputType);
|
||||
}
|
||||
|
||||
void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const {
|
||||
// Each toolchain should provide the appropriate include flags.
|
||||
}
|
||||
|
||||
ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
|
||||
if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
|
||||
StringRef Value = A->getValue(Args);
|
||||
@ -225,24 +230,18 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
|
||||
return ToolChain::CST_Libstdcxx;
|
||||
}
|
||||
|
||||
void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,
|
||||
ArgStringList &CmdArgs,
|
||||
bool ObjCXXAutoRefCount) const {
|
||||
CXXStdlibType Type = GetCXXStdlibType(Args);
|
||||
|
||||
// Header search paths are handled by the mass of goop in InitHeaderSearch.
|
||||
|
||||
switch (Type) {
|
||||
case ToolChain::CST_Libcxx:
|
||||
if (ObjCXXAutoRefCount)
|
||||
CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
|
||||
break;
|
||||
|
||||
case ToolChain::CST_Libstdcxx:
|
||||
if (ObjCXXAutoRefCount)
|
||||
CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
|
||||
break;
|
||||
}
|
||||
void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const {
|
||||
// Header search paths should be handled by each of the subclasses.
|
||||
// Historically, they have not been, and instead have been handled inside of
|
||||
// the CC1-layer frontend. As the logic is hoisted out, this generic function
|
||||
// will slowly stop being called.
|
||||
//
|
||||
// While it is being called, replicate a bit of a hack to propagate the
|
||||
// '-stdlib=' flag down to CC1 so that it can in turn customize the C++
|
||||
// header search paths with it. Once all systems are overriding this
|
||||
// function, the CC1 flag and this line can be removed.
|
||||
DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
|
||||
}
|
||||
|
||||
void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -372,6 +372,86 @@ class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
|
||||
};
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
|
||||
/// \brief Struct to store and manipulate GCC versions.
|
||||
///
|
||||
/// We rely on assumptions about the form and structure of GCC version
|
||||
/// numbers: they consist of at most three '.'-separated components, and each
|
||||
/// component is a non-negative integer except for the last component. For
|
||||
/// the last component we are very flexible in order to tolerate release
|
||||
/// candidates or 'x' wildcards.
|
||||
///
|
||||
/// Note that the ordering established among GCCVersions is based on the
|
||||
/// preferred version string to use. For example we prefer versions without
|
||||
/// a hard-coded patch number to those with a hard coded patch number.
|
||||
///
|
||||
/// Currently this doesn't provide any logic for textual suffixes to patches
|
||||
/// in the way that (for example) Debian's version format does. If that ever
|
||||
/// becomes necessary, it can be added.
|
||||
struct GCCVersion {
|
||||
/// \brief The unparsed text of the version.
|
||||
std::string Text;
|
||||
|
||||
/// \brief The parsed major, minor, and patch numbers.
|
||||
int Major, Minor, Patch;
|
||||
|
||||
/// \brief Any textual suffix on the patch number.
|
||||
std::string PatchSuffix;
|
||||
|
||||
static GCCVersion Parse(StringRef VersionText);
|
||||
bool operator<(const GCCVersion &RHS) const;
|
||||
bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
|
||||
bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
|
||||
bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
|
||||
};
|
||||
|
||||
|
||||
/// \brief This is a class to find a viable GCC installation for Clang to
|
||||
/// use.
|
||||
///
|
||||
/// This class tries to find a GCC installation on the system, and report
|
||||
/// information about it. It starts from the host information provided to the
|
||||
/// Driver, and has logic for fuzzing that where appropriate.
|
||||
class GCCInstallationDetector {
|
||||
|
||||
bool IsValid;
|
||||
std::string GccTriple;
|
||||
|
||||
// FIXME: These might be better as path objects.
|
||||
std::string GccInstallPath;
|
||||
std::string GccParentLibPath;
|
||||
|
||||
GCCVersion Version;
|
||||
|
||||
public:
|
||||
GCCInstallationDetector(const Driver &D);
|
||||
|
||||
/// \brief Check whether we detected a valid GCC install.
|
||||
bool isValid() const { return IsValid; }
|
||||
|
||||
/// \brief Get the GCC triple for the detected install.
|
||||
StringRef getTriple() const { return GccTriple; }
|
||||
|
||||
/// \brief Get the detected GCC installation path.
|
||||
StringRef getInstallPath() const { return GccInstallPath; }
|
||||
|
||||
/// \brief Get the detected GCC parent lib path.
|
||||
StringRef getParentLibPath() const { return GccParentLibPath; }
|
||||
|
||||
/// \brief Get the detected GCC version string.
|
||||
StringRef getVersion() const { return Version.Text; }
|
||||
|
||||
private:
|
||||
static void CollectLibDirsAndTriples(llvm::Triple::ArchType HostArch,
|
||||
SmallVectorImpl<StringRef> &LibDirs,
|
||||
SmallVectorImpl<StringRef> &Triples);
|
||||
|
||||
void ScanLibDirForGCCTriple(llvm::Triple::ArchType HostArch,
|
||||
const std::string &LibDir,
|
||||
StringRef CandidateTriple);
|
||||
};
|
||||
|
||||
GCCInstallationDetector GCCInstallation;
|
||||
|
||||
public:
|
||||
Linux(const HostInfo &Host, const llvm::Triple& Triple);
|
||||
|
||||
@ -380,6 +460,11 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
|
||||
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
|
||||
const ActionList &Inputs) const;
|
||||
|
||||
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const;
|
||||
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const;
|
||||
|
||||
std::string Linker;
|
||||
std::vector<std::string> ExtraOpts;
|
||||
};
|
||||
@ -417,6 +502,12 @@ class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain {
|
||||
virtual bool IsUnwindTablesDefault() const;
|
||||
virtual const char *GetDefaultRelocationModel() const;
|
||||
virtual const char *GetForcedPicModel() const;
|
||||
|
||||
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const;
|
||||
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
||||
ArgStringList &CC1Args) const;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace toolchains
|
||||
|
@ -364,16 +364,6 @@ void Clang::AddPreprocessingOptions(const Driver &D,
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F,
|
||||
options::OPT_index_header_map);
|
||||
|
||||
// Add C++ include arguments, if needed.
|
||||
types::ID InputType = Inputs[0].getType();
|
||||
if (types::isCXX(InputType)) {
|
||||
bool ObjCXXAutoRefCount
|
||||
= types::isObjC(InputType) && isObjCAutoRefCount(Args);
|
||||
getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs,
|
||||
ObjCXXAutoRefCount);
|
||||
Args.AddAllArgs(CmdArgs, options::OPT_stdlib_EQ);
|
||||
}
|
||||
|
||||
// Add -Wp, and -Xassembler if using the preprocessor.
|
||||
|
||||
// FIXME: There is a very unfortunate problem here, some troubled
|
||||
@ -428,6 +418,13 @@ void Clang::AddPreprocessingOptions(const Driver &D,
|
||||
// OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
|
||||
AddIncludeDirectoryList(Args, CmdArgs, "-objcxx-isystem",
|
||||
::getenv("OBJCPLUS_INCLUDE_PATH"));
|
||||
|
||||
// Add C++ include arguments, if needed.
|
||||
if (types::isCXX(Inputs[0].getType()))
|
||||
getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
|
||||
|
||||
// Add system include arguments.
|
||||
getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
|
||||
}
|
||||
|
||||
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
|
||||
@ -1966,6 +1963,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
if (ARC) {
|
||||
CmdArgs.push_back("-fobjc-arc");
|
||||
|
||||
// FIXME: It seems like this entire block, and several around it should be
|
||||
// wrapped in isObjC, but for now we just use it here as this is where it
|
||||
// was being used previously.
|
||||
if (types::isCXX(InputType) && types::isObjC(InputType)) {
|
||||
if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
|
||||
CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
|
||||
else
|
||||
CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
|
||||
}
|
||||
|
||||
// Allow the user to enable full exceptions code emission.
|
||||
// We define off for Objective-CC, on for Objective-C++.
|
||||
if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
|
||||
|
@ -569,10 +569,18 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (E.Group != frontend::Angled && E.Group != frontend::System)
|
||||
llvm::report_fatal_error("Invalid option set!");
|
||||
Res.push_back(E.Group == frontend::Angled ? "-iwithprefixbefore" :
|
||||
"-iwithprefix");
|
||||
if (E.IsInternal) {
|
||||
assert(E.Group == frontend::System && "Unexpected header search group");
|
||||
if (E.ImplicitExternC)
|
||||
Res.push_back("-internal-externc-isystem");
|
||||
else
|
||||
Res.push_back("-internal-isystem");
|
||||
} else {
|
||||
if (E.Group != frontend::Angled && E.Group != frontend::System)
|
||||
llvm::report_fatal_error("Invalid option set!");
|
||||
Res.push_back(E.Group == frontend::Angled ? "-iwithprefixbefore" :
|
||||
"-iwithprefix");
|
||||
}
|
||||
}
|
||||
Res.push_back(E.Path);
|
||||
}
|
||||
@ -1464,6 +1472,15 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
|
||||
ie = Args.filtered_end(); it != ie; ++it)
|
||||
Opts.AddPath((*it)->getValue(Args), frontend::ObjCXXSystem, true, false,
|
||||
true);
|
||||
|
||||
// Add the internal paths from a driver that detects standard include paths.
|
||||
for (arg_iterator I = Args.filtered_begin(OPT_internal_isystem,
|
||||
OPT_internal_externc_isystem),
|
||||
E = Args.filtered_end();
|
||||
I != E; ++I)
|
||||
Opts.AddPath((*I)->getValue(Args), frontend::System,
|
||||
false, false, /*IgnoreSysRoot=*/true, /*IsInternal=*/true,
|
||||
(*I)->getOption().matches(OPT_internal_externc_isystem));
|
||||
}
|
||||
|
||||
void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
|
||||
|
@ -28,12 +28,9 @@
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#ifdef _MSC_VER
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifndef CLANG_PREFIX
|
||||
#define CLANG_PREFIX
|
||||
#endif
|
||||
@ -211,219 +208,6 @@ void InitHeaderSearch::AddMinGW64CXXPaths(StringRef Base,
|
||||
CXXSystem, true, false, false);
|
||||
}
|
||||
|
||||
// FIXME: This probably should goto to some platform utils place.
|
||||
#ifdef _MSC_VER
|
||||
|
||||
// Read registry string.
|
||||
// This also supports a means to look for high-versioned keys by use
|
||||
// of a $VERSION placeholder in the key path.
|
||||
// $VERSION in the key path is a placeholder for the version number,
|
||||
// causing the highest value path to be searched for and used.
|
||||
// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
|
||||
// There can be additional characters in the component. Only the numberic
|
||||
// characters are compared.
|
||||
static bool getSystemRegistryString(const char *keyPath, const char *valueName,
|
||||
char *value, size_t maxLength) {
|
||||
HKEY hRootKey = NULL;
|
||||
HKEY hKey = NULL;
|
||||
const char* subKey = NULL;
|
||||
DWORD valueType;
|
||||
DWORD valueSize = maxLength - 1;
|
||||
long lResult;
|
||||
bool returnValue = false;
|
||||
|
||||
if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
|
||||
hRootKey = HKEY_CLASSES_ROOT;
|
||||
subKey = keyPath + 18;
|
||||
} else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
|
||||
hRootKey = HKEY_USERS;
|
||||
subKey = keyPath + 11;
|
||||
} else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
|
||||
hRootKey = HKEY_LOCAL_MACHINE;
|
||||
subKey = keyPath + 19;
|
||||
} else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
|
||||
hRootKey = HKEY_CURRENT_USER;
|
||||
subKey = keyPath + 18;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
const char *placeHolder = strstr(subKey, "$VERSION");
|
||||
char bestName[256];
|
||||
bestName[0] = '\0';
|
||||
// If we have a $VERSION placeholder, do the highest-version search.
|
||||
if (placeHolder) {
|
||||
const char *keyEnd = placeHolder - 1;
|
||||
const char *nextKey = placeHolder;
|
||||
// Find end of previous key.
|
||||
while ((keyEnd > subKey) && (*keyEnd != '\\'))
|
||||
keyEnd--;
|
||||
// Find end of key containing $VERSION.
|
||||
while (*nextKey && (*nextKey != '\\'))
|
||||
nextKey++;
|
||||
size_t partialKeyLength = keyEnd - subKey;
|
||||
char partialKey[256];
|
||||
if (partialKeyLength > sizeof(partialKey))
|
||||
partialKeyLength = sizeof(partialKey);
|
||||
strncpy(partialKey, subKey, partialKeyLength);
|
||||
partialKey[partialKeyLength] = '\0';
|
||||
HKEY hTopKey = NULL;
|
||||
lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
|
||||
if (lResult == ERROR_SUCCESS) {
|
||||
char keyName[256];
|
||||
int bestIndex = -1;
|
||||
double bestValue = 0.0;
|
||||
DWORD index, size = sizeof(keyName) - 1;
|
||||
for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
|
||||
NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
|
||||
const char *sp = keyName;
|
||||
while (*sp && !isdigit(*sp))
|
||||
sp++;
|
||||
if (!*sp)
|
||||
continue;
|
||||
const char *ep = sp + 1;
|
||||
while (*ep && (isdigit(*ep) || (*ep == '.')))
|
||||
ep++;
|
||||
char numBuf[32];
|
||||
strncpy(numBuf, sp, sizeof(numBuf) - 1);
|
||||
numBuf[sizeof(numBuf) - 1] = '\0';
|
||||
double value = strtod(numBuf, NULL);
|
||||
if (value > bestValue) {
|
||||
bestIndex = (int)index;
|
||||
bestValue = value;
|
||||
strcpy(bestName, keyName);
|
||||
}
|
||||
size = sizeof(keyName) - 1;
|
||||
}
|
||||
// If we found the highest versioned key, open the key and get the value.
|
||||
if (bestIndex != -1) {
|
||||
// Append rest of key.
|
||||
strncat(bestName, nextKey, sizeof(bestName) - 1);
|
||||
bestName[sizeof(bestName) - 1] = '\0';
|
||||
// Open the chosen key path remainder.
|
||||
lResult = RegOpenKeyEx(hTopKey, bestName, 0, KEY_READ, &hKey);
|
||||
if (lResult == ERROR_SUCCESS) {
|
||||
lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
|
||||
(LPBYTE)value, &valueSize);
|
||||
if (lResult == ERROR_SUCCESS)
|
||||
returnValue = true;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
RegCloseKey(hTopKey);
|
||||
}
|
||||
}
|
||||
else {
|
||||
lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ, &hKey);
|
||||
if (lResult == ERROR_SUCCESS) {
|
||||
lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
|
||||
(LPBYTE)value, &valueSize);
|
||||
if (lResult == ERROR_SUCCESS)
|
||||
returnValue = true;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
#else // _MSC_VER
|
||||
// Read registry string.
|
||||
static bool getSystemRegistryString(const char*, const char*, char*, size_t) {
|
||||
return(false);
|
||||
}
|
||||
#endif // _MSC_VER
|
||||
|
||||
// Get Visual Studio installation directory.
|
||||
static bool getVisualStudioDir(std::string &path) {
|
||||
// First check the environment variables that vsvars32.bat sets.
|
||||
const char* vcinstalldir = getenv("VCINSTALLDIR");
|
||||
if (vcinstalldir) {
|
||||
char *p = const_cast<char *>(strstr(vcinstalldir, "\\VC"));
|
||||
if (p)
|
||||
*p = '\0';
|
||||
path = vcinstalldir;
|
||||
return true;
|
||||
}
|
||||
|
||||
char vsIDEInstallDir[256];
|
||||
char vsExpressIDEInstallDir[256];
|
||||
// Then try the windows registry.
|
||||
bool hasVCDir = getSystemRegistryString(
|
||||
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
|
||||
"InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
|
||||
bool hasVCExpressDir = getSystemRegistryString(
|
||||
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
|
||||
"InstallDir", vsExpressIDEInstallDir, sizeof(vsExpressIDEInstallDir) - 1);
|
||||
// If we have both vc80 and vc90, pick version we were compiled with.
|
||||
if (hasVCDir && vsIDEInstallDir[0]) {
|
||||
char *p = (char*)strstr(vsIDEInstallDir, "\\Common7\\IDE");
|
||||
if (p)
|
||||
*p = '\0';
|
||||
path = vsIDEInstallDir;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hasVCExpressDir && vsExpressIDEInstallDir[0]) {
|
||||
char *p = (char*)strstr(vsExpressIDEInstallDir, "\\Common7\\IDE");
|
||||
if (p)
|
||||
*p = '\0';
|
||||
path = vsExpressIDEInstallDir;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Try the environment.
|
||||
const char *vs100comntools = getenv("VS100COMNTOOLS");
|
||||
const char *vs90comntools = getenv("VS90COMNTOOLS");
|
||||
const char *vs80comntools = getenv("VS80COMNTOOLS");
|
||||
const char *vscomntools = NULL;
|
||||
|
||||
// Try to find the version that we were compiled with
|
||||
if(false) {}
|
||||
#if (_MSC_VER >= 1600) // VC100
|
||||
else if(vs100comntools) {
|
||||
vscomntools = vs100comntools;
|
||||
}
|
||||
#elif (_MSC_VER == 1500) // VC80
|
||||
else if(vs90comntools) {
|
||||
vscomntools = vs90comntools;
|
||||
}
|
||||
#elif (_MSC_VER == 1400) // VC80
|
||||
else if(vs80comntools) {
|
||||
vscomntools = vs80comntools;
|
||||
}
|
||||
#endif
|
||||
// Otherwise find any version we can
|
||||
else if (vs100comntools)
|
||||
vscomntools = vs100comntools;
|
||||
else if (vs90comntools)
|
||||
vscomntools = vs90comntools;
|
||||
else if (vs80comntools)
|
||||
vscomntools = vs80comntools;
|
||||
|
||||
if (vscomntools && *vscomntools) {
|
||||
const char *p = strstr(vscomntools, "\\Common7\\Tools");
|
||||
path = p ? std::string(vscomntools, p) : vscomntools;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get Windows SDK installation directory.
|
||||
static bool getWindowsSDKDir(std::string &path) {
|
||||
char windowsSDKInstallDir[256];
|
||||
// Try the Windows registry.
|
||||
bool hasSDKDir = getSystemRegistryString(
|
||||
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
|
||||
"InstallationFolder",
|
||||
windowsSDKInstallDir,
|
||||
sizeof(windowsSDKInstallDir) - 1);
|
||||
// If we have both vc80 and vc90, pick version we were compiled with.
|
||||
if (hasSDKDir && windowsSDKInstallDir[0]) {
|
||||
path = windowsSDKInstallDir;
|
||||
return(true);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
|
||||
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
|
||||
const HeaderSearchOptions &HSOpts) {
|
||||
llvm::Triple::OSType os = triple.getOS();
|
||||
@ -468,33 +252,10 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
|
||||
}
|
||||
|
||||
switch (os) {
|
||||
case llvm::Triple::Win32: {
|
||||
std::string VSDir;
|
||||
std::string WindowsSDKDir;
|
||||
if (getVisualStudioDir(VSDir)) {
|
||||
AddPath(VSDir + "\\VC\\include", System, false, false, false);
|
||||
if (getWindowsSDKDir(WindowsSDKDir))
|
||||
AddPath(WindowsSDKDir + "\\include", System, false, false, false);
|
||||
else
|
||||
AddPath(VSDir + "\\VC\\PlatformSDK\\Include",
|
||||
System, false, false, false);
|
||||
} else {
|
||||
// Default install paths.
|
||||
AddPath("C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
|
||||
System, false, false, false);
|
||||
AddPath("C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
|
||||
System, false, false, false);
|
||||
AddPath(
|
||||
"C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
|
||||
System, false, false, false);
|
||||
AddPath("C:/Program Files/Microsoft Visual Studio 8/VC/include",
|
||||
System, false, false, false);
|
||||
AddPath(
|
||||
"C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include",
|
||||
System, false, false, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case llvm::Triple::Linux:
|
||||
case llvm::Triple::Win32:
|
||||
llvm_unreachable("Include management is handled in the driver.");
|
||||
|
||||
case llvm::Triple::Haiku:
|
||||
AddPath("/boot/common/include", System, true, false, false);
|
||||
AddPath("/boot/develop/headers/os", System, true, false, false);
|
||||
@ -564,19 +325,6 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
|
||||
System, false, false, false);
|
||||
break;
|
||||
|
||||
case llvm::Triple::Linux:
|
||||
// Generic Debian multiarch support:
|
||||
if (triple.getArch() == llvm::Triple::x86_64) {
|
||||
AddPath("/usr/include/x86_64-linux-gnu", System, false, false, false);
|
||||
AddPath("/usr/include/i686-linux-gnu/64", System, false, false, false);
|
||||
AddPath("/usr/include/i486-linux-gnu/64", System, false, false, false);
|
||||
} else if (triple.getArch() == llvm::Triple::x86) {
|
||||
AddPath("/usr/include/x86_64-linux-gnu/32", System, false, false, false);
|
||||
AddPath("/usr/include/i686-linux-gnu", System, false, false, false);
|
||||
AddPath("/usr/include/i486-linux-gnu", System, false, false, false);
|
||||
} else if (triple.getArch() == llvm::Triple::arm) {
|
||||
AddPath("/usr/include/arm-linux-gnueabi", System, false, false, false);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -637,6 +385,10 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp
|
||||
}
|
||||
|
||||
switch (os) {
|
||||
case llvm::Triple::Linux:
|
||||
case llvm::Triple::Win32:
|
||||
llvm_unreachable("Include management is handled in the driver.");
|
||||
|
||||
case llvm::Triple::Cygwin:
|
||||
// Cygwin-1.7
|
||||
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
|
||||
@ -663,257 +415,6 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp
|
||||
break;
|
||||
case llvm::Triple::DragonFly:
|
||||
AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false);
|
||||
break;
|
||||
case llvm::Triple::Linux:
|
||||
//===------------------------------------------------------------------===//
|
||||
// Debian based distros.
|
||||
// Note: these distros symlink /usr/include/c++/X.Y.Z -> X.Y
|
||||
//===------------------------------------------------------------------===//
|
||||
|
||||
// Ubuntu 11.11 "Oneiric Ocelot" -- gcc-4.6.0
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
|
||||
"x86_64-linux-gnu", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
|
||||
"i686-linux-gnu", "", "64", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
|
||||
"i486-linux-gnu", "", "64", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
|
||||
"arm-linux-gnueabi", "", "", triple);
|
||||
|
||||
// Ubuntu 11.04 "Natty Narwhal" -- gcc-4.5.2
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
|
||||
"x86_64-linux-gnu", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
|
||||
"i686-linux-gnu", "", "64", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
|
||||
"i486-linux-gnu", "", "64", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
|
||||
"arm-linux-gnueabi", "", "", triple);
|
||||
|
||||
// Ubuntu 10.10 "Maverick Meerkat" -- gcc-4.4.5
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
|
||||
"i686-linux-gnu", "", "64", triple);
|
||||
// The rest of 10.10 is the same as previous versions.
|
||||
|
||||
// Ubuntu 10.04 LTS "Lucid Lynx" -- gcc-4.4.3
|
||||
// Ubuntu 9.10 "Karmic Koala" -- gcc-4.4.1
|
||||
// Debian 6.0 "squeeze" -- gcc-4.4.2
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
|
||||
"x86_64-linux-gnu", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
|
||||
"i486-linux-gnu", "", "64", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
|
||||
"arm-linux-gnueabi", "", "", triple);
|
||||
// Ubuntu 9.04 "Jaunty Jackalope" -- gcc-4.3.3
|
||||
// Ubuntu 8.10 "Intrepid Ibex" -- gcc-4.3.2
|
||||
// Debian 5.0 "lenny" -- gcc-4.3.2
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
|
||||
"x86_64-linux-gnu", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
|
||||
"i486-linux-gnu", "", "64", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
|
||||
"arm-linux-gnueabi", "", "", triple);
|
||||
// Ubuntu 8.04.4 LTS "Hardy Heron" -- gcc-4.2.4
|
||||
// Ubuntu 8.04.[0-3] LTS "Hardy Heron" -- gcc-4.2.3
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2",
|
||||
"x86_64-linux-gnu", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2",
|
||||
"i486-linux-gnu", "", "64", triple);
|
||||
// Ubuntu 7.10 "Gutsy Gibbon" -- gcc-4.1.3
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1",
|
||||
"x86_64-linux-gnu", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1",
|
||||
"i486-linux-gnu", "", "64", triple);
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Redhat based distros.
|
||||
//===------------------------------------------------------------------===//
|
||||
// Fedora 15 (GCC 4.6.1)
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1",
|
||||
"i686-redhat-linux", "", "", triple);
|
||||
// Fedora 15 (GCC 4.6.0)
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
|
||||
"i686-redhat-linux", "", "", triple);
|
||||
// Fedora 14
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.1",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.1",
|
||||
"i686-redhat-linux", "", "", triple);
|
||||
// RHEL5(gcc44)
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
|
||||
"x86_64-redhat-linux6E", "32", "", triple);
|
||||
// Fedora 13
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
|
||||
"i686-redhat-linux","", "", triple);
|
||||
// Fedora 12
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
|
||||
"i686-redhat-linux","", "", triple);
|
||||
// Fedora 12 (pre-FEB-2010)
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
|
||||
"i686-redhat-linux","", "", triple);
|
||||
// Fedora 11
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
|
||||
"i586-redhat-linux","", "", triple);
|
||||
// Fedora 10
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
|
||||
"i386-redhat-linux","", "", triple);
|
||||
// Fedora 9
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
|
||||
"i386-redhat-linux", "", "", triple);
|
||||
// Fedora 8
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
|
||||
"x86_64-redhat-linux", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
|
||||
"i386-redhat-linux", "", "", triple);
|
||||
|
||||
// RHEL 5
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1",
|
||||
"x86_64-redhat-linux", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1",
|
||||
"i386-redhat-linux", "", "", triple);
|
||||
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
|
||||
// Exherbo (2010-01-25)
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
|
||||
"x86_64-pc-linux-gnu", "32", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
|
||||
// openSUSE 11.1 32 bit
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
|
||||
"i586-suse-linux", "", "", triple);
|
||||
// openSUSE 11.1 64 bit
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
|
||||
"x86_64-suse-linux", "32", "", triple);
|
||||
// openSUSE 11.2
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
|
||||
"i586-suse-linux", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
|
||||
"x86_64-suse-linux", "", "", triple);
|
||||
|
||||
// openSUSE 11.4
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
|
||||
"i586-suse-linux", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
|
||||
"x86_64-suse-linux", "", "", triple);
|
||||
|
||||
// openSUSE 12.1
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
|
||||
"i586-suse-linux", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
|
||||
"x86_64-suse-linux", "", "", triple);
|
||||
// Arch Linux 2008-06-24
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
|
||||
"x86_64-unknown-linux-gnu", "", "", triple);
|
||||
|
||||
// Arch Linux gcc 4.6
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1",
|
||||
"x86_64-unknown-linux-gnu", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
|
||||
"x86_64-unknown-linux-gnu", "", "", triple);
|
||||
|
||||
// Slackware gcc 4.5.2 (13.37)
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.2",
|
||||
"i486-slackware-linux", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.2",
|
||||
"x86_64-slackware-linux", "", "", triple);
|
||||
// Slackware gcc 4.5.3 (-current)
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.3",
|
||||
"i486-slackware-linux", "", "", triple);
|
||||
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.3",
|
||||
"x86_64-slackware-linux", "", "", triple);
|
||||
|
||||
// Gentoo x86 gcc 4.5.2
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/i686-pc-linux-gnu/4.5.2/include/g++-v4",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo x86 gcc 4.4.5
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/i686-pc-linux-gnu/4.4.5/include/g++-v4",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo x86 gcc 4.4.4
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/i686-pc-linux-gnu/4.4.4/include/g++-v4",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo x86 2010.0 stable
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/include/g++-v4",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo x86 2009.1 stable
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo x86 2009.0 stable
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo x86 2008.0 stable
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo x86 llvm-gcc trunk
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1",
|
||||
"i686-pc-linux-gnu", "", "", triple);
|
||||
|
||||
// Gentoo amd64 gcc 4.5.2
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4",
|
||||
"x86_64-pc-linux-gnu", "32", "", triple);
|
||||
// Gentoo amd64 gcc 4.4.5
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4",
|
||||
"x86_64-pc-linux-gnu", "32", "", triple);
|
||||
// Gentoo amd64 gcc 4.4.4
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4",
|
||||
"x86_64-pc-linux-gnu", "32", "", triple);
|
||||
// Gentoo amd64 gcc 4.4.3
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/include/g++-v4",
|
||||
"x86_64-pc-linux-gnu", "32", "", triple);
|
||||
// Gentoo amd64 gcc 4.3.4
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4",
|
||||
"x86_64-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo amd64 gcc 4.3.2
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.2/include/g++-v4",
|
||||
"x86_64-pc-linux-gnu", "", "", triple);
|
||||
// Gentoo amd64 stable
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4",
|
||||
"x86_64-pc-linux-gnu", "", "", triple);
|
||||
|
||||
// Gentoo amd64 llvm-gcc trunk
|
||||
AddGnuCPlusPlusIncludePaths(
|
||||
"/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1",
|
||||
"x86_64-pc-linux-gnu", "", "", triple);
|
||||
|
||||
break;
|
||||
case llvm::Triple::FreeBSD:
|
||||
// FreeBSD 8.0
|
||||
@ -953,6 +454,19 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp
|
||||
void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
|
||||
const llvm::Triple &triple,
|
||||
const HeaderSearchOptions &HSOpts) {
|
||||
// NB: This code path is going away. All of the logic is moving into the
|
||||
// driver which has the information necessary to do target-specific
|
||||
// selections of default include paths. Each target which moves there will be
|
||||
// exempted from this logic here until we can delete the entire pile of code.
|
||||
switch (triple.getOS()) {
|
||||
default:
|
||||
break; // Everything else continues to use this routine's logic.
|
||||
|
||||
case llvm::Triple::Linux:
|
||||
case llvm::Triple::Win32:
|
||||
return;
|
||||
}
|
||||
|
||||
if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes &&
|
||||
HSOpts.UseStandardSystemIncludes) {
|
||||
if (HSOpts.UseLibcxx) {
|
||||
@ -1155,8 +669,8 @@ void clang::ApplyHeaderSearchOptions(HeaderSearch &HS,
|
||||
// Add the user defined entries.
|
||||
for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) {
|
||||
const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i];
|
||||
Init.AddPath(E.Path, E.Group, false, E.IsUserSupplied, E.IsFramework,
|
||||
E.IgnoreSysRoot);
|
||||
Init.AddPath(E.Path, E.Group, !E.ImplicitExternC, E.IsUserSupplied,
|
||||
E.IsFramework, E.IgnoreSysRoot);
|
||||
}
|
||||
|
||||
Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);
|
||||
|
2
lib/clang/include/MipsGenCodeEmitter.inc
Normal file
2
lib/clang/include/MipsGenCodeEmitter.inc
Normal file
@ -0,0 +1,2 @@
|
||||
/* $FreeBSD$ */
|
||||
#include "MipsGenCodeEmitter.inc.h"
|
@ -5,6 +5,6 @@
|
||||
#define CLANG_VERSION_MINOR 0
|
||||
|
||||
#define CLANG_VENDOR "FreeBSD "
|
||||
#define CLANG_VENDOR_SUFFIX " 20111021"
|
||||
#define CLANG_VENDOR_SUFFIX " 20111209"
|
||||
|
||||
#define SVN_REVISION "142614"
|
||||
#define SVN_REVISION "145546"
|
||||
|
@ -24,6 +24,7 @@ SRCS= MipsAsmPrinter.cpp \
|
||||
TGHDRS= Intrinsics \
|
||||
MipsGenAsmWriter \
|
||||
MipsGenCallingConv \
|
||||
MipsGenCodeEmitter \
|
||||
MipsGenDAGISel \
|
||||
MipsGenInstrInfo \
|
||||
MipsGenRegisterInfo \
|
||||
|
Loading…
Reference in New Issue
Block a user