For 16 and 32-bit multiplies, use the IMUL instruction instead of the MUL instruction.
authorChris Lattner <sabre@nondot.org>
Sat, 21 Jun 2003 17:16:58 +0000 (17:16 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 21 Jun 2003 17:16:58 +0000 (17:16 +0000)
This allows us to not force the use of the EAX/AX registers!

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

lib/Target/X86/InstSelectSimple.cpp
lib/Target/X86/X86ISelSimple.cpp

index 59c9657f7036d01c3629e66a39cfadf62f44237c..729ab7acc8e78892eb1649f2adcd7f6718838f88 100644 (file)
@@ -1069,8 +1069,6 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *BB,
 /// registers op0Reg and op1Reg, and put the result in DestReg.  The type of the
 /// result should be given as DestTy.
 ///
-/// FIXME: doMultiply should use one of the two address IMUL instructions!
-///
 void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI,
                       unsigned DestReg, const Type *DestTy,
                       unsigned op0Reg, unsigned op1Reg) {
@@ -1079,28 +1077,20 @@ void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI,
   case cFP:              // Floating point multiply
     BMI(BB, MBBI, X86::FpMUL, 2, DestReg).addReg(op0Reg).addReg(op1Reg);
     return;
+  case cInt:
+  case cShort:
+    BMI(BB, MBBI, Class == cInt ? X86::IMULr32 : X86::IMULr16, 2, DestReg)
+      .addReg(op0Reg).addReg(op1Reg);
+    return;
+  case cByte:
+    // Must use the MUL instruction, which forces use of AL...
+    BMI(MBB, MBBI, X86::MOVrr8, 1, X86::AL).addReg(op0Reg);
+    BMI(MBB, MBBI, X86::MULr8, 1).addReg(op1Reg);
+    BMI(MBB, MBBI, X86::MOVrr8, 1, DestReg).addReg(X86::AL);
+    return;
   default:
   case cLong: assert(0 && "doMultiply cannot operate on LONG values!");
-  case cByte:
-  case cShort:
-  case cInt:          // Small integerals, handled below...
-    break;
   }
-  static const unsigned Regs[]     ={ X86::AL    , X86::AX     , X86::EAX     };
-  static const unsigned MulOpcode[]={ X86::MULr8 , X86::MULr16 , X86::MULr32  };
-  static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
-  unsigned Reg     = Regs[Class];
-
-  // Emit a MOV to put the first operand into the appropriately-sized
-  // subreg of EAX.
-  BMI(MBB, MBBI, MovOpcode[Class], 1, Reg).addReg(op0Reg);
-  
-  // Emit the appropriate multiply instruction.
-  BMI(MBB, MBBI, MulOpcode[Class], 1).addReg(op1Reg);
-
-  // Emit another MOV to put the result into the destination register.
-  BMI(MBB, MBBI, MovOpcode[Class], 1, DestReg).addReg(Reg);
 }
 
 /// visitMul - Multiplies are not simple binary operators because they must deal
index 59c9657f7036d01c3629e66a39cfadf62f44237c..729ab7acc8e78892eb1649f2adcd7f6718838f88 100644 (file)
@@ -1069,8 +1069,6 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *BB,
 /// registers op0Reg and op1Reg, and put the result in DestReg.  The type of the
 /// result should be given as DestTy.
 ///
-/// FIXME: doMultiply should use one of the two address IMUL instructions!
-///
 void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI,
                       unsigned DestReg, const Type *DestTy,
                       unsigned op0Reg, unsigned op1Reg) {
@@ -1079,28 +1077,20 @@ void ISel::doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI,
   case cFP:              // Floating point multiply
     BMI(BB, MBBI, X86::FpMUL, 2, DestReg).addReg(op0Reg).addReg(op1Reg);
     return;
+  case cInt:
+  case cShort:
+    BMI(BB, MBBI, Class == cInt ? X86::IMULr32 : X86::IMULr16, 2, DestReg)
+      .addReg(op0Reg).addReg(op1Reg);
+    return;
+  case cByte:
+    // Must use the MUL instruction, which forces use of AL...
+    BMI(MBB, MBBI, X86::MOVrr8, 1, X86::AL).addReg(op0Reg);
+    BMI(MBB, MBBI, X86::MULr8, 1).addReg(op1Reg);
+    BMI(MBB, MBBI, X86::MOVrr8, 1, DestReg).addReg(X86::AL);
+    return;
   default:
   case cLong: assert(0 && "doMultiply cannot operate on LONG values!");
-  case cByte:
-  case cShort:
-  case cInt:          // Small integerals, handled below...
-    break;
   }
-  static const unsigned Regs[]     ={ X86::AL    , X86::AX     , X86::EAX     };
-  static const unsigned MulOpcode[]={ X86::MULr8 , X86::MULr16 , X86::MULr32  };
-  static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
-  unsigned Reg     = Regs[Class];
-
-  // Emit a MOV to put the first operand into the appropriately-sized
-  // subreg of EAX.
-  BMI(MBB, MBBI, MovOpcode[Class], 1, Reg).addReg(op0Reg);
-  
-  // Emit the appropriate multiply instruction.
-  BMI(MBB, MBBI, MulOpcode[Class], 1).addReg(op1Reg);
-
-  // Emit another MOV to put the result into the destination register.
-  BMI(MBB, MBBI, MovOpcode[Class], 1, DestReg).addReg(Reg);
 }
 
 /// visitMul - Multiplies are not simple binary operators because they must deal