get_hazardous_pointer_with_mask (void * volatile * pp, struct MonoThreadHazardPointers * hp, int hazard_index)
{
  void * D.5154;
  unsigned int hazard_index.0;
  _Bool D.5156;
  long int D.5157;
  long int D.5158;
  void * D.5161;
  void * D.5162;
  void * p;

  <D.5116>:
  p = *pp;
  if (hp == 0B) goto <D.5152>; else goto <D.5153>;
  <D.5152>:
  D.5154 = p;
  return D.5154;
  <D.5153>:
  hazard_index.0 = (unsigned int) hazard_index;
  D.5156 = hazard_index.0 > 2;
  D.5157 = (long int) D.5156;
  D.5158 = __builtin_expect (D.5157, 0);
  if (D.5158 != 0) goto <D.5159>; else goto <D.5160>;
  <D.5159>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 40, "(hazard_index) >= 0 && (hazard_index) < HAZARD_POINTER_COUNT");
  <D.5160>:
  D.5161 = mono_lls_pointer_unmask (p);
  hp->hazard_pointers[hazard_index] = D.5161;
  mono_memory_write_barrier ();
  mono_memory_barrier ();
  D.5162 = *pp;
  if (D.5162 != p) goto <D.5163>; else goto <D.5164>;
  <D.5163>:
  hazard_index.0 = (unsigned int) hazard_index;
  D.5156 = hazard_index.0 > 2;
  D.5157 = (long int) D.5156;
  D.5158 = __builtin_expect (D.5157, 0);
  if (D.5158 != 0) goto <D.5165>; else goto <D.5166>;
  <D.5165>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 47, "(hazard_index) >= 0 && (hazard_index) < HAZARD_POINTER_COUNT");
  <D.5166>:
  hp->hazard_pointers[hazard_index] = 0B;
  // predicted unlikely by continue predictor.
  goto <D.5114>;
  <D.5164>:
  goto <D.5115>;
  <D.5114>:
  goto <D.5116>;
  <D.5115>:
  D.5154 = p;
  return D.5154;
}


mono_lls_pointer_unmask (void * p)
{
  void * D.5168;
  long unsigned int p.1;
  long unsigned int D.5170;

  p.1 = (long unsigned int) p;
  D.5170 = p.1 & 18446744073709551612;
  D.5168 = (void *) D.5170;
  return D.5168;
}


mono_memory_write_barrier ()
{
  mono_memory_barrier ();
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


mono_lls_init (struct MonoLinkedListSet * list, void (*<Tc2>) (void *) free_node_func)
{
  list->head = 0B;
  list->free_node_func = free_node_func;
}


mono_lls_find (struct MonoLinkedListSet * list, struct MonoThreadHazardPointers * hp, uintptr_t key)
{
  gboolean D.5176;
  struct MonoLinkedListSetNode * * D.5177;
  struct MonoLinkedListSetNode * D.5178;
  long unsigned int D.5180;
  _Bool D.5185;
  void * D.5189;
  void (*<Tc2>) (void *) D.5193;
  struct MonoLinkedListSetNode * cur;
  struct MonoLinkedListSetNode * next;
  struct MonoLinkedListSetNode * * prev;
  uintptr_t cur_key;
  void try_again = <<< error >>>;

  try_again:
  prev = &list->head;
  if (0 != 0) goto <D.5172>; else goto <D.5173>;
  <D.5172>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 95, "(2) >= 0 && (2) < HAZARD_POINTER_COUNT");
  <D.5173>:
  hp->hazard_pointers[2] = prev;
  mono_memory_write_barrier ();
  cur = get_hazardous_pointer_with_mask (prev, hp, 1);
  <D.5132>:
  if (cur == 0B) goto <D.5174>; else goto <D.5175>;
  <D.5174>:
  D.5176 = 0;
  return D.5176;
  <D.5175>:
  D.5177 = &cur->next;
  next = get_hazardous_pointer_with_mask (D.5177, hp, 0);
  cur_key = cur->key;
  mono_memory_read_barrier ();
  D.5178 = *prev;
  if (D.5178 != cur) goto try_again; else goto <D.5179>;
  <D.5179>:
  D.5180 = mono_lls_pointer_get_mark (next);
  if (D.5180 == 0) goto <D.5181>; else goto <D.5182>;
  <D.5181>:
  if (cur_key >= key) goto <D.5183>; else goto <D.5184>;
  <D.5183>:
  D.5185 = cur_key == key;
  D.5176 = (gboolean) D.5185;
  return D.5176;
  <D.5184>:
  prev = &cur->next;
  if (0 != 0) goto <D.5186>; else goto <D.5187>;
  <D.5186>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 120, "(2) >= 0 && (2) < HAZARD_POINTER_COUNT");
  <D.5187>:
  hp->hazard_pointers[2] = cur;
  mono_memory_write_barrier ();
  goto <D.5188>;
  <D.5182>:
  next = mono_lls_pointer_unmask (next);
  D.5189 = InterlockedCompareExchangePointer (prev, next, cur);
  if (D.5189 == cur) goto <D.5190>; else goto try_again;
  <D.5190>:
  mono_memory_write_barrier ();
  if (0 != 0) goto <D.5191>; else goto <D.5192>;
  <D.5191>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 126, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
  <D.5192>:
  hp->hazard_pointers[1] = 0B;
  D.5193 = list->free_node_func;
  if (D.5193 != 0B) goto <D.5194>; else goto <D.5195>;
  <D.5194>:
  D.5193 = list->free_node_func;
  mono_thread_hazardous_free_or_queue (cur, D.5193, 0, 1);
  <D.5195>:
  <D.5188>:
  cur = mono_lls_pointer_unmask (next);
  if (0 != 0) goto <D.5196>; else goto <D.5197>;
  <D.5196>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 133, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
  <D.5197>:
  hp->hazard_pointers[1] = cur;
  mono_memory_write_barrier ();
  goto <D.5132>;
}


