sgen_card_table_get_card_data (guint8 * data_dest, mword address, mword cards)
{
  gboolean D.18529;
  mword * start;
  mword * dest;
  mword * end;
  mword mask;

  start = sgen_card_table_get_shadow_card_address (address);
  dest = data_dest;
  end = data_dest + cards;
  mask = 0;
  goto <D.18364>;
  <D.18363>:
  {
    mword v;

    v = *start;
    *dest = v;
    mask = mask | v;
  }
  dest = dest + 8;
  start = start + 8;
  <D.18364>:
  if (dest < end) goto <D.18363>; else goto <D.18365>;
  <D.18365>:
  D.18529 = (gboolean) mask;
  return D.18529;
}


sgen_card_table_get_shadow_card_address (mword address)
{
  guint8 * D.18531;
  guint8 * sgen_shadow_cardtable.0;
  long unsigned int D.18533;
  sizetype D.18534;

  sgen_shadow_cardtable.0 = sgen_shadow_cardtable;
  D.18533 = address >> 9;
  D.18534 = D.18533 & 8388607;
  D.18531 = sgen_shadow_cardtable.0 + D.18534;
  return D.18531;
}


sgen_card_table_align_pointer (void * ptr)
{
  void * D.18536;
  long unsigned int ptr.1;
  long unsigned int D.18538;

  ptr.1 = (long unsigned int) ptr;
  D.18538 = ptr.1 & 18446744073709551104;
  D.18536 = (void *) D.18538;
  return D.18536;
}


sgen_card_table_mark_range (mword address, mword size)
{
  guint8 * D.18540;
  long unsigned int D.18541;

  D.18540 = sgen_card_table_get_card_address (address);
  D.18541 = cards_in_range (address, size);
  memset (D.18540, 1, D.18541);
}


sgen_card_table_get_card_address (mword address)
{
  guint8 * D.18542;
  guint8 * sgen_cardtable.2;
  long unsigned int D.18544;
  sizetype D.18545;

  sgen_cardtable.2 = sgen_cardtable;
  D.18544 = address >> 9;
  D.18545 = D.18544 & 8388607;
  D.18542 = sgen_cardtable.2 + D.18545;
  return D.18542;
}


cards_in_range (mword address, mword size)
{
  mword iftmp.3;
  long unsigned int D.18551;
  mword D.18552;
  long unsigned int D.18553;
  long unsigned int D.18554;
  long unsigned int D.18555;
  mword end;

  if (size != 0) goto <D.18548>; else goto <D.18549>;
  <D.18548>:
  iftmp.3 = size;
  goto <D.18550>;
  <D.18549>:
  iftmp.3 = 1;
  <D.18550>:
  D.18551 = iftmp.3 + address;
  end = D.18551 + 18446744073709551615;
  D.18553 = end >> 9;
  D.18554 = address >> 9;
  D.18555 = D.18553 - D.18554;
  D.18552 = D.18555 + 1;
  return D.18552;
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.18559;
  int D.18564;
  void * D.18566;
  long unsigned int D.18567;

  D.18559 = __builtin_constant_p (__len);
  if (D.18559 != 0) goto <D.18560>; else goto <D.18561>;
  <D.18560>:
  if (__len == 0) goto <D.18562>; else goto <D.18563>;
  <D.18562>:
  D.18564 = __builtin_constant_p (__ch);
  if (D.18564 == 0) goto <D.18557>; else goto <D.18565>;
  <D.18565>:
  if (__ch != 0) goto <D.18557>; else goto <D.18558>;
  <D.18557>:
  __warn_memset_zero_len ();
  D.18566 = __dest;
  return D.18566;
  <D.18558>:
  <D.18563>:
  <D.18561>:
  D.18567 = __builtin_object_size (__dest, 0);
  D.18566 = __builtin___memset_chk (__dest, __ch, __len, D.18567);
  return D.18566;
}


sgen_card_table_update_mod_union (guint8 * dest, char * obj, mword obj_size, size_t * out_num_cards)
{
  long unsigned int obj.4;
  long unsigned int D.18570;
  long unsigned int D.18571;
  guint8 * D.18572;
  _Bool D.18573;
  guint8 * sgen_cardtable.5;
  long int edge_card.6;
  long int start_card.7;
  long int D.18579;
  guint8 * D.18580;
  long int D.18581;
  long int D.18582;
  long int end_card.8;
  long int sgen_cardtable.9;
  long int D.18587;
  long int D.18588;
  long unsigned int D.18589;
  _Bool D.18590;
  long int D.18591;
  long int D.18592;
  long int D.18596;
  guint8 * D.18601;
  guint8 * result;
  guint8 * start_card;
  guint8 * end_card;
  gboolean init;
  size_t num_cards;

  result = dest;
  obj.4 = (long unsigned int) obj;
  start_card = sgen_card_table_get_card_address (obj.4);
  obj.4 = (long unsigned int) obj;
  D.18570 = obj.4 + obj_size;
  D.18571 = D.18570 + 18446744073709551615;
  D.18572 = sgen_card_table_get_card_address (D.18571);
  end_card = D.18572 + 1;
  D.18573 = dest == 0B;
  init = (gboolean) D.18573;
  if (end_card < start_card) goto <D.18574>; else goto <D.18575>;
  <D.18574>:
  {
    guint8 * edge_card;
    size_t num_cards_to_edge;

    sgen_cardtable.5 = sgen_cardtable;
    edge_card = sgen_cardtable.5 + 8388608;
    edge_card.6 = (long int) edge_card;
    start_card.7 = (long int) start_card;
    D.18579 = edge_card.6 - start_card.7;
    num_cards_to_edge = (size_t) D.18579;
    D.18580 = end_card + 8388608;
    D.18581 = (long int) D.18580;
    start_card.7 = (long int) start_card;
    D.18582 = D.18581 - start_card.7;
    num_cards = (size_t) D.18582;
    if (init != 0) goto <D.18583>; else goto <D.18584>;
    <D.18583>:
    dest = alloc_mod_union (num_cards);
    result = dest;
    <D.18584>:
    update_mod_union (dest, init, start_card, edge_card);
    edge_card.6 = (long int) edge_card;
    start_card.7 = (long int) start_card;
    D.18579 = edge_card.6 - start_card.7;
    end_card.8 = (long int) end_card;
    sgen_cardtable.5 = sgen_cardtable;
    sgen_cardtable.9 = (long int) sgen_cardtable.5;
    D.18587 = end_card.8 - sgen_cardtable.9;
    D.18588 = D.18579 + D.18587;
    D.18589 = (long unsigned int) D.18588;
    D.18590 = D.18589 != num_cards;
    D.18591 = (long int) D.18590;
    D.18592 = __builtin_expect (D.18591, 0);
    if (D.18592 != 0) goto <D.18593>; else goto <D.18594>;
    <D.18593>:
    monoeg_g_log (0B, 4, "wrong number of cards");
    <D.18420>:
    goto <D.18420>;
    <D.18594>:
    dest = dest + num_cards_to_edge;
    start_card = sgen_cardtable;
  }
  goto <D.18595>;
  <D.18575>:
  end_card.8 = (long int) end_card;
  start_card.7 = (long int) start_card;
  D.18596 = end_card.8 - start_card.7;
  num_cards = (size_t) D.18596;
  if (init != 0) goto <D.18597>; else goto <D.18598>;
  <D.18597>:
  dest = alloc_mod_union (num_cards);
  result = dest;
  <D.18598>:
  <D.18595>:
  update_mod_union (dest, init, start_card, end_card);
  if (out_num_cards != 0B) goto <D.18599>; else goto <D.18600>;
  <D.18599>:
  *out_num_cards = num_cards;
  <D.18600>:
  D.18601 = result;
  return D.18601;
}


