1dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- C++ -*-===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
10dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// This file contains the AArch64 addressing mode implementation stuff.
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#ifndef LLVM_TARGET_AArch64_AArch64ADDRESSINGMODES_H
15dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define LLVM_TARGET_AArch64_AArch64ADDRESSINGMODES_H
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/APFloat.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/APInt.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ErrorHandling.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/MathExtras.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <cassert>
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm {
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// AArch64_AM - AArch64 Addressing Mode Stuff
26dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesnamespace AArch64_AM {
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Shifts
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesenum ShiftExtendType {
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  InvalidShiftExtend = -1,
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  LSL = 0,
35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LSR,
36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ASR,
37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ROR,
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MSL,
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UXTB,
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UXTH,
42dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UXTW,
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  UXTX,
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SXTB,
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SXTH,
47dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SXTW,
48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SXTX,
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getShiftName - Get the string encoding for the shift type.
52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic inline const char *getShiftExtendName(AArch64_AM::ShiftExtendType ST) {
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (ST) {
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default: assert(false && "unhandled shift type!");
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::LSL: return "lsl";
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::LSR: return "lsr";
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::ASR: return "asr";
58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::ROR: return "ror";
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::MSL: return "msl";
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::UXTB: return "uxtb";
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::UXTH: return "uxth";
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::UXTW: return "uxtw";
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::UXTX: return "uxtx";
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::SXTB: return "sxtb";
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::SXTH: return "sxth";
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::SXTW: return "sxtw";
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::SXTX: return "sxtx";
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getShiftType - Extract the shift type.
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic inline AArch64_AM::ShiftExtendType getShiftType(unsigned Imm) {
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch ((Imm >> 6) & 0x7) {
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default: return AArch64_AM::InvalidShiftExtend;
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 0: return AArch64_AM::LSL;
77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1: return AArch64_AM::LSR;
78dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 2: return AArch64_AM::ASR;
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 3: return AArch64_AM::ROR;
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4: return AArch64_AM::MSL;
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getShiftValue - Extract the shift value.
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline unsigned getShiftValue(unsigned Imm) {
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Imm & 0x3f;
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getShifterImm - Encode the shift type and amount:
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   imm:     6-bit shift amount
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   shifter: 000 ==> lsl
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            001 ==> lsr
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            010 ==> asr
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            011 ==> ror
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            100 ==> msl
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   {8-6}  = shifter
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   {5-0}  = imm
98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic inline unsigned getShifterImm(AArch64_AM::ShiftExtendType ST,
99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     unsigned Imm) {
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert((Imm & 0x3f) == Imm && "Illegal shifted immedate value!");
101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned STEnc = 0;
102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (ST) {
103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:  llvm_unreachable("Invalid shift requested");
104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::LSL: STEnc = 0; break;
105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::LSR: STEnc = 1; break;
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::ASR: STEnc = 2; break;
107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::ROR: STEnc = 3; break;
108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::MSL: STEnc = 4; break;
109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return (STEnc << 6) | (Imm & 0x3f);
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Extends
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getArithShiftValue - get the arithmetic shift value.
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline unsigned getArithShiftValue(unsigned Imm) {
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return Imm & 0x7;
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getExtendType - Extract the extend type for operands of arithmetic ops.
123dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic inline AArch64_AM::ShiftExtendType getExtendType(unsigned Imm) {
124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert((Imm & 0x7) == Imm && "invalid immediate!");
125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Imm) {
126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default: llvm_unreachable("Compiler bug!");
127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 0: return AArch64_AM::UXTB;
128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 1: return AArch64_AM::UXTH;
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 2: return AArch64_AM::UXTW;
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 3: return AArch64_AM::UXTX;
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 4: return AArch64_AM::SXTB;
132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 5: return AArch64_AM::SXTH;
133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 6: return AArch64_AM::SXTW;
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case 7: return AArch64_AM::SXTX;
135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
138dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic inline AArch64_AM::ShiftExtendType getArithExtendType(unsigned Imm) {
139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return getExtendType((Imm >> 3) & 0x7);
140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
142dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Mapping from extend bits to required operation:
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   shifter: 000 ==> uxtb
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            001 ==> uxth
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            010 ==> uxtw
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            011 ==> uxtx
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            100 ==> sxtb
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            101 ==> sxth
14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            110 ==> sxtw
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            111 ==> sxtx
151dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesinline unsigned getExtendEncoding(AArch64_AM::ShiftExtendType ET) {
152dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (ET) {
153dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default: llvm_unreachable("Invalid extend type requested");
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::UXTB: return 0; break;
155dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::UXTH: return 1; break;
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::UXTW: return 2; break;
157dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::UXTX: return 3; break;
158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::SXTB: return 4; break;
159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::SXTH: return 5; break;
160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::SXTW: return 6; break;
161dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case AArch64_AM::SXTX: return 7; break;
162dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// getArithExtendImm - Encode the extend type and shift amount for an
166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines///                     arithmetic instruction:
167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines///   imm:     3-bit extend amount
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   {5-3}  = shifter
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   {2-0}  = imm3
170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic inline unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET,
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                         unsigned Imm) {
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert((Imm & 0x7) == Imm && "Illegal shifted immedate value!");
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return (getExtendEncoding(ET) << 3) | (Imm & 0x7);
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getMemDoShift - Extract the "do shift" flag value for load/store
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// instructions.
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool getMemDoShift(unsigned Imm) {
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0x1) != 0;
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getExtendType - Extract the extend type for the offset operand of
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// loads/stores.
184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic inline AArch64_AM::ShiftExtendType getMemExtendType(unsigned Imm) {
185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return getExtendType((Imm >> 1) & 0x7);
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getExtendImm - Encode the extend type and amount for a load/store inst:
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   doshift:     should the offset be scaled by the access size
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   shifter: 000 ==> uxtb
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            001 ==> uxth
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            010 ==> uxtw
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            011 ==> uxtx
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            100 ==> sxtb
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            101 ==> sxth
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            110 ==> sxtw
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///            111 ==> sxtx
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   {3-1}  = shifter
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///   {0}  = doshift
200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic inline unsigned getMemExtendImm(AArch64_AM::ShiftExtendType ET,
201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       bool DoShift) {
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return (getExtendEncoding(ET) << 1) | unsigned(DoShift);
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t ror(uint64_t elt, unsigned size) {
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((elt & 1) << (size-1)) | (elt >> 1);
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// processLogicalImmediate - Determine if an immediate value can be encoded
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// as the immediate operand of a logical instruction for the given register
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// size.  If so, return true with "encoding" set to the encoded value in
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// the form N:immr:imms.
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool processLogicalImmediate(uint64_t imm, unsigned regSize,
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           uint64_t &encoding) {
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (imm == 0ULL || imm == ~0ULL ||
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      (regSize != 64 && (imm >> regSize != 0 || imm == ~0U)))
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned size = 2;
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t eltVal = imm;
22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // First, determine the element size.
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (size < regSize) {
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned numElts = regSize / size;
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned mask = (1ULL << size) - 1;
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t lowestEltVal = imm & mask;
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool allMatched = true;
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (unsigned i = 1; i < numElts; ++i) {
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     uint64_t currEltVal = (imm >> (i*size)) & mask;
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (currEltVal != lowestEltVal) {
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        allMatched = false;
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (allMatched) {
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      eltVal = lowestEltVal;
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    size *= 2;
24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Second, determine the rotation to make the element be: 0^m 1^n.
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0; i < size; ++i) {
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    eltVal = ror(eltVal, size);
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t clz = countLeadingZeros(eltVal) - (64 - size);
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t cto = CountTrailingOnes_64(eltVal);
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (clz + cto == size) {
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Encode in immr the number of RORs it would take to get *from* this
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // element value to our target value, where i+1 is the number of RORs
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // to go the opposite direction.
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned immr = size - (i + 1);
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // If size has a 1 in the n'th bit, create a value that has zeroes in
25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // bits [0, n] and ones above that.
25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint64_t nimms = ~(size-1) << 1;
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Or the CTO value into the low bits, which must be below the Nth bit
26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // bit mentioned above.
26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      nimms |= (cto-1);
26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Extract the seventh bit and toggle it to create the N field.
26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned N = ((nimms >> 6) & 1) ^ 1;
26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      encoding = (N << 12) | (immr << 6) | (nimms & 0x3f);
26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// isLogicalImmediate - Return true if the immediate is valid for a logical
27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// immediate instruction of the given register size. Return false otherwise.
27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isLogicalImmediate(uint64_t imm, unsigned regSize) {
27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t encoding;
28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return processLogicalImmediate(imm, regSize, encoding);
28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// encodeLogicalImmediate - Return the encoded immediate value for a logical
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// immediate instruction of the given register size.
28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize) {
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t encoding = 0;
28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool res = processLogicalImmediate(imm, regSize, encoding);
28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(res && "invalid logical immediate");
28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  (void)res;
29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return encoding;
29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// decodeLogicalImmediate - Decode a logical immediate value in the form
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// "N:immr:imms" (where the immr and imms fields are each 6 bits) into the
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// integer value it represents with regSize bits.
29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeLogicalImmediate(uint64_t val, unsigned regSize) {
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Extract the N, imms, and immr fields.
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned N = (val >> 12) & 1;
29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned immr = (val >> 6) & 0x3f;
30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned imms = val & 0x3f;
30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert((regSize == 64 || N == 0) && "undefined logical immediate encoding");
30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(len >= 0 && "undefined logical immediate encoding");
30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned size = (1 << len);
30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned R = immr & (size - 1);
30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned S = imms & (size - 1);
30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(S != size - 1 && "undefined logical immediate encoding");
30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t pattern = (1ULL << (S + 1)) - 1;
31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0; i < R; ++i)
31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    pattern = ror(pattern, size);
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Replicate the pattern to fill the regSize.
31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  while (size != regSize) {
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    pattern |= (pattern << size);
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    size *= 2;
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return pattern;
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// isValidDecodeLogicalImmediate - Check to see if the logical immediate value
32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// in the form "N:immr:imms" (where the immr and imms fields are each 6 bits)
32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// is a valid encoding for an integer value with regSize bits.
32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isValidDecodeLogicalImmediate(uint64_t val,
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 unsigned regSize) {
32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Extract the N and imms fields needed for checking.
32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned N = (val >> 12) & 1;
32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned imms = val & 0x3f;
32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (regSize == 32 && N != 0) // undefined logical immediate encoding
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int len = 31 - countLeadingZeros((N << 6) | (~imms & 0x3f));
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (len < 0) // undefined logical immediate encoding
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned size = (1 << len);
33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned S = imms & (size - 1);
33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (S == size - 1) // undefined logical immediate encoding
33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Floating-point Immediates
34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline float getFPImmFloat(unsigned Imm) {
34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We expect an 8-bit binary encoding of a floating-point number here.
34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  union {
34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t I;
35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    float F;
35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } FPUnion;
35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t Sign = (Imm >> 7) & 0x1;
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t Exp = (Imm >> 4) & 0x7;
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t Mantissa = Imm & 0xf;
35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //   8-bit FP    iEEEE Float Encoding
35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //   abcd efgh   aBbbbbbc defgh000 00000000 00000000
35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //
36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // where B = NOT(b);
36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FPUnion.I = 0;
36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FPUnion.I |= Sign << 31;
36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30;
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25;
36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FPUnion.I |= (Exp & 0x3) << 23;
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FPUnion.I |= Mantissa << 19;
36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return FPUnion.F;
36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getFP32Imm - Return an 8-bit floating-point version of the 32-bit
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// floating-point value. If the value cannot be represented as an 8-bit
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// floating-point value, then return -1.
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline int getFP32Imm(const APInt &Imm) {
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint32_t Sign = Imm.lshr(31).getZExtValue() & 1;
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int32_t Exp = (Imm.lshr(23).getSExtValue() & 0xff) - 127;  // -126 to 127
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t Mantissa = Imm.getZExtValue() & 0x7fffff;  // 23 bits
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We can handle 4 bits of mantissa.
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // mantissa = (16+UInt(e:f:g:h))/16.
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Mantissa & 0x7ffff)
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return -1;
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Mantissa >>= 19;
38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((Mantissa & 0xf) != Mantissa)
38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return -1;
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Exp < -3 || Exp > 4)
38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return -1;
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Exp = ((Exp+3) & 0x7) ^ 4;
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((int)Sign << 7) | (Exp << 4) | Mantissa;
39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline int getFP32Imm(const APFloat &FPImm) {
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return getFP32Imm(FPImm.bitcastToAPInt());
39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// getFP64Imm - Return an 8-bit floating-point version of the 64-bit
40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// floating-point value. If the value cannot be represented as an 8-bit
40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// floating-point value, then return -1.
40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline int getFP64Imm(const APInt &Imm) {
40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Sign = Imm.lshr(63).getZExtValue() & 1;
40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t Exp = (Imm.lshr(52).getSExtValue() & 0x7ff) - 1023;   // -1022 to 1023
40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t Mantissa = Imm.getZExtValue() & 0xfffffffffffffULL;
40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We can handle 4 bits of mantissa.
40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // mantissa = (16+UInt(e:f:g:h))/16.
40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Mantissa & 0xffffffffffffULL)
41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return -1;
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Mantissa >>= 48;
41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((Mantissa & 0xf) != Mantissa)
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return -1;
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Exp < -3 || Exp > 4)
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return -1;
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Exp = ((Exp+3) & 0x7) ^ 4;
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((int)Sign << 7) | (Exp << 4) | Mantissa;
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline int getFP64Imm(const APFloat &FPImm) {
42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return getFP64Imm(FPImm.bitcastToAPInt());
42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===--------------------------------------------------------------------===//
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// AdvSIMD Modified Immediates
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===--------------------------------------------------------------------===//
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType1(uint64_t Imm) {
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0xffffff00ffffff00ULL) == 0);
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType1(uint64_t Imm) {
43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0xffULL);
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType1(uint8_t Imm) {
44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 32) | EncVal;
44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType2(uint64_t Imm) {
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0xffff00ffffff00ffULL) == 0);
45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType2(uint64_t Imm) {
45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0xff00ULL) >> 8;
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType2(uint8_t Imm) {
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 40) | (EncVal << 8);
45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00
46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType3(uint64_t Imm) {
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0xff00ffffff00ffffULL) == 0);
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType3(uint64_t Imm) {
46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0xff0000ULL) >> 16;
46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType3(uint8_t Imm) {
47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 48) | (EncVal << 16);
47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00
47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType4(uint64_t Imm) {
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0x00ffffff00ffffffULL) == 0);
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType4(uint64_t Imm) {
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0xff000000ULL) >> 24;
48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType4(uint8_t Imm) {
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 56) | (EncVal << 24);
48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType5(uint64_t Imm) {
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (((Imm & 0x00ff0000ULL) >> 16) == (Imm & 0x000000ffULL)) &&
49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0xff00ff00ff00ff00ULL) == 0);
49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType5(uint64_t Imm) {
49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0xffULL);
50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType5(uint8_t Imm) {
50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 48) | (EncVal << 32) | (EncVal << 16) | EncVal;
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType6(uint64_t Imm) {
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (((Imm & 0xff000000ULL) >> 16) == (Imm & 0x0000ff00ULL)) &&
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0x00ff00ff00ff00ffULL) == 0);
51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType6(uint64_t Imm) {
51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0xff00ULL) >> 8;
51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType6(uint8_t Imm) {
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 56) | (EncVal << 40) | (EncVal << 24) | (EncVal << 8);
52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 0x00 0x00 abcdefgh 0xFF 0x00 0x00 abcdefgh 0xFF
52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType7(uint64_t Imm) {
52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0xffff00ffffff00ffULL) == 0x000000ff000000ffULL);
52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType7(uint64_t Imm) {
53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0xff00ULL) >> 8;
53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType7(uint8_t Imm) {
53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
53536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 40) | (EncVal << 8) | 0x000000ff000000ffULL;
53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 0x00 abcdefgh 0xFF 0xFF 0x00 abcdefgh 0xFF 0xFF
53936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType8(uint64_t Imm) {
54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0xff00ffffff00ffffULL) == 0x0000ffff0000ffffULL);
54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType8(uint8_t Imm) {
54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 48) | (EncVal << 16) | 0x0000ffff0000ffffULL;
54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType8(uint64_t Imm) {
55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0x00ff0000ULL) >> 16;
55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
55336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh
55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType9(uint64_t Imm) {
55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm >> 48) == (Imm & 0x0000ffffULL)) &&
55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm >> 56) == (Imm & 0x000000ffULL));
55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType9(uint64_t Imm) {
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (Imm & 0xffULL);
56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType9(uint8_t Imm) {
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = Imm;
56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= (EncVal << 8);
56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= (EncVal << 16);
56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= (EncVal << 32);
56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return EncVal;
57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// cmode: 1110, op: 1
57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType10(uint64_t Imm) {
57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ByteA = Imm & 0xff00000000000000ULL;
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ByteB = Imm & 0x00ff000000000000ULL;
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ByteC = Imm & 0x0000ff0000000000ULL;
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ByteD = Imm & 0x000000ff00000000ULL;
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ByteE = Imm & 0x00000000ff000000ULL;
58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ByteF = Imm & 0x0000000000ff0000ULL;
58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ByteG = Imm & 0x000000000000ff00ULL;
58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t ByteH = Imm & 0x00000000000000ffULL;
58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (ByteA == 0ULL || ByteA == 0xff00000000000000ULL) &&
58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (ByteB == 0ULL || ByteB == 0x00ff000000000000ULL) &&
58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (ByteC == 0ULL || ByteC == 0x0000ff0000000000ULL) &&
58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (ByteD == 0ULL || ByteD == 0x000000ff00000000ULL) &&
58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (ByteE == 0ULL || ByteE == 0x00000000ff000000ULL) &&
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (ByteF == 0ULL || ByteF == 0x0000000000ff0000ULL) &&
59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (ByteG == 0ULL || ByteG == 0x000000000000ff00ULL) &&
59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (ByteH == 0ULL || ByteH == 0x00000000000000ffULL);
59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType10(uint64_t Imm) {
59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitA = (Imm & 0xff00000000000000ULL) != 0;
59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitB = (Imm & 0x00ff000000000000ULL) != 0;
59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitC = (Imm & 0x0000ff0000000000ULL) != 0;
59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitD = (Imm & 0x000000ff00000000ULL) != 0;
59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitE = (Imm & 0x00000000ff000000ULL) != 0;
60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitF = (Imm & 0x0000000000ff0000ULL) != 0;
60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitG = (Imm & 0x000000000000ff00ULL) != 0;
60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitH = (Imm & 0x00000000000000ffULL) != 0;
60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t EncVal = BitA;
60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitB;
60736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitC;
60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitD;
61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitE;
61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitF;
61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitG;
61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
61836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitH;
61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return EncVal;
62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType10(uint8_t Imm) {
62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = 0;
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x80) EncVal |= 0xff00000000000000ULL;
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x40) EncVal |= 0x00ff000000000000ULL;
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x20) EncVal |= 0x0000ff0000000000ULL;
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x10) EncVal |= 0x000000ff00000000ULL;
62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x08) EncVal |= 0x00000000ff000000ULL;
62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x04) EncVal |= 0x0000000000ff0000ULL;
63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x02) EncVal |= 0x000000000000ff00ULL;
63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x01) EncVal |= 0x00000000000000ffULL;
63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return EncVal;
63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// aBbbbbbc defgh000 0x00 0x00 aBbbbbbc defgh000 0x00 0x00
63636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType11(uint64_t Imm) {
63736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t BString = (Imm & 0x7E000000ULL) >> 25;
63836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((Imm >> 32) == (Imm & 0xffffffffULL)) &&
63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         (BString == 0x1f || BString == 0x20) &&
64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0x0007ffff0007ffffULL) == 0);
64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
64236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType11(uint64_t Imm) {
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitA = (Imm & 0x80000000ULL) != 0;
64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitB = (Imm & 0x20000000ULL) != 0;
64636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitC = (Imm & 0x01000000ULL) != 0;
64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitD = (Imm & 0x00800000ULL) != 0;
64836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitE = (Imm & 0x00400000ULL) != 0;
64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitF = (Imm & 0x00200000ULL) != 0;
65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitG = (Imm & 0x00100000ULL) != 0;
65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitH = (Imm & 0x00080000ULL) != 0;
65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t EncVal = BitA;
65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitB;
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitC;
65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitD;
66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitE;
66236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitF;
66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitG;
66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitH;
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return EncVal;
66936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType11(uint8_t Imm) {
67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = 0;
67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x80) EncVal |= 0x80000000ULL;
67436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x40) EncVal |= 0x3e000000ULL;
67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else            EncVal |= 0x40000000ULL;
67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x20) EncVal |= 0x01000000ULL;
67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x10) EncVal |= 0x00800000ULL;
67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x08) EncVal |= 0x00400000ULL;
67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x04) EncVal |= 0x00200000ULL;
68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x02) EncVal |= 0x00100000ULL;
68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x01) EncVal |= 0x00080000ULL;
68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 32) | EncVal;
68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// aBbbbbbb bbcdefgh 0x00 0x00 0x00 0x00 0x00 0x00
68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline bool isAdvSIMDModImmType12(uint64_t Imm) {
68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t BString = (Imm & 0x7fc0000000000000ULL) >> 54;
68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ((BString == 0xff || BString == 0x100) &&
68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         ((Imm & 0x0000ffffffffffffULL) == 0));
69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint8_t encodeAdvSIMDModImmType12(uint64_t Imm) {
69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitA = (Imm & 0x8000000000000000ULL) != 0;
69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitB = (Imm & 0x0040000000000000ULL) != 0;
69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitC = (Imm & 0x0020000000000000ULL) != 0;
69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitD = (Imm & 0x0010000000000000ULL) != 0;
69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitE = (Imm & 0x0008000000000000ULL) != 0;
69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitF = (Imm & 0x0004000000000000ULL) != 0;
69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitG = (Imm & 0x0002000000000000ULL) != 0;
70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t BitH = (Imm & 0x0001000000000000ULL) != 0;
70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint8_t EncVal = BitA;
70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitB;
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitC;
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitD;
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitE;
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitF;
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitG;
71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal <<= 1;
71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EncVal |= BitH;
71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return EncVal;
71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline uint64_t decodeAdvSIMDModImmType12(uint8_t Imm) {
72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  uint64_t EncVal = 0;
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x80) EncVal |= 0x8000000000000000ULL;
72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x40) EncVal |= 0x3fc0000000000000ULL;
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else            EncVal |= 0x4000000000000000ULL;
72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x20) EncVal |= 0x0020000000000000ULL;
72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x10) EncVal |= 0x0010000000000000ULL;
72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x08) EncVal |= 0x0008000000000000ULL;
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x04) EncVal |= 0x0004000000000000ULL;
72936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x02) EncVal |= 0x0002000000000000ULL;
73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Imm & 0x01) EncVal |= 0x0001000000000000ULL;
73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (EncVal << 32) | EncVal;
73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
734dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} // end namespace AArch64_AM
73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
73636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end namespace llvm
73736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
739