Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/MSP430/MCTargetDesc/MSP430MCCodeEmitter.cpp
Line
Count
Source (jump to first uncovered line)
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"
14
#include "MCTargetDesc/MSP430MCTargetDesc.h"
15
#include "MCTargetDesc/MSP430FixupKinds.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"
26
#include "llvm/MC/MCSubtargetInfo.h"
27
#include "llvm/Support/Endian.h"
28
#include "llvm/Support/EndianStream.h"
29
#include "llvm/Support/raw_ostream.h"
30
31
#define DEBUG_TYPE "mccodeemitter"
32
33
namespace llvm {
34
35
class MSP430MCCodeEmitter : public MCCodeEmitter {
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,
46
                                 SmallVectorImpl<MCFixup> &Fixups,
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,
54
                             SmallVectorImpl<MCFixup> &Fixups,
55
                             const MCSubtargetInfo &STI) const;
56
57
  unsigned getMemOpValue(const MCInst &MI, unsigned Op,
58
                         SmallVectorImpl<MCFixup> &Fixups,
59
                         const MCSubtargetInfo &STI) const;
60
61
  unsigned getPCRelImmOpValue(const MCInst &MI, unsigned Op,
62
                              SmallVectorImpl<MCFixup> &Fixups,
63
                              const MCSubtargetInfo &STI) const;
64
65
  unsigned getCGImmOpValue(const MCInst &MI, unsigned Op,
66
                           SmallVectorImpl<MCFixup> &Fixups,
67
                           const MCSubtargetInfo &STI) const;
68
69
  unsigned getCCOpValue(const MCInst &MI, unsigned Op,
70
                        SmallVectorImpl<MCFixup> &Fixups,
71
                        const MCSubtargetInfo &STI) const;
72
73
public:
74
  MSP430MCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
75
10
      : Ctx(ctx), MCII(MCII) {}
76
77
  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
78
                         SmallVectorImpl<MCFixup> &Fixups,
79
                         const MCSubtargetInfo &STI) const override;
80
};
81
82
void MSP430MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
83
                                            SmallVectorImpl<MCFixup> &Fixups,
