Index: lib/Target/Mips/MicroMipsSizeReduction.cpp =================================================================== --- lib/Target/Mips/MicroMipsSizeReduction.cpp +++ lib/Target/Mips/MicroMipsSizeReduction.cpp @@ -34,6 +34,7 @@ OT_OperandsAll, ///< Transfer all operands OT_Operands02, ///< Transfer operands 0 and 2 OT_Operand2, ///< Transfer just operand 2 + OT_OperandsXOR, ///< Transfer operands for XOR16 }; /// Reduction type @@ -159,6 +160,11 @@ static bool ReduceADDIUToADDIUR1SP(MachineInstr *MI, const ReduceEntry &Entry); + // Attempts to reduce XOR into XOR16 instruction, + // returns true on success. + static bool ReduceXORtoXOR16(MachineInstr *MI, + const ReduceEntry &Entry); + // Changes opcode of an instruction. static bool ReplaceInstruction(MachineInstr *MI, const ReduceEntry &Entry); @@ -222,6 +228,10 @@ OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)}, {RT_OneInstr, OpCodes(Mips::SW_MM, Mips::SWSP_MM), ReduceXWtoXWSP, OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)}, + {RT_OneInstr, OpCodes(Mips::XOR, Mips::XOR16_MM), ReduceXORtoXOR16, + OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)}, + {RT_OneInstr, OpCodes(Mips::XOR_MM, Mips::XOR16_MM), ReduceXORtoXOR16, + OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)} }; } @@ -395,6 +405,20 @@ return ReplaceInstruction(MI, Entry); } +bool MicroMipsSizeReduce::ReduceXORtoXOR16(MachineInstr *MI, + const ReduceEntry &Entry) { + if (!isMMThreeBitGPRegister(MI->getOperand(0)) + || !isMMThreeBitGPRegister(MI->getOperand(1)) + || !isMMThreeBitGPRegister(MI->getOperand(2))) + return false; + + if(!(MI->getOperand(0).getReg() == MI->getOperand(2).getReg()) + && !(MI->getOperand(0).getReg() == MI->getOperand(1).getReg())) + return false; + + return ReplaceInstruction(MI, Entry); +} + bool MicroMipsSizeReduce::ReduceMBB(MachineBasicBlock &MBB) { bool Modified = false; MachineBasicBlock::instr_iterator MII = MBB.instr_begin(), @@ -438,6 +462,16 @@ else if (OpTransfer == OT_Operands02) { MIB.add(MI->getOperand(0)); MIB.add(MI->getOperand(2)); + } else if (OpTransfer == OT_OperandsXOR) { + if (MI->getOperand(0).getReg() == MI->getOperand(2).getReg()) { + MIB.add(MI->getOperand(0)); + MIB.add(MI->getOperand(1)); + MIB.add(MI->getOperand(2)); + } else { + MIB.add(MI->getOperand(0)); + MIB.add(MI->getOperand(2)); + MIB.add(MI->getOperand(1)); + } } // Transfer MI flags. @@ -458,7 +492,8 @@ // TODO: Add support for other subtargets: // microMIPS32r6 and microMIPS64r6 - if (!Subtarget->inMicroMipsMode() || !Subtarget->hasMips32r2()) + if (!Subtarget->inMicroMipsMode() || !Subtarget->hasMips32r2() + || Subtarget->hasMips32r6() || Subtarget->hasMips64r6()) return false; MipsII = static_cast(Subtarget->getInstrInfo()); Index: test/CodeGen/Mips/micromips-sizereduction/micromips-xor16.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/micromips-sizereduction/micromips-xor16.ll @@ -0,0 +1,14 @@ +; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips -verify-machineinstrs < %s | FileCheck %s + +; Function Attrs: nounwind readnone +define i1 @fun(i32 %a, i32 %b) { +entry: +; CHECK-LABEL: fun: +; CHECK: xor16 + %reg1 = or i32 %a, %b + %reg2 = xor i32 %reg1, -1 + %bool1 = icmp ne i32 %a, -1 + %bool1.ext = zext i1 %bool1 to i32 + %bool2 = icmp eq i32 %bool1.ext, %reg2 + ret i1 %bool2 +}