/* Dwarf2 assembler output helper routines.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of GCC.
if (op)
{
fputs (op, asm_out_file);
- if (GET_CODE (x) == CONST_INT)
+ if (CONST_INT_P (x))
fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX,
(unsigned HOST_WIDE_INT) INTVAL (x));
else
}
-/* Output an immediate constant in a given size. */
+/* Output a value of a given size in target byte order. */
+
+void
+dw2_asm_output_data_raw (int size, unsigned HOST_WIDE_INT value)
+{
+ unsigned char bytes[8];
+ int i;
+
+ for (i = 0; i < 8; ++i)
+ {
+ bytes[i] = value & 0xff;
+ value >>= 8;
+ }
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ for (i = size - 1; i > 0; --i)
+ fprintf (asm_out_file, "0x%x,", bytes[i]);
+ fprintf (asm_out_file, "0x%x", bytes[0]);
+ }
+ else
+ {
+ for (i = 0; i < size - 1; ++i)
+ fprintf (asm_out_file, "0x%x,", bytes[i]);
+ fprintf (asm_out_file, "0x%x", bytes[i]);
+ }
+}
+
+/* Output an immediate constant in a given SIZE in bytes. */
void
dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
If COMMENT is not NULL and comments in the debug information
have been requested by the user, append the given COMMENT
to the generated output. */
-
+
void
dw2_asm_output_nstring (const char *str, size_t orig_len,
const char *comment, ...)
S(DW_EH_PE_sdata4 | DW_EH_PE_funcrel, "funcrel sdata4")
S(DW_EH_PE_sdata8 | DW_EH_PE_funcrel, "funcrel sdata8")
+ S(DW_EH_PE_indirect | DW_EH_PE_absptr, "indirect absolute")
+
S(DW_EH_PE_indirect | DW_EH_PE_absptr | DW_EH_PE_pcrel,
"indirect pcrel")
S(DW_EH_PE_indirect | DW_EH_PE_uleb128 | DW_EH_PE_pcrel,
};
gcc_assert (format >= 0 && format < 0x100 && format_names[format]);
-
+
return format_names[format];
#else
}
#endif
}
+/* Output an unsigned LEB128 quantity, but only the byte values. */
+
+void
+dw2_asm_output_data_uleb128_raw (unsigned HOST_WIDE_INT value)
+{
+ while (1)
+ {
+ int byte = (value & 0x7f);
+ value >>= 7;
+ if (value != 0)
+ /* More bytes to follow. */
+ byte |= 0x80;
+
+ fprintf (asm_out_file, "0x%x", byte);
+ if (value == 0)
+ break;
+ fputc (',', asm_out_file);
+ }
+}
+
/* Output an unsigned LEB128 quantity. */
void
va_end (ap);
}
+/* Output an signed LEB128 quantity, but only the byte values. */
+
+void
+dw2_asm_output_data_sleb128_raw (HOST_WIDE_INT value)
+{
+ int byte, more;
+
+ while (1)
+ {
+ byte = (value & 0x7f);
+ value >>= 7;
+ more = !((value == 0 && (byte & 0x40) == 0)
+ || (value == -1 && (byte & 0x40) != 0));
+ if (more)
+ byte |= 0x80;
+
+ fprintf (asm_out_file, "0x%x", byte);
+ if (!more)
+ break;
+ fputc (',', asm_out_file);
+ }
+}
+
/* Output a signed LEB128 quantity. */
void
}
#endif /* 0 */
\f
-static rtx dw2_force_const_mem (rtx, bool);
static int dw2_output_indirect_constant_1 (splay_tree_node, void *);
static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool;
/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
memory. Differs from force_const_mem in that a single pool is used for
the entire unit of translation, and the memory is not guaranteed to be
- "near" the function in any interesting sense. PUBLIC controls whether
+ "near" the function in any interesting sense. IS_PUBLIC controls whether
the symbol can be shared across the entire application (or DSO). */
-static rtx
-dw2_force_const_mem (rtx x, bool public)
+rtx
+dw2_force_const_mem (rtx x, bool is_public)
{
splay_tree_node node;
- const char *str;
- tree decl;
+ const char *key;
+ tree decl_id;
if (! indirect_pool)
/* We use strcmp, rather than just comparing pointers, so that the
gcc_assert (GET_CODE (x) == SYMBOL_REF);
- str = targetm.strip_name_encoding (XSTR (x, 0));
- node = splay_tree_lookup (indirect_pool, (splay_tree_key) str);
+ key = XSTR (x, 0);
+ node = splay_tree_lookup (indirect_pool, (splay_tree_key) key);
if (node)
- decl = (tree) node->value;
+ decl_id = (tree) node->value;
else
{
tree id;
+ const char *str = targetm.strip_name_encoding (key);
- if (public && USE_LINKONCE_INDIRECT)
+ if (is_public && USE_LINKONCE_INDIRECT)
{
- char *ref_name = alloca (strlen (str) + sizeof "DW.ref.");
+ char *ref_name = XALLOCAVEC (char, strlen (str) + sizeof "DW.ref.");
sprintf (ref_name, "DW.ref.%s", str);
- id = get_identifier (ref_name);
- decl = build_decl (VAR_DECL, id, ptr_type_node);
- DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
- TREE_PUBLIC (decl) = 1;
- DECL_INITIAL (decl) = decl;
- make_decl_one_only (decl);
+ gcc_assert (!maybe_get_identifier (ref_name));
+ decl_id = get_identifier (ref_name);
+ TREE_PUBLIC (decl_id) = 1;
}
else
{
ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
++dw2_const_labelno;
- id = get_identifier (label);
- decl = build_decl (VAR_DECL, id, ptr_type_node);
- DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
- TREE_STATIC (decl) = 1;
- DECL_INITIAL (decl) = decl;
+ gcc_assert (!maybe_get_identifier (label));
+ decl_id = get_identifier (label);
}
id = maybe_get_identifier (str);
if (id)
TREE_SYMBOL_REFERENCED (id) = 1;
- splay_tree_insert (indirect_pool, (splay_tree_key) str,
- (splay_tree_value) decl);
+ splay_tree_insert (indirect_pool, (splay_tree_key) key,
+ (splay_tree_value) decl_id);
}
- return XEXP (DECL_RTL (decl), 0);
+ return gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (decl_id));
}
/* A helper function for dw2_output_indirect_constants called through
{
const char *sym;
rtx sym_ref;
- tree decl;
+ tree id, decl;
sym = (const char *) node->key;
- decl = (tree) node->value;
+ id = (tree) node->value;
+
+ decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node);
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ DECL_INITIAL (decl) = decl;
+
+ if (TREE_PUBLIC (id))
+ {
+ TREE_PUBLIC (decl) = 1;
+ make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
+ }
+ else
+ TREE_STATIC (decl) = 1;
+
sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
+ sym = targetm.strip_name_encoding (sym);
if (TREE_PUBLIC (decl) && USE_LINKONCE_INDIRECT)
fprintf (asm_out_file, "\t.hidden %sDW.ref.%s\n", user_label_prefix, sym);
assemble_variable (decl, 1, 1, 1);
reference is shared across the entire application (or DSO). */
void
-dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool public,
+dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr, bool is_public,
const char *comment, ...)
{
int size;
the constant pool for this function. Moreover, we'd like to
share these constants across the entire unit of translation and
even, if possible, across the entire application (or DSO). */
- addr = dw2_force_const_mem (addr, public);
+ addr = dw2_force_const_mem (addr, is_public);
encoding &= ~DW_EH_PE_indirect;
goto restart;
}