alloc_mod_union (size_t num_cards)
{
  guint8 * D.18603;

  D.18603 = sgen_alloc_internal_dynamic (num_cards, 28, 1);
  return D.18603;
}


update_mod_union (guint8 * dest, gboolean init, guint8 * start_card, guint8 * end_card)
{
  long int end_card.10;
  long int start_card.11;
  long int D.18607;
  sizetype D.18611;
  guint8 * D.18612;
  unsigned char D.18613;
  guint8 * D.18614;
  unsigned char D.18615;
  unsigned char D.18616;
  long unsigned int D.18617;
  size_t num_cards;

  end_card.10 = (long int) end_card;
  start_card.11 = (long int) start_card;
  D.18607 = end_card.10 - start_card.11;
  num_cards = (size_t) D.18607;
  if (init != 0) goto <D.18608>; else goto <D.18609>;
  <D.18608>:
  memcpy (dest, start_card, num_cards);
  goto <D.18610>;
  <D.18609>:
  {
    int i;

    i = 0;
    goto <D.18402>;
    <D.18401>:
    D.18611 = (sizetype) i;
    D.18612 = dest + D.18611;
    D.18611 = (sizetype) i;
    D.18612 = dest + D.18611;
    D.18613 = *D.18612;
    D.18611 = (sizetype) i;
    D.18614 = start_card + D.18611;
    D.18615 = *D.18614;
    D.18616 = D.18613 | D.18615;
    *D.18612 = D.18616;
    i = i + 1;
    <D.18402>:
    D.18617 = (long unsigned int) i;
    if (D.18617 < num_cards) goto <D.18401>; else goto <D.18403>;
    <D.18403>:
  }
  <D.18610>:
}


memcpy (void * restrict __dest, const void * restrict __src, size_t __len)
{
  void * D.18618;
  long unsigned int D.18619;

  D.18619 = __builtin_object_size (__dest, 0);
  D.18618 = __builtin___memcpy_chk (__dest, __src, __len, D.18619);
  return D.18618;
}


mono_gc_get_card_table (int * shift_bits, void * * mask)
{
  guint8 * sgen_cardtable.12;
  guint8 * D.18624;

  sgen_cardtable.12 = sgen_cardtable;
  if (sgen_cardtable.12 == 0B) goto <D.18622>; else goto <D.18623>;
  <D.18622>:
  D.18624 = 0B;
  return D.18624;
  <D.18623>:
  *shift_bits = 9;
  *mask = 8388607B;
  D.18624 = sgen_cardtable;
  return D.18624;
}


mono_gc_card_table_nursery_check ()
{
  gboolean D.18626;
  int D.18627;
  _Bool D.18628;

  D.18627 = major_collector.is_concurrent;
  D.18628 = D.18627 == 0;
  D.18626 = (gboolean) D.18628;
  return D.18626;
}


