Home | History | Annotate | Download | only in R600
      1 //===- AMDGPUMCInstLower.cpp - Lower AMDGPU MachineInstr to an MCInst -----===//
      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 /// \file
     11 /// \brief Code to lower AMDGPU MachineInstrs to their corresponding MCInst.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 //
     15 
     16 #include "AMDGPUMCInstLower.h"
     17 #include "AMDGPUAsmPrinter.h"
     18 #include "R600InstrInfo.h"
     19 #include "llvm/CodeGen/MachineBasicBlock.h"
     20 #include "llvm/CodeGen/MachineInstr.h"
     21 #include "llvm/IR/Constants.h"
     22 #include "llvm/MC/MCExpr.h"
     23 #include "llvm/MC/MCInst.h"
     24 #include "llvm/MC/MCStreamer.h"
     25 #include "llvm/Support/ErrorHandling.h"
     26 
     27 using namespace llvm;
     28 
     29 AMDGPUMCInstLower::AMDGPUMCInstLower(MCContext &ctx):
     30   Ctx(ctx)
     31 { }
     32 
     33 void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
     34   OutMI.setOpcode(MI->getOpcode());
     35 
     36   for (unsigned i = 0, e = MI->getNumExplicitOperands(); i != e; ++i) {
     37     const MachineOperand &MO = MI->getOperand(i);
     38 
     39     MCOperand MCOp;
     40     switch (MO.getType()) {
     41     default:
     42       llvm_unreachable("unknown operand type");
     43     case MachineOperand::MO_FPImmediate: {
     44       const APFloat &FloatValue = MO.getFPImm()->getValueAPF();
     45       assert(&FloatValue.getSemantics() == &APFloat::IEEEsingle &&
     46              "Only floating point immediates are supported at the moment.");
     47       MCOp = MCOperand::CreateFPImm(FloatValue.convertToFloat());
     48       break;
     49     }
     50     case MachineOperand::MO_Immediate:
     51       MCOp = MCOperand::CreateImm(MO.getImm());
     52       break;
     53     case MachineOperand::MO_Register:
     54       MCOp = MCOperand::CreateReg(MO.getReg());
     55       break;
     56     case MachineOperand::MO_MachineBasicBlock:
     57       MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
     58                                    MO.getMBB()->getSymbol(), Ctx));
     59     }
     60     OutMI.addOperand(MCOp);
     61   }
     62 }
     63 
     64 void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
     65   AMDGPUMCInstLower MCInstLowering(OutContext);
     66 
     67   if (MI->isBundle()) {
     68     const MachineBasicBlock *MBB = MI->getParent();
     69     MachineBasicBlock::const_instr_iterator I = MI;
     70     ++I;
     71     while (I != MBB->end() && I->isInsideBundle()) {
     72       MCInst MCBundleInst;
     73       const MachineInstr *BundledInst = I;
     74       MCInstLowering.lower(BundledInst, MCBundleInst);
     75       OutStreamer.EmitInstruction(MCBundleInst);
     76       ++I;
     77     }
     78   } else {
     79     MCInst TmpInst;
     80     MCInstLowering.lower(MI, TmpInst);
     81     OutStreamer.EmitInstruction(TmpInst);
     82   }
     83 }
     84