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