sgen_cardtable_scan_object (char * obj, mword block_obj_size, guint8 * cards, gboolean mod_union, struct SgenGrayQueue * queue)
{
  long unsigned int D.18630;
  long unsigned int D.18631;
  void * D.18632;
  long unsigned int D.18633;
  int D.18634;
  unsigned char D.18637;
  unsigned int D.18640;
  struct MonoClass * D.18641;
  void * D.18642;
  long unsigned int obj.13;
  guint8 * sgen_shadow_cardtable.14;
  guint8 * D.18650;
  long int card_data_end.15;
  long int D.18654;
  long int D.18655;
  sizetype D.18656;
  long int card_data.16;
  long int card_base.17;
  long int D.18659;
  unsigned int D.18660;
  unsigned int extra_idx.18;
  unsigned int D.18662;
  int D.18663;
  sizetype D.18664;
  double[0:] * D.18667;
  long int start.19;
  char * D.18672;
  long int D.18673;
  long int D.18674;
  long int D.18675;
  long int D.18676;
  double[0:] * D.18677;
  int D.18678;
  sizetype D.18679;
  long unsigned int D.18680;
  long unsigned int D.18681;
  struct SgenObjectOperations * D.18684;
  sizetype D.18685;
  struct SgenObjectOperations * D.18687;
  int D.18692;
  _Bool D.18693;
  long int D.18694;
  long int D.18695;
  int D.18696;
  _Bool D.18697;
  long int D.18698;
  long int D.18699;
  guint8 * D.18702;
  int D.18708;
  struct SgenObjectOperations * D.18711;
  void (*<T2c8a>) (char *, struct SgenGrayQueue *) D.18712;
  int D.18714;
  struct SgenObjectOperations * D.18717;
  void (*<T2c8a>) (char *, struct SgenGrayQueue *) D.18718;
  struct MonoVTable * vt;
  struct MonoClass * klass;
  void LOOP_HEAD = <<< error >>>;

  D.18630 = MEM[(mword *)obj];
  D.18631 = D.18630 & 18446744073709551612;
  vt = (struct MonoVTable *) D.18631;
  klass = vt->klass;
  D.18632 = vt->gc_descr;
  D.18633 = (long unsigned int) D.18632;
  D.18634 = sgen_gc_descr_has_references (D.18633);
  if (D.18634 == 0) goto <D.18635>; else goto <D.18636>;
  <D.18635>:
  return;
  <D.18636>:
  D.18637 = vt->rank;
  if (D.18637 != 0) goto <D.18638>; else goto <D.18639>;
  <D.18638>:
  {
    guint8 * card_data;
    guint8 * card_base;
    guint8 * card_data_end;
    char * obj_start;
    mword obj_size;
    char * obj_end;
    size_t card_count;
    int extra_idx;
    struct MonoArray * arr;
    mword desc;
    int elem_size;
    guint8 * overflow_scan_end;

    obj_start = sgen_card_table_align_pointer (obj);
    D.18640 = sgen_par_object_get_size (vt, obj);
    obj_size = (mword) D.18640;
    obj_end = obj + obj_size;
    extra_idx = 0;
    arr = obj;
    D.18641 = klass->element_class;
    D.18642 = D.18641->gc_descr;
    desc = (mword) D.18642;
    elem_size = mono_array_element_size (klass);
    overflow_scan_end = 0B;
    if (cards != 0B) goto <D.18643>; else goto <D.18644>;
    <D.18643>:
    card_data = cards;
    goto <D.18645>;
    <D.18644>:
    obj.13 = (long unsigned int) obj;
    card_data = sgen_card_table_get_shadow_card_address (obj.13);
    <D.18645>:
    card_base = card_data;
    obj.13 = (long unsigned int) obj;
    card_count = cards_in_range (obj.13, obj_size);
    card_data_end = card_data + card_count;
    if (cards == 0B) goto <D.18647>; else goto <D.18648>;
    <D.18647>:
    sgen_shadow_cardtable.14 = sgen_shadow_cardtable;
    D.18650 = sgen_shadow_cardtable.14 + 8388608;
    if (D.18650 <= card_data_end) goto <D.18651>; else goto <D.18652>;
    <D.18651>:
    sgen_shadow_cardtable.14 = sgen_shadow_cardtable;
    card_data_end.15 = (long int) card_data_end;
    sgen_shadow_cardtable.14 = sgen_shadow_cardtable;
    D.18650 = sgen_shadow_cardtable.14 + 8388608;
    D.18654 = (long int) D.18650;
    D.18655 = card_data_end.15 - D.18654;
    D.18656 = (sizetype) D.18655;
    overflow_scan_end = sgen_shadow_cardtable.14 + D.18656;
    sgen_shadow_cardtable.14 = sgen_shadow_cardtable;
    card_data_end = sgen_shadow_cardtable.14 + 8388608;
    <D.18652>:
    <D.18648>:
    LOOP_HEAD:
    card_data = find_next_card (card_data, card_data_end);
    goto <D.18520>;
    <D.18519>:
    {
      int index;
      int idx;
      char * start;
      char * card_end;
      char * first_elem;
      char * elem;

      card_data.16 = (long int) card_data;
      card_base.17 = (long int) card_base;
      D.18659 = card_data.16 - card_base.17;
      D.18660 = (unsigned int) D.18659;
      extra_idx.18 = (unsigned int) extra_idx;
      D.18662 = D.18660 + extra_idx.18;
      idx = (int) D.18662;
      D.18663 = idx * 512;
      D.18664 = (sizetype) D.18663;
      start = obj_start + D.18664;
      card_end = start + 512;
      if (cards == 0B) goto <D.18665>; else goto <D.18666>;
      <D.18665>:
      sgen_card_table_prepare_card_for_scanning (card_data);
      <D.18666>:
      card_end = MIN_EXPR <obj_end, card_end>;
      D.18667 = &arr->vector;
      if (D.18667 >= start) goto <D.18668>; else goto <D.18669>;
      <D.18668>:
      index = 0;
      goto <D.18670>;
      <D.18669>:
      start.19 = (long int) start;
      D.18672 = obj + 32;
      D.18673 = (long int) D.18672;
      D.18674 = start.19 - D.18673;
      D.18675 = (long int) elem_size;
      D.18676 = D.18674 / D.18675;
      index = (int) D.18676;
      <D.18670>:
      D.18677 = &MEM[(struct MonoArray *)obj].vector;
      D.18678 = elem_size * index;
      D.18679 = (sizetype) D.18678;
      first_elem = D.18677 + D.18679;
      elem = first_elem;
      D.18641 = klass->element_class;
      D.18680 = BIT_FIELD_REF <*D.18641, 64, 256>;
      D.18681 = D.18680 & 8;
      if (D.18681 != 0) goto <D.18682>; else goto <D.18683>;
      <D.18682>:
      {
        void (*ScanVTypeFunc) (char *, mword, struct SgenGrayQueue *) scan_vtype_func;

        D.18684 = sgen_get_current_object_ops ();
        scan_vtype_func = D.18684->scan_vtype;
        goto <D.18511>;
        <D.18510>:
        scan_vtype_func (elem, desc, queue);
        D.18685 = (sizetype) elem_size;
        elem = elem + D.18685;
        <D.18511>:
        if (elem < card_end) goto <D.18510>; else goto <D.18512>;
        <D.18512>:
      }
      goto <D.18686>;
      <D.18683>:
      {
        void (*CopyOrMarkObjectFunc) (void * *, struct SgenGrayQueue *) copy_func;

        D.18687 = sgen_get_current_object_ops ();
        copy_func = D.18687->copy_or_mark_object;
        goto <D.18517>;
        <D.18516>:
        {
          void * new;
          void * old;

          old = MEM[(void * *)elem];
          if (mod_union != 0) goto <D.18691>; else goto <D.18688>;
          <D.18691>:
          if (old != 0B) goto <D.18689>; else goto <D.18688>;
          <D.18688>:
          D.18692 = sgen_ptr_in_nursery (old);
          D.18693 = D.18692 != 0;
          D.18694 = (long int) D.18693;
          D.18695 = __builtin_expect (D.18694, 0);
          if (D.18695 != 0) goto <D.18689>; else goto <D.18690>;
          <D.18689>:
          copy_func (elem, queue);
          new = MEM[(void * *)elem];
          D.18696 = sgen_ptr_in_nursery (new);
          D.18697 = D.18696 != 0;
          D.18698 = (long int) D.18697;
          D.18699 = __builtin_expect (D.18698, 0);
          if (D.18699 != 0) goto <D.18700>; else goto <D.18701>;
          <D.18700>:
          sgen_add_to_global_remset (elem, new);
          <D.18701>:
          <D.18690>:
        }
        elem = elem + 8;
        <D.18517>:
        if (elem < card_end) goto <D.18516>; else goto <D.18518>;
        <D.18518>:
      }
      <D.18686>:
    }
    D.18702 = card_data + 1;
    card_data = find_next_card (D.18702, card_data_end);
    <D.18520>:
    if (card_data < card_data_end) goto <D.18519>; else goto <D.18521>;
    <D.18521>:
    if (overflow_scan_end != 0B) goto <D.18703>; else goto <D.18704>;
    <D.18703>:
    card_data.16 = (long int) card_data;
    card_base.17 = (long int) card_base;
    D.18659 = card_data.16 - card_base.17;
    extra_idx = (int) D.18659;
    card_data = sgen_shadow_cardtable;
    card_base = card_data;
    card_data_end = overflow_scan_end;
    overflow_scan_end = 0B;
    goto LOOP_HEAD;
    <D.18704>:
  }
  goto <D.18705>;
  <D.18639>:
  if (cards != 0B) goto <D.18706>; else goto <D.18707>;
  <D.18706>:
  obj.13 = (long unsigned int) obj;
  D.18708 = sgen_card_table_is_range_marked (cards, obj.13, block_obj_size);
  if (D.18708 != 0) goto <D.18709>; else goto <D.18710>;
  <D.18709>:
  D.18711 = sgen_get_current_object_ops ();
  D.18712 = D.18711->scan_object;
  D.18712 (obj, queue);
  <D.18710>:
  goto <D.18713>;
  <D.18707>:
  obj.13 = (long unsigned int) obj;
  D.18714 = sgen_card_table_region_begin_scanning (obj.13, block_obj_size);
  if (D.18714 != 0) goto <D.18715>; else goto <D.18716>;
  <D.18715>:
  D.18717 = sgen_get_current_object_ops ();
  D.18718 = D.18717->scan_object;
  D.18718 (obj, queue);
  <D.18716>:
  <D.18713>:
  <D.18705>:
}


