GC_print_static_roots ()
{
  char * D.5260;
  long int D.5261;
  char * D.5262;
  long int D.5263;
  int D.5264;
  int D.5268;
  int D.5269;
  int D.5270;
  unsigned int D.5271;
  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.5130>;
  <D.5129>:
  D.5260 = GC_arrays._static_roots[i].r_start;
  D.5261 = (long int) D.5260;
  D.5262 = GC_arrays._static_roots[i].r_end;
  D.5263 = (long int) D.5262;
  GC_printf ("From 0x%lx to 0x%lx ", D.5261, D.5263, 0, 0, 0, 0);
  D.5264 = GC_arrays._static_roots[i].r_tmp;
  if (D.5264 != 0) goto <D.5265>; else goto <D.5266>;
  <D.5265>:
  GC_printf (" (temporary)\n", 0, 0, 0, 0, 0, 0);
  goto <D.5267>;
  <D.5266>:
  GC_printf ("\n", 0, 0, 0, 0, 0, 0);
  <D.5267>:
  D.5262 = GC_arrays._static_roots[i].r_end;
  D.5268 = (int) D.5262;
  D.5260 = GC_arrays._static_roots[i].r_start;
  D.5269 = (int) D.5260;
  D.5270 = D.5268 - D.5269;
  D.5271 = (unsigned int) D.5270;
  total = D.5271 + total;
  i = i + 1;
  <D.5130>:
  n_root_sets.0 = n_root_sets;
  if (i < n_root_sets.0) goto <D.5129>; else goto <D.5131>;
  <D.5131>:
  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.5275>; else goto <D.5276>;
  <D.5275>:
  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.5276>:
}


GC_is_static_root (char * p)
{
  int last_root_set.4;
  int n_root_sets.5;
  char * D.5282;
  char * D.5285;
  GC_bool D.5288;
  char * D.5289;
  char * D.5292;
  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.5280>; else goto <D.5281>;
  <D.5280>:
  last_root_set.4 = last_root_set;
  D.5282 = GC_arrays._static_roots[last_root_set.4].r_start;
  if (D.5282 <= p) goto <D.5283>; else goto <D.5284>;
  <D.5283>:
  last_root_set.4 = last_root_set;
  D.5285 = GC_arrays._static_roots[last_root_set.4].r_end;
  if (D.5285 > p) goto <D.5286>; else goto <D.5287>;
  <D.5286>:
  D.5288 = 1;
  return D.5288;
  <D.5287>:
  <D.5284>:
  <D.5281>:
  i = 0;
  goto <D.5138>;
  <D.5137>:
  D.5289 = GC_arrays._static_roots[i].r_start;
  if (D.5289 <= p) goto <D.5290>; else goto <D.5291>;
  <D.5290>:
  D.5292 = GC_arrays._static_roots[i].r_end;
  if (D.5292 > p) goto <D.5293>; else goto <D.5294>;
  <D.5293>:
  last_root_set = i;
  D.5288 = 1;
  return D.5288;
  <D.5294>:
  <D.5291>:
  i = i + 1;
  <D.5138>:
  n_root_sets.5 = n_root_sets;
  if (i < n_root_sets.5) goto <D.5137>; else goto <D.5139>;
  <D.5139>:
  D.5288 = 0;
  return D.5288;
}


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

  h = rt_hash (b);
  p = GC_arrays._root_index[h];
  goto <D.5150>;
  <D.5149>:
  D.5296 = p->r_start;
  if (D.5296 == b) goto <D.5297>; else goto <D.5298>;
  <D.5297>:
  D.5299 = p;
  return D.5299;
  <D.5298>:
  p = p->r_next;
  <D.5150>:
  if (p != 0B) goto <D.5149>; else goto <D.5151>;
  <D.5151>:
  D.5299 = 0B;
  return D.5299;
}


rt_hash (char * addr)
{
  long unsigned int D.5301;
  long unsigned int D.5302;
  long unsigned int D.5303;
  int D.5304;
  word result;

  result = (word) addr;
  D.5301 = result >> 24;
  result = D.5301 ^ result;
  D.5302 = result >> 12;
  result = D.5302 ^ result;
  D.5303 = result >> 6;
  result = D.5303 ^ result;
  result = result & 63;
  D.5304 = (int) result;
  return D.5304;
}


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

  D.5306 = _test_and_set (&GC_allocate_lock, 1);
  if (D.5306 != 0) goto <D.5307>; else goto <D.5308>;
  <D.5307>:
  GC_lock ();
  <D.5308>:
  GC_add_roots_inner (b, e, 0);
  GC_clear (&GC_allocate_lock);
}


