ARM64: separate load/store operands to simplify assembler
[oota-llvm.git] / lib / Target / ARM64 / InstPrinter / ARM64InstPrinter.cpp
index 6002dc938366212daa2b8db80634f3b89ff3f8a6..48fba37146e567739f53a224bd0cee7347fc988d 100644 (file)
@@ -63,18 +63,6 @@ void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
       return;
     }
 
-  // TBZ/TBNZ should print the register operand as a Wreg if the bit
-  // number is < 32.
-  if ((Opcode == ARM64::TBNZ || Opcode == ARM64::TBZ) &&
-      MI->getOperand(1).getImm() < 32) {
-    MCInst newMI = *MI;
-    unsigned Reg = MI->getOperand(0).getReg();
-    newMI.getOperand(0).setReg(getWRegFromXReg(Reg));
-    printInstruction(&newMI, O);
-    printAnnotation(O, Annot);
-    return;
-  }
-
   // SBFM/UBFM should print to a nicer aliased form if possible.
   if (Opcode == ARM64::SBFMXri || Opcode == ARM64::SBFMWri ||
       Opcode == ARM64::UBFMXri || Opcode == ARM64::UBFMWri) {
@@ -163,7 +151,7 @@ void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
       return;
     }
 
-    // Otherwise SBFX/UBFX is the prefered form
+    // Otherwise SBFX/UBFX is the preferred form
     O << '\t' << (IsSigned ? "sbfx" : "ubfx") << '\t'
       << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op1.getReg())
       << ", #" << Op2.getImm() << ", #" << Op3.getImm() - Op2.getImm() + 1;
@@ -190,7 +178,7 @@ void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
 
     int LSB = ImmR;
     int Width = ImmS - ImmR + 1;
-    // Otherwise BFXIL the prefered form
+    // Otherwise BFXIL the preferred form
     O << "\tbfxil\t"
       << getRegisterName(Op0.getReg()) << ", " << getRegisterName(Op2.getReg())
       << ", #" << LSB << ", #" << Width;
@@ -221,119 +209,6 @@ void ARM64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
     return;
   }
 
