shuffle code around a bit, implement and, or, xor
authorChris Lattner <sabre@nondot.org>
Sat, 2 Nov 2002 20:04:26 +0000 (20:04 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 2 Nov 2002 20:04:26 +0000 (20:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4502 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 106d99b19dc5e3ce48e0682c6e5c9fd03f9e81d8..425ff9ed81c38664bd2febb8ad047cf73278c7d3 100644 (file)
@@ -55,11 +55,23 @@ namespace {
     // Visitation methods for various instructions.  These methods simply emit
     // fixed X86 code for each instruction.
     //
-    void visitPHINode(PHINode &I);
     void visitReturnInst(ReturnInst &RI);
     void visitBranchInst(BranchInst &BI);
+
+    // Arithmetic operators
     void visitAdd(BinaryOperator &B);
+
+    // Bitwise operators
+    void visitAnd(BinaryOperator &B) { visitBitwise(B, 0); }
+    void visitOr (BinaryOperator &B) { visitBitwise(B, 1); }
+    void visitXor(BinaryOperator &B) { visitBitwise(B, 2); }
+    void visitBitwise(BinaryOperator &B, unsigned OpcodeClass);
+
+    // Binary comparison operators
+
+    // Other operators
     void visitShiftInst(ShiftInst &I);
+    void visitPHINode(PHINode &I);
 
     void visitInstruction(Instruction &I) {
       std::cerr << "Cannot instruction select: " << I;
@@ -142,19 +154,6 @@ void ISel::copyConstantToRegister(Constant *C, unsigned R) {
   }
 }
 
-/// visitPHINode - Turn an LLVM PHI node into an X86 PHI node...
-///
-void ISel::visitPHINode(PHINode &PN) {
-  MachineInstr *MI = BuildMI(BB, X86::PHI, PN.getNumOperands(), getReg(PN));
-
-  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
-    // FIXME: This will put constants after the PHI nodes in the block, which
-    // is invalid.  They should be put inline into the PHI node eventually.
-    //
-    MI->addRegOperand(getReg(PN.getIncomingValue(i)));
-    MI->addPCDispOperand(PN.getIncomingBlock(i));
-  }
-}
 
 
 /// 'ret' instruction - Here we are interested in meeting the x86 ABI.  As such,
@@ -192,6 +191,50 @@ void ISel::visitBranchInst(BranchInst &BI) {
 }
 
 
+
+/// 'add' instruction - Simply turn this into an x86 reg,reg add instruction.
+void ISel::visitAdd(BinaryOperator &B) {
+  unsigned Op0r = getReg(B.getOperand(0)), Op1r = getReg(B.getOperand(1));
+  unsigned DestReg = getReg(B);
+  unsigned Class = getClass(B.getType());
+
+  static const unsigned Opcodes[] = { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32 };
+
+  if (Class >= sizeof(Opcodes)/sizeof(Opcodes[0]))
+    visitInstruction(B);  // Not handled class yet...
+
+  BuildMI(BB, Opcodes[Class], 2, DestReg).addReg(Op0r).addReg(Op1r);
+
+  // For Longs: Here we have a pair of operands each occupying a pair of
+  // registers.  We need to do an ADDrr32 of the least-significant pair
+  // immediately followed by an ADCrr32 (Add with Carry) of the most-significant
+  // pair.  I don't know how we are representing these multi-register arguments.
+}
+
+/// visitBitwise - Implement the three bitwise operators for integral types...
+/// OperatorClass is one of: 0 for And, 1 for Or, 2 for Xor.
+void ISel::visitBitwise(BinaryOperator &B, unsigned OperatorClass) {
+  if (B.getType() == Type::BoolTy)  // FIXME: Handle bools
+    visitInstruction(B);
+
+  unsigned Class = getClass(B.getType());
+  if (Class > 2)  // FIXME: Handle longs
+    visitInstruction(B);
+
+  static const unsigned OpcodeTab[][4] = {
+    { X86::ANDrr8, X86::ANDrr16, X86::ANDrr32, 0 },  // AND
+    { X86:: ORrr8, X86:: ORrr16, X86:: ORrr32, 0 },  // OR
+    { X86::XORrr8, X86::XORrr16, X86::XORrr32, 0 },  // XOR
+  };
+  
+  unsigned Opcode = OpcodeTab[OperatorClass][Class];
+  unsigned Op0r = getReg(B.getOperand(0));
+  unsigned Op1r = getReg(B.getOperand(1));
+  BuildMI(BB, Opcode, 2, getReg(B)).addReg(Op0r).addReg(Op1r);
+}
+
+
+
 /// Shift instructions: 'shl', 'sar', 'shr' - Some special cases here
 /// for constant immediate shift values, and for constant immediate
 /// shift values equal to 1. Even the general case is sort of special,
@@ -255,28 +298,21 @@ ISel::visitShiftInst (ShiftInst & I)
     }
 }
 