_test_and_set (int * __p, int __v)
{
  int D.5309;
  int __r;
  int __t;

  __asm__ __volatile__("/* Inline test and set */
.set	push
	.set	mips2
	sync
	1:
	ll	%0,%3
	move	%1,%4
	beq	%0,%4,2f
	sc	%1,%2
	beqz	%1,1b
sync
	.set	pop
	2:
	/* End test and set */" : "=&r" __r, "=&r" __t, "=m" *__p : "m" *__p, "r" __v : "memory");
  D.5309 = __r;
  return D.5309;
}


GC_clear (volatile unsigned int * addr)
{
  __asm__ __volatile__(" " :  :  : "memory");
  *addr = 0;
}


GC_add_roots_inner (char * b, char * e, GC_bool tmp)
{
  char * D.5313;
  int e.6;
  int D.5317;
  int D.5318;
  long unsigned int D.5319;
  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.5326;
  int b.11;
  int D.5328;
  long unsigned int D.5329;
  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.5311>; else goto <D.5312>;
  <D.5311>:
  D.5313 = old->r_end;
  if (D.5313 >= e) goto <D.5314>; else goto <D.5315>;
  <D.5314>:
  return;
  <D.5315>:
  e.6 = (int) e;
  D.5313 = old->r_end;
  D.5317 = (int) D.5313;
  D.5318 = e.6 - D.5317;
  D.5319 = (long unsigned int) D.5318;
  GC_root_size.7 = GC_root_size;
  GC_root_size.8 = D.5319 + GC_root_size.7;
  GC_root_size = GC_root_size.8;
  old->r_end = e;
  return;
  <D.5312>:
  n_root_sets.9 = n_root_sets;
  if (n_root_sets.9 == 1024) goto <D.5323>; else goto <D.5324>;
  <D.5323>:
  GC_abort ("Too many root sets\n");
  <D.5324>:
  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.5326 = &GC_arrays._static_roots[n_root_sets.10];
  add_roots_to_index (D.5326);
  e.6 = (int) e;
  b.11 = (int) b;
  D.5328 = e.6 - b.11;
  D.5329 = (long unsigned int) D.5328;
  GC_root_size.7 = GC_root_size;
  GC_root_size.12 = D.5329 + 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.5333;
  struct roots * D.5334;
  register int h;

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


GC_clear_roots ()
{
  int D.5335;

  D.5335 = _test_and_set (&GC_allocate_lock, 1);
  if (D.5335 != 0) goto <D.5336>; else goto <D.5337>;
  <D.5336>:
  GC_lock ();
  <D.5337>:
  roots_were_cleared = 1;
  n_root_sets = 0;
  GC_root_size = 0;
  {
    register int i;

    i = 0;
    goto <D.5173>;
    <D.5172>:
    GC_arrays._root_index[i] = 0B;
    i = i + 1;
    <D.5173>:
    if (i <= 63) goto <D.5172>; else goto <D.5174>;
    <D.5174>:
  }
  GC_clear (&GC_allocate_lock);
}


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

  i = 0;
  goto <D.5191>;
  <D.5190>:
  D.5338 = GC_arrays._static_roots[i].r_tmp;
  if (D.5338 != 0) goto <D.5339>; else goto <D.5340>;
  <D.5339>:
  GC_remove_root_at_pos (i);
  goto <D.5341>;
  <D.5340>:
  i = i + 1;
  <D.5341>:
  <D.5191>:
  n_root_sets.14 = n_root_sets;
  if (i < n_root_sets.14) goto <D.5190>; else goto <D.5192>;
  <D.5192>:
  GC_rebuild_root_index ();
}


GC_remove_root_at_pos (int i)
{
  char * D.5343;
  int D.5344;
  char * D.5345;
  int D.5346;
  int D.5347;
  long unsigned int D.5348;
  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.5353;
  char * D.5354;
  int D.5355;

  D.5343 = GC_arrays._static_roots[i].r_start;
  D.5344 = (int) D.5343;
  D.5345 = GC_arrays._static_roots[i].r_end;
  D.5346 = (int) D.5345;
  D.5347 = D.5344 - D.5346;
  D.5348 = (long unsigned int) D.5347;
  GC_root_size.15 = GC_root_size;
  GC_root_size.16 = D.5348 + 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.5353 = GC_arrays._static_roots[n_root_sets.18].r_start;
  GC_arrays._static_roots[i].r_start = D.5353;
  n_root_sets.17 = n_root_sets;
  n_root_sets.18 = n_root_sets.17 + -1;
  D.5354 = GC_arrays._static_roots[n_root_sets.18].r_end;
  GC_arrays._static_roots[i].r_end = D.5354;
  n_root_sets.17 = n_root_sets;
  n_root_sets.18 = n_root_sets.17 + -1;
  D.5355 = GC_arrays._static_roots[n_root_sets.18].r_tmp;
  GC_arrays._static_roots[i].r_tmp = D.5355;
  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.5357;
  int n_root_sets.20;
  register int i;

  i = 0;
  goto <D.5182>;
  <D.5181>:
  GC_arrays._root_index[i] = 0B;
  i = i + 1;
  <D.5182>:
  if (i <= 63) goto <D.5181>; else goto <D.5183>;
  <D.5183>:
  i = 0;
  goto <D.5185>;
  <D.5184>:
  i.19 = (sizetype) i;
  D.5357 = &GC_arrays._static_roots[i.19];
  add_roots_to_index (D.5357);
  i = i + 1;
  <D.5185>:
  n_root_sets.20 = n_root_sets;
  if (i < n_root_sets.20) goto <D.5184>; else goto <D.5186>;
  <D.5186>:
}


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

  D.5359 = _test_and_set (&GC_allocate_lock, 1);
  if (D.5359 != 0) goto <D.5360>; else goto <D.5361>;
  <D.5360>:
  GC_lock ();
  <D.5361>:
  GC_remove_roots_inner (b, e);
  GC_clear (&GC_allocate_lock);
}


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

  i = 0;
  goto <D.5203>;
  <D.5202>:
  D.5364 = GC_arrays._static_roots[i].r_start;
  if (D.5364 >= b) goto <D.5365>; else goto <D.5362>;
  <D.5365>:
  D.5366 = GC_arrays._static_roots[i].r_end;
  if (D.5366 <= e) goto <D.5367>; else goto <D.5362>;
  <D.5367>:
  GC_remove_root_at_pos (i);
  goto <D.5363>;
  <D.5362>:
  i = i + 1;
  <D.5363>:
  <D.5203>:
  n_root_sets.21 = n_root_sets;
  if (i < n_root_sets.21) goto <D.5202>; else goto <D.5204>;
  <D.5204>:
  GC_rebuild_root_index ();
}


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

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


