Path: blob/main/contrib/llvm-project/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
35294 views
//===-- MSP430MCCodeEmitter.cpp - Convert MSP430 code to machine code -----===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the MSP430MCCodeEmitter class.9//10//===----------------------------------------------------------------------===//1112#include "MSP430.h"13#include "MCTargetDesc/MSP430MCTargetDesc.h"14#include "MCTargetDesc/MSP430FixupKinds.h"1516#include "llvm/ADT/APFloat.h"17#include "llvm/ADT/SmallVector.h"18#include "llvm/MC/MCCodeEmitter.h"19#include "llvm/MC/MCContext.h"20#include "llvm/MC/MCExpr.h"21#include "llvm/MC/MCFixup.h"22#include "llvm/MC/MCInst.h"23#include "llvm/MC/MCInstrInfo.h"24#include "llvm/MC/MCRegisterInfo.h"25#include "llvm/MC/MCSubtargetInfo.h"26#include "llvm/Support/Endian.h"27#include "llvm/Support/EndianStream.h"28#include "llvm/Support/raw_ostream.h"2930#define DEBUG_TYPE "mccodeemitter"3132namespace llvm {3334class MSP430MCCodeEmitter : public MCCodeEmitter {35MCContext &Ctx;36MCInstrInfo const &MCII;3738// Offset keeps track of current word number being emitted39// inside a particular instruction.40mutable unsigned Offset;4142/// TableGen'erated function for getting the binary encoding for an43/// instruction.44uint64_t getBinaryCodeForInstr(const MCInst &MI,45SmallVectorImpl<MCFixup> &Fixups,46const MCSubtargetInfo &STI) const;4748/// Returns the binary encoding of operands.49///50/// If an operand requires relocation, the relocation is recorded51/// and zero is returned.52unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,53SmallVectorImpl<MCFixup> &Fixups,54const MCSubtargetInfo &STI) const;5556unsigned getMemOpValue(const MCInst &MI, unsigned Op,57SmallVectorImpl<MCFixup> &Fixups,58const MCSubtargetInfo &STI) const;5960unsigned getPCRelImmOpValue(const MCInst &MI, unsigned Op,61SmallVectorImpl<MCFixup> &Fixups,62const MCSubtargetInfo &STI) const;6364unsigned getCGImmOpValue(const MCInst &MI, unsigned Op,65SmallVectorImpl<MCFixup> &Fixups,66const MCSubtargetInfo &STI) const;6768unsigned getCCOpValue(const MCInst &MI, unsigned Op,69SmallVectorImpl<MCFixup> &Fixups,70const MCSubtargetInfo &STI) const;7172public:73MSP430MCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)74: Ctx(ctx), MCII(MCII) {}7576void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,77SmallVectorImpl<MCFixup> &Fixups,78const MCSubtargetInfo &STI) const override;79};8081void MSP430MCCodeEmitter::encodeInstruction(const MCInst &MI,82SmallVectorImpl<char> &CB,83SmallVectorImpl<MCFixup> &Fixups,84const MCSubtargetInfo &STI) const {85const MCInstrDesc &Desc = MCII.get(MI.getOpcode());86// Get byte count of instruction.87unsigned Size = Desc.getSize();8889// Initialize fixup offset90Offset = 2;9192uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI);93size_t WordCount = Size / 2;9495while (WordCount--) {96support::endian::write(CB, (uint16_t)BinaryOpCode,97llvm::endianness::little);98BinaryOpCode >>= 16;99}100}101102unsigned MSP430MCCodeEmitter::getMachineOpValue(const MCInst &MI,103const MCOperand &MO,104SmallVectorImpl<MCFixup> &Fixups,105const MCSubtargetInfo &STI) const {106if (MO.isReg())107return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());108109if (MO.isImm()) {110Offset += 2;111return MO.getImm();112}113114assert(MO.isExpr() && "Expected expr operand");115Fixups.push_back(MCFixup::create(Offset, MO.getExpr(),116static_cast<MCFixupKind>(MSP430::fixup_16_byte), MI.getLoc()));117Offset += 2;118return 0;119}120121unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op,122SmallVectorImpl<MCFixup> &Fixups,123const MCSubtargetInfo &STI) const {124const MCOperand &MO1 = MI.getOperand(Op);125assert(MO1.isReg() && "Register operand expected");126unsigned Reg = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());127128const MCOperand &MO2 = MI.getOperand(Op + 1);129if (MO2.isImm()) {130Offset += 2;131return ((unsigned)MO2.getImm() << 4) | Reg;132}133134assert(MO2.isExpr() && "Expr operand expected");135MSP430::Fixups FixupKind;136switch (Reg) {137case 0:138FixupKind = MSP430::fixup_16_pcrel_byte;139break;140case 2:141FixupKind = MSP430::fixup_16_byte;142break;143default:144FixupKind = MSP430::fixup_16_byte;145break;146}147Fixups.push_back(MCFixup::create(Offset, MO2.getExpr(),148static_cast<MCFixupKind>(FixupKind), MI.getLoc()));149Offset += 2;150return Reg;151}152153unsigned MSP430MCCodeEmitter::getPCRelImmOpValue(const MCInst &MI, unsigned Op,154SmallVectorImpl<MCFixup> &Fixups,155const MCSubtargetInfo &STI) const {156const MCOperand &MO = MI.getOperand(Op);157if (MO.isImm())158return MO.getImm();159160assert(MO.isExpr() && "Expr operand expected");161Fixups.push_back(MCFixup::create(0, MO.getExpr(),162static_cast<MCFixupKind>(MSP430::fixup_10_pcrel), MI.getLoc()));163return 0;164}165166unsigned MSP430MCCodeEmitter::getCGImmOpValue(const MCInst &MI, unsigned Op,167SmallVectorImpl<MCFixup> &Fixups,168const MCSubtargetInfo &STI) const {169const MCOperand &MO = MI.getOperand(Op);170assert(MO.isImm() && "Expr operand expected");171172int64_t Imm = MO.getImm();173switch (Imm) {174default:175llvm_unreachable("Invalid immediate value");176case 4: return 0x22;177case 8: return 0x32;178case 0: return 0x03;179case 1: return 0x13;180case 2: return 0x23;181case -1: return 0x33;182}183}184185unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,186SmallVectorImpl<MCFixup> &Fixups,187const MCSubtargetInfo &STI) const {188const MCOperand &MO = MI.getOperand(Op);189assert(MO.isImm() && "Immediate operand expected");190switch (MO.getImm()) {191case MSP430CC::COND_NE: return 0;192case MSP430CC::COND_E: return 1;193case MSP430CC::COND_LO: return 2;194case MSP430CC::COND_HS: return 3;195case MSP430CC::COND_N: return 4;196case MSP430CC::COND_GE: return 5;197case MSP430CC::COND_L: return 6;198default:199llvm_unreachable("Unknown condition code");200}201}202203MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII,204MCContext &Ctx) {205return new MSP430MCCodeEmitter(Ctx, MCII);206}207208#include "MSP430GenMCCodeEmitter.inc"209210} // end of namespace llvm211212213