Rizin
unix-like reverse engineering framework and cli tools
ARMAddressingModes.h File Reference
#include "capstone/platform.h"
#include "../../MathExtras.h"

Go to the source code of this file.

Typedefs

typedef enum ARM_AM_ShiftOpc ARM_AM_ShiftOpc
 ARM_AM - ARM Addressing Mode Stuff. More...
 
typedef enum ARM_AM_AddrOpc ARM_AM_AddrOpc
 
typedef enum ARM_AM_AMSubMode ARM_AM_AMSubMode
 

Enumerations

enum  ARM_AM_ShiftOpc {
  ARM_AM_no_shift = 0 , ARM_AM_asr , ARM_AM_lsl , ARM_AM_lsr ,
  ARM_AM_ror , ARM_AM_rrx
}
 ARM_AM - ARM Addressing Mode Stuff. More...
 
enum  ARM_AM_AddrOpc { ARM_AM_sub = 0 , ARM_AM_add }
 
enum  ARM_AM_AMSubMode {
  ARM_AM_bad_am_submode = 0 , ARM_AM_ia , ARM_AM_ib , ARM_AM_da ,
  ARM_AM_db
}
 

Functions

static const char * ARM_AM_getAddrOpcStr (ARM_AM_AddrOpc Op)
 
static const char * ARM_AM_getShiftOpcStr (ARM_AM_ShiftOpc Op)
 
static unsigned ARM_AM_getShiftOpcEncoding (ARM_AM_ShiftOpc Op)
 
static const char * ARM_AM_getAMSubModeStr (ARM_AM_AMSubMode Mode)
 
static unsigned rotr32 (unsigned Val, unsigned Amt)
 
static unsigned rotl32 (unsigned Val, unsigned Amt)
 
static unsigned getSORegOpc (ARM_AM_ShiftOpc ShOp, unsigned Imm)
 
static unsigned getSORegOffset (unsigned Op)
 
static ARM_AM_ShiftOpc ARM_AM_getSORegShOp (unsigned Op)
 
static unsigned getSOImmValImm (unsigned Imm)
 
static unsigned getSOImmValRot (unsigned Imm)
 
static unsigned getSOImmValRotate (unsigned Imm)
 
static int getSOImmVal (unsigned Arg)
 
static bool isSOImmTwoPartVal (unsigned V)
 
static unsigned getSOImmTwoPartFirst (unsigned V)
 
static unsigned getSOImmTwoPartSecond (unsigned V)
 
static unsigned getThumbImmValShift (unsigned Imm)
 
static bool isThumbImmShiftedVal (unsigned V)
 
static unsigned getThumbImm16ValShift (unsigned Imm)
 
static bool isThumbImm16ShiftedVal (unsigned V)
 
static unsigned getThumbImmNonShiftedVal (unsigned V)
 
static int getT2SOImmValSplatVal (unsigned V)
 
static int getT2SOImmValRotateVal (unsigned V)
 
static int getT2SOImmVal (unsigned Arg)
 
static unsigned getT2SOImmValRotate (unsigned V)
 
static bool isT2SOImmTwoPartVal (unsigned Imm)
 
static unsigned getT2SOImmTwoPartFirst (unsigned Imm)
 
static unsigned getT2SOImmTwoPartSecond (unsigned Imm)
 
static unsigned ARM_AM_getAM2Opc (ARM_AM_AddrOpc Opc, unsigned Imm12, ARM_AM_ShiftOpc SO, unsigned IdxMode)
 
static unsigned getAM2Offset (unsigned AM2Opc)
 
static ARM_AM_AddrOpc getAM2Op (unsigned AM2Opc)
 
static ARM_AM_ShiftOpc getAM2ShiftOpc (unsigned AM2Opc)
 
static unsigned getAM2IdxMode (unsigned AM2Opc)
 
static unsigned getAM3Opc (ARM_AM_AddrOpc Opc, unsigned char Offset, unsigned IdxMode)
 getAM3Opc - This function encodes the addrmode3 opc field. More...
 
static unsigned char getAM3Offset (unsigned AM3Opc)
 
static ARM_AM_AddrOpc getAM3Op (unsigned AM3Opc)
 
static unsigned getAM3IdxMode (unsigned AM3Opc)
 
static ARM_AM_AMSubMode getAM4SubMode (unsigned Mode)
 
