804 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			804 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C++
		
	
	
	
//===- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions -------------===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "MCTargetDesc/HexagonMCCodeEmitter.h"
 | 
						|
#include "Hexagon.h"
 | 
						|
#include "MCTargetDesc/HexagonBaseInfo.h"
 | 
						|
#include "MCTargetDesc/HexagonFixupKinds.h"
 | 
						|
#include "MCTargetDesc/HexagonMCExpr.h"
 | 
						|
#include "MCTargetDesc/HexagonMCInstrInfo.h"
 | 
						|
#include "MCTargetDesc/HexagonMCTargetDesc.h"
 | 
						|
#include "llvm/ADT/Statistic.h"
 | 
						|
#include "llvm/MC/MCContext.h"
 | 
						|
#include "llvm/MC/MCExpr.h"
 | 
						|
#include "llvm/MC/MCFixup.h"
 | 
						|
#include "llvm/MC/MCInst.h"
 | 
						|
#include "llvm/MC/MCInstrDesc.h"
 | 
						|
#include "llvm/MC/MCInstrInfo.h"
 | 
						|
#include "llvm/MC/MCRegisterInfo.h"
 | 
						|
#include "llvm/MC/MCSubtargetInfo.h"
 | 
						|
#include "llvm/Support/Casting.h"
 | 
						|
#include "llvm/Support/Compiler.h"
 | 
						|
#include "llvm/Support/Debug.h"
 | 
						|
#include "llvm/Support/Endian.h"
 | 
						|
#include "llvm/Support/EndianStream.h"
 | 
						|
#include "llvm/Support/ErrorHandling.h"
 | 
						|
#include "llvm/Support/raw_ostream.h"
 | 
						|
#include <cassert>
 | 
						|
#include <cstddef>
 | 
						|
#include <cstdint>
 | 
						|
#include <map>
 | 
						|
#include <string>
 | 
						|
#include <vector>
 | 
						|
 | 
						|
#define DEBUG_TYPE "mccodeemitter"
 | 
						|
 | 
						|
using namespace llvm;
 | 
						|
using namespace Hexagon;
 | 
						|
 | 
						|
STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
 | 
						|
 | 
						|
static const unsigned fixup_Invalid = ~0u;
 | 
						|
 | 
						|
#define _ fixup_Invalid
 | 
						|
#define P(x) Hexagon::fixup_Hexagon##x
 | 
						|
static const std::map<unsigned, std::vector<unsigned>> ExtFixups = {
 | 
						|
  { MCSymbolRefExpr::VK_DTPREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_DTPREL_16_X),        P(_DTPREL_11_X),
 | 
						|
      P(_DTPREL_11_X),  P(_9_X),        _,                      P(_DTPREL_11_X),
 | 
						|
      P(_DTPREL_16_X),  _,              _,                      _,
 | 
						|
      P(_DTPREL_16_X),  _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_DTPREL_32_6_X) }},
 | 
						|
  { MCSymbolRefExpr::VK_GOT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_GOT_11_X),           _ /* [1] */,
 | 
						|
      _ /* [1] */,      P(_9_X),        _,                      P(_GOT_11_X),
 | 
						|
      P(_GOT_16_X),     _,              _,                      _,
 | 
						|
      P(_GOT_16_X),     _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_GOT_32_6_X)    }},
 | 
						|
  { MCSymbolRefExpr::VK_GOTREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_GOTREL_11_X),        P(_GOTREL_11_X),
 | 
						|
      P(_GOTREL_11_X),  P(_9_X),        _,                      P(_GOTREL_11_X),
 | 
						|
      P(_GOTREL_16_X),  _,              _,                      _,
 | 
						|
      P(_GOTREL_16_X),  _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_GOTREL_32_6_X) }},
 | 
						|
  { MCSymbolRefExpr::VK_TPREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_TPREL_16_X),         P(_TPREL_11_X),
 | 
						|
      P(_TPREL_11_X),   P(_9_X),        _,                      P(_TPREL_11_X),
 | 
						|
      P(_TPREL_16_X),   _,              _,                      _,
 | 
						|
      P(_TPREL_16_X),   _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_TPREL_32_6_X)  }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_GD_GOT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_GD_GOT_16_X),        P(_GD_GOT_11_X),
 | 
						|
      P(_GD_GOT_11_X),  P(_9_X),        _,                      P(_GD_GOT_11_X),
 | 
						|
      P(_GD_GOT_16_X),  _,              _,                      _,
 | 
						|
      P(_GD_GOT_16_X),  _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_GD_GOT_32_6_X) }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_GD_PLT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                P(_9_X),        _,                      P(_GD_PLT_B22_PCREL_X),
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_GD_PLT_B22_PCREL_X), _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _                 }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_IE,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_IE_16_X),            _,
 | 
						|
      _,                P(_9_X),        _,                      _,
 | 
						|
      P(_IE_16_X),      _,              _,                      _,
 | 
						|
      P(_IE_16_X),      _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_IE_32_6_X)     }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_IE_GOT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_IE_GOT_11_X),        P(_IE_GOT_11_X),
 | 
						|
      P(_IE_GOT_11_X),  P(_9_X),        _,                      P(_IE_GOT_11_X),
 | 
						|
      P(_IE_GOT_16_X),  _,              _,                      _,
 | 
						|
      P(_IE_GOT_16_X),  _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_IE_GOT_32_6_X) }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_LD_GOT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_LD_GOT_11_X),        P(_LD_GOT_11_X),
 | 
						|
      P(_LD_GOT_11_X),  P(_9_X),        _,                      P(_LD_GOT_11_X),
 | 
						|
      P(_LD_GOT_16_X),  _,              _,                      _,
 | 
						|
      P(_LD_GOT_16_X),  _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_LD_GOT_32_6_X) }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_LD_PLT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                P(_9_X),        _,                      P(_LD_PLT_B22_PCREL_X),
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_LD_PLT_B22_PCREL_X), _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _                 }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_PCREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_6_PCREL_X),          _,
 | 
						|
      _,                P(_9_X),        _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_32_PCREL)      }},
 | 
						|
  { MCSymbolRefExpr::VK_None,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_6_X),                P(_8_X),
 | 
						|
      P(_8_X),          P(_9_X),        P(_10_X),               P(_11_X),
 | 
						|
      P(_12_X),         P(_B13_PCREL),  _,                      P(_B15_PCREL_X),
 | 
						|
      P(_16_X),         _,              _,                      _,
 | 
						|
      _,                _,              P(_B22_PCREL_X),        _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_32_6_X)        }},
 | 
						|
};
 | 
						|
