1249259Sdim//===- AMDGPUMCInstLower.cpp - Lower AMDGPU MachineInstr to an MCInst -----===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim/// \file 11249259Sdim/// \brief Code to lower AMDGPU MachineInstrs to their corresponding MCInst. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim// 15249259Sdim 16249259Sdim#include "AMDGPUMCInstLower.h" 17249259Sdim#include "AMDGPUAsmPrinter.h" 18263508Sdim#include "InstPrinter/AMDGPUInstPrinter.h" 19249259Sdim#include "R600InstrInfo.h" 20249259Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 21249259Sdim#include "llvm/CodeGen/MachineInstr.h" 22249259Sdim#include "llvm/IR/Constants.h" 23263508Sdim#include "llvm/MC/MCCodeEmitter.h" 24249259Sdim#include "llvm/MC/MCExpr.h" 25249259Sdim#include "llvm/MC/MCInst.h" 26263508Sdim#include "llvm/MC/MCObjectStreamer.h" 27249259Sdim#include "llvm/MC/MCStreamer.h" 28249259Sdim#include "llvm/Support/ErrorHandling.h" 29263508Sdim#include "llvm/Support/Format.h" 30263508Sdim#include <algorithm> 31249259Sdim 32249259Sdimusing namespace llvm; 33249259Sdim 34249259SdimAMDGPUMCInstLower::AMDGPUMCInstLower(MCContext &ctx): 35249259Sdim Ctx(ctx) 36249259Sdim{ } 37249259Sdim 38249259Sdimvoid AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { 39249259Sdim OutMI.setOpcode(MI->getOpcode()); 40249259Sdim 41249259Sdim for (unsigned i = 0, e = MI->getNumExplicitOperands(); i != e; ++i) { 42249259Sdim const MachineOperand &MO = MI->getOperand(i); 43249259Sdim 44249259Sdim MCOperand MCOp; 45249259Sdim switch (MO.getType()) { 46249259Sdim default: 47249259Sdim llvm_unreachable("unknown operand type"); 48249259Sdim case MachineOperand::MO_FPImmediate: { 49249259Sdim const APFloat &FloatValue = MO.getFPImm()->getValueAPF(); 50249259Sdim assert(&FloatValue.getSemantics() == &APFloat::IEEEsingle && 51249259Sdim "Only floating point immediates are supported at the moment."); 52249259Sdim MCOp = MCOperand::CreateFPImm(FloatValue.convertToFloat()); 53249259Sdim break; 54249259Sdim } 55249259Sdim case MachineOperand::MO_Immediate: 56249259Sdim MCOp = MCOperand::CreateImm(MO.getImm()); 57249259Sdim break; 58249259Sdim case MachineOperand::MO_Register: 59249259Sdim MCOp = MCOperand::CreateReg(MO.getReg()); 60249259Sdim break; 61249259Sdim case MachineOperand::MO_MachineBasicBlock: 62249259Sdim MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( 63249259Sdim MO.getMBB()->getSymbol(), Ctx)); 64249259Sdim } 65249259Sdim OutMI.addOperand(MCOp); 66249259Sdim } 67249259Sdim} 68249259Sdim 69249259Sdimvoid AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) { 70249259Sdim AMDGPUMCInstLower MCInstLowering(OutContext); 71249259Sdim 72249259Sdim if (MI->isBundle()) { 73249259Sdim const MachineBasicBlock *MBB = MI->getParent(); 74249259Sdim MachineBasicBlock::const_instr_iterator I = MI; 75249259Sdim ++I; 76249259Sdim while (I != MBB->end() && I->isInsideBundle()) { 77263508Sdim EmitInstruction(I); 78249259Sdim ++I; 79249259Sdim } 80249259Sdim } else { 81249259Sdim MCInst TmpInst; 82249259Sdim MCInstLowering.lower(MI, TmpInst); 83249259Sdim OutStreamer.EmitInstruction(TmpInst); 84263508Sdim 85263508Sdim if (DisasmEnabled) { 86263508Sdim // Disassemble instruction/operands to text. 87263508Sdim DisasmLines.resize(DisasmLines.size() + 1); 88263508Sdim std::string &DisasmLine = DisasmLines.back(); 89263508Sdim raw_string_ostream DisasmStream(DisasmLine); 90263508Sdim 91263508Sdim AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(), *TM.getInstrInfo(), 92263508Sdim *TM.getRegisterInfo()); 93263508Sdim InstPrinter.printInst(&TmpInst, DisasmStream, StringRef()); 94263508Sdim 95263508Sdim // Disassemble instruction/operands to hex representation. 96263508Sdim SmallVector<MCFixup, 4> Fixups; 97263508Sdim SmallVector<char, 16> CodeBytes; 98263508Sdim raw_svector_ostream CodeStream(CodeBytes); 99263508Sdim 100263508Sdim MCObjectStreamer &ObjStreamer = (MCObjectStreamer &)OutStreamer; 101263508Sdim MCCodeEmitter &InstEmitter = ObjStreamer.getAssembler().getEmitter(); 102263508Sdim InstEmitter.EncodeInstruction(TmpInst, CodeStream, Fixups); 103263508Sdim CodeStream.flush(); 104263508Sdim 105263508Sdim HexLines.resize(HexLines.size() + 1); 106263508Sdim std::string &HexLine = HexLines.back(); 107263508Sdim raw_string_ostream HexStream(HexLine); 108263508Sdim 109263508Sdim for (size_t i = 0; i < CodeBytes.size(); i += 4) { 110263508Sdim unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i]; 111263508Sdim HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord); 112263508Sdim } 113263508Sdim 114263508Sdim DisasmStream.flush(); 115263508Sdim DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size()); 116263508Sdim } 117249259Sdim } 118249259Sdim} 119