From 6b9d4617800d9450825f8a4b122a9aeb76f2795f Mon Sep 17 00:00:00 2001 From: Reed Kotler Date: Wed, 13 Feb 2013 20:28:27 +0000 Subject: [PATCH] For Mips 16, add the optimization where the 16 bit form of addiu sp can be used 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 | 15 +++++++++++--- lib/Target/Mips/Mips16InstrInfo.h | 12 +++++++++++ lib/Target/Mips/Mips16InstrInfo.td | 22 ++++++++++++++++++++ test/CodeGen/Mips/align16.ll | 31 +++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/Mips/align16.ll diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp index 9f27ac35173..5a91519fd84 100644 --- a/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/lib/Target/Mips/Mips16InstrInfo.cpp @@ -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); } diff --git a/lib/Target/Mips/Mips16InstrInfo.h b/lib/Target/Mips/Mips16InstrInfo.h index 26a5a5e5fb9..f8570bdc27c 100644 --- a/lib/Target/Mips/Mips16InstrInfo.h +++ b/lib/Target/Mips/Mips16InstrInfo.h @@ -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; diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index c3e61bbd12f..06344dbccf6 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -31,6 +31,21 @@ def mem16_ea : Operand { let EncoderMethod = "getMemEncoding"; } +// +// +// I8 instruction format +// + +class FI816_ins_base _func, string asmstr, + string asmstr2, InstrItinClass itin>: + FI816<_func, (outs), (ins simm16:$imm), !strconcat(asmstr, asmstr2), + [], itin>; + + +class FI816_SP_ins _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 index 00000000000..99139abbe84 --- /dev/null +++ b/test/CodeGen/Mips/align16.ll @@ -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