GC_next_exclusion (char * start_addr)
{
  unsigned int GC_excl_table_entries.22;
  unsigned int D.5372;
  char * D.5373;
  long unsigned int D.5374;
  long unsigned int start_addr.23;
  char * D.5379;
  long unsigned int D.5380;
  struct exclusion * D.5383;
  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.5216>;
  <D.5215>:
  D.5372 = low + high;
  mid = D.5372 >> 1;
  D.5373 = GC_arrays._excl_table[mid].e_end;
  D.5374 = (long unsigned int) D.5373;
  start_addr.23 = (long unsigned int) start_addr;
  if (D.5374 <= start_addr.23) goto <D.5376>; else goto <D.5377>;
  <D.5376>:
  low = mid + 1;
  goto <D.5378>;
  <D.5377>:
  high = mid;
  <D.5378>:
  <D.5216>:
  if (high > low) goto <D.5215>; else goto <D.5217>;
  <D.5217>:
  D.5379 = GC_arrays._excl_table[low].e_end;
  D.5380 = (long unsigned int) D.5379;
  start_addr.23 = (long unsigned int) start_addr;
  if (D.5380 <= start_addr.23) goto <D.5381>; else goto <D.5382>;
  <D.5381>:
  D.5383 = 0B;
  return D.5383;
  <D.5382>:
  D.5383 = &GC_arrays._excl_table[low];
  return D.5383;
}


