For Mips 16, add the optimization where the 16 bit form of addiu sp can be used
authorReed Kotler <rkotler@mips.com>
Wed, 13 Feb 2013 20:28:27 +0000 (20:28 +0000)
committerReed Kotler <rkotler@mips.com>
Wed, 13 Feb 2013 20:28:27 +0000 (20:28 +0000)
if the offset fits in 11 bits. This makes use of the fact that the abi
requires sp to be 8 byte aligned so the actual offset can fit in 8
bits. It will be shifted left and sign extended before being actually used.
The assembler or direct object emitter will shift right the 11 bit
signed field by 3 bits. We don't need to deal with that here.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175073 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/Mips16InstrInfo.cpp
lib/Target/Mips/Mips16InstrInfo.h
lib/Target/Mips/Mips16InstrInfo.td
test/CodeGen/Mips/align16.ll [new file with mode: 0644]

index 9f27ac35173ed1c009d3cc80150571ba3437f80e..5a91519fd841015d609114516ab8c906fb8a2b33 100644 (file)
@@ -184,7 +184,7 @@ void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize,
       int64_t Remainder = FrameSize - Base;
       BuildMI(MBB, I, DL, get(Mips::SaveRaF16)). addImm(Base);
       if (isInt<16>(-Remainder))
-        BuildMI(MBB, I, DL, get(Mips::AddiuSpImmX16)). addImm(-Remainder);
+        BuildAddiuSpImm(MBB, I, DL, -Remainder);
       else
         adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1);
     }
@@ -225,7 +225,7 @@ void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize,
                        // returns largest possible n bit unsigned integer
       int64_t Remainder = FrameSize - Base;
       if (isInt<16>(Remainder))
-        BuildMI(MBB, I, DL, get(Mips::AddiuSpImmX16)). addImm(Remainder);
+        BuildAddiuSpImm(MBB, I, DL, Remainder);
       else
         adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1);
       BuildMI(MBB, I, DL, get(Mips::RestoreRaF16)). addImm(Base);
@@ -299,7 +299,7 @@ void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
                                      MachineBasicBlock::iterator I) const {
   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
   if (isInt<16>(Amount))  // need to change to addiu sp, ....and isInt<16>
-    BuildMI(MBB, I, DL, get(Mips::AddiuSpImmX16)). addImm(Amount);
+    BuildAddiuSpImm(MBB, I, DL, Amount);
   else
     adjustStackPtrBigUnrestricted(SP, Amount, MBB, I);
 }
@@ -400,6 +400,15 @@ void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB,
   BuildMI(MBB, I, I->getDebugLoc(), get(Opc));
 }
 
+void Mips16InstrInfo::BuildAddiuSpImm(
+  MachineBasicBlock &MBB,
+  MachineBasicBlock::iterator II, DebugLoc DL, int64_t Imm) const {
+  if (validSpImm8(Imm))
+    BuildMI(MBB, II, DL, get(Mips::AddiuSpImm16)).addImm(Imm);
+  else
+    BuildMI(MBB, II, DL, get(Mips::AddiuSpImmX16)).addImm(Imm);
+}
+
 const MipsInstrInfo *llvm::createMips16InstrInfo(MipsTargetMachine &TM) {
   return new Mips16InstrInfo(TM);
 }
index 26a5a5e5fb9e62829a6c617bd032c12c2a4e73df..f8570bdc27c4800f180d1c75d6c722987923047a 100644 (file)
@@ -86,6 +86,18 @@ public:
                          MachineBasicBlock::iterator II, DebugLoc DL,
                          unsigned &NewImm) const;
 
+  static bool validSpImm8(int offset) {
+    return ((offset & 7) == 0) && isInt<11>(offset);
+  }
+
+  //
+  // build the proper one based on the Imm field
+  //
+  void BuildAddiuSpImm(MachineBasicBlock &MBB,
+                           MachineBasicBlock::iterator II, DebugLoc DL,
+                           int64_t Imm) const;
+
+
 private:
   virtual unsigned GetAnalyzableBrOpc(unsigned Opc) const;
 
index c3e61bbd12f7859a4547982b45e0a9fc965b6f07..06344dbccf63cfca43319532d4162cbc6a3a222b 100644 (file)
@@ -31,6 +31,21 @@ def mem16_ea : Operand<i32> {
   let EncoderMethod = "getMemEncoding";
 }
 
+//
+//
+// I8 instruction format
+//
+
+class FI816_ins_base<bits<3> _func, string asmstr,
+                     string asmstr2, InstrItinClass itin>:
+  FI816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2),
+        [], itin>;
+
+
+class FI816_SP_ins<bits<3> _func, string asmstr,
+                   InstrItinClass itin>:
+  FI816_ins_base<_func, asmstr, "\t$$sp, $imm # 16 bit inst", itin>;
+
 //
 // RI instruction format
 //
@@ -451,6 +466,13 @@ def AddiuRxPcImmX16: FEXT_RI16_PC_ins<0b00001, "addiu", IIAlu>;
 // Purpose: Add Immediate Unsigned Word (2-Operand, SP-Relative, Extended)
 // To add a constant to the stack pointer.
 //
+def AddiuSpImm16
+  : FI816_SP_ins<0b011, "addiu", IIAlu> {
+  let Defs = [SP];
+  let Uses = [SP];
+  let AddedComplexity = 5;
+}
+
 def AddiuSpImmX16
   : FEXT_I816_SP_ins<0b011, "addiu", IIAlu> {
   let Defs = [SP];
diff --git a/test/CodeGen/Mips/align16.ll b/test/CodeGen/Mips/align16.ll
new file mode 100644 (file)
index 0000000..99139ab
--- /dev/null
@@ -0,0 +1,31 @@
+; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static < %s | FileCheck %s -check-prefix=16
+
+@i = global i32 25, align 4
+@.str = private unnamed_addr constant [5 x i8] c"%i \0A\00", align 1
+
+define void @p(i32* %i) nounwind {
+entry:
+  ret void
+}
+
+
+define void @foo() nounwind {
+entry:
+  %y = alloca [512 x i32], align 4
+  %x = alloca i32, align 8
+  %zz = alloca i32, align 4
+  %z = alloca i32, align 4
+  %0 = load i32* @i, align 4
+  %arrayidx = getelementptr inbounds [512 x i32]* %y, i32 0, i32 10
+  store i32 %0, i32* %arrayidx, align 4
+  %1 = load i32* @i, align 4
+  store i32 %1, i32* %x, align 8
+  call void @p(i32* %x)
+  %arrayidx1 = getelementptr inbounds [512 x i32]* %y, i32 0, i32 10
+  call void @p(i32* %arrayidx1)
+  ret void
+}
+; 16:  save    $ra, $s0, $s1, 2040
+; 16:  addiu   $sp, -48 # 16 bit inst
+; 16:  addiu   $sp, 48 # 16 bit inst
+; 16:  restore $ra,  $s0, $s1, 2040
\ No newline at end of file