Distinguish and choose 16 or 32 bit forms of save/restore for Mips16.
authorReed Kotler <rkotler@mips.com>
Wed, 11 Dec 2013 03:32:44 +0000 (03:32 +0000)
committerReed Kotler <rkotler@mips.com>
Wed, 11 Dec 2013 03:32:44 +0000 (03:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196999 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
lib/Target/Mips/Mips16InstrInfo.cpp
test/CodeGen/Mips/sr1.ll [new file with mode: 0644]

index c23fc6a6ed01da95ceb9843d971447cce60b232b..82deec1a1e58ab13cf40a097a4296e1f727beeac 100644 (file)
@@ -85,12 +85,20 @@ void MipsInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
     O << "\t.set\tmips32r2\n";
     break;
   case Mips::Save16:
+    O << "\tsave\t";
+    printSaveRestore(MI, O);
+    O << " # 16 bit inst\n";
+    return;
   case Mips::SaveX16:
     O << "\tsave\t";
     printSaveRestore(MI, O);
     O << "\n";
     return;
   case Mips::Restore16:
+    O << "\trestore\t";
+    printSaveRestore(MI, O);
+    O << " # 16 bit inst\n";
+    return;
   case Mips::RestoreX16:
     O << "\trestore\t";
     printSaveRestore(MI, O);
index 2df83e8850685a8d7e32462ab096f5dbb609cff9..7a3f9d2842cfbd48feb4b68d29e41b6ba1c3012a 100644 (file)
@@ -1,3 +1,4 @@
+
 //===-- Mips16InstrInfo.cpp - Mips16 Instruction Information --------------===//
 //
 //                     The LLVM Compiler Infrastructure
@@ -176,9 +177,10 @@ void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize,
   const BitVector Reserved = RI.getReservedRegs(*MBB.getParent());
   bool SaveS2 = Reserved[Mips::S2];
   MachineInstrBuilder MIB;
+  unsigned Opc = ((FrameSize <= 128) && !SaveS2)? Mips::Save16:Mips::SaveX16;
   if (isUInt<11>(FrameSize))
     MIB = BuildMI(
-            MBB, I, DL, get(Mips::SaveX16)).addReg(Mips::RA).
+            MBB, I, DL, get(Opc)).addReg(Mips::RA).
             addReg(Mips::S0).
             addReg(Mips::S1).addImm(FrameSize);
   else {
@@ -186,7 +188,7 @@ void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize,
                      // returns largest possible n bit unsigned integer
     int64_t Remainder = FrameSize - Base;
     MIB = BuildMI(
-            MBB, I, DL, get(Mips::SaveX16)).addReg(Mips::RA).
+            MBB, I, DL, get(Opc)).addReg(Mips::RA).
             addReg(Mips::S0).
             addReg(Mips::S1).addImm(Base);
     if (isInt<16>(-Remainder))
@@ -206,9 +208,11 @@ void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize,
   const BitVector Reserved = RI.getReservedRegs(*MBB.getParent());
   bool SaveS2 = Reserved[Mips::S2];
   MachineInstrBuilder MIB;
+  unsigned Opc = ((FrameSize <= 128) && !SaveS2)?
+    Mips::Restore16:Mips::RestoreX16;
   if (isUInt<11>(FrameSize))
     MIB = BuildMI(
-            MBB, I, DL, get(Mips::RestoreX16)).
+            MBB, I, DL, get(Opc)).
             addReg(Mips::RA, RegState::Define).
             addReg(Mips::S0, RegState::Define).
             addReg(Mips::S1, RegState::Define).
@@ -222,7 +226,7 @@ void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize,
     else
       adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1);
     MIB = BuildMI(
-            MBB, I, DL, get(Mips::RestoreX16)).
+            MBB, I, DL, get(Opc)).
             addReg(Mips::RA, RegState::Define).
             addReg(Mips::S0, RegState::Define).
             addReg(Mips::S1, RegState::Define).
diff --git a/test/CodeGen/Mips/sr1.ll b/test/CodeGen/Mips/sr1.ll
new file mode 100644 (file)
index 0000000..5303661
--- /dev/null
@@ -0,0 +1,64 @@
+; RUN: llc  -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -relocation-model=static  < %s | FileCheck %s -check-prefix=NEG
+
+; RUN: llc  -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -relocation-model=static  < %s | FileCheck %s 
+
+@f = common global float 0.000000e+00, align 4
+
+; Function Attrs: nounwind
+define void @foo1() #0 {
+entry:
+  %c = alloca [10 x i8], align 1
+  %arraydecay = getelementptr inbounds [10 x i8]* %c, i32 0, i32 0
+  call void @x(i8* %arraydecay)
+  %arraydecay1 = getelementptr inbounds [10 x i8]* %c, i32 0, i32 0
+  call void @x(i8* %arraydecay1)
+  ret void
+; CHECK:       .ent    foo1
+; CHECK:       save    $ra, $16, $17, [[FS:[0-9]+]] # 16 bit inst
+; CHECK:       restore $ra, $16, $17, [[FS]]
+; CHECK:       .end    foo1
+}
+
+declare void @x(i8*) #1
+
+; Function Attrs: nounwind
+define void @foo2() #0 {
+entry:
+  %c = alloca [150 x i8], align 1
+  %arraydecay = getelementptr inbounds [150 x i8]* %c, i32 0, i32 0
+  call void @x(i8* %arraydecay)
+  %arraydecay1 = getelementptr inbounds [150 x i8]* %c, i32 0, i32 0
+  call void @x(i8* %arraydecay1)
+  ret void
+; CHECK:       .ent    foo2
+; CHECK:       save    $ra, $16, $17, [[FS:[0-9]+]]
+; CHECK:       restore $ra, $16, $17, [[FS]]
+; CHECK:       .end    foo2
+; NEG:         .ent    foo2
+; NEG-NOT:     save    $ra, $16, $17, [[FS:[0-9]+]]  # 16 bit inst
+; NEG-NOT:     restore $ra, $16, $17, [[FS]]  # 16 bit inst
+; NEG:         .end    foo2
+}
+
+; Function Attrs: nounwind
+define void @foo3() #0 {
+entry:
+  %call = call float @xf()
+  store float %call, float* @f, align 4
+  ret void
+; CHECK:       .ent    foo3
+; CHECK:       save    $ra, $16, $17, [[FS:[0-9]+]], $18
+; CHECK:       restore $ra, $16, $17, [[FS]], $18
+; CHECK:       .end    foo3
+; NEG:         .ent    foo3
+; NEG-NOT:     save    $ra, $16, $17, [[FS:[0-9]+]], $18  # 16 bit inst
+; NEG-NOT:     restore $ra, $16, $17, [[FS]], $18  # 16 bit inst
+; NEG:         .end    foo3
+}
+
+declare float @xf() #1
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+