MipsInstPrinter.cpp revision 224133
1169689Skan//===-- MipsInstPrinter.cpp - Convert Mips MCInst to assembly syntax --------===//
2122180Skan//
3132718Skan//                     The LLVM Compiler Infrastructure
4122180Skan//
5132718Skan// This file is distributed under the University of Illinois Open Source
6122180Skan// License. See LICENSE.TXT for details.
7122180Skan//
8122180Skan//===----------------------------------------------------------------------===//
9122180Skan//
10132718Skan// This class prints an Mips MCInst to a .s file.
11122180Skan//
12122180Skan//===----------------------------------------------------------------------===//
13122180Skan
14122180Skan#define DEBUG_TYPE "asm-printer"
15122180Skan#include "MipsInstPrinter.h"
16132718Skan#include "llvm/MC/MCExpr.h"
17169689Skan#include "llvm/MC/MCInst.h"
18169689Skan#include "llvm/Support/ErrorHandling.h"
19122180Skan#include "llvm/Support/raw_ostream.h"
20122180Skan#include "llvm/ADT/StringExtras.h"
21122180Skanusing namespace llvm;
22122180Skan
23122180Skan#define GET_INSTRUCTION_NAME
24122180Skan#include "MipsGenAsmWriter.inc"
25122180Skan
26122180Skanconst char* Mips::MipsFCCToString(Mips::CondCode CC) {
27122180Skan  switch (CC) {
28169689Skan  case FCOND_F:
29122180Skan  case FCOND_T:   return "f";
30122180Skan  case FCOND_UN:
31122180Skan  case FCOND_OR:  return "un";
32122180Skan  case FCOND_OEQ:
33122180Skan  case FCOND_UNE: return "eq";
34122180Skan  case FCOND_UEQ:
35122180Skan  case FCOND_ONE: return "ueq";
36122180Skan  case FCOND_OLT:
37169689Skan  case FCOND_UGE: return "olt";
38169689Skan  case FCOND_ULT:
39169689Skan  case FCOND_OGE: return "ult";
40169689Skan  case FCOND_OLE:
41169689Skan  case FCOND_UGT: return "ole";
42122180Skan  case FCOND_ULE:
43169689Skan  case FCOND_OGT: return "ule";
44169689Skan  case FCOND_SF:
45169689Skan  case FCOND_ST:  return "sf";
46169689Skan  case FCOND_NGLE:
47169689Skan  case FCOND_GLE: return "ngle";
48122180Skan  case FCOND_SEQ:
49122180Skan  case FCOND_SNE: return "seq";
50122180Skan  case FCOND_NGL:
51122180Skan  case FCOND_GL:  return "ngl";
52169689Skan  case FCOND_LT:
53169689Skan  case FCOND_NLT: return "lt";
54169689Skan  case FCOND_NGE:
55169689Skan  case FCOND_GE:  return "nge";
56169689Skan  case FCOND_LE:
57169689Skan  case FCOND_NLE: return "le";
58122180Skan  case FCOND_NGT:
59169689Skan  case FCOND_GT:  return "ngt";
60169689Skan  }
61169689Skan  llvm_unreachable("Impossible condition code!");
62122180Skan}
63169689Skan
64122180SkanStringRef MipsInstPrinter::getOpcodeName(unsigned Opcode) const {
65122180Skan  return getInstructionName(Opcode);
66169689Skan}
67169689Skan
68122180Skanvoid MipsInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
69169689Skan  OS << '$' << LowercaseString(getRegisterName(RegNo));
70122180Skan}
71122180Skan
72169689Skanvoid MipsInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
73169689Skan  printInstruction(MI, O);
74169689Skan}
75122180Skan
76169689Skanvoid MipsInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
77122180Skan                                   raw_ostream &O) {
78122180Skan  const MCOperand &Op = MI->getOperand(OpNo);
79169689Skan  if (Op.isReg()) {
80169689Skan    printRegName(O, Op.getReg());
81169689Skan    return;
82169689Skan  }
83169689Skan
84169689Skan  if (Op.isImm()) {
85169689Skan    O << Op.getImm();
86169689Skan    return;
87169689Skan  }
88169689Skan
89169689Skan  assert(Op.isExpr() && "unknown operand kind in printOperand");
90169689Skan  O << *Op.getExpr();
91169689Skan}
92169689Skan
93169689Skanvoid MipsInstPrinter::printUnsignedImm(const MCInst *MI, int opNum,
94169689Skan                                       raw_ostream &O) {
95169689Skan  const MCOperand &MO = MI->getOperand(opNum);
96169689Skan  if (MO.isImm())
97169689Skan    O << (unsigned short int)MO.getImm();
98169689Skan  else
99169689Skan    printOperand(MI, opNum, O);
100122180Skan}
101169689Skan
102122180Skanvoid MipsInstPrinter::
103122180SkanprintMemOperand(const MCInst *MI, int opNum, raw_ostream &O) {
104169689Skan  // Load/Store memory operands -- imm($reg)
105122180Skan  // If PIC target the target is loaded as the
106122180Skan  // pattern lw $25,%call16($28)
107122180Skan  printOperand(MI, opNum+1, O);
108169689Skan  O << "(";
109122180Skan  printOperand(MI, opNum, O);
110122180Skan  O << ")";
111169689Skan}
112122180Skan
113122180Skanvoid MipsInstPrinter::
114169689SkanprintMemOperandEA(const MCInst *MI, int opNum, raw_ostream &O) {
115169689Skan  // when using stack locations for not load/store instructions
116169689Skan  // print the same way as all normal 3 operand instructions.
117122180Skan  printOperand(MI, opNum, O);
118169689Skan  O << ", ";
119122180Skan  printOperand(MI, opNum+1, O);
120122180Skan  return;
121169689Skan}
122169689Skan
123169689Skanvoid MipsInstPrinter::
124122180SkanprintFCCOperand(const MCInst *MI, int opNum, raw_ostream &O) {
125169689Skan  const MCOperand& MO = MI->getOperand(opNum);
126122180Skan  O << MipsFCCToString((Mips::CondCode)MO.getImm());
127122180Skan}
128169689Skan