GC_print_static_roots ()
{
  char * D.5325;
  long int D.5326;
  char * D.5327;
  long int D.5328;
  int D.5329;
  int D.5333;
  int D.5334;
  int D.5335;
  unsigned int D.5336;
  int n_root_sets.0;
  long int total.1;
  long unsigned int GC_root_size.2;
  long int GC_root_size.3;
  register int i;
  size_t total;

  total = 0;
  i = 0;
  goto <D.5194>;
  <D.5193>:
  D.5325 = GC_arrays._static_roots[i].r_end;
  D.5326 = (long int) D.5325;
  D.5327 = GC_arrays._static_roots[i].r_start;
  D.5328 = (long int) D.5327;
  GC_printf ("From 0x%lx to 0x%lx ", D.5328, D.5326, 0, 0, 0, 0);
  D.5329 = GC_arrays._static_roots[i].r_tmp;
  if (D.5329 != 0) goto <D.5330>; else goto <D.5331>;
  <D.5330>:
  GC_printf (" (temporary)\n", 0, 0, 0, 0, 0, 0);
  goto <D.5332>;
  <D.5331>:
  GC_printf ("\n", 0, 0, 0, 0, 0, 0);
  <D.5332>:
  D.5325 = GC_arrays._static_roots[i].r_end;
  D.5333 = (int) D.5325;
  D.5327 = GC_arrays._static_roots[i].r_start;
  D.5334 = (int) D.5327;
  D.5335 = D.5333 - D.5334;
  D.5336 = (unsigned int) D.5335;
  total = D.5336 + total;
  i = i + 1;
  <D.5194>:
  n_root_sets.0 = n_root_sets;
  if (i < n_root_sets.0) goto <D.5193>; else goto <D.5195>;
  <D.5195>:
  total.1 = (long int) total;
  GC_printf ("Total size: %ld\n", total.1, 0, 0, 0, 0, 0);
  GC_root_size.2 = GC_root_size;
  if (GC_root_size.2 != total) goto <D.5340>; else goto <D.5341>;
  <D.5340>:
  GC_root_size.2 = GC_root_size;
  GC_root_size.3 = (long int) GC_root_size.2;
  GC_printf ("GC_root_size incorrect: %ld!!\n", GC_root_size.3, 0, 0, 0, 0, 0);
  <D.5341>:
}


GC_is_static_root (char * p)
{
  int last_root_set.4;
  int n_root_sets.5;
  char * D.5347;
  char * D.5350;
  GC_bool D.5353;
  char * D.5354;
  char * D.5357;
  static int last_root_set = 1024;
  register int i;

  last_root_set.4 = last_root_set;
  n_root_sets.5 = n_root_sets;
  if (last_root_set.4 < n_root_sets.5) goto <D.5345>; else goto <D.5346>;
  <D.5345>:
  last_root_set.4 = last_root_set;
  D.5347 = GC_arrays._static_roots[last_root_set.4].r_start;
  if (D.5347 <= p) goto <D.5348>; else goto <D.5349>;
  <D.5348>:
  last_root_set.4 = last_root_set;
  D.5350 = GC_arrays._static_roots[last_root_set.4].r_end;
  if (D.5350 > p) goto <D.5351>; else goto <D.5352>;
  <D.5351>:
  D.5353 = 1;
  return D.5353;
  <D.5352>:
  <D.5349>:
  <D.5346>:
  i = 0;
  goto <D.5202>;
  <D.5201>:
  D.5354 = GC_arrays._static_roots[i].r_start;
  if (D.5354 <= p) goto <D.5355>; else goto <D.5356>;
  <D.5355>:
  D.5357 = GC_arrays._static_roots[i].r_end;
  if (D.5357 > p) goto <D.5358>; else goto <D.5359>;
  <D.5358>:
  last_root_set = i;
  D.5353 = 1;
  return D.5353;
  <D.5359>:
  <D.5356>:
  i = i + 1;
  <D.5202>:
  n_root_sets.5 = n_root_sets;
  if (i < n_root_sets.5) goto <D.5201>; else goto <D.5203>;
  <D.5203>:
  D.5353 = 0;
  return D.5353;
}


GC_roots_present (char * b)
{
  char * D.5361;
  struct roots * D.5364;
  register int h;
  register struct roots * p;

  h = rt_hash (b);
  p = GC_arrays._root_index[h];
  goto <D.5214>;
  <D.5213>:
  D.5361 = p->r_start;
  if (D.5361 == b) goto <D.5362>; else goto <D.5363>;
  <D.5362>:
  D.5364 = p;
  return D.5364;
  <D.5363>:
  p = p->r_next;
  <D.5214>:
  if (p != 0B) goto <D.5213>; else goto <D.5215>;
  <D.5215>:
  D.5364 = 0B;
  return D.5364;
}