sgen_gc_descr_has_references (mword desc)
{
  long unsigned int D.18720;
  gboolean D.18723;
  long unsigned int D.18724;
  long unsigned int D.18727;

  D.18720 = desc & 4294901767;
  if (D.18720 == 1) goto <D.18721>; else goto <D.18722>;
  <D.18721>:
  D.18723 = 0;
  return D.18723;
  <D.18722>:
  D.18724 = desc & 49159;
  if (D.18724 == 4) goto <D.18725>; else goto <D.18726>;
  <D.18725>:
  D.18723 = 0;
  return D.18723;
  <D.18726>:
  D.18727 = desc & 7;
  if (D.18727 == 7) goto <D.18728>; else goto <D.18729>;
  <D.18728>:
  D.18723 = 0;
  return D.18723;
  <D.18729>:
  D.18723 = 1;
  return D.18723;
}


sgen_par_object_get_size (struct MonoVTable * vtable, struct MonoObject * o)
{
  void * D.18731;
  long unsigned int D.18732;
  guint D.18737;
  int D.18738;
  int D.18739;
  unsigned int D.18740;
  long unsigned int D.18743;
  int D.18744;
  unsigned int D.18745;
  unsigned int element_size.20;
  unsigned int D.18747;
  long unsigned int D.18748;
  long unsigned int D.18749;
  struct MonoClass * D.18752;
  unsigned char D.18753;
  long unsigned int D.18754;
  long unsigned int D.18755;
  mword descr;
  mword type;

  D.18731 = vtable->gc_descr;
  descr = (mword) D.18731;
  type = descr & 7;
  D.18732 = type + 18446744073709551615;
  if (D.18732 <= 1) goto <D.18733>; else goto <D.18734>;
  <D.18733>:
  {
    mword size;

    size = descr & 65528;
    if (size == 0) goto <D.18735>; else goto <D.18736>;
    <D.18735>:
    D.18738 = MEM[(struct MonoString *)o].length;
    D.18739 = D.18738 * 2;
    D.18740 = (unsigned int) D.18739;
    D.18737 = D.18740 + 26;
    return D.18737;
    <D.18736>:
    D.18737 = (guint) size;
    return D.18737;
  }
  <D.18734>:
  if (type == 4) goto <D.18741>; else goto <D.18742>;
  <D.18741>:
  {
    int element_size;
    struct MonoArray * array;
    size_t size;

    D.18743 = descr >> 3;
    D.18744 = (int) D.18743;
    element_size = D.18744 & 1023;
    array = o;
    D.18745 = array->max_length;
    element_size.20 = (unsigned int) element_size;
    D.18747 = D.18745 * element_size.20;
    D.18748 = (long unsigned int) D.18747;
    size = D.18748 + 32;
    D.18749 = descr & 8192;
    if (D.18749 != 0) goto <D.18750>; else goto <D.18751>;
    <D.18750>:
    size = size + 3;
    size = size & 18446744073709551612;
    D.18752 = vtable->klass;
    D.18753 = D.18752->rank;
    D.18754 = (long unsigned int) D.18753;
    D.18755 = D.18754 * 8;
    size = D.18755 + size;
    <D.18751>:
    D.18737 = (guint) size;
    return D.18737;
  }
  <D.18742>:
  D.18737 = slow_object_get_size (vtable, o);
  return D.18737;
}


