Home | History | Annotate | Download | only in Hexagon
      1 //===- HexagonMCInstLower.cpp - Convert Hexagon 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 // This file contains code to lower Hexagon MachineInstrs to their corresponding
     11 // MCInst records.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "Hexagon.h"
     16 #include "HexagonAsmPrinter.h"
     17 #include "MCTargetDesc/HexagonMCExpr.h"
     18 #include "MCTargetDesc/HexagonMCInstrInfo.h"
     19 #include "MCTargetDesc/HexagonMCTargetDesc.h"
     20 #include "llvm/ADT/APFloat.h"
     21 #include "llvm/ADT/APInt.h"
     22 #include "llvm/CodeGen/MachineBasicBlock.h"
     23 #include "llvm/CodeGen/MachineInstr.h"
     24 #include "llvm/CodeGen/MachineOperand.h"
     25 #include "llvm/IR/Constants.h"
     26 #include "llvm/MC/MCContext.h"
     27 #include "llvm/MC/MCExpr.h"
     28 #include "llvm/MC/MCInst.h"
     29 #include "llvm/Support/ErrorHandling.h"
     30 #include "llvm/Support/raw_ostream.h"
     31 #include <cassert>
     32 
     33 using namespace llvm;
     34 
     35 namespace llvm {
     36 
     37 void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
     38                       MCInst &MCB, HexagonAsmPrinter &AP);
     39 
     40 } // end namespace llvm
     41 
     42 static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
     43                               HexagonAsmPrinter &Printer, bool MustExtend) {
     44   MCContext &MC = Printer.OutContext;
     45   const MCExpr *ME;
     46 
     47   // Populate the relocation type based on Hexagon target flags
     48   // set on an operand
     49   MCSymbolRefExpr::VariantKind RelocationType;
     50   switch (MO.getTargetFlags() & ~HexagonII::HMOTF_ConstExtended) {
     51   default:
     52     RelocationType = MCSymbolRefExpr::VK_None;
     53     break;
     54   case HexagonII::MO_PCREL:
     55     RelocationType = MCSymbolRefExpr::VK_Hexagon_PCREL;
     56     break;
     57   case HexagonII::MO_GOT:
     58     RelocationType = MCSymbolRefExpr::VK_GOT;
     59     break;
     60   case HexagonII::MO_LO16:
     61     RelocationType = MCSymbolRefExpr::VK_Hexagon_LO16;
     62     break;
     63   case HexagonII::MO_HI16:
     64     RelocationType = MCSymbolRefExpr::VK_Hexagon_HI16;
     65     break;
     66   case HexagonII::MO_GPREL:
     67     RelocationType = MCSymbolRefExpr::VK_Hexagon_GPREL;
     68     break;
     69   case HexagonII::MO_GDGOT:
     70     RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_GOT;
     71     break;
     72   case HexagonII::MO_GDPLT:
     73     RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_PLT;
     74     break;
     75   case HexagonII::MO_IE:
     76     RelocationType = MCSymbolRefExpr::VK_Hexagon_IE;
     77     break;
     78   case HexagonII::MO_IEGOT:
     79     RelocationType = MCSymbolRefExpr::VK_Hexagon_IE_GOT;
     80     break;
     81   case HexagonII::MO_TPREL:
     82     RelocationType = MCSymbolRefExpr::VK_TPREL;
     83     break;
     84   }
     85 
     86   ME = MCSymbolRefExpr::create(Symbol, RelocationType, MC);
     87 
     88   if (!MO.isJTI() && MO.getOffset())
     89     ME = MCBinaryExpr::createAdd(ME, MCConstantExpr::create(MO.getOffset(), MC),
     90                                  MC);
     91 
     92   ME = HexagonMCExpr::create(ME, MC);
     93   HexagonMCInstrInfo::setMustExtend(*ME, MustExtend);
     94   return MCOperand::createExpr(ME);
     95 }
     96 
     97 // Create an MCInst from a MachineInstr
     98 void llvm::HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
     99                             MCInst &MCB, HexagonAsmPrinter &AP) {
    100   if (MI->getOpcode() == Hexagon::ENDLOOP0) {
    101     HexagonMCInstrInfo::setInnerLoop(MCB);
    102     return;
    103   }
    104   if (MI->getOpcode() == Hexagon::ENDLOOP1) {
    105     HexagonMCInstrInfo::setOuterLoop(MCB);
    106     return;
    107   }
    108   MCInst *MCI = new (AP.OutContext) MCInst;
    109   MCI->setOpcode(MI->getOpcode());
    110   assert(MCI->getOpcode() == static_cast<unsigned>(MI->getOpcode()) &&
    111          "MCI opcode should have been set on construction");
    112 
    113   for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) {
    114     const MachineOperand &MO = MI->getOperand(i);
    115     MCOperand MCO;
    116     bool MustExtend = MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended;
    117 
    118     switch (MO.getType()) {
    119     default:
    120       MI->print(errs());
    121       llvm_unreachable("unknown operand type");
    122     case MachineOperand::MO_RegisterMask:
    123       continue;
    124     case MachineOperand::MO_Register:
    125       // Ignore all implicit register operands.
    126       if (MO.isImplicit())
    127         continue;
    128       MCO = MCOperand::createReg(MO.getReg());
    129       break;
    130     case MachineOperand::MO_FPImmediate: {
    131       APFloat Val = MO.getFPImm()->getValueAPF();
    132       // FP immediates are used only when setting GPRs, so they may be dealt
    133       // with like regular immediates from this point on.
    134       auto Expr = HexagonMCExpr::create(
    135           MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(),
    136                                  AP.OutContext),
    137           AP.OutContext);
    138       HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
    139       MCO = MCOperand::createExpr(Expr);
    140       break;
    141     }
    142     case MachineOperand::MO_Immediate: {
    143       auto Expr = HexagonMCExpr::create(
    144           MCConstantExpr::create(MO.getImm(), AP.OutContext), AP.OutContext);
    145       HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
    146       MCO = MCOperand::createExpr(Expr);
    147       break;
    148     }
    149     case MachineOperand::MO_MachineBasicBlock: {
    150       MCExpr const *Expr = MCSymbolRefExpr::create(MO.getMBB()->getSymbol(),
    151                                                    AP.OutContext);
    152       Expr = HexagonMCExpr::create(Expr, AP.OutContext);
    153       HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
    154       MCO = MCOperand::createExpr(Expr);
    155       break;
    156     }
    157     case MachineOperand::MO_GlobalAddress:
    158       MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP, MustExtend);
    159       break;
    160     case MachineOperand::MO_ExternalSymbol:
    161       MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()),
    162                          AP, MustExtend);
    163       break;
    164     case MachineOperand::MO_JumpTableIndex:
    165       MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, MustExtend);
    166       break;
    167     case MachineOperand::MO_ConstantPoolIndex:
    168       MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, MustExtend);
    169       break;
    170     case MachineOperand::MO_BlockAddress:
    171       MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP,
    172                          MustExtend);
    173       break;
    174     }
    175 
    176     MCI->addOperand(MCO);
    177   }
    178   AP.HexagonProcessInstruction(*MCI, *MI);
    179   HexagonMCInstrInfo::extendIfNeeded(AP.OutContext, MCII, MCB, *MCI);
    180   MCB.addOperand(MCOperand::createInst(MCI));
    181 }
    182