X86ATTInstPrinter.cpp revision cde4ce411b1ace4a80ea1dd38df97e8508aed0c9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file includes code for rendering MCInst instances as AT&T-style 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// assembly. 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define DEBUG_TYPE "asm-printer" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "X86ATTInstPrinter.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "X86InstComments.h" 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "X86Subtarget.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "llvm/MC/MCInst.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/MC/MCAsmInfo.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/MC/MCExpr.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/ErrorHandling.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/Format.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/FormattedStream.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "X86GenInstrNames.inc" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Include the auto-generated portion of the assembly writer. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GET_INSTRUCTION_NAME 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define PRINT_ALIAS_INSTR 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "X86GenRegisterNames.inc" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "X86GenAsmWriter.inc" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef PRINT_ALIAS_INSTR 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef GET_INSTRUCTION_NAME 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)X86ATTInstPrinter::X86ATTInstPrinter(TargetMachine &TM, const MCAsmInfo &MAI) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : MCInstPrinter(MAI) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the set of available features. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setAvailableFeatures(ComputeAvailableFeatures( 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &TM.getSubtarget<X86Subtarget>())); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void X86ATTInstPrinter::printRegName(raw_ostream &OS, 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned RegNo) const { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OS << '%' << getRegisterName(RegNo); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void X86ATTInstPrinter::printInst(const MCInst *MI, raw_ostream &OS) { 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Try to print any aliases first. 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!printAliasInstr(MI, OS)) 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printInstruction(MI, OS); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If verbose assembly is enabled, we can print some informative comments. 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (CommentStream) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EmitAnyX86InstComments(MI, *CommentStream, getRegisterName); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)StringRef X86ATTInstPrinter::getOpcodeName(unsigned Opcode) const { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return getInstructionName(Opcode); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void X86ATTInstPrinter::printSSECC(const MCInst *MI, unsigned Op, 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) raw_ostream &O) { 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) switch (MI->getOperand(Op).getImm()) { 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: assert(0 && "Invalid ssecc argument!"); 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 0: O << "eq"; break; 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 1: O << "lt"; break; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case 2: O << "le"; break; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 3: O << "unord"; break; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 4: O << "neq"; break; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 5: O << "nlt"; break; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 6: O << "nle"; break; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case 7: O << "ord"; break; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// print_pcrel_imm - This is used to print an immediate value that ends up 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// being encoded as a pc-relative value (e.g. for jumps and calls). These 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// print slightly differently than normal immediates. For example, a $ is not 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// emitted. 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void X86ATTInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo, 837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) raw_ostream &O) { 847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const MCOperand &Op = MI->getOperand(OpNo); 857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (Op.isImm()) 867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Print this as a signed 32-bit value. 877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) O << (int)Op.getImm(); 887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) else { 897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) assert(Op.isExpr() && "unknown pcrel immediate operand"); 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) O << *Op.getExpr(); 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void X86ATTInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) raw_ostream &O) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const MCOperand &Op = MI->getOperand(OpNo); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Op.isReg()) { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) O << '%' << getRegisterName(Op.getReg()); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (Op.isImm()) { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) O << '$' << Op.getImm(); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (CommentStream && (Op.getImm() > 255 || Op.getImm() < -256)) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *CommentStream << format("imm = 0x%llX\n", (long long)Op.getImm()); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) assert(Op.isExpr() && "unknown operand kind in printOperand"); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) O << '$' << *Op.getExpr(); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op, 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) raw_ostream &O) { 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const MCOperand &BaseReg = MI->getOperand(Op); 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const MCOperand &IndexReg = MI->getOperand(Op+2); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const MCOperand &DispSpec = MI->getOperand(Op+3); 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const MCOperand &SegReg = MI->getOperand(Op+4); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If this has a segment register, print it. 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (SegReg.getReg()) { 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printOperand(MI, Op+4, O); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) O << ':'; 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (DispSpec.isImm()) { 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64_t DispVal = DispSpec.getImm(); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) O << DispVal; 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) O << *DispSpec.getExpr(); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (IndexReg.getReg() || BaseReg.getReg()) { 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) O << '('; 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (BaseReg.getReg()) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printOperand(MI, Op, O); 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IndexReg.getReg()) { 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) O << ','; 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) printOperand(MI, Op+2, O); 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) unsigned ScaleVal = MI->getOperand(Op+1).getImm(); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ScaleVal != 1) 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) O << ',' << ScaleVal; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) O << ')'; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)