rt_hash (char * addr)
{
  long unsigned int D.5366;
  long unsigned int D.5367;
  long unsigned int D.5368;
  int D.5369;
  word result;

  result = (word) addr;
  D.5366 = result >> 24;
  result = D.5366 ^ result;
  D.5367 = result >> 12;
  result = D.5367 ^ result;
  D.5368 = result >> 6;
  result = D.5368 ^ result;
  result = result & 63;
  D.5369 = (int) result;
  return D.5369;
}


GC_add_roots (char * b, char * e)
{
  int D.5371;

  D.5371 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5371 != 0) goto <D.5372>; else goto <D.5373>;
  <D.5372>:
  GC_lock ();
  <D.5373>:
  GC_add_roots_inner (b, e, 0);
  pthread_mutex_unlock (&GC_allocate_ml);
}


GC_add_roots_inner (char * b, char * e, GC_bool tmp)
{
  char * D.5376;
  int e.6;
  int D.5380;
  int D.5381;
  long unsigned int D.5382;
  long unsigned int GC_root_size.7;
  long unsigned int GC_root_size.8;
  int n_root_sets.9;
  sizetype n_root_sets.10;
  struct roots * D.5389;
  int b.11;
  int D.5391;
  long unsigned int D.5392;
  long unsigned int GC_root_size.12;
  int n_root_sets.13;
  struct roots * old;

  old = GC_roots_present (b);
  if (old != 0B) goto <D.5374>; else goto <D.5375>;
  <D.5374>:
  D.5376 = old->r_end;
  if (D.5376 >= e) goto <D.5377>; else goto <D.5378>;
  <D.5377>:
  return;
  <D.5378>:
  e.6 = (int) e;
  D.5376 = old->r_end;
  D.5380 = (int) D.5376;
  D.5381 = e.6 - D.5380;
  D.5382 = (long unsigned int) D.5381;
  GC_root_size.7 = GC_root_size;
  GC_root_size.8 = D.5382 + GC_root_size.7;
  GC_root_size = GC_root_size.8;
  old->r_end = e;
  return;
  <D.5375>:
  n_root_sets.9 = n_root_sets;
  if (n_root_sets.9 == 1024) goto <D.5386>; else goto <D.5387>;
  <D.5386>:
  GC_abort ("Too many root sets\n");
  <D.5387>:
  n_root_sets.9 = n_root_sets;
  GC_arrays._static_roots[n_root_sets.9].r_start = b;
  n_root_sets.9 = n_root_sets;
  GC_arrays._static_roots[n_root_sets.9].r_end = e;
  n_root_sets.9 = n_root_sets;
  GC_arrays._static_roots[n_root_sets.9].r_tmp = tmp;
  n_root_sets.9 = n_root_sets;
  GC_arrays._static_roots[n_root_sets.9].r_next = 0B;
  n_root_sets.9 = n_root_sets;
  n_root_sets.10 = (sizetype) n_root_sets.9;
  D.5389 = &GC_arrays._static_roots[n_root_sets.10];
  add_roots_to_index (D.5389);
  e.6 = (int) e;
  b.11 = (int) b;
  D.5391 = e.6 - b.11;
  D.5392 = (long unsigned int) D.5391;
  GC_root_size.7 = GC_root_size;
  GC_root_size.12 = D.5392 + GC_root_size.7;
  GC_root_size = GC_root_size.12;
  n_root_sets.9 = n_root_sets;
  n_root_sets.13 = n_root_sets.9 + 1;
  n_root_sets = n_root_sets.13;
}


add_roots_to_index (struct roots * p)
{
  char * D.5396;
  struct roots * D.5397;
  register int h;

  D.5396 = p->r_start;
  h = rt_hash (D.5396);
  D.5397 = GC_arrays._root_index[h];
  p->r_next = D.5397;
  GC_arrays._root_index[h] = p;
}


GC_clear_roots ()
{
  int D.5398;

  D.5398 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5398 != 0) goto <D.5399>; else goto <D.5400>;
  <D.5399>:
  GC_lock ();
  <D.5400>:
  roots_were_cleared = 1;
  n_root_sets = 0;
  GC_root_size = 0;
  {
    register int i;

    i = 0;
    goto <D.5237>;
    <D.5236>:
    GC_arrays._root_index[i] = 0B;
    i = i + 1;
    <D.5237>:
    if (i <= 63) goto <D.5236>; else goto <D.5238>;
    <D.5238>:
  }
  pthread_mutex_unlock (&GC_allocate_ml);
}