+/// visitPHINode - Turn an LLVM PHI node into an X86 PHI node...
+///
+void ISel::visitPHINode(PHINode &PN) {
+  MachineInstr *MI = BuildMI(BB, X86::PHI, PN.getNumOperands(), getReg(PN));
 
-/// 'add' instruction - Simply turn this into an x86 reg,reg add instruction.
-void ISel::visitAdd(BinaryOperator &B) {
-  unsigned Op0r = getReg(B.getOperand(0)), Op1r = getReg(B.getOperand(1));
-  unsigned DestReg = getReg(B);
-  unsigned Class = getClass(B.getType());
-
-  static const unsigned Opcodes[] = { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32 };
-
-  if (Class >= sizeof(Opcodes)/sizeof(Opcodes[0]))
-    visitInstruction(B);  // Not handled class yet...
-
-  BuildMI(BB, Opcodes[Class], 2, DestReg).addReg(Op0r).addReg(Op1r);
-
-  // For Longs: Here we have a pair of operands each occupying a pair of
-  // registers.  We need to do an ADDrr32 of the least-significant pair
-  // immediately followed by an ADCrr32 (Add with Carry) of the most-significant
-  // pair.  I don't know how we are representing these multi-register arguments.
+  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+    // FIXME: This will put constants after the PHI nodes in the block, which
+    // is invalid.  They should be put inline into the PHI node eventually.
+    //
+    MI->addRegOperand(getReg(PN.getIncomingValue(i)));
+    MI->addPCDispOperand(PN.getIncomingBlock(i));
+  }
 }
 
 
-
 /// createSimpleX86InstructionSelector - This pass converts an LLVM function
 /// into a machine code representation is a very simple peep-hole fashion.  The
 /// generated code sucks but the implementation is nice and simple.
index 106d99b19dc5e3ce48e0682c6e5c9fd03f9e81d8..425ff9ed81c38664bd2febb8ad047cf73278c7d3 100644 (file)
@@ -55,11 +55,23 @@ namespace {
     // Visitation methods for various instructions.  These methods simply emit
     // fixed X86 code for each instruction.
     //
-    void visitPHINode(PHINode &I);
     void visitReturnInst(ReturnInst &RI);
     void visitBranchInst(BranchInst &BI);
+
+    // Arithmetic operators
     void visitAdd(BinaryOperator &B);
+
+    // Bitwise operators
+    void visitAnd(BinaryOperator &B) { visitBitwise(B, 0); }
+    void visitOr (BinaryOperator &B) { visitBitwise(B, 1); }
+    void visitXor(BinaryOperator &B) { visitBitwise(B, 2); }
+    void visitBitwise(BinaryOperator &B, unsigned OpcodeClass);
+
+    // Binary comparison operators
+
+    // Other operators
     void visitShiftInst(ShiftInst &I);
+    void visitPHINode(PHINode &I);
 
     void visitInstruction(Instruction &I) {
       std::cerr << "Cannot instruction select: " << I;
@@ -142,19 +154,6 @@ void ISel::copyConstantToRegister(Constant *C, unsigned R) {
   }
 }
 
-/// visitPHINode - Turn an LLVM PHI node into an X86 PHI node...
-///
-void ISel::visitPHINode(PHINode &PN) {
-  MachineInstr *MI = BuildMI(BB, X86::PHI, PN.getNumOperands(), getReg(PN));
-
-  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
-    // FIXME: This will put constants after the PHI nodes in the block, which
-    // is invalid.  They should be put inline into the PHI node eventually.
-    //
-    MI->addRegOperand(getReg(PN.getIncomingValue(i)));
-    MI->addPCDispOperand(PN.getIncomingBlock(i));
-  }
-}
 
 
 /// 'ret' instruction - Here we are interested in meeting the x86 ABI.  As such,
@@ -192,6 +191,50 @@ void ISel::visitBranchInst(BranchInst &BI) {
 }
 
 
