From ca9671d8644a614d6f1d347794c8f04cce0445d0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 2 Nov 2002 20:28:58 +0000 Subject: Implement multiply operator git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4506 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/InstSelectSimple.cpp | 29 ++++++++++++++++++++++++++++- lib/Target/X86/X86ISelSimple.cpp | 29 ++++++++++++++++++++++++++++- lib/Target/X86/X86InstrInfo.def | 4 ++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 72d764e7bf..291dd42dc8 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -61,6 +61,7 @@ namespace { // Arithmetic operators void visitAdd(BinaryOperator &B) { visitSimpleBinary(B, 0); } void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); } + void visitMul(BinaryOperator &B); // Bitwise operators void visitAnd(BinaryOperator &B) { visitSimpleBinary(B, 2); } @@ -221,7 +222,33 @@ void ISel::visitSimpleBinary(BinaryOperator &B, unsigned OperatorClass) { BuildMI(BB, Opcode, 2, getReg(B)).addReg(Op0r).addReg(Op1r); } +/// visitMul - Multiplies are not simple binary operators because they must deal +/// with the EAX register explicitly. +/// +void ISel::visitMul(BinaryOperator &I) { + unsigned Class = getClass(I.getType()); + if (Class > 2) // FIXME: Handle longs + visitInstruction(I); + + static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX }; + static const unsigned MulOpcode[]={ X86::MULrr8, X86::MULrr16, X86::MULrr32 }; + static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 }; + + unsigned Reg = Regs[Class]; + unsigned Op0Reg = getReg(I.getOperand(1)); + unsigned Op1Reg = getReg(I.getOperand(1)); + // Put the first operand into one of the A registers... + BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg); + + // Emit the appropriate multiple instruction... + // FIXME: We need to mark that this modified AH, DX, or EDX also!! + BuildMI(BB, MulOpcode[Class], 2, Reg).addReg(Reg).addReg(Op1Reg); + + // Put the result into the destination register... + BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(Reg); + +} /// Shift instructions: 'shl', 'sar', 'shr' - Some special cases here /// for constant immediate shift values, and for constant immediate @@ -269,7 +296,7 @@ ISel::visitShiftInst (ShiftInst & I) // // Emit: move cl, shiftAmount (put the shift amount in CL.) - BuildMI (BB, X86::MOVrr8, 2, X86::CL).addReg(getReg(I.getOperand(1))); + BuildMI(BB, X86::MOVrr8, 1, X86::CL).addReg(getReg(I.getOperand(1))); // This is a shift right (SHR). static const unsigned NonConstantOperand[][4] = { diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 72d764e7bf..291dd42dc8 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -61,6 +61,7 @@ namespace { // Arithmetic operators void visitAdd(BinaryOperator &B) { visitSimpleBinary(B, 0); } void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); } + void visitMul(BinaryOperator &B); // Bitwise operators void visitAnd(BinaryOperator &B) { visitSimpleBinary(B, 2); } @@ -221,7 +222,33 @@ void ISel::visitSimpleBinary(BinaryOperator &B, unsigned OperatorClass) { BuildMI(BB, Opcode, 2, getReg(B)).addReg(Op0r).addReg(Op1r); } +/// visitMul - Multiplies are not simple binary operators because they must deal +/// with the EAX register explicitly. +/// +void ISel::visitMul(BinaryOperator &I) { + unsigned Class = getClass(I.getType()); + if (Class > 2) // FIXME: Handle longs + visitInstruction(I); + + static const unsigned Regs[] ={ X86::AL , X86::AX , X86::EAX }; + static const unsigned MulOpcode[]={ X86::MULrr8, X86::MULrr16, X86::MULrr32 }; + static const unsigned MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 }; + + unsigned Reg = Regs[Class]; + unsigned Op0Reg = getReg(I.getOperand(1)); + unsigned Op1Reg = getReg(I.getOperand(1)); + // Put the first operand into one of the A registers... + BuildMI(BB, MovOpcode[Class], 1, Reg).addReg(Op0Reg); + + // Emit the appropriate multiple instruction... + // FIXME: We need to mark that this modified AH, DX, or EDX also!! + BuildMI(BB, MulOpcode[Class], 2, Reg).addReg(Reg).addReg(Op1Reg); + + // Put the result into the destination register... + BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(Reg); + +} /// Shift instructions: 'shl', 'sar', 'shr' - Some special cases here /// for constant immediate shift values, and for constant immediate @@ -269,7 +296,7 @@ ISel::visitShiftInst (ShiftInst & I) // // Emit: move cl, shiftAmount (put the shift amount in CL.) - BuildMI (BB, X86::MOVrr8, 2, X86::CL).addReg(getReg(I.getOperand(1))); + BuildMI(BB, X86::MOVrr8, 1, X86::CL).addReg(getReg(I.getOperand(1))); // This is a shift right (SHR). static const unsigned NonConstantOperand[][4] = { diff --git a/lib/Target/X86/X86InstrInfo.def b/lib/Target/X86/X86InstrInfo.def index 22f9ad4a90..73a03b4429 100644 --- a/lib/Target/X86/X86InstrInfo.def +++ b/lib/Target/X86/X86InstrInfo.def @@ -52,6 +52,10 @@ I(ADDrr32 , "addl", 0, 0) // R32 += R32 01/r I(SUBrr8 , "subb", 0, 0) // R8 -= R8 2A/r I(SUBrr16 , "subw", 0, 0) // R16 -= R16 2B/r I(SUBrr32 , "subl", 0, 0) // R32 -= R32 2B/r +I(MULrr8 , "mulb", 0, 0) // AX = AL*R8 F6/4 +I(MULrr16 , "mulw", 0, 0) // DX:AX= AX*R16 F7/4 +I(MULrr32 , "mull", 0, 0) // ED:EA= EA*R32 F7/4 + // Logical operators I(ANDrr8 , "andb", 0, 0) // R8 &= R8 20/r -- cgit v1.2.3