Home | History | Annotate | Download | only in InstPrinter
      1 //===-- X86InstComments.cpp - Generate verbose-asm comments for instrs ----===//
      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 defines functionality used to emit comments about X86 instructions to
     11 // an output stream for -fverbose-asm.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "X86InstComments.h"
     16 #include "MCTargetDesc/X86MCTargetDesc.h"
     17 #include "llvm/MC/MCInst.h"
     18 #include "llvm/Support/raw_ostream.h"
     19 #include "../Utils/X86ShuffleDecode.h"
     20 using namespace llvm;
     21 
     22 //===----------------------------------------------------------------------===//
     23 // Top Level Entrypoint
     24 //===----------------------------------------------------------------------===//
     25 
     26 /// EmitAnyX86InstComments - This function decodes x86 instructions and prints
     27 /// newline terminated strings to the specified string if desired.  This
     28 /// information is shown in disassembly dumps when verbose assembly is enabled.
     29 void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
     30                                   const char *(*getRegName)(unsigned)) {
     31   // If this is a shuffle operation, the switch should fill in this state.
     32   SmallVector<unsigned, 8> ShuffleMask;
     33   const char *DestName = 0, *Src1Name = 0, *Src2Name = 0;
     34 
     35   switch (MI->getOpcode()) {
     36   case X86::INSERTPSrr:
     37     Src1Name = getRegName(MI->getOperand(1).getReg());
     38     Src2Name = getRegName(MI->getOperand(2).getReg());
     39     DecodeINSERTPSMask(MI->getOperand(3).getImm(), ShuffleMask);
     40     break;
     41 
     42   case X86::MOVLHPSrr:
     43     Src2Name = getRegName(MI->getOperand(2).getReg());
     44     Src1Name = getRegName(MI->getOperand(0).getReg());
     45     DecodeMOVLHPSMask(2, ShuffleMask);
     46     break;
     47 
     48   case X86::MOVHLPSrr:
     49     Src2Name = getRegName(MI->getOperand(2).getReg());
     50     Src1Name = getRegName(MI->getOperand(0).getReg());
     51     DecodeMOVHLPSMask(2, ShuffleMask);
     52     break;
     53 
     54   case X86::PSHUFDri:
     55     Src1Name = getRegName(MI->getOperand(1).getReg());
     56     // FALL THROUGH.
     57   case X86::PSHUFDmi:
     58     DestName = getRegName(MI->getOperand(0).getReg());
     59     DecodePSHUFMask(4, MI->getOperand(MI->getNumOperands()-1).getImm(),
     60                     ShuffleMask);
     61     break;
     62 
     63   case X86::PSHUFHWri:
     64     Src1Name = getRegName(MI->getOperand(1).getReg());
     65     // FALL THROUGH.
     66   case X86::PSHUFHWmi:
     67     DestName = getRegName(MI->getOperand(0).getReg());
     68     DecodePSHUFHWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
     69                       ShuffleMask);
     70     break;
     71   case X86::PSHUFLWri:
     72     Src1Name = getRegName(MI->getOperand(1).getReg());
     73     // FALL THROUGH.
     74   case X86::PSHUFLWmi:
     75     DestName = getRegName(MI->getOperand(0).getReg());
     76     DecodePSHUFLWMask(MI->getOperand(MI->getNumOperands()-1).getImm(),
     77                       ShuffleMask);
     78     break;
     79 
     80   case X86::PUNPCKHBWrr:
     81     Src2Name = getRegName(MI->getOperand(2).getReg());
     82     // FALL THROUGH.
     83   case X86::PUNPCKHBWrm:
     84     Src1Name = getRegName(MI->getOperand(0).getReg());
     85     DecodePUNPCKHMask(16, ShuffleMask);
     86     break;
     87   case X86::PUNPCKHWDrr:
     88     Src2Name = getRegName(MI->getOperand(2).getReg());
     89     // FALL THROUGH.
     90   case X86::PUNPCKHWDrm:
     91     Src1Name = getRegName(MI->getOperand(0).getReg());
     92     DecodePUNPCKHMask(8, ShuffleMask);
     93     break;
     94   case X86::PUNPCKHDQrr:
     95     Src2Name = getRegName(MI->getOperand(2).getReg());
     96     // FALL THROUGH.
     97   case X86::PUNPCKHDQrm:
     98     Src1Name = getRegName(MI->getOperand(0).getReg());
     99     DecodePUNPCKHMask(4, ShuffleMask);
    100     break;
    101   case X86::PUNPCKHQDQrr:
    102     Src2Name = getRegName(MI->getOperand(2).getReg());
    103     // FALL THROUGH.
    104   case X86::PUNPCKHQDQrm:
    105     Src1Name = getRegName(MI->getOperand(0).getReg());
    106     DecodePUNPCKHMask(2, ShuffleMask);
    107     break;
    108 
    109   case X86::PUNPCKLBWrr:
    110     Src2Name = getRegName(MI->getOperand(2).getReg());
    111     // FALL THROUGH.
    112   case X86::PUNPCKLBWrm:
    113     Src1Name = getRegName(MI->getOperand(0).getReg());
    114     DecodePUNPCKLBWMask(16, ShuffleMask);
    115     break;
    116   case X86::PUNPCKLWDrr:
    117     Src2Name = getRegName(MI->getOperand(2).getReg());
    118     // FALL THROUGH.
    119   case X86::PUNPCKLWDrm:
    120     Src1Name = getRegName(MI->getOperand(0).getReg());
    121     DecodePUNPCKLWDMask(8, ShuffleMask);
    122     break;
    123   case X86::PUNPCKLDQrr:
    124     Src2Name = getRegName(MI->getOperand(2).getReg());
    125     // FALL THROUGH.
    126   case X86::PUNPCKLDQrm:
    127     Src1Name = getRegName(MI->getOperand(0).getReg());
    128     DecodePUNPCKLDQMask(4, ShuffleMask);
    129     break;
    130   case X86::PUNPCKLQDQrr:
    131     Src2Name = getRegName(MI->getOperand(2).getReg());
    132     // FALL THROUGH.
    133   case X86::PUNPCKLQDQrm:
    134     Src1Name = getRegName(MI->getOperand(0).getReg());
    135     DecodePUNPCKLQDQMask(2, ShuffleMask);
    136     break;
    137 
    138   case X86::SHUFPDrri:
    139     DecodeSHUFPSMask(2, MI->getOperand(3).getImm(), ShuffleMask);
    140     Src1Name = getRegName(MI->getOperand(0).getReg());
    141     Src2Name = getRegName(MI->getOperand(2).getReg());
    142     break;
    143 
    144   case X86::SHUFPSrri:
    145     Src2Name = getRegName(MI->getOperand(2).getReg());
    146     // FALL THROUGH.
    147   case X86::SHUFPSrmi:
    148     DecodeSHUFPSMask(4, MI->getOperand(3).getImm(), ShuffleMask);
    149     Src1Name = getRegName(MI->getOperand(0).getReg());
    150     break;
    151 
    152   case X86::UNPCKLPDrr:
    153     Src2Name = getRegName(MI->getOperand(2).getReg());
    154     // FALL THROUGH.
    155   case X86::UNPCKLPDrm:
    156     DecodeUNPCKLPDMask(2, ShuffleMask);
    157     Src1Name = getRegName(MI->getOperand(0).getReg());
    158     break;
    159   case X86::VUNPCKLPDrr:
    160     Src2Name = getRegName(MI->getOperand(2).getReg());
    161     // FALL THROUGH.
    162   case X86::VUNPCKLPDrm:
    163     DecodeUNPCKLPDMask(2, ShuffleMask);
    164     Src1Name = getRegName(MI->getOperand(1).getReg());
    165     break;
    166   case X86::VUNPCKLPDYrr:
    167     Src2Name = getRegName(MI->getOperand(2).getReg());
    168     // FALL THROUGH.
    169   case X86::VUNPCKLPDYrm:
    170     DecodeUNPCKLPDMask(4, ShuffleMask);
    171     Src1Name = getRegName(MI->getOperand(1).getReg());
    172     break;
    173   case X86::UNPCKLPSrr:
    174     Src2Name = getRegName(MI->getOperand(2).getReg());
    175     // FALL THROUGH.
    176   case X86::UNPCKLPSrm:
    177     DecodeUNPCKLPSMask(4, ShuffleMask);
    178     Src1Name = getRegName(MI->getOperand(0).getReg());
    179     break;
    180   case X86::VUNPCKLPSrr:
    181     Src2Name = getRegName(MI->getOperand(2).getReg());
    182     // FALL THROUGH.
    183   case X86::VUNPCKLPSrm:
    184     DecodeUNPCKLPSMask(4, ShuffleMask);
    185     Src1Name = getRegName(MI->getOperand(1).getReg());
    186     break;
    187   case X86::VUNPCKLPSYrr:
    188     Src2Name = getRegName(MI->getOperand(2).getReg());
    189     // FALL THROUGH.
    190   case X86::VUNPCKLPSYrm:
    191     DecodeUNPCKLPSMask(8, ShuffleMask);
    192     Src1Name = getRegName(MI->getOperand(1).getReg());
    193     break;
    194   case X86::UNPCKHPDrr:
    195     Src2Name = getRegName(MI->getOperand(2).getReg());
    196     // FALL THROUGH.
    197   case X86::UNPCKHPDrm:
    198     DecodeUNPCKHPMask(2, ShuffleMask);
    199     Src1Name = getRegName(MI->getOperand(0).getReg());
    200     break;
    201   case X86::UNPCKHPSrr:
    202     Src2Name = getRegName(MI->getOperand(2).getReg());
    203     // FALL THROUGH.
    204   case X86::UNPCKHPSrm:
    205     DecodeUNPCKHPMask(4, ShuffleMask);
    206     Src1Name = getRegName(MI->getOperand(0).getReg());
    207     break;
    208   }
    209 
    210 
    211   // If this was a shuffle operation, print the shuffle mask.
    212   if (!ShuffleMask.empty()) {
    213     if (DestName == 0) DestName = Src1Name;
    214     OS << (DestName ? DestName : "mem") << " = ";
    215 
    216     // If the two sources are the same, canonicalize the input elements to be
    217     // from the first src so that we get larger element spans.
    218     if (Src1Name == Src2Name) {
    219       for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
    220         if ((int)ShuffleMask[i] >= 0 && // Not sentinel.
    221             ShuffleMask[i] >= e)        // From second mask.
    222           ShuffleMask[i] -= e;
    223       }
    224     }
    225 
    226     // The shuffle mask specifies which elements of the src1/src2 fill in the
    227     // destination, with a few sentinel values.  Loop through and print them
    228     // out.
    229     for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
    230       if (i != 0)
    231         OS << ',';
    232       if (ShuffleMask[i] == SM_SentinelZero) {
    233         OS << "zero";
    234         continue;
    235       }
    236 
    237       // Otherwise, it must come from src1 or src2.  Print the span of elements
    238       // that comes from this src.
    239       bool isSrc1 = ShuffleMask[i] < ShuffleMask.size();
    240       const char *SrcName = isSrc1 ? Src1Name : Src2Name;
    241       OS << (SrcName ? SrcName : "mem") << '[';
    242       bool IsFirst = true;
    243       while (i != e &&
    244              (int)ShuffleMask[i] >= 0 &&
    245              (ShuffleMask[i] < ShuffleMask.size()) == isSrc1) {
    246         if (!IsFirst)
    247           OS << ',';
    248         else
    249           IsFirst = false;
    250         OS << ShuffleMask[i] % ShuffleMask.size();
    251         ++i;
    252       }
    253       OS << ']';
    254       --i;  // For loop increments element #.
    255     }
    256     //MI->print(OS, 0);
    257     OS << "\n";
    258   }
    259 
    260 }
    261