GC_exclude_static_roots (void * start, void * finish)
{
  unsigned int GC_excl_table_entries.24;
  char * D.5391;
  long unsigned int D.5392;
  long unsigned int finish.25;
  int next.26;
  int D.5399;
  int D.5400;
  int D.5401;
  unsigned int D.5402;
  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.5386>; else goto <D.5387>;
  <D.5386>:
  next = 0B;
  goto <D.5388>;
  <D.5387>:
  next = GC_next_exclusion (start);
  <D.5388>:
  if (next != 0B) goto <D.5389>; else goto <D.5390>;
  <D.5389>:
  D.5391 = next->e_start;
  D.5392 = (long unsigned int) D.5391;
  finish.25 = (long unsigned int) finish;
  if (D.5392 < finish.25) goto <D.5394>; else goto <D.5395>;
  <D.5394>:
  GC_abort ("exclusion ranges overlap");
  <D.5395>:
  D.5391 = next->e_start;
  D.5392 = (long unsigned int) D.5391;
  finish.25 = (long unsigned int) finish;
  if (D.5392 == finish.25) goto <D.5396>; else goto <D.5397>;
  <D.5396>:
  next->e_start = start;
  return;
  <D.5397>:
  next.26 = (int) next;
  D.5399 = (int) &GC_arrays._excl_table;
  D.5400 = next.26 - D.5399;
  D.5401 = D.5400 /[ex] 8;
  next_index = (size_t) D.5401;
  i = GC_excl_table_entries;
  goto <D.5226>;
  <D.5225>:
  D.5402 = i + 4294967295;
  GC_arrays._excl_table[i] = GC_arrays._excl_table[D.5402];
  i = i + 4294967295;
  <D.5226>:
  if (i > next_index) goto <D.5225>; else goto <D.5227>;
  <D.5227>:
  goto <D.5403>;
  <D.5390>:
  next_index = GC_excl_table_entries;
  <D.5403>:
  GC_excl_table_entries.24 = GC_excl_table_entries;
  if (GC_excl_table_entries.24 == 256) goto <D.5404>; else goto <D.5405>;
  <D.5404>:
  GC_abort ("Too many exclusions");
  <D.5405>:
  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.5236>;
  <D.5235>:
  next = GC_next_exclusion (bottom);
  if (next == 0B) goto <D.5408>; else goto <D.5410>;
  <D.5410>:
  excl_start = next->e_start;
  if (excl_start >= top) goto <D.5408>; else goto <D.5409>;
  <D.5408>:
  GC_push_conditional (bottom, top, all);
  return;
  <D.5409>:
  if (excl_start > bottom) goto <D.5411>; else goto <D.5412>;
  <D.5411>:
  GC_push_conditional (bottom, excl_start, all);
  <D.5412>:
  bottom = next->e_end;
  <D.5236>:
  if (bottom < top) goto <D.5235>; else goto <D.5237>;
  <D.5237>:
}


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

  if (cold_gc_frame == 0B) goto <D.5414>; else goto <D.5415>;
  <D.5414>:
  return;
  <D.5415>:
  D.5416 = GC_approx_sp ();
  GC_push_all_eager (D.5416, 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.5419>; else goto <D.5420>;
  <D.5419>:
  GC_register_dynamic_libraries ();
  <D.5420>:
}


GC_push_roots (GC_bool all, char * cold_gc_frame)
{
  char * D.5421;
  char * D.5422;
  int n_root_sets.29;
  char * * D.5424;
  int GC_n_kinds.30;
  int GC_no_dls.31;
  int roots_were_cleared.32;
  void (*<T630>) (void) GC_push_other_roots.33;
  int i;
  int kind;

  i = 0;
  goto <D.5253>;
  <D.5252>:
  D.5421 = GC_arrays._static_roots[i].r_start;
  D.5422 = GC_arrays._static_roots[i].r_end;
  GC_push_conditional_with_exclusions (D.5421, D.5422, all);
  i = i + 1;
  <D.5253>:
  n_root_sets.29 = n_root_sets;
  if (i < n_root_sets.29) goto <D.5252>; else goto <D.5254>;
  <D.5254>:
  kind = 0;
  goto <D.5257>;
  <D.5256>:
  {
    void * base;

    D.5424 = GC_obj_kinds[kind].ok_freelist;
    base = GC_base (D.5424);
    if (base != 0B) goto <D.5425>; else goto <D.5426>;
    <D.5425>:
    GC_set_mark_bit (base);
    <D.5426>:
  }
  kind = kind + 1;
  <D.5257>:
  GC_n_kinds.30 = GC_n_kinds;
  if (kind < GC_n_kinds.30) goto <D.5256>; else goto <D.5258>;
  <D.5258>:
  GC_no_dls.31 = GC_no_dls;
  if (GC_no_dls.31 != 0) goto <D.5428>; else goto <D.5431>;
  <D.5431>:
  roots_were_cleared.32 = roots_were_cleared;
  if (roots_were_cleared.32 != 0) goto <D.5428>; else goto <D.5429>;
  <D.5428>:
  GC_push_gc_structures ();
  <D.5429>:
  GC_generic_push_regs (cold_gc_frame);
  GC_push_other_roots.33 = GC_push_other_roots;
  if (GC_push_other_roots.33 != 0B) goto <D.5434>; else goto <D.5435>;
  <D.5434>:
  GC_push_other_roots.33 = GC_push_other_roots;
  GC_push_other_roots.33 ();
  <D.5435>:
}