GC_remove_tmp_roots ()
{
  int D.5401;
  int n_root_sets.14;
  register int i;

  i = 0;
  goto <D.5255>;
  <D.5254>:
  D.5401 = GC_arrays._static_roots[i].r_tmp;
  if (D.5401 != 0) goto <D.5402>; else goto <D.5403>;
  <D.5402>:
  GC_remove_root_at_pos (i);
  goto <D.5404>;
  <D.5403>:
  i = i + 1;
  <D.5404>:
  <D.5255>:
  n_root_sets.14 = n_root_sets;
  if (i < n_root_sets.14) goto <D.5254>; else goto <D.5256>;
  <D.5256>:
  GC_rebuild_root_index ();
}


GC_remove_root_at_pos (int i)
{
  char * D.5406;
  int D.5407;
  char * D.5408;
  int D.5409;
  int D.5410;
  long unsigned int D.5411;
  long unsigned int GC_root_size.15;
  long unsigned int GC_root_size.16;
  int n_root_sets.17;
  int n_root_sets.18;
  char * D.5416;
  char * D.5417;
  int D.5418;

  D.5406 = GC_arrays._static_roots[i].r_start;
  D.5407 = (int) D.5406;
  D.5408 = GC_arrays._static_roots[i].r_end;
  D.5409 = (int) D.5408;
  D.5410 = D.5407 - D.5409;
  D.5411 = (long unsigned int) D.5410;
  GC_root_size.15 = GC_root_size;
  GC_root_size.16 = D.5411 + GC_root_size.15;
  GC_root_size = GC_root_size.16;
  n_root_sets.17 = n_root_sets;
  n_root_sets.18 = n_root_sets.17 + -1;
  D.5416 = GC_arrays._static_roots[n_root_sets.18].r_start;
  GC_arrays._static_roots[i].r_start = D.5416;
  n_root_sets.17 = n_root_sets;
  n_root_sets.18 = n_root_sets.17 + -1;
  D.5417 = GC_arrays._static_roots[n_root_sets.18].r_end;
  GC_arrays._static_roots[i].r_end = D.5417;
  n_root_sets.17 = n_root_sets;
  n_root_sets.18 = n_root_sets.17 + -1;
  D.5418 = GC_arrays._static_roots[n_root_sets.18].r_tmp;
  GC_arrays._static_roots[i].r_tmp = D.5418;
  n_root_sets.17 = n_root_sets;
  n_root_sets.18 = n_root_sets.17 + -1;
  n_root_sets = n_root_sets.18;
}


GC_rebuild_root_index ()
{
  sizetype i.19;
  struct roots * D.5420;
  int n_root_sets.20;
  register int i;

  i = 0;
  goto <D.5246>;
  <D.5245>:
  GC_arrays._root_index[i] = 0B;
  i = i + 1;
  <D.5246>:
  if (i <= 63) goto <D.5245>; else goto <D.5247>;
  <D.5247>:
  i = 0;
  goto <D.5249>;
  <D.5248>:
  i.19 = (sizetype) i;
  D.5420 = &GC_arrays._static_roots[i.19];
  add_roots_to_index (D.5420);
  i = i + 1;
  <D.5249>:
  n_root_sets.20 = n_root_sets;
  if (i < n_root_sets.20) goto <D.5248>; else goto <D.5250>;
  <D.5250>:
}


GC_remove_roots (char * b, char * e)
{
  int D.5422;

  D.5422 = pthread_mutex_trylock (&GC_allocate_ml);
  if (D.5422 != 0) goto <D.5423>; else goto <D.5424>;
  <D.5423>:
  GC_lock ();
  <D.5424>:
  GC_remove_roots_inner (b, e);
  pthread_mutex_unlock (&GC_allocate_ml);
}


GC_remove_roots_inner (char * b, char * e)
{
  char * D.5427;
  char * D.5429;
  int n_root_sets.21;
  int i;

  i = 0;
  goto <D.5267>;
  <D.5266>:
  D.5427 = GC_arrays._static_roots[i].r_start;
  if (D.5427 >= b) goto <D.5428>; else goto <D.5425>;
  <D.5428>:
  D.5429 = GC_arrays._static_roots[i].r_end;
  if (D.5429 <= e) goto <D.5430>; else goto <D.5425>;
  <D.5430>:
  GC_remove_root_at_pos (i);
  goto <D.5426>;
  <D.5425>:
  i = i + 1;
  <D.5426>:
  <D.5267>:
  n_root_sets.21 = n_root_sets;
  if (i < n_root_sets.21) goto <D.5266>; else goto <D.5268>;
  <D.5268>:
  GC_rebuild_root_index ();
}


