diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp index 78845898997..c23fc6a6ed0 100644 --- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp +++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp @@ -83,6 +83,19 @@ void MipsInstPrinter::printInst(const MCInst *MI, raw_ostream &O, case Mips::RDHWR64: O << "\t.set\tpush\n"; O << "\t.set\tmips32r2\n"; + break; + case Mips::Save16: + case Mips::SaveX16: + O << "\tsave\t"; + printSaveRestore(MI, O); + O << "\n"; + return; + case Mips::Restore16: + case Mips::RestoreX16: + O << "\trestore\t"; + printSaveRestore(MI, O); + O << "\n"; + return; } // Try to print any aliases first. @@ -286,3 +299,14 @@ bool MipsInstPrinter::printAlias(const MCInst &MI, raw_ostream &OS) { default: return false; } } + +void MipsInstPrinter::printSaveRestore(const MCInst *MI, raw_ostream &O) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + if (i != 0) O << ", "; + if (MI->getOperand(i).isReg()) + printRegName(O, MI->getOperand(i).getReg()); + else + printUnsignedImm(MI, i, O); + } +} + diff --git a/lib/Target/Mips/InstPrinter/MipsInstPrinter.h b/lib/Target/Mips/InstPrinter/MipsInstPrinter.h index f75ae249c3e..2b745f028e1 100644 --- a/lib/Target/Mips/InstPrinter/MipsInstPrinter.h +++ b/lib/Target/Mips/InstPrinter/MipsInstPrinter.h @@ -104,6 +104,7 @@ private: bool printAlias(const char *Str, const MCInst &MI, unsigned OpNo0, unsigned OpNo1, raw_ostream &OS); bool printAlias(const MCInst &MI, raw_ostream &OS); + void printSaveRestore(const MCInst *MI, raw_ostream &O); }; } // end namespace llvm diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp index c53db0e60a8..05658106bbe 100644 --- a/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/lib/Target/Mips/Mips16InstrInfo.cpp @@ -182,12 +182,17 @@ void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); if (!NeverUseSaveRestore) { if (isUInt<11>(FrameSize)) - BuildMI(MBB, I, DL, get(Mips::SaveRaF16)).addImm(FrameSize); + //BuildMI(MBB, I, DL, get(Mips::SaveRaF16)).addImm(FrameSize); + BuildMI(MBB, I, DL, get(Mips::SaveX16)).addReg(Mips::RA). + addReg(Mips::S0). + addReg(Mips::S1).addReg(Mips::S2).addImm(FrameSize); else { int Base = 2040; // should create template function like isUInt that // returns largest possible n bit unsigned integer int64_t Remainder = FrameSize - Base; - BuildMI(MBB, I, DL, get(Mips::SaveRaF16)). addImm(Base); + BuildMI(MBB, I, DL, get(Mips::SaveX16)).addReg(Mips::RA). + addReg(Mips::S0). + addReg(Mips::S1).addReg(Mips::S2).addImm(Base); if (isInt<16>(-Remainder)) BuildAddiuSpImm(MBB, I, -Remainder); else @@ -224,7 +229,9 @@ void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); if (!NeverUseSaveRestore) { if (isUInt<11>(FrameSize)) - BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)).addImm(FrameSize); + BuildMI(MBB, I, DL, get(Mips::RestoreX16)).addReg(Mips::RA). + addReg(Mips::S0). + addReg(Mips::S1).addReg(Mips::S2).addImm(FrameSize); else { int Base = 2040; // should create template function like isUInt that // returns largest possible n bit unsigned integer @@ -233,7 +240,9 @@ void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, BuildAddiuSpImm(MBB, I, Remainder); else adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); - BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)). addImm(Base); + BuildMI(MBB, I, DL, get(Mips::RestoreX16)).addReg(Mips::RA). + addReg(Mips::S0). + addReg(Mips::S1).addReg(Mips::S2).addImm(Base); } } else { diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index 365fe2b5e14..7879d4d73eb 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -957,26 +957,18 @@ def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>; // 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=1,s1=1 in -def RestoreRaF16: - FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), - "restore\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IILoad >, MayLoad { +def Restore16: + FI8_SVRS16<0b1, (outs), (ins variable_ops), + "", [], IILoad >, MayLoad { let isCodeGenOnly = 1; - let Defs = [S0, S1, S2, RA, SP]; + let Defs = [SP]; let Uses = [SP]; } -// Use Restore to increment SP since SP is not a Mip 16 register, this -// is an easy way to do that which does not require a register. -// -let ra=0, s=0,s0=0,s1=0 in -def RestoreIncSpF16: - FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), - "restore\t$frame_size", [], IILoad >, MayLoad { + +def RestoreX16: + FI8_SVRS16<0b1, (outs), (ins variable_ops), + "", [], IILoad >, MayLoad { let isCodeGenOnly = 1; let Defs = [SP]; let Uses = [SP]; @@ -989,23 +981,17 @@ def RestoreIncSpF16: // 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=1,s1=1 in -def SaveRaF16: - FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), - "save\t$$ra, $$s0, $$s1, $$s2, $frame_size", [], IIStore >, MayStore { +def Save16: + FI8_SVRS16<0b1, (outs), (ins variable_ops), + "", [], IIStore >, MayStore { let isCodeGenOnly = 1; - let Uses = [RA, SP, S0, S1, S2]; + let Uses = [SP]; let Defs = [SP]; } -// -// Use Save to decrement the SP by a constant since SP is not -// a Mips16 register. -// -let ra=0, s=0,s0=0,s1=0 in -def SaveDecSpF16: - FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), - "save\t$frame_size", [], IIStore >, MayStore { +def SaveX16: + FI8_SVRS16<0b1, (outs), (ins variable_ops), + "", [], IIStore >, MayStore { let isCodeGenOnly = 1; let Uses = [SP]; let Defs = [SP]; diff --git a/test/CodeGen/Mips/align16.ll b/test/CodeGen/Mips/align16.ll index 267cff54291..1b724e9fc86 100644 --- a/test/CodeGen/Mips/align16.ll +++ b/test/CodeGen/Mips/align16.ll @@ -25,7 +25,7 @@ entry: call void @p(i32* %arrayidx1) ret void } -; 16: save $ra, $s0, $s1, $s2, 2040 +; 16: save $ra, $16, $17, $18, 2040 ; 16: addiu $sp, -56 # 16 bit inst ; 16: addiu $sp, 56 # 16 bit inst -; 16: restore $ra, $s0, $s1, $s2, 2040 +; 16: restore $ra, $16, $17, $18, 2040 diff --git a/test/CodeGen/Mips/alloca16.ll b/test/CodeGen/Mips/alloca16.ll index 017665f00bd..a836d124889 100644 --- a/test/CodeGen/Mips/alloca16.ll +++ b/test/CodeGen/Mips/alloca16.ll @@ -20,7 +20,7 @@ entry: define void @test() nounwind { entry: ; 16: .frame $sp,24,$ra -; 16: save $ra, $s0, $s1, $s2, 24 +; 16: save $ra, $16, $17, $18, 24 ; 16: move $16, $sp ; 16: move ${{[0-9]+}}, $sp ; 16: subu $[[REGISTER:[0-9]+]], ${{[0-9]+}}, ${{[0-9]+}} diff --git a/test/CodeGen/Mips/ex2.ll b/test/CodeGen/Mips/ex2.ll index c5535e7661a..5b3463e5094 100644 --- a/test/CodeGen/Mips/ex2.ll +++ b/test/CodeGen/Mips/ex2.ll @@ -6,7 +6,7 @@ define i32 @main() { ; 16-LABEL: main: ; 16: .cfi_startproc -; 16: save $ra, $s0, $s1, $s2, 40 +; 16: save $ra, $16, $17, $18, 40 ; 16: .cfi_def_cfa_offset 40 ; 16: .cfi_offset 18, -8 ; 16: .cfi_offset 17, -12 diff --git a/test/CodeGen/Mips/helloworld.ll b/test/CodeGen/Mips/helloworld.ll index 058a041c16a..32bc45fba38 100644 --- a/test/CodeGen/Mips/helloworld.ll +++ b/test/CodeGen/Mips/helloworld.ll @@ -25,7 +25,7 @@ entry: ; SR32: .set noreorder ; SR32: .set nomacro ; SR32: .set noat -; SR: save $ra, $s0, $s1, $s2, [[FS:[0-9]+]] +; SR: save $ra, $16, $17, $18, [[FS:[0-9]+]] ; PE: .ent main ; PE: .align 2 ; PE-NEXT: li $[[T1:[0-9]+]], %hi(_gp_disp) @@ -37,7 +37,7 @@ entry: ; C2: move $25, ${{[0-9]+}} ; C1: move $gp, ${{[0-9]+}} ; C1: jalrc ${{[0-9]+}} -; SR: restore $ra, $s0, $s1, $s2, [[FS]] +; SR: restore $ra, $16, $17, $18, [[FS]] ; PE: li $2, 0 ; PE: jrc $ra