LCOV - code coverage report
Current view: top level - lib/Target/AVR/InstPrinter - AVRInstPrinter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 61 65 93.8 %
Date: 2018-10-20 13:21:21 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- AVRInstPrinter.cpp - Convert AVR 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 AVR MCInst to a .s file.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "AVRInstPrinter.h"
      15             : 
      16             : #include "MCTargetDesc/AVRMCTargetDesc.h"
      17             : 
      18             : #include "llvm/MC/MCExpr.h"
      19             : #include "llvm/MC/MCInst.h"
      20             : #include "llvm/MC/MCInstrDesc.h"
      21             : #include "llvm/MC/MCInstrInfo.h"
      22             : #include "llvm/MC/MCRegisterInfo.h"
      23             : #include "llvm/Support/ErrorHandling.h"
      24             : #include "llvm/Support/FormattedStream.h"
      25             : 
      26             : #include <cstring>
      27             : 
      28             : #define DEBUG_TYPE "asm-printer"
      29             : 
      30             : namespace llvm {
      31             : 
      32             : // Include the auto-generated portion of the assembly writer.
      33             : #define PRINT_ALIAS_INSTR
      34             : #include "AVRGenAsmWriter.inc"
      35             : 
      36        9898 : void AVRInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
      37             :                                StringRef Annot, const MCSubtargetInfo &STI) {
      38        9898 :   unsigned Opcode = MI->getOpcode();
      39             : 
      40             :   // First handle load and store instructions with postinc or predec
      41             :   // of the form "ld reg, X+".
      42             :   // TODO: We should be able to rewrite this using TableGen data.
      43        9898 :   switch (Opcode) {
      44          78 :   case AVR::LDRdPtr:
      45             :   case AVR::LDRdPtrPi:
      46             :   case AVR::LDRdPtrPd:
      47          78 :     O << "\tld\t";
      48          78 :     printOperand(MI, 0, O);
      49          78 :     O << ", ";
      50             : 
      51          78 :     if (Opcode == AVR::LDRdPtrPd)
      52             :       O << '-';
      53             : 
      54          78 :     printOperand(MI, 1, O);
      55             : 
      56          78 :     if (Opcode == AVR::LDRdPtrPi)
      57             :       O << '+';
      58             :     break;
      59          41 :   case AVR::STPtrRr:
      60          41 :     O << "\tst\t";
      61          41 :     printOperand(MI, 0, O);
      62          41 :     O << ", ";
      63          41 :     printOperand(MI, 1, O);
      64          41 :     break;
      65          23 :   case AVR::STPtrPiRr:
      66             :   case AVR::STPtrPdRr:
      67          23 :     O << "\tst\t";
      68             : 
      69          23 :     if (Opcode == AVR::STPtrPdRr)
      70             :       O << '-';
      71             : 
      72          23 :     printOperand(MI, 1, O);
      73             : 
      74          23 :     if (Opcode == AVR::STPtrPiRr)
      75             :       O << '+';
      76             : 
      77          23 :     O << ", ";
      78          23 :     printOperand(MI, 2, O);
      79          23 :     break;
      80        9756 :   default:
      81        9756 :     if (!printAliasInstr(MI, O))
      82        9094 :       printInstruction(MI, O);
      83             : 
      84        9756 :     printAnnotation(O, Annot);
      85        9756 :     break;
      86             :   }
      87        9898 : }
      88             : 
      89        5936 : const char *AVRInstPrinter::getPrettyRegisterName(unsigned RegNum,
      90             :                                                   MCRegisterInfo const &MRI) {
      91             :   // GCC prints register pairs by just printing the lower register
      92             :   // If the register contains a subregister, print it instead
      93        5936 :   if (MRI.getNumSubRegIndices() > 0) {
      94        5936 :     unsigned RegLoNum = MRI.getSubReg(RegNum, AVR::sub_lo);
      95        5936 :     RegNum = (RegLoNum != AVR::NoRegister) ? RegLoNum : RegNum;
      96             :   }
      97             : 
      98        5936 :   return getRegisterName(RegNum);
      99             : }
     100             : 
     101        8479 : void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
     102             :                                   raw_ostream &O) {
     103             :   const MCOperand &Op = MI->getOperand(OpNo);
     104        8479 :   const MCOperandInfo &MOI = this->MII.get(MI->getOpcode()).OpInfo[OpNo];
     105             : 
     106        8479 :   if (Op.isReg()) {
     107       13014 :     bool isPtrReg = (MOI.RegClass == AVR::PTRREGSRegClassID) ||
     108        6507 :                     (MOI.RegClass == AVR::PTRDISPREGSRegClassID) ||
     109             :                     (MOI.RegClass == AVR::ZREGRegClassID);
     110             : 
     111        6507 :     if (isPtrReg) {
     112         573 :       O << getRegisterName(Op.getReg(), AVR::ptr);
     113             :     } else {
     114        5934 :       O << getPrettyRegisterName(Op.getReg(), MRI);
     115             :     }
     116        1972 :   } else if (Op.isImm()) {
     117        1634 :     O << Op.getImm();
     118             :   } else {
     119             :     assert(Op.isExpr() && "Unknown operand kind in printOperand");
     120         338 :     O << *Op.getExpr();
     121             :   }
     122        8479 : }
     123             : 
     124             : /// This is used to print an immediate value that ends up
     125             : /// being encoded as a pc-relative value.
     126         252 : void AVRInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
     127             :                                    raw_ostream &O) {
     128             :   const MCOperand &Op = MI->getOperand(OpNo);
     129             : 
     130         252 :   if (Op.isImm()) {
     131           0 :     int64_t Imm = Op.getImm();
     132             :     O << '.';
     133             : 
     134             :     // Print a position sign if needed.
     135             :     // Negative values have their sign printed automatically.
     136           0 :     if (Imm >= 0)
     137             :       O << '+';
     138             : 
     139           0 :     O << Imm;
     140             :   } else {
     141             :     assert(Op.isExpr() && "Unknown pcrel immediate operand");
     142         252 :     O << *Op.getExpr();
     143             :   }
     144         252 : }
     145             : 
     146         401 : void AVRInstPrinter::printMemri(const MCInst *MI, unsigned OpNo,
     147             :                                 raw_ostream &O) {
     148             :   assert(MI->getOperand(OpNo).isReg() && "Expected a register for the first operand");
     149             : 
     150         401 :   const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
     151             : 
     152             :   // Print the register.
     153         401 :   printOperand(MI, OpNo, O);
     154             : 
     155             :   // Print the {+,-}offset.
     156         401 :   if (OffsetOp.isImm()) {
     157         399 :     int64_t Offset = OffsetOp.getImm();
     158             : 
     159         399 :     if (Offset >= 0)
     160             :       O << '+';
     161             : 
     162         399 :     O << Offset;
     163           2 :   } else if (OffsetOp.isExpr()) {
     164           2 :     O << *OffsetOp.getExpr();
     165             :   } else {
     166           0 :     llvm_unreachable("unknown type for offset");
     167             :   }
     168         401 : }
     169             : 
     170             : } // end of namespace llvm
     171             : 

Generated by: LCOV version 1.13