From 0f1c461423ddc3fcea0fd8813b934838cc2b95e5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 21 Jun 2003 17:16:58 +0000 Subject: [PATCH] For 16 and 32-bit multiplies, use the IMUL instruction instead of the MUL instruction. 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 | 32 ++++++++++------------------- lib/Target/X86/X86ISelSimple.cpp | 32 ++++++++++------------------- 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 59c9657f703..729ab7acc8e 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -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 diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 59c9657f703..729ab7acc8e 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -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