-  // FIXME: TableGen should be able to do all of these now.
-
-  // ANDS WZR, Wn, Wm{, lshift #imm} ==> TST Wn{, lshift #imm}
-  // ANDS XZR, Xn, Xm{, lshift #imm} ==> TST Xn{, lshift #imm}
-  if ((Opcode == ARM64::ANDSWrs && MI->getOperand(0).getReg() == ARM64::WZR) ||
-      (Opcode == ARM64::ANDSXrs && MI->getOperand(0).getReg() == ARM64::XZR)) {
-    O << "\ttst\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
-    printShiftedRegister(MI, 2, O);
-    return;
-  }
-
-  // ORN Wn, WZR, Wm{, lshift #imm} ==> MVN Wn, Wm{, lshift #imm}
-  // ORN Xn, XZR, Xm{, lshift #imm} ==> MVN Xn, Xm{, lshift #imm}
-  if ((Opcode == ARM64::ORNWrs && MI->getOperand(1).getReg() == ARM64::WZR) ||
-      (Opcode == ARM64::ORNXrs && MI->getOperand(1).getReg() == ARM64::XZR)) {
-    O << "\tmvn\t" << getRegisterName(MI->getOperand(0).getReg()) << ", ";
-    printShiftedRegister(MI, 2, O);
-    return;
-  }
-  // SUBS WZR, Wn, #imm ==> CMP Wn, #imm
-  // SUBS XZR, Xn, #imm ==> CMP Xn, #imm
-  if ((Opcode == ARM64::SUBSWri && MI->getOperand(0).getReg() == ARM64::WZR) ||
-      (Opcode == ARM64::SUBSXri && MI->getOperand(0).getReg() == ARM64::XZR)) {
-    O << "\tcmp\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
-    printAddSubImm(MI, 2, O);
-    return;
-  }
-  // SUBS WZR, Wn, Wm{, lshift #imm} ==> CMP Wn, Wm{, lshift #imm}
-  // SUBS XZR, Xn, Xm{, lshift #imm} ==> CMP Xn, Xm{, lshift #imm}
-  if ((Opcode == ARM64::SUBSWrs && MI->getOperand(0).getReg() == ARM64::WZR) ||
-      (Opcode == ARM64::SUBSXrs && MI->getOperand(0).getReg() == ARM64::XZR)) {
-    O << "\tcmp\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
-    printShiftedRegister(MI, 2, O);
-    return;
-  }
-  // SUBS XZR, Xn, Wm, uxtb #imm ==> CMP Xn, uxtb #imm
-  // SUBS WZR, Wn, Xm, uxtb #imm ==> CMP Wn, uxtb #imm
-  if ((Opcode == ARM64::SUBSXrx && MI->getOperand(0).getReg() == ARM64::XZR) ||
-      (Opcode == ARM64::SUBSWrx && MI->getOperand(0).getReg() == ARM64::WZR)) {
-    O << "\tcmp\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
-    printExtendedRegister(MI, 2, O);
-    return;
-  }
-  // SUBS XZR, Xn, Xm, uxtx #imm ==> CMP Xn, uxtb #imm
-  if (Opcode == ARM64::SUBSXrx64 && MI->getOperand(0).getReg() == ARM64::XZR) {
-    O << "\tcmp\t" << getRegisterName(MI->getOperand(1).getReg()) << ", "
-      << getRegisterName(MI->getOperand(2).getReg());
-    printExtend(MI, 3, O);
-    return;
-  }
-
-  // ADDS WZR, Wn, #imm ==> CMN Wn, #imm
-  // ADDS XZR, Xn, #imm ==> CMN Xn, #imm
-  if ((Opcode == ARM64::ADDSWri && MI->getOperand(0).getReg() == ARM64::WZR) ||
-      (Opcode == ARM64::ADDSXri && MI->getOperand(0).getReg() == ARM64::XZR)) {
-    O << "\tcmn\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
-    printAddSubImm(MI, 2, O);
-    return;
-  }
-  // ADDS WZR, Wn, Wm{, lshift #imm} ==> CMN Wn, Wm{, lshift #imm}
-  // ADDS XZR, Xn, Xm{, lshift #imm} ==> CMN Xn, Xm{, lshift #imm}
-  if ((Opcode == ARM64::ADDSWrs && MI->getOperand(0).getReg() == ARM64::WZR) ||
-      (Opcode == ARM64::ADDSXrs && MI->getOperand(0).getReg() == ARM64::XZR)) {
-    O << "\tcmn\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
-    printShiftedRegister(MI, 2, O);
-    return;
-  }
-  // ADDS XZR, Xn, Wm, uxtb #imm ==> CMN Xn, uxtb #imm
-  if (Opcode == ARM64::ADDSXrx && MI->getOperand(0).getReg() == ARM64::XZR) {
-    O << "\tcmn\t" << getRegisterName(MI->getOperand(1).getReg()) << ", ";
-    printExtendedRegister(MI, 2, O);
-    return;
-  }
-  // ADDS XZR, Xn, Xm, uxtx #imm ==> CMN Xn, uxtb #imm
-  if (Opcode == ARM64::ADDSXrx64 && MI->getOperand(0).getReg() == ARM64::XZR) {
-    O << "\tcmn\t" << getRegisterName(MI->getOperand(1).getReg()) << ", "
-      << getRegisterName(MI->getOperand(2).getReg());
-    printExtend(MI, 3, O);
-    return;
-  }
-  // ADD WSP, Wn, #0 ==> MOV WSP, Wn
-  if (Opcode == ARM64::ADDWri && (MI->getOperand(0).getReg() == ARM64::WSP ||
-                                  MI->getOperand(1).getReg() == ARM64::WSP) &&
-      MI->getOperand(2).getImm() == 0 &&
-      ARM64_AM::getShiftValue(MI->getOperand(3).getImm()) == 0) {
-    O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
-      << ", " << getRegisterName(MI->getOperand(1).getReg());
-    return;
-  }
-  // ADD XSP, Wn, #0 ==> MOV XSP, Wn
-  if (Opcode == ARM64::ADDXri && (MI->getOperand(0).getReg() == ARM64::SP ||
-                                  MI->getOperand(1).getReg() == ARM64::SP) &&
-      MI->getOperand(2).getImm() == 0 &&
-      ARM64_AM::getShiftValue(MI->getOperand(3).getImm()) == 0) {
-    O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
-      << ", " << getRegisterName(MI->getOperand(1).getReg());
-    return;
-  }
-  // ORR Wn, WZR, Wm ==> MOV Wn, Wm
-  if (Opcode == ARM64::ORRWrs && MI->getOperand(1).getReg() == ARM64::WZR &&
-      MI->getOperand(3).getImm() == 0) {
-    O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
-      << ", " << getRegisterName(MI->getOperand(2).getReg());
-    return;
-  }
-  // ORR Xn, XZR, Xm ==> MOV Xn, Xm
-  if (Opcode == ARM64::ORRXrs && MI->getOperand(1).getReg() == ARM64::XZR &&
-      MI->getOperand(3).getImm() == 0) {
-    O << "\tmov\t" << getRegisterName(MI->getOperand(0).getReg())
-      << ", " << getRegisterName(MI->getOperand(2).getReg());
-    return;
-  }
-
   if (!printAliasInstr(MI, O))
     printInstruction(MI, O);
 
