LLVM  9.0.0svn
MSP430MCCodeEmitter.cpp
Go to the documentation of this file.
1 //===-- MSP430MCCodeEmitter.cpp - Convert MSP430 code to machine code -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the MSP430MCCodeEmitter class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MSP430.h"
16 
17 #include "llvm/ADT/APFloat.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/MC/MCCodeEmitter.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCFixup.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/Support/Endian.h"
30 
31 #define DEBUG_TYPE "mccodeemitter"
32 
33 namespace llvm {
34 
36  MCContext &Ctx;
37  MCInstrInfo const &MCII;
38 
39  // Offset keeps track of current word number being emitted
40  // inside a particular instruction.
41  mutable unsigned Offset;
42 
43  /// TableGen'erated function for getting the binary encoding for an
44  /// instruction.
45  uint64_t getBinaryCodeForInstr(const MCInst &MI,
47  const MCSubtargetInfo &STI) const;
48 
49  /// Returns the binary encoding of operands.
50  ///
51  /// If an operand requires relocation, the relocation is recorded
52  /// and zero is returned.
53  unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
55  const MCSubtargetInfo &STI) const;
56 
57  unsigned getMemOpValue(const MCInst &MI, unsigned Op,
59  const MCSubtargetInfo &STI) const;
60 
61  unsigned getPCRelImmOpValue(const MCInst &MI, unsigned Op,
63  const MCSubtargetInfo &STI) const;
64 
65  unsigned getCGImmOpValue(const MCInst &MI, unsigned Op,
67  const MCSubtargetInfo &STI) const;
68 
69  unsigned getCCOpValue(const MCInst &MI, unsigned Op,
71  const MCSubtargetInfo &STI) const;
72 
73 public:
75  : Ctx(ctx), MCII(MCII) {}
76 
77  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
79  const MCSubtargetInfo &STI) const override;
80 };
81 
84  const MCSubtargetInfo &STI) const {
85  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
86  // Get byte count of instruction.
87  unsigned Size = Desc.getSize();
88 
89  // Initialize fixup offset
90  Offset = 2;
91 
92  uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI);
93  size_t WordCount = Size / 2;
94 
95  while (WordCount--) {
96  support::endian::write(OS, (uint16_t)BinaryOpCode, support::little);
97  BinaryOpCode >>= 16;
98  }
99 }
100 
101 unsigned MSP430MCCodeEmitter::getMachineOpValue(const MCInst &MI,
102  const MCOperand &MO,
104  const MCSubtargetInfo &STI) const {
105  if (MO.isReg())
106  return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
107 
108  if (MO.isImm()) {
109  Offset += 2;
110  return MO.getImm();
111  }
112 
113  assert(MO.isExpr() && "Expected expr operand");
114  Fixups.push_back(MCFixup::create(Offset, MO.getExpr(),
115  static_cast<MCFixupKind>(MSP430::fixup_16_byte), MI.getLoc()));
116  Offset += 2;
117  return 0;
118 }
119 
120 unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op,
121  SmallVectorImpl<MCFixup> &Fixups,
122  const MCSubtargetInfo &STI) const {
123  const MCOperand &MO1 = MI.getOperand(Op);
124  assert(MO1.isReg() && "Register operand expected");
125  unsigned Reg = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
126 
127  const MCOperand &MO2 = MI.getOperand(Op + 1);
128  if (MO2.isImm()) {
129  Offset += 2;
130  return ((unsigned)MO2.getImm() << 4) | Reg;
131  }
132 
133  assert(MO2.isExpr() && "Expr operand expected");
135  switch (Reg) {
136  case 0:
137  FixupKind = MSP430::fixup_16_pcrel_byte;
138  break;
139  case 2:
140  FixupKind = MSP430::fixup_16_byte;
141  break;
142  default:
143  FixupKind = MSP430::fixup_16_byte;
144  break;
145  }
146  Fixups.push_back(MCFixup::create(Offset, MO2.getExpr(),
147  static_cast<MCFixupKind>(FixupKind), MI.getLoc()));
148  Offset += 2;
149  return Reg;
150 }
151 
152 unsigned MSP430MCCodeEmitter::getPCRelImmOpValue(const MCInst &MI, unsigned Op,
153  SmallVectorImpl<MCFixup> &Fixups,
154  const MCSubtargetInfo &STI) const {
155  const MCOperand &MO = MI.getOperand(Op);
156  if (MO.isImm())
157  return MO.getImm();
158 
159  assert(MO.isExpr() && "Expr operand expected");
160  Fixups.push_back(MCFixup::create(0, MO.getExpr(),
161  static_cast<MCFixupKind>(MSP430::fixup_10_pcrel), MI.getLoc()));
162  return 0;
163 }
164 
165 unsigned MSP430MCCodeEmitter::getCGImmOpValue(const MCInst &MI, unsigned Op,
166  SmallVectorImpl<MCFixup> &Fixups,
167  const MCSubtargetInfo &STI) const {
168  const MCOperand &MO = MI.getOperand(Op);
169  assert(MO.isImm() && "Expr operand expected");
170 
171  int64_t Imm = MO.getImm();
172  switch (Imm) {
173  default:
174  llvm_unreachable("Invalid immediate value");
175  case 4: return 0x22;
176  case 8: return 0x32;
177  case 0: return 0x03;
178  case 1: return 0x13;
179  case 2: return 0x23;
180  case -1: return 0x33;
181  }
182 }
183 
184 unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,
185  SmallVectorImpl<MCFixup> &Fixups,
186  const MCSubtargetInfo &STI) const {
187  const MCOperand &MO = MI.getOperand(Op);
188  assert(MO.isImm() && "Immediate operand expected");
189  switch (MO.getImm()) {
190  case MSP430CC::COND_NE: return 0;
191  case MSP430CC::COND_E: return 1;
192  case MSP430CC::COND_LO: return 2;
193  case MSP430CC::COND_HS: return 3;
194  case MSP430CC::COND_N: return 4;
195  case MSP430CC::COND_GE: return 5;
196  case MSP430CC::COND_L: return 6;
197  default:
198  llvm_unreachable("Unknown condition code");
199  }
200 }
201 
203  const MCRegisterInfo &MRI,
204  MCContext &Ctx) {
205  return new MSP430MCCodeEmitter(Ctx, MCII);
206 }
207 
208 #include "MSP430GenMCCodeEmitter.inc"
209 
210 } // end of namespace llvm
bool isImm() const
Definition: MCInst.h:58
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:164
unsigned Reg
void encodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const override
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
bool isReg() const
Definition: MCInst.h:57
MCCodeEmitter * createMSP430MCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
Creates a machine code emitter for MSP430.
static Lanai::Fixups FixupKind(const MCExpr *Expr)
MSP430MCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
Context object for machine code objects.
Definition: MCContext.h:62
const MCExpr * getExpr() const
Definition: MCInst.h:95
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition: Endian.h:99
int64_t getImm() const
Definition: MCInst.h:75
unsigned const MachineRegisterInfo * MRI
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:23
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:22
This file declares a class to represent arbitrary precision floating point values and provide a varie...
bool isExpr() const
Definition: MCInst.h:60
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:90
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
SMLoc getLoc() const
Definition: MCInst.h:177
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:44
Generic base class for all target subtargets.
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:294
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
IRTranslator LLVM IR MI
unsigned getOpcode() const
Definition: MCInst.h:171
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Definition: MCInstrDesc.h:586