static unsigned getAM4ModeImm (ARM_AM_AMSubMode SubMode)
 
static unsigned ARM_AM_getAM5Opc (ARM_AM_AddrOpc Opc, unsigned char Offset)
 getAM5Opc - This function encodes the addrmode5 opc field. More...
 
static unsigned char ARM_AM_getAM5Offset (unsigned AM5Opc)
 
static ARM_AM_AddrOpc ARM_AM_getAM5Op (unsigned AM5Opc)
 
static unsigned createNEONModImm (unsigned OpCmode, unsigned Val)
 
static unsigned getNEONModImmOpCmode (unsigned ModImm)
 
static unsigned getNEONModImmVal (unsigned ModImm)
 
static uint64_t ARM_AM_decodeNEONModImm (unsigned ModImm, unsigned *EltBits)
 
ARM_AM_AMSubMode getLoadStoreMultipleSubMode (int Opcode)
 
static float getFPImmFloat (unsigned Imm)
 

Typedef Documentation

◆ ARM_AM_AddrOpc

◆ ARM_AM_AMSubMode

◆ ARM_AM_ShiftOpc

ARM_AM - ARM Addressing Mode Stuff.

Enumeration Type Documentation

◆ ARM_AM_AddrOpc

Enumerator
ARM_AM_sub 
ARM_AM_add 

Definition at line 33 of file ARMAddressingModes.h.

33  {
34  ARM_AM_sub = 0,
ARM_AM_AddrOpc
@ ARM_AM_sub
@ ARM_AM_add

◆ ARM_AM_AMSubMode

Enumerator
ARM_AM_bad_am_submode 
ARM_AM_ia 
ARM_AM_ib 
ARM_AM_da 
ARM_AM_db 

Definition at line 66 of file ARMAddressingModes.h.

66  {
68  ARM_AM_ia,
69  ARM_AM_ib,
70  ARM_AM_da,
71  ARM_AM_db
ARM_AM_AMSubMode
@ ARM_AM_ib
@ ARM_AM_bad_am_submode
@ ARM_AM_db
@ ARM_AM_ia
@ ARM_AM_da

◆ ARM_AM_ShiftOpc

ARM_AM - ARM Addressing Mode Stuff.

Enumerator
ARM_AM_no_shift 
ARM_AM_asr 
ARM_AM_lsl 
ARM_AM_lsr 
ARM_AM_ror 
ARM_AM_rrx 

Definition at line 24 of file ARMAddressingModes.h.

24  {
25  ARM_AM_no_shift = 0,
26  ARM_AM_asr,
27  ARM_AM_lsl,
28  ARM_AM_lsr,
29  ARM_AM_ror,
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

Function Documentation

◆ ARM_AM_decodeNEONModImm()

static uint64_t ARM_AM_decodeNEONModImm ( unsigned  ModImm,
unsigned EltBits 
)
inlinestatic

decodeNEONModImm - Decode a NEON modified immediate value into the element value and the element size in bits. (If the element size is smaller than the vector, it is splatted into all the elements.)

Definition at line 599 of file ARMAddressingModes.h.

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 }
static unsigned getNEONModImmOpCmode(unsigned ModImm)
static unsigned getNEONModImmVal(unsigned ModImm)
unsigned long uint64_t
Definition: sftypes.h:28

References getNEONModImmOpCmode(), and getNEONModImmVal().

◆ ARM_AM_getAddrOpcStr()

static const char* ARM_AM_getAddrOpcStr ( ARM_AM_AddrOpc  Op)
inlinestatic

Definition at line 38 of file ARMAddressingModes.h.

39 {
40  return Op == ARM_AM_sub ? "-" : "";
41 }

References ARM_AM_sub.

◆ ARM_AM_getAM2Opc()

static unsigned ARM_AM_getAM2Opc ( ARM_AM_AddrOpc  Opc,
unsigned  Imm12,
ARM_AM_ShiftOpc  SO,
unsigned  IdxMode 
)
inlinestatic

Definition at line 442 of file ARMAddressingModes.h.

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 }
static int
Definition: sfsocketcall.h:114

References ARM_AM_sub, and int.

◆ ARM_AM_getAM5Offset()

static unsigned char ARM_AM_getAM5Offset ( unsigned  AM5Opc)
inlinestatic

Definition at line 549 of file ARMAddressingModes.h.

550 {
551  return AM5Opc & 0xFF;
552 }

◆ ARM_AM_getAM5Op()

static ARM_AM_AddrOpc ARM_AM_getAM5Op ( unsigned  AM5Opc)
inlinestatic

Definition at line 553 of file ARMAddressingModes.h.

554 {
555  return ((AM5Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
556 }

References ARM_AM_add, and ARM_AM_sub.

◆ ARM_AM_getAM5Opc()

static unsigned ARM_AM_getAM5Opc ( ARM_AM_AddrOpc  Opc,
unsigned char  Offset 
)
inlinestatic

getAM5Opc - This function encodes the addrmode5 opc field.

Definition at line 544 of file ARMAddressingModes.h.

545 {
546  bool isSub = Opc == ARM_AM_sub;
547  return ((int)isSub << 8) | Offset;
548 }
static ut32 Offset
Definition: asm_arc.c:20

References ARM_AM_sub, and Offset.

◆ ARM_AM_getAMSubModeStr()

static const char* ARM_AM_getAMSubModeStr ( ARM_AM_AMSubMode  Mode)
inlinestatic

Definition at line 74 of file ARMAddressingModes.h.

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 }

References ARM_AM_da, ARM_AM_db, ARM_AM_ia, and ARM_AM_ib.

◆ ARM_AM_getShiftOpcEncoding()

static unsigned ARM_AM_getShiftOpcEncoding ( ARM_AM_ShiftOpc  Op)
inlinestatic

Definition at line 55 of file ARMAddressingModes.h.

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 }

References ARM_AM_asr, ARM_AM_lsl, ARM_AM_lsr, and ARM_AM_ror.

◆ ARM_AM_getShiftOpcStr()

static const char* ARM_AM_getShiftOpcStr ( ARM_AM_ShiftOpc  Op)
inlinestatic

Definition at line 43 of file ARMAddressingModes.h.

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 }

