Home | History | Annotate | Download | only in ARM
      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 (at) gmail.com>, 2013-2014 */
     16 
     17 #ifndef CS_LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
     18 #define CS_LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
     19 
     20 #include "../../include/platform.h"
     21 #include "../../MathExtras.h"
     22 
     23 /// ARM_AM - ARM Addressing Mode Stuff
     24 typedef enum ARM_AM_ShiftOpc {
     25 	ARM_AM_no_shift = 0,
     26 	ARM_AM_asr,
     27 	ARM_AM_lsl,
     28 	ARM_AM_lsr,
     29 	ARM_AM_ror,
     30 	ARM_AM_rrx
     31 } ARM_AM_ShiftOpc;
     32 
     33 typedef enum ARM_AM_AddrOpc {
     34 	ARM_AM_sub = 0,
     35 	ARM_AM_add
     36 } ARM_AM_AddrOpc;
     37 
     38 static inline char *ARM_AM_getAddrOpcStr(ARM_AM_AddrOpc Op)
     39 {
     40 	return Op == ARM_AM_sub ? "-" : "";
     41 }
     42 
     43 static inline 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 {
     67 	ARM_AM_bad_am_submode = 0,
     68 	ARM_AM_ia,
     69 	ARM_AM_ib,
     70 	ARM_AM_da,
     71 	ARM_AM_db
     72 } ARM_AM_AMSubMode;
     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 
     85 /// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
     86 ///
     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 
     93 /// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.
     94 ///
     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 
    130 /// getSOImmValImm - Given an encoded imm field for the reg/imm form, return
    131 /// the 8-bit imm value.
    132 static inline unsigned getSOImmValImm(unsigned Imm)
    133 {
    134 	return Imm & 0xFF;
    135 }
    136 
    137 /// getSOImmValRot - Given an encoded imm field for the reg/imm form, return
    138 /// the rotate amount.
    139 static inline unsigned getSOImmValRot(unsigned Imm)
    140 {
    141 	return (Imm >> 8) * 2;
    142 }
    143 
    144 /// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
    145 /// computing the rotate amount to use.  If this immediate value cannot be
    146 /// handled with a single shifter-op, determine a good rotate amount that will
    147 /// take a maximal chunk of bits out of the immediate.
    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 
    181 /// getSOImmVal - Given a 32-bit immediate, if it is something that can fit
    182 /// into an shifter_operand immediate operand, return the 12-bit encoding for
    183 /// it.  If not, return -1.
    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 
    201 /// isSOImmTwoPartVal - Return true if the specified value can be obtained by
    202 /// or'ing together two SOImmVal's.
    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 
    215 /// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal,
    216 /// return the first chunk of it.
    217 static inline unsigned getSOImmTwoPartFirst(unsigned V)
    218 {
    219 	return rotr32(255U, getSOImmValRotate(V)) & V;
    220 }
    221 
    222 /// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal,
    223 /// return the second chunk of it.
    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 
    234 /// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
    235 /// by a left shift. Returns the shift amount to use.
    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 
    246 /// isThumbImmShiftedVal - Return true if the specified value can be obtained
    247 /// by left shifting a 8-bit immediate.
    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 
    255 /// getThumbImm16ValShift - Try to handle Imm with a 16-bit immediate followed
    256 /// by a left shift. Returns the shift amount to use.
    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 
    267 /// isThumbImm16ShiftedVal - Return true if the specified value can be
    268 /// obtained by left shifting a 16-bit immediate.
    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 
    276 /// getThumbImmNonShiftedVal - If V is a value that satisfies
    277 /// isThumbImmShiftedVal, return the non-shiftd value.
    278 static inline unsigned getThumbImmNonShiftedVal(unsigned V)
    279 {
    280 	return V >> getThumbImmValShift(V);
    281 }
    282 
    283 
    284 /// getT2SOImmValSplat - Return the 12-bit encoded representation
    285 /// if the specified value can be obtained by splatting the low 8 bits
    286 /// into every other byte or every byte of a 32-bit value. i.e.,
    287 ///     00000000 00000000 00000000 abcdefgh    control = 0
    288 ///     00000000 abcdefgh 00000000 abcdefgh    control = 1
    289 ///     abcdefgh 00000000 abcdefgh 00000000    control = 2
    290 ///     abcdefgh abcdefgh abcdefgh abcdefgh    control = 3
    291 /// Return -1 if none of the above apply.
    292 /// See ARM Reference Manual A6.3.2.
    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 
    318 /// getT2SOImmValRotateVal - Return the 12-bit encoded representation if the
    319 /// specified value is a rotated 8-bit value. Return -1 if no rotation
    320 /// encoding is possible.
    321 /// See ARM Reference Manual A6.3.2.
    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 
    335 /// getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit
    336 /// into a Thumb-2 shifter_operand immediate operand, return the 12-bit
    337 /// encoding for it.  If not, return -1.
    338 /// See ARM Reference Manual A6.3.2.
    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.
    348 	Rot = getT2SOImmValRotateVal(Arg);
    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 
    484 /// getAM3Opc - This function encodes the addrmode3 opc field.
    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 
    543 /// getAM5Opc - This function encodes the addrmode5 opc field.
    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 
    596 /// decodeNEONModImm - Decode a NEON modified immediate value into the
    597 /// element value and the element size in bits.  (If the element size is
    598 /// smaller than the vector, it is splatted into all the elements.)
    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 
    638 ARM_AM_AMSubMode getLoadStoreMultipleSubMode(int Opcode);
    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 |= 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 
    671