GC_approx_sp ()
{
  char * D.5432;
  volatile word dummy;

  dummy = 42;
  D.5432 = &dummy;
  return D.5432;
}


GC_next_exclusion (char * start_addr)
{
  unsigned int GC_excl_table_entries.22;
  unsigned int D.5435;
  char * D.5436;
  long unsigned int D.5437;
  long unsigned int start_addr.23;
  char * D.5442;
  long unsigned int D.5443;
  struct exclusion * D.5446;
  size_t low;
  size_t high;
  size_t mid;

  low = 0;
  GC_excl_table_entries.22 = GC_excl_table_entries;
  high = GC_excl_table_entries.22 + 4294967295;
  goto <D.5280>;
  <D.5279>:
  D.5435 = low + high;
  mid = D.5435 >> 1;
  D.5436 = GC_arrays._excl_table[mid].e_end;
  D.5437 = (long unsigned int) D.5436;
  start_addr.23 = (long unsigned int) start_addr;
  if (D.5437 <= start_addr.23) goto <D.5439>; else goto <D.5440>;
  <D.5439>:
  low = mid + 1;
  goto <D.5441>;
  <D.5440>:
  high = mid;
  <D.5441>:
  <D.5280>:
  if (high > low) goto <D.5279>; else goto <D.5281>;
  <D.5281>:
  D.5442 = GC_arrays._excl_table[low].e_end;
  D.5443 = (long unsigned int) D.5442;
  start_addr.23 = (long unsigned int) start_addr;
  if (D.5443 <= start_addr.23) goto <D.5444>; else goto <D.5445>;
  <D.5444>:
  D.5446 = 0B;
  return D.5446;
  <D.5445>:
  D.5446 = &GC_arrays._excl_table[low];
  return D.5446;
}


GC_exclude_static_roots (void * start, void * finish)
{
  unsigned int GC_excl_table_entries.24;
  char * D.5454;
  long unsigned int D.5455;
  long unsigned int finish.25;
  int next.26;
  int D.5462;
  int D.5463;
  int D.5464;
  unsigned int D.5465;
  unsigned int GC_excl_table_entries.27;
  struct exclusion * next;
  size_t next_index;
  size_t i;

  GC_excl_table_entries.24 = GC_excl_table_entries;
  if (GC_excl_table_entries.24 == 0) goto <D.5449>; else goto <D.5450>;
  <D.5449>:
  next = 0B;
  goto <D.5451>;
  <D.5450>:
  next = GC_next_exclusion (start);
  <D.5451>:
  if (next != 0B) goto <D.5452>; else goto <D.5453>;
  <D.5452>:
  D.5454 = next->e_start;
  D.5455 = (long unsigned int) D.5454;
  finish.25 = (long unsigned int) finish;
  if (D.5455 < finish.25) goto <D.5457>; else goto <D.5458>;
  <D.5457>:
  GC_abort ("exclusion ranges overlap");
  <D.5458>:
  D.5454 = next->e_start;
  D.5455 = (long unsigned int) D.5454;
  finish.25 = (long unsigned int) finish;
  if (D.5455 == finish.25) goto <D.5459>; else goto <D.5460>;
  <D.5459>:
  next->e_start = start;
  return;
  <D.5460>:
  next.26 = (int) next;
  D.5462 = (int) &GC_arrays._excl_table;
  D.5463 = next.26 - D.5462;
  D.5464 = D.5463 /[ex] 8;
  next_index = (size_t) D.5464;
  i = GC_excl_table_entries;
  goto <D.5290>;
  <D.5289>:
  D.5465 = i + 4294967295;
  GC_arrays._excl_table[i] = GC_arrays._excl_table[D.5465];
  i = i + 4294967295;
  <D.5290>:
  if (i > next_index) goto <D.5289>; else goto <D.5291>;
  <D.5291>:
  goto <D.5466>;
  <D.5453>:
  next_index = GC_excl_table_entries;
  <D.5466>:
  GC_excl_table_entries.24 = GC_excl_table_entries;
  if (GC_excl_table_entries.24 == 256) goto <D.5467>; else goto <D.5468>;
  <D.5467>:
  GC_abort ("Too many exclusions");
  <D.5468>:
  GC_arrays._excl_table[next_index].e_start = start;
  GC_arrays._excl_table[next_index].e_end = finish;
  GC_excl_table_entries.24 = GC_excl_table_entries;
  GC_excl_table_entries.27 = GC_excl_table_entries.24 + 1;
  GC_excl_table_entries = GC_excl_table_entries.27;
}


