1 //===-- ARM/ARMMCCodeEmitter.cpp - Convert ARM 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 ARMMCCodeEmitter class.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "arm-emitter"
16 #include "ARMInstrInfo.h"
17 #include "llvm/MC/MCCodeEmitter.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/Support/raw_ostream.h"
24 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
27 class ARMMCCodeEmitter : public MCCodeEmitter {
28 ARMMCCodeEmitter(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
29 void operator=(const ARMMCCodeEmitter &); // DO NOT IMPLEMENT
30 const TargetMachine &TM;
31 const TargetInstrInfo &TII;
35 ARMMCCodeEmitter(TargetMachine &tm, MCContext &ctx)
36 : TM(tm), TII(*TM.getInstrInfo()), Ctx(ctx) {
39 ~ARMMCCodeEmitter() {}
41 // getBinaryCodeForInstr - TableGen'erated function for getting the
42 // binary encoding for an instruction.
43 unsigned getBinaryCodeForInstr(const MCInst &MI) const;
45 /// getMachineOpValue - Return binary encoding of operand. If the machine
46 /// operand requires relocation, record the relocation and return zero.
47 unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO);
48 unsigned getMachineOpValue(const MCInst &MI, unsigned OpIdx) {
49 return getMachineOpValue(MI, MI.getOperand(OpIdx));
52 unsigned getNumFixupKinds() const {
53 assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented.");
57 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
58 static MCFixupKindInfo rtn;
59 assert(0 && "ARMMCCodeEmitter::getFixupKindInfo() not yet implemented.");
63 static unsigned GetARMRegNum(const MCOperand &MO) {
64 // FIXME: getARMRegisterNumbering() is sufficient?
65 assert(0 && "ARMMCCodeEmitter::GetARMRegNum() not yet implemented.");
69 void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const {
74 void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte,
75 raw_ostream &OS) const {
76 // Output the constant in little endian byte order.
77 for (unsigned i = 0; i != Size; ++i) {
78 EmitByte(Val & 255, CurByte, OS);
83 void EmitImmediate(const MCOperand &Disp,
84 unsigned ImmSize, MCFixupKind FixupKind,
85 unsigned &CurByte, raw_ostream &OS,
86 SmallVectorImpl<MCFixup> &Fixups,
87 int ImmOffset = 0) const;
89 void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
90 SmallVectorImpl<MCFixup> &Fixups) const;
93 } // end anonymous namespace
96 MCCodeEmitter *llvm::createARMMCCodeEmitter(const Target &,
99 return new ARMMCCodeEmitter(TM, Ctx);
102 void ARMMCCodeEmitter::
103 EmitImmediate(const MCOperand &DispOp, unsigned Size, MCFixupKind FixupKind,
104 unsigned &CurByte, raw_ostream &OS,
105 SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const {
106 assert(0 && "ARMMCCodeEmitter::EmitImmediate() not yet implemented.");
109 void ARMMCCodeEmitter::
110 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
111 SmallVectorImpl<MCFixup> &Fixups) const {
112 unsigned Opcode = MI.getOpcode();
113 const TargetInstrDesc &Desc = TII.get(Opcode);
114 uint64_t TSFlags = Desc.TSFlags;
115 // Keep track of the current byte being emitted.
116 unsigned CurByte = 0;
118 // Pseudo instructions don't get encoded.
119 if ((TSFlags & ARMII::FormMask) == ARMII::Pseudo)
122 ++MCNumEmitted; // Keep track of the # of mi's emitted
123 switch (TSFlags & ARMII::FormMask) {
124 case ARMII::BrMiscFrm:
125 case ARMII::MiscFrm: {
126 unsigned Value = getBinaryCodeForInstr(MI);
127 EmitConstant(Value, 4, CurByte, OS);
131 llvm_unreachable("Unhandled instruction encoding format!");
137 // FIXME: These #defines shouldn't be necessary. Instead, tblgen should
138 // be able to generate code emitter helpers for either variant, like it
139 // does for the AsmWriter.
140 #define ARMCodeEmitter ARMMCCodeEmitter
141 #define MachineInstr MCInst
142 #include "ARMGenCodeEmitter.inc"
143 #undef ARMCodeEmitter