Index: CodeGen/Mips/micromips-sizereduction/micromips-addiur1sp-addiusp.ll =================================================================== --- /dev/null +++ CodeGen/Mips/micromips-sizereduction/micromips-addiur1sp-addiusp.ll @@ -0,0 +1,17 @@ +; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips -verify-machineinstrs < %s | FileCheck %s + +define i32 @f1() { +entry: +; CHECK-LABEL: f1: +; CHECK: addiusp +; CHECK: addiur1sp +; CHECK: addiusp + %a = alloca [10 x i32], align 4 + %index = getelementptr inbounds [10 x i32], [10 x i32]* %a, i32 0, i32 0 + call void @init(i32* %index) + %0 = load i32, i32* %index, align 4 + ret i32 %0 +} + +declare void @init(i32*) + Index: Target/Mips/MicroMipsSizeReduction.cpp =================================================================== --- Target/Mips/MicroMipsSizeReduction.cpp +++ Target/Mips/MicroMipsSizeReduction.cpp @@ -32,6 +32,8 @@ enum OperandTransfer { OT_NA, ///< Not applicable OT_OperandsAll, ///< Transfer all operands + OT_Operands02, ///< Transfer opernads no 0 and no 2 + OT_Operand2, ///< Transfer just oppernad no 2 }; /// Reduction type @@ -147,6 +149,16 @@ static bool ReduceArithmeticInstructions(MachineInstr *MI, const ReduceEntry &Entry); + // Attempts to reduce ADDIU into ADDIUSP instruction, + // returns true on success + static bool ReduceADDIUToADDIUSP(MachineInstr *MI, + const ReduceEntry &Entry); + + // Attempts to reduce ADDIU into ADDIUR1SP instruction, + // returns true on success + static bool ReduceADDIUToADDIUR1SP(MachineInstr *MI, + const ReduceEntry &Entry); + // Changes opcode of an instruction static bool ReplaceInstruction(MachineInstr *MI, const ReduceEntry &Entry); @@ -164,6 +176,14 @@ // ReduceType, OpCodes, ReduceFunction, // OpInfo(TransferOperands), // ImmField(Shift, LBound, HBound, ImmFieldPosition) + {RT_OneInstr, OpCodes(Mips::ADDiu, Mips::ADDIUR1SP_MM), + ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)}, + {RT_OneInstr, OpCodes(Mips::ADDiu, Mips::ADDIUSP_MM), + ReduceADDIUToADDIUSP, OpInfo(OT_Operand2), ImmField(0, 0, 0, 2)}, + {RT_OneInstr, OpCodes(Mips::ADDiu_MM, Mips::ADDIUR1SP_MM), + ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)}, + {RT_OneInstr, OpCodes(Mips::ADDiu_MM, Mips::ADDIUSP_MM), + ReduceADDIUToADDIUSP, OpInfo(OT_Operand2), ImmField(0, 0, 0, 2)}, {RT_OneInstr, OpCodes(Mips::ADDu, Mips::ADDU16_MM), ReduceArithmeticInstructions, OpInfo(OT_OperandsAll), ImmField(0, 0, 0, -1)}, @@ -174,6 +194,8 @@ OpInfo(OT_OperandsAll), ImmField(0, -1, 15, 2)}, {RT_OneInstr, OpCodes(Mips::LBu_MM, Mips::LBU16_MM), ReduceLXUtoLXU16, OpInfo(OT_OperandsAll), ImmField(0, -1, 15, 2)}, + {RT_OneInstr, OpCodes(Mips::LEA_ADDiu, Mips::ADDIUR1SP_MM), + ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)}, {RT_OneInstr, OpCodes(Mips::LHu, Mips::LHU16_MM), ReduceLXUtoLXU16, OpInfo(OT_OperandsAll), ImmField(1, 0, 16, 2)}, {RT_OneInstr, OpCodes(Mips::LHu_MM, Mips::LHU16_MM), ReduceLXUtoLXU16, @@ -234,6 +256,15 @@ return true; } +// Returns true if the value is ADDIUSP immediate +static bool AddiuspImmValue(int64_t Value) { + int64_t Value2 = Value >> 2; + if (Value == (Value2 << 2) && + ((Value2 >= 2 && Value2 <= 257) || (Value2 >= -258 && Value2 <= -3))) + return true; + return false; +} + // Returns true if the variable Value has the number of least-significant zero // bits equal to Shift and if the shifted value is between the bounds static bool InRange(int64_t Value, unsigned short Shift, int LBound, @@ -310,6 +341,34 @@ return ReplaceInstruction(MI, Entry); } +bool MicroMipsSizeReduce::ReduceADDIUToADDIUR1SP(MachineInstr *MI, + const ReduceEntry &Entry) { + + if (!ImmInRange(MI, Entry)) + return false; + + if (!isMMThreeBitGPRegister(MI->getOperand(0)) || !IsSP(MI->getOperand(1))) + return false; + + return ReplaceInstruction(MI, Entry); +} + +bool MicroMipsSizeReduce::ReduceADDIUToADDIUSP(MachineInstr *MI, + const ReduceEntry &Entry) { + + int64_t ImmValue; + if (!GetImm(MI, Entry.ImmField(), ImmValue)) + return false; + + if (!AddiuspImmValue(ImmValue)) + return false; + + if (!IsSP(MI->getOperand(0)) || !IsSP(MI->getOperand(1))) + return false; + + return ReplaceInstruction(MI, Entry); +} + bool MicroMipsSizeReduce::ReduceLXUtoLXU16(MachineInstr *MI, const ReduceEntry &Entry) { @@ -361,10 +420,36 @@ bool MicroMipsSizeReduce::ReplaceInstruction(MachineInstr *MI, const ReduceEntry &Entry) { - MI->setDesc(MipsII->get(Entry.NarrowOpc())); - DEBUG(dbgs() << "Converted into 16-bit: " << *MI); - ++NumReduced; - return true; + enum OperandTransfer OpTransfer = Entry.TransferOperands(); + if (OpTransfer == OT_OperandsAll) { + DEBUG(dbgs() << "Converted 32-bit: " << *MI); + MI->setDesc(MipsII->get(Entry.NarrowOpc())); + DEBUG(dbgs() << " to 16-bit: " << *MI); + ++NumReduced; + return true; + } else { + MachineBasicBlock &MBB = *MI->getParent(); + const MCInstrDesc &NewMCID = MipsII->get(Entry.NarrowOpc()); + DebugLoc dl = MI->getDebugLoc(); + MachineInstrBuilder MIB = BuildMI(MBB, MI, dl, NewMCID); + + if (OpTransfer == OT_Operand2) + MIB.add(MI->getOperand(2)); + else if (OpTransfer == OT_Operands02) { + MIB.add(MI->getOperand(0)); + MIB.add(MI->getOperand(2)); + } + + // Transfer MI flags. + MIB.setMIFlags(MI->getFlags()); + + DEBUG(dbgs() << "Converted 32-bit: " << *MI + << " to 16-bit: " << *MIB); + MBB.erase_instr(MI); + ++NumReduced; + return true; + } + return false; } bool MicroMipsSizeReduce::runOnMachineFunction(MachineFunction &MF) {