1 //===-- MSP430MCCodeEmitter.cpp - Convert MSP430 code to machine code -----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the MSP430MCCodeEmitter class.
12 //===----------------------------------------------------------------------===//
15 #include "MCTargetDesc/MSP430MCTargetDesc.h"
16 #include "MCTargetDesc/MSP430FixupKinds.h"
18 #include "llvm/ADT/APFloat.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCFixup.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/Support/Endian.h"
29 #include "llvm/Support/EndianStream.h"
30 #include "llvm/Support/raw_ostream.h"
32 #define DEBUG_TYPE "mccodeemitter"
36 class MSP430MCCodeEmitter : public MCCodeEmitter {
38 MCInstrInfo const &MCII;
40 // Offset keeps track of current word number being emitted
41 // inside a particular instruction.
42 mutable unsigned Offset;
44 /// TableGen'erated function for getting the binary encoding for an
46 uint64_t getBinaryCodeForInstr(const MCInst &MI,
47 SmallVectorImpl<MCFixup> &Fixups,
48 const MCSubtargetInfo &STI) const;
50 /// Returns the binary encoding of operands.
52 /// If an operand requires relocation, the relocation is recorded
53 /// and zero is returned.
54 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
55 SmallVectorImpl<MCFixup> &Fixups,
56 const MCSubtargetInfo &STI) const;
58 unsigned getMemOpValue(const MCInst &MI, unsigned Op,
59 SmallVectorImpl<MCFixup> &Fixups,
60 const MCSubtargetInfo &STI) const;
62 unsigned getPCRelImmOpValue(const MCInst &MI, unsigned Op,
63 SmallVectorImpl<MCFixup> &Fixups,
64 const MCSubtargetInfo &STI) const;
66 unsigned getCGImmOpValue(const MCInst &MI, unsigned Op,
67 SmallVectorImpl<MCFixup> &Fixups,
68 const MCSubtargetInfo &STI) const;
70 unsigned getCCOpValue(const MCInst &MI, unsigned Op,
71 SmallVectorImpl<MCFixup> &Fixups,
72 const MCSubtargetInfo &STI) const;
75 MSP430MCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
76 : Ctx(ctx), MCII(MCII) {}
78 void encodeInstruction(const MCInst &MI, raw_ostream &OS,
79 SmallVectorImpl<MCFixup> &Fixups,
80 const MCSubtargetInfo &STI) const override;
83 void MSP430MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
84 SmallVectorImpl<MCFixup> &Fixups,
85 const MCSubtargetInfo &STI) const {
86 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
87 // Get byte count of instruction.
88 unsigned Size = Desc.getSize();
90 // Initialize fixup offset
93 uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI);
94 size_t WordCount = Size / 2;
97 support::endian::write(OS, (uint16_t)BinaryOpCode, support::little);
102 unsigned MSP430MCCodeEmitter::getMachineOpValue(const MCInst &MI,
104 SmallVectorImpl<MCFixup> &Fixups,
105 const MCSubtargetInfo &STI) const {
107 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
114 assert(MO.isExpr() && "Expected expr operand");
115 Fixups.push_back(MCFixup::create(Offset, MO.getExpr(),
116 static_cast<MCFixupKind>(MSP430::fixup_16_byte), MI.getLoc()));
121 unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op,
122 SmallVectorImpl<MCFixup> &Fixups,
123 const MCSubtargetInfo &STI) const {
124 const MCOperand &MO1 = MI.getOperand(Op);
125 assert(MO1.isReg() && "Register operand expected");
126 unsigned Reg = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
128 const MCOperand &MO2 = MI.getOperand(Op + 1);
131 return ((unsigned)MO2.getImm() << 4) | Reg;
134 assert(MO2.isExpr() && "Expr operand expected");
135 MSP430::Fixups FixupKind;
138 FixupKind = MSP430::fixup_16_pcrel_byte;
141 FixupKind = MSP430::fixup_16_byte;
144 FixupKind = MSP430::fixup_16_byte;
147 Fixups.push_back(MCFixup::create(Offset, MO2.getExpr(),
148 static_cast<MCFixupKind>(FixupKind), MI.getLoc()));
153 unsigned MSP430MCCodeEmitter::getPCRelImmOpValue(const MCInst &MI, unsigned Op,
154 SmallVectorImpl<MCFixup> &Fixups,
155 const MCSubtargetInfo &STI) const {
156 const MCOperand &MO = MI.getOperand(Op);
160 assert(MO.isExpr() && "Expr operand expected");
161 Fixups.push_back(MCFixup::create(0, MO.getExpr(),
162 static_cast<MCFixupKind>(MSP430::fixup_10_pcrel), MI.getLoc()));
166 unsigned MSP430MCCodeEmitter::getCGImmOpValue(const MCInst &MI, unsigned Op,
167 SmallVectorImpl<MCFixup> &Fixups,
168 const MCSubtargetInfo &STI) const {
169 const MCOperand &MO = MI.getOperand(Op);
170 assert(MO.isImm() && "Expr operand expected");
172 int64_t Imm = MO.getImm();
175 llvm_unreachable("Invalid immediate value");
181 case -1: return 0x33;
185 unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,
186 SmallVectorImpl<MCFixup> &Fixups,
187 const MCSubtargetInfo &STI) const {
188 const MCOperand &MO = MI.getOperand(Op);
189 assert(MO.isImm() && "Immediate operand expected");
190 switch (MO.getImm()) {
191 case MSP430CC::COND_NE: return 0;
192 case MSP430CC::COND_E: return 1;
193 case MSP430CC::COND_LO: return 2;
194 case MSP430CC::COND_HS: return 3;
195 case MSP430CC::COND_N: return 4;
196 case MSP430CC::COND_GE: return 5;
197 case MSP430CC::COND_L: return 6;
199 llvm_unreachable("Unknown condition code");
203 MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII,
204 const MCRegisterInfo &MRI,
206 return new MSP430MCCodeEmitter(Ctx, MCII);
209 #include "MSP430GenMCCodeEmitter.inc"
211 } // end of namespace llvm