Rizin
unix-like reverse engineering framework and cli tools
ARMAddressingModes.h
Go to the documentation of this file.
1 //===-- ARMAddressingModes.h - ARM 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 ARM addressing mode implementation stuff.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 /* Capstone Disassembly Engine */
15 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
16 
17 #ifndef CS_LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
18 #define CS_LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
19 
20 #include "capstone/platform.h"
21 #include "../../MathExtras.h"
22 
24 typedef enum ARM_AM_ShiftOpc {
32 
33 typedef enum ARM_AM_AddrOpc {
37 
38 static inline const char *ARM_AM_getAddrOpcStr(ARM_AM_AddrOpc Op)
39 {
40  return Op == ARM_AM_sub ? "-" : "";
41 }
42 
43 static inline const char *ARM_AM_getShiftOpcStr(ARM_AM_ShiftOpc Op)
44 {
45  switch (Op) {
46  default: return ""; //llvm_unreachable("Unknown shift opc!");
47  case ARM_AM_asr: return "asr";
48  case ARM_AM_lsl: return "lsl";
49  case ARM_AM_lsr: return "lsr";
50  case ARM_AM_ror: return "ror";
51  case ARM_AM_rrx: return "rrx";
52  }
53 }
54 
55 static inline unsigned ARM_AM_getShiftOpcEncoding(ARM_AM_ShiftOpc Op)
56 {
57  switch (Op) {
58  default: return (unsigned int)-1; //llvm_unreachable("Unknown shift opc!");
59  case ARM_AM_asr: return 2;
60  case ARM_AM_lsl: return 0;
61  case ARM_AM_lsr: return 1;
62  case ARM_AM_ror: return 3;
63  }
64 }
65 
66 typedef enum ARM_AM_AMSubMode {
71  ARM_AM_db
73 
74 static inline const char *ARM_AM_getAMSubModeStr(ARM_AM_AMSubMode Mode)
75 {
76  switch (Mode) {
77  default: return "";
78  case ARM_AM_ia: return "ia";
79  case ARM_AM_ib: return "ib";
80  case ARM_AM_da: return "da";
81  case ARM_AM_db: return "db";
82  }
83 }
84 
87 static inline unsigned rotr32(unsigned Val, unsigned Amt)
88 {
89  //assert(Amt < 32 && "Invalid rotate amount");
90  return (Val >> Amt) | (Val << ((32-Amt)&31));
91 }
92 
95 static inline unsigned rotl32(unsigned Val, unsigned Amt)
96 {
97  //assert(Amt < 32 && "Invalid rotate amount");
98  return (Val << Amt) | (Val >> ((32-Amt)&31));
99 }
100 
101 //===--------------------------------------------------------------------===//
102 // Addressing Mode #1: shift_operand with registers
103 //===--------------------------------------------------------------------===//
104 //
105 // This 'addressing mode' is used for arithmetic instructions. It can
106 // represent things like:
107 // reg
108 // reg [asr|lsl|lsr|ror|rrx] reg
109 // reg [asr|lsl|lsr|ror|rrx] imm
110 //
111 // This is stored three operands [rega, regb, opc]. The first is the base
112 // reg, the second is the shift amount (or reg0 if not present or imm). The
113 // third operand encodes the shift opcode and the imm if a reg isn't present.
114 //
115 static inline unsigned getSORegOpc(ARM_AM_ShiftOpc ShOp, unsigned Imm)
116 {
117  return ShOp | (Imm << 3);
118 }
119 
120 static inline unsigned getSORegOffset(unsigned Op)
121 {
122  return Op >> 3;
123 }
124 
125 static inline ARM_AM_ShiftOpc ARM_AM_getSORegShOp(unsigned Op)
126 {
127  return (ARM_AM_ShiftOpc)(Op & 7);
128 }
129 
132 static inline unsigned getSOImmValImm(unsigned Imm)
133 {
134  return Imm & 0xFF;
135 }
136 
139 static inline unsigned getSOImmValRot(unsigned Imm)
140 {
141  return (Imm >> 8) * 2;
142 }
143 
148 static inline unsigned getSOImmValRotate(unsigned Imm)
149 {
150  unsigned TZ, RotAmt;
151  // 8-bit (or less) immediates are trivially shifter_operands with a rotate
152  // of zero.
153  if ((Imm & ~255U) == 0) return 0;
154 
155  // Use CTZ to compute the rotate amount.
156  TZ = CountTrailingZeros_32(Imm);
157 
158  // Rotate amount must be even. Something like 0x200 must be rotated 8 bits,
159  // not 9.
160  RotAmt = TZ & ~1;
161 
162  // If we can handle this spread, return it.
163  if ((rotr32(Imm, RotAmt) & ~255U) == 0)
164  return (32-RotAmt)&31; // HW rotates right, not left.
165 
166  // For values like 0xF000000F, we should ignore the low 6 bits, then
167  // retry the hunt.
168  if (Imm & 63U) {
169  unsigned TZ2 = CountTrailingZeros_32(Imm & ~63U);
170  unsigned RotAmt2 = TZ2 & ~1;
171  if ((rotr32(Imm, RotAmt2) & ~255U) == 0)
172  return (32-RotAmt2)&31; // HW rotates right, not left.
173  }
174 
175  // Otherwise, we have no way to cover this span of bits with a single
176  // shifter_op immediate. Return a chunk of bits that will be useful to
177  // handle.
178  return (32-RotAmt)&31; // HW rotates right, not left.
179 }
180 
184 static inline int getSOImmVal(unsigned Arg)
185 {
186  unsigned RotAmt;
187  // 8-bit (or less) immediates are trivially shifter_operands with a rotate
188  // of zero.
189  if ((Arg & ~255U) == 0) return Arg;
190 
191  RotAmt = getSOImmValRotate(Arg);
192 
193  // If this cannot be handled with a single shifter_op, bail out.
194  if (rotr32(~255U, RotAmt) & Arg)
195  return -1;
196 
197  // Encode this correctly.
198  return rotl32(Arg, RotAmt) | ((RotAmt>>1) << 8);
199 }
200 
203 static inline bool isSOImmTwoPartVal(unsigned V)
204 {
205  // If this can be handled with a single shifter_op, bail out.
206  V = rotr32(~255U, getSOImmValRotate(V)) & V;
207  if (V == 0)
208  return false;
209 
210  // If this can be handled with two shifter_op's, accept.
211  V = rotr32(~255U, getSOImmValRotate(V)) & V;
212  return V == 0;
213 }
214 
217 static inline unsigned getSOImmTwoPartFirst(unsigned V)
218 {
219  return rotr32(255U, getSOImmValRotate(V)) & V;
220 }
221 
224 static inline unsigned getSOImmTwoPartSecond(unsigned V)
225 {
226  // Mask out the first hunk.
227  V = rotr32(~255U, getSOImmValRotate(V)) & V;
228 
229  // Take what's left.
230  //assert(V == (rotr32(255U, getSOImmValRotate(V)) & V));
231  return V;
232 }
233 
236 static inline unsigned getThumbImmValShift(unsigned Imm)
237 {
238  // 8-bit (or less) immediates are trivially immediate operand with a shift
239  // of zero.
240  if ((Imm & ~255U) == 0) return 0;
241 
242  // Use CTZ to compute the shift amount.
243  return CountTrailingZeros_32(Imm);
244 }
245 
248 static inline bool isThumbImmShiftedVal(unsigned V)
249 {
250  // If this can be handled with
251  V = (~255U << getThumbImmValShift(V)) & V;
252  return V == 0;
253 }
254 
257 static inline unsigned getThumbImm16ValShift(unsigned Imm)
258 {
259  // 16-bit (or less) immediates are trivially immediate operand with a shift
260  // of zero.
261  if ((Imm & ~65535U) == 0) return 0;
262 
263  // Use CTZ to compute the shift amount.
264  return CountTrailingZeros_32(Imm);
265 }
266 
269 static inline bool isThumbImm16ShiftedVal(unsigned V)
270 {
271  // If this can be handled with
272  V = (~65535U << getThumbImm16ValShift(V)) & V;
273  return V == 0;
274 }
275 
278 static inline unsigned getThumbImmNonShiftedVal(unsigned V)
279 {
280  return V >> getThumbImmValShift(V);
281 }
282 
283 
293 static inline int getT2SOImmValSplatVal(unsigned V)
294 {
295  unsigned u, Vs, Imm;
296  // control = 0
297  if ((V & 0xffffff00) == 0)
298  return V;
299 
300  // If the value is zeroes in the first byte, just shift those off
301  Vs = ((V & 0xff) == 0) ? V >> 8 : V;
302  // Any passing value only has 8 bits of payload, splatted across the word
303  Imm = Vs & 0xff;
304  // Likewise, any passing values have the payload splatted into the 3rd byte
305  u = Imm | (Imm << 16);
306 
307  // control = 1 or 2
308  if (Vs == u)
309  return (((Vs == V) ? 1 : 2) << 8) | Imm;
310 
311  // control = 3
312  if (Vs == (u | (u << 8)))
313  return (3 << 8) | Imm;
314 
315  return -1;
316 }
317 
322 static inline int getT2SOImmValRotateVal(unsigned V)
323 {
324  unsigned RotAmt = CountLeadingZeros_32(V);
325  if (RotAmt >= 24)
326  return -1;
327 
328  // If 'Arg' can be handled with a single shifter_op return the value.
329  if ((rotr32(0xff000000U, RotAmt) & V) == V)
330  return (rotr32(V, 24 - RotAmt) & 0x7f) | ((RotAmt + 8) << 7);
331 
332  return -1;
333 }
334 
339 static inline int getT2SOImmVal(unsigned Arg)
340 {
341  int Rot;
342  // If 'Arg' is an 8-bit splat, then get the encoded value.
343  int Splat = getT2SOImmValSplatVal(Arg);
344  if (Splat != -1)
345  return Splat;
346 
347  // If 'Arg' can be handled with a single shifter_op return the value.
349  if (Rot != -1)
350  return Rot;
351 
352  return -1;
353 }
354 
355 static inline unsigned getT2SOImmValRotate(unsigned V)
356 {
357  unsigned RotAmt;
358 
359  if ((V & ~255U) == 0)
360  return 0;
361 
362  // Use CTZ to compute the rotate amount.
363  RotAmt = CountTrailingZeros_32(V);
364  return (32 - RotAmt) & 31;
365 }
366 
367 static inline bool isT2SOImmTwoPartVal (unsigned Imm)
368 {
369  unsigned V = Imm;
370  // Passing values can be any combination of splat values and shifter
371  // values. If this can be handled with a single shifter or splat, bail
372  // out. Those should be handled directly, not with a two-part val.
373  if (getT2SOImmValSplatVal(V) != -1)
374  return false;
375  V = rotr32 (~255U, getT2SOImmValRotate(V)) & V;
376  if (V == 0)
377  return false;
378 
379  // If this can be handled as an immediate, accept.
380  if (getT2SOImmVal(V) != -1) return true;
381 
382  // Likewise, try masking out a splat value first.
383  V = Imm;
384  if (getT2SOImmValSplatVal(V & 0xff00ff00U) != -1)
385  V &= ~0xff00ff00U;
386  else if (getT2SOImmValSplatVal(V & 0x00ff00ffU) != -1)
387  V &= ~0x00ff00ffU;
388  // If what's left can be handled as an immediate, accept.
389  if (getT2SOImmVal(V) != -1) return true;
390 
391  // Otherwise, do not accept.
392  return false;
393 }
394 
395 static inline unsigned getT2SOImmTwoPartFirst(unsigned Imm)
396 {
397  //assert (isT2SOImmTwoPartVal(Imm) &&
398  // "Immedate cannot be encoded as two part immediate!");
399  // Try a shifter operand as one part
400  unsigned V = rotr32 (~(unsigned int)255, getT2SOImmValRotate(Imm)) & Imm;
401  // If the rest is encodable as an immediate, then return it.
402  if (getT2SOImmVal(V) != -1) return V;
403 
404  // Try masking out a splat value first.
405  if (getT2SOImmValSplatVal(Imm & 0xff00ff00U) != -1)
406  return Imm & 0xff00ff00U;
407 
408  // The other splat is all that's left as an option.
409  //assert (getT2SOImmValSplatVal(Imm & 0x00ff00ffU) != -1);
410  return Imm & 0x00ff00ffU;
411 }
412 
413 static inline unsigned getT2SOImmTwoPartSecond(unsigned Imm)
414 {
415  // Mask out the first hunk
416  Imm ^= getT2SOImmTwoPartFirst(Imm);
417  // Return what's left
418  //assert (getT2SOImmVal(Imm) != -1 &&
419  // "Unable to encode second part of T2 two part SO immediate");
420  return Imm;
421 }
422 
423 
424 //===--------------------------------------------------------------------===//
425 // Addressing Mode #2
426 //===--------------------------------------------------------------------===//
427 //
428 // This is used for most simple load/store instructions.
429 //
430 // addrmode2 := reg +/- reg shop imm
431 // addrmode2 := reg +/- imm12
432 //
433 // The first operand is always a Reg. The second operand is a reg if in
434 // reg/reg form, otherwise it's reg#0. The third field encodes the operation
435 // in bit 12, the immediate in bits 0-11, and the shift op in 13-15. The
436 // fourth operand 16-17 encodes the index mode.
437 //
438 // If this addressing mode is a frame index (before prolog/epilog insertion
439 // and code rewriting), this operand will have the form: FI#, reg0, <offs>
440 // with no shift amount for the frame offset.
441 //
442 static inline unsigned ARM_AM_getAM2Opc(ARM_AM_AddrOpc Opc, unsigned Imm12, ARM_AM_ShiftOpc SO,
443  unsigned IdxMode)
444 {
445  //assert(Imm12 < (1 << 12) && "Imm too large!");
446  bool isSub = Opc == ARM_AM_sub;
447  return Imm12 | ((int)isSub << 12) | (SO << 13) | (IdxMode << 16) ;
448 }
449 
450 static inline unsigned getAM2Offset(unsigned AM2Opc)
451 {
452  return AM2Opc & ((1 << 12)-1);
453 }
454 
455 static inline ARM_AM_AddrOpc getAM2Op(unsigned AM2Opc)
456 {
457  return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add;
458 }
459 
460 static inline ARM_AM_ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
461 {
462  return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7);
463 }
464 
465 static inline unsigned getAM2IdxMode(unsigned AM2Opc)
466 {
467  return (AM2Opc >> 16);
468 }
469 
470 //===--------------------------------------------------------------------===//
471 // Addressing Mode #3
472 //===--------------------------------------------------------------------===//
473 //
474 // This is used for sign-extending loads, and load/store-pair instructions.
475 //
476 // addrmode3 := reg +/- reg
477 // addrmode3 := reg +/- imm8
478 //
479 // The first operand is always a Reg. The second operand is a reg if in
480 // reg/reg form, otherwise it's reg#0. The third field encodes the operation
481 // in bit 8, the immediate in bits 0-7. The fourth operand 9-10 encodes the
482 // index mode.
483 
485 static inline unsigned getAM3Opc(ARM_AM_AddrOpc Opc, unsigned char Offset,
486  unsigned IdxMode)
487 {
488  bool isSub = Opc == ARM_AM_sub;
489  return ((int)isSub << 8) | Offset | (IdxMode << 9);
490 }
491 
492 static inline unsigned char getAM3Offset(unsigned AM3Opc)
493 {
494  return AM3Opc & 0xFF;
495 }
496 
497 static inline ARM_AM_AddrOpc getAM3Op(unsigned AM3Opc)
498 {
499  return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
500 }
501 
502 static inline unsigned getAM3IdxMode(unsigned AM3Opc)
503 {
504  return (AM3Opc >> 9);
505 }
506 
507 //===--------------------------------------------------------------------===//
508 // Addressing Mode #4
509 //===--------------------------------------------------------------------===//
510 //
511 // This is used for load / store multiple instructions.
512 //
513 // addrmode4 := reg, <mode>
514 //
515 // The four modes are:
516 // IA - Increment after
517 // IB - Increment before
518 // DA - Decrement after
519 // DB - Decrement before
520 // For VFP instructions, only the IA and DB modes are valid.
521 
522 static inline ARM_AM_AMSubMode getAM4SubMode(unsigned Mode)
523 {
524  return (ARM_AM_AMSubMode)(Mode & 0x7);
525 }
526 
527 static inline unsigned getAM4ModeImm(ARM_AM_AMSubMode SubMode)
528 {
529  return (int)SubMode;
530 }
531 
532 //===--------------------------------------------------------------------===//
533 // Addressing Mode #5
534 //===--------------------------------------------------------------------===//
535 //
536 // This is used for coprocessor instructions, such as FP load/stores.
537 //
538 // addrmode5 := reg +/- imm8*4
539 //
540 // The first operand is always a Reg. The second operand encodes the
541 // operation in bit 8 and the immediate in bits 0-7.
542 
544 static inline unsigned ARM_AM_getAM5Opc(ARM_AM_AddrOpc Opc, unsigned char Offset)
545 {
546  bool isSub = Opc == ARM_AM_sub;
547  return ((int)isSub << 8) | Offset;
548 }
549 static inline unsigned char ARM_AM_getAM5Offset(unsigned AM5Opc)
550 {
551  return AM5Opc & 0xFF;
552 }
553 static inline ARM_AM_AddrOpc ARM_AM_getAM5Op(unsigned AM5Opc)
554 {
555  return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
556 }
557 
558 //===--------------------------------------------------------------------===//
559 // Addressing Mode #6
560 //===--------------------------------------------------------------------===//
561 //
562 // This is used for NEON load / store instructions.
563 //
564 // addrmode6 := reg with optional alignment
565 //
566 // This is stored in two operands [regaddr, align]. The first is the
567 // address register. The second operand is the value of the alignment
568 // specifier in bytes or zero if no explicit alignment.
569 // Valid alignments depend on the specific instruction.
570 
571 //===--------------------------------------------------------------------===//
572 // NEON Modified Immediates
573 //===--------------------------------------------------------------------===//
574 //
575 // Several NEON instructions (e.g., VMOV) take a "modified immediate"
576 // vector operand, where a small immediate encoded in the instruction
577 // specifies a full NEON vector value. These modified immediates are
578 // represented here as encoded integers. The low 8 bits hold the immediate
579 // value; bit 12 holds the "Op" field of the instruction, and bits 11-8 hold
580 // the "Cmode" field of the instruction. The interfaces below treat the
581 // Op and Cmode values as a single 5-bit value.
582 
583 static inline unsigned createNEONModImm(unsigned OpCmode, unsigned Val)
584 {
585  return (OpCmode << 8) | Val;
586 }
587 static inline unsigned getNEONModImmOpCmode(unsigned ModImm)
588 {
589  return (ModImm >> 8) & 0x1f;
590 }
591 static inline unsigned getNEONModImmVal(unsigned ModImm)
592 {
593  return ModImm & 0xff;
594 }
595 
599 static inline uint64_t ARM_AM_decodeNEONModImm(unsigned ModImm, unsigned *EltBits)
600 {
601  unsigned OpCmode = getNEONModImmOpCmode(ModImm);
602  unsigned Imm8 = getNEONModImmVal(ModImm);
603  uint64_t Val = 0;
604  unsigned ByteNum;
605 
606  if (OpCmode == 0xe) {
607  // 8-bit vector elements
608  Val = Imm8;
609  *EltBits = 8;
610  } else if ((OpCmode & 0xc) == 0x8) {
611  // 16-bit vector elements
612  ByteNum = (OpCmode & 0x6) >> 1;
613  Val = (uint64_t)Imm8 << (8 * ByteNum);
614  *EltBits = 16;
615  } else if ((OpCmode & 0x8) == 0) {
616  // 32-bit vector elements, zero with one byte set
617  ByteNum = (OpCmode & 0x6) >> 1;
618  Val = (uint64_t)Imm8 << (8 * ByteNum);
619  *EltBits = 32;
620  } else if ((OpCmode & 0xe) == 0xc) {
621  // 32-bit vector elements, one byte with low bits set
622  ByteNum = 1 + (OpCmode & 0x1);
623  Val = (Imm8 << (8 * ByteNum)) | (0xffff >> (8 * (2 - ByteNum)));
624  *EltBits = 32;
625  } else if (OpCmode == 0x1e) {
626  // 64-bit vector elements
627  for (ByteNum = 0; ByteNum < 8; ++ByteNum) {
628  if ((ModImm >> ByteNum) & 1)
629  Val |= (uint64_t)0xff << (8 * ByteNum);
630  }
631  *EltBits = 64;
632  } else {
633  //llvm_unreachable("Unsupported NEON immediate");
634  }
635  return Val;
636 }
637 
639 
640 //===--------------------------------------------------------------------===//
641 // Floating-point Immediates
642 //
643 static inline float getFPImmFloat(unsigned Imm)
644 {
645  // We expect an 8-bit binary encoding of a floating-point number here.
646  union {
647  uint32_t I;
648  float F;
649  } FPUnion;
650 
651  uint8_t Sign = (Imm >> 7) & 0x1;
652  uint8_t Exp = (Imm >> 4) & 0x7;
653  uint8_t Mantissa = Imm & 0xf;
654 
655  // 8-bit FP iEEEE Float Encoding
656  // abcd efgh aBbbbbbc defgh000 00000000 00000000
657  //
658  // where B = NOT(b);
659 
660  FPUnion.I = 0;
661  FPUnion.I |= ((uint32_t) Sign) << 31;
662  FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
663  FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
664  FPUnion.I |= (Exp & 0x3) << 23;
665  FPUnion.I |= Mantissa << 19;
666  return FPUnion.F;
667 }
668 
669 #endif
670 
static uint64_t ARM_AM_decodeNEONModImm(unsigned ModImm, unsigned *EltBits)
static unsigned getAM4ModeImm(ARM_AM_AMSubMode SubMode)
ARM_AM_AMSubMode getLoadStoreMultipleSubMode(int Opcode)
static unsigned getSORegOpc(ARM_AM_ShiftOpc ShOp, unsigned Imm)
static unsigned getAM2IdxMode(unsigned AM2Opc)
static unsigned getNEONModImmOpCmode(unsigned ModImm)
static unsigned ARM_AM_getAM5Opc(ARM_AM_AddrOpc Opc, unsigned char Offset)
getAM5Opc - This function encodes the addrmode5 opc field.
static int getT2SOImmValSplatVal(unsigned V)
static unsigned ARM_AM_getShiftOpcEncoding(ARM_AM_ShiftOpc Op)
static ARM_AM_ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
static bool isT2SOImmTwoPartVal(unsigned Imm)
static ARM_AM_AMSubMode getAM4SubMode(unsigned Mode)
static unsigned getSOImmValRot(unsigned Imm)
static unsigned char getAM3Offset(unsigned AM3Opc)
static unsigned getSOImmValImm(unsigned Imm)
static unsigned getAM3IdxMode(unsigned AM3Opc)
static unsigned getSOImmTwoPartSecond(unsigned V)
static bool isThumbImm16ShiftedVal(unsigned V)
static unsigned getThumbImm16ValShift(unsigned Imm)
static const char * ARM_AM_getAMSubModeStr(ARM_AM_AMSubMode Mode)
static unsigned getSORegOffset(unsigned Op)
static unsigned createNEONModImm(unsigned OpCmode, unsigned Val)
static ARM_AM_ShiftOpc ARM_AM_getSORegShOp(unsigned Op)
static unsigned ARM_AM_getAM2Opc(ARM_AM_AddrOpc Opc, unsigned Imm12, ARM_AM_ShiftOpc SO, unsigned IdxMode)
static int getT2SOImmValRotateVal(unsigned V)
static unsigned getNEONModImmVal(unsigned ModImm)
static unsigned getSOImmValRotate(unsigned Imm)
static const char * ARM_AM_getAddrOpcStr(ARM_AM_AddrOpc Op)
static unsigned getThumbImmValShift(unsigned Imm)
static unsigned getT2SOImmTwoPartSecond(unsigned Imm)
ARM_AM_ShiftOpc
ARM_AM - ARM Addressing Mode Stuff.
@ ARM_AM_rrx
@ ARM_AM_ror
@ ARM_AM_lsl
@ ARM_AM_lsr
@ ARM_AM_no_shift
@ ARM_AM_asr
static unsigned rotr32(unsigned Val, unsigned Amt)
static const char * ARM_AM_getShiftOpcStr(ARM_AM_ShiftOpc Op)
static unsigned char ARM_AM_getAM5Offset(unsigned AM5Opc)
static unsigned getAM3Opc(ARM_AM_AddrOpc Opc, unsigned char Offset, unsigned IdxMode)
getAM3Opc - This function encodes the addrmode3 opc field.
static ARM_AM_AddrOpc getAM2Op(unsigned AM2Opc)
static ARM_AM_AddrOpc getAM3Op(unsigned AM3Opc)
static ARM_AM_AddrOpc ARM_AM_getAM5Op(unsigned AM5Opc)
static int getSOImmVal(unsigned Arg)
ARM_AM_AMSubMode
@ ARM_AM_ib
@ ARM_AM_bad_am_submode
@ ARM_AM_db
@ ARM_AM_ia
@ ARM_AM_da
static unsigned getAM2Offset(unsigned AM2Opc)
static int getT2SOImmVal(unsigned Arg)
static unsigned getThumbImmNonShiftedVal(unsigned V)
ARM_AM_AddrOpc
@ ARM_AM_sub
@ ARM_AM_add
static bool isSOImmTwoPartVal(unsigned V)
static unsigned getSOImmTwoPartFirst(unsigned V)
static unsigned getT2SOImmTwoPartFirst(unsigned Imm)
static unsigned rotl32(unsigned Val, unsigned Amt)
static float getFPImmFloat(unsigned Imm)
static bool isThumbImmShiftedVal(unsigned V)
static unsigned getT2SOImmValRotate(unsigned V)
static unsigned CountLeadingZeros_32(uint32_t Value)
Definition: MathExtras.h:95
static unsigned CountTrailingZeros_32(uint32_t Value)
Definition: MathExtras.h:190
#define I(x)
Definition: arc.h:164
static ut32 Offset
Definition: asm_arc.c:20
static int
Definition: sfsocketcall.h:114
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
Definition: spp.h:121
#define V(handle, symbol)
#define F(x)
Definition: tricore.h:111