// [1] The fixup is GOT_16_X for signed values and GOT_11_X for unsigned.
 | 
						|
 | 
						|
static const std::map<unsigned, std::vector<unsigned>> StdFixups = {
 | 
						|
  { MCSymbolRefExpr::VK_DTPREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_DTPREL_16),    _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_DTPREL_32)     }},
 | 
						|
  { MCSymbolRefExpr::VK_GOT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_GOT_32)        }},
 | 
						|
  { MCSymbolRefExpr::VK_GOTREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _ /* [2] */,      _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_GOTREL_32)     }},
 | 
						|
  { MCSymbolRefExpr::VK_PLT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_PLT_B22_PCREL),      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _                 }},
 | 
						|
  { MCSymbolRefExpr::VK_TPREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      P(_TPREL_11_X),
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_TPREL_16),     _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_TPREL_32)      }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_GD_GOT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_GD_GOT_16),    _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_GD_GOT_32)     }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_GD_PLT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_GD_PLT_B22_PCREL),   _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _                 }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_GPREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_GPREL16_0),    _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _                 }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_HI16,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_HI16),         _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _                 }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_IE,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_IE_32)         }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_IE_GOT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_IE_GOT_16),    _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_IE_GOT_32)     }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_LD_GOT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_LD_GOT_16),    _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_LD_GOT_32)     }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_LD_PLT,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_LD_PLT_B22_PCREL),   _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _                 }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_LO16,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_LO16),         _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _                 }},
 | 
						|
  { MCSymbolRefExpr::VK_Hexagon_PCREL,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_32_PCREL)      }},
 | 
						|
  { MCSymbolRefExpr::VK_None,
 | 
						|
    { _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                P(_B13_PCREL),  _,                      P(_B15_PCREL),
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              P(_B22_PCREL),          _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      _,                _,              _,                      _,
 | 
						|
      P(_32)            }},
 | 
						|
};
 | 
						|
//
 | 
						|
// [2] The actual fixup is LO16 or HI16, depending on the instruction.
 | 
						|
#undef P
 | 
						|
#undef _
 | 
						|
 | 
						|
