[llvm-commits] CVS: llvm/lib/Target/X86/InstSelectSimple.cpp X86InstrInfo.def

Chris Lattner lattner at cs.uiuc.edu
Sat Nov 2 14:55:08 PST 2002


Changes in directory llvm/lib/Target/X86:

InstSelectSimple.cpp updated: 1.20 -> 1.21
X86InstrInfo.def updated: 1.11 -> 1.12

---
Log message:

Implement signed and unsigned division and remainder


---
Diffs of the changes:

Index: llvm/lib/Target/X86/InstSelectSimple.cpp
diff -u llvm/lib/Target/X86/InstSelectSimple.cpp:1.20 llvm/lib/Target/X86/InstSelectSimple.cpp:1.21
--- llvm/lib/Target/X86/InstSelectSimple.cpp:1.20	Sat Nov  2 14:28:58 2002
+++ llvm/lib/Target/X86/InstSelectSimple.cpp	Sat Nov  2 14:54:46 2002
@@ -59,15 +59,19 @@
     void visitBranchInst(BranchInst &BI);
 
     // Arithmetic operators
+    void visitSimpleBinary(BinaryOperator &B, unsigned OpcodeClass);
     void visitAdd(BinaryOperator &B) { visitSimpleBinary(B, 0); }
     void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); }
     void visitMul(BinaryOperator &B);
 
+    void visitDiv(BinaryOperator &B) { visitDivRem(B); }
+    void visitRem(BinaryOperator &B) { visitDivRem(B); }
+    void visitDivRem(BinaryOperator &B);
+
     // Bitwise operators
     void visitAnd(BinaryOperator &B) { visitSimpleBinary(B, 2); }
     void visitOr (BinaryOperator &B) { visitSimpleBinary(B, 3); }
     void visitXor(BinaryOperator &B) { visitSimpleBinary(B, 4); }
-    void visitSimpleBinary(BinaryOperator &B, unsigned OpcodeClass);
 
     // Binary comparison operators
 
@@ -247,7 +251,55 @@
 
   // Put the result into the destination register...
   BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(Reg);
+}
+
+/// visitDivRem - Handle division and remainder instructions... these
+/// instruction both require the same instructions to be generated, they just
+/// select the result from a different register.  Note that both of these
+/// instructions work differently for signed and unsigned operands.
+///
+void ISel::visitDivRem(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 MovOpcode[]={ X86::MOVrr8, X86::MOVrr16, X86::MOVrr32 };
+  static const unsigned ExtOpcode[]={ X86::CBW   , X86::CWD    , X86::CWQ     };
+  static const unsigned ClrOpcode[]={ X86::XORrr8, X86::XORrr16, X86::XORrr32 };
+  static const unsigned ExtRegs[]  ={ X86::AH    , X86::DX     , X86::EDX     };
+
+  static const unsigned DivOpcode[][4] = {
+    { X86::DIVrr8 , X86::DIVrr16 , X86::DIVrr32 , 0 },  // Unsigned division
+    { X86::IDIVrr8, X86::IDIVrr16, X86::IDIVrr32, 0 },  // Signed division
+  };
+
+  bool isSigned   = I.getType()->isSigned();
+  unsigned Reg    = Regs[Class];
+  unsigned ExtReg = ExtRegs[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);
+
+  if (isSigned) {
+    // Emit a sign extension instruction...
+    BuildMI(BB, ExtOpcode[Class], 1, ExtReg).addReg(Reg);
+  } else {
+    // If unsigned, emit a zeroing instruction... (reg = xor reg, reg)
+    BuildMI(BB, ClrOpcode[Class], 2, ExtReg).addReg(ExtReg).addReg(ExtReg);
+  }
+
+  // Figure out which register we want to pick the result out of...
+  unsigned DestReg = (I.getOpcode() == Instruction::Div) ? Reg : ExtReg;
+  
+  // Emit the appropriate multiple instruction...
+  // FIXME: We need to mark that this modified AH, DX, or EDX also!!
+  BuildMI(BB,DivOpcode[isSigned][Class], 2, DestReg).addReg(Reg).addReg(Op1Reg);
+
+  // Put the result into the destination register...
+  BuildMI(BB, MovOpcode[Class], 1, getReg(I)).addReg(DestReg);
 }
 
 /// Shift instructions: 'shl', 'sar', 'shr' - Some special cases here
@@ -255,11 +307,9 @@
 /// shift values equal to 1. Even the general case is sort of special,
 /// because the shift amount has to be in CL, not just any old register.
 ///
-void
-ISel::visitShiftInst (ShiftInst & I)
-{
-  unsigned Op0r = getReg (I.getOperand (0));
-  unsigned DestReg = getReg (I);
+void ISel::visitShiftInst (ShiftInst &I) {
+  unsigned Op0r = getReg (I.getOperand(0));
+  unsigned DestReg = getReg(I);
   bool isLeftShift = I.getOpcode() == Instruction::Shl;
   bool isOperandSigned = I.getType()->isUnsigned();
   unsigned OperandClass = getClass(I.getType());


Index: llvm/lib/Target/X86/X86InstrInfo.def
diff -u llvm/lib/Target/X86/X86InstrInfo.def:1.11 llvm/lib/Target/X86/X86InstrInfo.def:1.12
--- llvm/lib/Target/X86/X86InstrInfo.def:1.11	Sat Nov  2 14:28:58 2002
+++ llvm/lib/Target/X86/X86InstrInfo.def	Sat Nov  2 14:54:46 2002
@@ -56,6 +56,16 @@
 I(MULrr16     , "mulw",               0, 0)           // DX:AX= AX*R16 F7/4
 I(MULrr32     , "mull",               0, 0)           // ED:EA= EA*R32 F7/4
 
+// unsigned division/remainder
+I(DIVrr8      , "divb",               0, 0)           // AX/r8= AL&AH  F6/6
+I(DIVrr16     , "divw",               0, 0)           // DA/r16=AX&DX  F7/6
+I(DIVrr32     , "divl",               0, 0)           // DA/r32=EAX&DX F7/6
+
+// signed division/remainder
+I(IDIVrr8     , "idivb",              0, 0)           // AX/r8= AL&AH  F6/6
+I(IDIVrr16    , "idivw",              0, 0)           // DA/r16=AX&DX  F7/6
+I(IDIVrr32    , "idivl",              0, 0)           // DA/r32=EAX&DX F7/6
+
 
 // Logical operators
 I(ANDrr8      , "andb",               0, 0)           // R8  &= R8    20/r
@@ -87,6 +97,12 @@
 I(SARir16     , "sarw",               0, 0)           // R16  >>= imm8 C1/7 ib
 I(SARrr32     , "sarl",               0, 0)           // R32  >>= cl   D3/7
 I(SARir32     , "sarl",               0, 0)           // R32  >>= imm8 C1/7 ib
+
+
+// Miscellaneous instructions...
+I(CBW         , "cbw",                0, 0)           // AH = signext(AL)  98
+I(CWD         , "cwd",                0, 0)           // DX = signext(AX)  99
+I(CWQ         , "cwq",                0, 0)           // EDX= signext(EAX) 99
 
 // At this point, I is dead, so undefine the macro
 #undef I





More information about the llvm-commits mailing list