References ARM_AM_asr, ARM_AM_lsl, ARM_AM_lsr, ARM_AM_ror, and ARM_AM_rrx.

◆ ARM_AM_getSORegShOp()

static ARM_AM_ShiftOpc ARM_AM_getSORegShOp ( unsigned  Op)
inlinestatic

Definition at line 125 of file ARMAddressingModes.h.

126 {
127  return (ARM_AM_ShiftOpc)(Op & 7);
128 }

◆ createNEONModImm()

static unsigned createNEONModImm ( unsigned  OpCmode,
unsigned  Val 
)
inlinestatic

Definition at line 583 of file ARMAddressingModes.h.

584 {
585  return (OpCmode << 8) | Val;
586 }

◆ getAM2IdxMode()

static unsigned getAM2IdxMode ( unsigned  AM2Opc)
inlinestatic

Definition at line 465 of file ARMAddressingModes.h.

466 {
467  return (AM2Opc >> 16);
468 }

◆ getAM2Offset()

static unsigned getAM2Offset ( unsigned  AM2Opc)
inlinestatic

Definition at line 450 of file ARMAddressingModes.h.

451 {
452  return AM2Opc & ((1 << 12)-1);
453 }

◆ getAM2Op()

static ARM_AM_AddrOpc getAM2Op ( unsigned  AM2Opc)
inlinestatic

Definition at line 455 of file ARMAddressingModes.h.

456 {
457  return ((AM2Opc >> 12) & 1) ? ARM_AM_sub : ARM_AM_add;
458 }

References ARM_AM_add, and ARM_AM_sub.

◆ getAM2ShiftOpc()

static ARM_AM_ShiftOpc getAM2ShiftOpc ( unsigned  AM2Opc)
inlinestatic

Definition at line 460 of file ARMAddressingModes.h.

461 {
462  return (ARM_AM_ShiftOpc)((AM2Opc >> 13) & 7);
463 }

◆ getAM3IdxMode()

static unsigned getAM3IdxMode ( unsigned  AM3Opc)
inlinestatic

Definition at line 502 of file ARMAddressingModes.h.

503 {
504  return (AM3Opc >> 9);
505 }

◆ getAM3Offset()

static unsigned char getAM3Offset ( unsigned  AM3Opc)
inlinestatic

Definition at line 492 of file ARMAddressingModes.h.

