Home | History | Annotate | Download | only in MCTargetDesc
      1 //===- HexagonInstPrinter.cpp - Convert Hexagon MCInst to assembly syntax -===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This class prints an Hexagon MCInst to a .s file.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "HexagonAsmPrinter.h"
     15 #include "HexagonInstPrinter.h"
     16 #include "MCTargetDesc/HexagonBaseInfo.h"
     17 #include "MCTargetDesc/HexagonMCInstrInfo.h"
     18 #include "llvm/MC/MCAsmInfo.h"
     19 #include "llvm/MC/MCExpr.h"
     20 #include "llvm/MC/MCInst.h"
     21 #include "llvm/Support/Debug.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 
     24 using namespace llvm;
     25 
     26 #define DEBUG_TYPE "asm-printer"
     27 
     28 #define GET_INSTRUCTION_NAME
     29 #include "HexagonGenAsmWriter.inc"
     30 
     31 HexagonInstPrinter::HexagonInstPrinter(MCAsmInfo const &MAI,
     32                                        MCInstrInfo const &MII,
     33                                        MCRegisterInfo const &MRI)
     34     : MCInstPrinter(MAI, MII, MRI), MII(MII), HasExtender(false) {
     35 }
     36 
     37 StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
     38   return MII.getName(Opcode);
     39 }
     40 
     41 void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
     42   O << getRegName(RegNo);
     43 }
     44 
     45 StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
     46   return getRegisterName(RegNo);
     47 }
     48 
     49 void HexagonInstPrinter::setExtender(MCInst const &MCI) {
     50   HasExtender = HexagonMCInstrInfo::isImmext(MCI);
     51 }
     52 
     53 void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
     54                                    StringRef Annot, const MCSubtargetInfo &STI) {
     55   assert(HexagonMCInstrInfo::isBundle(*MI));
     56   assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
     57   assert(HexagonMCInstrInfo::bundleSize(*MI) > 0);
     58   HasExtender = false;
     59   for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
     60     MCInst const &MCI = *I.getInst();
     61     if (HexagonMCInstrInfo::isDuplex(MII, MCI)) {
     62       printInstruction(MCI.getOperand(1).getInst(), OS);
     63       OS << '\v';
     64       HasExtender = false;
     65       printInstruction(MCI.getOperand(0).getInst(), OS);
     66     } else
     67       printInstruction(&MCI, OS);
     68     setExtender(MCI);
     69     OS << "\n";
     70   }
     71 
     72   auto Separator = "";
     73   if (HexagonMCInstrInfo::isInnerLoop(*MI)) {
     74     OS << Separator;
     75     Separator = " ";
     76     MCInst ME;
     77     ME.setOpcode(Hexagon::ENDLOOP0);
     78     printInstruction(&ME, OS);
     79   }
     80   if (HexagonMCInstrInfo::isOuterLoop(*MI)) {
     81     OS << Separator;
     82     Separator = " ";
     83     MCInst ME;
     84     ME.setOpcode(Hexagon::ENDLOOP1);
     85     printInstruction(&ME, OS);
     86   }
     87 }
     88 
     89 void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo,
     90                                       raw_ostream &O) const {
     91   if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo &&
     92       (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)))
     93     O << "#";
     94   MCOperand const &MO = MI->getOperand(OpNo);
     95   if (MO.isReg()) {
     96     O << getRegisterName(MO.getReg());
     97   } else if (MO.isExpr()) {
     98     int64_t Value;
     99     if (MO.getExpr()->evaluateAsAbsolute(Value))
    100       O << formatImm(Value);
    101     else
    102       O << *MO.getExpr();
    103   } else {
    104     llvm_unreachable("Unknown operand");
    105   }
    106 }
    107 
    108 void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo,
    109                                          raw_ostream &O) const {
    110   printOperand(MI, OpNo, O);
    111 }
    112 
    113 void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI,
    114                                                  unsigned OpNo,
    115                                                  raw_ostream &O) const {
    116   O << MI->getOperand(OpNo).getImm();
    117 }
    118 
    119 void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned OpNo,
    120                                             raw_ostream &O) const {
    121   O << -MI->getOperand(OpNo).getImm();
    122 }
    123 
    124 void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned OpNo,
    125                                              raw_ostream &O) const {
    126   O << -1;
    127 }
    128 
    129 void HexagonInstPrinter::prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
    130                                              raw_ostream &O) const {
    131   int64_t Imm;
    132   bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
    133   Imm = SignExtend64<9>(Imm);
    134   assert(Success); (void)Success;
    135   assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
    136   O << formatImm(Imm/64);
    137 }
    138 
    139 void HexagonInstPrinter::prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
    140                                              raw_ostream &O) const {
    141   int64_t Imm;
    142   bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
    143   Imm = SignExtend64<10>(Imm);
    144   assert(Success); (void)Success;
    145   assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
    146   O << formatImm(Imm/128);
    147 }
    148 
    149 void HexagonInstPrinter::prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
    150                                              raw_ostream &O) const {
    151   int64_t Imm;
    152   bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
    153   Imm = SignExtend64<10>(Imm);
    154   assert(Success); (void)Success;
    155   assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
    156   O << formatImm(Imm/64);
    157 }
    158 
    159 void HexagonInstPrinter::prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
    160                                              raw_ostream &O) const {
    161   int64_t Imm;
    162   bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
    163   Imm = SignExtend64<11>(Imm);
    164   assert(Success); (void)Success;
    165   assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
    166   O << formatImm(Imm/128);
    167 }
    168 
    169 void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned OpNo,
    170                                             raw_ostream &O) const {
    171   printOperand(MI, OpNo, O);
    172 }
    173 
    174 void HexagonInstPrinter::printJumpTable(MCInst const *MI, unsigned OpNo,
    175                                         raw_ostream &O) const {
    176   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
    177 
    178   printOperand(MI, OpNo, O);
    179 }
    180 
    181 void HexagonInstPrinter::printConstantPool(MCInst const *MI, unsigned OpNo,
    182                                            raw_ostream &O) const {
    183   assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
    184 
    185   printOperand(MI, OpNo, O);
    186 }
    187 
    188 void HexagonInstPrinter::printBranchOperand(MCInst const *MI, unsigned OpNo,
    189                                             raw_ostream &O) const {
    190   // Branches can take an immediate operand.  This is used by the branch
    191   // selection pass to print $+8, an eight byte displacement from the PC.
    192   llvm_unreachable("Unknown branch operand.");
    193 }
    194 
    195 void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo,
    196                                           raw_ostream &O) const {}
    197 
    198 void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned OpNo,
    199                                              raw_ostream &O) const {}
    200 
    201 void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned OpNo,
    202                                                raw_ostream &O) const {}
    203 
    204 void HexagonInstPrinter::printSymbol(MCInst const *MI, unsigned OpNo,
    205                                      raw_ostream &O, bool hi) const {
    206   MCOperand const &MO = MI->getOperand(OpNo);
    207 
    208   O << '#' << (hi ? "HI" : "LO") << '(';
    209   if (MO.isImm()) {
    210     O << '#';
    211     printOperand(MI, OpNo, O);
    212   } else {
    213     printOperand(MI, OpNo, O);
    214     assert("Unknown symbol operand");
    215   }
    216   O << ')';
    217 }
    218 
    219 void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo,
    220                                        raw_ostream &O) const {
    221   MCOperand const &MO = MI->getOperand(OpNo);
    222   assert (MO.isExpr());
    223   MCExpr const &Expr = *MO.getExpr();
    224   int64_t Value;
    225   if (Expr.evaluateAsAbsolute(Value))
    226     O << format("0x%" PRIx64, Value);
    227   else {
    228     if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))
    229       if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo)
    230         O << "##";
    231     O << Expr;
    232   }
    233 }
    234