slow_object_get_size (struct MonoVTable * vtable, struct MonoObject * o)
{
  struct MonoClass * D.18757;
  guint D.18760;
  int D.18761;
  int D.18762;
  unsigned int D.18763;
  unsigned char D.18764;
  int D.18767;
  unsigned int D.18768;
  unsigned int D.18769;
  unsigned int D.18770;
  long unsigned int D.18771;
  struct MonoArrayBounds * D.18772;
  _Bool D.18773;
  long int D.18774;
  long int D.18775;
  long unsigned int D.18778;
  long unsigned int D.18779;
  int D.18780;
  struct MonoClass * klass;

  klass = vtable->klass;
  D.18757 = mono_defaults.string_class;
  if (D.18757 == klass) goto <D.18758>; else goto <D.18759>;
  <D.18758>:
  D.18761 = MEM[(struct MonoString *)o].length;
  D.18762 = D.18761 * 2;
  D.18763 = (unsigned int) D.18762;
  D.18760 = D.18763 + 26;
  return D.18760;
  <D.18759>:
  D.18764 = klass->rank;
  if (D.18764 != 0) goto <D.18765>; else goto <D.18766>;
  <D.18765>:
  {
    struct MonoArray * array;
    size_t size;

    array = o;
    D.18767 = klass->sizes.element_size;
    D.18768 = (unsigned int) D.18767;
    D.18769 = array->max_length;
    D.18770 = D.18768 * D.18769;
    D.18771 = (long unsigned int) D.18770;
    size = D.18771 + 32;
    D.18772 = array->bounds;
    D.18773 = D.18772 != 0B;
    D.18774 = (long int) D.18773;
    D.18775 = __builtin_expect (D.18774, 0);
    if (D.18775 != 0) goto <D.18776>; else goto <D.18777>;
    <D.18776>:
    size = size + 3;
    size = size & 18446744073709551612;
    D.18764 = klass->rank;
    D.18778 = (long unsigned int) D.18764;
    D.18779 = D.18778 * 8;
    size = D.18779 + size;
    <D.18777>:
    D.18760 = (guint) size;
    return D.18760;
  }
  <D.18766>:
  D.18780 = klass->instance_size;
  D.18760 = (guint) D.18780;
  return D.18760;
}


sgen_card_table_prepare_card_for_scanning (guint8 * card)
{

}


sgen_ptr_in_nursery (void * p)
{
  gboolean D.18782;
  int sgen_nursery_bits.21;
  int D.18784;
  int D.18785;
  long unsigned int D.18786;
  long unsigned int p.22;
  long unsigned int D.18788;
  char * sgen_nursery_start.23;
  long unsigned int sgen_nursery_start.24;
  _Bool D.18791;

  sgen_nursery_bits.21 = sgen_nursery_bits;
  D.18784 = 1 << sgen_nursery_bits.21;
  D.18785 = -D.18784;
  D.18786 = (long unsigned int) D.18785;
  p.22 = (long unsigned int) p;
  D.18788 = D.18786 & p.22;
  sgen_nursery_start.23 = sgen_nursery_start;
  sgen_nursery_start.24 = (long unsigned int) sgen_nursery_start.23;
  D.18791 = D.18788 == sgen_nursery_start.24;
  D.18782 = (gboolean) D.18791;
  return D.18782;
}


find_next_card (guint8 * card_data, guint8 * end)
{
  unsigned char D.18793;
  guint8 * D.18796;
  long unsigned int card_data.25;
  long unsigned int D.18798;
  long unsigned int end.26;
  long unsigned int D.18803;
  int D.18806;
  sizetype D.18807;
  mword * cards;
  mword * cards_end;
  mword card;

  goto <D.18473>;
  <D.18472>:
  D.18793 = *card_data;
  if (D.18793 != 0) goto <D.18794>; else goto <D.18795>;
  <D.18794>:
  D.18796 = card_data;
  return D.18796;
  <D.18795>:
  card_data = card_data + 1;
  <D.18473>:
  card_data.25 = (long unsigned int) card_data;
  D.18798 = card_data.25 & 7;
  if (D.18798 != 0) goto <D.18799>; else goto <D.18474>;
  <D.18799>:
  if (card_data < end) goto <D.18472>; else goto <D.18474>;
  <D.18474>:
  if (card_data == end) goto <D.18800>; else goto <D.18801>;
  <D.18800>:
  D.18796 = end;
  return D.18796;
  <D.18801>:
  cards = card_data;
  end.26 = (long unsigned int) end;
  D.18803 = end.26 & 18446744073709551608;
  cards_end = (mword *) D.18803;
  goto <D.18476>;
  <D.18475>:
  card = *cards;
  if (card != 0) goto <D.18804>; else goto <D.18805>;
  <D.18804>:
  D.18806 = find_card_offset (card);
  D.18807 = (sizetype) D.18806;
  D.18796 = cards + D.18807;
  return D.18796;
  <D.18805>:
  cards = cards + 8;
  <D.18476>:
  if (cards < cards_end) goto <D.18475>; else goto <D.18477>;
  <D.18477>:
  card_data = cards_end;
  goto <D.18479>;
  <D.18478>:
  D.18793 = *card_data;
  if (D.18793 != 0) goto <D.18808>; else goto <D.18809>;
  <D.18808>:
  D.18796 = card_data;
  return D.18796;
  <D.18809>:
  card_data = card_data + 1;
  <D.18479>:
  if (card_data < end) goto <D.18478>; else goto <D.18480>;
  <D.18480>:
  D.18796 = end;
  return D.18796;
}


find_card_offset (mword card)
{
  sizetype D.18811;
  guint8 * D.18812;
  unsigned char D.18813;
  int D.18816;
  unsigned int i.27;
  int i;
  guint8 * ptr;

  ptr = &card;
  i = 0;
  goto <D.18463>;
  <D.18462>:
  D.18811 = (sizetype) i;
  D.18812 = ptr + D.18811;
  D.18813 = *D.18812;
  if (D.18813 != 0) goto <D.18814>; else goto <D.18815>;
  <D.18814>:
  D.18816 = i;
  return D.18816;
  <D.18815>:
  i = i + 1;
  <D.18463>:
  i.27 = (unsigned int) i;
  if (i.27 <= 7) goto <D.18462>; else goto <D.18464>;
  <D.18464>:
  D.18816 = 0;
  return D.18816;
}