493 {
494  return AM3Opc & 0xFF;
495 }

◆ getAM3Op()

static ARM_AM_AddrOpc getAM3Op ( unsigned  AM3Opc)
inlinestatic

Definition at line 497 of file ARMAddressingModes.h.

498 {
499  return ((AM3Opc >> 8) & 1) ? ARM_AM_sub : ARM_AM_add;
500 }

References ARM_AM_add, and ARM_AM_sub.

◆ getAM3Opc()

static unsigned getAM3Opc ( ARM_AM_AddrOpc  Opc,
unsigned char  Offset,
unsigned  IdxMode 
)
inlinestatic

getAM3Opc - This function encodes the addrmode3 opc field.

Definition at line 485 of file ARMAddressingModes.h.

487 {
488  bool isSub = Opc == ARM_AM_sub;
489  return ((int)isSub << 8) | Offset | (IdxMode << 9);
490 }

References ARM_AM_sub, and Offset.

◆ getAM4ModeImm()

static unsigned getAM4ModeImm ( ARM_AM_AMSubMode  SubMode)
inlinestatic

Definition at line 527 of file ARMAddressingModes.h.

528 {
529  return (int)SubMode;
530 }

◆ getAM4SubMode()

static ARM_AM_AMSubMode getAM4SubMode ( unsigned  Mode)
inlinestatic

Definition at line 522 of file ARMAddressingModes.h.

523 {
524  return (ARM_AM_AMSubMode)(Mode & 0x7);
525 }

◆ getFPImmFloat()

static float getFPImmFloat ( unsigned  Imm)
inlinestatic

Definition at line 643 of file ARMAddressingModes.h.

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 }
#define I(x)
Definition: arc.h:164
unsigned int uint32_t
Definition: sftypes.h:29
unsigned char uint8_t
Definition: sftypes.h:31
#define F(x)
Definition: tricore.h:111

References F, and I.

◆ getLoadStoreMultipleSubMode()

ARM_AM_AMSubMode getLoadStoreMultipleSubMode ( int  Opcode)

◆ getNEONModImmOpCmode()

static unsigned getNEONModImmOpCmode ( unsigned  ModImm)
inlinestatic

Definition at line 587 of file ARMAddressingModes.h.

588 {
589  return (ModImm >> 8) & 0x1f;
590 }

Referenced by ARM_AM_decodeNEONModImm().

◆ getNEONModImmVal()

static unsigned getNEONModImmVal ( unsigned  ModImm)
inlinestatic

Definition at line 591 of file ARMAddressingModes.h.

592 {
593  return ModImm & 0xff;
594 }

Referenced by ARM_AM_decodeNEONModImm().

◆ getSOImmTwoPartFirst()

static unsigned getSOImmTwoPartFirst ( unsigned  V)
inlinestatic

getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal, return the first chunk of it.

Definition at line 217 of file ARMAddressingModes.h.

218 {
219  return rotr32(255U, getSOImmValRotate(V)) & V;
220 }
static unsigned getSOImmValRotate(unsigned Imm)
static unsigned rotr32(unsigned Val, unsigned Amt)
#define V(handle, symbol)

References getSOImmValRotate(), rotr32(), and V.

◆ getSOImmTwoPartSecond()

static unsigned getSOImmTwoPartSecond ( unsigned  V)
inlinestatic

getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal, return the second chunk of it.

Definition at line 224 of file ARMAddressingModes.h.

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 }

References getSOImmValRotate(), rotr32(), and V.

◆ getSOImmVal()

static int getSOImmVal ( unsigned  Arg)
inlinestatic

getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immediate operand, return the 12-bit encoding for it. If not, return -1.

Definition at line 184 of file ARMAddressingModes.h.

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 }
static unsigned rotl32(unsigned Val, unsigned Amt)
Definition: spp.h:121

References getSOImmValRotate(), rotl32(), and rotr32().

◆ getSOImmValImm()

static unsigned getSOImmValImm ( unsigned  Imm)
inlinestatic

getSOImmValImm - Given an encoded imm field for the reg/imm form, return the 8-bit imm value.

Definition at line 132 of file ARMAddressingModes.h.

133 {
134  return Imm & 0xFF;
135 }

◆ getSOImmValRot()

static unsigned getSOImmValRot ( unsigned  Imm)
inlinestatic

