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 "Utils/X86ShuffleDecode.h"
     18 #include "llvm/MC/MCInst.h"
     19 #include "llvm/Support/raw_ostream.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     Src2Name = getRegName(MI->getOperand(2).getReg());
    140     // FALL THROUGH.
    141   case X86::SHUFPDrmi:
    142     DecodeSHUFPSMask(2, MI->getOperand(3).getImm(), ShuffleMask);
    143     Src1Name = getRegName(MI->getOperand(0).getReg());
    144     break;
    145 
    146   case X86::SHUFPSrri:
    147     Src2Name = getRegName(MI->getOperand(2).getReg());
    148     // FALL THROUGH.
    149   case X86::SHUFPSrmi:
    150     DecodeSHUFPSMask(4, MI->getOperand(3).getImm(), ShuffleMask);
    151     Src1Name = getRegName(MI->getOperand(0).getReg());
    152     break;
    153 
    154   case X86::UNPCKLPDrr:
    155     Src2Name = getRegName(MI->getOperand(2).getReg());
    156     // FALL THROUGH.
    157   case X86::UNPCKLPDrm:
    158     DecodeUNPCKLPDMask(2, ShuffleMask);
    159     Src1Name = getRegName(MI->getOperand(0).getReg());
    160     break;
    161   case X86::VUNPCKLPDrr:
    162     Src2Name = getRegName(MI->getOperand(2).getReg());
    163     // FALL THROUGH.
    164   case X86::VUNPCKLPDrm:
    165     DecodeUNPCKLPDMask(2, ShuffleMask);
    166     Src1Name = getRegName(MI->getOperand(1).getReg());
    167     break;
    168   case X86::VUNPCKLPDYrr:
    169     Src2Name = getRegName(MI->getOperand(2).getReg());
    170     // FALL THROUGH.
    171   case X86::VUNPCKLPDYrm:
    172     DecodeUNPCKLPDMask(4, ShuffleMask);
    173     Src1Name = getRegName(MI->getOperand(1).getReg());
    174     break;
    175   case X86::UNPCKLPSrr:
    176     Src2Name = getRegName(MI->getOperand(2).getReg());
    177     // FALL THROUGH.
    178   case X86::UNPCKLPSrm:
    179     DecodeUNPCKLPSMask(4, ShuffleMask);
    180     Src1Name = getRegName(MI->getOperand(0).getReg());
    181     break;
    182   case X86::VUNPCKLPSrr:
    183     Src2Name = getRegName(MI->getOperand(2).getReg());
    184     // FALL THROUGH.
    185   case X86::VUNPCKLPSrm:
    186     DecodeUNPCKLPSMask(4, ShuffleMask);
    187     Src1Name = getRegName(MI->getOperand(1).getReg());
    188     break;
    189   case X86::VUNPCKLPSYrr:
    190     Src2Name = getRegName(MI->getOperand(2).getReg());
    191     // FALL THROUGH.
    192   case X86::VUNPCKLPSYrm:
    193     DecodeUNPCKLPSMask(8, ShuffleMask);
    194     Src1Name = getRegName(MI->getOperand(1).getReg());
    195     break;
    196   case X86::UNPCKHPDrr:
    197     Src2Name = getRegName(MI->getOperand(2).getReg());
    198     // FALL THROUGH.
    199   case X86::UNPCKHPDrm:
    200     DecodeUNPCKHPMask(2, ShuffleMask);
    201     Src1Name = getRegName(MI->getOperand(0).getReg());
    202     break;
    203   case X86::UNPCKHPSrr:
    204     Src2Name = getRegName(MI->getOperand(2).getReg());
    205     // FALL THROUGH.
    206   case X86::UNPCKHPSrm:
    207     DecodeUNPCKHPMask(4, ShuffleMask);
    208     Src1Name = getRegName(MI->getOperand(0).getReg());
    209     break;
    210   case X86::VPERMILPSri:
    211     DecodeVPERMILPSMask(4, MI->getOperand(2).getImm(),
    212                         ShuffleMask);
    213     Src1Name = getRegName(MI->getOperand(0).getReg());
    214     break;
    215   case X86::VPERMILPSYri:
    216     DecodeVPERMILPSMask(8, MI->getOperand(2).getImm(),
    217                         ShuffleMask);
    218     Src1Name = getRegName(MI->getOperand(0).getReg());
    219     break;
    220   case X86::VPERMILPDri:
    221     DecodeVPERMILPDMask(2, MI->getOperand(2).getImm(),
    222                         ShuffleMask);
    223     Src1Name = getRegName(MI->getOperand(0).getReg());
    224     break;
    225   case X86::VPERMILPDYri:
    226     DecodeVPERMILPDMask(4, MI->getOperand(2).getImm(),
    227                         ShuffleMask);
    228     Src1Name = getRegName(MI->getOperand(0).getReg());
    229     break;
    230   case X86::VPERM2F128rr:
    231     DecodeVPERM2F128Mask(MI->getOperand(3).getImm(), ShuffleMask);
    232     Src1Name = getRegName(MI->getOperand(1).getReg());
    233     Src2Name = getRegName(MI->getOperand(2).getReg());
    234     break;
    235   }
    236 
    237 
    238   // If this was a shuffle operation, print the shuffle mask.
    239   if (!ShuffleMask.empty()) {
    240     if (DestName == 0) DestName = Src1Name;
    241     OS << (DestName ? DestName : "mem") << " = ";
    242 
    243     // If the two sources are the same, canonicalize the input elements to be
    244     // from the first src so that we get larger element spans.
    245     if (Src1Name == Src2Name) {
    246       for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
    247         if ((int)ShuffleMask[i] >= 0 && // Not sentinel.
    248             ShuffleMask[i] >= e)        // From second mask.
    249           ShuffleMask[i] -= e;
    250       }
    251     }
    252 
    253     // The shuffle mask specifies which elements of the src1/src2 fill in the
    254     // destination, with a few sentinel values.  Loop through and print them
    255     // out.
    256     for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
    257       if (i != 0)
    258         OS << ',';
    259       if (ShuffleMask[i] == SM_SentinelZero) {
    260         OS << "zero";
    261         continue;
    262       }
    263 
    264       // Otherwise, it must come from src1 or src2.  Print the span of elements
    265       // that comes from this src.
    266       bool isSrc1 = ShuffleMask[i] < ShuffleMask.size();
    267       const char *SrcName = isSrc1 ? Src1Name : Src2Name;
    268       OS << (SrcName ? SrcName : "mem") << '[';
    269       bool IsFirst = true;
    270       while (i != e &&
    271              (int)ShuffleMask[i] >= 0 &&
    272              (ShuffleMask[i] < ShuffleMask.size()) == isSrc1) {
    273         if (!IsFirst)
    274           OS << ',';
    275         else
    276           IsFirst = false;
    277         OS << ShuffleMask[i] % ShuffleMask.size();
    278         ++i;
    279       }
    280       OS << ']';
    281       --i;  // For loop increments element #.
    282     }
    283     //MI->print(OS, 0);
    284     OS << "\n";
    285   }
    286 
    287 }
    288