Implement multiply operator
authorChris Lattner <sabre@nondot.org>
Sat, 2 Nov 2002 20:28:58 +0000 (20:28 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 2 Nov 2002 20:28:58 +0000 (20:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4506 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 72d764e7bfa89adf48d9a8f3edc06b426bfc9cb6..291dd42dc896b0d77585b47d8d80f26d218b4903 100644 (file)
@@ -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] = {
index 72d764e7bfa89adf48d9a8f3edc06b426bfc9cb6..291dd42dc896b0d77585b47d8d80f26d218b4903 100644 (file)
@@ -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] = {
index 22f9ad4a904dd87dc8a6030f6dd69501aa78b07a..73a03b4429ecb13591e7caba426f7e2aab266213 100644 (file)
@@ -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