getSOImmValRot - Given an encoded imm field for the reg/imm form, return the rotate amount.

Definition at line 139 of file ARMAddressingModes.h.

140 {
141  return (Imm >> 8) * 2;
142 }

◆ getSOImmValRotate()

static unsigned getSOImmValRotate ( unsigned  Imm)
inlinestatic

getSOImmValRotate - Try to handle Imm with an immediate shifter operand, computing the rotate amount to use. If this immediate value cannot be handled with a single shifter-op, determine a good rotate amount that will take a maximal chunk of bits out of the immediate.

Definition at line 148 of file ARMAddressingModes.h.

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 }
static unsigned CountTrailingZeros_32(uint32_t Value)
Definition: MathExtras.h:190

References CountTrailingZeros_32(), and rotr32().

Referenced by getSOImmTwoPartFirst(), getSOImmTwoPartSecond(), getSOImmVal(), and isSOImmTwoPartVal().

◆ getSORegOffset()

static unsigned getSORegOffset ( unsigned  Op)
inlinestatic

Definition at line 120 of file ARMAddressingModes.h.

121 {
122  return Op >> 3;
123 }

◆ getSORegOpc()

static unsigned getSORegOpc ( ARM_AM_ShiftOpc  ShOp,
unsigned  Imm 
)
inlinestatic

Definition at line 115 of file ARMAddressingModes.h.

116 {
117  return ShOp | (Imm << 3);
118 }

◆ getT2SOImmTwoPartFirst()

static unsigned getT2SOImmTwoPartFirst ( unsigned  Imm)
inlinestatic

Definition at line 395 of file ARMAddressingModes.h.

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 }
static int getT2SOImmValSplatVal(unsigned V)
static int getT2SOImmVal(unsigned Arg)
static unsigned getT2SOImmValRotate(unsigned V)

References getT2SOImmVal(), getT2SOImmValRotate(), getT2SOImmValSplatVal(), rotr32(), and V.

Referenced by getT2SOImmTwoPartSecond().

◆ getT2SOImmTwoPartSecond()

static unsigned getT2SOImmTwoPartSecond ( unsigned  Imm)
inlinestatic

Definition at line 413 of file ARMAddressingModes.h.

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 }
static unsigned getT2SOImmTwoPartFirst(unsigned Imm)

References getT2SOImmTwoPartFirst().

◆ getT2SOImmVal()

static int getT2SOImmVal ( unsigned  Arg)
inlinestatic

getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_operand immediate operand, return the 12-bit encoding for it. If not, return -1. See ARM Reference Manual A6.3.2.

Definition at line 339 of file ARMAddressingModes.h.

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 }
static int getT2SOImmValRotateVal(unsigned V)

References getT2SOImmValRotateVal(), and getT2SOImmValSplatVal().

Referenced by getT2SOImmTwoPartFirst(), and isT2SOImmTwoPartVal().

◆ getT2SOImmValRotate()

static unsigned getT2SOImmValRotate ( unsigned  V)
inlinestatic

Definition at line 355 of file ARMAddressingModes.h.

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 }

References CountTrailingZeros_32(), and V.

Referenced by getT2SOImmTwoPartFirst(), and isT2SOImmTwoPartVal().

◆ getT2SOImmValRotateVal()

static int getT2SOImmValRotateVal ( unsigned  V)
inlinestatic

getT2SOImmValRotateVal - Return the 12-bit encoded representation if the specified value is a rotated 8-bit value. Return -1 if no rotation encoding is possible. See ARM Reference Manual A6.3.2.

Definition at line 322 of file ARMAddressingModes.h.

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 }
static unsigned CountLeadingZeros_32(uint32_t Value)
Definition: MathExtras.h:95

References CountLeadingZeros_32(), rotr32(), and V.

Referenced by getT2SOImmVal().

◆ getT2SOImmValSplatVal()

static int getT2SOImmValSplatVal ( unsigned  V)
inlinestatic

getT2SOImmValSplat - Return the 12-bit encoded representation if the specified value can be obtained by splatting the low 8 bits into every other byte or every byte of a 32-bit value. i.e., 00000000 00000000 00000000 abcdefgh control = 0 00000000 abcdefgh 00000000 abcdefgh control = 1 abcdefgh 00000000 abcdefgh 00000000 control = 2 abcdefgh abcdefgh abcdefgh abcdefgh control = 3 Return -1 if none of the above apply. See ARM Reference Manual A6.3.2.