sgen_card_table_is_range_marked (guint8 * cards, mword address, mword size)
{
  long unsigned int D.18819;
  guint8 * cards.28;
  unsigned char D.18821;
  gboolean D.18824;
  guint8 * end;

  D.18819 = cards_in_range (address, size);
  end = cards + D.18819;
  goto <D.18380>;
  <D.18379>:
  cards.28 = cards;
  cards = cards.28 + 1;
  D.18821 = *cards.28;
  if (D.18821 != 0) goto <D.18822>; else goto <D.18823>;
  <D.18822>:
  D.18824 = 1;
  return D.18824;
  <D.18823>:
  <D.18380>:
  if (cards != end) goto <D.18379>; else goto <D.18381>;
  <D.18381>:
  D.18824 = 0;
  return D.18824;
}


sgen_card_table_region_begin_scanning (mword start, mword end)
{
  int D.18826;
  gboolean D.18829;

  goto <D.18351>;
  <D.18350>:
  D.18826 = sgen_card_table_card_begin_scanning (start);
  if (D.18826 != 0) goto <D.18827>; else goto <D.18828>;
  <D.18827>:
  D.18829 = 1;
  return D.18829;
  <D.18828>:
  start = start + 512;
  <D.18351>:
  if (start <= end) goto <D.18350>; else goto <D.18352>;
  <D.18352>:
  D.18829 = 0;
  return D.18829;
}


sgen_card_table_card_begin_scanning (mword address)
{
  gboolean D.18831;
  guint8 * D.18832;
  unsigned char D.18833;
  _Bool D.18834;

  D.18832 = sgen_card_table_get_shadow_card_address (address);
  D.18833 = *D.18832;
  D.18834 = D.18833 != 0;
  D.18831 = (gboolean) D.18834;
  return D.18831;
}


sgen_card_table_init (struct SgenRemeberedSet * remset)
{
  void * sgen_cardtable.29;
  void * sgen_shadow_cardtable.30;
  struct SgenMajorCollector * D.18838;
  int need_mod_union.31;

  sgen_cardtable.29 = sgen_alloc_os_memory (8388608, 2, "card table");
  sgen_cardtable = sgen_cardtable.29;
  sgen_shadow_cardtable.30 = sgen_alloc_os_memory (8388608, 2, "shadow card table");
  sgen_shadow_cardtable = sgen_shadow_cardtable.30;
  mono_counters_register ("cardtable major scan time", 519, &major_card_scan_time);
  mono_counters_register ("cardtable los scan time", 519, &los_card_scan_time);
  remset->wbarrier_set_field = sgen_card_table_wbarrier_set_field;
  remset->wbarrier_set_arrayref = sgen_card_table_wbarrier_set_arrayref;
  remset->wbarrier_arrayref_copy = sgen_card_table_wbarrier_arrayref_copy;
  remset->wbarrier_value_copy = sgen_card_table_wbarrier_value_copy;
  remset->wbarrier_object_copy = sgen_card_table_wbarrier_object_copy;
  remset->wbarrier_generic_nostore = sgen_card_table_wbarrier_generic_nostore;
  remset->record_pointer = sgen_card_table_record_pointer;
  remset->finish_scan_remsets = sgen_card_table_finish_scan_remsets;
  remset->finish_minor_collection = sgen_card_table_finish_minor_collection;
  remset->prepare_for_major_collection = sgen_card_table_prepare_for_major_collection;
  remset->find_address = sgen_card_table_find_address;
  remset->find_address_with_cards = sgen_card_table_find_address_with_cards;
  D.18838 = sgen_get_major_collector ();
  need_mod_union.31 = D.18838->is_concurrent;
  need_mod_union = need_mod_union.31;
}


sgen_card_table_find_address_with_cards (char * cards_start, guint8 * cards, char * addr)
{
  gboolean D.18840;
  long int addr.32;
  long int cards_start.33;
  long int D.18843;
  long int D.18844;
  sizetype D.18845;
  guint8 * D.18846;
  unsigned char D.18847;

  cards_start = sgen_card_table_align_pointer (cards_start);
  addr.32 = (long int) addr;
  cards_start.33 = (long int) cards_start;
  D.18843 = addr.32 - cards_start.33;
  D.18844 = D.18843 >> 9;
  D.18845 = (sizetype) D.18844;
  D.18846 = cards + D.18845;
  D.18847 = *D.18846;
  D.18840 = (gboolean) D.18847;
  return D.18840;
}


sgen_card_table_find_address (char * addr)
{
  gboolean D.18849;
  long unsigned int addr.34;

  addr.34 = (long unsigned int) addr;
  D.18849 = sgen_card_table_address_is_marked (addr.34);
  return D.18849;
}


sgen_card_table_address_is_marked (mword address)
{
  gboolean D.18852;
  guint8 * D.18853;
  unsigned char D.18854;
  _Bool D.18855;

  D.18853 = sgen_card_table_get_card_address (address);
  D.18854 = *D.18853;
  D.18855 = D.18854 != 0;
  D.18852 = (gboolean) D.18855;
  return D.18852;
}


sgen_card_table_prepare_for_major_collection ()
{
  sgen_major_collector_iterate_live_block_ranges (clear_cards);
  sgen_los_iterate_live_block_ranges (clear_cards);
}


