diff options
author | Chris Lattner <sabre@nondot.org> | 2004-07-19 23:47:21 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-07-19 23:47:21 +0000 |
commit | 596b97f1abd6b4462977393996a5ca716856a465 (patch) | |
tree | c3cfd49eece00fbcd6fb70637e4b5c3d7850ef39 /lib/Target/X86/InstSelectSimple.cpp | |
parent | da77c44c2c008271d802954706350518b2683e76 (diff) |
Generate better code for multiplies by negative constants like -4, -1, -9, etc.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15012 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/InstSelectSimple.cpp')
-rw-r--r-- | lib/Target/X86/InstSelectSimple.cpp | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 3dced748bc..fc851324bf 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -2324,11 +2324,21 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB, static const unsigned MOVrrTab[] = {X86::MOV8rr, X86::MOV16rr, X86::MOV32rr}; static const unsigned MOVriTab[] = {X86::MOV8ri, X86::MOV16ri, X86::MOV32ri}; static const unsigned ADDrrTab[] = {X86::ADD8rr, X86::ADD16rr, X86::ADD32rr}; + static const unsigned NEGrTab[] = {X86::NEG8r , X86::NEG16r , X86::NEG32r }; unsigned Class = getClass(DestTy); + unsigned TmpReg; // Handle special cases here. switch (ConstRHS) { + case -2: + TmpReg = makeAnotherReg(DestTy); + BuildMI(*MBB, IP, NEGrTab[Class], 1, TmpReg).addReg(op0Reg); + BuildMI(*MBB, IP, ADDrrTab[Class], 1,DestReg).addReg(TmpReg).addReg(TmpReg); + return; + case -1: + BuildMI(*MBB, IP, NEGrTab[Class], 1, DestReg).addReg(op0Reg); + return; case 0: BuildMI(*MBB, IP, MOVriTab[Class], 1, DestReg).addImm(0); return; @@ -2342,10 +2352,20 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB, case 5: case 9: if (Class == cInt) { - addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, DestReg), + addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, TmpReg), op0Reg, ConstRHS-1, op0Reg, 0); return; } + case -3: + case -5: + case -9: + if (Class == cInt) { + TmpReg = makeAnotherReg(DestTy); + addFullAddress(BuildMI(*MBB, IP, X86::LEA32r, 5, TmpReg), + op0Reg, -ConstRHS-1, op0Reg, 0); + BuildMI(*MBB, IP, NEGrTab[Class], 1, DestReg).addReg(TmpReg); + return; + } } // If the element size is exactly a power of 2, use a shift to get it. @@ -2353,16 +2373,34 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB, switch (Class) { default: assert(0 && "Unknown class for this function!"); case cByte: - BuildMI(*MBB, IP, X86::SHL32ri,2, DestReg).addReg(op0Reg).addImm(Shift-1); + BuildMI(*MBB, IP, X86::SHL8ri,2, DestReg).addReg(op0Reg).addImm(Shift-1); return; case cShort: - BuildMI(*MBB, IP, X86::SHL32ri,2, DestReg).addReg(op0Reg).addImm(Shift-1); + BuildMI(*MBB, IP, X86::SHL16ri,2, DestReg).addReg(op0Reg).addImm(Shift-1); return; case cInt: BuildMI(*MBB, IP, X86::SHL32ri,2, DestReg).addReg(op0Reg).addImm(Shift-1); return; } } + + // If the element size is a negative power of 2, use a shift/neg to get it. + if (unsigned Shift = ExactLog2(-ConstRHS)) { + TmpReg = makeAnotherReg(DestTy); + BuildMI(*MBB, IP, NEGrTab[Class], 1, TmpReg).addReg(op0Reg); + switch (Class) { + default: assert(0 && "Unknown class for this function!"); + case cByte: + BuildMI(*MBB, IP, X86::SHL8ri,2, DestReg).addReg(TmpReg).addImm(Shift-1); + return; + case cShort: + BuildMI(*MBB, IP, X86::SHL16ri,2, DestReg).addReg(TmpReg).addImm(Shift-1); + return; + case cInt: + BuildMI(*MBB, IP, X86::SHL32ri,2, DestReg).addReg(TmpReg).addImm(Shift-1); + return; + } + } if (Class == cShort) { BuildMI(*MBB, IP, X86::IMUL16rri,2,DestReg).addReg(op0Reg).addImm(ConstRHS); @@ -2373,7 +2411,7 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB, } // Most general case, emit a normal multiply... - unsigned TmpReg = makeAnotherReg(DestTy); + TmpReg = makeAnotherReg(DestTy); BuildMI(*MBB, IP, MOVriTab[Class], 1, TmpReg).addImm(ConstRHS); // Emit a MUL to multiply the register holding the index by |