m3-sys/m3cc/gcc-apple/gcc/varasm.c
/* Given a constant rtx X, make (or find) a memory constant for its value
   and return a MEM rtx to refer to it in memory.  */
Given a constant rtx X, make (or find) a memory constant for its value
and return a MEM rtx to refer to it in memory.
Given a constant rtx X make ( or find ) a memory constant for its value and return a MEM rtx to refer to it in memory .
rtx
force_const_mem (enum machine_mode mode, rtx x)
{
  struct constant_descriptor_rtx *desc, tmp;
  struct rtx_constant_pool *pool;
  char label[256];
  rtx def, symbol;
  hashval_t hash;
  unsigned int align;
  void **slot;
  if (targetm.cannot_force_const_mem (x))
    return NULL_RTX;
  current_function_uses_const_pool = 1;
  pool = (targetm.use_blocks_for_constant_p (mode, x)
	  ? shared_constant_pool
	  : cfun->varasm->pool);
  tmp.constant = x;
  tmp.mode = mode;
  hash = const_rtx_hash (x);
  slot = htab_find_slot_with_hash (pool->const_rtx_htab, &tmp, hash, INSERT);
  desc = *slot;
  if (desc)
    return copy_rtx (desc->mem);
  desc = ggc_alloc (sizeof (*desc));
  *slot = desc;
  align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode);
#ifdef CONSTANT_ALIGNMENT
  {
    tree type = lang_hooks.types.type_for_mode (mode, 0);
    if (type != NULL_TREE)
      align = CONSTANT_ALIGNMENT (make_tree (type, x), align);
  }
#endif
  pool->offset += (align / BITS_PER_UNIT) - 1;
  pool->offset &= ~ ((align / BITS_PER_UNIT) - 1);
  desc->next = NULL;
  desc->constant = tmp.constant;
  desc->offset = pool->offset;
  desc->hash = hash;
  desc->mode = mode;
  desc->align = align;
  desc->labelno = const_labelno;
  desc->mark = 0;
  pool->offset += GET_MODE_SIZE (mode);
  if (pool->last)
    pool->last->next = desc;
  else
    pool->first = pool->last = desc;
  pool->last = desc;
  ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
  ++const_labelno;
  if (use_object_blocks_p () && targetm.use_blocks_for_constant_p (mode, x))
    {
      section *sect = targetm.asm_out.select_rtx_section (mode, x, align);
      symbol = create_block_symbol (ggc_strdup (label),
				    get_block_for_section (sect), -1);
    }
  else
    symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
  desc->sym = symbol;
  SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL;
  CONSTANT_POOL_ADDRESS_P (symbol) = 1;
  SET_SYMBOL_REF_CONSTANT (symbol, desc);
  desc->mem = def = gen_const_mem (mode, symbol);
  set_mem_attributes (def, lang_hooks.types.type_for_mode (mode, 0), 1);
  set_mem_align (def, align);
  if (GET_CODE (x) == LABEL_REF)
    LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
  return copy_rtx (def);
}
rtx force_const_mem ( enum machine_mode mode , rtx x ) { struct constant_descriptor_rtx * desc , tmp ; struct rtx_constant_pool * pool ; char label [ 256 ] ; rtx def , symbol ; hashval_t hash ; unsigned int align ; void * * slot ; if ( targetm . cannot_force_const_mem ( x ) ) return NULL_RTX ; current_function_uses_const_pool = 1 ; pool = ( targetm . use_blocks_for_constant_p ( mode , x ) ? shared_constant_pool : cfun -> varasm -> pool ) ; tmp . constant = x ; tmp . mode = mode ; hash = const_rtx_hash ( x ) ; slot = htab_find_slot_with_hash ( pool -> const_rtx_htab , & tmp , hash , INSERT ) ; desc = * slot ; if ( desc ) return copy_rtx ( desc -> mem ) ; desc = ggc_alloc ( sizeof ( * desc ) ) ; * slot = desc ; align = GET_MODE_ALIGNMENT ( mode == VOIDmode ? word_mode : mode ) ; #ifdef CONSTANT_ALIGNMENT { tree type = lang_hooks . types . type_for_mode ( mode , 0 ) ; if ( type != NULL_TREE ) align = CONSTANT_ALIGNMENT ( make_tree ( type , x ) , align ) ; } #endif pool -> offset += ( align / BITS_PER_UNIT ) - 1 ; pool -> offset &= ~ ( ( align / BITS_PER_UNIT ) - 1 ) ; desc -> next = NULL ; desc -> constant = tmp . constant ; desc -> offset = pool -> offset ; desc -> hash = hash ; desc -> mode = mode ; desc -> align = align ; desc -> labelno = const_labelno ; desc -> mark = 0 ; pool -> offset += GET_MODE_SIZE ( mode ) ; if ( pool -> last ) pool -> last -> next = desc ; else pool -> first = pool -> last = desc ; pool -> last = desc ; ASM_GENERATE_INTERNAL_LABEL ( label , " " , const_labelno ) ; ++ const_labelno ; if ( use_object_blocks_p ( ) && targetm . use_blocks_for_constant_p ( mode , x ) ) { section * sect = targetm . asm_out . select_rtx_section ( mode , x , align ) ; symbol = create_block_symbol ( ggc_strdup ( label ) , get_block_for_section ( sect ) , -1 ) ; } else symbol = gen_rtx_SYMBOL_REF ( Pmode , ggc_strdup ( label ) ) ; desc -> sym = symbol ; SYMBOL_REF_FLAGS ( symbol ) |= SYMBOL_FLAG_LOCAL ; CONSTANT_POOL_ADDRESS_P ( symbol ) = 1 ; SET_SYMBOL_REF_CONSTANT ( symbol , desc ) ; desc -> mem = def = gen_const_mem ( mode , symbol ) ; set_mem_attributes ( def , lang_hooks . types . type_for_mode ( mode , 0 ) , 1 ) ; set_mem_align ( def , align ) ; if ( GET_CODE ( x ) == LABEL_REF ) LABEL_PRESERVE_P ( XEXP ( x , 0 ) ) = 1 ; return copy_rtx ( def ) ; }
Given a constant rtx X, make (or find) a memory constant for its value
and return a MEM rtx to refer to it in memory.
Given a constant rtx X make ( or find ) a memory constant for its value and return a MEM rtx to refer to it in memory .
/* If we're not allowed to drop X into the constant pool, don't.  */ /* Record that this function has used a constant pool entry.  */ /* Decide which pool to use.  */ /* Lookup the value in the hashtable.  */ /* If the constant was already present, return its memory.  */ /* Otherwise, create a new descriptor.  */ /* Align the location counter as required by EXP's data type.  */ /* Create a string containing the label name, in LABEL.  */ /* Construct the SYMBOL_REF.  Make sure to mark it as belonging to
     the constants pool.  */ /* Construct the MEM.  */ /* If we're dropping a label to the constant pool, make sure we
     don't delete it.  */