diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2007-11-12 19:49:57 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2007-11-12 19:49:57 +0000 |
commit | ea37730b1e060a50a6ac463c5fea7bf85de7015e (patch) | |
tree | 906d4cd1910f2512f4326665afdb3fabd9491ff5 /lib/Target/Mips | |
parent | 300766ddcd3dacbb8c219b9a11e229d55298c7bd (diff) | |
download | external_llvm-ea37730b1e060a50a6ac463c5fea7bf85de7015e.zip external_llvm-ea37730b1e060a50a6ac463c5fea7bf85de7015e.tar.gz external_llvm-ea37730b1e060a50a6ac463c5fea7bf85de7015e.tar.bz2 |
Added JumpTable support
Fixed some AsmPrinter issues
Added GLOBAL_OFFSET_TABLE Node handle.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44024 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips')
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.cpp | 82 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 28 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 35 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 1 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 8 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetAsmInfo.cpp | 22 |
6 files changed, 142 insertions, 34 deletions
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 2dc9c2f..4a934b5 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -29,6 +29,7 @@ #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Support/Mangler.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/SetVector.h" @@ -237,9 +238,8 @@ emitFunctionStart(MachineFunction &MF) const Function *F = MF.getFunction(); SwitchToTextSection(getSectionForFunction(*F).c_str(), F); - // On Mips GAS, if .align #n is present, #n means the number of bits - // to be cleared. So, if we want 4 byte alignment, we must have .align 2 - EmitAlignment(1, F); + // 2 bits aligned + EmitAlignment(2, F); O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.ent\t" << CurrentFnName << "\n"; @@ -280,6 +280,9 @@ runOnMachineFunction(MachineFunction &MF) // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); + // Print out jump tables referenced by the function + EmitJumpTableInfo(MF.getJumpTableInfo(), MF); + O << "\n\n"; // What's my mangled name? @@ -388,6 +391,11 @@ printOperand(const MachineInstr *MI, int opNum) O << MO.getSymbolName(); break; + case MachineOperand::MO_JumpTableIndex: + O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + << '_' << MO.getJumpTableIndex(); + break; + // FIXME: Verify correct case MachineOperand::MO_ConstantPoolIndex: O << TAI->getPrivateGlobalPrefix() << "CPI" @@ -450,19 +458,30 @@ doFinalization(Module &M) std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); unsigned Size = TD->getABITypeSize(C->getType()); - unsigned Align = TD->getPrefTypeAlignment(C->getType()); + unsigned Align = TD->getPreferredAlignmentLog(I); + // Is this correct ? if (C->isNullValue() && (I->hasLinkOnceLinkage() || - I->hasInternalLinkage() || I->hasWeakLinkage() - /* FIXME: Verify correct */)) { - - SwitchToDataSection(".data", I); - if (I->hasInternalLinkage()) - O << "\t.local " << name << "\n"; - - O << "\t.comm " << name << "," - << TD->getABITypeSize(C->getType()) - << "," << Align << "\n"; + I->hasInternalLinkage() || I->hasWeakLinkage())) + { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + + if (!NoZerosInBSS && TAI->getBSSSection()) + SwitchToDataSection(TAI->getBSSSection(), I); + else + SwitchToDataSection(TAI->getDataSection(), I); + + if (I->hasInternalLinkage()) { + if (TAI->getLCOMMDirective()) + O << TAI->getLCOMMDirective() << name << "," << Size; + else + O << "\t.local\t" << name << "\n"; + } else { + O << TAI->getCOMMDirective() << name << "," << Size; + // The .comm alignment in bytes. + if (TAI->getCOMMDirectiveTakesAlignment()) + O << "," << (1 << Align); + } } else { @@ -483,24 +502,37 @@ doFinalization(Module &M) // something. For now, just emit them as external. case GlobalValue::ExternalLinkage: // If external or appending, declare as a global symbol - O << "\t.globl " << name << "\n"; + O << TAI->getGlobalDirective() << name << "\n"; + // Fall Through case GlobalValue::InternalLinkage: - if (C->isNullValue()) - SwitchToDataSection(".bss", I); - else - SwitchToDataSection(".data", I); + // FIXME: special handling for ".ctors" & ".dtors" sections + if (I->hasSection() && (I->getSection() == ".ctors" || + I->getSection() == ".dtors")) { + std::string SectionName = ".section " + I->getSection(); + SectionName += ",\"aw\",%progbits"; + SwitchToDataSection(SectionName.c_str()); + } else { + if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection()) + SwitchToDataSection(TAI->getBSSSection(), I); + else if (!I->isConstant()) + SwitchToDataSection(TAI->getDataSection(), I); + else { + // Read-only data. + if (TAI->getReadOnlySection()) + SwitchToDataSection(TAI->getReadOnlySection(), I); + else + SwitchToDataSection(TAI->getDataSection(), I); + } + } break; case GlobalValue::GhostLinkage: - cerr << "Should not have any" - << "unmaterialized functions!\n"; + cerr << "Should not have any unmaterialized functions!\n"; abort(); case GlobalValue::DLLImportLinkage: - cerr << "DLLImport linkage is" - << "not supported by this target!\n"; + cerr << "DLLImport linkage is not supported by this target!\n"; abort(); case GlobalValue::DLLExportLinkage: - cerr << "DLLExport linkage is" - << "not supported by this target!\n"; + cerr << "DLLExport linkage is not supported by this target!\n"; abort(); default: assert(0 && "Unknown linkage type!"); diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 6165d58..a2c1a0b 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -78,6 +78,7 @@ private: // Include the pieces autogenerated from the target description. #include "MipsGenDAGISel.inc" + SDOperand getGlobalBaseReg(); SDNode *Select(SDOperand N); // Complex Pattern. @@ -124,6 +125,23 @@ InstructionSelectBasicBlock(SelectionDAG &SD) ScheduleAndEmitDAG(SD); } +/// getGlobalBaseReg - Output the instructions required to put the +/// GOT address into a register. +SDOperand MipsDAGToDAGISel::getGlobalBaseReg() +{ + MachineFunction* MF = BB->getParent(); + unsigned GP = 0; + for(MachineFunction::livein_iterator ii = MF->livein_begin(), + ee = MF->livein_end(); ii != ee; ++ii) + if (ii->first == Mips::GP) { + GP = ii->second; + break; + } + assert(GP && "GOT PTR not in liveins"); + return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), + GP, MVT::i32); +} + /// ComplexPattern used on MipsInstrInfo /// Used on Mips Load/Store instructions bool MipsDAGToDAGISel:: @@ -138,7 +156,8 @@ SelectAddr(SDOperand Op, SDOperand Addr, SDOperand &Offset, SDOperand &Base) // on PIC code Load GA if (TM.getRelocationModel() == Reloc::PIC_) { - if (Addr.getOpcode() == ISD::TargetGlobalAddress) { + if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || + (Addr.getOpcode() == ISD::TargetJumpTable)){ Base = CurDAG->getRegister(Mips::GP, MVT::i32); Offset = Addr; return true; @@ -253,6 +272,13 @@ Select(SDOperand N) return CurDAG->getTargetNode(Mips::MFHI, MVT::i32, MFInFlag); } + // Get target GOT address. + case ISD::GLOBAL_OFFSET_TABLE: { + SDOperand Result = getGlobalBaseReg(); + ReplaceUses(N, Result); + return NULL; + } + /// Handle direct and indirect calls when using PIC. On PIC, when /// GOT is smaller than about 64k (small code) the GA target is /// loaded with only one instruction. Otherwise GA's target must diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 440d3e3..d12d30b 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -55,6 +55,9 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM) setSetCCResultType(MVT::i32); setSetCCResultContents(ZeroOrOneSetCCResult); + // JumpTable targets must use GOT when using PIC_ + setUsesGlobalOffsetTable(true); + // Set up the register classes addRegisterClass(MVT::i32, Mips::CPURegsRegisterClass); @@ -62,6 +65,7 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM) setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); setOperationAction(ISD::RET, MVT::Other, Custom); + setOperationAction(ISD::JumpTable, MVT::i32, Custom); // Load extented operations for i1 types must be promoted setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote); @@ -119,6 +123,7 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) case ISD::RET: return LowerRET(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); + case ISD::JumpTable: return LowerJumpTable(Op, DAG); } return SDOperand(); } @@ -175,6 +180,29 @@ LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) assert(0 && "TLS not implemented for MIPS."); } +SDOperand MipsTargetLowering:: +LowerJumpTable(SDOperand Op, SelectionDAG &DAG) +{ + SDOperand ResNode; + SDOperand HiPart; + + MVT::ValueType PtrVT = Op.getValueType(); + JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); + SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); + + if (getTargetMachine().getRelocationModel() != Reloc::PIC_) { + const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::i32); + SDOperand Ops[] = { JTI }; + HiPart = DAG.getNode(MipsISD::Hi, VTs, 1, Ops, 1); + } else // Emit Load from Global Pointer + HiPart = DAG.getLoad(MVT::i32, DAG.getEntryNode(), JTI, NULL, 0); + + SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, JTI); + ResNode = DAG.getNode(ISD::ADD, MVT::i32, HiPart, Lo); + + return ResNode; +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation // @@ -346,13 +374,11 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC) // location is used on function prologue to save GP and also after all // emited CALL's to restore GP. if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { - // Function can have an arbitrary number of calls, so // hold the LastStackLoc with the biggest offset. int FI; MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); if (LastStackLoc >= MipsFI->getGPStackOffset()) { - LastStackLoc = (!LastStackLoc) ? (16) : (LastStackLoc+4); // Create the frame index only once. SPOffset here can be anything // (this will be fixed on processFunctionBeforeFrameFinalized) @@ -363,7 +389,6 @@ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC) MipsFI->setGPStackOffset(LastStackLoc); } - // Reload GP value. FI = MipsFI->getGPFI(); SDOperand FIN = DAG.getFrameIndex(FI,getPointerTy()); @@ -455,6 +480,10 @@ LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF); + // GP holds the GOT address on PIC calls. + if (getTargetMachine().getRelocationModel() == Reloc::PIC_) + AddLiveIn(MF, Mips::GP, Mips::CPURegsRegisterClass); + // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 37c39f3..fba671a 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -76,6 +76,7 @@ namespace llvm { SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG); SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG); SDOperand LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG); // Inline asm support ConstraintType getConstraintType(const std::string &Constraint) const; diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index c6fcaed..3d7504b 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -274,13 +274,13 @@ class JumpFR<bits<6> op, bits<6> func, string instr_asm>: (outs), (ins CPURegs:$target), !strconcat(instr_asm, " $target"), - [], IIBranch>; + [(brind CPURegs:$target)], IIBranch>; // Jump and Link (Call) let isCall=1, hasDelaySlot=1, // All calls clobber the non-callee saved registers... Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, - T3, T4, T5, T6, T7, T8, T9, K0, K1] in { + T3, T4, T5, T6, T7, T8, T9, K0, K1], Uses = [GP] in { class JumpLink<bits<6> op, string instr_asm>: FJ< op, (outs), @@ -518,6 +518,10 @@ def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>; def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>; def : Pat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)), (ADDiu CPURegs:$hi, tglobaladdr:$lo)>; +def : Pat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>; +def : Pat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>; +def : Pat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)), + (ADDiu CPURegs:$hi, tjumptable:$lo)>; // Mips does not have not, so we increase the operation def : Pat<(not CPURegs:$in), diff --git a/lib/Target/Mips/MipsTargetAsmInfo.cpp b/lib/Target/Mips/MipsTargetAsmInfo.cpp index 08166f6..2d3eff1 100644 --- a/lib/Target/Mips/MipsTargetAsmInfo.cpp +++ b/lib/Target/Mips/MipsTargetAsmInfo.cpp @@ -12,11 +12,27 @@ //===----------------------------------------------------------------------===// #include "MipsTargetAsmInfo.h" +#include "MipsTargetMachine.h" using namespace llvm; MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM) { - Data16bitsDirective = "\t.half\t"; - Data32bitsDirective = "\t.word\t"; - CommentString = "#"; + AlignmentIsInBytes = false; + Data16bitsDirective = "\t.half\t"; + Data32bitsDirective = "\t.word\t"; + PrivateGlobalPrefix = "$"; + JumpTableDataSection = "\t.rdata"; + CommentString = "#"; + ReadOnlySection = "\t.rdata"; + ZeroDirective = "\t.space\t"; + BSSSection = "\t.section\t.bss"; + GlobalDirective = "\t.globl\t"; + LCOMMDirective = "\t.lcomm\t"; + + if (TM.getRelocationModel() == Reloc::Static) + JumpTableDirective = "\t.word\t"; + else + JumpTableDirective = "\t.gpword\t"; + + COMMDirectiveTakesAlignment = true; } |