Emit more efficient 64-bit operations when the RHS is a constant, and one
authorChris Lattner <sabre@nondot.org>
Tue, 6 Apr 2004 03:15:53 +0000 (03:15 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 6 Apr 2004 03:15:53 +0000 (03:15 +0000)
of the words of the constant is zeros.  For example:
  Y = and long X, 1234

now generates:
  Yl = and Xl, 1234
  Yh = 0

instead of:
  Yl = and Xl, 1234
  Yh = and Xh, 0

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12685 91177308-0d34-0410-b5e6-96231b3b80d8

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

index ac5c6ec158e00591628806e62ad940b28334b508..1d4b7c97e227895118184a5b3d7817cdcf802145 100644 (file)
@@ -1767,18 +1767,54 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
     };
   
     unsigned Opcode = OpcodeTab[OperatorClass][Class];
+    unsigned Op1l = cast<ConstantInt>(Op1C)->getRawValue();
 
-    uint64_t Op1v = cast<ConstantInt>(Op1C)->getRawValue();
-    BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1v &0xFFFFFFFF);
+    if (Class != cLong) {
+      BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1l);
+      return;
+    } else {
+      // If this is a long value and the high or low bits have a special
+      // property, emit some special cases.
+      unsigned Op1h = cast<ConstantInt>(Op1C)->getRawValue() >> 32LL;
+
+      // If the constant is zero in the low 32-bits, just copy the low part
+      // across and apply the normal 32-bit operation to the high parts.  There
+      // will be no carry or borrow into the top.
+      if (Op1l == 0) {
+        if (OperatorClass != 2) // All but and...
+          BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg).addReg(Op0r);
+        else
+          BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg).addImm(0);
+        BuildMI(*MBB, IP, OpcodeTab[OperatorClass][cLong], 2, DestReg+1)
+          .addReg(Op0r+1).addImm(Op1h);
+        return;
+      }
 
-    if (Class == cLong) {
+      // If this is a logical operation and the top 32-bits are zero, just
+      // operate on the lower 32.
+      if (Op1h == 0 && OperatorClass > 1) {
+        BuildMI(*MBB, IP, OpcodeTab[OperatorClass][cLong], 2, DestReg)
+          .addReg(Op0r).addImm(Op1l);
+        if (OperatorClass != 2)  // All but and
+          BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg+1).addReg(Op0r+1);
+        else
+          BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg+1).addImm(0);
+        return;
+      }
+
+      // TODO: We could handle lots of other special cases here, such as AND'ing
+      // with 0xFFFFFFFF00000000 -> noop, etc.
+
+      // Otherwise, code generate the full operation with a constant.
       static const unsigned TopTab[] = {
         X86::ADC32ri, X86::SBB32ri, X86::AND32ri, X86::OR32ri, X86::XOR32ri
       };
+
+      BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1l);
       BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1)
-          .addReg(Op0r+1).addImm(uint64_t(Op1v) >> 32);
+          .addReg(Op0r+1).addImm(Op1h);
+      return;
     }
-    return;
   }
 
   // Finally, handle the general case now.
index ac5c6ec158e00591628806e62ad940b28334b508..1d4b7c97e227895118184a5b3d7817cdcf802145 100644 (file)
@@ -1767,18 +1767,54 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
     };
   
     unsigned Opcode = OpcodeTab[OperatorClass][Class];
+    unsigned Op1l = cast<ConstantInt>(Op1C)->getRawValue();
 
-    uint64_t Op1v = cast<ConstantInt>(Op1C)->getRawValue();
-    BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1v &0xFFFFFFFF);
+    if (Class != cLong) {
+      BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1l);
+      return;
+    } else {
+      // If this is a long value and the high or low bits have a special
+      // property, emit some special cases.
+      unsigned Op1h = cast<ConstantInt>(Op1C)->getRawValue() >> 32LL;
+
+      // If the constant is zero in the low 32-bits, just copy the low part
+      // across and apply the normal 32-bit operation to the high parts.  There
+      // will be no carry or borrow into the top.
+      if (Op1l == 0) {
+        if (OperatorClass != 2) // All but and...
+          BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg).addReg(Op0r);
+        else
+          BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg).addImm(0);
+        BuildMI(*MBB, IP, OpcodeTab[OperatorClass][cLong], 2, DestReg+1)
+          .addReg(Op0r+1).addImm(Op1h);
+        return;
+      }
 
-    if (Class == cLong) {
+      // If this is a logical operation and the top 32-bits are zero, just
+      // operate on the lower 32.
+      if (Op1h == 0 && OperatorClass > 1) {
+        BuildMI(*MBB, IP, OpcodeTab[OperatorClass][cLong], 2, DestReg)
+          .addReg(Op0r).addImm(Op1l);
+        if (OperatorClass != 2)  // All but and
+          BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg+1).addReg(Op0r+1);
+        else
+          BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg+1).addImm(0);
+        return;
+      }
+
+      // TODO: We could handle lots of other special cases here, such as AND'ing
+      // with 0xFFFFFFFF00000000 -> noop, etc.
+
+      // Otherwise, code generate the full operation with a constant.
       static const unsigned TopTab[] = {
         X86::ADC32ri, X86::SBB32ri, X86::AND32ri, X86::OR32ri, X86::XOR32ri
       };
+
+      BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1l);
       BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1)
-          .addReg(Op0r+1).addImm(uint64_t(Op1v) >> 32);
+          .addReg(Op0r+1).addImm(Op1h);
+      return;
     }
-    return;
   }
 
   // Finally, handle the general case now.