summaryrefslogtreecommitdiffstats
path: root/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp')
-rw-r--r--lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
new file mode 100644
index 0000000..9d50edc
--- /dev/null
+++ b/lib/Target/X86/AsmPrinter/X86ATTInstPrinter.cpp
@@ -0,0 +1,143 @@
+//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file includes code for rendering MCInst instances as AT&T-style
+// assembly.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "asm-printer"
+#include "llvm/MC/MCInst.h"
+#include "X86ATTAsmPrinter.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+// Include the auto-generated portion of the assembly writer.
+#define MachineInstr MCInst
+#define NO_ASM_WRITER_BOILERPLATE
+#include "X86GenAsmWriter.inc"
+#undef MachineInstr
+
+void X86ATTAsmPrinter::printSSECC(const MCInst *MI, unsigned Op) {
+ switch (MI->getOperand(Op).getImm()) {
+ default: assert(0 && "Invalid ssecc argument!");
+ case 0: O << "eq"; break;
+ case 1: O << "lt"; break;
+ case 2: O << "le"; break;
+ case 3: O << "unord"; break;
+ case 4: O << "neq"; break;
+ case 5: O << "nlt"; break;
+ case 6: O << "nle"; break;
+ case 7: O << "ord"; break;
+ }
+}
+
+
+void X86ATTAsmPrinter::printPICLabel(const MCInst *MI, unsigned Op) {
+ assert(0 &&
+ "This is only used for MOVPC32r, should lower before asm printing!");
+}
+
+
+/// print_pcrel_imm - This is used to print an immediate value that ends up
+/// being encoded as a pc-relative value. These print slightly differently, for
+/// example, a $ is not emitted.
+void X86ATTAsmPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) {
+ const MCOperand &Op = MI->getOperand(OpNo);
+
+ if (Op.isImm())
+ O << Op.getImm();
+ else if (Op.isMBBLabel())
+ // FIXME: Keep in sync with printBasicBlockLabel. printBasicBlockLabel
+ // should eventually call into this code, not the other way around.
+ O << TAI->getPrivateGlobalPrefix() << "BB" << Op.getMBBLabelFunction()
+ << '_' << Op.getMBBLabelBlock();
+ else
+ assert(0 && "Unknown pcrel immediate operand");
+}
+
+
+void X86ATTAsmPrinter::printOperand(const MCInst *MI, unsigned OpNo,
+ const char *Modifier, bool NotRIPRel) {
+ assert(Modifier == 0 && "Modifiers should not be used");
+
+ const MCOperand &Op = MI->getOperand(OpNo);
+ if (Op.isReg()) {
+ O << '%';
+ unsigned Reg = Op.getReg();
+#if 0
+ if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
+ MVT VT = (strcmp(Modifier+6,"64") == 0) ?
+ MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
+ ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
+ Reg = getX86SubSuperRegister(Reg, VT);
+ }
+#endif
+ O << TRI->getAsmName(Reg);
+ return;
+ } else if (Op.isImm()) {
+ //if (!Modifier || (strcmp(Modifier, "debug") && strcmp(Modifier, "mem")))
+ O << '$';
+ O << Op.getImm();
+ return;
+ }
+
+ O << "<<UNKNOWN OPERAND KIND>>";
+}
+
+void X86ATTAsmPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) {
+ bool NotRIPRel = false;
+
+ const MCOperand &BaseReg = MI->getOperand(Op);
+ const MCOperand &IndexReg = MI->getOperand(Op+2);
+ const MCOperand &DispSpec = MI->getOperand(Op+3);
+
+ NotRIPRel |= IndexReg.getReg() || BaseReg.getReg();
+ if (DispSpec.isImm()) {
+ int64_t DispVal = DispSpec.getImm();
+ if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))
+ O << DispVal;
+ } else {
+ abort();
+ //assert(DispSpec.isGlobal() || DispSpec.isCPI() ||
+ // DispSpec.isJTI() || DispSpec.isSymbol());
+ //printOperand(MI, Op+3, "mem", NotRIPRel);
+ }
+
+ if (IndexReg.getReg() || BaseReg.getReg()) {
+ // There are cases where we can end up with ESP/RSP in the indexreg slot.
+ // If this happens, swap the base/index register to support assemblers that
+ // don't work when the index is *SP.
+ // FIXME: REMOVE THIS.
+ assert(IndexReg.getReg() != X86::ESP && IndexReg.getReg() != X86::RSP);
+
+ O << '(';
+ if (BaseReg.getReg())
+ printOperand(MI, Op);
+
+ if (IndexReg.getReg()) {
+ O << ',';
+ printOperand(MI, Op+2);
+ unsigned ScaleVal = MI->getOperand(Op+1).getImm();
+ if (ScaleVal != 1)
+ O << ',' << ScaleVal;
+ }
+ O << ')';
+ }
+}
+
+void X86ATTAsmPrinter::printMemReference(const MCInst *MI, unsigned Op) {
+ const MCOperand &Segment = MI->getOperand(Op+4);
+ if (Segment.getReg()) {
+ printOperand(MI, Op+4);
+ O << ':';
+ }
+ printLeaMemReference(MI, Op);
+}
OpenPOWER on IntegriCloud