mono_memory_read_barrier ()
{
  mono_memory_barrier ();
}


mono_lls_pointer_get_mark (void * n)
{
  uintptr_t D.5199;
  long unsigned int n.2;

  n.2 = (long unsigned int) n;
  D.5199 = n.2 & 1;
  return D.5199;
}


InterlockedCompareExchangePointer (void * volatile * dest, void * exch, void * comp)
{
  void * D.5202;
  long unsigned int exch.3;
  long unsigned int comp.4;
  long unsigned int D.5205;

  exch.3 = (long unsigned int) exch;
  comp.4 = (long unsigned int) comp;
  D.5205 = __sync_val_compare_and_swap_8 (dest, comp.4, exch.3);
  D.5202 = (void *) D.5205;
  return D.5202;
}


mono_lls_insert (struct MonoLinkedListSet * list, struct MonoThreadHazardPointers * hp, struct MonoLinkedListSetNode * value)
{
  long unsigned int D.5207;
  int D.5208;
  gboolean D.5211;
  void * D.5214;
  struct MonoLinkedListSetNode * cur;
  struct MonoLinkedListSetNode * * prev;

  mono_memory_barrier ();
  <D.5140>:
  D.5207 = value->key;
  D.5208 = mono_lls_find (list, hp, D.5207);
  if (D.5208 != 0) goto <D.5209>; else goto <D.5210>;
  <D.5209>:
  D.5211 = 0;
  return D.5211;
  <D.5210>:
  cur = hp->hazard_pointers[1];
  prev = hp->hazard_pointers[2];
  value->next = cur;
  if (0 != 0) goto <D.5212>; else goto <D.5213>;
  <D.5212>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 159, "(0) >= 0 && (0) < HAZARD_POINTER_COUNT");
  <D.5213>:
  hp->hazard_pointers[0] = value;
  mono_memory_write_barrier ();
  mono_memory_write_barrier ();
  D.5214 = InterlockedCompareExchangePointer (prev, value, cur);
  if (D.5214 == cur) goto <D.5215>; else goto <D.5216>;
  <D.5215>:
  D.5211 = 1;
  return D.5211;
  <D.5216>:
  goto <D.5140>;
}


mono_lls_remove (struct MonoLinkedListSet * list, struct MonoThreadHazardPointers * hp, struct MonoLinkedListSetNode * value)
{
  long unsigned int D.5218;
  int D.5219;
  gboolean D.5222;
  _Bool D.5223;
  long int D.5224;
  long int D.5225;
  void * D.5228;
  struct MonoLinkedListSetNode * * D.5229;
  void * D.5230;
  void * D.5233;
  void (*<Tc2>) (void *) D.5238;
  struct MonoLinkedListSetNode * cur;
  struct MonoLinkedListSetNode * * prev;
  struct MonoLinkedListSetNode * next;

  <D.5150>:
  D.5218 = value->key;
  D.5219 = mono_lls_find (list, hp, D.5218);
  if (D.5219 == 0) goto <D.5220>; else goto <D.5221>;
  <D.5220>:
  D.5222 = 0;
  return D.5222;
  <D.5221>:
  next = hp->hazard_pointers[0];
  cur = hp->hazard_pointers[1];
  prev = hp->hazard_pointers[2];
  D.5223 = cur != value;
  D.5224 = (long int) D.5223;
  D.5225 = __builtin_expect (D.5224, 0);
  if (D.5225 != 0) goto <D.5226>; else goto <D.5227>;
  <D.5226>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 185, "cur == value");
  <D.5227>:
  D.5228 = mask (next, 1);
  D.5229 = &cur->next;
  D.5230 = InterlockedCompareExchangePointer (D.5229, D.5228, next);
  if (D.5230 != next) goto <D.5231>; else goto <D.5232>;
  <D.5231>:
  // predicted unlikely by continue predictor.
  goto <D.5149>;
  <D.5232>:
  mono_memory_write_barrier ();
  D.5233 = InterlockedCompareExchangePointer (prev, next, cur);
  if (D.5233 == cur) goto <D.5234>; else goto <D.5235>;
  <D.5234>:
  mono_memory_write_barrier ();
  if (0 != 0) goto <D.5236>; else goto <D.5237>;
  <D.5236>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-linked-list-set.c", 194, "(1) >= 0 && (1) < HAZARD_POINTER_COUNT");
  <D.5237>:
  hp->hazard_pointers[1] = 0B;
  D.5238 = list->free_node_func;
  if (D.5238 != 0B) goto <D.5239>; else goto <D.5240>;
  <D.5239>:
  D.5238 = list->free_node_func;
  mono_thread_hazardous_free_or_queue (value, D.5238, 0, 1);
  <D.5240>:
  goto <D.5241>;
  <D.5235>:
  D.5218 = value->key;
  mono_lls_find (list, hp, D.5218);
  <D.5241>:
  D.5222 = 1;
  return D.5222;
  <D.5149>:
  goto <D.5150>;
}


mask (void * n, uintptr_t bit)
{
  void * D.5243;
  long unsigned int n.5;
  long unsigned int D.5245;

  n.5 = (long unsigned int) n;
  D.5245 = n.5 | bit;
  D.5243 = (void *) D.5245;
  return D.5243;
}