GC_push_conditional_with_exclusions (char * bottom, char * top, int all)
{
  struct exclusion * next;
  char * excl_start;

  goto <D.5300>;
  <D.5299>:
  next = GC_next_exclusion (bottom);
  if (next == 0B) goto <D.5471>; else goto <D.5473>;
  <D.5473>:
  excl_start = next->e_start;
  if (excl_start >= top) goto <D.5471>; else goto <D.5472>;
  <D.5471>:
  GC_push_conditional (bottom, top, all);
  return;
  <D.5472>:
  if (excl_start > bottom) goto <D.5474>; else goto <D.5475>;
  <D.5474>:
  GC_push_conditional (bottom, excl_start, all);
  <D.5475>:
  bottom = next->e_end;
  <D.5300>:
  if (bottom < top) goto <D.5299>; else goto <D.5301>;
  <D.5301>:
}


GC_push_current_stack (char * cold_gc_frame)
{
  char * D.5479;

  if (cold_gc_frame == 0B) goto <D.5477>; else goto <D.5478>;
  <D.5477>:
  return;
  <D.5478>:
  D.5479 = GC_approx_sp ();
  GC_push_all_eager (D.5479, cold_gc_frame);
}


GC_push_gc_structures ()
{
  GC_push_finalizer_structures ();
  GC_push_stubborn_structures ();
  GC_push_thread_structures ();
}


GC_cond_register_dynamic_libraries ()
{
  int GC_no_dls.28;

  GC_remove_tmp_roots ();
  GC_no_dls.28 = GC_no_dls;
  if (GC_no_dls.28 == 0) goto <D.5482>; else goto <D.5483>;
  <D.5482>:
  GC_register_dynamic_libraries ();
  <D.5483>:
}


GC_push_roots (GC_bool all, char * cold_gc_frame)
{
  char * D.5484;
  char * D.5485;
  int n_root_sets.29;
  char * * D.5487;
  int GC_n_kinds.30;
  int GC_no_dls.31;
  int roots_were_cleared.32;
  int GC_world_stopped.33;
  void (*<T640>) (void) GC_push_other_roots.34;
  int i;
  int kind;

  i = 0;
  goto <D.5318>;
  <D.5317>:
  D.5484 = GC_arrays._static_roots[i].r_end;
  D.5485 = GC_arrays._static_roots[i].r_start;
  GC_push_conditional_with_exclusions (D.5485, D.5484, all);
  i = i + 1;
  <D.5318>:
  n_root_sets.29 = n_root_sets;
  if (i < n_root_sets.29) goto <D.5317>; else goto <D.5319>;
  <D.5319>:
  kind = 0;
  goto <D.5322>;
  <D.5321>:
  {
    void * base;

    D.5487 = GC_obj_kinds[kind].ok_freelist;
    base = GC_base (D.5487);
    if (base != 0B) goto <D.5488>; else goto <D.5489>;
    <D.5488>:
    GC_set_mark_bit (base);
    <D.5489>:
  }
  kind = kind + 1;
  <D.5322>:
  GC_n_kinds.30 = GC_n_kinds;
  if (kind < GC_n_kinds.30) goto <D.5321>; else goto <D.5323>;
  <D.5323>:
  GC_no_dls.31 = GC_no_dls;
  if (GC_no_dls.31 != 0) goto <D.5491>; else goto <D.5494>;
  <D.5494>:
  roots_were_cleared.32 = roots_were_cleared;
  if (roots_were_cleared.32 != 0) goto <D.5491>; else goto <D.5492>;
  <D.5491>:
  GC_push_gc_structures ();
  <D.5492>:
  GC_world_stopped.33 = GC_world_stopped;
  if (GC_world_stopped.33 != 0) goto <D.5497>; else goto <D.5498>;
  <D.5497>:
  GC_mark_thread_local_free_lists ();
  <D.5498>:
  GC_generic_push_regs (cold_gc_frame);
  GC_push_other_roots.34 = GC_push_other_roots;
  if (GC_push_other_roots.34 != 0B) goto <D.5500>; else goto <D.5501>;
  <D.5500>:
  GC_push_other_roots.34 = GC_push_other_roots;
  GC_push_other_roots.34 ();
  <D.5501>:
}


