Bug Summary

File:llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
Warning:line 234, column 5
Value stored to 'NoExpr' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name M68kMCCodeEmitter.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/M68k/MCTargetDesc -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/M68k/MCTargetDesc -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/M68k/MCTargetDesc -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/M68k -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/M68k -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -D NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/lib/Target/M68k/MCTargetDesc -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-09-04-040900-46481-1 -x c++ /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp
1//===-- M68kMCCodeEmitter.cpp - Convert M68k code emitter ---*- C++ -*-===//
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/// \file
10/// This file contains defintions for M68k code emitter.
11///
12//===----------------------------------------------------------------------===//
13
14#include "MCTargetDesc/M68kMCCodeEmitter.h"
15#include "MCTargetDesc/M68kBaseInfo.h"
16#include "MCTargetDesc/M68kFixupKinds.h"
17#include "MCTargetDesc/M68kMCTargetDesc.h"
18
19#include "llvm/MC/MCCodeEmitter.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/MC/MCRegisterInfo.h"
25#include "llvm/MC/MCSubtargetInfo.h"
26#include "llvm/MC/MCSymbol.h"
27#include "llvm/Support/Debug.h"
28#include "llvm/Support/EndianStream.h"
29#include "llvm/Support/raw_ostream.h"
30
31using namespace llvm;
32
33#define DEBUG_TYPE"m68k-mccodeemitter" "m68k-mccodeemitter"
34
35namespace {
36class M68kMCCodeEmitter : public MCCodeEmitter {
37 M68kMCCodeEmitter(const M68kMCCodeEmitter &) = delete;
38 void operator=(const M68kMCCodeEmitter &) = delete;
39 const MCInstrInfo &MCII;
40 MCContext &Ctx;
41
42public:
43 M68kMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
44 : MCII(mcii), Ctx(ctx) {}
45
46 ~M68kMCCodeEmitter() override {}
47
48 // TableGen'erated function
49 const uint8_t *getGenInstrBeads(const MCInst &MI) const {
50 return M68k::getMCInstrBeads(MI.getOpcode());
51 }
52
53 unsigned encodeBits(unsigned ThisByte, uint8_t Bead, const MCInst &MI,
54 const MCInstrDesc &Desc, uint64_t &Buffer,
55 unsigned Offset, SmallVectorImpl<MCFixup> &Fixups,
56 const MCSubtargetInfo &STI) const;
57
58 unsigned encodeReg(unsigned ThisByte, uint8_t Bead, const MCInst &MI,
59 const MCInstrDesc &Desc, uint64_t &Buffer, unsigned Offset,
60 SmallVectorImpl<MCFixup> &Fixups,
61 const MCSubtargetInfo &STI) const;
62
63 unsigned encodeImm(unsigned ThisByte, uint8_t Bead, const MCInst &MI,
64 const MCInstrDesc &Desc, uint64_t &Buffer, unsigned Offset,
65 SmallVectorImpl<MCFixup> &Fixups,
66 const MCSubtargetInfo &STI) const;
67
68 void encodeInstruction(const MCInst &MI, raw_ostream &OS,
69 SmallVectorImpl<MCFixup> &Fixups,
70 const MCSubtargetInfo &STI) const override;
71};
72
73} // end anonymous namespace
74
75unsigned M68kMCCodeEmitter::encodeBits(unsigned ThisByte, uint8_t Bead,
76 const MCInst &MI,
77 const MCInstrDesc &Desc,
78 uint64_t &Buffer, unsigned Offset,
79 SmallVectorImpl<MCFixup> &Fixups,
80 const MCSubtargetInfo &STI) const {
81 unsigned Num = 0;
82 switch (Bead & 0xF) {
83 case M68kBeads::Bits1:
84 Num = 1;
85 break;
86 case M68kBeads::Bits2:
87 Num = 2;
88 break;
89 case M68kBeads::Bits3:
90 Num = 3;
91 break;
92 case M68kBeads::Bits4:
93 Num = 4;
94 break;
95 }
96 unsigned char Val = (Bead & 0xF0) >> 4;
97
98 LLVM_DEBUG(dbgs() << "\tEncodeBits"do { } while (false)
99 << " Num: " << Num << " Val: 0x")do { } while (false);
100 LLVM_DEBUG(dbgs().write_hex(Val) << "\n")do { } while (false);
101
102 Buffer |= (Val << Offset);
103
104 return Num;
105}
106
107unsigned M68kMCCodeEmitter::encodeReg(unsigned ThisByte, uint8_t Bead,
108 const MCInst &MI, const MCInstrDesc &Desc,
109 uint64_t &Buffer, unsigned Offset,
110 SmallVectorImpl<MCFixup> &Fixups,
111 const MCSubtargetInfo &STI) const {
112 bool DA, Reg;
113 switch (Bead & 0xF) {
114 default:
115 llvm_unreachable("Unrecognized Bead code for register type")__builtin_unreachable();
116 case M68kBeads::DAReg:
117 Reg = true;
118 DA = true;
119 break;
120 case M68kBeads::DA:
121 Reg = false;
122 DA = true;
123 break;
124 case M68kBeads::DReg:
125 case M68kBeads::Reg:
126 Reg = true;
127 DA = false;
128 break;
129 }
130
131 unsigned Op = (Bead & 0x70) >> 4;
132 bool Alt = (Bead & 0x80);
133 LLVM_DEBUG(dbgs() << "\tEncodeReg"do { } while (false)
134 << " Op: " << Op << ", DA: " << DA << ", Reg: " << Regdo { } while (false)
135 << ", Alt: " << Alt << "\n")do { } while (false);
136
137 auto MIOpIdx = M68k::getLogicalOperandIdx(MI.getOpcode(), Op);
138 bool IsPCRel = Desc.OpInfo[MIOpIdx].OperandType == MCOI::OPERAND_PCREL;
139
140 MCOperand MCO;
141 if (M68kII::hasMultiMIOperands(MI.getOpcode(), Op)) {
142 if (IsPCRel) {
143 assert(Alt &&(static_cast<void> (0))
144 "PCRel addresses use Alt bead register encoding by default")(static_cast<void> (0));
145 MCO = MI.getOperand(MIOpIdx + M68k::PCRelIndex);
146 } else {
147 MCO = MI.getOperand(MIOpIdx + (Alt ? M68k::MemIndex : M68k::MemBase));
148 }
149 } else {
150 assert(!Alt && "You cannot use Alt register with a simple operand")(static_cast<void> (0));
151 MCO = MI.getOperand(MIOpIdx);
152 }
153
154 unsigned RegNum = MCO.getReg();
155 auto RI = Ctx.getRegisterInfo();
156
157 unsigned Written = 0;
158 if (Reg) {
159 uint32_t Val = RI->getEncodingValue(RegNum);
160 Buffer |= (Val & 7) << Offset;
161 Offset += 3;
162 Written += 3;
163 }
164
165 if (DA) {
166 Buffer |= (uint64_t)M68kII::isAddressRegister(RegNum) << Offset;
167 Written++;
168 }
169
170 return Written;
171}
172
173static unsigned EmitConstant(uint64_t Val, unsigned Size, unsigned Pad,
174 uint64_t &Buffer, unsigned Offset) {
175 assert(Size + Offset <= 64 && isUIntN(Size, Val) && "Value does not fit")(static_cast<void> (0));
176
177 // Writing Value in host's endianness
178 Buffer |= (Val & ((1ULL << Size) - 1)) << Offset;
179 return Size + Pad;
180}
181
182unsigned M68kMCCodeEmitter::encodeImm(unsigned ThisByte, uint8_t Bead,
183 const MCInst &MI, const MCInstrDesc &Desc,
184 uint64_t &Buffer, unsigned Offset,
185 SmallVectorImpl<MCFixup> &Fixups,
186 const MCSubtargetInfo &STI) const {
187 unsigned ThisWord = ThisByte / 2;
188 unsigned Size = 0;
189 unsigned Pad = 0;
190 unsigned FixOffset = 0;
191 int64_t Addendum = 0;
192 bool NoExpr = false;
193
194 unsigned Type = Bead & 0xF;
195 unsigned Op = (Bead & 0x70) >> 4;
196 bool Alt = (Bead & 0x80);
197
198 auto MIOpIdx = M68k::getLogicalOperandIdx(MI.getOpcode(), Op);
199 bool IsPCRel = Desc.OpInfo[MIOpIdx].OperandType == MCOI::OPERAND_PCREL;
200
201 // The PC value upon instruction reading of a short jump will point to the
202 // next instruction, thus we need to compensate 2 bytes, which is the diff
203 // between the patch point and the PC.
204 if (IsPCRel && ThisWord == 0)
205 Addendum -= 2;
206
207 switch (Type) {
208 // ??? what happens if it is not byte aligned
209 // ??? is it even possible
210 case M68kBeads::Disp8:
211 Size = 8;
212 Pad = 0;
213 FixOffset = ThisByte + 1;
214 Addendum += 1;
215 break;
216 case M68kBeads::Imm8:
217 Size = 8;
218 Pad = 8;
219 FixOffset = ThisByte;
220 break;
221 case M68kBeads::Imm16:
222 Size = 16;
223 Pad = 0;
224 FixOffset = ThisByte;
225 break;
226 case M68kBeads::Imm32:
227 Size = 32;
228 Pad = 0;
229 FixOffset = ThisByte;
230 break;
231 case M68kBeads::Imm3:
232 Size = 3;
233 Pad = 0;
234 NoExpr = true;
Value stored to 'NoExpr' is never read
235 break;
236 }
237
238 LLVM_DEBUG(dbgs() << "\tEncodeImm"do { } while (false)
239 << " Op: " << Op << ", Size: " << Size << ", Alt: " << Altdo { } while (false)
240 << "\n")do { } while (false);
241
242 MCOperand MCO;
243 if (M68kII::hasMultiMIOperands(MI.getOpcode(), Op)) {
244
245 if (IsPCRel) {
246 assert(!Alt && "You cannot use ALT operand with PCRel")(static_cast<void> (0));
247 MCO = MI.getOperand(MIOpIdx + M68k::PCRelDisp);
248 } else {
249 MCO = MI.getOperand(MIOpIdx + (Alt ? M68k::MemOuter : M68k::MemDisp));
250 }
251
252 if (MCO.isExpr()) {
253 assert(!NoExpr && "Cannot use expression here")(static_cast<void> (0));
254 const MCExpr *Expr = MCO.getExpr();
255
256 // This only makes sense for PCRel instructions since PC points to the
257 // extension word and Disp8 for example is right justified and requires
258 // correction. E.g. R_68K_PC32 is calculated as S + A - P, P for Disp8
259 // will be EXTENSION_WORD + 1 thus we need to have A equal to 1 to
260 // compensate.
261 // TODO count extension words
262 if (IsPCRel && Addendum != 0) {
263 Expr = MCBinaryExpr::createAdd(
264 Expr, MCConstantExpr::create(Addendum, Ctx), Ctx);
265 }
266
267 Fixups.push_back(MCFixup::create(
268 FixOffset, Expr, getFixupForSize(Size, IsPCRel), MI.getLoc()));
269 // Write zeros
270 return EmitConstant(0, Size, Pad, Buffer, Offset);
271 }
272
273 } else {
274 MCO = MI.getOperand(MIOpIdx);
275 if (MCO.isExpr()) {
276 assert(!NoExpr && "Cannot use expression here")(static_cast<void> (0));
277 const MCExpr *Expr = MCO.getExpr();
278
279 if (Addendum != 0) {
280 Expr = MCBinaryExpr::createAdd(
281 Expr, MCConstantExpr::create(Addendum, Ctx), Ctx);
282 }
283
284 Fixups.push_back(MCFixup::create(
285 FixOffset, Expr, getFixupForSize(Size, IsPCRel), MI.getLoc()));
286 // Write zeros
287 return EmitConstant(0, Size, Pad, Buffer, Offset);
288 }
289 }
290
291 int64_t I = MCO.getImm();
292
293 // Store 8 as 0, thus making range 1-8
294 if (Type == M68kBeads::Imm3 && Alt) {
295 assert(I && "Cannot encode Alt Imm3 zero value")(static_cast<void> (0));
296 I %= 8;
297 } else {
298 assert(isIntN(Size, I))(static_cast<void> (0));
299 }
300
301 uint64_t Imm = I;
302
303 // 32 bit Imm requires HI16 first then LO16
304 if (Size == 32) {
305 Offset += EmitConstant((Imm >> 16) & 0xFFFF, 16, Pad, Buffer, Offset);
306 EmitConstant(Imm & 0xFFFF, 16, Pad, Buffer, Offset);
307 return Size;
308 }
309
310 return EmitConstant(Imm & ((1ULL << Size) - 1), Size, Pad, Buffer, Offset);
311}
312
313#include "M68kGenMCCodeBeads.inc"
314
315void M68kMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
316 SmallVectorImpl<MCFixup> &Fixups,
317 const MCSubtargetInfo &STI) const {
318 unsigned Opcode = MI.getOpcode();
319 const MCInstrDesc &Desc = MCII.get(Opcode);
320
321 LLVM_DEBUG(dbgs() << "EncodeInstruction: " << MCII.getName(Opcode) << "("do { } while (false)
322 << Opcode << ")\n")do { } while (false);
323
324 const uint8_t *Beads = getGenInstrBeads(MI);
325 if (!Beads || !*Beads) {
326 llvm_unreachable("*** Instruction does not have Beads defined")__builtin_unreachable();
327 }
328
329 uint64_t Buffer = 0;
330 unsigned Offset = 0;
331 unsigned ThisByte = 0;
332
333 for (uint8_t Bead = *Beads; Bead; Bead = *++Beads) {
334 // Check for control beads
335 if (!(Bead & 0xF)) {
336 switch (Bead >> 4) {
337 case M68kBeads::Ignore:
338 continue;
339 }
340 }
341
342 switch (Bead & 0xF) {
343 default:
344 llvm_unreachable("Unknown Bead code")__builtin_unreachable();
345 break;
346 case M68kBeads::Bits1:
347 case M68kBeads::Bits2:
348 case M68kBeads::Bits3:
349 case M68kBeads::Bits4:
350 Offset +=
351 encodeBits(ThisByte, Bead, MI, Desc, Buffer, Offset, Fixups, STI);
352 break;
353 case M68kBeads::DAReg:
354 case M68kBeads::DA:
355 case M68kBeads::DReg:
356 case M68kBeads::Reg:
357 Offset +=
358 encodeReg(ThisByte, Bead, MI, Desc, Buffer, Offset, Fixups, STI);
359 break;
360 case M68kBeads::Disp8:
361 case M68kBeads::Imm8:
362 case M68kBeads::Imm16:
363 case M68kBeads::Imm32:
364 case M68kBeads::Imm3:
365 Offset +=
366 encodeImm(ThisByte, Bead, MI, Desc, Buffer, Offset, Fixups, STI);
367 break;
368 }
369
370 // Since M68k is Big Endian we need to rotate each instruction word
371 while (Offset / 16) {
372 support::endian::write<uint16_t>(OS, Buffer, support::big);
373 Buffer >>= 16;
374 Offset -= 16;
375 ThisByte += 2;
376 }
377 }
378
379 assert(Offset == 0 && "M68k Instructions are % 2 bytes")(static_cast<void> (0));
380 assert((ThisByte && !(ThisByte % 2)) && "M68k Instructions are % 2 bytes")(static_cast<void> (0));
381}
382
383MCCodeEmitter *llvm::createM68kMCCodeEmitter(const MCInstrInfo &MCII,
384 const MCRegisterInfo &MRI,
385 MCContext &Ctx) {
386 return new M68kMCCodeEmitter(MCII, Ctx);
387}