7#if defined(USE_SIMULATOR) 
   13const Simulator::PACKey Simulator::kPACKeyIB = {0xeebb163b474e04c8,
 
   14                                                0x5267ac6fc280fb7c, 1};
 
   18uint64_t GetNibble(uint64_t in_data, 
int position) {
 
   22uint64_t PACCellShuffle(uint64_t in_data) {
 
   23  static int in_positions[16] = {52, 24, 44, 0,  28, 48, 4,  40,
 
   24                                 32, 12, 56, 20, 8,  36, 16, 60};
 
   25  uint64_t out_data = 0;
 
   26  for (
int i = 0; 
i < 16; ++
i) {
 
   27    out_data |= GetNibble(in_data, in_positions[
i]) << (4 * 
i);
 
   32uint64_t PACCellInvShuffle(uint64_t in_data) {
 
   33  static int in_positions[16] = {12, 24, 48, 36, 56, 44, 4,  16,
 
   34                                 32, 52, 28, 8,  20, 0,  40, 60};
 
   35  uint64_t out_data = 0;
 
   36  for (
int i = 0; 
i < 16; ++
i) {
 
   37    out_data |= GetNibble(in_data, in_positions[
i]) << (4 * 
i);
 
   42uint64_t RotCell(uint64_t in_cell, 
int amount) {
 
   43  DCHECK((amount >= 1) && (amount <= 3));
 
   46  uint8_t temp = in_cell << 4 | in_cell;
 
   47  return static_cast<uint64_t
>((temp >> (4 - amount)) & 0xf);
 
   50uint64_t PACMult(uint64_t s_input) {
 
   55  uint64_t s_output = 0;
 
   57  for (
int i = 0; 
i < 4; ++
i) {
 
   58    uint8_t s12 = (s_input >> (4 * (
i + 12))) & 0xf;
 
   59    uint8_t s8 = (s_input >> (4 * (
i + 8))) & 0xf;
 
   60    uint8_t s4 = (s_input >> (4 * (
i + 4))) & 0xf;
 
   61    uint8_t s0 = (s_input >> (4 * (
i + 0))) & 0xf;
 
   63    t0 = RotCell(s8, 1) ^ RotCell(s4, 2) ^ RotCell(s0, 1);
 
   64    t1 = RotCell(s12, 1) ^ RotCell(s4, 1) ^ RotCell(s0, 2);
 
   65    t2 = RotCell(s12, 2) ^ RotCell(s8, 1) ^ RotCell(s0, 1);
 
   66    t3 = RotCell(s12, 1) ^ RotCell(s8, 2) ^ RotCell(s4, 1);
 
   68    s_output |= 
static_cast<uint64_t
>(t3) << (4 * (
i + 0));
 
   69    s_output |= 
static_cast<uint64_t
>(t2) << (4 * (
i + 4));
 
   70    s_output |= 
static_cast<uint64_t
>(t1) << (4 * (
i + 8));
 
   71    s_output |= 
static_cast<uint64_t
>(t0) << (4 * (
i + 12));
 
   76uint64_t PACSub(uint64_t t_input) {
 
   77  uint64_t t_output = 0;
 
   78  uint8_t substitutions[16] = {0xb, 0x6, 0x8, 0xf, 0xc, 0x0, 0x9, 0xe,
 
   79                               0x3, 0x7, 0x4, 0x5, 0xd, 0x2, 0x1, 0xa};
 
   80  for (
int i = 0; 
i < 16; ++
i) {
 
   81    unsigned index = ((t_input >> (4 * 
i)) & 0xf);
 
   82    t_output |= 
static_cast<uint64_t
>(substitutions[
index]) << (4 * 
i);
 
   87uint64_t PACInvSub(uint64_t t_input) {
 
   88  uint64_t t_output = 0;
 
   89  uint8_t substitutions[16] = {0x5, 0xe, 0xd, 0x8, 0xa, 0xb, 0x1, 0x9,
 
   90                               0x2, 0x6, 0xf, 0x0, 0x4, 0xc, 0x7, 0x3};
 
   91  for (
int i = 0; 
i < 16; ++
i) {
 
   92    unsigned index = ((t_input >> (4 * 
i)) & 0xf);
 
   93    t_output |= 
static_cast<uint64_t
>(substitutions[
index]) << (4 * 
i);
 
   98uint64_t TweakCellInvRot(uint64_t in_cell) {
 
   99  uint64_t out_cell = 0;
 
  100  out_cell |= (in_cell & 0x7) << 1;
 
  101  out_cell |= (in_cell & 0x1) ^ ((in_cell >> 3) & 0x1);
 
  105uint64_t TweakInvShuffle(uint64_t in_data) {
 
  106  uint64_t out_data = 0;
 
  107  out_data |= TweakCellInvRot(in_data >> 48) << 0;
 
  108  out_data |= ((in_data >> 52) & 0xf) << 4;
 
  109  out_data |= ((in_data >> 20) & 0xff) << 8;
 
  110  out_data |= ((in_data >> 0) & 0xff) << 16;
 
  111  out_data |= TweakCellInvRot(in_data >> 8) << 24;
 
  112  out_data |= ((in_data >> 12) & 0xf) << 28;
 
  113  out_data |= TweakCellInvRot(in_data >> 28) << 32;
 
  114  out_data |= TweakCellInvRot(in_data >> 60) << 36;
 
  115  out_data |= TweakCellInvRot(in_data >> 56) << 40;
 
  116  out_data |= TweakCellInvRot(in_data >> 16) << 44;
 
  117  out_data |= ((in_data >> 32) & 0xfff) << 48;
 
  118  out_data |= TweakCellInvRot(in_data >> 44) << 60;
 
  122uint64_t TweakCellRot(uint64_t in_cell) {
 
  123  uint64_t out_cell = 0;
 
  124  out_cell |= ((in_cell & 0x1) ^ ((in_cell >> 1) & 0x1)) << 3;
 
  125  out_cell |= (in_cell >> 0x1) & 0x7;
 
  129uint64_t TweakShuffle(uint64_t in_data) {
 
  130  uint64_t out_data = 0;
 
  131  out_data |= ((in_data >> 16) & 0xff) << 0;
 
  132  out_data |= TweakCellRot(in_data >> 24) << 8;
 
  133  out_data |= ((in_data >> 28) & 0xf) << 12;
 
  134  out_data |= TweakCellRot(in_data >> 44) << 16;
 
  135  out_data |= ((in_data >> 8) & 0xff) << 20;
 
  136  out_data |= TweakCellRot(in_data >> 32) << 28;
 
  137  out_data |= ((in_data >> 48) & 0xfff) << 32;
 
  138  out_data |= TweakCellRot(in_data >> 60) << 44;
 
  139  out_data |= TweakCellRot(in_data >> 0) << 48;
 
  140  out_data |= ((in_data >> 4) & 0xf) << 52;
 
  141  out_data |= TweakCellRot(in_data >> 40) << 56;
 
  142  out_data |= TweakCellRot(in_data >> 36) << 60;
 
  152uint64_t Simulator::ComputePAC(uint64_t data, uint64_t context, PACKey 
key) {
 
  153  uint64_t key0 = 
key.high;
 
  154  uint64_t key1 = 
key.low;
 
  155  const uint64_t RC[5] = {0x0000000000000000, 0x13198a2e03707344,
 
  156                          0xa4093822299f31d0, 0x082efa98ec4e6c89,
 
  158  const uint64_t Alpha = 0xc0ac29B7c97c50dd;
 
  160  uint64_t modk0 = ((key0 & 0x1) << 63) | ((key0 >> 2) << 1) |
 
  161                   ((key0 >> 63) ^ ((key0 >> 1) & 0x1));
 
  162  uint64_t running_mod = 
context;
 
  163  uint64_t working_val = data ^ key0;
 
  165  for (
int i = 0; 
i < 5; ++
i) {
 
  166    round_key = key1 ^ running_mod;
 
  167    working_val ^= round_key;
 
  168    working_val ^= RC[
i];
 
  170      working_val = PACCellShuffle(working_val);
 
  171      working_val = PACMult(working_val);
 
  173    working_val = PACSub(working_val);
 
  174    running_mod = TweakShuffle(running_mod);
 
  177  round_key = modk0 ^ running_mod;
 
  178  working_val ^= round_key;
 
  179  working_val = PACCellShuffle(working_val);
 
  180  working_val = PACMult(working_val);
 
  181  working_val = PACSub(working_val);
 
  182  working_val = PACCellShuffle(working_val);
 
  183  working_val = PACMult(working_val);
 
  185  working_val = PACCellInvShuffle(working_val);
 
  186  working_val = PACInvSub(working_val);
 
  187  working_val = PACMult(working_val);
 
  188  working_val = PACCellInvShuffle(working_val);
 
  190  working_val ^= running_mod;
 
  192  for (
int i = 0; 
i < 5; ++
i) {
 
  193    working_val = PACInvSub(working_val);
 
  195      working_val = PACMult(working_val);
 
  196      working_val = PACCellInvShuffle(working_val);
 
  198    running_mod = TweakInvShuffle(running_mod);
 
  199    round_key = key1 ^ running_mod;
 
  200    working_val ^= RC[4 - 
i];
 
  201    working_val ^= round_key;
 
  202    working_val ^= Alpha;
 
  205  return working_val ^ modk0;
 
  211uint64_t Simulator::CalculatePACMask(uint64_t ptr, PointerType type, 
int ttbr) {
 
  212  int bottom_pac_bit = GetBottomPACBit(ptr, ttbr);
 
  213  int top_pac_bit = GetTopPACBit(ptr, type);
 
  219uint64_t Simulator::AuthPAC(uint64_t ptr, uint64_t context, PACKey 
key,
 
  223  uint64_t pac_mask = CalculatePACMask(ptr, type, (ptr >> 55) & 1);
 
  224  uint64_t original_ptr =
 
  225      ((ptr & 
kTTBRMask) == 0) ? (ptr & ~pac_mask) : (ptr | pac_mask);
 
  227  uint64_t pac = ComputePAC(original_ptr, context, 
key);
 
  229  uint64_t error_code = UINT64_C(1) << 
key.number;
 
  230  if ((pac & pac_mask) == (ptr & pac_mask)) {
 
  233    int error_lsb = GetTopPACBit(ptr, type) - 2;
 
  234    uint64_t error_mask = UINT64_C(0x3) << error_lsb;
 
  235    if (
v8_flags.sim_abort_on_bad_auth) {
 
  236      FATAL(
"Pointer authentication failure.");
 
  238    return (original_ptr & ~error_mask) | (error_code << error_lsb);
 
  242uint64_t Simulator::AddPAC(uint64_t ptr, uint64_t context, PACKey 
key,
 
  244  int top_pac_bit = GetTopPACBit(ptr, type);
 
  246  DCHECK(HasTBI(ptr, type));
 
  247  int ttbr = (ptr >> 55) & 1;
 
  248  uint64_t pac_mask = CalculatePACMask(ptr, type, ttbr);
 
  249  uint64_t ext_ptr = (ttbr == 0) ? (ptr & ~pac_mask) : (ptr | pac_mask);
 
  251  uint64_t pac = ComputePAC(ext_ptr, context, 
key);
 
  255  if (((ptr & (pac_mask | 
kTTBRMask)) != 0x0) &&
 
  256      ((~ptr & (pac_mask | 
kTTBRMask)) != 0x0)) {
 
  257    pac ^= UINT64_C(1) << (top_pac_bit - 1);
 
  260  uint64_t ttbr_shifted = 
static_cast<uint64_t
>(ttbr) << 55;
 
  261  return (pac & pac_mask) | ttbr_shifted | (ptr & ~pac_mask);
 
  264uint64_t Simulator::StripPAC(uint64_t ptr, PointerType type) {
 
  265  uint64_t pac_mask = CalculatePACMask(ptr, type, (ptr >> 55) & 1);
 
  266  return ((ptr & 
kTTBRMask) == 0) ? (ptr & ~pac_mask) : (ptr | pac_mask);
 
constexpr uint64_t kTTBRMask
 
V8_EXPORT_PRIVATE FlagValues v8_flags
 
uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x)
 
#define DCHECK(condition)