clear_cards (mword start, mword size)
{
  guint8 * D.18857;
  guint8 * sgen_cardtable.35;
  guint8 * D.18859;
  long int D.18862;
  long int addr.36;
  long int D.18864;
  long unsigned int D.18865;
  guint8 * addr;
  size_t bytes;

  addr = sgen_card_table_get_card_address (start);
  bytes = cards_in_range (start, size);
  D.18857 = addr + bytes;
  sgen_cardtable.35 = sgen_cardtable;
  D.18859 = sgen_cardtable.35 + 8388608;
  if (D.18857 > D.18859) goto <D.18860>; else goto <D.18861>;
  <D.18860>:
  {
    size_t first_chunk;

    sgen_cardtable.35 = sgen_cardtable;
    D.18859 = sgen_cardtable.35 + 8388608;
    D.18862 = (long int) D.18859;
    addr.36 = (long int) addr;
    D.18864 = D.18862 - addr.36;
    first_chunk = (size_t) D.18864;
    memset (addr, 0, first_chunk);
    sgen_cardtable.35 = sgen_cardtable;
    D.18865 = bytes - first_chunk;
    memset (sgen_cardtable.35, 0, D.18865);
  }
  goto <D.18866>;
  <D.18861>:
  memset (addr, 0, bytes);
  <D.18866>:
}


sgen_card_table_finish_minor_collection ()
{
  sgen_card_tables_collect_stats (0);
}


sgen_card_tables_collect_stats (gboolean begin)
{

}


sgen_card_table_finish_scan_remsets (void * start_nursery, void * end_nursery, struct SgenGrayQueue * queue)
{
  long int D.18867;
  long int D.18868;
  int D.18869;
  long long int last_major_scan_time.37;
  long long int major_card_scan_time.38;
  long long int last_major_scan_time.39;
  long long int major_card_scan_time.40;
  long int D.18874;
  long int D.18875;
  int D.18876;
  long long int last_los_scan_time.41;
  long long int los_card_scan_time.42;
  long long int last_los_scan_time.43;
  long long int los_card_scan_time.44;
  gint64 atv;
  gint64 btv;

  sgen_card_tables_collect_stats (1);
  sgen_major_collector_iterate_live_block_ranges (move_cards_to_shadow_table);
  sgen_los_iterate_live_block_ranges (move_cards_to_shadow_table);
  sgen_card_table_prepare_for_major_collection ();
  atv = mono_100ns_ticks ();
  sgen_major_collector_scan_card_table (queue);
  btv = mono_100ns_ticks ();
  D.18867 = btv - atv;
  D.18868 = D.18867 / 10;
  D.18869 = (int) D.18868;
  last_major_scan_time.37 = (long long int) D.18869;
  last_major_scan_time = last_major_scan_time.37;
  major_card_scan_time.38 = major_card_scan_time;
  last_major_scan_time.39 = last_major_scan_time;
  major_card_scan_time.40 = major_card_scan_time.38 + last_major_scan_time.39;
  major_card_scan_time = major_card_scan_time.40;
  sgen_los_scan_card_table (0, queue);
  atv = mono_100ns_ticks ();
  D.18874 = atv - btv;
  D.18875 = D.18874 / 10;
  D.18876 = (int) D.18875;
  last_los_scan_time.41 = (long long int) D.18876;
  last_los_scan_time = last_los_scan_time.41;
  los_card_scan_time.42 = los_card_scan_time;
  last_los_scan_time.43 = last_los_scan_time;
  los_card_scan_time.44 = los_card_scan_time.42 + last_los_scan_time.43;
  los_card_scan_time = los_card_scan_time.44;
}


move_cards_to_shadow_table (mword start, mword size)
{
  guint8 * D.18881;
  guint8 * sgen_shadow_cardtable.45;
  guint8 * D.18883;
  long int D.18886;
  long int to.46;
  long int D.18888;
  long unsigned int D.18889;
  guint8 * sgen_cardtable.47;
  guint8 * from;
  guint8 * to;
  size_t bytes;

  from = sgen_card_table_get_card_address (start);
  to = sgen_card_table_get_shadow_card_address (start);
  bytes = cards_in_range (start, size);
  D.18881 = to + bytes;
  sgen_shadow_cardtable.45 = sgen_shadow_cardtable;
  D.18883 = sgen_shadow_cardtable.45 + 8388608;
  if (D.18881 > D.18883) goto <D.18884>; else goto <D.18885>;
  <D.18884>:
  {
    size_t first_chunk;
    size_t second_chunk;

    sgen_shadow_cardtable.45 = sgen_shadow_cardtable;
    D.18883 = sgen_shadow_cardtable.45 + 8388608;
    D.18886 = (long int) D.18883;
    to.46 = (long int) to;
    D.18888 = D.18886 - to.46;
    first_chunk = (size_t) D.18888;
    D.18889 = MIN_EXPR <bytes, 8388608>;
    second_chunk = D.18889 - first_chunk;
    memcpy (to, from, first_chunk);
    sgen_shadow_cardtable.45 = sgen_shadow_cardtable;
    sgen_cardtable.47 = sgen_cardtable;
    memcpy (sgen_shadow_cardtable.45, sgen_cardtable.47, second_chunk);
  }
  goto <D.18891>;
  <D.18885>:
  memcpy (to, from, bytes);
  <D.18891>:
}


sgen_card_table_record_pointer (void * address)
{
  long unsigned int address.48;
  guint8 * D.18893;

  address.48 = (long unsigned int) address;
  D.18893 = sgen_card_table_get_card_address (address.48);
  *D.18893 = 1;
}


sgen_card_table_wbarrier_generic_nostore (void * ptr)
{
  long unsigned int ptr.49;

  ptr.49 = (long unsigned int) ptr;
  sgen_card_table_mark_address (ptr.49);
}


sgen_card_table_mark_address (mword address)
{
  guint8 * D.18895;

  D.18895 = sgen_card_table_get_card_address (address);
  *D.18895 = 1;
}


sgen_card_table_wbarrier_object_copy (struct MonoObject * obj, struct MonoObject * src)
{
  struct MonoVTable * D.18896;
  struct MonoClass * D.18897;
  struct SgenThreadInfo * sgen_thread_info.50;
  void * D.18899;
  const void * D.18900;
  long unsigned int D.18901;
  long unsigned int D.18902;
  long unsigned int obj.51;
  long unsigned int D.18904;
  int size;

  D.18896 = obj->vtable;
  D.18897 = D.18896->klass;
  size = D.18897->instance_size;
  sgen_thread_info.50 = sgen_thread_info;
  sgen_thread_info.50->in_critical_region = 1;
  mono_memory_barrier ();
  D.18899 = obj + 16;
  D.18900 = src + 16;
  D.18901 = (long unsigned int) size;
  D.18902 = D.18901 + 18446744073709551600;
  mono_gc_memmove_aligned (D.18899, D.18900, D.18902);
  obj.51 = (long unsigned int) obj;
  D.18904 = (long unsigned int) size;
  sgen_card_table_mark_range (obj.51, D.18904);
  mono_memory_barrier ();
  sgen_thread_info.50 = sgen_thread_info;
  sgen_thread_info.50->in_critical_region = 0;
}


