Coverage Report

Created: 2023-12-08 06:05

/src/capstonenext/arch/ARM/ARMAddressingModes.h
Line
Count
Source (jump to first uncovered line)
1
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
2
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
3
/*    Rot127 <unisono@quyllur.org> 2022-2023 */
4
/* Automatically translated source file from LLVM. */
5
6
/* LLVM-commit: 464bda7750a3ba9e23823fc707d7e7b6fc38438d */
7
/* LLVM-tag: llvmorg-16.0.2-5-g464bda7750a3 */
8
9
/* Only small edits allowed. */
10
/* For multiple similiar edits, please create a Patch for the translator. */
11
12
/* Capstone's C++ file translator: */
13
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
14
15
//===-- ARMAddressingModes.h - ARM Addressing Modes -------------*- C++ -*-===//
16
//
17
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
18
// See https://llvm.org/LICENSE.txt for license information.
19
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
20
//
21
//===----------------------------------------------------------------------===//
22
//
23
// This file contains the ARM addressing mode implementation stuff.
24
//
25
//===----------------------------------------------------------------------===//
26
27
#ifndef CS_ARM_ADDRESSINGMODES_H
28
#define CS_ARM_ADDRESSINGMODES_H
29
30
#include <capstone/platform.h>
31
#include <stdio.h>
32
#include <stdlib.h>
33
#include <string.h>
34
35
#include "../../MathExtras.h"
36
#include <assert.h>
37
38
#define CONCAT(a, b) CONCAT_(a, b)
39
#define CONCAT_(a, b) a##_##b
40
41
/// ARM_AM - ARM Addressing Mode Stuff
42
typedef enum ShiftOpc {
43
  ARM_AM_no_shift = 0,
44
  ARM_AM_asr,
45
  ARM_AM_lsl,
46
  ARM_AM_lsr,
47
  ARM_AM_ror,
48
  ARM_AM_rrx,
49
  ARM_AM_uxtw
50
} ARM_AM_ShiftOpc;
51
52
typedef enum AddrOpc { ARM_AM_sub = 0, ARM_AM_add } ARM_AM_AddrOpc;
53
54
static inline const char *ARM_AM_getAddrOpcStr(ARM_AM_AddrOpc Op)
55
91.3k
{
56
91.3k
  return Op == ARM_AM_sub ? "-" : "";
57
91.3k
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAddrOpcStr
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAddrOpcStr
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAddrOpcStr
ARMInstPrinter.c:ARM_AM_getAddrOpcStr
Line
Count
Source
55
91.3k
{
56
91.3k
  return Op == ARM_AM_sub ? "-" : "";
57
91.3k
}
58
59
static inline const char *ARM_AM_getShiftOpcStr(ARM_AM_ShiftOpc Op)
60
24.7k
{
61
24.7k
  switch (Op) {
62
0
  default:
63
0
    assert(0 && "Unknown shift opc!");
64
5.37k
  case ARM_AM_asr:
65
5.37k
    return "asr";
66
7.09k
  case ARM_AM_lsl:
67
7.09k
    return "lsl";
68
4.25k
  case ARM_AM_lsr:
69
4.25k
    return "lsr";
70
6.10k
  case ARM_AM_ror:
71
6.10k
    return "ror";
72
1.43k
  case ARM_AM_rrx:
73
1.43k
    return "rrx";
74
523
  case ARM_AM_uxtw:
75
523
    return "uxtw";
76
24.7k
  }
77
24.7k
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getShiftOpcStr
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getShiftOpcStr
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getShiftOpcStr
ARMInstPrinter.c:ARM_AM_getShiftOpcStr
Line
Count
Source
60
24.7k
{
61
24.7k
  switch (Op) {
62
0
  default:
63
0
    assert(0 && "Unknown shift opc!");
64
5.37k
  case ARM_AM_asr:
65
5.37k
    return "asr";
66
7.09k
  case ARM_AM_lsl:
67
7.09k
    return "lsl";
68
4.25k
  case ARM_AM_lsr:
69
4.25k
    return "lsr";
70
6.10k
  case ARM_AM_ror:
71
6.10k
    return "ror";
72
1.43k
  case ARM_AM_rrx:
73
1.43k
    return "rrx";
74
523
  case ARM_AM_uxtw:
75
523
    return "uxtw";
76
24.7k
  }
77
24.7k
}
78
79
static inline unsigned ARM_AM_getShiftOpcEncoding(ARM_AM_ShiftOpc Op)
80
0
{
81
0
  switch (Op) {
82
0
  default:
83
0
    assert(0 && "Unknown shift opc!");
84
0
  case ARM_AM_asr:
85
0
    return 2;
86
0
  case ARM_AM_lsl:
87
0
    return 0;
88
0
  case ARM_AM_lsr:
89
0
    return 1;
90
0
  case ARM_AM_ror:
91
0
    return 3;
92
0
  }
93
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getShiftOpcEncoding
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getShiftOpcEncoding
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getShiftOpcEncoding
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getShiftOpcEncoding
94
95
typedef enum AMSubMode {
96
  ARM_AM_bad_am_submode = 0,
97
  ARM_AM_ia,
98
  ARM_AM_ib,
99
  ARM_AM_da,
100
  ARM_AM_db
101
} ARM_AM_SubMode;
102
103
static inline const char *ARM_AM_getAMSubModeStr(ARM_AM_SubMode Mode)
104
0
{
105
0
  switch (Mode) {
106
0
  default:
107
0
    assert(0 && "Unknown addressing sub-mode!");
108
0
  case ARM_AM_ia:
109
0
    return "ia";
110
0
  case ARM_AM_ib:
111
0
    return "ib";
112
0
  case ARM_AM_da:
113
0
    return "da";
114
0
  case ARM_AM_db:
115
0
    return "db";
116
0
  }
117
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAMSubModeStr
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAMSubModeStr
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAMSubModeStr
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAMSubModeStr
118
119
/// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
120
///
121
static inline unsigned ARM_AM_rotr32(unsigned Val, unsigned Amt)
122
41.5k
{
123
41.5k
  return (Val >> Amt) | (Val << ((32 - Amt) & 31));
124
41.5k
}
ARMMapping.c:ARM_AM_rotr32
Line
Count
Source
122
23.3k
{
123
23.3k
  return (Val >> Amt) | (Val << ((32 - Amt) & 31));
124
23.3k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_rotr32
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_rotr32
ARMInstPrinter.c:ARM_AM_rotr32
Line
Count
Source
122
18.1k
{
123
18.1k
  return (Val >> Amt) | (Val << ((32 - Amt) & 31));
124
18.1k
}
125
126
/// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.
127
///
128
static inline unsigned ARM_AM_rotl32(unsigned Val, unsigned Amt)
129
9.38k
{
130
9.38k
  return (Val << Amt) | (Val >> ((32 - Amt) & 31));
131
9.38k
}
ARMMapping.c:ARM_AM_rotl32
Line
Count
Source
129
4.69k
{
130
4.69k
  return (Val << Amt) | (Val >> ((32 - Amt) & 31));
131
4.69k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_rotl32
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_rotl32
ARMInstPrinter.c:ARM_AM_rotl32
Line
Count
Source
129
4.69k
{
130
4.69k
  return (Val << Amt) | (Val >> ((32 - Amt) & 31));
131
4.69k
}
132
133
//===--------------------------------------------------------------------===//
134
// Addressing Mode #1: shift_operand with registers
135
//===--------------------------------------------------------------------===//
136
//
137
// This 'addressing mode' is used for arithmetic instructions.  It can
138
// represent things like:
139
//   reg
140
//   reg [asr|lsl|lsr|ror|rrx] reg
141
//   reg [asr|lsl|lsr|ror|rrx] imm
142
//
143
// This is stored three operands [rega, regb, opc].  The first is the base
144
// reg, the second is the shift amount (or reg0 if not present or imm).  The
145
// third operand encodes the shift opcode and the imm if a reg isn't present.
146
//
147
static inline unsigned ARM_AM_getSORegOpc(ARM_AM_ShiftOpc ShOp, unsigned Imm)
148
0
{
149
0
  return ShOp | (Imm << 3);
150
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getSORegOpc
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSORegOpc
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSORegOpc
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getSORegOpc
151
152
static inline unsigned ARM_AM_getSORegOffset(unsigned Op)
153
28.6k
{
154
28.6k
  return Op >> 3;
155
28.6k
}
ARMMapping.c:ARM_AM_getSORegOffset
Line
Count
Source
153
14.1k
{
154
14.1k
  return Op >> 3;
155
14.1k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSORegOffset
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSORegOffset
ARMInstPrinter.c:ARM_AM_getSORegOffset
Line
Count
Source
153
14.4k
{
154
14.4k
  return Op >> 3;
155
14.4k
}
156
157
static inline ARM_AM_ShiftOpc ARM_AM_getSORegShOp(unsigned Op)
158
65.5k
{
159
65.5k
  return (ARM_AM_ShiftOpc)(Op & 7);
160
65.5k
}
ARMMapping.c:ARM_AM_getSORegShOp
Line
Count
Source
158
18.0k
{
159
18.0k
  return (ARM_AM_ShiftOpc)(Op & 7);
160
18.0k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSORegShOp
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSORegShOp
ARMInstPrinter.c:ARM_AM_getSORegShOp
Line
Count
Source
158
47.4k
{
159
47.4k
  return (ARM_AM_ShiftOpc)(Op & 7);
160
47.4k
}
161
162
/// getSOImmValImm - Given an encoded imm field for the reg/imm form, return
163
/// the 8-bit imm value.
164
static inline unsigned ARM_AM_getSOImmValImm(unsigned Imm)
165
0
{
166
0
  return Imm & 0xFF;
167
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getSOImmValImm
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmValImm
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmValImm
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getSOImmValImm
168
169
/// getSOImmValRot - Given an encoded imm field for the reg/imm form, return
170
/// the rotate amount.
171
static inline unsigned ARM_AM_getSOImmValRot(unsigned Imm)
172
0
{
173
0
  return (Imm >> 8) * 2;
174
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getSOImmValRot
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmValRot
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmValRot
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getSOImmValRot
175
176
/// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
177
/// computing the rotate amount to use.  If this immediate value cannot be
178
/// handled with a single shifter-op, determine a good rotate amount that will
179
/// take a maximal chunk of bits out of the immediate.
180
static inline unsigned ARM_AM_getSOImmValRotate(unsigned Imm)
181
9.38k
{
182
  // 8-bit (or less) immediates are trivially shifter_operands with a rotate
183
  // of zero.
184
9.38k
  if ((Imm & ~255U) == 0)
185
0
    return 0;
186
187
  // Use CTZ to compute the rotate amount.
188
9.38k
  unsigned TZ = CountTrailingZeros_32(Imm);
189
190
  // Rotate amount must be even.  Something like 0x200 must be rotated 8 bits,
191
  // not 9.
192
9.38k
  unsigned RotAmt = TZ & ~1;
193
194
  // If we can handle this spread, return it.
195
9.38k
  if ((ARM_AM_rotr32(Imm, RotAmt) & ~255U) == 0)
196
5.18k
    return (32 - RotAmt) & 31; // HW rotates right, not left.
197
198
  // For values like 0xF000000F, we should ignore the low 6 bits, then
199
  // retry the hunt.
200
4.19k
  if (Imm & 63U) {
201
4.19k
    unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
202
4.19k
    unsigned RotAmt2 = TZ2 & ~1;
203
4.19k
    if ((ARM_AM_rotr32(Imm, RotAmt2) & ~255U) == 0)
204
4.19k
      return (32 - RotAmt2) &
205
4.19k
             31; // HW rotates right, not left.
206
4.19k
  }
207
208
  // Otherwise, we have no way to cover this span of bits with a single
209
  // shifter_op immediate.  Return a chunk of bits that will be useful to
210
  // handle.
211
0
  return (32 - RotAmt) & 31; // HW rotates right, not left.
212
4.19k
}
ARMMapping.c:ARM_AM_getSOImmValRotate
Line
Count
Source
181
4.69k
{
182
  // 8-bit (or less) immediates are trivially shifter_operands with a rotate
183
  // of zero.
184
4.69k
  if ((Imm & ~255U) == 0)
185
0
    return 0;
186
187
  // Use CTZ to compute the rotate amount.
188
4.69k
  unsigned TZ = CountTrailingZeros_32(Imm);
189
190
  // Rotate amount must be even.  Something like 0x200 must be rotated 8 bits,
191
  // not 9.
192
4.69k
  unsigned RotAmt = TZ & ~1;
193
194
  // If we can handle this spread, return it.
195
4.69k
  if ((ARM_AM_rotr32(Imm, RotAmt) & ~255U) == 0)
196
2.59k
    return (32 - RotAmt) & 31; // HW rotates right, not left.
197
198
  // For values like 0xF000000F, we should ignore the low 6 bits, then
199
  // retry the hunt.
200
2.09k
  if (Imm & 63U) {
201
2.09k
    unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
202
2.09k
    unsigned RotAmt2 = TZ2 & ~1;
203
2.09k
    if ((ARM_AM_rotr32(Imm, RotAmt2) & ~255U) == 0)
204
2.09k
      return (32 - RotAmt2) &
205
2.09k
             31; // HW rotates right, not left.
206
2.09k
  }
207
208
  // Otherwise, we have no way to cover this span of bits with a single
209
  // shifter_op immediate.  Return a chunk of bits that will be useful to
210
  // handle.
211
0
  return (32 - RotAmt) & 31; // HW rotates right, not left.
212
2.09k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmValRotate
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmValRotate
ARMInstPrinter.c:ARM_AM_getSOImmValRotate
Line
Count
Source
181
4.69k
{
182
  // 8-bit (or less) immediates are trivially shifter_operands with a rotate
183
  // of zero.
184
4.69k
  if ((Imm & ~255U) == 0)
185
0
    return 0;
186
187
  // Use CTZ to compute the rotate amount.
188
4.69k
  unsigned TZ = CountTrailingZeros_32(Imm);
189
190
  // Rotate amount must be even.  Something like 0x200 must be rotated 8 bits,
191
  // not 9.
192
4.69k
  unsigned RotAmt = TZ & ~1;
193
194
  // If we can handle this spread, return it.
195
4.69k
  if ((ARM_AM_rotr32(Imm, RotAmt) & ~255U) == 0)
196
2.59k
    return (32 - RotAmt) & 31; // HW rotates right, not left.
197
198
  // For values like 0xF000000F, we should ignore the low 6 bits, then
199
  // retry the hunt.
200
2.09k
  if (Imm & 63U) {
201
2.09k
    unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
202
2.09k
    unsigned RotAmt2 = TZ2 & ~1;
203
2.09k
    if ((ARM_AM_rotr32(Imm, RotAmt2) & ~255U) == 0)
204
2.09k
      return (32 - RotAmt2) &
205
2.09k
             31; // HW rotates right, not left.
206
2.09k
  }
207
208
  // Otherwise, we have no way to cover this span of bits with a single
209
  // shifter_op immediate.  Return a chunk of bits that will be useful to
210
  // handle.
211
0
  return (32 - RotAmt) & 31; // HW rotates right, not left.
212
2.09k
}
213
214
/// getSOImmVal - Given a 32-bit immediate, if it is something that can fit
215
/// into an shifter_operand immediate operand, return the 12-bit encoding for
216
/// it.  If not, return -1.
217
static inline int ARM_AM_getSOImmVal(unsigned Arg)
218
13.3k
{
219
  // 8-bit (or less) immediates are trivially shifter_operands with a rotate
220
  // of zero.
221
13.3k
  if ((Arg & ~255U) == 0)
222
3.92k
    return Arg;
223
224
9.38k
  unsigned RotAmt = ARM_AM_getSOImmValRotate(Arg);
225
226
  // If this cannot be handled with a single shifter_op, bail out.
227
9.38k
  if (ARM_AM_rotr32(~255U, RotAmt) & Arg)
228
0
    return -1;
229
230
  // Encode this correctly.
231
9.38k
  return ARM_AM_rotl32(Arg, RotAmt) | ((RotAmt >> 1) << 8);
232
9.38k
}
ARMMapping.c:ARM_AM_getSOImmVal
Line
Count
Source
218
6.65k
{
219
  // 8-bit (or less) immediates are trivially shifter_operands with a rotate
220
  // of zero.
221
6.65k
  if ((Arg & ~255U) == 0)
222
1.96k
    return Arg;
223
224
4.69k
  unsigned RotAmt = ARM_AM_getSOImmValRotate(Arg);
225
226
  // If this cannot be handled with a single shifter_op, bail out.
227
4.69k
  if (ARM_AM_rotr32(~255U, RotAmt) & Arg)
228
0
    return -1;
229
230
  // Encode this correctly.
231
4.69k
  return ARM_AM_rotl32(Arg, RotAmt) | ((RotAmt >> 1) << 8);
232
4.69k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmVal
ARMInstPrinter.c:ARM_AM_getSOImmVal
Line
Count
Source
218
6.65k
{
219
  // 8-bit (or less) immediates are trivially shifter_operands with a rotate
220
  // of zero.
221
6.65k
  if ((Arg & ~255U) == 0)
222
1.96k
    return Arg;
223
224
4.69k
  unsigned RotAmt = ARM_AM_getSOImmValRotate(Arg);
225
226
  // If this cannot be handled with a single shifter_op, bail out.
227
4.69k
  if (ARM_AM_rotr32(~255U, RotAmt) & Arg)
228
0
    return -1;
229
230
  // Encode this correctly.
231
4.69k
  return ARM_AM_rotl32(Arg, RotAmt) | ((RotAmt >> 1) << 8);
232
4.69k
}
233
234
/// isSOImmTwoPartVal - Return true if the specified value can be obtained by
235
/// or'ing together two SOImmVal's.
236
static inline bool ARM_AM_isSOImmTwoPartVal(unsigned V)
237
0
{
238
0
  // If this can be handled with a single shifter_op, bail out.
239
0
  V = ARM_AM_rotr32(~255U, ARM_AM_getSOImmValRotate(V)) & V;
240
0
  if (V == 0)
241
0
    return false;
242
0
243
0
  // If this can be handled with two shifter_op's, accept.
244
0
  V = ARM_AM_rotr32(~255U, ARM_AM_getSOImmValRotate(V)) & V;
245
0
  return V == 0;
246
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_isSOImmTwoPartVal
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_isSOImmTwoPartVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isSOImmTwoPartVal
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_isSOImmTwoPartVal
247
248
/// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal,
249
/// return the first chunk of it.
250
static inline unsigned ARM_AM_getSOImmTwoPartFirst(unsigned V)
251
0
{
252
0
  return ARM_AM_rotr32(255U, ARM_AM_getSOImmValRotate(V)) & V;
253
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getSOImmTwoPartFirst
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmTwoPartFirst
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmTwoPartFirst
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getSOImmTwoPartFirst
254
255
/// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal,
256
/// return the second chunk of it.
257
static inline unsigned ARM_AM_getSOImmTwoPartSecond(unsigned V)
258
0
{
259
0
  // Mask out the first hunk.
260
0
  V = ARM_AM_rotr32(~255U, ARM_AM_getSOImmValRotate(V)) & V;
261
0
262
0
  // Take what's left.
263
0
264
0
  return V;
265
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getSOImmTwoPartSecond
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmTwoPartSecond
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmTwoPartSecond
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getSOImmTwoPartSecond
266
267
/// isSOImmTwoPartValNeg - Return true if the specified value can be obtained
268
/// by two SOImmVal, that -V = First + Second.
269
/// "R+V" can be optimized to (sub (sub R, First), Second).
270
/// "R=V" can be optimized to (sub (mvn R, ~(-First)), Second).
271
static inline bool ARM_AM_isSOImmTwoPartValNeg(unsigned V)
272
0
{
273
0
  unsigned First;
274
0
  if (!ARM_AM_isSOImmTwoPartVal(-V))
275
0
    return false;
276
0
  // Return false if ~(-First) is not a SoImmval.
277
0
  First = ARM_AM_getSOImmTwoPartFirst(-V);
278
0
  First = ~(-First);
279
0
  return !(ARM_AM_rotr32(~255U, ARM_AM_getSOImmValRotate(First)) & First);
280
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_isSOImmTwoPartValNeg
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_isSOImmTwoPartValNeg
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isSOImmTwoPartValNeg
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_isSOImmTwoPartValNeg
281
282
/// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
283
/// by a left shift. Returns the shift amount to use.
284
static inline unsigned ARM_AM_getThumbImmValShift(unsigned Imm)
285
0
{
286
0
  // 8-bit (or less) immediates are trivially immediate operand with a shift
287
0
  // of zero.
288
0
  if ((Imm & ~255U) == 0)
289
0
    return 0;
290
0
291
0
  // Use CTZ to compute the shift amount.
292
0
  return CountTrailingZeros_32(Imm);
293
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getThumbImmValShift
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getThumbImmValShift
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getThumbImmValShift
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getThumbImmValShift
294
295
/// isThumbImmShiftedVal - Return true if the specified value can be obtained
296
/// by left shifting a 8-bit immediate.
297
static inline bool ARM_AM_isThumbImmShiftedVal(unsigned V)
298
0
{
299
0
  // If this can be handled with
300
0
  V = (~255U << ARM_AM_getThumbImmValShift(V)) & V;
301
0
  return V == 0;
302
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_isThumbImmShiftedVal
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_isThumbImmShiftedVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isThumbImmShiftedVal
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_isThumbImmShiftedVal
303
304
/// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed
305
/// by a left shift. Returns the shift amount to use.
306
static inline unsigned ARM_AM_getThumbImm16ValShift(unsigned Imm)
307
0
{
308
0
  // 16-bit (or less) immediates are trivially immediate operand with a shift
309
0
  // of zero.
310
0
  if ((Imm & ~65535U) == 0)
311
0
    return 0;
312
0
313
0
  // Use CTZ to compute the shift amount.
314
0
  return CountTrailingZeros_32(Imm);
315
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getThumbImm16ValShift
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getThumbImm16ValShift
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getThumbImm16ValShift
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getThumbImm16ValShift
316
317
/// isThumbImm16ShiftedVal - Return true if the specified value can be
318
/// obtained by left shifting a 16-bit immediate.
319
static inline bool ARM_AM_isThumbImm16ShiftedVal(unsigned V)
320
0
{
321
0
  // If this can be handled with
322
0
  V = (~65535U << ARM_AM_getThumbImm16ValShift(V)) & V;
323
0
  return V == 0;
324
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_isThumbImm16ShiftedVal
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_isThumbImm16ShiftedVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isThumbImm16ShiftedVal
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_isThumbImm16ShiftedVal
325
326
/// getThumbImmNonShiftedVal - If V is a value that satisfies
327
/// isThumbImmShiftedVal, return the non-shiftd value.
328
static inline unsigned ARM_AM_getThumbImmNonShiftedVal(unsigned V)
329
0
{
330
0
  return V >> ARM_AM_getThumbImmValShift(V);
331
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getThumbImmNonShiftedVal
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getThumbImmNonShiftedVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getThumbImmNonShiftedVal
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getThumbImmNonShiftedVal
332
333
/// getT2SOImmValSplat - Return the 12-bit encoded representation
334
/// if the specified value can be obtained by splatting the low 8 bits
335
/// into every other byte or every byte of a 32-bit value. i.e.,
336
///     00000000 00000000 00000000 abcdefgh    control = 0
337
///     00000000 abcdefgh 00000000 abcdefgh    control = 1
338
///     abcdefgh 00000000 abcdefgh 00000000    control = 2
339
///     abcdefgh abcdefgh abcdefgh abcdefgh    control = 3
340
/// Return -1 if none of the above apply.
341
/// See ARM Reference Manual A6.3.2.
342
static inline int ARM_AM_getT2SOImmValSplatVal(unsigned V)
343
0
{
344
0
  unsigned u, Vs, Imm;
345
0
  // control = 0
346
0
  if ((V & 0xffffff00) == 0)
347
0
    return V;
348
0
349
0
  // If the value is zeroes in the first byte, just shift those off
350
0
  Vs = ((V & 0xff) == 0) ? V >> 8 : V;
351
0
  // Any passing value only has 8 bits of payload, splatted across the word
352
0
  Imm = Vs & 0xff;
353
0
  // Likewise, any passing values have the payload splatted into the 3rd byte
354
0
  u = Imm | (Imm << 16);
355
0
356
0
  // control = 1 or 2
357
0
  if (Vs == u)
358
0
    return (((Vs == V) ? 1 : 2) << 8) | Imm;
359
0
360
0
  // control = 3
361
0
  if (Vs == (u | (u << 8)))
362
0
    return (3 << 8) | Imm;
363
0
364
0
  return -1;
365
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getT2SOImmValSplatVal
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmValSplatVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmValSplatVal
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getT2SOImmValSplatVal
366
367
/// getT2SOImmValRotateVal - Return the 12-bit encoded representation if the
368
/// specified value is a rotated 8-bit value. Return -1 if no rotation
369
/// encoding is possible.
370
/// See ARM Reference Manual A6.3.2.
371
static inline int ARM_AM_getT2SOImmValRotateVal(unsigned V)
372
0
{
373
0
  unsigned RotAmt = CountLeadingZeros_32(V);
374
0
  if (RotAmt >= 24)
375
0
    return -1;
376
0
377
0
  // If 'Arg' can be handled with a single shifter_op return the value.
378
0
  if ((ARM_AM_rotr32(0xff000000U, RotAmt) & V) == V)
379
0
    return (ARM_AM_rotr32(V, 24 - RotAmt) & 0x7f) |
380
0
           ((RotAmt + 8) << 7);
381
0
382
0
  return -1;
383
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getT2SOImmValRotateVal
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmValRotateVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmValRotateVal
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getT2SOImmValRotateVal
384
385
/// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit
386
/// into a Thumb-2 shifter_operand immediate operand, return the 12-bit
387
/// encoding for it.  If not, return -1.
388
/// See ARM Reference Manual A6.3.2.
389
static inline int ARM_AM_getT2SOImmVal(unsigned Arg)
390
0
{
391
0
  // If 'Arg' is an 8-bit splat, then get the encoded value.
392
0
  int Splat = ARM_AM_getT2SOImmValSplatVal(Arg);
393
0
  if (Splat != -1)
394
0
    return Splat;
395
0
396
0
  // If 'Arg' can be handled with a single shifter_op return the value.
397
0
  int Rot = ARM_AM_getT2SOImmValRotateVal(Arg);
398
0
  if (Rot != -1)
399
0
    return Rot;
400
0
401
0
  return -1;
402
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getT2SOImmVal
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmVal
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getT2SOImmVal
403
404
static inline unsigned ARM_AM_getT2SOImmValRotate(unsigned V)
405
0
{
406
0
  if ((V & ~255U) == 0)
407
0
    return 0;
408
0
  // Use CTZ to compute the rotate amount.
409
0
  unsigned RotAmt = CountTrailingZeros_32(V);
410
0
  return (32 - RotAmt) & 31;
411
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getT2SOImmValRotate
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmValRotate
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmValRotate
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getT2SOImmValRotate
412
413
static inline bool ARM_AM_isT2SOImmTwoPartVal(unsigned Imm)
414
0
{
415
0
  unsigned V = Imm;
416
0
  // Passing values can be any combination of splat values and shifter
417
0
  // values. If this can be handled with a single shifter or splat, bail
418
0
  // out. Those should be handled directly, not with a two-part val.
419
0
  if (ARM_AM_getT2SOImmValSplatVal(V) != -1)
420
0
    return false;
421
0
  V = ARM_AM_rotr32(~255U, ARM_AM_getT2SOImmValRotate(V)) & V;
422
0
  if (V == 0)
423
0
    return false;
424
0
425
0
  // If this can be handled as an immediate, accept.
426
0
  if (ARM_AM_getT2SOImmVal(V) != -1)
427
0
    return true;
428
0
429
0
  // Likewise, try masking out a splat value first.
430
0
  V = Imm;
431
0
  if (ARM_AM_getT2SOImmValSplatVal(V & 0xff00ff00U) != -1)
432
0
    V &= ~0xff00ff00U;
433
0
  else if (ARM_AM_getT2SOImmValSplatVal(V & 0x00ff00ffU) != -1)
434
0
    V &= ~0x00ff00ffU;
435
0
  // If what's left can be handled as an immediate, accept.
436
0
  if (ARM_AM_getT2SOImmVal(V) != -1)
437
0
    return true;
438
0
439
0
  // Otherwise, do not accept.
440
0
  return false;
441
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_isT2SOImmTwoPartVal
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_isT2SOImmTwoPartVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isT2SOImmTwoPartVal
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_isT2SOImmTwoPartVal
442
443
static inline unsigned ARM_AM_getT2SOImmTwoPartFirst(unsigned Imm)
444
0
{
445
0
  // Try a shifter operand as one part
446
0
  unsigned V = ARM_AM_rotr32(~255, ARM_AM_getT2SOImmValRotate(Imm)) & Imm;
447
0
  // If the rest is encodable as an immediate, then return it.
448
0
  if (ARM_AM_getT2SOImmVal(V) != -1)
449
0
    return V;
450
0
451
0
  // Try masking out a splat value first.
452
0
  if (ARM_AM_getT2SOImmValSplatVal(Imm & 0xff00ff00U) != -1)
453
0
    return Imm & 0xff00ff00U;
454
0
455
0
  // The other splat is all that's left as an option.
456
0
457
0
  return Imm & 0x00ff00ffU;
458
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getT2SOImmTwoPartFirst
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmTwoPartFirst
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmTwoPartFirst
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getT2SOImmTwoPartFirst
459
460
static inline unsigned ARM_AM_getT2SOImmTwoPartSecond(unsigned Imm)
461
0
{
462
0
  // Mask out the first hunk
463
0
  Imm ^= ARM_AM_getT2SOImmTwoPartFirst(Imm);
464
0
  // Return what's left
465
0
466
0
  return Imm;
467
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getT2SOImmTwoPartSecond
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmTwoPartSecond
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmTwoPartSecond
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getT2SOImmTwoPartSecond
468
469
//===--------------------------------------------------------------------===//
470
// Addressing Mode #2
471
//===--------------------------------------------------------------------===//
472
//
473
// This is used for most simple load/store instructions.
474
//
475
// addrmode2 := reg +/- reg shop imm
476
// addrmode2 := reg +/- imm12
477
//
478
// The first operand is always a Reg.  The second operand is a reg if in
479
// reg/reg form, otherwise it's reg#0.  The third field encodes the operation
480
// in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
481
// fourth operand 16-17 encodes the index mode.
482
//
483
// If this addressing mode is a frame index (before prolog/epilog insertion
484
// and code rewriting), this operand will have the form:  FI#, reg0, <offs>
485
// with no shift amount for the frame offset.
486
//
487
static inline unsigned ARM_AM_getAM2Opc(ARM_AM_AddrOpc Opc, unsigned Imm12,
488
          ARM_AM_ShiftOpc SO, unsigned IdxMode)
489
31.1k
{
490
31.1k
  bool isSub = Opc == ARM_AM_sub;
491
31.1k
  return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16);
492
31.1k
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM2Opc
ARMDisassembler.c:ARM_AM_getAM2Opc
Line
Count
Source
489
31.1k
{
490
31.1k
  bool isSub = Opc == ARM_AM_sub;
491
31.1k
  return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16);
492
31.1k
}
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2Opc
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM2Opc
493
494
static inline unsigned ARM_AM_getAM2Offset(unsigned AM2Opc)
495
26.8k
{
496
26.8k
  return AM2Opc & ((1 << 12) - 1);
497
26.8k
}
ARMMapping.c:ARM_AM_getAM2Offset
Line
Count
Source
495
14.8k
{
496
14.8k
  return AM2Opc & ((1 << 12) - 1);
497
14.8k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM2Offset
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2Offset
ARMInstPrinter.c:ARM_AM_getAM2Offset
Line
Count
Source
495
11.9k
{
496
11.9k
  return AM2Opc & ((1 << 12) - 1);
497
11.9k
}
498
499
static inline ARM_AM_AddrOpc ARM_AM_getAM2Op(unsigned AM2Opc)
500
23.3k
{
501
23.3k
  return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add;
502
23.3k
}
ARMMapping.c:ARM_AM_getAM2Op
Line
Count
Source
500
11.6k
{
501
11.6k
  return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add;
502
11.6k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM2Op
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2Op
ARMInstPrinter.c:ARM_AM_getAM2Op
Line
Count
Source
500
11.6k
{
501
11.6k
  return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add;
502
11.6k
}
503
504
static inline ARM_AM_ShiftOpc ARM_AM_getAM2ShiftOpc(unsigned AM2Opc)
505
12.9k
{
506
12.9k
  return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7);
507
12.9k
}
ARMMapping.c:ARM_AM_getAM2ShiftOpc
Line
Count
Source
505
6.46k
{
506
6.46k
  return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7);
507
6.46k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM2ShiftOpc
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2ShiftOpc
ARMInstPrinter.c:ARM_AM_getAM2ShiftOpc
Line
Count
Source
505
6.46k
{
506
6.46k
  return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7);
507
6.46k
}
508
509
static inline unsigned ARM_AM_getAM2IdxMode(unsigned AM2Opc)
510
0
{
511
0
  return (AM2Opc >> 16);
512
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM2IdxMode
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM2IdxMode
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2IdxMode
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM2IdxMode
513
514
//===--------------------------------------------------------------------===//
515
// Addressing Mode #3
516
//===--------------------------------------------------------------------===//
517
//
518
// This is used for sign-extending loads, and load/store-pair instructions.
519
//
520
// addrmode3 := reg +/- reg
521
// addrmode3 := reg +/- imm8
522
//
523
// The first operand is always a Reg.  The second operand is a reg if in
524
// reg/reg form, otherwise it's reg#0.  The third field encodes the operation
525
// in bit 8, the immediate in bits 0-7. The fourth operand 9-10 encodes the
526
// index mode.
527
/// getAM3Opc - This function encodes the addrmode3 opc field.
528
static inline unsigned ARM_AM_getAM3Opc(ARM_AM_AddrOpc Opc,
529
          unsigned char Offset, unsigned IdxMode)
530
0
{
531
0
  bool isSub = Opc == ARM_AM_sub;
532
0
  return ((int)isSub << 8) | Offset | (IdxMode << 9);
533
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM3Opc
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM3Opc
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM3Opc
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM3Opc
534
535
static inline unsigned char ARM_AM_getAM3Offset(unsigned AM3Opc)
536
9.34k
{
537
9.34k
  return AM3Opc & 0xFF;
538
9.34k
}
ARMMapping.c:ARM_AM_getAM3Offset
Line
Count
Source
536
4.67k
{
537
4.67k
  return AM3Opc & 0xFF;
538
4.67k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM3Offset
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM3Offset
ARMInstPrinter.c:ARM_AM_getAM3Offset
Line
Count
Source
536
4.67k
{
537
4.67k
  return AM3Opc & 0xFF;
538
4.67k
}
539
540
static inline ARM_AM_AddrOpc ARM_AM_getAM3Op(unsigned AM3Opc)
541
20.6k
{
542
20.6k
  return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
543
20.6k
}
ARMMapping.c:ARM_AM_getAM3Op
Line
Count
Source
541
10.3k
{
542
10.3k
  return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
543
10.3k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM3Op
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM3Op
ARMInstPrinter.c:ARM_AM_getAM3Op
Line
Count
Source
541
10.3k
{
542
10.3k
  return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
543
10.3k
}
544
545
static inline unsigned ARM_AM_getAM3IdxMode(unsigned AM3Opc)
546
0
{
547
0
  return (AM3Opc >> 9);
548
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM3IdxMode
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM3IdxMode
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM3IdxMode
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM3IdxMode
549
550
//===--------------------------------------------------------------------===//
551
// Addressing Mode #4
552
//===--------------------------------------------------------------------===//
553
//
554
// This is used for load / store multiple instructions.
555
//
556
// addrmode4 := reg, <mode>
557
//
558
// The four modes are:
559
//    IA - Increment after
560
//    IB - Increment before
561
//    DA - Decrement after
562
//    DB - Decrement before
563
// For VFP instructions, only the IA and DB modes are valid.
564
static inline ARM_AM_SubMode ARM_AM_getAM4SubMode(unsigned Mode)
565
0
{
566
0
  return (ARM_AM_SubMode)(Mode & 0x7);
567
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM4SubMode
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM4SubMode
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM4SubMode
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM4SubMode
568
569
static inline unsigned ARM_AM_getAM4ModeImm(ARM_AM_SubMode SubMode)
570
0
{
571
0
  return (int)SubMode;
572
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM4ModeImm
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM4ModeImm
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM4ModeImm
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM4ModeImm
573
574
//===--------------------------------------------------------------------===//
575
// Addressing Mode #5
576
//===--------------------------------------------------------------------===//
577
//
578
// This is used for coprocessor instructions, such as FP load/stores.
579
//
580
// addrmode5 := reg +/- imm8*4
581
//
582
// The first operand is always a Reg.  The second operand encodes the
583
// operation (add or subtract) in bit 8 and the immediate in bits 0-7.
584
/// getAM5Opc - This function encodes the addrmode5 opc field.
585
static inline unsigned ARM_AM_getAM5Opc(ARM_AM_AddrOpc Opc,
586
          unsigned char Offset)
587
38.4k
{
588
38.4k
  bool isSub = Opc == ARM_AM_sub;
589
38.4k
  return ((int)isSub << 8) | Offset;
590
38.4k
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM5Opc
ARMDisassembler.c:ARM_AM_getAM5Opc
Line
Count
Source
587
38.4k
{
588
38.4k
  bool isSub = Opc == ARM_AM_sub;
589
38.4k
  return ((int)isSub << 8) | Offset;
590
38.4k
}
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5Opc
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM5Opc
591
592
static inline unsigned char ARM_AM_getAM5Offset(unsigned AM5Opc)
593
60.1k
{
594
60.1k
  return AM5Opc & 0xFF;
595
60.1k
}
ARMMapping.c:ARM_AM_getAM5Offset
Line
Count
Source
593
22.0k
{
594
22.0k
  return AM5Opc & 0xFF;
595
22.0k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM5Offset
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5Offset
ARMInstPrinter.c:ARM_AM_getAM5Offset
Line
Count
Source
593
38.1k
{
594
38.1k
  return AM5Opc & 0xFF;
595
38.1k
}
596
597
static inline ARM_AM_AddrOpc ARM_AM_getAM5Op(unsigned AM5Opc)
598
60.1k
{
599
60.1k
  return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
600
60.1k
}
ARMMapping.c:ARM_AM_getAM5Op
Line
Count
Source
598
22.0k
{
599
22.0k
  return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
600
22.0k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM5Op
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5Op
ARMInstPrinter.c:ARM_AM_getAM5Op
Line
Count
Source
598
38.1k
{
599
38.1k
  return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
600
38.1k
}
601
602
//===--------------------------------------------------------------------===//
603
// Addressing Mode #5 FP16
604
//===--------------------------------------------------------------------===//
605
//
606
// This is used for coprocessor instructions, such as 16-bit FP load/stores.
607
//
608
// addrmode5fp16 := reg +/- imm8*2
609
//
610
// The first operand is always a Reg.  The second operand encodes the
611
// operation (add or subtract) in bit 8 and the immediate in bits 0-7.
612
/// getAM5FP16Opc - This function encodes the addrmode5fp16 opc field.
613
static inline unsigned ARM_AM_getAM5FP16Opc(ARM_AM_AddrOpc Opc,
614
              unsigned char Offset)
615
1.07k
{
616
1.07k
  bool isSub = Opc == ARM_AM_sub;
617
1.07k
  return ((int)isSub << 8) | Offset;
618
1.07k
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM5FP16Opc
ARMDisassembler.c:ARM_AM_getAM5FP16Opc
Line
Count
Source
615
1.07k
{
616
1.07k
  bool isSub = Opc == ARM_AM_sub;
617
1.07k
  return ((int)isSub << 8) | Offset;
618
1.07k
}
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5FP16Opc
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM5FP16Opc
619
620
static inline unsigned char ARM_AM_getAM5FP16Offset(unsigned AM5Opc)
621
936
{
622
936
  return AM5Opc & 0xFF;
623
936
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM5FP16Offset
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM5FP16Offset
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5FP16Offset
ARMInstPrinter.c:ARM_AM_getAM5FP16Offset
Line
Count
Source
621
936
{
622
936
  return AM5Opc & 0xFF;
623
936
}
624
625
static inline ARM_AM_AddrOpc ARM_AM_getAM5FP16Op(unsigned AM5Opc)
626
1.85k
{
627
1.85k
  return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
628
1.85k
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM5FP16Op
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM5FP16Op
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5FP16Op
ARMInstPrinter.c:ARM_AM_getAM5FP16Op
Line
Count
Source
626
1.85k
{
627
1.85k
  return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
628
1.85k
}
629
630
//===--------------------------------------------------------------------===//
631
// Addressing Mode #6
632
//===--------------------------------------------------------------------===//
633
//
634
// This is used for NEON load / store instructions.
635
//
636
// addrmode6 := reg with optional alignment
637
//
638
// This is stored in two operands [regaddr, align].  The first is the
639
// address register.  The second operand is the value of the alignment
640
// specifier in bytes or zero if no explicit alignment.
641
// Valid alignments depend on the specific instruction.
642
//===--------------------------------------------------------------------===//
643
// NEON/MVE Modified Immediates
644
//===--------------------------------------------------------------------===//
645
//
646
// Several NEON and MVE instructions (e.g., VMOV) take a "modified immediate"
647
// vector operand, where a small immediate encoded in the instruction
648
// specifies a full NEON vector value.  These modified immediates are
649
// represented here as encoded integers.  The low 8 bits hold the immediate
650
// value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold
651
// the "Cmode" field of the instruction.  The interfaces below treat the
652
// Op and Cmode values as a single 5-bit value.
653
static inline unsigned ARM_AM_createVMOVModImm(unsigned OpCmode, unsigned Val)
654
0
{
655
0
  return (OpCmode << 8) | Val;
656
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_createVMOVModImm
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_createVMOVModImm
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_createVMOVModImm
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_createVMOVModImm
657
658
static inline unsigned ARM_AM_getVMOVModImmOpCmode(unsigned ModImm)
659
4.75k
{
660
4.75k
  return (ModImm >> 8) & 0x1f;
661
4.75k
}
ARMMapping.c:ARM_AM_getVMOVModImmOpCmode
Line
Count
Source
659
2.37k
{
660
2.37k
  return (ModImm >> 8) & 0x1f;
661
2.37k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getVMOVModImmOpCmode
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getVMOVModImmOpCmode
ARMInstPrinter.c:ARM_AM_getVMOVModImmOpCmode
Line
Count
Source
659
2.37k
{
660
2.37k
  return (ModImm >> 8) & 0x1f;
661
2.37k
}
662
663
static inline unsigned ARM_AM_getVMOVModImmVal(unsigned ModImm)
664
4.75k
{
665
4.75k
  return ModImm & 0xff;
666
4.75k
}
ARMMapping.c:ARM_AM_getVMOVModImmVal
Line
Count
Source
664
2.37k
{
665
2.37k
  return ModImm & 0xff;
666
2.37k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getVMOVModImmVal
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getVMOVModImmVal
ARMInstPrinter.c:ARM_AM_getVMOVModImmVal
Line
Count
Source
664
2.37k
{
665
2.37k
  return ModImm & 0xff;
666
2.37k
}
667
668
/// decodeVMOVModImm - Decode a NEON/MVE modified immediate value into the
669
/// element value and the element size in bits.  (If the element size is
670
/// smaller than the vector, it is splatted into all the elements.)
671
static inline uint64_t ARM_AM_decodeVMOVModImm(unsigned ModImm,
672
                 unsigned *EltBits)
673
4.75k
{
674
4.75k
  unsigned OpCmode = ARM_AM_getVMOVModImmOpCmode(ModImm);
675
4.75k
  unsigned Imm8 = ARM_AM_getVMOVModImmVal(ModImm);
676
4.75k
  uint64_t Val = 0;
677
678
4.75k
  if (OpCmode == 0xe) {
679
    // 8-bit vector elements
680
440
    Val = Imm8;
681
440
    *EltBits = 8;
682
4.31k
  } else if ((OpCmode & 0xc) == 0x8) {
683
    // 16-bit vector elements
684
818
    unsigned ByteNum = (OpCmode & 0x6) >> 1;
685
818
    Val = Imm8 << (8 * ByteNum);
686
818
    *EltBits = 16;
687
3.49k
  } else if ((OpCmode & 0x8) == 0) {
688
    // 32-bit vector elements, zero with one byte set
689
2.36k
    unsigned ByteNum = (OpCmode & 0x6) >> 1;
690
2.36k
    Val = Imm8 << (8 * ByteNum);
691
2.36k
    *EltBits = 32;
692
2.36k
  } else if ((OpCmode & 0xe) == 0xc) {
693
    // 32-bit vector elements, one byte with low bits set
694
782
    unsigned ByteNum = 1 + (OpCmode & 0x1);
695
782
    Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
696
782
    *EltBits = 32;
697
782
  } else if (OpCmode == 0x1e) {
698
    // 64-bit vector elements
699
3.13k
    for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
700
2.78k
      if ((ModImm >> ByteNum) & 1)
701
1.30k
        Val |= (uint64_t)0xff << (8 * ByteNum);
702
2.78k
    }
703
348
    *EltBits = 64;
704
348
  } else {
705
0
    assert(0 && "Unsupported VMOV immediate");
706
0
  }
707
4.75k
  return Val;
708
4.75k
}
ARMMapping.c:ARM_AM_decodeVMOVModImm
Line
Count
Source
673
2.37k
{
674
2.37k
  unsigned OpCmode = ARM_AM_getVMOVModImmOpCmode(ModImm);
675
2.37k
  unsigned Imm8 = ARM_AM_getVMOVModImmVal(ModImm);
676
2.37k
  uint64_t Val = 0;
677
678
2.37k
  if (OpCmode == 0xe) {
679
    // 8-bit vector elements
680
220
    Val = Imm8;
681
220
    *EltBits = 8;
682
2.15k
  } else if ((OpCmode & 0xc) == 0x8) {
683
    // 16-bit vector elements
684
409
    unsigned ByteNum = (OpCmode & 0x6) >> 1;
685
409
    Val = Imm8 << (8 * ByteNum);
686
409
    *EltBits = 16;
687
1.74k
  } else if ((OpCmode & 0x8) == 0) {
688
    // 32-bit vector elements, zero with one byte set
689
1.18k
    unsigned ByteNum = (OpCmode & 0x6) >> 1;
690
1.18k
    Val = Imm8 << (8 * ByteNum);
691
1.18k
    *EltBits = 32;
692
1.18k
  } else if ((OpCmode & 0xe) == 0xc) {
693
    // 32-bit vector elements, one byte with low bits set
694
391
    unsigned ByteNum = 1 + (OpCmode & 0x1);
695
391
    Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
696
391
    *EltBits = 32;
697
391
  } else if (OpCmode == 0x1e) {
698
    // 64-bit vector elements
699
1.56k
    for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
700
1.39k
      if ((ModImm >> ByteNum) & 1)
701
652
        Val |= (uint64_t)0xff << (8 * ByteNum);
702
1.39k
    }
703
174
    *EltBits = 64;
704
174
  } else {
705
0
    assert(0 && "Unsupported VMOV immediate");
706
0
  }
707
2.37k
  return Val;
708
2.37k
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_decodeVMOVModImm
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_decodeVMOVModImm
ARMInstPrinter.c:ARM_AM_decodeVMOVModImm
Line
Count
Source
673
2.37k
{
674
2.37k
  unsigned OpCmode = ARM_AM_getVMOVModImmOpCmode(ModImm);
675
2.37k
  unsigned Imm8 = ARM_AM_getVMOVModImmVal(ModImm);
676
2.37k
  uint64_t Val = 0;
677
678
2.37k
  if (OpCmode == 0xe) {
679
    // 8-bit vector elements
680
220
    Val = Imm8;
681
220
    *EltBits = 8;
682
2.15k
  } else if ((OpCmode & 0xc) == 0x8) {
683
    // 16-bit vector elements
684
409
    unsigned ByteNum = (OpCmode & 0x6) >> 1;
685
409
    Val = Imm8 << (8 * ByteNum);
686
409
    *EltBits = 16;
687
1.74k
  } else if ((OpCmode & 0x8) == 0) {
688
    // 32-bit vector elements, zero with one byte set
689
1.18k
    unsigned ByteNum = (OpCmode & 0x6) >> 1;
690
1.18k
    Val = Imm8 << (8 * ByteNum);
691
1.18k
    *EltBits = 32;
692
1.18k
  } else if ((OpCmode & 0xe) == 0xc) {
693
    // 32-bit vector elements, one byte with low bits set
694
391
    unsigned ByteNum = 1 + (OpCmode & 0x1);
695
391
    Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
696
391
    *EltBits = 32;
697
391
  } else if (OpCmode == 0x1e) {
698
    // 64-bit vector elements
699
1.56k
    for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
700
1.39k
      if ((ModImm >> ByteNum) & 1)
701
652
        Val |= (uint64_t)0xff << (8 * ByteNum);
702
1.39k
    }
703
174
    *EltBits = 64;
704
174
  } else {
705
0
    assert(0 && "Unsupported VMOV immediate");
706
0
  }
707
2.37k
  return Val;
708
2.37k
}
709
710
// Generic validation for single-byte immediate (0X00, 00X0, etc).
711
static inline bool ARM_AM_isNEONBytesplat(unsigned Value, unsigned Size)
712
0
{
713
0
  unsigned count = 0;
714
0
  for (unsigned i = 0; i < Size; ++i) {
715
0
    if (Value & 0xff)
716
0
      count++;
717
0
    Value >>= 8;
718
0
  }
719
0
  return count == 1;
720
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_isNEONBytesplat
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_isNEONBytesplat
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isNEONBytesplat
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_isNEONBytesplat
721
722
/// Checks if Value is a correct immediate for instructions like VBIC/VORR.
723
static inline bool ARM_AM_isNEONi16splat(unsigned Value)
724
0
{
725
0
  if (Value > 0xffff)
726
0
    return false;
727
0
  // i16 value with set bits only in one byte X0 or 0X.
728
0
  return Value == 0 || ARM_AM_isNEONBytesplat(Value, 2);
729
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_isNEONi16splat
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_isNEONi16splat
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isNEONi16splat
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_isNEONi16splat
730
731
// Encode NEON 16 bits Splat immediate for instructions like VBIC/VORR
732
static inline unsigned ARM_AM_encodeNEONi16splat(unsigned Value)
733
0
{
734
0
  if (Value >= 0x100)
735
0
    Value = (Value >> 8) | 0xa00;
736
0
  else
737
0
    Value |= 0x800;
738
0
  return Value;
739
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_encodeNEONi16splat
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_encodeNEONi16splat
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_encodeNEONi16splat
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_encodeNEONi16splat
740
741
/// Checks if Value is a correct immediate for instructions like VBIC/VORR.
742
static inline bool ARM_AM_isNEONi32splat(unsigned Value)
743
0
{
744
0
  // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
745
0
  return Value == 0 || ARM_AM_isNEONBytesplat(Value, 4);
746
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_isNEONi32splat
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_isNEONi32splat
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isNEONi32splat
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_isNEONi32splat
747
748
/// Encode NEON 32 bits Splat immediate for instructions like VBIC/VORR.
749
static inline unsigned ARM_AM_encodeNEONi32splat(unsigned Value)
750
0
{
751
0
  if (Value >= 0x100 && Value <= 0xff00)
752
0
    Value = (Value >> 8) | 0x200;
753
0
  else if (Value > 0xffff && Value <= 0xff0000)
754
0
    Value = (Value >> 16) | 0x400;
755
0
  else if (Value > 0xffffff)
756
0
    Value = (Value >> 24) | 0x600;
757
0
  return Value;
758
0
}
Unexecuted instantiation: ARMMapping.c:ARM_AM_encodeNEONi32splat
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_encodeNEONi32splat
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_encodeNEONi32splat
Unexecuted instantiation: ARMInstPrinter.c:ARM_AM_encodeNEONi32splat
759
760
//===--------------------------------------------------------------------===//
761
// Floating-point Immediates
762
//
763
static inline float ARM_AM_getFPImmFloat(unsigned Imm)
764
1.13k
{
765
  // We expect an 8-bit binary encoding of a floating-point number here.
766
767
1.13k
  uint8_t Sign = (Imm >> 7) & 0x1;
768
1.13k
  uint8_t Exp = (Imm >> 4) & 0x7;
769
1.13k
  uint8_t Mantissa = Imm & 0xf;
770
771
  //   8-bit FP    IEEE Float Encoding
772
  //   abcd efgh   aBbbbbbc defgh000 00000000 00000000
773
  //
774
  // where B = NOT(b);
775
1.13k
  uint32_t I = 0;
776
1.13k
  I |= Sign << 31;
777
1.13k
  I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
778
1.13k
  I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
779
1.13k
  I |= (Exp & 0x3) << 23;
780
1.13k
  I |= Mantissa << 19;
781
1.13k
  return BitsToFloat(I);
782
1.13k
}
ARMMapping.c:ARM_AM_getFPImmFloat
Line
Count
Source
764
565
{
765
  // We expect an 8-bit binary encoding of a floating-point number here.
766
767
565
  uint8_t Sign = (Imm >> 7) & 0x1;
768
565
  uint8_t Exp = (Imm >> 4) & 0x7;
769
565
  uint8_t Mantissa = Imm & 0xf;
770
771
  //   8-bit FP    IEEE Float Encoding
772
  //   abcd efgh   aBbbbbbc defgh000 00000000 00000000
773
  //
774
  // where B = NOT(b);
775
565
  uint32_t I = 0;
776
565
  I |= Sign << 31;
777
565
  I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
778
565
  I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
779
565
  I |= (Exp & 0x3) << 23;
780
565
  I |= Mantissa << 19;
781
565
  return BitsToFloat(I);
782
565
}
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getFPImmFloat
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getFPImmFloat
ARMInstPrinter.c:ARM_AM_getFPImmFloat
Line
Count
Source
764
565
{
765
  // We expect an 8-bit binary encoding of a floating-point number here.
766
767
565
  uint8_t Sign = (Imm >> 7) & 0x1;
768
565
  uint8_t Exp = (Imm >> 4) & 0x7;
769
565
  uint8_t Mantissa = Imm & 0xf;
770
771
  //   8-bit FP    IEEE Float Encoding
772
  //   abcd efgh   aBbbbbbc defgh000 00000000 00000000
773
  //
774
  // where B = NOT(b);
775
565
  uint32_t I = 0;
776
565
  I |= Sign << 31;
777
565
  I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
778
565
  I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
779
565
  I |= (Exp & 0x3) << 23;
780
565
  I |= Mantissa << 19;
781
565
  return BitsToFloat(I);
782
565
}
783
784
#endif // CS_ARM_ADDRESSINGMODES_H