84
257
                                            const MCSubtargetInfo &STI) const {
85
257
  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
86
257
  // Get byte count of instruction.
87
257
  unsigned Size = Desc.getSize();
88
257
89
257
  // Initialize fixup offset
90
257
  Offset = 2;
91
257
92
257
  uint64_t BinaryOpCode = getBinaryCodeForInstr(MI, Fixups, STI);
93
257
  size_t WordCount = Size / 2;
94
257
95
606
  while (WordCount--) {
96
349
    support::endian::write(OS, (uint16_t)BinaryOpCode, support::little);
97
349
    BinaryOpCode >>= 16;
98
349
  }
99
257
}
100
101
unsigned MSP430MCCodeEmitter::getMachineOpValue(const MCInst &MI,
102
                                                const MCOperand &MO,
103
                                                SmallVectorImpl<MCFixup> &Fixups,
104
273
                                                const MCSubtargetInfo &STI) const {
105
273
  if (MO.isReg())
106
258
    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
107
15
108
15
  if (MO.isImm()) {
109
12
    Offset += 2;
110
12
    return MO.getImm();
111
12
  }
112
3
113
3
  assert(MO.isExpr() && "Expected expr operand");
114
3
  Fixups.push_back(MCFixup::create(Offset, MO.getExpr(),
115
3
      static_cast<MCFixupKind>(MSP430::fixup_16_byte), MI.getLoc()));
116
3
  Offset += 2;
117
3
  return 0;
118
3
}
119
120
unsigned MSP430MCCodeEmitter::getMemOpValue(const MCInst &MI, unsigned Op,
121
                                            SmallVectorImpl<MCFixup> &Fixups,
122
77
                                            const MCSubtargetInfo &STI) const {
123
77
  const MCOperand &MO1 = MI.getOperand(Op);
124
77
  assert(MO1.isReg() && "Register operand expected");
125
77
  unsigned Reg = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
126
77
127
77
  const MCOperand &MO2 = MI.getOperand(Op + 1);
128
77
  if (MO2.isImm()) {
129
35
    Offset += 2;
130
35
    return ((unsigned)MO2.getImm() << 4) | Reg;
131
35
  }
132
42
133
42
  assert(MO2.isExpr() && "Expr operand expected");
134
42
  MSP430::Fixups FixupKind;
135
42
  switch (Reg) {
136
42
  case 0:
137
22
    FixupKind = MSP430::fixup_16_pcrel_byte;
138
22
    break;
139
42
  case 2:
140
16
    FixupKind = MSP430::fixup_16_byte;
141
16
    break;
142
42
  default:
143
4
    FixupKind = MSP430::fixup_16_byte;
144
4
    break;
145
42
  }
146
42
  Fixups.push_back(MCFixup::create(Offset, MO2.getExpr(),
147
42
    static_cast<MCFixupKind>(FixupKind), MI.getLoc()));
148
42
  Offset += 2;
149
42
  return Reg;
150
42
}
151
152
unsigned MSP430MCCodeEmitter::getPCRelImmOpValue(const MCInst &MI, unsigned Op,
153
                                                 SmallVectorImpl<MCFixup> &Fixups,
154
27
                                                 const MCSubtargetInfo &STI) const {
155
27
  const MCOperand &MO = MI.getOperand(Op);
156
27
  if (MO.isImm())
157
24
    return MO.getImm();
158
3
159
3
  assert(MO.isExpr() && "Expr operand expected");
160
3
  Fixups.push_back(MCFixup::create(0, MO.getExpr(),
161
3
    static_cast<MCFixupKind>(MSP430::fixup_10_pcrel), MI.getLoc()));
162
3
  return 0;
163
3
}
164
165
unsigned MSP430MCCodeEmitter::getCGImmOpValue(const MCInst &MI, unsigned Op,
166
                                              SmallVectorImpl<MCFixup> &Fixups,
167
53
                                              const MCSubtargetInfo &STI) const {
168
53
  const MCOperand &MO = MI.getOperand(Op);
169
53
  assert(MO.isImm() && "Expr operand expected");
170
53
  
171
53
  int64_t Imm = MO.getImm();
172
53
  switch (Imm) {
173
53
  default:
174
0
    llvm_unreachable("Invalid immediate value");
175
53
  
case 4: return 0x225
;
176
53
  
case 8: return 0x327
;
177
53
  
case 0: return 0x0314
;
178
53
  
case 1: return 0x1310
;
179
53
  
case 2: return 0x239
;
180
53
  
case -1: return 0x338
;
181
53
  }
182
53
}
183
184
unsigned MSP430MCCodeEmitter::getCCOpValue(const MCInst &MI, unsigned Op,
185
                                           SmallVectorImpl<MCFixup> &Fixups,
186
22
                                           const MCSubtargetInfo &STI) const {
187
22
  const MCOperand &MO = MI.getOperand(Op);
188
22
  assert(MO.isImm() && "Immediate operand expected");
189
22
  switch (MO.getImm()) {
190
22
  
case MSP430CC::COND_NE: return 04
;
191
22
  
case MSP430CC::COND_E: return 14
;
192
22
  
case MSP430CC::COND_LO: return 24
;
193
22
  
case MSP430CC::COND_HS: return 34
;
194
22
  
case MSP430CC::COND_N: return 42
;
195
22
  
case MSP430CC::COND_GE: return 52
;
196
22
  
case MSP430CC::COND_L: return 62
;
197
22
  default:
198
0
    llvm_unreachable("Unknown condition code");
199
22
  }
200
22
}
201
202
MCCodeEmitter *createMSP430MCCodeEmitter(const MCInstrInfo &MCII,
203
                                         const MCRegisterInfo &MRI,
204
10
                                         MCContext &Ctx) {
205
10
  return new MSP430MCCodeEmitter(Ctx, MCII);
206
10
}
207
208
#include "MSP430GenMCCodeEmitter.inc"
209
210
} // end of namespace llvm