Rizin
unix-like reverse engineering framework and cli tools
AArch64AddressingModes.h
Go to the documentation of this file.
1 //===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the AArch64 addressing mode implementation stuff.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef CS_AARCH64_ADDRESSINGMODES_H
15 #define CS_AARCH64_ADDRESSINGMODES_H
16 
17 /* Capstone Disassembly Engine */
18 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
19 
20 #include "../../MathExtras.h"
21 
23 
24 //===----------------------------------------------------------------------===//
25 // Shifts
26 //
27 
35 
40 
46 
49 {
50  switch (ST) {
51  default: return NULL; // never reach
52  case AArch64_AM_LSL: return "lsl";
53  case AArch64_AM_LSR: return "lsr";
54  case AArch64_AM_ASR: return "asr";
55  case AArch64_AM_ROR: return "ror";
56  case AArch64_AM_MSL: return "msl";
57  case AArch64_AM_UXTB: return "uxtb";
58  case AArch64_AM_UXTH: return "uxth";
59  case AArch64_AM_UXTW: return "uxtw";
60  case AArch64_AM_UXTX: return "uxtx";
61  case AArch64_AM_SXTB: return "sxtb";
62  case AArch64_AM_SXTH: return "sxth";
63  case AArch64_AM_SXTW: return "sxtw";
64  case AArch64_AM_SXTX: return "sxtx";
65  }
66 }
67 
70 {
71  switch ((Imm >> 6) & 0x7) {
72  default: return AArch64_AM_InvalidShiftExtend;
73  case 0: return AArch64_AM_LSL;
74  case 1: return AArch64_AM_LSR;
75  case 2: return AArch64_AM_ASR;
76  case 3: return AArch64_AM_ROR;
77  case 4: return AArch64_AM_MSL;
78  }
79 }
80 
82 static inline unsigned AArch64_AM_getShiftValue(unsigned Imm)
83 {
84  return Imm & 0x3f;
85 }
86 
87 //===----------------------------------------------------------------------===//
88 // Extends
89 //
90 
92 static inline unsigned AArch64_AM_getArithShiftValue(unsigned Imm)
93 {
94  return Imm & 0x7;
95 }
96 
99 {
100  // assert((Imm & 0x7) == Imm && "invalid immediate!");
101  switch (Imm) {
102  default: // llvm_unreachable("Compiler bug!");
103  case 0: return AArch64_AM_UXTB;
104  case 1: return AArch64_AM_UXTH;
105  case 2: return AArch64_AM_UXTW;
106  case 3: return AArch64_AM_UXTX;
107  case 4: return AArch64_AM_SXTB;
108  case 5: return AArch64_AM_SXTH;
109  case 6: return AArch64_AM_SXTW;
110  case 7: return AArch64_AM_SXTX;
111  }
112 }
113 
115 {
116  return AArch64_AM_getExtendType((Imm >> 3) & 0x7);
117 }
118 
119 static inline uint64_t ror(uint64_t elt, unsigned size)
120 {
121  return ((elt & 1) << (size-1)) | (elt >> 1);
122 }
123 
127 static inline uint64_t AArch64_AM_decodeLogicalImmediate(uint64_t val, unsigned regSize)
128 {
129  // Extract the N, imms, and immr fields.
130  unsigned N = (val >> 12) & 1;
131  unsigned immr = (val >> 6) & 0x3f;
132  unsigned imms = val & 0x3f;
133  unsigned i;
134 
135  // assert((regSize == 64 || N == 0) && "undefined logical immediate encoding");
136  int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
137  // assert(len >= 0 && "undefined logical immediate encoding");
138  unsigned size = (1 << len);
139  unsigned R = immr & (size - 1);
140  unsigned S = imms & (size - 1);
141  // assert(S != size - 1 && "undefined logical immediate encoding");
142  uint64_t pattern = (1ULL << (S + 1)) - 1;
143  for (i = 0; i < R; ++i)
144  pattern = ror(pattern, size);
145 
146  // Replicate the pattern to fill the regSize.
147  while (size != regSize) {
148  pattern |= (pattern << size);
149  size *= 2;
150  }
151 
152  return pattern;
153 }
154 
158 static inline bool AArch64_AM_isValidDecodeLogicalImmediate(uint64_t val, unsigned regSize)
159 {
160  unsigned size;
161  unsigned S;
162  int len;
163  // Extract the N and imms fields needed for checking.
164  unsigned N = (val >> 12) & 1;
165  unsigned imms = val & 0x3f;
166 
167  if (regSize == 32 && N != 0) // undefined logical immediate encoding
168  return false;
169  len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
170  if (len < 0) // undefined logical immediate encoding
171  return false;
172  size = (1 << len);
173  S = imms & (size - 1);
174  if (S == size - 1) // undefined logical immediate encoding
175  return false;
176 
177  return true;
178 }
179 
180 //===----------------------------------------------------------------------===//
181 // Floating-point Immediates
182 //
183 static inline float AArch64_AM_getFPImmFloat(unsigned Imm)
184 {
185  // We expect an 8-bit binary encoding of a floating-point number here.
186  union {
187  uint32_t I;
188  float F;
189  } FPUnion;
190 
191  uint8_t Sign = (Imm >> 7) & 0x1;
192  uint8_t Exp = (Imm >> 4) & 0x7;
193  uint8_t Mantissa = Imm & 0xf;
194 
195  // 8-bit FP iEEEE Float Encoding
196  // abcd efgh aBbbbbbc defgh000 00000000 00000000
197  //
198  // where B = NOT(b);
199 
200  FPUnion.I = 0;
201  FPUnion.I |= ((uint32_t)Sign) << 31;
202  FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
203  FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
204  FPUnion.I |= (Exp & 0x3) << 23;
205  FPUnion.I |= Mantissa << 19;
206 
207  return FPUnion.F;
208 }
209 
210 //===--------------------------------------------------------------------===//
211 // AdvSIMD Modified Immediates
212 //===--------------------------------------------------------------------===//
213 
215 {
216  static const uint32_t lookup[16] = {
217  0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
218  0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
219  0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
220  0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
221  };
222  return lookup[Imm & 0x0f] | ((uint64_t)lookup[Imm >> 4] << 32);
223 }
224 
225 #endif
size_t len
Definition: 6502dis.c:15
static unsigned AArch64_AM_getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static uint64_t ror(uint64_t elt, unsigned size)
static const char * AArch64_AM_getShiftExtendName(AArch64_AM_ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
static uint64_t AArch64_AM_decodeLogicalImmediate(uint64_t val, unsigned regSize)
static uint64_t AArch64_AM_decodeAdvSIMDModImmType10(uint8_t Imm)
static AArch64_AM_ShiftExtendType AArch64_AM_getExtendType(unsigned Imm)
getExtendType - Extract the extend type for operands of arithmetic ops.
AArch64_AM_ShiftExtendType
AArch64_AM - AArch64 Addressing Mode Stuff.
@ AArch64_AM_UXTH
@ AArch64_AM_MSL
@ AArch64_AM_SXTB
@ AArch64_AM_UXTB
@ AArch64_AM_LSL
@ AArch64_AM_SXTH
@ AArch64_AM_LSR
@ AArch64_AM_UXTW
@ AArch64_AM_UXTX
@ AArch64_AM_ROR
@ AArch64_AM_ASR
@ AArch64_AM_InvalidShiftExtend
@ AArch64_AM_SXTW
@ AArch64_AM_SXTX
static AArch64_AM_ShiftExtendType AArch64_AM_getShiftType(unsigned Imm)
getShiftType - Extract the shift type.
static AArch64_AM_ShiftExtendType AArch64_AM_getArithExtendType(unsigned Imm)
static bool AArch64_AM_isValidDecodeLogicalImmediate(uint64_t val, unsigned regSize)
static unsigned AArch64_AM_getArithShiftValue(unsigned Imm)
getArithShiftValue - get the arithmetic shift value.
static float AArch64_AM_getFPImmFloat(unsigned Imm)
lzma_index ** i
Definition: index.h:629
#define I(x)
Definition: arc.h:164
#define R(x, b, m)
Definition: arc.h:168
static int countLeadingZeros(ut64 x)
Definition: armass64.c:107
ut16 val
Definition: armass64_const.h:6
#define NULL
Definition: cris-opc.c:27
voidpf void uLong size
Definition: ioapi.h:138
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
#define F(x)
Definition: tricore.h:111
#define N
Definition: zip_err_str.c:8
#define S
Definition: zip_err_str.c:9