+
+/// 'add' instruction - Simply turn this into an x86 reg,reg add instruction.
+void ISel::visitAdd(BinaryOperator &B) {
+  unsigned Op0r = getReg(B.getOperand(0)), Op1r = getReg(B.getOperand(1));
+  unsigned DestReg = getReg(B);
+  unsigned Class = getClass(B.getType());
+
+  static const unsigned Opcodes[] = { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32 };
+
+  if (Class >= sizeof(Opcodes)/sizeof(Opcodes[0]))
+    visitInstruction(B);  // Not handled class yet...
+
+  BuildMI(BB, Opcodes[Class], 2, DestReg).addReg(Op0r).addReg(Op1r);
+
+  // For Longs: Here we have a pair of operands each occupying a pair of
+  // registers.  We need to do an ADDrr32 of the least-significant pair
+  // immediately followed by an ADCrr32 (Add with Carry) of the most-significant
+  // pair.  I don't know how we are representing these multi-register arguments.
+}
+
+/// visitBitwise - Implement the three bitwise operators for integral types...
+/// OperatorClass is one of: 0 for And, 1 for Or, 2 for Xor.
+void ISel::visitBitwise(BinaryOperator &B, unsigned OperatorClass) {
+  if (B.getType() == Type::BoolTy)  // FIXME: Handle bools
+    visitInstruction(B);
+
+  unsigned Class = getClass(B.getType());
+  if (Class > 2)  // FIXME: Handle longs
+    visitInstruction(B);
+
+  static const unsigned OpcodeTab[][4] = {
+    { X86::ANDrr8, X86::ANDrr16, X86::ANDrr32, 0 },  // AND
+    { X86:: ORrr8, X86:: ORrr16, X86:: ORrr32, 0 },  // OR
+    { X86::XORrr8, X86::XORrr16, X86::XORrr32, 0 },  // XOR
+  };
+  
+  unsigned Opcode = OpcodeTab[OperatorClass][Class];
+  unsigned Op0r = getReg(B.getOperand(0));
+  unsigned Op1r = getReg(B.getOperand(1));
+  BuildMI(BB, Opcode, 2, getReg(B)).addReg(Op0r).addReg(Op1r);
+}
+
+
+
 /// Shift instructions: 'shl', 'sar', 'shr' - Some special cases here
 /// for constant immediate shift values, and for constant immediate
 /// shift values equal to 1. Even the general case is sort of special,
@@ -255,28 +298,21 @@ ISel::visitShiftInst (ShiftInst & I)
     }
 }
 
+/// visitPHINode - Turn an LLVM PHI node into an X86 PHI node...
+///
+void ISel::visitPHINode(PHINode &PN) {
+  MachineInstr *MI = BuildMI(BB, X86::PHI, PN.getNumOperands(), getReg(PN));
 
-/// 'add' instruction - Simply turn this into an x86 reg,reg add instruction.
-void ISel::visitAdd(BinaryOperator &B) {
-  unsigned Op0r = getReg(B.getOperand(0)), Op1r = getReg(B.getOperand(1));
-  unsigned DestReg = getReg(B);
-  unsigned Class = getClass(B.getType());
-
-  static const unsigned Opcodes[] = { X86::ADDrr8, X86::ADDrr16, X86::ADDrr32 };
-
-  if (Class >= sizeof(Opcodes)/sizeof(Opcodes[0]))
-    visitInstruction(B);  // Not handled class yet...
-
-  BuildMI(BB, Opcodes[Class], 2, DestReg).addReg(Op0r).addReg(Op1r);
-
-  // For Longs: Here we have a pair of operands each occupying a pair of
-  // registers.  We need to do an ADDrr32 of the least-significant pair
-  // immediately followed by an ADCrr32 (Add with Carry) of the most-significant
-  // pair.  I don't know how we are representing these multi-register arguments.
+  for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+    // FIXME: This will put constants after the PHI nodes in the block, which
+    // is invalid.  They should be put inline into the PHI node eventually.
+    //
+    MI->addRegOperand(getReg(PN.getIncomingValue(i)));
+    MI->addPCDispOperand(PN.getIncomingBlock(i));
+  }
 }
 
 
-
 /// createSimpleX86InstructionSelector - This pass converts an LLVM function
 /// into a machine code representation is a very simple peep-hole fashion.  The
 /// generated code sucks but the implementation is nice and simple.
index 327c4e64f6887e13e42252c88870af6956282aa3..2bddb4ccc5d64565a82ef434ba102f3ec99c6a2a 100644 (file)
@@ -48,7 +48,18 @@ I(MOVir32     , "movl",               0, 0)           // R32 = imm32  B8+ rd
 // Arithmetic instructions
 I(ADDrr8      , "addb",               0, 0)           // R8  += R8    00/r
 I(ADDrr16     , "addw",               0, 0)           // R16 += R16   01/r
-I(ADDrr32     , "addl",               0, 0)           // R32 += R32   02/r
+I(ADDrr32     , "addl",               0, 0)           // R32 += R32   01/r
+
+// Logical operators
+I(ANDrr8      , "andb",               0, 0)           // R8  &= R8    20/r
+I(ANDrr16     , "andw",               0, 0)           // R16 &= R16   21/r
+I(ANDrr32     , "andl",               0, 0)           // R32 &= R32   21/r
+I(ORrr8       , "orb",                0, 0)           // R8  |= R8    08/r
+I(ORrr16      , "orw",                0, 0)           // R16 |= R16   09/r
+I(ORrr32      , "orl",                0, 0)           // R32 |= R32   09/r
+I(XORrr8      , "xorb",               0, 0)           // R8  ^= R8    30/r
+I(XORrr16     , "xorw",               0, 0)           // R16 ^= R16   31/r
+I(XORrr32     , "xorl",               0, 0)           // R32 ^= R32   31/r
 
 // Shift instructions
 I(SHLrr8      , "shlb",               0, 0)           // R8   <<= cl   D2/4