R600/SI: Expand ashr of v2i32/v4i32 for SI
[oota-llvm.git] / lib / Target / AArch64 / AArch64InstrInfo.cpp
index d59f2f1cc0f114ae56d5abb35c6614a420e0c98f..d8f45eb5a615384adac0f1fe47ba9f3701eec09d 100644 (file)
@@ -36,7 +36,7 @@ using namespace llvm;
 
 AArch64InstrInfo::AArch64InstrInfo(const AArch64Subtarget &STI)
   : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP),
-    RI(*this, STI), Subtarget(STI) {}
+    Subtarget(STI) {}
 
 void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator I, DebugLoc DL,
@@ -116,17 +116,6 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     .addImm(0);
 }
 
-MachineInstr *
-AArch64InstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx,
-                                           uint64_t Offset, const MDNode *MDPtr,
-                                           DebugLoc DL) const {
-  MachineInstrBuilder MIB = BuildMI(MF, DL, get(AArch64::DBG_VALUE))
-    .addFrameIndex(FrameIx).addImm(0)
-    .addImm(Offset)
-    .addMetadata(MDPtr);
-  return &*MIB;
-}
-
 /// Does the Opcode represent a conditional branch that we can remove and re-add
 /// at the end of a basic block?
 static bool isCondBranch(unsigned Opc) {
@@ -582,8 +571,6 @@ unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
   case TargetOpcode::EH_LABEL:
   case TargetOpcode::DBG_VALUE:
     return 0;
-  case AArch64::CONSTPOOL_ENTRY:
-    return MI.getOperand(2).getImm();
   case AArch64::TLSDESCCALL:
     return 0;
   default:
@@ -613,27 +600,45 @@ bool llvm::rewriteA64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
   llvm_unreachable("Unimplemented rewriteFrameIndex");
 }
 
-void llvm::emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+void llvm::emitRegUpdate(MachineBasicBlock &MBB,
+                         MachineBasicBlock::iterator MBBI,
                          DebugLoc dl, const TargetInstrInfo &TII,
                          unsigned DstReg, unsigned SrcReg, unsigned ScratchReg,
                          int64_t NumBytes, MachineInstr::MIFlag MIFlags) {
   if (NumBytes == 0 && DstReg == SrcReg)
     return;
-  else if (abs(NumBytes) & ~0xffffff) {
+  else if (abs64(NumBytes) & ~0xffffff) {
     // Generically, we have to materialize the offset into a temporary register
     // and subtract it. There are a couple of ways this could be done, for now
-    // we'll go for a literal-pool load.
-    MachineFunction &MF = *MBB.getParent();
-    MachineConstantPool *MCP = MF.getConstantPool();
-    const Constant *C
-      = ConstantInt::get(Type::getInt64Ty(MF.getFunction()->getContext()),
-                         abs(NumBytes));
-    unsigned CPI = MCP->getConstantPoolIndex(C, 8);
-
-    // LDR xTMP, .LITPOOL
-    BuildMI(MBB, MBBI, dl, TII.get(AArch64::LDRx_lit), ScratchReg)
-      .addConstantPoolIndex(CPI)
-      .setMIFlag(MIFlags);
+    // we'll use a movz/movk or movn/movk sequence.
+    uint64_t Bits = static_cast<uint64_t>(abs64(NumBytes));
+    BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg)
+      .addImm(0xffff & Bits).addImm(0)
+      .setMIFlags(MIFlags);
+
+    Bits >>= 16;
+    if (Bits & 0xffff) {
+      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
+        .addReg(ScratchReg)
+        .addImm(0xffff & Bits).addImm(1)
+        .setMIFlags(MIFlags);
+    }
+
+    Bits >>= 16;
+    if (Bits & 0xffff) {
+      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
+        .addReg(ScratchReg)
+        .addImm(0xffff & Bits).addImm(2)
+        .setMIFlags(MIFlags);
+    }
+
+    Bits >>= 16;
+    if (Bits & 0xffff) {
+      BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
+        .addReg(ScratchReg)
+        .addImm(0xffff & Bits).addImm(3)
+        .setMIFlags(MIFlags);
+    }
 
     // ADD DST, SRC, xTMP (, lsl #0)
     unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx;
@@ -657,7 +662,7 @@ void llvm::emitRegUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBB
   } else {
     LowOp = AArch64::SUBxxi_lsl0_s;
     HighOp = AArch64::SUBxxi_lsl12_s;
-    NumBytes = abs(NumBytes);
+    NumBytes = abs64(NumBytes);
   }
 
   // If we're here, at the very least a move needs to be produced, which just
@@ -695,7 +700,8 @@ namespace {
     LDTLSCleanup() : MachineFunctionPass(ID) {}
 
     virtual bool runOnMachineFunction(MachineFunction &MF) {
-      AArch64MachineFunctionInfo* MFI = MF.getInfo<AArch64MachineFunctionInfo>();
+      AArch64MachineFunctionInfo* MFI
+        = MF.getInfo<AArch64MachineFunctionInfo>();
       if (MFI->getNumLocalDynamicTLSAccesses() < 2) {
         // No point folding accesses if there isn't at least two.
         return false;