mono_memory_barrier ()
{
  __sync_synchronize ();
}


sgen_card_table_wbarrier_value_copy (void * dest, void * src, int count, struct MonoClass * klass)
{
  int D.18905;
  long unsigned int D.18906;
  struct SgenThreadInfo * sgen_thread_info.52;
  long unsigned int dest.53;
  size_t element_size;
  size_t size;

  D.18905 = mono_class_value_size (klass, 0B);
  element_size = (size_t) D.18905;
  D.18906 = (long unsigned int) count;
  size = D.18906 * element_size;
  sgen_thread_info.52 = sgen_thread_info;
  sgen_thread_info.52->in_critical_region = 1;
  mono_memory_barrier ();
  mono_gc_memmove_atomic (dest, src, size);
  dest.53 = (long unsigned int) dest;
  sgen_card_table_mark_range (dest.53, size);
  mono_memory_barrier ();
  sgen_thread_info.52 = sgen_thread_info;
  sgen_thread_info.52->in_critical_region = 0;
}


sgen_card_table_wbarrier_arrayref_copy (void * dest_ptr, void * src_ptr, int count)
{
  long unsigned int D.18912;
  long unsigned int D.18913;
  void * * D.18914;
  sizetype D.18916;
  int need_mod_union.54;
  int D.18921;
  long unsigned int dest.55;
  int D.18926;
  void * * dest;
  void * * src;

  dest = dest_ptr;
  src = src_ptr;
  if (src < dest) goto <D.18911>; else goto <D.18909>;
  <D.18911>:
  D.18912 = (long unsigned int) count;
  D.18913 = D.18912 * 8;
  D.18914 = src + D.18913;
  if (D.18914 > dest) goto <D.18915>; else goto <D.18909>;
  <D.18915>:
  {
    void * * start;

    start = dest;
    D.18912 = (long unsigned int) count;
    D.18913 = D.18912 * 8;
    D.18916 = D.18913 + 18446744073709551608;
    dest = dest + D.18916;
    D.18912 = (long unsigned int) count;
    D.18913 = D.18912 * 8;
    D.18916 = D.18913 + 18446744073709551608;
    src = src + D.18916;
    goto <D.18322>;
    <D.18321>:
    {
      void * value;

      value = *src;
      *dest = value;
      need_mod_union.54 = need_mod_union;
      if (need_mod_union.54 != 0) goto <D.18917>; else goto <D.18920>;
      <D.18920>:
      D.18921 = sgen_ptr_in_nursery (value);
      if (D.18921 != 0) goto <D.18917>; else goto <D.18918>;
      <D.18917>:
      dest.55 = (long unsigned int) dest;
      sgen_card_table_mark_address (dest.55);
      <D.18918>:
      sgen_dummy_use (value);
    }
    src = src + 18446744073709551608;
    dest = dest + 18446744073709551608;
    <D.18322>:
    if (dest >= start) goto <D.18321>; else goto <D.18323>;
    <D.18323>:
  }
  goto <D.18910>;
  <D.18909>:
  {
    void * * end;

    D.18912 = (long unsigned int) count;
    D.18913 = D.18912 * 8;
    end = dest + D.18913;
    goto <D.18327>;
    <D.18326>:
    {
      void * value;

      value = *src;
      *dest = value;
      need_mod_union.54 = need_mod_union;
      if (need_mod_union.54 != 0) goto <D.18923>; else goto <D.18925>;
      <D.18925>:
      D.18926 = sgen_ptr_in_nursery (value);
      if (D.18926 != 0) goto <D.18923>; else goto <D.18924>;
      <D.18923>:
      dest.55 = (long unsigned int) dest;
      sgen_card_table_mark_address (dest.55);
      <D.18924>:
      sgen_dummy_use (value);
    }
    src = src + 8;
    dest = dest + 8;
    <D.18327>:
    if (dest < end) goto <D.18326>; else goto <D.18328>;
    <D.18328>:
  }
  <D.18910>:
}


sgen_dummy_use (void * v)
{
  __asm__ __volatile__("" : "=r" v : "r" v);
}


sgen_card_table_wbarrier_set_arrayref (struct MonoArray * arr, void * slot_ptr, struct MonoObject * value)
{
  int need_mod_union.56;
  int D.18931;
  long unsigned int slot_ptr.57;

  MEM[(void * *)slot_ptr] = value;
  need_mod_union.56 = need_mod_union;
  if (need_mod_union.56 != 0) goto <D.18927>; else goto <D.18930>;
  <D.18930>:
  D.18931 = sgen_ptr_in_nursery (value);
  if (D.18931 != 0) goto <D.18927>; else goto <D.18928>;
  <D.18927>:
  slot_ptr.57 = (long unsigned int) slot_ptr;
  sgen_card_table_mark_address (slot_ptr.57);
  <D.18928>:
  sgen_dummy_use (value);
}


sgen_card_table_wbarrier_set_field (struct MonoObject * obj, void * field_ptr, struct MonoObject * value)
{
  int need_mod_union.58;
  int D.18937;
  long unsigned int field_ptr.59;

  MEM[(void * *)field_ptr] = value;
  need_mod_union.58 = need_mod_union;
  if (need_mod_union.58 != 0) goto <D.18933>; else goto <D.18936>;
  <D.18936>:
  D.18937 = sgen_ptr_in_nursery (value);
  if (D.18937 != 0) goto <D.18933>; else goto <D.18934>;
  <D.18933>:
  field_ptr.59 = (long unsigned int) field_ptr;
  sgen_card_table_mark_address (field_ptr.59);
  <D.18934>:
  sgen_dummy_use (value);
}