Definition at line 293 of file ARMAddressingModes.h.

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 }

References V.

Referenced by getT2SOImmTwoPartFirst(), getT2SOImmVal(), and isT2SOImmTwoPartVal().

◆ getThumbImm16ValShift()

static unsigned getThumbImm16ValShift ( unsigned  Imm)
inlinestatic

getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed by a left shift. Returns the shift amount to use.

Definition at line 257 of file ARMAddressingModes.h.

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 }

References CountTrailingZeros_32().

Referenced by isThumbImm16ShiftedVal().

◆ getThumbImmNonShiftedVal()

static unsigned getThumbImmNonShiftedVal ( unsigned  V)
inlinestatic

getThumbImmNonShiftedVal - If V is a value that satisfies isThumbImmShiftedVal, return the non-shiftd value.

Definition at line 278 of file ARMAddressingModes.h.

279 {
280  return V >> getThumbImmValShift(V);
281 }
static unsigned getThumbImmValShift(unsigned Imm)

References getThumbImmValShift(), and V.

◆ getThumbImmValShift()

static unsigned getThumbImmValShift ( unsigned  Imm)
inlinestatic

getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed by a left shift. Returns the shift amount to use.

Definition at line 236 of file ARMAddressingModes.h.

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 }

References CountTrailingZeros_32().

Referenced by getThumbImmNonShiftedVal(), and isThumbImmShiftedVal().

◆ isSOImmTwoPartVal()

static bool isSOImmTwoPartVal ( unsigned  V)
inlinestatic

isSOImmTwoPartVal - Return true if the specified value can be obtained by or'ing together two SOImmVal's.

Definition at line 203 of file ARMAddressingModes.h.

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 }

References getSOImmValRotate(), rotr32(), and V.

◆ isT2SOImmTwoPartVal()

static bool isT2SOImmTwoPartVal ( unsigned  Imm)
inlinestatic

Definition at line 367 of file ARMAddressingModes.h.

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 }

References getT2SOImmVal(), getT2SOImmValRotate(), getT2SOImmValSplatVal(), rotr32(), and V.

◆ isThumbImm16ShiftedVal()

static bool isThumbImm16ShiftedVal ( unsigned  V)
inlinestatic

isThumbImm16ShiftedVal - Return true if the specified value can be obtained by left shifting a 16-bit immediate.

Definition at line 269 of file ARMAddressingModes.h.

270 {
271  // If this can be handled with
272  V = (~65535U << getThumbImm16ValShift(V)) & V;
273  return V == 0;
274 }
static unsigned getThumbImm16ValShift(unsigned Imm)

References getThumbImm16ValShift(), and V.

◆ isThumbImmShiftedVal()

static bool isThumbImmShiftedVal ( unsigned  V)
inlinestatic

isThumbImmShiftedVal - Return true if the specified value can be obtained by left shifting a 8-bit immediate.

Definition at line 248 of file ARMAddressingModes.h.

249 {
250  // If this can be handled with
251  V = (~255U << getThumbImmValShift(V)) & V;
252  return V == 0;
253 }

References getThumbImmValShift(), and V.

◆ rotl32()

static unsigned rotl32 ( unsigned  Val,
unsigned  Amt 
)
inlinestatic

rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.

Definition at line 95 of file ARMAddressingModes.h.

96 {
97  //assert(Amt < 32 && "Invalid rotate amount");
98  return (Val << Amt) | (Val >> ((32-Amt)&31));
99 }

Referenced by getSOImmVal().

◆ rotr32()

static unsigned rotr32 ( unsigned  Val,
unsigned  Amt 
)
inlinestatic

rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.

Definition at line 87 of file ARMAddressingModes.h.

88 {
89  //assert(Amt < 32 && "Invalid rotate amount");
90  return (Val >> Amt) | (Val << ((32-Amt)&31));
91 }

Referenced by getSOImmTwoPartFirst(), getSOImmTwoPartSecond(), getSOImmVal(), getSOImmValRotate(), getT2SOImmTwoPartFirst(), getT2SOImmValRotateVal(), isSOImmTwoPartVal(), and isT2SOImmTwoPartVal().