diff options
-rw-r--r-- | lib/Target/Mips/Mips16InstrFormats.td | 4 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16InstrInfo.td | 233 | ||||
-rw-r--r-- | lib/Target/Mips/MipsFrameLowering.cpp | 21 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 34 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 5 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.cpp | 18 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.h | 5 | ||||
-rw-r--r-- | lib/Target/Mips/MipsMachineFunction.cpp | 11 | ||||
-rw-r--r-- | test/CodeGen/Mips/helloworld_call.ll | 17 | ||||
-rw-r--r-- | test/CodeGen/Mips/helloworld_pe.ll | 18 | ||||
-rw-r--r-- | test/CodeGen/Mips/helloworld_sr.ll | 16 |
11 files changed, 338 insertions, 44 deletions
diff --git a/lib/Target/Mips/Mips16InstrFormats.td b/lib/Target/Mips/Mips16InstrFormats.td index 6babee918d..61602b62fb 100644 --- a/lib/Target/Mips/Mips16InstrFormats.td +++ b/lib/Target/Mips/Mips16InstrFormats.td @@ -529,14 +529,16 @@ class FEXT_RRI16<bits<5> _op, dag outs, dag ins, string asmstr, list<dag> pattern, InstrItinClass itin>: MipsInst16_EXTEND<outs, ins, asmstr, pattern, itin, FrmEXT_RRI16> { + bits<5> op; bits<16> imm16; bits<3> rx; bits<3> ry; + let op=_op; let Inst{26-21} = imm16{10-5}; let Inst{20-16} = imm16{15-11}; - let Inst{15-11} = _op; + let Inst{15-11} = op; let Inst{10-8} = rx; let Inst{7-5} = ry; let Inst{4-0} = imm16{4-0}; diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index 71801ca6f2..c85204278b 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -11,35 +11,209 @@ // //===----------------------------------------------------------------------===// +def uimm5 : Operand<i8> { + let DecoderMethod= "DecodeSimm16"; +} + +// +// RRR-type instruction format +// + +class FRRR16_ins<bits<2> _f, string asmstr, InstrItinClass itin> : + FRRR16<_f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry), + !strconcat(asmstr, "\t$rz, $rx, $ry"), [], itin>; + +// +// I8_MOV32R instruction format (used only by MOV32R instruction) +// +class FI8_MOV32R16_ins<string asmstr, InstrItinClass itin>: + FI8_MOV32R16<(outs CPURegs:$r32), (ins CPU16Regs:$rz), + !strconcat(asmstr, "\t$r32, $rz"), [], itin>; + +// +// EXT-RI instruction format +// + +class FEXT_RI16_ins_base<bits<5> _op, string asmstr, string asmstr2, + InstrItinClass itin>: + FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins simm16:$imm), + !strconcat(asmstr, asmstr2), [], itin>; + +class FEXT_RI16_ins<bits<5> _op, string asmstr, + InstrItinClass itin>: + FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $imm", itin>; + +class FEXT_RI16_PC_ins<bits<5> _op, string asmstr, InstrItinClass itin>: + FEXT_RI16_ins_base<_op, asmstr, "\t$rx, $$pc, $imm", itin>; + +// +// RR-type instruction format +// +let rx=0 in +class FRR16_JALRC_RA_only_ins<bits<1> nd_, bits<1> l_, + string asmstr, InstrItinClass itin>: + FRR16_JALRC<nd_, l_, 1, (outs), (ins), !strconcat(asmstr, "\t $$ra"), + [], itin> ; + +// +// EXT-RRI instruction format +// + +class FEXT_RRI16_mem_ins<bits<5> op, string asmstr, Operand MemOpnd, + InstrItinClass itin>: + FEXT_RRI16<op, (outs CPU16Regs:$ry), (ins MemOpnd:$addr), + !strconcat(asmstr, "\t$ry, $addr"), [], itin>; + +// +// EXT-SHIFT instruction format +// +class FEXT_SHIFT16_ins<bits<2> _f, string asmstr, InstrItinClass itin>: + FEXT_SHIFT16<_f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry, uimm5:$sa), + !strconcat(asmstr, "\t$rx, $ry, $sa"), [], itin>; + +// +// Address operand +def mem16 : Operand<i32> { + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops CPU16Regs, simm16); + let EncoderMethod = "getMemEncoding"; +} + +// +// Format: ADDIU rx, pc, immediate MIPS16e +// Purpose: Add Immediate Unsigned Word (3-Operand, PC-Relative, Extended) +// To add a constant to the program counter. +// +class AddiuRxPcImmX16_base : FEXT_RI16_PC_ins<0b00001, "addiu", IIAlu>; +def AddiuRxPcImmX16 : AddiuRxPcImmX16_base; +// +// Format: ADDU rz, rx, ry MIPS16e +// Purpose: Add Unsigned Word (3-Operand) +// To add 32-bit integers. +// + +class AdduRxRyRz16_base: FRRR16_ins<01, "addu", IIAlu>; +def AdduRxRyRz16: AdduRxRyRz16_base; + +// +// Format: JR ra MIPS16e +// Purpose: Jump Register Through Register ra +// To execute a branch to the instruction address in the return +// address register. +// + +def JrRa16: FRR16_JALRC_RA_only_ins<0, 0, "jr", IIAlu>; + +// +// Format: LI rx, immediate MIPS16e +// Purpose: Load Immediate (Extended) +// To load a constant into a GPR. +// +def LiRxImmX16: FEXT_RI16_ins<0b01101, "li", IIAlu>; + +// +// Format: LW ry, offset(rx) MIPS16e +// Purpose: Load Word (Extended) +// To load a word from memory as a signed value. +// +class LwRxRyOffMemX16_base: FEXT_RRI16_mem_ins<0b10011, "lw", mem16, IIAlu>; +def LwRxRyOffMemX16: LwRxRyOffMemX16_base; + +// +// Format: MOVE r32, rz MIPS16e +// Purpose: Move +// To move the contents of a GPR to a GPR. +// +def Mov32R16: FI8_MOV32R16_ins<"move", IIAlu>; +// +// Format: RESTORE {ra,}{s0/s1/s0-1,}{framesize} +// (All args are optional) MIPS16e +// Purpose: Restore Registers and Deallocate Stack Frame +// To deallocate a stack frame before exit from a subroutine, +// restoring return address and static registers, and adjusting +// stack +// + +// fixed form for restoring RA and the frame +// for direct object emitter, encoding needs to be adjusted for the +// frame size +// +let ra=1, s=0,s0=0,s1=0 in +def RestoreRaF16: + FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), + "restore \t$$ra, $frame_size", [], IILoad >; + +// +// Format: SAVE {ra,}{s0/s1/s0-1,}{framesize} (All arguments are optional) +// MIPS16e +// Purpose: Save Registers and Set Up Stack Frame +// To set up a stack frame on entry to a subroutine, +// saving return address and static registers, and adjusting stack +// +let ra=1, s=1,s0=0,s1=0 in +def SaveRaF16: + FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), + "save \t$$ra, $frame_size", [], IILoad >; + +// +// Format: SLL rx, ry, sa MIPS16e +// Purpose: Shift Word Left Logical (Extended) +// To execute a left-shift of a word by a fixed number of bits—0 to 31 bits. +// +def SllX16: FEXT_SHIFT16_ins<0b00, "sll", IIAlu>; + +// +// Format: SW ry, offset(rx) MIPS16e +// Purpose: Store Word (Extended) +// To store a word to memory. +// +class SwRxRyOffMemX16_base: FEXT_RRI16_mem_ins<0b11011, "sw", mem16, IIAlu>; +def SwRxRyOffMemX16: SwRxRyOffMemX16_base; + class Mips16Pat<dag pattern, dag result> : Pat<pattern, result> { let Predicates = [InMips16Mode]; } -// Mips16 pseudos -let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, - hasExtraSrcRegAllocReq = 1 in -def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>; +class ArithLogicR16Defs<SDNode OpNode, bit isComm = 0> { + dag OutOperandList = (outs CPU16Regs:$rz); + dag InOperandList = (ins CPU16Regs:$rx, CPU16Regs:$ry); + list<dag> Pattern = [(set CPU16Regs:$rz, + (OpNode CPU16Regs:$rx, CPU16Regs:$ry))]; +} -def LI16E : FEXT_RI16<0b01101, (outs CPU16Regs:$rx), - (ins uimm16:$amt), - !strconcat("li", "\t$rx, $amt"), - [(set CPU16Regs:$rx, immZExt16:$amt )],IILoad>; +multiclass ArithLogicR16_base { + def _add: AdduRxRyRz16_base, ArithLogicR16Defs<add, 1>; +} -let isReturn=1, isTerminator=1, hasDelaySlot=1, isCodeGenOnly=1, - isBarrier=1, hasCtrlDep=1, rx=0 in -def RET16 : FRR16_JALRC - <0,0,0, (outs), (ins CPURAReg:$target), "jr\t$target", [], IIBranch>; +defm ArithLogicR16_patt : ArithLogicR16_base; -// As stack alignment is always done with addiu, we need a 16-bit immediate -let Defs = [SP], Uses = [SP] in { -def ADJCALLSTACKDOWN16 : MipsPseudo16<(outs), (ins uimm16:$amt), - "!ADJCALLSTACKDOWN $amt", - [(callseq_start timm:$amt)]>; -def ADJCALLSTACKUP16 : MipsPseudo16<(outs), (ins uimm16:$amt1, uimm16:$amt2), - "!ADJCALLSTACKUP $amt1", - [(callseq_end timm:$amt1, timm:$amt2)]>; +class LoadM16Defs<PatFrag OpNode, Operand _MemOpnd, bit Pseudo=0> { + bit isPseudo = Pseudo; + Operand MemOpnd = _MemOpnd; + dag OutOperandList = (outs CPU16Regs:$ry); + dag InOperandList = (ins MemOpnd:$addr); + list<dag> Pattern = [(set CPU16Regs:$ry, (OpNode addr:$addr))]; +} + +multiclass LoadM16_base { + def _LwRxRyOffMemX16: LwRxRyOffMemX16_base, LoadM16Defs<load_a, mem16>; +} + +defm LoadM16: LoadM16_base; + +class StoreM16Defs<PatFrag OpNode, Operand _MemOpnd, bit Pseudo=0> { + bit isPseudo = Pseudo; + Operand MemOpnd = _MemOpnd; + dag OutOperandList = (outs ); + dag InOperandList = (ins CPU16Regs:$ry, MemOpnd:$addr); + list<dag> Pattern = [(OpNode CPU16Regs:$ry, addr:$addr)]; +} + +multiclass StoreM16_base { + def _SwRxRyOffMemX16: SwRxRyOffMemX16_base, StoreM16Defs<store_a, mem16>; } +defm StoreM16: StoreM16_base; // Jump and Link (Call) let isCall=1, hasDelaySlot=1 in @@ -47,6 +221,23 @@ def JumpLinkReg16: FRR16_JALRC<0, 0, 0, (outs), (ins CPU16Regs:$rs), "jalr \t$rs", [(MipsJmpLink CPU16Regs:$rs)], IIBranch>; +// Mips16 pseudos +let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, + hasExtraSrcRegAllocReq = 1 in +def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>; + +// As stack alignment is always done with addiu, we need a 16-bit immediate +// This is basically deprecated code but needs to be there for things +// to work. +let Defs = [SP], Uses = [SP] in { +def ADJCALLSTACKDOWN16 : MipsPseudo16<(outs), (ins uimm16:$amt), + ";", + [(callseq_start timm:$amt)]>; +def ADJCALLSTACKUP16 : MipsPseudo16<(outs), (ins uimm16:$amt1, uimm16:$amt2), + ";", + [(callseq_end timm:$amt1, timm:$amt2)]>; +} // Small immediates -def : Mips16Pat<(i32 immZExt16:$in), (LI16E immZExt16:$in)>; +def : Mips16Pat<(i32 immZExt16:$in), (LiRxImmX16 immZExt16:$in)>; +def : Mips16Pat<(MipsLo tglobaladdr:$in), (LiRxImmX16 tglobaladdr:$in)>; diff --git a/lib/Target/Mips/MipsFrameLowering.cpp b/lib/Target/Mips/MipsFrameLowering.cpp index cb55995404..6338f3c4ea 100644 --- a/lib/Target/Mips/MipsFrameLowering.cpp +++ b/lib/Target/Mips/MipsFrameLowering.cpp @@ -114,7 +114,7 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const { unsigned StackAlign = getStackAlignment(); uint64_t StackSize = RoundUpToAlignment(MFI->getStackSize(), StackAlign); - if (MipsFI->globalBaseRegSet()) + if (MipsFI->globalBaseRegSet()) StackSize += MFI->getObjectOffset(MipsFI->getGlobalRegFI()) + StackAlign; else StackSize += RoundUpToAlignment(MipsFI->getMaxCallFrameSize(), StackAlign); @@ -130,8 +130,13 @@ void MipsFrameLowering::emitPrologue(MachineFunction &MF) const { MachineLocation DstML, SrcML; // Adjust stack. - if (isInt<16>(-StackSize)) // addi sp, sp, (-stacksize) - BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(-StackSize); + if (isInt<16>(-StackSize)) {// addi sp, sp, (-stacksize) + if (STI.inMips16Mode()) + BuildMI(MBB, MBBI, dl, + TII.get(Mips::SaveRaF16)).addImm(StackSize); // cleanup + else + BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(-StackSize); + } else { // Expand immediate that doesn't fit in 16-bit. unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT; @@ -237,8 +242,14 @@ void MipsFrameLowering::emitEpilogue(MachineFunction &MF, return; // Adjust stack. - if (isInt<16>(StackSize)) // addi sp, sp, (-stacksize) - BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(StackSize); + if (isInt<16>(StackSize)) { // addi sp, sp, (-stacksize) + if (STI.inMips16Mode()) + // assumes stacksize multiple of 8 + BuildMI(MBB, MBBI, dl, + TII.get(Mips::RestoreRaF16)).addImm(StackSize); + else + BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(StackSize); + } else { // Expand immediate that doesn't fit in 16-bit. unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT; diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index c409e57021..ea33b74a75 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -128,18 +128,21 @@ void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) { const MipsInstrInfo *MII = TM.getInstrInfo(); const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); - unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg(); - int FI = 0; + unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg(); + int FI = 0; - if (!Subtarget.inMips16Mode()) - FI= MipsFI->initGlobalRegFI(); + FI= MipsFI->initGlobalRegFI(); const TargetRegisterClass *RC = Subtarget.isABI_N64() ? (const TargetRegisterClass*)&Mips::CPU64RegsRegClass : (const TargetRegisterClass*)&Mips::CPURegsRegClass; + if (Subtarget.inMips16Mode()) + RC=(const TargetRegisterClass*)&Mips::CPU16RegsRegClass; + V0 = RegInfo.createVirtualRegister(RC); V1 = RegInfo.createVirtualRegister(RC); + V2 = RegInfo.createVirtualRegister(RC); if (Subtarget.isABI_N64()) { MF.getRegInfo().addLiveIn(Mips::T9_64); @@ -160,6 +163,21 @@ void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) { return; } + if (Subtarget.inMips16Mode()) { + BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0) + .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI); + BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), + V1) + .addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); + BuildMI(MBB, I, DL, TII.get(Mips::SllX16), + V2 ).addReg(V0).addImm(16); + BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg) + .addReg(V1).addReg(V2); + + + return; + } + if (MF.getTarget().getRelocationModel() == Reloc::Static) { // Set global register to __gnu_local_gp. // @@ -169,8 +187,6 @@ void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) { .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI); BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0) .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO); - MII->storeRegToStackSlot(MBB, I, GlobalBaseReg, false, FI, RC, - TargetRegInfo); return; } @@ -194,8 +210,10 @@ void MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) { assert(Subtarget.isABI_O32()); - if (Subtarget.inMips16Mode()) - return; // no need to load GP. It can be calculated anywhere + + //if (Subtarget.inMips16Mode()) + // return; // no need to load GP. It can be calculated anywhere + // For O32 ABI, the following instruction sequence is emitted to initialize diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 6b80e3fe3e..7741f9f982 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -2645,6 +2645,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; SDValue InChain = CLI.Chain; SDValue Callee = CLI.Callee; + SDValue CalleeSave = CLI.Callee; bool &isTailCall = CLI.IsTailCall; CallingConv::ID CallConv = CLI.CallConv; bool isVarArg = CLI.IsVarArg; @@ -2901,7 +2902,7 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector<SDValue, 8> Ops; Ops.push_back(Chain); - Ops.push_back(Callee); + Ops.push_back(Subtarget->inMips16Mode()? CalleeSave: Callee); // Add argument registers to the end of the list so that they are // known live into the call. @@ -2909,6 +2910,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, Ops.push_back(DAG.getRegister(RegsToPass[i].first, RegsToPass[i].second.getValueType())); + if (Subtarget->inMips16Mode()) + Ops.push_back(Callee); // Add a register mask operand representing the call-preserved registers. const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); const uint32_t *Mask = TRI->getCallPreservedMask(CallConv); diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index 7d8488f0b8..458e4f7d1f 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -30,6 +30,7 @@ using namespace llvm; MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm) : MipsGenInstrInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP), TM(tm), IsN64(TM.getSubtarget<MipsSubtarget>().isABI_N64()), + InMips16Mode(TM.getSubtarget<MipsSubtarget>().inMips16Mode()), RI(*TM.getSubtargetImpl(), *this), UncondBrOpc(TM.getRelocationModel() == Reloc::PIC_ ? Mips::B : Mips::J) {} @@ -107,8 +108,13 @@ copyPhysReg(MachineBasicBlock &MBB, unsigned Opc = 0, ZeroReg = 0; if (Mips::CPURegsRegClass.contains(DestReg)) { // Copy to CPU Reg. - if (Mips::CPURegsRegClass.contains(SrcReg)) - Opc = Mips::ADDu, ZeroReg = Mips::ZERO; + if (Mips::CPURegsRegClass.contains(SrcReg)) { + if (InMips16Mode) + Opc=Mips::Mov32R16; + else { + Opc = Mips::ADDu, ZeroReg = Mips::ZERO; + } + } else if (Mips::CCRRegClass.contains(SrcReg)) Opc = Mips::CFC1; else if (Mips::FGR32RegClass.contains(SrcReg)) @@ -240,6 +246,12 @@ void MipsInstrInfo::ExpandRetRA(MachineBasicBlock &MBB, .addReg(Mips::RA); } +void MipsInstrInfo::ExpandRetRA16(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned Opc) const { + BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(Opc)); +} + void MipsInstrInfo::ExpandExtractElementF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { const TargetInstrInfo *TII = TM.getInstrInfo(); @@ -283,7 +295,7 @@ bool MipsInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { ExpandRetRA(MBB, MI, Mips::RET); break; case Mips::RetRA16: - ExpandRetRA(MBB, MI, Mips::RET16); + ExpandRetRA16(MBB, MI, Mips::JrRa16); break; case Mips::BuildPairF64: ExpandBuildPairF64(MBB, MI); diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index b4721a7b39..358f8173a0 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -27,7 +27,7 @@ namespace llvm { class MipsInstrInfo : public MipsGenInstrInfo { MipsTargetMachine &TM; - bool IsN64; + bool IsN64; bool InMips16Mode; const MipsRegisterInfo RI; unsigned UncondBrOpc; public: @@ -65,6 +65,9 @@ public: private: void ExpandRetRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned Opc) const; + void ExpandRetRA16(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + unsigned Opc) const; + void BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, DebugLoc DL, const SmallVectorImpl<MachineOperand>& Cond) const; void ExpandExtractElementF64(MachineBasicBlock &MBB, diff --git a/lib/Target/Mips/MipsMachineFunction.cpp b/lib/Target/Mips/MipsMachineFunction.cpp index e3746d4a42..362173eda3 100644 --- a/lib/Target/Mips/MipsMachineFunction.cpp +++ b/lib/Target/Mips/MipsMachineFunction.cpp @@ -33,10 +33,13 @@ unsigned MipsFunctionInfo::getGlobalBaseReg() { const MipsSubtarget &ST = MF.getTarget().getSubtarget<MipsSubtarget>(); - const TargetRegisterClass *RC = ST.isABI_N64() ? - (const TargetRegisterClass*)&Mips::CPU64RegsRegClass : - (const TargetRegisterClass*)&Mips::CPURegsRegClass; - + const TargetRegisterClass *RC; + if (ST.inMips16Mode()) + RC=(const TargetRegisterClass*)&Mips::CPU16RegsRegClass; + else + RC = ST.isABI_N64() ? + (const TargetRegisterClass*)&Mips::CPU64RegsRegClass : + (const TargetRegisterClass*)&Mips::CPURegsRegClass; return GlobalBaseReg = MF.getRegInfo().createVirtualRegister(RC); } diff --git a/test/CodeGen/Mips/helloworld_call.ll b/test/CodeGen/Mips/helloworld_call.ll new file mode 100644 index 0000000000..61c0446083 --- /dev/null +++ b/test/CodeGen/Mips/helloworld_call.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1 + +define i32 @main() nounwind { +entry: + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0)) + ret i32 0 + +; 16: .set mips16 # @main + +; 16: move $gp, ${{[0-9]+}} +; 16: jalr ${{[0-9]+}} +; 16: li $2, 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/helloworld_pe.ll b/test/CodeGen/Mips/helloworld_pe.ll new file mode 100644 index 0000000000..ba46662d52 --- /dev/null +++ b/test/CodeGen/Mips/helloworld_pe.ll @@ -0,0 +1,18 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1 + +define i32 @main() nounwind { +entry: + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0)) + ret i32 0 + +; 16: .set mips16 # @main + +; 16: li $[[T1:[0-9]+]], %hi(_gp_disp) +; 16: addiu $[[T2:[0-9]+]], $pc, %lo(_gp_disp) +; 16: sll $[[T3:[0-9]+]], $[[T1]], 16 +; 16: li $2, 0 +} + +declare i32 @printf(i8*, ...) diff --git a/test/CodeGen/Mips/helloworld_sr.ll b/test/CodeGen/Mips/helloworld_sr.ll new file mode 100644 index 0000000000..641ee274e0 --- /dev/null +++ b/test/CodeGen/Mips/helloworld_sr.ll @@ -0,0 +1,16 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 + +@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1 + +define i32 @main() nounwind { +entry: + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0)) + ret i32 0 + +; 16: .set mips16 # @main + +; 16: save $ra, [[FS:[0-9]+]] +; 16: restore $ra, [[FS]] +} + +declare i32 @printf(i8*, ...) |