1 //===---- AMDILMCCodeEmitter.cpp - Convert AMDIL text to AMDIL binary ----===//
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 //===---------------------------------------------------------------------===//
12 #define DEBUG_TYPE "amdil-emitter"
14 #include "AMDILInstrInfo.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/MC/MCCodeEmitter.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/Support/raw_ostream.h"
24 class AMDILMCCodeEmitter
: public MCCodeEmitter
{
25 AMDILMCCodeEmitter(const AMDILMCCodeEmitter
&);// DO NOT IMPLEMENT
26 void operator=(const AMDILMCCodeEmitter
&); // DO NOT IMPLEMENT
27 const TargetMachine
&TM
;
28 const TargetInstrInfo
&TII
;
32 AMDILMCCodeEmitter(TargetMachine
&tm
, MCContext
&ctx
, bool is64Bit
);
33 ~AMDILMCCodeEmitter();
34 unsigned getNumFixupKinds() const;
35 const MCFixupKindInfo
& getFixupKindInfo(MCFixupKind Kind
) const;
36 static unsigned GetAMDILRegNum(const MCOperand
&MO
);
37 void EmitByte(unsigned char C
, unsigned &CurByte
, raw_ostream
&OS
) const;
38 void EmitConstant(uint64_t Val
, unsigned Size
, unsigned &CurByte
,
39 raw_ostream
&OS
) const;
40 void EmitImmediate(const MCOperand
&Disp
, unsigned ImmSize
,
41 MCFixupKind FixupKind
, unsigned &CurByte
, raw_ostream
&os
,
42 SmallVectorImpl
<MCFixup
> &Fixups
, int ImmOffset
= 0) const;
44 void EncodeInstruction(const MCInst
&MI
, raw_ostream
&OS
,
45 SmallVectorImpl
<MCFixup
> &Fixups
) const;
47 }; // class AMDILMCCodeEmitter
48 }; // anonymous namespace
51 MCCodeEmitter
*createAMDILMCCodeEmitter(const Target
&,
52 TargetMachine
&TM
, MCContext
&Ctx
)
54 return new AMDILMCCodeEmitter(TM
, Ctx
, false);
58 AMDILMCCodeEmitter::AMDILMCCodeEmitter(TargetMachine
&tm
, MCContext
&ctx
60 : TM(tm
), TII(*TM
.getInstrInfo()), Ctx(ctx
)
62 Is64BitMode
= is64Bit
;
65 AMDILMCCodeEmitter::~AMDILMCCodeEmitter()
70 AMDILMCCodeEmitter::getNumFixupKinds() const
75 const MCFixupKindInfo
&
76 AMDILMCCodeEmitter::getFixupKindInfo(MCFixupKind Kind
) const
78 // const static MCFixupKindInfo Infos[] = {};
79 if (Kind
< FirstTargetFixupKind
) {
80 return MCCodeEmitter::getFixupKindInfo(Kind
);
82 assert(unsigned(Kind
- FirstTargetFixupKind
) < getNumFixupKinds() &&
84 return MCCodeEmitter::getFixupKindInfo(Kind
);
85 // return Infos[Kind - FirstTargetFixupKind];
90 AMDILMCCodeEmitter::EmitByte(unsigned char C
, unsigned &CurByte
,
91 raw_ostream
&OS
) const
97 AMDILMCCodeEmitter::EmitConstant(uint64_t Val
, unsigned Size
, unsigned &CurByte
,
98 raw_ostream
&OS
) const
100 // Output the constant in little endian byte order
101 for (unsigned i
= 0; i
!= Size
; ++i
) {
102 EmitByte(Val
& 255, CurByte
, OS
);
107 AMDILMCCodeEmitter::EmitImmediate(const MCOperand
&DispOp
, unsigned ImmSize
,
108 MCFixupKind FixupKind
, unsigned &CurByte
, raw_ostream
&OS
,
109 SmallVectorImpl
<MCFixup
> &Fixups
, int ImmOffset
) const
111 // If this is a simple integer displacement that doesn't require a relocation
113 if (DispOp
.isImm()) {
114 EmitConstant(DispOp
.getImm() + ImmOffset
, ImmSize
, CurByte
, OS
);
117 // If we have an immoffset, add it to the expression
118 const MCExpr
*Expr
= DispOp
.getExpr();
121 Expr
= MCBinaryExpr::CreateAdd(Expr
,
122 MCConstantExpr::Create(ImmOffset
, Ctx
), Ctx
);
124 // Emit a symbolic constant as a fixup and 4 zeros.
125 Fixups
.push_back(MCFixup::Create(CurByte
, Expr
, FixupKind
));
126 // TODO: Why the 4 zeros?
127 EmitConstant(0, ImmSize
, CurByte
, OS
);
131 AMDILMCCodeEmitter::EncodeInstruction(const MCInst
&MI
, raw_ostream
&OS
,
132 SmallVectorImpl
<MCFixup
> &Fixups
) const
135 unsigned Opcode
= MI
.getOpcode();
136 const TargetInstrDesc
&Desc
= TII
.get(Opcode
);
137 unsigned TSFlags
= Desc
.TSFlags
;
139 // Keep track of the current byte being emitted.
140 unsigned CurByte
= 0;
142 unsigned NumOps
= Desc
.getNumOperands();
145 unsigned char BaseOpcode
= 0;
148 if (// !Desc.isVariadic() &&
150 errs() << "Cannot encode all operands of: ";