diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
commit | cd749a9c07f1de2fb8affde90537efa4bc3e7c54 (patch) | |
tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /lib/Target/Alpha | |
parent | 72621d11de5b873f1695f391eb95f0b336c3d2d4 (diff) | |
download | FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.zip FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.tar.gz |
Update llvm to r84119.
Diffstat (limited to 'lib/Target/Alpha')
27 files changed, 707 insertions, 636 deletions
diff --git a/lib/Target/Alpha/Alpha.h b/lib/Target/Alpha/Alpha.h index 0818e25..b8a0645 100644 --- a/lib/Target/Alpha/Alpha.h +++ b/lib/Target/Alpha/Alpha.h @@ -22,20 +22,22 @@ namespace llvm { class AlphaTargetMachine; class FunctionPass; class MachineCodeEmitter; - class raw_ostream; + class ObjectCodeEmitter; + class formatted_raw_ostream; FunctionPass *createAlphaISelDag(AlphaTargetMachine &TM); - FunctionPass *createAlphaCodePrinterPass(raw_ostream &OS, - TargetMachine &TM, - bool Verbose); FunctionPass *createAlphaPatternInstructionSelector(TargetMachine &TM); FunctionPass *createAlphaCodeEmitterPass(AlphaTargetMachine &TM, MachineCodeEmitter &MCE); FunctionPass *createAlphaJITCodeEmitterPass(AlphaTargetMachine &TM, - JITCodeEmitter &JCE); + JITCodeEmitter &JCE); + FunctionPass *createAlphaObjectCodeEmitterPass(AlphaTargetMachine &TM, + ObjectCodeEmitter &OCE); FunctionPass *createAlphaLLRPPass(AlphaTargetMachine &tm); FunctionPass *createAlphaBranchSelectionPass(); + extern Target TheAlphaTarget; + } // end namespace llvm; // Defines symbolic names for Alpha registers. This defines a mapping from diff --git a/lib/Target/Alpha/Alpha.td b/lib/Target/Alpha/Alpha.td index e3748c6..6efdf55 100644 --- a/lib/Target/Alpha/Alpha.td +++ b/lib/Target/Alpha/Alpha.td @@ -30,6 +30,12 @@ def FeatureCIX : SubtargetFeature<"cix", "HasCT", "true", include "AlphaRegisterInfo.td" //===----------------------------------------------------------------------===// +// Calling Convention Description +//===----------------------------------------------------------------------===// + +include "AlphaCallingConv.td" + +//===----------------------------------------------------------------------===// // Schedule Description //===----------------------------------------------------------------------===// diff --git a/lib/Target/Alpha/AlphaBranchSelector.cpp b/lib/Target/Alpha/AlphaBranchSelector.cpp index aca8ca7..719ffae 100644 --- a/lib/Target/Alpha/AlphaBranchSelector.cpp +++ b/lib/Target/Alpha/AlphaBranchSelector.cpp @@ -17,7 +17,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/Compiler.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/MC/MCAsmInfo.h" using namespace llvm; namespace { diff --git a/lib/Target/Alpha/AlphaCallingConv.td b/lib/Target/Alpha/AlphaCallingConv.td new file mode 100644 index 0000000..38ada69 --- /dev/null +++ b/lib/Target/Alpha/AlphaCallingConv.td @@ -0,0 +1,37 @@ +//===- AlphaCallingConv.td - Calling Conventions for Alpha -*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This describes the calling conventions for Alpha architecture. +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Alpha Return Value Calling Convention +//===----------------------------------------------------------------------===// +def RetCC_Alpha : CallingConv<[ + // i64 is returned in register R0 + CCIfType<[i64], CCAssignToReg<[R0]>>, + + // f32 / f64 are returned in F0/F1 + CCIfType<[f32, f64], CCAssignToReg<[F0, F1]>> +]>; + +//===----------------------------------------------------------------------===// +// Alpha Argument Calling Conventions +//===----------------------------------------------------------------------===// +def CC_Alpha : CallingConv<[ + // The first 6 arguments are passed in registers, whether integer or + // floating-point + CCIfType<[i64], CCAssignToRegWithShadow<[R16, R17, R18, R19, R20, R21], + [F16, F17, F18, F19, F20, F21]>>, + + CCIfType<[f32, f64], CCAssignToRegWithShadow<[F16, F17, F18, F19, F20, F21], + [R16, R17, R18, R19, R20, R21]>>, + + // Stack slots are 8 bytes in size and 8-byte aligned. + CCIfType<[i64, f32, f64], CCAssignToStack<8, 8>> +]>; diff --git a/lib/Target/Alpha/AlphaCodeEmitter.cpp b/lib/Target/Alpha/AlphaCodeEmitter.cpp index f50f007..8023add 100644 --- a/lib/Target/Alpha/AlphaCodeEmitter.cpp +++ b/lib/Target/Alpha/AlphaCodeEmitter.cpp @@ -19,16 +19,19 @@ #include "llvm/PassManager.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/JITCodeEmitter.h" +#include "llvm/CodeGen/ObjectCodeEmitter.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Function.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { - + class AlphaCodeEmitter { MachineCodeEmitter &MCE; public: @@ -57,7 +60,7 @@ namespace { public: static char ID; explicit Emitter(TargetMachine &tm, CodeEmitter &mce) - : MachineFunctionPass(&ID), AlphaCodeEmitter(mce), + : MachineFunctionPass(&ID), AlphaCodeEmitter(mce), II(0), TM(tm), MCE(mce) {} Emitter(TargetMachine &tm, CodeEmitter &mce, const AlphaInstrInfo& ii) : MachineFunctionPass(&ID), AlphaCodeEmitter(mce), @@ -69,8 +72,6 @@ namespace { return "Alpha Machine Code Emitter"; } - void emitInstruction(const MachineInstr &MI); - private: void emitBasicBlock(MachineBasicBlock &MBB); }; @@ -91,6 +92,10 @@ FunctionPass *llvm::createAlphaJITCodeEmitterPass(AlphaTargetMachine &TM, JITCodeEmitter &JCE) { return new Emitter<JITCodeEmitter>(TM, JCE); } +FunctionPass *llvm::createAlphaObjectCodeEmitterPass(AlphaTargetMachine &TM, + ObjectCodeEmitter &OCE) { + return new Emitter<ObjectCodeEmitter>(TM, OCE); +} template <class CodeEmitter> bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) { @@ -111,6 +116,7 @@ void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) { for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) { const MachineInstr &MI = *I; + MCE.processDebugLoc(MI.getDebugLoc(), true); switch(MI.getOpcode()) { default: MCE.emitWordLE(getBinaryCodeForInstr(*I)); @@ -119,8 +125,10 @@ void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) { case Alpha::PCLABEL: case Alpha::MEMLABEL: case TargetInstrInfo::IMPLICIT_DEF: + case TargetInstrInfo::KILL: break; //skip these } + MCE.processDebugLoc(MI.getDebugLoc(), false); } } @@ -159,13 +167,12 @@ static unsigned getAlphaRegNumber(unsigned Reg) { case Alpha::R30 : case Alpha::F30 : return 30; case Alpha::R31 : case Alpha::F31 : return 31; default: - assert(0 && "Unhandled reg"); - abort(); + llvm_unreachable("Unhandled reg"); } } unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr &MI, - const MachineOperand &MO) { + const MachineOperand &MO) { unsigned rv = 0; // Return value; defaults to 0 for unhandled cases // or things that get fixed up later by the JIT. @@ -175,7 +182,7 @@ unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr &MI, } else if (MO.isImm()) { rv = MO.getImm(); } else if (MO.isGlobal() || MO.isSymbol() || MO.isCPI()) { - DOUT << MO << " is a relocated op for " << MI << "\n"; + DEBUG(errs() << MO << " is a relocated op for " << MI << "\n"); unsigned Reloc = 0; int Offset = 0; bool useGOT = false; @@ -211,8 +218,7 @@ unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr &MI, Offset = MI.getOperand(3).getImm(); break; default: - assert(0 && "unknown relocatable instruction"); - abort(); + llvm_unreachable("unknown relocatable instruction"); } if (MO.isGlobal()) MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), @@ -229,14 +235,14 @@ unsigned AlphaCodeEmitter::getMachineOpValue(const MachineInstr &MI, } else if (MO.isMBB()) { MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), Alpha::reloc_bsr, MO.getMBB())); - }else { - cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; - abort(); + } else { +#ifndef NDEBUG + errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; +#endif + llvm_unreachable(0); } return rv; } #include "AlphaGenCodeEmitter.inc" - - diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp index e3f631a..e3587fb 100644 --- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp +++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp @@ -26,9 +26,12 @@ #include "llvm/DerivedTypes.h" #include "llvm/GlobalValue.h" #include "llvm/Intrinsics.h" +#include "llvm/LLVMContext.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" #include <algorithm> using namespace llvm; @@ -114,7 +117,7 @@ namespace { uint64_t complow = 1 << (63 - at); uint64_t comphigh = 1 << (64 - at); //cerr << x << ":" << complow << ":" << comphigh << "\n"; - if (abs(complow - x) <= abs(comphigh - x)) + if (abs64(complow - x) <= abs64(comphigh - x)) return complow; else return comphigh; @@ -208,7 +211,6 @@ private: /// GOT address into a register. /// SDNode *AlphaDAGToDAGISel::getGlobalBaseReg() { - MachineFunction *MF = BB->getParent(); unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF); return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); } @@ -216,7 +218,6 @@ SDNode *AlphaDAGToDAGISel::getGlobalBaseReg() { /// getGlobalRetAddr - Grab the return address. /// SDNode *AlphaDAGToDAGISel::getGlobalRetAddr() { - MachineFunction *MF = BB->getParent(); unsigned GlobalRetAddr = getInstrInfo()->getGlobalRetAddr(MF); return CurDAG->getRegister(GlobalRetAddr, TLI.getPointerTy()).getNode(); } @@ -269,8 +270,8 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R27, N0, Chain.getValue(1)); SDNode *CNode = - CurDAG->getTargetNode(Alpha::JSRs, dl, MVT::Other, MVT::Flag, - Chain, Chain.getValue(1)); + CurDAG->getMachineNode(Alpha::JSRs, dl, MVT::Other, MVT::Flag, + Chain, Chain.getValue(1)); Chain = CurDAG->getCopyFromReg(Chain, dl, Alpha::R27, MVT::i64, SDValue(CNode, 1)); return CurDAG->SelectNodeTo(N, Alpha::BISr, MVT::i64, Chain, Chain); @@ -278,8 +279,8 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { case ISD::READCYCLECOUNTER: { SDValue Chain = N->getOperand(0); - return CurDAG->getTargetNode(Alpha::RPCC, dl, MVT::i64, MVT::Other, - Chain); + return CurDAG->getMachineNode(Alpha::RPCC, dl, MVT::i64, MVT::Other, + Chain); } case ISD::Constant: { @@ -302,10 +303,11 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { // val32 >= IMM_LOW + IMM_LOW * IMM_MULT) //always true break; //(zext (LDAH (LDA))) //Else use the constant pool - ConstantInt *C = ConstantInt::get(Type::Int64Ty, uval); + ConstantInt *C = ConstantInt::get( + Type::getInt64Ty(*CurDAG->getContext()), uval); SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64); - SDNode *Tmp = CurDAG->getTargetNode(Alpha::LDAHr, dl, MVT::i64, CPI, - SDValue(getGlobalBaseReg(), 0)); + SDNode *Tmp = CurDAG->getMachineNode(Alpha::LDAHr, dl, MVT::i64, CPI, + SDValue(getGlobalBaseReg(), 0)); return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other, CPI, SDValue(Tmp, 0), CurDAG->getEntryNode()); } @@ -313,7 +315,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { case ISD::ConstantFP: { ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N); bool isDouble = N->getValueType(0) == MVT::f64; - MVT T = isDouble ? MVT::f64 : MVT::f32; + EVT T = isDouble ? MVT::f64 : MVT::f32; if (CN->getValueAPF().isPosZero()) { return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS, T, CurDAG->getRegister(Alpha::F31, T), @@ -323,7 +325,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { T, CurDAG->getRegister(Alpha::F31, T), CurDAG->getRegister(Alpha::F31, T)); } else { - abort(); + llvm_report_error("Unhandled FP constant type"); } break; } @@ -336,7 +338,7 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { bool rev = false; bool inv = false; switch(CC) { - default: DEBUG(N->dump(CurDAG)); assert(0 && "Unknown FP comparison!"); + default: DEBUG(N->dump(CurDAG)); llvm_unreachable("Unknown FP comparison!"); case ISD::SETEQ: case ISD::SETOEQ: case ISD::SETUEQ: Opc = Alpha::CMPTEQ; break; case ISD::SETLT: case ISD::SETOLT: case ISD::SETULT: @@ -356,48 +358,29 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { }; SDValue tmp1 = N->getOperand(rev?1:0); SDValue tmp2 = N->getOperand(rev?0:1); - SDNode *cmp = CurDAG->getTargetNode(Opc, dl, MVT::f64, tmp1, tmp2); + SDNode *cmp = CurDAG->getMachineNode(Opc, dl, MVT::f64, tmp1, tmp2); if (inv) - cmp = CurDAG->getTargetNode(Alpha::CMPTEQ, dl, - MVT::f64, SDValue(cmp, 0), - CurDAG->getRegister(Alpha::F31, MVT::f64)); + cmp = CurDAG->getMachineNode(Alpha::CMPTEQ, dl, + MVT::f64, SDValue(cmp, 0), + CurDAG->getRegister(Alpha::F31, MVT::f64)); switch(CC) { case ISD::SETUEQ: case ISD::SETULT: case ISD::SETULE: case ISD::SETUNE: case ISD::SETUGT: case ISD::SETUGE: { - SDNode* cmp2 = CurDAG->getTargetNode(Alpha::CMPTUN, dl, MVT::f64, - tmp1, tmp2); - cmp = CurDAG->getTargetNode(Alpha::ADDT, dl, MVT::f64, - SDValue(cmp2, 0), SDValue(cmp, 0)); + SDNode* cmp2 = CurDAG->getMachineNode(Alpha::CMPTUN, dl, MVT::f64, + tmp1, tmp2); + cmp = CurDAG->getMachineNode(Alpha::ADDT, dl, MVT::f64, + SDValue(cmp2, 0), SDValue(cmp, 0)); break; } default: break; } - SDNode* LD = CurDAG->getTargetNode(Alpha::FTOIT, dl, - MVT::i64, SDValue(cmp, 0)); - return CurDAG->getTargetNode(Alpha::CMPULT, dl, MVT::i64, - CurDAG->getRegister(Alpha::R31, MVT::i64), - SDValue(LD,0)); - } - break; - - case ISD::SELECT: - if (N->getValueType(0).isFloatingPoint() && - (N->getOperand(0).getOpcode() != ISD::SETCC || - !N->getOperand(0).getOperand(1).getValueType().isFloatingPoint())) { - //This should be the condition not covered by the Patterns - //FIXME: Don't have SelectCode die, but rather return something testable - // so that things like this can be caught in fall though code - //move int to fp - bool isDouble = N->getValueType(0) == MVT::f64; - SDValue cond = N->getOperand(0); - SDValue TV = N->getOperand(1); - SDValue FV = N->getOperand(2); - - SDNode* LD = CurDAG->getTargetNode(Alpha::ITOFT, dl, MVT::f64, cond); - return CurDAG->getTargetNode(isDouble?Alpha::FCMOVNET:Alpha::FCMOVNES, - dl, MVT::f64, FV, TV, SDValue(LD,0)); + SDNode* LD = CurDAG->getMachineNode(Alpha::FTOIT, dl, + MVT::i64, SDValue(cmp, 0)); + return CurDAG->getMachineNode(Alpha::CMPULT, dl, MVT::i64, + CurDAG->getRegister(Alpha::R31, MVT::i64), + SDValue(LD,0)); } break; @@ -422,11 +405,11 @@ SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { if (get_zapImm(mask)) { SDValue Z = - SDValue(CurDAG->getTargetNode(Alpha::ZAPNOTi, dl, MVT::i64, - N->getOperand(0).getOperand(0), - getI64Imm(get_zapImm(mask))), 0); - return CurDAG->getTargetNode(Alpha::SRLr, dl, MVT::i64, Z, - getI64Imm(sval)); + SDValue(CurDAG->getMachineNode(Alpha::ZAPNOTi, dl, MVT::i64, + N->getOperand(0).getOperand(0), + getI64Imm(get_zapImm(mask))), 0); + return CurDAG->getMachineNode(Alpha::SRLr, dl, MVT::i64, Z, + getI64Imm(sval)); } } break; @@ -443,95 +426,26 @@ void AlphaDAGToDAGISel::SelectCALL(SDValue Op) { SDNode *N = Op.getNode(); SDValue Chain = N->getOperand(0); SDValue Addr = N->getOperand(1); - SDValue InFlag(0,0); // Null incoming flag value. + SDValue InFlag = N->getOperand(N->getNumOperands() - 1); DebugLoc dl = N->getDebugLoc(); - std::vector<SDValue> CallOperands; - std::vector<MVT> TypeOperands; - - //grab the arguments - for(int i = 2, e = N->getNumOperands(); i < e; ++i) { - TypeOperands.push_back(N->getOperand(i).getValueType()); - CallOperands.push_back(N->getOperand(i)); - } - int count = N->getNumOperands() - 2; - - static const unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18, - Alpha::R19, Alpha::R20, Alpha::R21}; - static const unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18, - Alpha::F19, Alpha::F20, Alpha::F21}; - - for (int i = 6; i < count; ++i) { - unsigned Opc = Alpha::WTF; - if (TypeOperands[i].isInteger()) { - Opc = Alpha::STQ; - } else if (TypeOperands[i] == MVT::f32) { - Opc = Alpha::STS; - } else if (TypeOperands[i] == MVT::f64) { - Opc = Alpha::STT; - } else - assert(0 && "Unknown operand"); - - SDValue Ops[] = { CallOperands[i], getI64Imm((i - 6) * 8), - CurDAG->getCopyFromReg(Chain, dl, Alpha::R30, MVT::i64), - Chain }; - Chain = SDValue(CurDAG->getTargetNode(Opc, dl, MVT::Other, Ops, 4), 0); - } - for (int i = 0; i < std::min(6, count); ++i) { - if (TypeOperands[i].isInteger()) { - Chain = CurDAG->getCopyToReg(Chain, dl, args_int[i], - CallOperands[i], InFlag); - InFlag = Chain.getValue(1); - } else if (TypeOperands[i] == MVT::f32 || TypeOperands[i] == MVT::f64) { - Chain = CurDAG->getCopyToReg(Chain, dl, args_float[i], - CallOperands[i], InFlag); - InFlag = Chain.getValue(1); - } else - assert(0 && "Unknown operand"); - } - - // Finally, once everything is in registers to pass to the call, emit the - // call itself. if (Addr.getOpcode() == AlphaISD::GPRelLo) { SDValue GOT = SDValue(getGlobalBaseReg(), 0); Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R29, GOT, InFlag); InFlag = Chain.getValue(1); - Chain = SDValue(CurDAG->getTargetNode(Alpha::BSR, dl, MVT::Other, - MVT::Flag, Addr.getOperand(0), - Chain, InFlag), 0); + Chain = SDValue(CurDAG->getMachineNode(Alpha::BSR, dl, MVT::Other, + MVT::Flag, Addr.getOperand(0), + Chain, InFlag), 0); } else { Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R27, Addr, InFlag); InFlag = Chain.getValue(1); - Chain = SDValue(CurDAG->getTargetNode(Alpha::JSR, dl, MVT::Other, - MVT::Flag, Chain, InFlag), 0); + Chain = SDValue(CurDAG->getMachineNode(Alpha::JSR, dl, MVT::Other, + MVT::Flag, Chain, InFlag), 0); } InFlag = Chain.getValue(1); - std::vector<SDValue> CallResults; - - switch (N->getValueType(0).getSimpleVT()) { - default: assert(0 && "Unexpected ret value!"); - case MVT::Other: break; - case MVT::i64: - Chain = CurDAG->getCopyFromReg(Chain, dl, - Alpha::R0, MVT::i64, InFlag).getValue(1); - CallResults.push_back(Chain.getValue(0)); - break; - case MVT::f32: - Chain = CurDAG->getCopyFromReg(Chain, dl, - Alpha::F0, MVT::f32, InFlag).getValue(1); - CallResults.push_back(Chain.getValue(0)); - break; - case MVT::f64: - Chain = CurDAG->getCopyFromReg(Chain, dl, - Alpha::F0, MVT::f64, InFlag).getValue(1); - CallResults.push_back(Chain.getValue(0)); - break; - } - - CallResults.push_back(Chain); - for (unsigned i = 0, e = CallResults.size(); i != e; ++i) - ReplaceUses(Op.getValue(i), CallResults[i]); + ReplaceUses(Op.getValue(0), Chain); + ReplaceUses(Op.getValue(1), InFlag); } diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index fa0b656..b3f865c 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -13,17 +13,22 @@ #include "AlphaISelLowering.h" #include "AlphaTargetMachine.h" +#include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Module.h" #include "llvm/Intrinsics.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; /// AddLiveIn - This helper function adds the specified physical register to the @@ -37,14 +42,15 @@ static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, return VReg; } -AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) { +AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) + : TargetLowering(TM, new TargetLoweringObjectFileELF()) { // Set up the TargetLowering object. //I am having problems with shr n i8 1 setShiftAmountType(MVT::i64); setBooleanContents(ZeroOrOneBooleanContent); - + setUsesGlobalOffsetTable(true); - + addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass); addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass); @@ -54,24 +60,26 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); - + setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, Expand); - + setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); + setTruncStoreAction(MVT::f64, MVT::f32, Expand); + // setOperationAction(ISD::BRIND, MVT::Other, Expand); setOperationAction(ISD::BR_JT, MVT::Other, Expand); setOperationAction(ISD::BR_CC, MVT::Other, Expand); - setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); + setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); setOperationAction(ISD::FREM, MVT::f32, Expand); setOperationAction(ISD::FREM, MVT::f64, Expand); - + setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); @@ -85,7 +93,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::BSWAP , MVT::i64, Expand); setOperationAction(ISD::ROTL , MVT::i64, Expand); setOperationAction(ISD::ROTR , MVT::i64, Expand); - + setOperationAction(ISD::SREM , MVT::i64, Custom); setOperationAction(ISD::UREM , MVT::i64, Custom); setOperationAction(ISD::SDIV , MVT::i64, Custom); @@ -99,6 +107,9 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); + setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom); + setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand); + setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand); // We don't support sin/cos/sqrt/pow setOperationAction(ISD::FSIN , MVT::f64, Expand); @@ -123,7 +134,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); // Not implemented yet. - setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); + setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); @@ -141,8 +152,6 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::VAARG, MVT::Other, Custom); setOperationAction(ISD::VAARG, MVT::i32, Custom); - setOperationAction(ISD::RET, MVT::Other, Custom); - setOperationAction(ISD::JumpTable, MVT::i64, Custom); setOperationAction(ISD::JumpTable, MVT::i32, Custom); @@ -159,7 +168,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) computeRegisterProperties(); } -MVT AlphaTargetLowering::getSetCCResultType(MVT VT) const { +MVT::SimpleValueType AlphaTargetLowering::getSetCCResultType(EVT VT) const { return MVT::i64; } @@ -187,13 +196,13 @@ unsigned AlphaTargetLowering::getFunctionAlignment(const Function *F) const { } static SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) { - MVT PtrVT = Op.getValueType(); + EVT PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); SDValue Zero = DAG.getConstant(0, PtrVT); // FIXME there isn't really any debug info here DebugLoc dl = Op.getDebugLoc(); - + SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, JTI, DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, JTI, Hi); @@ -219,43 +228,205 @@ static SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) { // //#define GP $29 // //#define SP $30 -static SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, - int &VarArgsBase, - int &VarArgsOffset) { +#include "AlphaGenCallingConv.inc" + +SDValue +AlphaTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + // Analyze operands of the call, assigning locations to each operand. + SmallVector<CCValAssign, 16> ArgLocs; + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); + + CCInfo.AnalyzeCallOperands(Outs, CC_Alpha); + + // Get a count of how many bytes are to be pushed on the stack. + unsigned NumBytes = CCInfo.getNextStackOffset(); + + Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes, + getPointerTy(), true)); + + SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; + SmallVector<SDValue, 12> MemOpChains; + SDValue StackPtr; + + // Walk the register/memloc assignments, inserting copies/loads. + for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { + CCValAssign &VA = ArgLocs[i]; + + SDValue Arg = Outs[i].Val; + + // Promote the value if needed. + switch (VA.getLocInfo()) { + default: assert(0 && "Unknown loc info!"); + case CCValAssign::Full: break; + case CCValAssign::SExt: + Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); + break; + case CCValAssign::ZExt: + Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); + break; + case CCValAssign::AExt: + Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); + break; + } + + // Arguments that can be passed on register must be kept at RegsToPass + // vector + if (VA.isRegLoc()) { + RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); + } else { + assert(VA.isMemLoc()); + + if (StackPtr.getNode() == 0) + StackPtr = DAG.getCopyFromReg(Chain, dl, Alpha::R30, MVT::i64); + + SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), + StackPtr, + DAG.getIntPtrConstant(VA.getLocMemOffset())); + + MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, + PseudoSourceValue::getStack(), 0)); + } + } + + // Transform all store nodes into one single node because all store nodes are + // independent of each other. + if (!MemOpChains.empty()) + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &MemOpChains[0], MemOpChains.size()); + + // Build a sequence of copy-to-reg nodes chained together with token chain and + // flag operands which copy the outgoing args into registers. The InFlag in + // necessary since all emited instructions must be stuck together. + SDValue InFlag; + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { + Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, + RegsToPass[i].second, InFlag); + InFlag = Chain.getValue(1); + } + + // Returns a chain & a flag for retval copy to use. + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SmallVector<SDValue, 8> Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + + // Add argument registers to the end of the list so that they are + // known live into the call. + for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) + Ops.push_back(DAG.getRegister(RegsToPass[i].first, + RegsToPass[i].second.getValueType())); + + if (InFlag.getNode()) + Ops.push_back(InFlag); + + Chain = DAG.getNode(AlphaISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); + InFlag = Chain.getValue(1); + + // Create the CALLSEQ_END node. + Chain = DAG.getCALLSEQ_END(Chain, + DAG.getConstant(NumBytes, getPointerTy(), true), + DAG.getConstant(0, getPointerTy(), true), + InFlag); + InFlag = Chain.getValue(1); + + // Handle result values, copying them out of physregs into vregs that we + // return. + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, + Ins, dl, DAG, InVals); +} + +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +/// +SDValue +AlphaTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + // Assign locations to each value returned by this call. + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, + *DAG.getContext()); + + CCInfo.AnalyzeCallResult(Ins, RetCC_Alpha); + + // Copy all of the result registers out of their specified physreg. + for (unsigned i = 0; i != RVLocs.size(); ++i) { + CCValAssign &VA = RVLocs[i]; + + Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), + VA.getLocVT(), InFlag).getValue(1); + SDValue RetValue = Chain.getValue(0); + InFlag = Chain.getValue(2); + + // If this is an 8/16/32-bit value, it is really passed promoted to 64 + // bits. Insert an assert[sz]ext to capture this, then truncate to the + // right size. + if (VA.getLocInfo() == CCValAssign::SExt) + RetValue = DAG.getNode(ISD::AssertSext, dl, VA.getLocVT(), RetValue, + DAG.getValueType(VA.getValVT())); + else if (VA.getLocInfo() == CCValAssign::ZExt) + RetValue = DAG.getNode(ISD::AssertZext, dl, VA.getLocVT(), RetValue, + DAG.getValueType(VA.getValVT())); + + if (VA.getLocInfo() != CCValAssign::Full) + RetValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), RetValue); + + InVals.push_back(RetValue); + } + + return Chain; +} + +SDValue +AlphaTargetLowering::LowerFormalArguments(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - std::vector<SDValue> ArgValues; - SDValue Root = Op.getOperand(0); - DebugLoc dl = Op.getDebugLoc(); unsigned args_int[] = { Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21}; unsigned args_float[] = { Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21}; - - for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues()-1; ArgNo != e; ++ArgNo) { + + for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { SDValue argt; - MVT ObjectVT = Op.getValue(ArgNo).getValueType(); + EVT ObjectVT = Ins[ArgNo].VT; SDValue ArgVal; if (ArgNo < 6) { - switch (ObjectVT.getSimpleVT()) { + switch (ObjectVT.getSimpleVT().SimpleTy) { default: assert(false && "Invalid value type!"); case MVT::f64: - args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], + args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], &Alpha::F8RCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, args_float[ArgNo], ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT); break; case MVT::f32: - args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], + args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo], &Alpha::F4RCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, args_float[ArgNo], ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT); break; case MVT::i64: - args_int[ArgNo] = AddLiveIn(MF, args_int[ArgNo], + args_int[ArgNo] = AddLiveIn(MF, args_int[ArgNo], &Alpha::GPRCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, args_int[ArgNo], MVT::i64); + ArgVal = DAG.getCopyFromReg(Chain, dl, args_int[ArgNo], MVT::i64); break; } } else { //more args @@ -265,60 +436,58 @@ static SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG, // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i64); - ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0); + ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0); } - ArgValues.push_back(ArgVal); + InVals.push_back(ArgVal); } // If the functions takes variable number of arguments, copy all regs to stack - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; if (isVarArg) { - VarArgsOffset = (Op.getNode()->getNumValues()-1) * 8; + VarArgsOffset = Ins.size() * 8; std::vector<SDValue> LS; for (int i = 0; i < 6; ++i) { if (TargetRegisterInfo::isPhysicalRegister(args_int[i])) args_int[i] = AddLiveIn(MF, args_int[i], &Alpha::GPRCRegClass); - SDValue argt = DAG.getCopyFromReg(Root, dl, args_int[i], MVT::i64); + SDValue argt = DAG.getCopyFromReg(Chain, dl, args_int[i], MVT::i64); int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); if (i == 0) VarArgsBase = FI; SDValue SDFI = DAG.getFrameIndex(FI, MVT::i64); - LS.push_back(DAG.getStore(Root, dl, argt, SDFI, NULL, 0)); + LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0)); if (TargetRegisterInfo::isPhysicalRegister(args_float[i])) args_float[i] = AddLiveIn(MF, args_float[i], &Alpha::F8RCRegClass); - argt = DAG.getCopyFromReg(Root, dl, args_float[i], MVT::f64); + argt = DAG.getCopyFromReg(Chain, dl, args_float[i], MVT::f64); FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); SDFI = DAG.getFrameIndex(FI, MVT::i64); - LS.push_back(DAG.getStore(Root, dl, argt, SDFI, NULL, 0)); + LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, NULL, 0)); } //Set up a token factor with all the stack traffic - Root = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LS[0], LS.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LS[0], LS.size()); } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()); + return Chain; } -static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { - DebugLoc dl = Op.getDebugLoc(); - SDValue Copy = DAG.getCopyToReg(Op.getOperand(0), dl, Alpha::R26, - DAG.getNode(AlphaISD::GlobalRetAddr, - DebugLoc::getUnknownLoc(), - MVT::i64), - SDValue()); - switch (Op.getNumOperands()) { +SDValue +AlphaTargetLowering::LowerReturn(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + + SDValue Copy = DAG.getCopyToReg(Chain, dl, Alpha::R26, + DAG.getNode(AlphaISD::GlobalRetAddr, + DebugLoc::getUnknownLoc(), + MVT::i64), + SDValue()); + switch (Outs.size()) { default: - assert(0 && "Do not know how to return this many arguments!"); - abort(); - case 1: + llvm_unreachable("Do not know how to return this many arguments!"); + case 0: break; //return SDValue(); // ret void is legal - case 3: { - MVT ArgVT = Op.getOperand(1).getValueType(); + case 1: { + EVT ArgVT = Outs[0].Val.getValueType(); unsigned ArgReg; if (ArgVT.isInteger()) ArgReg = Alpha::R0; @@ -326,14 +495,14 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { assert(ArgVT.isFloatingPoint()); ArgReg = Alpha::F0; } - Copy = DAG.getCopyToReg(Copy, dl, ArgReg, - Op.getOperand(1), Copy.getValue(1)); + Copy = DAG.getCopyToReg(Copy, dl, ArgReg, + Outs[0].Val, Copy.getValue(1)); if (DAG.getMachineFunction().getRegInfo().liveout_empty()) DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg); break; } - case 5: { - MVT ArgVT = Op.getOperand(1).getValueType(); + case 2: { + EVT ArgVT = Outs[0].Val.getValueType(); unsigned ArgReg1, ArgReg2; if (ArgVT.isInteger()) { ArgReg1 = Alpha::R0; @@ -343,104 +512,25 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { ArgReg1 = Alpha::F0; ArgReg2 = Alpha::F1; } - Copy = DAG.getCopyToReg(Copy, dl, ArgReg1, - Op.getOperand(1), Copy.getValue(1)); - if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), + Copy = DAG.getCopyToReg(Copy, dl, ArgReg1, + Outs[0].Val, Copy.getValue(1)); + if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg1) == DAG.getMachineFunction().getRegInfo().liveout_end()) DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg1); - Copy = DAG.getCopyToReg(Copy, dl, ArgReg2, - Op.getOperand(3), Copy.getValue(1)); - if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), + Copy = DAG.getCopyToReg(Copy, dl, ArgReg2, + Outs[1].Val, Copy.getValue(1)); + if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(), DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg2) == DAG.getMachineFunction().getRegInfo().liveout_end()) DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg2); break; } } - return DAG.getNode(AlphaISD::RET_FLAG, dl, + return DAG.getNode(AlphaISD::RET_FLAG, dl, MVT::Other, Copy, Copy.getValue(1)); } -std::pair<SDValue, SDValue> -AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, - bool RetSExt, bool RetZExt, bool isVarArg, - bool isInreg, unsigned NumFixedArgs, - unsigned CallingConv, - bool isTailCall, SDValue Callee, - ArgListTy &Args, SelectionDAG &DAG, - DebugLoc dl) { - int NumBytes = 0; - if (Args.size() > 6) - NumBytes = (Args.size() - 6) * 8; - - Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); - std::vector<SDValue> args_to_use; - for (unsigned i = 0, e = Args.size(); i != e; ++i) - { - switch (getValueType(Args[i].Ty).getSimpleVT()) { - default: assert(0 && "Unexpected ValueType for argument!"); - case MVT::i1: - case MVT::i8: - case MVT::i16: - case MVT::i32: - // Promote the integer to 64 bits. If the input type is signed use a - // sign extend, otherwise use a zero extend. - if (Args[i].isSExt) - Args[i].Node = DAG.getNode(ISD::SIGN_EXTEND, dl, - MVT::i64, Args[i].Node); - else if (Args[i].isZExt) - Args[i].Node = DAG.getNode(ISD::ZERO_EXTEND, dl, - MVT::i64, Args[i].Node); - else - Args[i].Node = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i64, Args[i].Node); - break; - case MVT::i64: - case MVT::f64: - case MVT::f32: - break; - } - args_to_use.push_back(Args[i].Node); - } - - std::vector<MVT> RetVals; - MVT RetTyVT = getValueType(RetTy); - MVT ActualRetTyVT = RetTyVT; - if (RetTyVT.getSimpleVT() >= MVT::i1 && RetTyVT.getSimpleVT() <= MVT::i32) - ActualRetTyVT = MVT::i64; - - if (RetTyVT != MVT::isVoid) - RetVals.push_back(ActualRetTyVT); - RetVals.push_back(MVT::Other); - - std::vector<SDValue> Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - Ops.insert(Ops.end(), args_to_use.begin(), args_to_use.end()); - SDValue TheCall = DAG.getNode(AlphaISD::CALL, dl, - RetVals, &Ops[0], Ops.size()); - Chain = TheCall.getValue(RetTyVT != MVT::isVoid); - Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), - DAG.getIntPtrConstant(0, true), SDValue()); - SDValue RetVal = TheCall; - - if (RetTyVT != ActualRetTyVT) { - ISD::NodeType AssertKind = ISD::DELETED_NODE; - if (RetSExt) - AssertKind = ISD::AssertSext; - else if (RetZExt) - AssertKind = ISD::AssertZext; - - if (AssertKind != ISD::DELETED_NODE) - RetVal = DAG.getNode(AssertKind, dl, MVT::i64, RetVal, - DAG.getValueType(RetTyVT)); - - RetVal = DAG.getNode(ISD::TRUNCATE, dl, RetTyVT, RetVal); - } - - return std::make_pair(RetVal, Chain); -} - void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain, SDValue &DataPtr, SelectionDAG &DAG) { Chain = N->getOperand(0); @@ -475,12 +565,7 @@ void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain, SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { DebugLoc dl = Op.getDebugLoc(); switch (Op.getOpcode()) { - default: assert(0 && "Wasn't expecting to be able to lower this!"); - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG, - VarArgsBase, - VarArgsOffset); - - case ISD::RET: return LowerRET(Op,DAG); + default: llvm_unreachable("Wasn't expecting to be able to lower this!"); case ISD::JumpTable: return LowerJumpTable(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: { @@ -488,11 +573,40 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (IntNo) { default: break; // Don't custom lower most intrinsics. case Intrinsic::alpha_umulh: - return DAG.getNode(ISD::MULHU, dl, MVT::i64, + return DAG.getNode(ISD::MULHU, dl, MVT::i64, Op.getOperand(1), Op.getOperand(2)); } } + case ISD::SRL_PARTS: { + SDValue ShOpLo = Op.getOperand(0); + SDValue ShOpHi = Op.getOperand(1); + SDValue ShAmt = Op.getOperand(2); + SDValue bm = DAG.getNode(ISD::SUB, dl, MVT::i64, + DAG.getConstant(64, MVT::i64), ShAmt); + SDValue BMCC = DAG.getSetCC(dl, MVT::i64, bm, + DAG.getConstant(0, MVT::i64), ISD::SETLE); + // if 64 - shAmt <= 0 + SDValue Hi_Neg = DAG.getConstant(0, MVT::i64); + SDValue ShAmt_Neg = DAG.getNode(ISD::SUB, dl, MVT::i64, + DAG.getConstant(0, MVT::i64), bm); + SDValue Lo_Neg = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt_Neg); + // else + SDValue carries = DAG.getNode(ISD::SHL, dl, MVT::i64, ShOpHi, bm); + SDValue Hi_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt); + SDValue Lo_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpLo, ShAmt); + Lo_Pos = DAG.getNode(ISD::OR, dl, MVT::i64, Lo_Pos, carries); + // Merge + SDValue Hi = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Hi_Neg, Hi_Pos); + SDValue Lo = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Lo_Neg, Lo_Pos); + SDValue Ops[2] = { Lo, Hi }; + return DAG.getMergeValues(Ops, 2, dl); + } + // case ISD::SRA_PARTS: + + // case ISD::SHL_PARTS: + + case ISD::SINT_TO_FP: { assert(Op.getOperand(0).getValueType() == MVT::i64 && "Unhandled SINT_TO_FP type in custom expander!"); @@ -509,7 +623,7 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { if (!isDouble) //Promote src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, src); - + src = DAG.getNode(AlphaISD::CVTTQ_, dl, MVT::f64, src); return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i64, src); @@ -519,14 +633,14 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { Constant *C = CP->getConstVal(); SDValue CPI = DAG.getTargetConstantPool(C, MVT::i64, CP->getAlignment()); // FIXME there isn't really any debug info here - + SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, CPI, DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, CPI, Hi); return Lo; } case ISD::GlobalTLSAddress: - assert(0 && "TLS not implemented for Alpha."); + llvm_unreachable("TLS not implemented for Alpha."); case ISD::GlobalAddress: { GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); GlobalValue *GV = GSDN->getGlobal(); @@ -540,11 +654,11 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, GA, Hi); return Lo; } else - return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, GA, + return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, GA, DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); } case ISD::ExternalSymbol: { - return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, + return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op) ->getSymbol(), MVT::i64), DAG.getGLOBAL_OFFSET_TABLE(MVT::i64)); @@ -554,7 +668,7 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SREM: //Expand only on constant case if (Op.getOperand(1).getOpcode() == ISD::Constant) { - MVT VT = Op.getNode()->getValueType(0); + EVT VT = Op.getNode()->getValueType(0); SDValue Tmp1 = Op.getNode()->getOpcode() == ISD::UREM ? BuildUDIV(Op.getNode(), DAG, NULL) : BuildSDIV(Op.getNode(), DAG, NULL); @@ -567,7 +681,7 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::UDIV: if (Op.getValueType().isInteger()) { if (Op.getOperand(1).getOpcode() == ISD::Constant) - return Op.getOpcode() == ISD::SDIV ? BuildSDIV(Op.getNode(), DAG, NULL) + return Op.getOpcode() == ISD::SDIV ? BuildSDIV(Op.getNode(), DAG, NULL) : BuildUDIV(Op.getNode(), DAG, NULL); const char* opstr = 0; switch (Op.getOpcode()) { @@ -601,12 +715,12 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { SDValue SrcP = Op.getOperand(2); const Value *DestS = cast<SrcValueSDNode>(Op.getOperand(3))->getValue(); const Value *SrcS = cast<SrcValueSDNode>(Op.getOperand(4))->getValue(); - + SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP, SrcS, 0); SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP, DestS, 0); - SDValue NP = DAG.getNode(ISD::ADD, dl, MVT::i64, SrcP, + SDValue NP = DAG.getNode(ISD::ADD, dl, MVT::i64, SrcP, DAG.getConstant(8, MVT::i64)); - Val = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Result, + Val = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Result, NP, NULL,0, MVT::i32); SDValue NPD = DAG.getNode(ISD::ADD, dl, MVT::i64, DestP, DAG.getConstant(8, MVT::i64)); @@ -616,7 +730,7 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { SDValue Chain = Op.getOperand(0); SDValue VAListP = Op.getOperand(1); const Value *VAListS = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); - + // vastart stores the address of the VarArgsBase and VarArgsOffset SDValue FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP, VAListS, 0); @@ -625,13 +739,13 @@ SDValue AlphaTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { return DAG.getTruncStore(S1, dl, DAG.getConstant(VarArgsOffset, MVT::i64), SA2, NULL, 0, MVT::i32); } - case ISD::RETURNADDR: + case ISD::RETURNADDR: return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc::getUnknownLoc(), MVT::i64); //FIXME: implement case ISD::FRAMEADDR: break; } - + return SDValue(); } @@ -655,7 +769,7 @@ void AlphaTargetLowering::ReplaceNodeResults(SDNode *N, /// getConstraintType - Given a constraint letter, return the type of /// constraint it is for this target. -AlphaTargetLowering::ConstraintType +AlphaTargetLowering::ConstraintType AlphaTargetLowering::getConstraintType(const std::string &Constraint) const { if (Constraint.size() == 1) { switch (Constraint[0]) { @@ -670,37 +784,37 @@ AlphaTargetLowering::getConstraintType(const std::string &Constraint) const { std::vector<unsigned> AlphaTargetLowering:: getRegClassForInlineAsmConstraint(const std::string &Constraint, - MVT VT) const { + EVT VT) const { if (Constraint.size() == 1) { switch (Constraint[0]) { default: break; // Unknown constriant letter - case 'f': + case 'f': return make_vector<unsigned>(Alpha::F0 , Alpha::F1 , Alpha::F2 , Alpha::F3 , Alpha::F4 , Alpha::F5 , - Alpha::F6 , Alpha::F7 , Alpha::F8 , - Alpha::F9 , Alpha::F10, Alpha::F11, - Alpha::F12, Alpha::F13, Alpha::F14, - Alpha::F15, Alpha::F16, Alpha::F17, - Alpha::F18, Alpha::F19, Alpha::F20, - Alpha::F21, Alpha::F22, Alpha::F23, - Alpha::F24, Alpha::F25, Alpha::F26, - Alpha::F27, Alpha::F28, Alpha::F29, + Alpha::F6 , Alpha::F7 , Alpha::F8 , + Alpha::F9 , Alpha::F10, Alpha::F11, + Alpha::F12, Alpha::F13, Alpha::F14, + Alpha::F15, Alpha::F16, Alpha::F17, + Alpha::F18, Alpha::F19, Alpha::F20, + Alpha::F21, Alpha::F22, Alpha::F23, + Alpha::F24, Alpha::F25, Alpha::F26, + Alpha::F27, Alpha::F28, Alpha::F29, Alpha::F30, Alpha::F31, 0); - case 'r': - return make_vector<unsigned>(Alpha::R0 , Alpha::R1 , Alpha::R2 , - Alpha::R3 , Alpha::R4 , Alpha::R5 , - Alpha::R6 , Alpha::R7 , Alpha::R8 , - Alpha::R9 , Alpha::R10, Alpha::R11, - Alpha::R12, Alpha::R13, Alpha::R14, - Alpha::R15, Alpha::R16, Alpha::R17, - Alpha::R18, Alpha::R19, Alpha::R20, - Alpha::R21, Alpha::R22, Alpha::R23, - Alpha::R24, Alpha::R25, Alpha::R26, - Alpha::R27, Alpha::R28, Alpha::R29, + case 'r': + return make_vector<unsigned>(Alpha::R0 , Alpha::R1 , Alpha::R2 , + Alpha::R3 , Alpha::R4 , Alpha::R5 , + Alpha::R6 , Alpha::R7 , Alpha::R8 , + Alpha::R9 , Alpha::R10, Alpha::R11, + Alpha::R12, Alpha::R13, Alpha::R14, + Alpha::R15, Alpha::R16, Alpha::R17, + Alpha::R18, Alpha::R19, Alpha::R20, + Alpha::R21, Alpha::R22, Alpha::R23, + Alpha::R24, Alpha::R25, Alpha::R26, + Alpha::R27, Alpha::R28, Alpha::R29, Alpha::R30, Alpha::R31, 0); } } - + return std::vector<unsigned>(); } //===----------------------------------------------------------------------===// @@ -709,7 +823,8 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint, MachineBasicBlock * AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const { + MachineBasicBlock *BB, + DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); assert((MI->getOpcode() == Alpha::CAS32 || MI->getOpcode() == Alpha::CAS64 || @@ -719,10 +834,10 @@ AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MI->getOpcode() == Alpha::SWAP64) && "Unexpected instr type to insert"); - bool is32 = MI->getOpcode() == Alpha::CAS32 || + bool is32 = MI->getOpcode() == Alpha::CAS32 || MI->getOpcode() == Alpha::LAS32 || MI->getOpcode() == Alpha::SWAP32; - + //Load locked store conditional for atomic ops take on the same form //start: //ll @@ -734,30 +849,35 @@ AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, DebugLoc dl = MI->getDebugLoc(); MachineFunction::iterator It = BB; ++It; - + MachineBasicBlock *thisMBB = BB; MachineFunction *F = BB->getParent(); MachineBasicBlock *llscMBB = F->CreateMachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB); + // Inform sdisel of the edge changes. + for (MachineBasicBlock::succ_iterator I = BB->succ_begin(), + E = BB->succ_end(); I != E; ++I) + EM->insert(std::make_pair(*I, sinkMBB)); + sinkMBB->transferSuccessors(thisMBB); F->insert(It, llscMBB); F->insert(It, sinkMBB); BuildMI(thisMBB, dl, TII->get(Alpha::BR)).addMBB(llscMBB); - + unsigned reg_res = MI->getOperand(0).getReg(), reg_ptr = MI->getOperand(1).getReg(), reg_v2 = MI->getOperand(2).getReg(), reg_store = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass); - BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::LDL_L : Alpha::LDQ_L), + BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::LDL_L : Alpha::LDQ_L), reg_res).addImm(0).addReg(reg_ptr); switch (MI->getOpcode()) { case Alpha::CAS32: case Alpha::CAS64: { - unsigned reg_cmp + unsigned reg_cmp = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass); BuildMI(llscMBB, dl, TII->get(Alpha::CMPEQ), reg_cmp) .addReg(reg_v2).addReg(reg_res); diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h index 4925367..b580c9d 100644 --- a/lib/Target/Alpha/AlphaISelLowering.h +++ b/lib/Target/Alpha/AlphaISelLowering.h @@ -62,12 +62,11 @@ namespace llvm { class AlphaTargetLowering : public TargetLowering { int VarArgsOffset; // What is the offset to the first vaarg int VarArgsBase; // What is the base FrameIndex - bool useITOF; public: explicit AlphaTargetLowering(TargetMachine &TM); /// getSetCCResultType - Get the SETCC result ValueType - virtual MVT getSetCCResultType(MVT VT) const; + virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; /// LowerOperation - Provide custom lowering hooks for some operations. /// @@ -82,24 +81,21 @@ namespace llvm { // Friendly names for dumps const char *getTargetNodeName(unsigned Opcode) const; - /// LowerCallTo - This hook lowers an abstract call to a function into an - /// actual call. - virtual std::pair<SDValue, SDValue> - LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, - bool isVarArg, bool isInreg, unsigned NumFixedArgs, unsigned CC, - bool isTailCall, SDValue Callee, ArgListTy &Args, - SelectionDAG &DAG, DebugLoc dl); + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); ConstraintType getConstraintType(const std::string &Constraint) const; std::vector<unsigned> getRegClassForInlineAsmConstraint(const std::string &Constraint, - MVT VT) const; - - bool hasITOF() { return useITOF; } + EVT VT) const; MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const; + MachineBasicBlock *BB, + DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const; virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; @@ -111,6 +107,26 @@ namespace llvm { void LowerVAARG(SDNode *N, SDValue &Chain, SDValue &DataPtr, SelectionDAG &DAG); + virtual SDValue + LowerFormalArguments(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); }; } diff --git a/lib/Target/Alpha/AlphaInstrInfo.cpp b/lib/Target/Alpha/AlphaInstrInfo.cpp index 76a594f..86173ff 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.cpp +++ b/lib/Target/Alpha/AlphaInstrInfo.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; AlphaInstrInfo::AlphaInstrInfo() @@ -200,29 +201,7 @@ AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FrameIdx).addReg(Alpha::F31); else - abort(); -} - -void AlphaInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, - bool isKill, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const { - unsigned Opc = 0; - if (RC == Alpha::F4RCRegisterClass) - Opc = Alpha::STS; - else if (RC == Alpha::F8RCRegisterClass) - Opc = Alpha::STT; - else if (RC == Alpha::GPRCRegisterClass) - Opc = Alpha::STQ; - else - abort(); - DebugLoc DL = DebugLoc::getUnknownLoc(); - MachineInstrBuilder MIB = - BuildMI(MF, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)); - for (unsigned i = 0, e = Addr.size(); i != e; ++i) - MIB.addOperand(Addr[i]); - NewMIs.push_back(MIB); + llvm_unreachable("Unhandled register class"); } void @@ -245,28 +224,7 @@ AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, BuildMI(MBB, MI, DL, get(Alpha::LDQ), DestReg) .addFrameIndex(FrameIdx).addReg(Alpha::F31); else - abort(); -} - -void AlphaInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const { - unsigned Opc = 0; - if (RC == Alpha::F4RCRegisterClass) - Opc = Alpha::LDS; - else if (RC == Alpha::F8RCRegisterClass) - Opc = Alpha::LDT; - else if (RC == Alpha::GPRCRegisterClass) - Opc = Alpha::LDQ; - else - abort(); - DebugLoc DL = DebugLoc::getUnknownLoc(); - MachineInstrBuilder MIB = - BuildMI(MF, DL, get(Opc), DestReg); - for (unsigned i = 0, e = Addr.size(); i != e; ++i) - MIB.addOperand(Addr[i]); - NewMIs.push_back(MIB); + llvm_unreachable("Unhandled register class"); } MachineInstr *AlphaInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, @@ -331,7 +289,7 @@ static unsigned AlphaRevCondCode(unsigned Opcode) { case Alpha::FBLE: return Alpha::FBGT; case Alpha::FBLT: return Alpha::FBGE; default: - assert(0 && "Unknown opcode"); + llvm_unreachable("Unknown opcode"); } return 0; // Not reached } diff --git a/lib/Target/Alpha/AlphaInstrInfo.h b/lib/Target/Alpha/AlphaInstrInfo.h index ea09885..274f452 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.h +++ b/lib/Target/Alpha/AlphaInstrInfo.h @@ -54,20 +54,10 @@ public: unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const; - virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; - - virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const; virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF, MachineInstr* MI, diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index e73bdf9..3b98206 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -702,7 +702,7 @@ def FCMOVNET : FPForm<0x17, 0x02B, "fcmovne $RCOND,$RTRUE,$RDEST", [], s_fcmov>; //misc FP selects //Select double - + def : Pat<(select (seteq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), (FCMOVNET F8RC:$sf, F8RC:$st, (CMPTEQ F8RC:$RA, F8RC:$RB))>; def : Pat<(select (setoeq F8RC:$RA, F8RC:$RB), F8RC:$st, F8RC:$sf), @@ -791,12 +791,14 @@ def : Pat<(select (setule F8RC:$RA, F8RC:$RB), F4RC:$st, F4RC:$sf), let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F4RC:$RA), Fb = 31 in -def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[], s_ftoi>; //Floating to integer move, S_floating +def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC", + [(set GPRC:$RC, (bitconvert F4RC:$RA))], s_ftoi>; //Floating to integer move, S_floating let OutOperandList = (ops GPRC:$RC), InOperandList = (ops F8RC:$RA), Fb = 31 in def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC", [(set GPRC:$RC, (bitconvert F8RC:$RA))], s_ftoi>; //Floating to integer move let OutOperandList = (ops F4RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in -def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[], s_itof>; //Integer to floating move, S_floating +def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC", + [(set F4RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move, S_floating let OutOperandList = (ops F8RC:$RC), InOperandList = (ops GPRC:$RA), Fb = 31 in def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC", [(set F8RC:$RC, (bitconvert GPRC:$RA))], s_itof>; //Integer to floating move @@ -818,6 +820,10 @@ let OutOperandList = (ops F4RC:$RC), InOperandList = (ops F8RC:$RB), Fa = 31 in def CVTTS : FPForm<0x16, 0x7AC, "cvtts/sui $RB,$RC", [(set F4RC:$RC, (fround F8RC:$RB))], s_fadd>; +def : Pat<(select GPRC:$RC, F8RC:$st, F8RC:$sf), + (f64 (FCMOVEQT F8RC:$st, F8RC:$sf, (ITOFT GPRC:$RC)))>; +def : Pat<(select GPRC:$RC, F4RC:$st, F4RC:$sf), + (f32 (FCMOVEQS F4RC:$st, F4RC:$sf, (ITOFT GPRC:$RC)))>; ///////////////////////////////////////////////////////// //Branching diff --git a/lib/Target/Alpha/AlphaJITInfo.cpp b/lib/Target/Alpha/AlphaJITInfo.cpp index ba7478e..d328135 100644 --- a/lib/Target/Alpha/AlphaJITInfo.cpp +++ b/lib/Target/Alpha/AlphaJITInfo.cpp @@ -16,8 +16,9 @@ #include "AlphaRelocations.h" #include "llvm/Function.h" #include "llvm/CodeGen/JITCodeEmitter.h" -#include "llvm/Config/alloca.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include <cstdlib> using namespace llvm; @@ -57,12 +58,12 @@ static void EmitBranchToAt(void *At, void *To) { AtI[0] = BUILD_OR(0, 27, 27); - DOUT << "Stub targeting " << To << "\n"; + DEBUG(errs() << "Stub targeting " << To << "\n"); for (int x = 1; x <= 8; ++x) { AtI[2*x - 1] = BUILD_SLLi(27,27,8); unsigned d = (Fn >> (64 - 8 * x)) & 0x00FF; - //DOUT << "outputing " << hex << d << dec << "\n"; + //DEBUG(errs() << "outputing " << hex << d << dec << "\n"); AtI[2*x] = BUILD_ORi(27, 27, d); } AtI[17] = BUILD_JMP(31,27,0); //jump, preserving ra, and setting pv @@ -71,7 +72,7 @@ static void EmitBranchToAt(void *At, void *To) { void AlphaJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { //FIXME - assert(0); + llvm_unreachable(0); } static TargetJITInfo::JITCompilerFn JITCompilerFunction; @@ -86,12 +87,12 @@ extern "C" { //rewrite the stub to an unconditional branch if (((unsigned*)CameFromStub)[18] == 0x00FFFFFF) { - DOUT << "Came from a stub, rewriting\n"; + DEBUG(errs() << "Came from a stub, rewriting\n"); EmitBranchToAt(CameFromStub, Target); } else { - DOUT << "confused, didn't come from stub at " << CameFromStub - << " old jump vector " << oldpv - << " new jump vector " << Target << "\n"; + DEBUG(errs() << "confused, didn't come from stub at " << CameFromStub + << " old jump vector " << oldpv + << " new jump vector " << Target << "\n"); } //Change pv to new Target @@ -184,8 +185,7 @@ extern "C" { ); #else void AlphaCompilationCallback() { - cerr << "Cannot call AlphaCompilationCallback() on a non-Alpha arch!\n"; - abort(); + llvm_unreachable("Cannot call AlphaCompilationCallback() on a non-Alpha arch!"); } #endif } @@ -199,7 +199,7 @@ void *AlphaJITInfo::emitFunctionStub(const Function* F, void *Fn, for (int x = 0; x < 19; ++ x) JCE.emitWordLE(0); EmitBranchToAt(Addr, Fn); - DOUT << "Emitting Stub to " << Fn << " at [" << Addr << "]\n"; + DEBUG(errs() << "Emitting Stub to " << Fn << " at [" << Addr << "]\n"); return JCE.finishGVStub(F); } @@ -241,34 +241,34 @@ void AlphaJITInfo::relocate(void *Function, MachineRelocation *MR, long idx = 0; bool doCommon = true; switch ((Alpha::RelocationType)MR->getRelocationType()) { - default: assert(0 && "Unknown relocation type!"); + default: llvm_unreachable("Unknown relocation type!"); case Alpha::reloc_literal: //This is a LDQl idx = MR->getGOTIndex(); - DOUT << "Literal relocation to slot " << idx; + DEBUG(errs() << "Literal relocation to slot " << idx); idx = (idx - GOToffset) * 8; - DOUT << " offset " << idx << "\n"; + DEBUG(errs() << " offset " << idx << "\n"); break; case Alpha::reloc_gprellow: idx = (unsigned char*)MR->getResultPointer() - &GOTBase[GOToffset * 8]; idx = getLower16(idx); - DOUT << "gprellow relocation offset " << idx << "\n"; - DOUT << " Pointer is " << (void*)MR->getResultPointer() - << " GOT is " << (void*)&GOTBase[GOToffset * 8] << "\n"; + DEBUG(errs() << "gprellow relocation offset " << idx << "\n"); + DEBUG(errs() << " Pointer is " << (void*)MR->getResultPointer() + << " GOT is " << (void*)&GOTBase[GOToffset * 8] << "\n"); break; case Alpha::reloc_gprelhigh: idx = (unsigned char*)MR->getResultPointer() - &GOTBase[GOToffset * 8]; idx = getUpper16(idx); - DOUT << "gprelhigh relocation offset " << idx << "\n"; - DOUT << " Pointer is " << (void*)MR->getResultPointer() - << " GOT is " << (void*)&GOTBase[GOToffset * 8] << "\n"; + DEBUG(errs() << "gprelhigh relocation offset " << idx << "\n"); + DEBUG(errs() << " Pointer is " << (void*)MR->getResultPointer() + << " GOT is " << (void*)&GOTBase[GOToffset * 8] << "\n"); break; case Alpha::reloc_gpdist: switch (*RelocPos >> 26) { case 0x09: //LDAH idx = &GOTBase[GOToffset * 8] - (unsigned char*)RelocPos; idx = getUpper16(idx); - DOUT << "LDAH: " << idx << "\n"; + DEBUG(errs() << "LDAH: " << idx << "\n"); //add the relocation to the map gpdistmap[std::make_pair(Function, MR->getConstantVal())] = RelocPos; break; @@ -278,10 +278,10 @@ void AlphaJITInfo::relocate(void *Function, MachineRelocation *MR, idx = &GOTBase[GOToffset * 8] - (unsigned char*)gpdistmap[std::make_pair(Function, MR->getConstantVal())]; idx = getLower16(idx); - DOUT << "LDA: " << idx << "\n"; + DEBUG(errs() << "LDA: " << idx << "\n"); break; default: - assert(0 && "Cannot handle gpdist yet"); + llvm_unreachable("Cannot handle gpdist yet"); } break; case Alpha::reloc_bsr: { diff --git a/lib/Target/Alpha/AlphaMCAsmInfo.cpp b/lib/Target/Alpha/AlphaMCAsmInfo.cpp new file mode 100644 index 0000000..b652a53 --- /dev/null +++ b/lib/Target/Alpha/AlphaMCAsmInfo.cpp @@ -0,0 +1,22 @@ +//===-- AlphaMCAsmInfo.cpp - Alpha asm properties ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the AlphaMCAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "AlphaMCAsmInfo.h" +using namespace llvm; + +AlphaMCAsmInfo::AlphaMCAsmInfo(const Target &T, const StringRef &TT) { + AlignmentIsInBytes = false; + PrivateGlobalPrefix = "$"; + PICJumpTableDirective = ".gprel32"; + WeakRefDirective = "\t.weak\t"; +} diff --git a/lib/Target/Alpha/AlphaMCAsmInfo.h b/lib/Target/Alpha/AlphaMCAsmInfo.h new file mode 100644 index 0000000..c27065d --- /dev/null +++ b/lib/Target/Alpha/AlphaMCAsmInfo.h @@ -0,0 +1,29 @@ +//=====-- AlphaMCAsmInfo.h - Alpha asm properties -------------*- C++ -*--====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the AlphaMCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef ALPHATARGETASMINFO_H +#define ALPHATARGETASMINFO_H + +#include "llvm/MC/MCAsmInfo.h" + +namespace llvm { + class Target; + class StringRef; + + struct AlphaMCAsmInfo : public MCAsmInfo { + explicit AlphaMCAsmInfo(const Target &T, const StringRef &TT); + }; + +} // namespace llvm + +#endif diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp index 0ff53c7..98e9730 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.cpp +++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp @@ -28,6 +28,8 @@ #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include <cstdlib> @@ -149,8 +151,10 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, //variable locals //<- SP -void AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS) const { +unsigned +AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, int *Value, + RegScavenger *RS) const { assert(SPAdj == 0 && "Unexpected"); unsigned i = 0; @@ -172,16 +176,16 @@ void AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // Now add the frame object offset to the offset from the virtual frame index. int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); - DOUT << "FI: " << FrameIndex << " Offset: " << Offset << "\n"; + DEBUG(errs() << "FI: " << FrameIndex << " Offset: " << Offset << "\n"); Offset += MF.getFrameInfo()->getStackSize(); - DOUT << "Corrected Offset " << Offset - << " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n"; + DEBUG(errs() << "Corrected Offset " << Offset + << " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n"); if (Offset > IMM_HIGH || Offset < IMM_LOW) { - DOUT << "Unconditionally using R28 for evil purposes Offset: " - << Offset << "\n"; + DEBUG(errs() << "Unconditionally using R28 for evil purposes Offset: " + << Offset << "\n"); //so in this case, we need to use a temporary register, and move the //original inst off the SP/FP //fix up the old: @@ -195,6 +199,7 @@ void AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, } else { MI.getOperand(i).ChangeToImmediate(Offset); } + return 0; } @@ -244,8 +249,10 @@ void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const { BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30) .addImm(getLower16(NumBytes)).addReg(Alpha::R30); } else { - cerr << "Too big a stack frame at " << NumBytes << "\n"; - abort(); + std::string msg; + raw_string_ostream Msg(msg); + Msg << "Too big a stack frame at " + NumBytes; + llvm_report_error(Msg.str()); } //now if we need to, save the old FP and set the new @@ -294,14 +301,16 @@ void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30) .addImm(getLower16(NumBytes)).addReg(Alpha::R30); } else { - cerr << "Too big a stack frame at " << NumBytes << "\n"; - abort(); + std::string msg; + raw_string_ostream Msg(msg); + Msg << "Too big a stack frame at " + NumBytes; + llvm_report_error(Msg.str()); } } } unsigned AlphaRegisterInfo::getRARegister() const { - assert(0 && "What is the return address register"); + llvm_unreachable("What is the return address register"); return 0; } @@ -310,17 +319,17 @@ unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const { } unsigned AlphaRegisterInfo::getEHExceptionRegister() const { - assert(0 && "What is the exception register"); + llvm_unreachable("What is the exception register"); return 0; } unsigned AlphaRegisterInfo::getEHHandlerRegister() const { - assert(0 && "What is the exception handler register"); + llvm_unreachable("What is the exception handler register"); return 0; } int AlphaRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { - assert(0 && "What is the dwarf register number"); + llvm_unreachable("What is the dwarf register number"); return -1; } diff --git a/lib/Target/Alpha/AlphaRegisterInfo.h b/lib/Target/Alpha/AlphaRegisterInfo.h index 5012fe8..66f0898 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.h +++ b/lib/Target/Alpha/AlphaRegisterInfo.h @@ -41,8 +41,9 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo { MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; - void eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS = NULL) const; + unsigned eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, int *Value = NULL, + RegScavenger *RS = NULL) const; //void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; diff --git a/lib/Target/Alpha/AlphaSubtarget.cpp b/lib/Target/Alpha/AlphaSubtarget.cpp index d5a9365..bda7104 100644 --- a/lib/Target/Alpha/AlphaSubtarget.cpp +++ b/lib/Target/Alpha/AlphaSubtarget.cpp @@ -16,7 +16,7 @@ #include "AlphaGenSubtarget.inc" using namespace llvm; -AlphaSubtarget::AlphaSubtarget(const Module &M, const std::string &FS) +AlphaSubtarget::AlphaSubtarget(const std::string &TT, const std::string &FS) : HasCT(false) { std::string CPU = "generic"; diff --git a/lib/Target/Alpha/AlphaSubtarget.h b/lib/Target/Alpha/AlphaSubtarget.h index 0a944cb..f0eb93c 100644 --- a/lib/Target/Alpha/AlphaSubtarget.h +++ b/lib/Target/Alpha/AlphaSubtarget.h @@ -20,7 +20,6 @@ #include <string> namespace llvm { -class Module; class AlphaSubtarget : public TargetSubtarget { protected: @@ -31,9 +30,9 @@ protected: public: /// This constructor initializes the data members to match that - /// of the specified module. + /// of the specified triple. /// - AlphaSubtarget(const Module &M, const std::string &FS); + AlphaSubtarget(const std::string &TT, const std::string &FS); /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. diff --git a/lib/Target/Alpha/AlphaTargetMachine.cpp b/lib/Target/Alpha/AlphaTargetMachine.cpp index 060089c..b8bc13b 100644 --- a/lib/Target/Alpha/AlphaTargetMachine.cpp +++ b/lib/Target/Alpha/AlphaTargetMachine.cpp @@ -12,60 +12,26 @@ #include "Alpha.h" #include "AlphaJITInfo.h" -#include "AlphaTargetAsmInfo.h" +#include "AlphaMCAsmInfo.h" #include "AlphaTargetMachine.h" -#include "llvm/Module.h" #include "llvm/PassManager.h" -#include "llvm/Target/TargetMachineRegistry.h" -#include "llvm/Support/raw_ostream.h" - +#include "llvm/Support/FormattedStream.h" +#include "llvm/Target/TargetRegistry.h" using namespace llvm; -// Register the targets -static RegisterTarget<AlphaTargetMachine> X("alpha", "Alpha [experimental]"); - -// No assembler printer by default -AlphaTargetMachine::AsmPrinterCtorFn AlphaTargetMachine::AsmPrinterCtor = 0; - -// Force static initialization. -extern "C" void LLVMInitializeAlphaTarget() { } - -const TargetAsmInfo *AlphaTargetMachine::createTargetAsmInfo() const { - return new AlphaTargetAsmInfo(*this); -} - -unsigned AlphaTargetMachine::getModuleMatchQuality(const Module &M) { - // We strongly match "alpha*". - std::string TT = M.getTargetTriple(); - if (TT.size() >= 5 && TT[0] == 'a' && TT[1] == 'l' && TT[2] == 'p' && - TT[3] == 'h' && TT[4] == 'a') - return 20; - // If the target triple is something non-alpha, we don't match. - if (!TT.empty()) return 0; - - if (M.getEndianness() == Module::LittleEndian && - M.getPointerSize() == Module::Pointer64) - return 10; // Weak match - else if (M.getEndianness() != Module::AnyEndianness || - M.getPointerSize() != Module::AnyPointerSize) - return 0; // Match for some other target - - return getJITMatchQuality()/2; -} - -unsigned AlphaTargetMachine::getJITMatchQuality() { -#ifdef __alpha - return 10; -#else - return 0; -#endif +extern "C" void LLVMInitializeAlphaTarget() { + // Register the target. + RegisterTargetMachine<AlphaTargetMachine> X(TheAlphaTarget); + RegisterAsmInfo<AlphaMCAsmInfo> Y(TheAlphaTarget); } -AlphaTargetMachine::AlphaTargetMachine(const Module &M, const std::string &FS) - : DataLayout("e-f128:128:128"), +AlphaTargetMachine::AlphaTargetMachine(const Target &T, const std::string &TT, + const std::string &FS) + : LLVMTargetMachine(T, TT), + DataLayout("e-f128:128:128"), FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0), JITInfo(*this), - Subtarget(M, FS), + Subtarget(TT, FS), TLInfo(*this) { setRelocationModel(Reloc::PIC_); } @@ -84,51 +50,40 @@ bool AlphaTargetMachine::addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel) { // Must run branch selection immediately preceding the asm printer PM.add(createAlphaBranchSelectionPass()); - return false; -} -bool AlphaTargetMachine::addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, - raw_ostream &Out) { PM.add(createAlphaLLRPPass(*this)); - // Output assembly language. - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(Out, *this, Verbose)); return false; } bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, MachineCodeEmitter &MCE) { + MachineCodeEmitter &MCE) { PM.add(createAlphaCodeEmitterPass(*this, MCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, true)); - } return false; } bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE) { + JITCodeEmitter &JCE) { PM.add(createAlphaJITCodeEmitterPass(*this, JCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, true)); - } + return false; +} +bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + ObjectCodeEmitter &OCE) { + PM.add(createAlphaObjectCodeEmitterPass(*this, OCE)); return false; } bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, MachineCodeEmitter &MCE) { - return addCodeEmitter(PM, OptLevel, DumpAsm, MCE); + return addCodeEmitter(PM, OptLevel, MCE); } bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE) { - return addCodeEmitter(PM, OptLevel, DumpAsm, JCE); + return addCodeEmitter(PM, OptLevel, JCE); +} +bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + ObjectCodeEmitter &OCE) { + return addCodeEmitter(PM, OptLevel, OCE); } diff --git a/lib/Target/Alpha/AlphaTargetMachine.h b/lib/Target/Alpha/AlphaTargetMachine.h index 26684c7..f03e938 100644 --- a/lib/Target/Alpha/AlphaTargetMachine.h +++ b/lib/Target/Alpha/AlphaTargetMachine.h @@ -34,18 +34,9 @@ class AlphaTargetMachine : public LLVMTargetMachine { AlphaSubtarget Subtarget; AlphaTargetLowering TLInfo; -protected: - virtual const TargetAsmInfo *createTargetAsmInfo() const; - - // To avoid having target depend on the asmprinter stuff libraries, asmprinter - // set this functions to ctor pointer at startup time if they are linked in. - typedef FunctionPass *(*AsmPrinterCtorFn)(raw_ostream &o, - TargetMachine &tm, - bool verbose); - static AsmPrinterCtorFn AsmPrinterCtor; - public: - AlphaTargetMachine(const Module &M, const std::string &FS); + AlphaTargetMachine(const Target &T, const std::string &TT, + const std::string &FS); virtual const AlphaInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } @@ -61,31 +52,24 @@ public: return &JITInfo; } - static unsigned getJITMatchQuality(); - static unsigned getModuleMatchQuality(const Module &M); - // Pass Pipeline Configuration virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel); virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel); - virtual bool addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, raw_ostream &Out); virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, MachineCodeEmitter &MCE); + MachineCodeEmitter &MCE); + virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, + JITCodeEmitter &JCE); virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE); + ObjectCodeEmitter &JCE); virtual bool addSimpleCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, MachineCodeEmitter &MCE); virtual bool addSimpleCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE); - - static void registerAsmPrinter(AsmPrinterCtorFn F) { - AsmPrinterCtor = F; - } + virtual bool addSimpleCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + ObjectCodeEmitter &OCE); }; } // end namespace llvm diff --git a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp index 982ef5e..d8e8b79 100644 --- a/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp +++ b/lib/Target/Alpha/AsmPrinter/AlphaAsmPrinter.cpp @@ -17,16 +17,20 @@ #include "AlphaInstrInfo.h" #include "AlphaTargetMachine.h" #include "llvm/Module.h" -#include "llvm/MDNode.h" #include "llvm/Type.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mangler.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/ADT/Statistic.h" using namespace llvm; @@ -37,21 +41,22 @@ namespace { /// Unique incrementer for label values for referencing Global values. /// - explicit AlphaAsmPrinter(raw_ostream &o, TargetMachine &tm, - const TargetAsmInfo *T, bool V) + explicit AlphaAsmPrinter(formatted_raw_ostream &o, TargetMachine &tm, + const MCAsmInfo *T, bool V) : AsmPrinter(o, tm, T, V) {} virtual const char *getPassName() const { return "Alpha Assembly Printer"; } - bool printInstruction(const MachineInstr *MI); + void printInstruction(const MachineInstr *MI); + static const char *getRegisterName(unsigned RegNo); + void printOp(const MachineOperand &MO, bool IsCallOp = false); void printOperand(const MachineInstr *MI, int opNum); - void printBaseOffsetPair (const MachineInstr *MI, int i, bool brackets=true); - void printModuleLevelGV(const GlobalVariable* GVar); + void printBaseOffsetPair(const MachineInstr *MI, int i, bool brackets=true); + void PrintGlobalVariable(const GlobalVariable *GVar); bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); + void EmitStartOfAsmFile(Module &M); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); @@ -62,17 +67,6 @@ namespace { }; } // end of anonymous namespace -/// createAlphaCodePrinterPass - Returns a pass that prints the Alpha -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *llvm::createAlphaCodePrinterPass(raw_ostream &o, - TargetMachine &tm, - bool verbose) { - return new AlphaAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose); -} - #include "AlphaGenAsmWriter.inc" void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum) @@ -81,7 +75,7 @@ void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum) if (MO.getType() == MachineOperand::MO_Register) { assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && "Not physreg??"); - O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; + O << getRegisterName(MO.getReg()); } else if (MO.isImm()) { O << MO.getImm(); assert(MO.getImm() < (1 << 30)); @@ -92,24 +86,21 @@ void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum) void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { - const TargetRegisterInfo &RI = *TM.getRegisterInfo(); - switch (MO.getType()) { case MachineOperand::MO_Register: - O << RI.get(MO.getReg()).AsmName; + O << getRegisterName(MO.getReg()); return; case MachineOperand::MO_Immediate: - cerr << "printOp() does not handle immediate values\n"; - abort(); + llvm_unreachable("printOp() does not handle immediate values"); return; case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); + GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI); return; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" + O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); return; @@ -117,14 +108,12 @@ void AlphaAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { O << MO.getSymbolName(); return; - case MachineOperand::MO_GlobalAddress: { - GlobalValue *GV = MO.getGlobal(); - O << Mang->getValueName(GV); + case MachineOperand::MO_GlobalAddress: + O << Mang->getMangledName(MO.getGlobal()); return; - } case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); return; @@ -151,13 +140,14 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Print out labels for the function. const Function *F = MF.getFunction(); - SwitchToSection(TAI->SectionForGlobal(F)); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); EmitAlignment(MF.getAlignment(), F); switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); + default: llvm_unreachable("Unknown linkage type!"); case Function::InternalLinkage: // Symbols default to internal. case Function::PrivateLinkage: + case Function::LinkerPrivateLinkage: break; case Function::ExternalLinkage: O << "\t.globl " << CurrentFnName << "\n"; @@ -166,7 +156,7 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) { case Function::WeakODRLinkage: case Function::LinkOnceAnyLinkage: case Function::LinkOnceODRLinkage: - O << TAI->getWeakRefDirective() << CurrentFnName << "\n"; + O << MAI->getWeakRefDirective() << CurrentFnName << "\n"; break; } @@ -180,17 +170,19 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) { for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { if (I != MF.begin()) { - printBasicBlockLabel(I, true, true); - O << '\n'; + EmitBasicBlockStart(I); } for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. ++EmittedInsts; - if (!printInstruction(II)) { - assert(0 && "Unhandled instruction in asm writer!"); - abort(); - } + processDebugLoc(II, true); + printInstruction(II); + + if (VerboseAsm && !II->getDebugLoc().isUnknown()) + EmitComments(*II); + O << '\n'; + processDebugLoc(II, false); } } @@ -200,17 +192,15 @@ bool AlphaAsmPrinter::runOnMachineFunction(MachineFunction &MF) { return false; } -bool AlphaAsmPrinter::doInitialization(Module &M) -{ - if(TM.getSubtarget<AlphaSubtarget>().hasCT()) +void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) { + if (TM.getSubtarget<AlphaSubtarget>().hasCT()) O << "\t.arch ev6\n"; //This might need to be ev67, so leave this test here else O << "\t.arch ev6\n"; O << "\t.set noat\n"; - return AsmPrinter::doInitialization(M); } -void AlphaAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { +void AlphaAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) { const TargetData *TD = TM.getTargetData(); if (!GVar->hasInitializer()) return; // External global require no code @@ -219,15 +209,14 @@ void AlphaAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { if (EmitSpecialLLVMGlobal(GVar)) return; - std::string name = Mang->getValueName(GVar); + std::string name = Mang->getMangledName(GVar); Constant *C = GVar->getInitializer(); - if (isa<MDNode>(C) || isa<MDString>(C)) - return; unsigned Size = TD->getTypeAllocSize(C->getType()); unsigned Align = TD->getPreferredAlignmentLog(GVar); // 0: Switch to section - SwitchToSection(TAI->SectionForGlobal(GVar)); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang, + TM)); // 1: Check visibility printVisibility(name, GVar->getVisibility()); @@ -239,23 +228,22 @@ void AlphaAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: case GlobalValue::CommonLinkage: - O << TAI->getWeakRefDirective() << name << '\n'; + O << MAI->getWeakRefDirective() << name << '\n'; break; case GlobalValue::AppendingLinkage: case GlobalValue::ExternalLinkage: - O << TAI->getGlobalDirective() << name << "\n"; + O << MAI->getGlobalDirective() << name << "\n"; break; case GlobalValue::InternalLinkage: case GlobalValue::PrivateLinkage: + case GlobalValue::LinkerPrivateLinkage: break; default: - assert(0 && "Unknown linkage type!"); - cerr << "Unknown linkage type!\n"; - abort(); + llvm_unreachable("Unknown linkage type!"); } // 3: Type, Size, Align - if (TAI->hasDotTypeDotSizeDirective()) { + if (MAI->hasDotTypeDotSizeDirective()) { O << "\t.type\t" << name << ", @object\n"; O << "\t.size\t" << name << ", " << Size << "\n"; } @@ -268,14 +256,6 @@ void AlphaAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { O << '\n'; } -bool AlphaAsmPrinter::doFinalization(Module &M) { - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - printModuleLevelGV(I); - - return AsmPrinter::doFinalization(M); -} - /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, @@ -298,12 +278,6 @@ bool AlphaAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, } // Force static initialization. -extern "C" void LLVMInitializeAlphaAsmPrinter() { } - -namespace { - static struct Register { - Register() { - AlphaTargetMachine::registerAsmPrinter(createAlphaCodePrinterPass); - } - } Registrator; +extern "C" void LLVMInitializeAlphaAsmPrinter() { + RegisterAsmPrinter<AlphaAsmPrinter> X(TheAlphaTarget); } diff --git a/lib/Target/Alpha/AsmPrinter/Makefile b/lib/Target/Alpha/AsmPrinter/Makefile index c5b3e94..3c64a3c 100644 --- a/lib/Target/Alpha/AsmPrinter/Makefile +++ b/lib/Target/Alpha/AsmPrinter/Makefile @@ -1,4 +1,4 @@ -##===- lib/Target/Alpha/Makefile ---------------------------*- Makefile -*-===## +##===- lib/Target/Alpha/AsmPrinter/Makefile ----------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # diff --git a/lib/Target/Alpha/CMakeLists.txt b/lib/Target/Alpha/CMakeLists.txt index 2a382d5..b4f41ae 100644 --- a/lib/Target/Alpha/CMakeLists.txt +++ b/lib/Target/Alpha/CMakeLists.txt @@ -8,6 +8,7 @@ tablegen(AlphaGenInstrInfo.inc -gen-instr-desc) tablegen(AlphaGenCodeEmitter.inc -gen-emitter) tablegen(AlphaGenAsmWriter.inc -gen-asm-writer) tablegen(AlphaGenDAGISel.inc -gen-dag-isel) +tablegen(AlphaGenCallingConv.inc -gen-callingconv) tablegen(AlphaGenSubtarget.inc -gen-subtarget) add_llvm_target(AlphaCodeGen @@ -18,9 +19,9 @@ add_llvm_target(AlphaCodeGen AlphaISelLowering.cpp AlphaJITInfo.cpp AlphaLLRP.cpp + AlphaMCAsmInfo.cpp AlphaRegisterInfo.cpp AlphaSubtarget.cpp - AlphaTargetAsmInfo.cpp AlphaTargetMachine.cpp ) diff --git a/lib/Target/Alpha/Makefile b/lib/Target/Alpha/Makefile index d6c82c7..d2d7109 100644 --- a/lib/Target/Alpha/Makefile +++ b/lib/Target/Alpha/Makefile @@ -15,8 +15,8 @@ BUILT_SOURCES = AlphaGenRegisterInfo.h.inc AlphaGenRegisterNames.inc \ AlphaGenRegisterInfo.inc AlphaGenInstrNames.inc \ AlphaGenInstrInfo.inc AlphaGenCodeEmitter.inc \ AlphaGenAsmWriter.inc AlphaGenDAGISel.inc \ - AlphaGenSubtarget.inc + AlphaGenCallingConv.inc AlphaGenSubtarget.inc -DIRS = AsmPrinter +DIRS = AsmPrinter TargetInfo include $(LEVEL)/Makefile.common diff --git a/lib/Target/Alpha/TargetInfo/AlphaTargetInfo.cpp b/lib/Target/Alpha/TargetInfo/AlphaTargetInfo.cpp new file mode 100644 index 0000000..f7099b9 --- /dev/null +++ b/lib/Target/Alpha/TargetInfo/AlphaTargetInfo.cpp @@ -0,0 +1,20 @@ +//===-- AlphaTargetInfo.cpp - Alpha Target Implementation -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Alpha.h" +#include "llvm/Module.h" +#include "llvm/Target/TargetRegistry.h" +using namespace llvm; + +llvm::Target llvm::TheAlphaTarget; + +extern "C" void LLVMInitializeAlphaTargetInfo() { + RegisterTarget<Triple::alpha, /*HasJIT=*/true> + X(TheAlphaTarget, "alpha", "Alpha [experimental]"); +} diff --git a/lib/Target/Alpha/TargetInfo/CMakeLists.txt b/lib/Target/Alpha/TargetInfo/CMakeLists.txt new file mode 100644 index 0000000..2a7291b --- /dev/null +++ b/lib/Target/Alpha/TargetInfo/CMakeLists.txt @@ -0,0 +1,7 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMAlphaInfo + AlphaTargetInfo.cpp + ) + +add_dependencies(LLVMAlphaInfo AlphaCodeGenTable_gen) diff --git a/lib/Target/Alpha/TargetInfo/Makefile b/lib/Target/Alpha/TargetInfo/Makefile new file mode 100644 index 0000000..de01d7f --- /dev/null +++ b/lib/Target/Alpha/TargetInfo/Makefile @@ -0,0 +1,15 @@ +##===- lib/Target/Alpha/TargetInfo/Makefile ----------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMAlphaInfo + +# Hack: we need to include 'main' target directory to grab private headers +CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common |