uint32_t HexagonMCCodeEmitter::parseBits(size_t Last, MCInst const &MCB,
 | 
						|
                                         MCInst const &MCI) const {
 | 
						|
  bool Duplex = HexagonMCInstrInfo::isDuplex(MCII, MCI);
 | 
						|
  if (State.Index == 0) {
 | 
						|
    if (HexagonMCInstrInfo::isInnerLoop(MCB)) {
 | 
						|
      assert(!Duplex);
 | 
						|
      assert(State.Index != Last);
 | 
						|
      return HexagonII::INST_PARSE_LOOP_END;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (State.Index == 1) {
 | 
						|
    if (HexagonMCInstrInfo::isOuterLoop(MCB)) {
 | 
						|
      assert(!Duplex);
 | 
						|
      assert(State.Index != Last);
 | 
						|
      return HexagonII::INST_PARSE_LOOP_END;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (Duplex) {
 | 
						|
    assert(State.Index == Last);
 | 
						|
    return HexagonII::INST_PARSE_DUPLEX;
 | 
						|
  }
 | 
						|
  if (State.Index == Last)
 | 
						|
    return HexagonII::INST_PARSE_PACKET_END;
 | 
						|
  return HexagonII::INST_PARSE_NOT_END;
 | 
						|
}
 | 
						|
 | 
						|
/// Emit the bundle.
 | 
						|
void HexagonMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
 | 
						|
                                             SmallVectorImpl<MCFixup> &Fixups,
 | 
						|
                                             const MCSubtargetInfo &STI) const {
 | 
						|
  MCInst &HMB = const_cast<MCInst &>(MI);
 | 
						|
 | 
						|
  assert(HexagonMCInstrInfo::isBundle(HMB));
 | 
						|
  LLVM_DEBUG(dbgs() << "Encoding bundle\n";);
 | 
						|
  State.Addend = 0;
 | 
						|
  State.Extended = false;
 | 
						|
  State.Bundle = &MI;
 | 
						|
  State.Index = 0;
 | 
						|
  size_t Last = HexagonMCInstrInfo::bundleSize(HMB) - 1;
 | 
						|
  uint64_t Features = computeAvailableFeatures(STI.getFeatureBits());
 | 
						|
 | 
						|
  for (auto &I : HexagonMCInstrInfo::bundleInstructions(HMB)) {
 | 
						|
    MCInst &HMI = const_cast<MCInst &>(*I.getInst());
 | 
						|
    verifyInstructionPredicates(HMI, Features);
 | 
						|
 | 
						|
    EncodeSingleInstruction(HMI, OS, Fixups, STI, parseBits(Last, HMB, HMI));
 | 
						|
    State.Extended = HexagonMCInstrInfo::isImmext(HMI);
 | 
						|
    State.Addend += HEXAGON_INSTR_SIZE;
 | 
						|
    ++State.Index;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
static bool RegisterMatches(unsigned Consumer, unsigned Producer,
 | 
						|
                            unsigned Producer2) {
 | 
						|
  if (Consumer == Producer)
 | 
						|
    return true;
 | 
						|
  if (Consumer == Producer2)
 | 
						|
    return true;
 | 
						|
  // Calculate if we're a single vector consumer referencing a double producer
 | 
						|
  if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
 | 
						|
    if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31)
 | 
						|
      return ((Consumer - Hexagon::V0) >> 1) == (Producer - Hexagon::W0);
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
/// EncodeSingleInstruction - Emit a single
 | 
						|
void HexagonMCCodeEmitter::EncodeSingleInstruction(const MCInst &MI,
 | 
						|
      raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
 | 
						|
      const MCSubtargetInfo &STI, uint32_t Parse) const {
 | 
						|
  assert(!HexagonMCInstrInfo::isBundle(MI));
 | 
						|
  uint64_t Binary;
 | 
						|
 | 
						|
  // Pseudo instructions don't get encoded and shouldn't be here
 | 
						|
  // in the first place!
 | 
						|
  assert(!HexagonMCInstrInfo::getDesc(MCII, MI).isPseudo() &&
 | 
						|
         "pseudo-instruction found");
 | 
						|
  LLVM_DEBUG(dbgs() << "Encoding insn `"
 | 
						|
                    << HexagonMCInstrInfo::getName(MCII, MI) << "'\n");
 | 
						|
 | 
						|
  Binary = getBinaryCodeForInstr(MI, Fixups, STI);
 | 
						|
  unsigned Opc = MI.getOpcode();
 | 
						|
 | 
						|
  // Check for unimplemented instructions. Immediate extenders
 | 
						|
  // are encoded as zero, so they need to be accounted for.
 | 
						|
  if (!Binary && Opc != DuplexIClass0 && Opc != A4_ext) {
 | 
						|
    LLVM_DEBUG(dbgs() << "Unimplemented inst `"
 | 
						|
                      << HexagonMCInstrInfo::getName(MCII, MI) << "'\n");
 | 
						|
    llvm_unreachable("Unimplemented Instruction");
 | 
						|
  }
 | 
						|
  Binary |= Parse;
 | 
						|
 | 
						|
  // if we need to emit a duplexed instruction
 | 
						|
  if (Opc >= Hexagon::DuplexIClass0 && Opc <= Hexagon::DuplexIClassF) {
 | 
						|
    assert(Parse == HexagonII::INST_PARSE_DUPLEX &&
 | 
						|
           "Emitting duplex without duplex parse bits");
 | 
						|
    unsigned DupIClass = MI.getOpcode() - Hexagon::DuplexIClass0;
 | 
						|
    // 29 is the bit position.
 | 
						|
    // 0b1110 =0xE bits are masked off and down shifted by 1 bit.
 | 
						|
    // Last bit is moved to bit position 13
 | 
						|
    Binary = ((DupIClass & 0xE) << (29 - 1)) | ((DupIClass & 0x1) << 13);
 | 
						|
 | 
						|
    const MCInst *Sub0 = MI.getOperand(0).getInst();
 | 
						|
    const MCInst *Sub1 = MI.getOperand(1).getInst();
 | 
						|
 | 
						|
    // Get subinstruction slot 0.
 | 
						|
    unsigned SubBits0 = getBinaryCodeForInstr(*Sub0, Fixups, STI);
 | 
						|
    // Get subinstruction slot 1.
 | 
						|
    State.SubInst1 = true;
 | 
						|
    unsigned SubBits1 = getBinaryCodeForInstr(*Sub1, Fixups, STI);
 | 
						|
    State.SubInst1 = false;
 | 
						|
 | 
						|
    Binary |= SubBits0 | (SubBits1 << 16);
 | 
						|
  }
 | 
						|
  support::endian::write<uint32_t>(OS, Binary, support::little);
 | 
						|
  ++MCNumEmitted;
 | 
						|
}
 | 
						|
 | 
						|
LLVM_ATTRIBUTE_NORETURN
 | 
						|
static void raise_relocation_error(unsigned Width, unsigned Kind) {
 | 
						|
  std::string Text;
 | 
						|
  raw_string_ostream Stream(Text);
 | 
						|
  Stream << "Unrecognized relocation combination: width=" << Width
 | 
						|
         << " kind=" << Kind;
 | 
						|
  report_fatal_error(Stream.str());
 | 
						|
}
 | 
						|
 | 
						|
/// Some insns are not extended and thus have no bits. These cases require
 | 
						|
/// a more brute force method for determining the correct relocation.
 | 
						|
Hexagon::Fixups HexagonMCCodeEmitter::getFixupNoBits(
 | 
						|
      MCInstrInfo const &MCII, const MCInst &MI, const MCOperand &MO,
 | 
						|
      const MCSymbolRefExpr::VariantKind VarKind) const {
 | 
						|
  const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI);
 | 
						|
  unsigned InsnType = HexagonMCInstrInfo::getType(MCII, MI);
 | 
						|
  using namespace Hexagon;
 | 
						|
 | 
						|
  if (InsnType == HexagonII::TypeEXTENDER) {
 | 
						|
    if (VarKind == MCSymbolRefExpr::VK_None) {
 | 
						|
      auto Instrs = HexagonMCInstrInfo::bundleInstructions(*State.Bundle);
 | 
						|
      for (auto I = Instrs.begin(), N = Instrs.end(); I != N; ++I) {
 | 
						|
        if (I->getInst() != &MI)
 | 
						|
          continue;
 | 
						|
        assert(I+1 != N && "Extender cannot be last in packet");
 | 
						|
        const MCInst &NextI = *(I+1)->getInst();
 | 
						|
        const MCInstrDesc &NextD = HexagonMCInstrInfo::getDesc(MCII, NextI);
 | 
						|
        if (NextD.isBranch() || NextD.isCall() ||
 | 
						|
            HexagonMCInstrInfo::getType(MCII, NextI) == HexagonII::TypeCR)
 | 
						|
          return fixup_Hexagon_B32_PCREL_X;
 | 
						|
        return fixup_Hexagon_32_6_X;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    static const std::map<unsigned,unsigned> Relocs = {
 | 
						|
      { MCSymbolRefExpr::VK_GOTREL,         fixup_Hexagon_GOTREL_32_6_X },
 | 
						|
      { MCSymbolRefExpr::VK_GOT,            fixup_Hexagon_GOT_32_6_X },
 | 
						|
      { MCSymbolRefExpr::VK_TPREL,          fixup_Hexagon_TPREL_32_6_X },
 | 
						|
      { MCSymbolRefExpr::VK_DTPREL,         fixup_Hexagon_DTPREL_32_6_X },
 | 
						|
      { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_32_6_X },
 | 
						|
      { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_32_6_X },
 | 
						|
      { MCSymbolRefExpr::VK_Hexagon_IE,     fixup_Hexagon_IE_32_6_X },
 | 
						|
      { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_32_6_X },
 | 
						|
      { MCSymbolRefExpr::VK_Hexagon_PCREL,  fixup_Hexagon_B32_PCREL_X },
 | 
						|
      { MCSymbolRefExpr::VK_Hexagon_GD_PLT, fixup_Hexagon_GD_PLT_B32_PCREL_X },
 | 
						|
      { MCSymbolRefExpr::VK_Hexagon_LD_PLT, fixup_Hexagon_LD_PLT_B32_PCREL_X },
 | 
						|
    };
 | 
						|
 | 
						|
    auto F = Relocs.find(VarKind);
 | 
						|
    if (F != Relocs.end())
 | 
						|
      return Hexagon::Fixups(F->second);
 | 
						|
    raise_relocation_error(0, VarKind);
 | 
						|
  }
 | 
						|
 | 
						|
  if (MCID.isBranch())
 | 
						|
    return fixup_Hexagon_B13_PCREL;
 | 
						|
 | 
						|
  static const std::map<unsigned,unsigned> RelocsLo = {
 | 
						|
    { MCSymbolRefExpr::VK_GOT,            fixup_Hexagon_GOT_LO16 },
 | 
						|
    { MCSymbolRefExpr::VK_GOTREL,         fixup_Hexagon_GOTREL_LO16 },
 | 
						|
    { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_LO16 },
 | 
						|
    { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_LO16 },
 | 
						|
    { MCSymbolRefExpr::VK_Hexagon_IE,     fixup_Hexagon_IE_LO16 },
 | 
						|
    { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_LO16 },
 | 
						|
    { MCSymbolRefExpr::VK_TPREL,          fixup_Hexagon_TPREL_LO16 },
 | 
						|
    { MCSymbolRefExpr::VK_DTPREL,         fixup_Hexagon_DTPREL_LO16 },
 | 
						|
    { MCSymbolRefExpr::VK_None,           fixup_Hexagon_LO16 },
 | 
						|
  };
 | 
						|
 | 
						|
  static const std::map<unsigned,unsigned> RelocsHi = {
 | 
						|
    { MCSymbolRefExpr::VK_GOT,            fixup_Hexagon_GOT_HI16 },
 | 
						|
    { MCSymbolRefExpr::VK_GOTREL,         fixup_Hexagon_GOTREL_HI16 },
 | 
						|
    { MCSymbolRefExpr::VK_Hexagon_GD_GOT, fixup_Hexagon_GD_GOT_HI16 },
 | 
						|
    { MCSymbolRefExpr::VK_Hexagon_LD_GOT, fixup_Hexagon_LD_GOT_HI16 },
 | 
						|
    { MCSymbolRefExpr::VK_Hexagon_IE,     fixup_Hexagon_IE_HI16 },
 | 
						|
    { MCSymbolRefExpr::VK_Hexagon_IE_GOT, fixup_Hexagon_IE_GOT_HI16 },
 | 
						|
    { MCSymbolRefExpr::VK_TPREL,          fixup_Hexagon_TPREL_HI16 },
 | 
						|
    { MCSymbolRefExpr::VK_DTPREL,         fixup_Hexagon_DTPREL_HI16 },
 | 
						|
    { MCSymbolRefExpr::VK_None,           fixup_Hexagon_HI16 },
 | 
						|
  };
 | 
						|
 | 
						|
  switch (MCID.getOpcode()) {
 | 
						|
    case Hexagon::LO:
 | 
						|
    case Hexagon::A2_tfril: {
 | 
						|
      auto F = RelocsLo.find(VarKind);
 | 
						|
      if (F != RelocsLo.end())
 | 
						|
        return Hexagon::Fixups(F->second);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    case Hexagon::HI:
 | 
						|
    case Hexagon::A2_tfrih: {
 | 
						|
      auto F = RelocsHi.find(VarKind);
 | 
						|
      if (F != RelocsHi.end())
 | 
						|
        return Hexagon::Fixups(F->second);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  raise_relocation_error(0, VarKind);
 | 
						|
}
 | 
						|
 | 
						|
static bool isPCRel(unsigned Kind) {
 | 
						|
  switch (Kind){
 | 
						|
  case fixup_Hexagon_B22_PCREL:
 | 
						|
  case fixup_Hexagon_B15_PCREL:
 | 
						|
  case fixup_Hexagon_B7_PCREL:
 | 
						|
  case fixup_Hexagon_B13_PCREL:
 | 
						|
  case fixup_Hexagon_B9_PCREL:
 | 
						|
  case fixup_Hexagon_B32_PCREL_X:
 | 
						|
  case fixup_Hexagon_B22_PCREL_X:
 | 
						|
  case fixup_Hexagon_B15_PCREL_X:
 | 
						|
  case fixup_Hexagon_B13_PCREL_X:
 | 
						|
  case fixup_Hexagon_B9_PCREL_X:
 | 
						|
  case fixup_Hexagon_B7_PCREL_X:
 | 
						|
  case fixup_Hexagon_32_PCREL:
 | 
						|
  case fixup_Hexagon_PLT_B22_PCREL:
 | 
						|
  case fixup_Hexagon_GD_PLT_B22_PCREL:
 | 
						|
  case fixup_Hexagon_LD_PLT_B22_PCREL:
 | 
						|
  case fixup_Hexagon_GD_PLT_B22_PCREL_X:
 | 
						|
  case fixup_Hexagon_LD_PLT_B22_PCREL_X:
 | 
						|
  case fixup_Hexagon_6_PCREL_X:
 | 
						|
    return true;
 | 
						|
  default:
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI,
 | 
						|
      const MCOperand &MO, const MCExpr *ME, SmallVectorImpl<MCFixup> &Fixups,
 | 
						|
      const MCSubtargetInfo &STI) const {
 | 
						|
  if (isa<HexagonMCExpr>(ME))
 | 
						|
    ME = &HexagonMCInstrInfo::getExpr(*ME);
 | 
						|
  int64_t Value;
 | 
						|
  if (ME->evaluateAsAbsolute(Value)) {
 | 
						|
    bool InstExtendable = HexagonMCInstrInfo::isExtendable(MCII, MI) ||
 | 
						|
                          HexagonMCInstrInfo::isExtended(MCII, MI);
 | 
						|
    // Only sub-instruction #1 can be extended in a duplex. If MI is a
 | 
						|
    // sub-instruction #0, it is not extended even if Extended is true
 | 
						|
    // (it can be true for the duplex as a whole).
 | 
						|
    bool IsSub0 = HexagonMCInstrInfo::isSubInstruction(MI) && !State.SubInst1;
 | 
						|
    if (State.Extended && InstExtendable && !IsSub0) {
 | 
						|
      unsigned OpIdx = ~0u;
 | 
						|
      for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
 | 
						|
        if (&MO != &MI.getOperand(I))
 | 
						|
          continue;
 | 
						|
        OpIdx = I;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      assert(OpIdx != ~0u);
 | 
						|
      if (OpIdx == HexagonMCInstrInfo::getExtendableOp(MCII, MI)) {
 | 
						|
        unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
 | 
						|
        Value = (Value & 0x3f) << Shift;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return Value;
 | 
						|
  }
 | 
						|
  assert(ME->getKind() == MCExpr::SymbolRef ||
 | 
						|
         ME->getKind() == MCExpr::Binary);
 | 
						|
  if (ME->getKind() == MCExpr::Binary) {
 | 
						|
    MCBinaryExpr const *Binary = cast<MCBinaryExpr>(ME);
 | 
						|
    getExprOpValue(MI, MO, Binary->getLHS(), Fixups, STI);
 | 
						|
    getExprOpValue(MI, MO, Binary->getRHS(), Fixups, STI);
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  unsigned FixupKind = fixup_Invalid;
 | 
						|
  const MCSymbolRefExpr *MCSRE = static_cast<const MCSymbolRefExpr *>(ME);
 | 
						|
  const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MI);
 | 
						|
  unsigned FixupWidth = HexagonMCInstrInfo::getExtentBits(MCII, MI) -
 | 
						|
                        HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
 | 
						|
  MCSymbolRefExpr::VariantKind VarKind = MCSRE->getKind();
 | 
						|
  unsigned Opc = MCID.getOpcode();
 | 
						|
  unsigned IType = HexagonMCInstrInfo::getType(MCII, MI);
 | 
						|
 | 
						|
  LLVM_DEBUG(dbgs() << "----------------------------------------\n"
 | 
						|
                    << "Opcode Name: " << HexagonMCInstrInfo::getName(MCII, MI)
 | 
						|
                    << "\nOpcode: " << Opc << "\nRelocation bits: "
 | 
						|
                    << FixupWidth << "\nAddend: " << State.Addend
 | 
						|
                    << "\nVariant: " << unsigned(VarKind)
 | 
						|
                    << "\n----------------------------------------\n");
 | 
						|
 | 
						|
  // Pick the applicable fixup kind for the symbol.
 | 
						|
  // Handle special cases first, the rest will be looked up in the tables.
 | 
						|
 | 
						|
  if (FixupWidth == 16 && !State.Extended) {
 | 
						|
    if (VarKind == MCSymbolRefExpr::VK_None) {
 | 
						|
      if (HexagonMCInstrInfo::s27_2_reloc(*MO.getExpr())) {
 | 
						|
        // A2_iconst.
 | 
						|
        FixupKind = Hexagon::fixup_Hexagon_27_REG;
 | 
						|
      } else {
 | 
						|
        // Look for GP-relative fixups.
 | 
						|
        unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
 | 
						|
        static const Hexagon::Fixups GPRelFixups[] = {
 | 
						|
          Hexagon::fixup_Hexagon_GPREL16_0, Hexagon::fixup_Hexagon_GPREL16_1,
 | 
						|
          Hexagon::fixup_Hexagon_GPREL16_2, Hexagon::fixup_Hexagon_GPREL16_3
 | 
						|
        };
 | 
						|
        assert(Shift < array_lengthof(GPRelFixups));
 | 
						|
        auto UsesGP = [] (const MCInstrDesc &D) {
 | 
						|
          for (const MCPhysReg *U = D.getImplicitUses(); U && *U; ++U)
 | 
						|
            if (*U == Hexagon::GP)
 | 
						|
              return true;
 | 
						|
          return false;
 | 
						|
        };
 | 
						|
        if (UsesGP(MCID))
 | 
						|
          FixupKind = GPRelFixups[Shift];
 | 
						|
      }
 | 
						|
    } else if (VarKind == MCSymbolRefExpr::VK_GOTREL) {
 | 
						|
      // Select between LO/HI.
 | 
						|
      if (Opc == Hexagon::LO)
 | 
						|
        FixupKind = Hexagon::fixup_Hexagon_GOTREL_LO16;
 | 
						|
      else if (Opc == Hexagon::HI)
 | 
						|
        FixupKind = Hexagon::fixup_Hexagon_GOTREL_HI16;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    bool BranchOrCR = MCID.isBranch() || IType == HexagonII::TypeCR;
 | 
						|
    switch (FixupWidth) {
 | 
						|
      case 9:
 | 
						|
        if (BranchOrCR)
 | 
						|
          FixupKind = State.Extended ? Hexagon::fixup_Hexagon_B9_PCREL_X
 | 
						|
                                     : Hexagon::fixup_Hexagon_B9_PCREL;
 | 
						|
        break;
 | 
						|
      case 8:
 | 
						|
      case 7:
 | 
						|
        if (State.Extended && VarKind == MCSymbolRefExpr::VK_GOT)
 | 
						|
          FixupKind = HexagonMCInstrInfo::isExtentSigned(MCII, MI)
 | 
						|
                        ? Hexagon::fixup_Hexagon_GOT_16_X
 | 
						|
                        : Hexagon::fixup_Hexagon_GOT_11_X;
 | 
						|
        else if (FixupWidth == 7 && BranchOrCR)
 | 
						|
          FixupKind = State.Extended ? Hexagon::fixup_Hexagon_B7_PCREL_X
 | 
						|
                                     : Hexagon::fixup_Hexagon_B7_PCREL;
 | 
						|
        break;
 | 
						|
      case 0:
 | 
						|
        FixupKind = getFixupNoBits(MCII, MI, MO, VarKind);
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (FixupKind == fixup_Invalid) {
 | 
						|
    const auto &FixupTable = State.Extended ? ExtFixups : StdFixups;
 | 
						|
 | 
						|
    auto FindVK = FixupTable.find(VarKind);
 | 
						|
    if (FindVK != FixupTable.end())
 | 
						|
      FixupKind = FindVK->second[FixupWidth];
 | 
						|
  }
 | 
						|
 | 
						|
  if (FixupKind == fixup_Invalid)
 | 
						|
    raise_relocation_error(FixupWidth, VarKind);
 | 
						|
 | 
						|
  const MCExpr *FixupExpr = MO.getExpr();
 | 
						|
  if (State.Addend != 0 && isPCRel(FixupKind)) {
 | 
						|
    const MCExpr *C = MCConstantExpr::create(State.Addend, MCT);
 | 
						|
    FixupExpr = MCBinaryExpr::createAdd(FixupExpr, C, MCT);
 | 
						|
  }
 | 
						|
 | 
						|
  MCFixup Fixup = MCFixup::create(State.Addend, FixupExpr,
 | 
						|
                                  MCFixupKind(FixupKind), MI.getLoc());
 | 
						|
  Fixups.push_back(Fixup);
 | 
						|
  // All of the information is in the fixup.
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
unsigned
 | 
						|
HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO,
 | 
						|
                                        SmallVectorImpl<MCFixup> &Fixups,
 | 
						|
                                        MCSubtargetInfo const &STI) const {
 | 
						|
#ifndef NDEBUG
 | 
						|
  size_t OperandNumber = ~0U;
 | 
						|
  for (unsigned i = 0, n = MI.getNumOperands(); i < n; ++i)
 | 
						|
    if (&MI.getOperand(i) == &MO) {
 | 
						|
      OperandNumber = i;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  assert((OperandNumber != ~0U) && "Operand not found");
 | 
						|
#endif
 | 
						|
 | 
						|
  if (HexagonMCInstrInfo::isNewValue(MCII, MI) &&
 | 
						|
      &MO == &HexagonMCInstrInfo::getNewValueOperand(MCII, MI)) {
 | 
						|
    // Calculate the new value distance to the associated producer
 | 
						|
    unsigned SOffset = 0;
 | 
						|
    unsigned VOffset = 0;
 | 
						|
    unsigned UseReg = MO.getReg();
 | 
						|
    unsigned DefReg1, DefReg2;
 | 
						|
 | 
						|
    auto Instrs = HexagonMCInstrInfo::bundleInstructions(*State.Bundle);
 | 
						|
    const MCOperand *I = Instrs.begin() + State.Index - 1;
 | 
						|
 | 
						|
    for (;; --I) {
 | 
						|
      assert(I != Instrs.begin() - 1 && "Couldn't find producer");
 | 
						|
      MCInst const &Inst = *I->getInst();
 | 
						|
      if (HexagonMCInstrInfo::isImmext(Inst))
 | 
						|
        continue;
 | 
						|
 | 
						|
      DefReg1 = DefReg2 = 0;
 | 
						|
      ++SOffset;
 | 
						|
      if (HexagonMCInstrInfo::isVector(MCII, Inst)) {
 | 
						|
        // Vector instructions don't count scalars.
 | 
						|
        ++VOffset;
 | 
						|
      }
 | 
						|
      if (HexagonMCInstrInfo::hasNewValue(MCII, Inst))
 | 
						|
        DefReg1 = HexagonMCInstrInfo::getNewValueOperand(MCII, Inst).getReg();
 | 
						|
      if (HexagonMCInstrInfo::hasNewValue2(MCII, Inst))
 | 
						|
        DefReg2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, Inst).getReg();
 | 
						|
      if (!RegisterMatches(UseReg, DefReg1, DefReg2)) {
 | 
						|
        // This isn't the register we're looking for
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
      if (!HexagonMCInstrInfo::isPredicated(MCII, Inst)) {
 | 
						|
        // Producer is unpredicated
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      assert(HexagonMCInstrInfo::isPredicated(MCII, MI) &&
 | 
						|
             "Unpredicated consumer depending on predicated producer");
 | 
						|
      if (HexagonMCInstrInfo::isPredicatedTrue(MCII, Inst) ==
 | 
						|
          HexagonMCInstrInfo::isPredicatedTrue(MCII, MI))
 | 
						|
        // Producer predicate sense matched ours.
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    // Hexagon PRM 10.11 Construct Nt from distance
 | 
						|
    unsigned Offset = HexagonMCInstrInfo::isVector(MCII, MI) ? VOffset
 | 
						|
                                                             : SOffset;
 | 
						|
    Offset <<= 1;
 | 
						|
    Offset |= HexagonMCInstrInfo::SubregisterBit(UseReg, DefReg1, DefReg2);
 | 
						|
    return Offset;
 | 
						|
  }
 | 
						|
 | 
						|
  assert(!MO.isImm());
 | 
						|
  if (MO.isReg()) {
 | 
						|
    unsigned Reg = MO.getReg();
 | 
						|
    if (HexagonMCInstrInfo::isSubInstruction(MI) ||
 | 
						|
        HexagonMCInstrInfo::getType(MCII, MI) == HexagonII::TypeCJ)
 | 
						|
      return HexagonMCInstrInfo::getDuplexRegisterNumbering(Reg);
 | 
						|
    return MCT.getRegisterInfo()->getEncodingValue(Reg);
 | 
						|
  }
 | 
						|
 | 
						|
  return getExprOpValue(MI, MO, MO.getExpr(), Fixups, STI);
 | 
						|
}
 | 
						|
 | 
						|
MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII,
 | 
						|
                                                MCRegisterInfo const &MRI,
 | 
						|
                                                MCContext &MCT) {
 | 
						|
  return new HexagonMCCodeEmitter(MII, MCT);
 | 
						|
}
 | 
						|
 | 
						|
#define ENABLE_INSTR_PREDICATE_VERIFIER
 | 
						|
#include "HexagonGenMCCodeEmitter.inc"
 |