@@ -1115,11 +990,11 @@ void ARM64InstPrinter::printShiftedRegister(const MCInst *MI, unsigned OpNum,
 void ARM64InstPrinter::printExtendedRegister(const MCInst *MI, unsigned OpNum,
                                              raw_ostream &O) {
   O << getRegisterName(MI->getOperand(OpNum).getReg());
-  printExtend(MI, OpNum + 1, O);
+  printArithExtend(MI, OpNum + 1, O);
 }
 
-void ARM64InstPrinter::printExtend(const MCInst *MI, unsigned OpNum,
-                                   raw_ostream &O) {
+void ARM64InstPrinter::printArithExtend(const MCInst *MI, unsigned OpNum,
+                                        raw_ostream &O) {
   unsigned Val = MI->getOperand(OpNum).getImm();
   ARM64_AM::ShiftExtendType ExtType = ARM64_AM::getArithExtendType(Val);
   unsigned ShiftVal = ARM64_AM::getArithShiftValue(Val);
@@ -1144,10 +1019,21 @@ void ARM64InstPrinter::printExtend(const MCInst *MI, unsigned OpNum,
     O << " #" << ShiftVal;
 }
 
-void ARM64InstPrinter::printDotCondCode(const MCInst *MI, unsigned OpNum,
-                                        raw_ostream &O) {
-  ARM64CC::CondCode CC = (ARM64CC::CondCode)MI->getOperand(OpNum).getImm();
-  O << '.' << ARM64CC::getCondCodeName(CC);
+void ARM64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum,
+                                      raw_ostream &O, char SrcRegKind,
+                                      unsigned Width) {
+  unsigned SignExtend = MI->getOperand(OpNum).getImm();
+  unsigned DoShift = MI->getOperand(OpNum + 1).getImm();
+
+  // sxtw, sxtx, uxtw or lsl (== uxtx)
+  bool IsLSL = !SignExtend && SrcRegKind == 'x';
+  if (IsLSL)
+    O << "lsl";
+  else
+    O << (SignExtend ? 's' : 'u') << "xt" << SrcRegKind;
+
+  if (DoShift || IsLSL)
+    O << " #" << Log2_32(Width / 8);
 }
 
 void ARM64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum,
@@ -1173,18 +1059,15 @@ void ARM64InstPrinter::printImmScale(const MCInst *MI, unsigned OpNum,
   O << '#' << Scale * MI->getOperand(OpNum).getImm();
 }
 
-void ARM64InstPrinter::printAMIndexed(const MCInst *MI, unsigned OpNum,
-                                      unsigned Scale, raw_ostream &O) {
-  const MCOperand MO1 = MI->getOperand(OpNum + 1);
-  O << '[' << getRegisterName(MI->getOperand(OpNum).getReg());
-  if (MO1.isImm()) {
-    if (MO1.getImm() != 0)
-      O << ", #" << (MO1.getImm() * Scale);
+void ARM64InstPrinter::printUImm12Offset(const MCInst *MI, unsigned OpNum,
+                                         unsigned Scale, raw_ostream &O) {
+  const MCOperand MO = MI->getOperand(OpNum);
+  if (MO.isImm()) {
+    O << "#" << (MO.getImm() * Scale);
   } else {
-    assert(MO1.isExpr() && "Unexpected operand type!");
-    O << ", " << *MO1.getExpr();
+    assert(MO.isExpr() && "Unexpected operand type!");
+    O << *MO.getExpr();
   }
-  O << ']';
 }
 
 void ARM64InstPrinter::printAMIndexedWB(const MCInst *MI, unsigned OpNum,
@@ -1211,37 +1094,6 @@ void ARM64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum,
     O << '#' << prfop;
 }
 
-void ARM64InstPrinter::printMemoryPostIndexed(const MCInst *MI, unsigned OpNum,
-                                              raw_ostream &O, unsigned Scale) {
-  O << '[' << getRegisterName(MI->getOperand(OpNum).getReg()) << ']' << ", #"
-    << Scale * MI->getOperand(OpNum + 1).getImm();
-}
-
-void ARM64InstPrinter::printMemoryRegOffset(const MCInst *MI, unsigned OpNum,
-                                            raw_ostream &O, int Scale) {
-  unsigned Val = MI->getOperand(OpNum + 2).getImm();
-  ARM64_AM::ShiftExtendType ExtType = ARM64_AM::getMemExtendType(Val);
-
-  O << '[' << getRegisterName(MI->getOperand(OpNum).getReg()) << ", ";
-  if (ExtType == ARM64_AM::UXTW || ExtType == ARM64_AM::SXTW)
-    O << getRegisterName(getWRegFromXReg(MI->getOperand(OpNum + 1).getReg()));
-  else
-    O << getRegisterName(MI->getOperand(OpNum + 1).getReg());
-
-  bool DoShift = ARM64_AM::getMemDoShift(Val);
-
-  if (ExtType == ARM64_AM::UXTX) {
-    if (DoShift)
-      O << ", lsl";
-  } else
-    O << ", " << ARM64_AM::getShiftExtendName(ExtType);
-
-  if (DoShift)
-    O << " #" << Log2_32(Scale);
-
-  O << "]";
-}
-
 void ARM64InstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
                                          raw_ostream &O) {
   const MCOperand &MO = MI->getOperand(OpNum);