/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 | 48.3k | { | 
| 56 | 48.3k |   return Op == ARM_AM_sub ? "-" : ""; | 
| 57 | 48.3k | } Unexecuted instantiation: ARMMapping.c:ARM_AM_getAddrOpcStrUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAddrOpcStrUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAddrOpcStrARMInstPrinter.c:ARM_AM_getAddrOpcStr| Line | Count | Source |  | 55 | 48.3k | { |  | 56 | 48.3k |   return Op == ARM_AM_sub ? "-" : ""; |  | 57 | 48.3k | } | 
 | 
| 58 |  |  | 
| 59 |  | static inline const char *ARM_AM_getShiftOpcStr(ARM_AM_ShiftOpc Op) | 
| 60 | 27.7k | { | 
| 61 | 27.7k |   switch (Op) { | 
| 62 | 0 |   default: | 
| 63 | 0 |     assert(0 && "Unknown shift opc!"); | 
| 64 | 6.11k |   case ARM_AM_asr: | 
| 65 | 6.11k |     return "asr"; | 
| 66 | 8.73k |   case ARM_AM_lsl: | 
| 67 | 8.73k |     return "lsl"; | 
| 68 | 5.14k |   case ARM_AM_lsr: | 
| 69 | 5.14k |     return "lsr"; | 
| 70 | 5.26k |   case ARM_AM_ror: | 
| 71 | 5.26k |     return "ror"; | 
| 72 | 1.99k |   case ARM_AM_rrx: | 
| 73 | 1.99k |     return "rrx"; | 
| 74 | 499 |   case ARM_AM_uxtw: | 
| 75 | 499 |     return "uxtw"; | 
| 76 | 27.7k |   } | 
| 77 | 27.7k | } Unexecuted instantiation: ARMMapping.c:ARM_AM_getShiftOpcStrUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getShiftOpcStrUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getShiftOpcStrARMInstPrinter.c:ARM_AM_getShiftOpcStr| Line | Count | Source |  | 60 | 27.7k | { |  | 61 | 27.7k |   switch (Op) { |  | 62 | 0 |   default: |  | 63 | 0 |     assert(0 && "Unknown shift opc!"); |  | 64 | 6.11k |   case ARM_AM_asr: |  | 65 | 6.11k |     return "asr"; |  | 66 | 8.73k |   case ARM_AM_lsl: |  | 67 | 8.73k |     return "lsl"; |  | 68 | 5.14k |   case ARM_AM_lsr: |  | 69 | 5.14k |     return "lsr"; |  | 70 | 5.26k |   case ARM_AM_ror: |  | 71 | 5.26k |     return "ror"; |  | 72 | 1.99k |   case ARM_AM_rrx: |  | 73 | 1.99k |     return "rrx"; |  | 74 | 499 |   case ARM_AM_uxtw: |  | 75 | 499 |     return "uxtw"; |  | 76 | 27.7k |   } |  | 77 | 27.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_getShiftOpcEncodingUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getShiftOpcEncodingUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getShiftOpcEncodingUnexecuted 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_getAMSubModeStrUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAMSubModeStrUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAMSubModeStrUnexecuted 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 | 54.3k | { | 
| 123 | 54.3k |   return (Val >> Amt) | (Val << ((32 - Amt) & 31)); | 
| 124 | 54.3k | } ARMMapping.c:ARM_AM_rotr32| Line | Count | Source |  | 122 | 30.8k | { |  | 123 | 30.8k |   return (Val >> Amt) | (Val << ((32 - Amt) & 31)); |  | 124 | 30.8k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_rotr32Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_rotr32ARMInstPrinter.c:ARM_AM_rotr32| Line | Count | Source |  | 122 | 23.5k | { |  | 123 | 23.5k |   return (Val >> Amt) | (Val << ((32 - Amt) & 31)); |  | 124 | 23.5k | } | 
 | 
| 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 | 12.5k | { | 
| 130 | 12.5k |   return (Val << Amt) | (Val >> ((32 - Amt) & 31)); | 
| 131 | 12.5k | } ARMMapping.c:ARM_AM_rotl32| Line | Count | Source |  | 129 | 6.25k | { |  | 130 | 6.25k |   return (Val << Amt) | (Val >> ((32 - Amt) & 31)); |  | 131 | 6.25k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_rotl32Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_rotl32ARMInstPrinter.c:ARM_AM_rotl32| Line | Count | Source |  | 129 | 6.25k | { |  | 130 | 6.25k |   return (Val << Amt) | (Val >> ((32 - Amt) & 31)); |  | 131 | 6.25k | } | 
 | 
| 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_getSORegOpcUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getSORegOpcUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSORegOpcUnexecuted instantiation: ARMInstPrinter.c:ARM_AM_getSORegOpc | 
| 151 |  |  | 
| 152 |  | static inline unsigned ARM_AM_getSORegOffset(unsigned Op) | 
| 153 | 28.3k | { | 
| 154 | 28.3k |   return Op >> 3; | 
| 155 | 28.3k | } ARMMapping.c:ARM_AM_getSORegOffset| Line | Count | Source |  | 153 | 14.2k | { |  | 154 | 14.2k |   return Op >> 3; |  | 155 | 14.2k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSORegOffsetUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSORegOffsetARMInstPrinter.c:ARM_AM_getSORegOffset| Line | Count | Source |  | 153 | 14.0k | { |  | 154 | 14.0k |   return Op >> 3; |  | 155 | 14.0k | } | 
 | 
| 156 |  |  | 
| 157 |  | static inline ARM_AM_ShiftOpc ARM_AM_getSORegShOp(unsigned Op) | 
| 158 | 40.1k | { | 
| 159 | 40.1k |   return (ARM_AM_ShiftOpc)(Op & 7); | 
| 160 | 40.1k | } ARMMapping.c:ARM_AM_getSORegShOp| Line | Count | Source |  | 158 | 19.9k | { |  | 159 | 19.9k |   return (ARM_AM_ShiftOpc)(Op & 7); |  | 160 | 19.9k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSORegShOpUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSORegShOpARMInstPrinter.c:ARM_AM_getSORegShOp| Line | Count | Source |  | 158 | 20.2k | { |  | 159 | 20.2k |   return (ARM_AM_ShiftOpc)(Op & 7); |  | 160 | 20.2k | } | 
 | 
| 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_getSOImmValImmUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmValImmUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmValImmUnexecuted 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_getSOImmValRotUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmValRotUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmValRotUnexecuted 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 | 12.5k | { | 
| 182 |  |   // 8-bit (or less) immediates are trivially shifter_operands with a rotate | 
| 183 |  |   // of zero. | 
| 184 | 12.5k |   if ((Imm & ~255U) == 0) | 
| 185 | 0 |     return 0; | 
| 186 |  |  | 
| 187 |  |   // Use CTZ to compute the rotate amount. | 
| 188 | 12.5k |   unsigned TZ = CountTrailingZeros_32(Imm); | 
| 189 |  |  | 
| 190 |  |   // Rotate amount must be even.  Something like 0x200 must be rotated 8 bits, | 
| 191 |  |   // not 9. | 
| 192 | 12.5k |   unsigned RotAmt = TZ & ~1; | 
| 193 |  |  | 
| 194 |  |   // If we can handle this spread, return it. | 
| 195 | 12.5k |   if ((ARM_AM_rotr32(Imm, RotAmt) & ~255U) == 0) | 
| 196 | 7.71k |     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.79k |   if (Imm & 63U) { | 
| 201 | 4.79k |     unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U); | 
| 202 | 4.79k |     unsigned RotAmt2 = TZ2 & ~1; | 
| 203 | 4.79k |     if ((ARM_AM_rotr32(Imm, RotAmt2) & ~255U) == 0) | 
| 204 | 4.79k |       return (32 - RotAmt2) & | 
| 205 | 4.79k |              31; // HW rotates right, not left. | 
| 206 | 4.79k |   } | 
| 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.79k | } ARMMapping.c:ARM_AM_getSOImmValRotate| Line | Count | Source |  | 181 | 6.25k | { |  | 182 |  |   // 8-bit (or less) immediates are trivially shifter_operands with a rotate |  | 183 |  |   // of zero. |  | 184 | 6.25k |   if ((Imm & ~255U) == 0) |  | 185 | 0 |     return 0; |  | 186 |  |  |  | 187 |  |   // Use CTZ to compute the rotate amount. |  | 188 | 6.25k |   unsigned TZ = CountTrailingZeros_32(Imm); |  | 189 |  |  |  | 190 |  |   // Rotate amount must be even.  Something like 0x200 must be rotated 8 bits, |  | 191 |  |   // not 9. |  | 192 | 6.25k |   unsigned RotAmt = TZ & ~1; |  | 193 |  |  |  | 194 |  |   // If we can handle this spread, return it. |  | 195 | 6.25k |   if ((ARM_AM_rotr32(Imm, RotAmt) & ~255U) == 0) |  | 196 | 3.85k |     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.39k |   if (Imm & 63U) { |  | 201 | 2.39k |     unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U); |  | 202 | 2.39k |     unsigned RotAmt2 = TZ2 & ~1; |  | 203 | 2.39k |     if ((ARM_AM_rotr32(Imm, RotAmt2) & ~255U) == 0) |  | 204 | 2.39k |       return (32 - RotAmt2) & |  | 205 | 2.39k |              31; // HW rotates right, not left. |  | 206 | 2.39k |   } |  | 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.39k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmValRotateUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmValRotateARMInstPrinter.c:ARM_AM_getSOImmValRotate| Line | Count | Source |  | 181 | 6.25k | { |  | 182 |  |   // 8-bit (or less) immediates are trivially shifter_operands with a rotate |  | 183 |  |   // of zero. |  | 184 | 6.25k |   if ((Imm & ~255U) == 0) |  | 185 | 0 |     return 0; |  | 186 |  |  |  | 187 |  |   // Use CTZ to compute the rotate amount. |  | 188 | 6.25k |   unsigned TZ = CountTrailingZeros_32(Imm); |  | 189 |  |  |  | 190 |  |   // Rotate amount must be even.  Something like 0x200 must be rotated 8 bits, |  | 191 |  |   // not 9. |  | 192 | 6.25k |   unsigned RotAmt = TZ & ~1; |  | 193 |  |  |  | 194 |  |   // If we can handle this spread, return it. |  | 195 | 6.25k |   if ((ARM_AM_rotr32(Imm, RotAmt) & ~255U) == 0) |  | 196 | 3.85k |     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.39k |   if (Imm & 63U) { |  | 201 | 2.39k |     unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U); |  | 202 | 2.39k |     unsigned RotAmt2 = TZ2 & ~1; |  | 203 | 2.39k |     if ((ARM_AM_rotr32(Imm, RotAmt2) & ~255U) == 0) |  | 204 | 2.39k |       return (32 - RotAmt2) & |  | 205 | 2.39k |              31; // HW rotates right, not left. |  | 206 | 2.39k |   } |  | 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.39k | } | 
 | 
| 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 | 17.3k | { | 
| 219 |  |   // 8-bit (or less) immediates are trivially shifter_operands with a rotate | 
| 220 |  |   // of zero. | 
| 221 | 17.3k |   if ((Arg & ~255U) == 0) | 
| 222 | 4.83k |     return Arg; | 
| 223 |  |  | 
| 224 | 12.5k |   unsigned RotAmt = ARM_AM_getSOImmValRotate(Arg); | 
| 225 |  |  | 
| 226 |  |   // If this cannot be handled with a single shifter_op, bail out. | 
| 227 | 12.5k |   if (ARM_AM_rotr32(~255U, RotAmt) & Arg) | 
| 228 | 0 |     return -1; | 
| 229 |  |  | 
| 230 |  |   // Encode this correctly. | 
| 231 | 12.5k |   return ARM_AM_rotl32(Arg, RotAmt) | ((RotAmt >> 1) << 8); | 
| 232 | 12.5k | } ARMMapping.c:ARM_AM_getSOImmVal| Line | Count | Source |  | 218 | 8.67k | { |  | 219 |  |   // 8-bit (or less) immediates are trivially shifter_operands with a rotate |  | 220 |  |   // of zero. |  | 221 | 8.67k |   if ((Arg & ~255U) == 0) |  | 222 | 2.41k |     return Arg; |  | 223 |  |  |  | 224 | 6.25k |   unsigned RotAmt = ARM_AM_getSOImmValRotate(Arg); |  | 225 |  |  |  | 226 |  |   // If this cannot be handled with a single shifter_op, bail out. |  | 227 | 6.25k |   if (ARM_AM_rotr32(~255U, RotAmt) & Arg) |  | 228 | 0 |     return -1; |  | 229 |  |  |  | 230 |  |   // Encode this correctly. |  | 231 | 6.25k |   return ARM_AM_rotl32(Arg, RotAmt) | ((RotAmt >> 1) << 8); |  | 232 | 6.25k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmValARMInstPrinter.c:ARM_AM_getSOImmVal| Line | Count | Source |  | 218 | 8.67k | { |  | 219 |  |   // 8-bit (or less) immediates are trivially shifter_operands with a rotate |  | 220 |  |   // of zero. |  | 221 | 8.67k |   if ((Arg & ~255U) == 0) |  | 222 | 2.41k |     return Arg; |  | 223 |  |  |  | 224 | 6.25k |   unsigned RotAmt = ARM_AM_getSOImmValRotate(Arg); |  | 225 |  |  |  | 226 |  |   // If this cannot be handled with a single shifter_op, bail out. |  | 227 | 6.25k |   if (ARM_AM_rotr32(~255U, RotAmt) & Arg) |  | 228 | 0 |     return -1; |  | 229 |  |  |  | 230 |  |   // Encode this correctly. |  | 231 | 6.25k |   return ARM_AM_rotl32(Arg, RotAmt) | ((RotAmt >> 1) << 8); |  | 232 | 6.25k | } | 
 | 
| 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_isSOImmTwoPartValUnexecuted instantiation: ARMDisassembler.c:ARM_AM_isSOImmTwoPartValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isSOImmTwoPartValUnexecuted 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_getSOImmTwoPartFirstUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmTwoPartFirstUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmTwoPartFirstUnexecuted 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_getSOImmTwoPartSecondUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getSOImmTwoPartSecondUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getSOImmTwoPartSecondUnexecuted 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_isSOImmTwoPartValNegUnexecuted instantiation: ARMDisassembler.c:ARM_AM_isSOImmTwoPartValNegUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isSOImmTwoPartValNegUnexecuted 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_getThumbImmValShiftUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getThumbImmValShiftUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getThumbImmValShiftUnexecuted 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_isThumbImmShiftedValUnexecuted instantiation: ARMDisassembler.c:ARM_AM_isThumbImmShiftedValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isThumbImmShiftedValUnexecuted 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_getThumbImm16ValShiftUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getThumbImm16ValShiftUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getThumbImm16ValShiftUnexecuted 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_isThumbImm16ShiftedValUnexecuted instantiation: ARMDisassembler.c:ARM_AM_isThumbImm16ShiftedValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isThumbImm16ShiftedValUnexecuted 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_getThumbImmNonShiftedValUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getThumbImmNonShiftedValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getThumbImmNonShiftedValUnexecuted 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_getT2SOImmValSplatValUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmValSplatValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmValSplatValUnexecuted 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_getT2SOImmValRotateValUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmValRotateValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmValRotateValUnexecuted 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_getT2SOImmValUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmValUnexecuted 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_getT2SOImmValRotateUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmValRotateUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmValRotateUnexecuted 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_isT2SOImmTwoPartValUnexecuted instantiation: ARMDisassembler.c:ARM_AM_isT2SOImmTwoPartValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isT2SOImmTwoPartValUnexecuted 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_getT2SOImmTwoPartFirstUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmTwoPartFirstUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmTwoPartFirstUnexecuted 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_getT2SOImmTwoPartSecondUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getT2SOImmTwoPartSecondUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getT2SOImmTwoPartSecondUnexecuted 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 | 15.6k | { | 
| 490 | 15.6k |   bool isSub = Opc == ARM_AM_sub; | 
| 491 | 15.6k |   return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16); | 
| 492 | 15.6k | } Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM2OpcARMDisassembler.c:ARM_AM_getAM2Opc| Line | Count | Source |  | 489 | 15.6k | { |  | 490 | 15.6k |   bool isSub = Opc == ARM_AM_sub; |  | 491 | 15.6k |   return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16); |  | 492 | 15.6k | } | 
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2OpcUnexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM2Opc | 
| 493 |  |  | 
| 494 |  | static inline unsigned ARM_AM_getAM2Offset(unsigned AM2Opc) | 
| 495 | 33.2k | { | 
| 496 | 33.2k |   return AM2Opc & ((1 << 12) - 1); | 
| 497 | 33.2k | } ARMMapping.c:ARM_AM_getAM2Offset| Line | Count | Source |  | 495 | 18.5k | { |  | 496 | 18.5k |   return AM2Opc & ((1 << 12) - 1); |  | 497 | 18.5k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM2OffsetUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2OffsetARMInstPrinter.c:ARM_AM_getAM2Offset| Line | Count | Source |  | 495 | 14.7k | { |  | 496 | 14.7k |   return AM2Opc & ((1 << 12) - 1); |  | 497 | 14.7k | } | 
 | 
| 498 |  |  | 
| 499 |  | static inline ARM_AM_AddrOpc ARM_AM_getAM2Op(unsigned AM2Opc) | 
| 500 | 28.9k | { | 
| 501 | 28.9k |   return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add; | 
| 502 | 28.9k | } ARMMapping.c:ARM_AM_getAM2Op| Line | Count | Source |  | 500 | 14.4k | { |  | 501 | 14.4k |   return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add; |  | 502 | 14.4k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM2OpUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2OpARMInstPrinter.c:ARM_AM_getAM2Op| Line | Count | Source |  | 500 | 14.4k | { |  | 501 | 14.4k |   return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add; |  | 502 | 14.4k | } | 
 | 
| 503 |  |  | 
| 504 |  | static inline ARM_AM_ShiftOpc ARM_AM_getAM2ShiftOpc(unsigned AM2Opc) | 
| 505 | 16.4k | { | 
| 506 | 16.4k |   return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7); | 
| 507 | 16.4k | } ARMMapping.c:ARM_AM_getAM2ShiftOpc| Line | Count | Source |  | 505 | 8.23k | { |  | 506 | 8.23k |   return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7); |  | 507 | 8.23k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM2ShiftOpcUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2ShiftOpcARMInstPrinter.c:ARM_AM_getAM2ShiftOpc| Line | Count | Source |  | 505 | 8.23k | { |  | 506 | 8.23k |   return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7); |  | 507 | 8.23k | } | 
 | 
| 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_getAM2IdxModeUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM2IdxModeUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM2IdxModeUnexecuted 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_getAM3OpcUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM3OpcUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM3OpcUnexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM3Opc | 
| 534 |  |  | 
| 535 |  | static inline unsigned char ARM_AM_getAM3Offset(unsigned AM3Opc) | 
| 536 | 10.3k | { | 
| 537 | 10.3k |   return AM3Opc & 0xFF; | 
| 538 | 10.3k | } ARMMapping.c:ARM_AM_getAM3Offset| Line | Count | Source |  | 536 | 5.17k | { |  | 537 | 5.17k |   return AM3Opc & 0xFF; |  | 538 | 5.17k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM3OffsetUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM3OffsetARMInstPrinter.c:ARM_AM_getAM3Offset| Line | Count | Source |  | 536 | 5.17k | { |  | 537 | 5.17k |   return AM3Opc & 0xFF; |  | 538 | 5.17k | } | 
 | 
| 539 |  |  | 
| 540 |  | static inline ARM_AM_AddrOpc ARM_AM_getAM3Op(unsigned AM3Opc) | 
| 541 | 25.3k | { | 
| 542 | 25.3k |   return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add; | 
| 543 | 25.3k | } ARMMapping.c:ARM_AM_getAM3Op| Line | Count | Source |  | 541 | 12.6k | { |  | 542 | 12.6k |   return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add; |  | 543 | 12.6k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM3OpUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM3OpARMInstPrinter.c:ARM_AM_getAM3Op| Line | Count | Source |  | 541 | 12.6k | { |  | 542 | 12.6k |   return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add; |  | 543 | 12.6k | } | 
 | 
| 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_getAM3IdxModeUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM3IdxModeUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM3IdxModeUnexecuted 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_getAM4SubModeUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM4SubModeUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM4SubModeUnexecuted 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_getAM4ModeImmUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM4ModeImmUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM4ModeImmUnexecuted 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 | 21.3k | { | 
| 588 | 21.3k |   bool isSub = Opc == ARM_AM_sub; | 
| 589 | 21.3k |   return ((int)isSub << 8) | Offset; | 
| 590 | 21.3k | } Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM5OpcARMDisassembler.c:ARM_AM_getAM5Opc| Line | Count | Source |  | 587 | 21.3k | { |  | 588 | 21.3k |   bool isSub = Opc == ARM_AM_sub; |  | 589 | 21.3k |   return ((int)isSub << 8) | Offset; |  | 590 | 21.3k | } | 
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5OpcUnexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM5Opc | 
| 591 |  |  | 
| 592 |  | static inline unsigned char ARM_AM_getAM5Offset(unsigned AM5Opc) | 
| 593 | 43.2k | { | 
| 594 | 43.2k |   return AM5Opc & 0xFF; | 
| 595 | 43.2k | } ARMMapping.c:ARM_AM_getAM5Offset| Line | Count | Source |  | 593 | 21.9k | { |  | 594 | 21.9k |   return AM5Opc & 0xFF; |  | 595 | 21.9k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM5OffsetUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5OffsetARMInstPrinter.c:ARM_AM_getAM5Offset| Line | Count | Source |  | 593 | 21.3k | { |  | 594 | 21.3k |   return AM5Opc & 0xFF; |  | 595 | 21.3k | } | 
 | 
| 596 |  |  | 
| 597 |  | static inline ARM_AM_AddrOpc ARM_AM_getAM5Op(unsigned AM5Opc) | 
| 598 | 43.2k | { | 
| 599 | 43.2k |   return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add; | 
| 600 | 43.2k | } ARMMapping.c:ARM_AM_getAM5Op| Line | Count | Source |  | 598 | 21.9k | { |  | 599 | 21.9k |   return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add; |  | 600 | 21.9k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM5OpUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5OpARMInstPrinter.c:ARM_AM_getAM5Op| Line | Count | Source |  | 598 | 21.3k | { |  | 599 | 21.3k |   return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add; |  | 600 | 21.3k | } | 
 | 
| 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 | 876 | { | 
| 616 | 876 |   bool isSub = Opc == ARM_AM_sub; | 
| 617 | 876 |   return ((int)isSub << 8) | Offset; | 
| 618 | 876 | } Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM5FP16OpcARMDisassembler.c:ARM_AM_getAM5FP16Opc| Line | Count | Source |  | 615 | 876 | { |  | 616 | 876 |   bool isSub = Opc == ARM_AM_sub; |  | 617 | 876 |   return ((int)isSub << 8) | Offset; |  | 618 | 876 | } | 
Unexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5FP16OpcUnexecuted instantiation: ARMInstPrinter.c:ARM_AM_getAM5FP16Opc | 
| 619 |  |  | 
| 620 |  | static inline unsigned char ARM_AM_getAM5FP16Offset(unsigned AM5Opc) | 
| 621 | 660 | { | 
| 622 | 660 |   return AM5Opc & 0xFF; | 
| 623 | 660 | } Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM5FP16OffsetUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM5FP16OffsetUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5FP16OffsetARMInstPrinter.c:ARM_AM_getAM5FP16Offset| Line | Count | Source |  | 621 | 660 | { |  | 622 | 660 |   return AM5Opc & 0xFF; |  | 623 | 660 | } | 
 | 
| 624 |  |  | 
| 625 |  | static inline ARM_AM_AddrOpc ARM_AM_getAM5FP16Op(unsigned AM5Opc) | 
| 626 | 1.19k | { | 
| 627 | 1.19k |   return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add; | 
| 628 | 1.19k | } Unexecuted instantiation: ARMMapping.c:ARM_AM_getAM5FP16OpUnexecuted instantiation: ARMDisassembler.c:ARM_AM_getAM5FP16OpUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getAM5FP16OpARMInstPrinter.c:ARM_AM_getAM5FP16Op| Line | Count | Source |  | 626 | 1.19k | { |  | 627 | 1.19k |   return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add; |  | 628 | 1.19k | } | 
 | 
| 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_createVMOVModImmUnexecuted instantiation: ARMDisassembler.c:ARM_AM_createVMOVModImmUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_createVMOVModImmUnexecuted instantiation: ARMInstPrinter.c:ARM_AM_createVMOVModImm | 
| 657 |  |  | 
| 658 |  | static inline unsigned ARM_AM_getVMOVModImmOpCmode(unsigned ModImm) | 
| 659 | 10.6k | { | 
| 660 | 10.6k |   return (ModImm >> 8) & 0x1f; | 
| 661 | 10.6k | } ARMMapping.c:ARM_AM_getVMOVModImmOpCmode| Line | Count | Source |  | 659 | 5.31k | { |  | 660 | 5.31k |   return (ModImm >> 8) & 0x1f; |  | 661 | 5.31k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getVMOVModImmOpCmodeUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getVMOVModImmOpCmodeARMInstPrinter.c:ARM_AM_getVMOVModImmOpCmode| Line | Count | Source |  | 659 | 5.31k | { |  | 660 | 5.31k |   return (ModImm >> 8) & 0x1f; |  | 661 | 5.31k | } | 
 | 
| 662 |  |  | 
| 663 |  | static inline unsigned ARM_AM_getVMOVModImmVal(unsigned ModImm) | 
| 664 | 10.6k | { | 
| 665 | 10.6k |   return ModImm & 0xff; | 
| 666 | 10.6k | } ARMMapping.c:ARM_AM_getVMOVModImmVal| Line | Count | Source |  | 664 | 5.31k | { |  | 665 | 5.31k |   return ModImm & 0xff; |  | 666 | 5.31k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getVMOVModImmValUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getVMOVModImmValARMInstPrinter.c:ARM_AM_getVMOVModImmVal| Line | Count | Source |  | 664 | 5.31k | { |  | 665 | 5.31k |   return ModImm & 0xff; |  | 666 | 5.31k | } | 
 | 
| 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 | 10.6k | { | 
| 674 | 10.6k |   unsigned OpCmode = ARM_AM_getVMOVModImmOpCmode(ModImm); | 
| 675 | 10.6k |   unsigned Imm8 = ARM_AM_getVMOVModImmVal(ModImm); | 
| 676 | 10.6k |   uint64_t Val = 0; | 
| 677 |  |  | 
| 678 | 10.6k |   if (OpCmode == 0xe) { | 
| 679 |  |     // 8-bit vector elements | 
| 680 | 168 |     Val = Imm8; | 
| 681 | 168 |     *EltBits = 8; | 
| 682 | 10.4k |   } else if ((OpCmode & 0xc) == 0x8) { | 
| 683 |  |     // 16-bit vector elements | 
| 684 | 1.17k |     unsigned ByteNum = (OpCmode & 0x6) >> 1; | 
| 685 | 1.17k |     Val = Imm8 << (8 * ByteNum); | 
| 686 | 1.17k |     *EltBits = 16; | 
| 687 | 9.29k |   } else if ((OpCmode & 0x8) == 0) { | 
| 688 |  |     // 32-bit vector elements, zero with one byte set | 
| 689 | 5.25k |     unsigned ByteNum = (OpCmode & 0x6) >> 1; | 
| 690 | 5.25k |     Val = Imm8 << (8 * ByteNum); | 
| 691 | 5.25k |     *EltBits = 32; | 
| 692 | 5.25k |   } else if ((OpCmode & 0xe) == 0xc) { | 
| 693 |  |     // 32-bit vector elements, one byte with low bits set | 
| 694 | 2.58k |     unsigned ByteNum = 1 + (OpCmode & 0x1); | 
| 695 | 2.58k |     Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum))); | 
| 696 | 2.58k |     *EltBits = 32; | 
| 697 | 2.58k |   } else if (OpCmode == 0x1e) { | 
| 698 |  |     // 64-bit vector elements | 
| 699 | 13.1k |     for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) { | 
| 700 | 11.6k |       if ((ModImm >> ByteNum) & 1) | 
| 701 | 5.73k |         Val |= (uint64_t)0xff << (8 * ByteNum); | 
| 702 | 11.6k |     } | 
| 703 | 1.45k |     *EltBits = 64; | 
| 704 | 1.45k |   } else { | 
| 705 | 0 |     assert(0 && "Unsupported VMOV immediate"); | 
| 706 | 0 |   } | 
| 707 | 10.6k |   return Val; | 
| 708 | 10.6k | } ARMMapping.c:ARM_AM_decodeVMOVModImm| Line | Count | Source |  | 673 | 5.31k | { |  | 674 | 5.31k |   unsigned OpCmode = ARM_AM_getVMOVModImmOpCmode(ModImm); |  | 675 | 5.31k |   unsigned Imm8 = ARM_AM_getVMOVModImmVal(ModImm); |  | 676 | 5.31k |   uint64_t Val = 0; |  | 677 |  |  |  | 678 | 5.31k |   if (OpCmode == 0xe) { |  | 679 |  |     // 8-bit vector elements |  | 680 | 84 |     Val = Imm8; |  | 681 | 84 |     *EltBits = 8; |  | 682 | 5.23k |   } else if ((OpCmode & 0xc) == 0x8) { |  | 683 |  |     // 16-bit vector elements |  | 684 | 586 |     unsigned ByteNum = (OpCmode & 0x6) >> 1; |  | 685 | 586 |     Val = Imm8 << (8 * ByteNum); |  | 686 | 586 |     *EltBits = 16; |  | 687 | 4.64k |   } else if ((OpCmode & 0x8) == 0) { |  | 688 |  |     // 32-bit vector elements, zero with one byte set |  | 689 | 2.62k |     unsigned ByteNum = (OpCmode & 0x6) >> 1; |  | 690 | 2.62k |     Val = Imm8 << (8 * ByteNum); |  | 691 | 2.62k |     *EltBits = 32; |  | 692 | 2.62k |   } else if ((OpCmode & 0xe) == 0xc) { |  | 693 |  |     // 32-bit vector elements, one byte with low bits set |  | 694 | 1.29k |     unsigned ByteNum = 1 + (OpCmode & 0x1); |  | 695 | 1.29k |     Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum))); |  | 696 | 1.29k |     *EltBits = 32; |  | 697 | 1.29k |   } else if (OpCmode == 0x1e) { |  | 698 |  |     // 64-bit vector elements |  | 699 | 6.55k |     for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) { |  | 700 | 5.82k |       if ((ModImm >> ByteNum) & 1) |  | 701 | 2.86k |         Val |= (uint64_t)0xff << (8 * ByteNum); |  | 702 | 5.82k |     } |  | 703 | 728 |     *EltBits = 64; |  | 704 | 728 |   } else { |  | 705 | 0 |     assert(0 && "Unsupported VMOV immediate"); |  | 706 | 0 |   } |  | 707 | 5.31k |   return Val; |  | 708 | 5.31k | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_decodeVMOVModImmUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_decodeVMOVModImmARMInstPrinter.c:ARM_AM_decodeVMOVModImm| Line | Count | Source |  | 673 | 5.31k | { |  | 674 | 5.31k |   unsigned OpCmode = ARM_AM_getVMOVModImmOpCmode(ModImm); |  | 675 | 5.31k |   unsigned Imm8 = ARM_AM_getVMOVModImmVal(ModImm); |  | 676 | 5.31k |   uint64_t Val = 0; |  | 677 |  |  |  | 678 | 5.31k |   if (OpCmode == 0xe) { |  | 679 |  |     // 8-bit vector elements |  | 680 | 84 |     Val = Imm8; |  | 681 | 84 |     *EltBits = 8; |  | 682 | 5.23k |   } else if ((OpCmode & 0xc) == 0x8) { |  | 683 |  |     // 16-bit vector elements |  | 684 | 586 |     unsigned ByteNum = (OpCmode & 0x6) >> 1; |  | 685 | 586 |     Val = Imm8 << (8 * ByteNum); |  | 686 | 586 |     *EltBits = 16; |  | 687 | 4.64k |   } else if ((OpCmode & 0x8) == 0) { |  | 688 |  |     // 32-bit vector elements, zero with one byte set |  | 689 | 2.62k |     unsigned ByteNum = (OpCmode & 0x6) >> 1; |  | 690 | 2.62k |     Val = Imm8 << (8 * ByteNum); |  | 691 | 2.62k |     *EltBits = 32; |  | 692 | 2.62k |   } else if ((OpCmode & 0xe) == 0xc) { |  | 693 |  |     // 32-bit vector elements, one byte with low bits set |  | 694 | 1.29k |     unsigned ByteNum = 1 + (OpCmode & 0x1); |  | 695 | 1.29k |     Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum))); |  | 696 | 1.29k |     *EltBits = 32; |  | 697 | 1.29k |   } else if (OpCmode == 0x1e) { |  | 698 |  |     // 64-bit vector elements |  | 699 | 6.55k |     for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) { |  | 700 | 5.82k |       if ((ModImm >> ByteNum) & 1) |  | 701 | 2.86k |         Val |= (uint64_t)0xff << (8 * ByteNum); |  | 702 | 5.82k |     } |  | 703 | 728 |     *EltBits = 64; |  | 704 | 728 |   } else { |  | 705 | 0 |     assert(0 && "Unsupported VMOV immediate"); |  | 706 | 0 |   } |  | 707 | 5.31k |   return Val; |  | 708 | 5.31k | } | 
 | 
| 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_isNEONBytesplatUnexecuted instantiation: ARMDisassembler.c:ARM_AM_isNEONBytesplatUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isNEONBytesplatUnexecuted 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_isNEONi16splatUnexecuted instantiation: ARMDisassembler.c:ARM_AM_isNEONi16splatUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isNEONi16splatUnexecuted 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_encodeNEONi16splatUnexecuted instantiation: ARMDisassembler.c:ARM_AM_encodeNEONi16splatUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_encodeNEONi16splatUnexecuted 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_isNEONi32splatUnexecuted instantiation: ARMDisassembler.c:ARM_AM_isNEONi32splatUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_isNEONi32splatUnexecuted 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_encodeNEONi32splatUnexecuted instantiation: ARMDisassembler.c:ARM_AM_encodeNEONi32splatUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_encodeNEONi32splatUnexecuted instantiation: ARMInstPrinter.c:ARM_AM_encodeNEONi32splat | 
| 759 |  |  | 
| 760 |  | //===--------------------------------------------------------------------===// | 
| 761 |  | // Floating-point Immediates | 
| 762 |  | // | 
| 763 |  | static inline float ARM_AM_getFPImmFloat(unsigned Imm) | 
| 764 | 1.21k | { | 
| 765 |  |   // We expect an 8-bit binary encoding of a floating-point number here. | 
| 766 |  |  | 
| 767 | 1.21k |   uint8_t Sign = (Imm >> 7) & 0x1; | 
| 768 | 1.21k |   uint8_t Exp = (Imm >> 4) & 0x7; | 
| 769 | 1.21k |   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.21k |   uint32_t I = 0; | 
| 776 | 1.21k |   I |= Sign << 31; | 
| 777 | 1.21k |   I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; | 
| 778 | 1.21k |   I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; | 
| 779 | 1.21k |   I |= (Exp & 0x3) << 23; | 
| 780 | 1.21k |   I |= Mantissa << 19; | 
| 781 | 1.21k |   return BitsToFloat(I); | 
| 782 | 1.21k | } ARMMapping.c:ARM_AM_getFPImmFloat| Line | Count | Source |  | 764 | 608 | { |  | 765 |  |   // We expect an 8-bit binary encoding of a floating-point number here. |  | 766 |  |  |  | 767 | 608 |   uint8_t Sign = (Imm >> 7) & 0x1; |  | 768 | 608 |   uint8_t Exp = (Imm >> 4) & 0x7; |  | 769 | 608 |   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 | 608 |   uint32_t I = 0; |  | 776 | 608 |   I |= Sign << 31; |  | 777 | 608 |   I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; |  | 778 | 608 |   I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; |  | 779 | 608 |   I |= (Exp & 0x3) << 23; |  | 780 | 608 |   I |= Mantissa << 19; |  | 781 | 608 |   return BitsToFloat(I); |  | 782 | 608 | } | 
Unexecuted instantiation: ARMDisassembler.c:ARM_AM_getFPImmFloatUnexecuted instantiation: ARMDisassemblerExtension.c:ARM_AM_getFPImmFloatARMInstPrinter.c:ARM_AM_getFPImmFloat| Line | Count | Source |  | 764 | 608 | { |  | 765 |  |   // We expect an 8-bit binary encoding of a floating-point number here. |  | 766 |  |  |  | 767 | 608 |   uint8_t Sign = (Imm >> 7) & 0x1; |  | 768 | 608 |   uint8_t Exp = (Imm >> 4) & 0x7; |  | 769 | 608 |   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 | 608 |   uint32_t I = 0; |  | 776 | 608 |   I |= Sign << 31; |  | 777 | 608 |   I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; |  | 778 | 608 |   I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; |  | 779 | 608 |   I |= (Exp & 0x3) << 23; |  | 780 | 608 |   I |= Mantissa << 19; |  | 781 | 608 |   return BitsToFloat(I); |  | 782 | 608 | } | 
 | 
| 783 |  |  | 
| 784 |  | #endif // CS_ARM_ADDRESSINGMODES_H |