| 1 |
282 |
jeremybenn |
/* Definitions of target machine for GNU compiler,
|
| 2 |
|
|
for some generic XCOFF file format
|
| 3 |
|
|
Copyright (C) 2001, 2002, 2003, 2004, 2007, 2008
|
| 4 |
|
|
Free Software Foundation, Inc.
|
| 5 |
|
|
|
| 6 |
|
|
This file is part of GCC.
|
| 7 |
|
|
|
| 8 |
|
|
GCC is free software; you can redistribute it and/or modify it
|
| 9 |
|
|
under the terms of the GNU General Public License as published
|
| 10 |
|
|
by the Free Software Foundation; either version 3, or (at your
|
| 11 |
|
|
option) any later version.
|
| 12 |
|
|
|
| 13 |
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT
|
| 14 |
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
| 15 |
|
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
| 16 |
|
|
License for more details.
|
| 17 |
|
|
|
| 18 |
|
|
You should have received a copy of the GNU General Public License
|
| 19 |
|
|
along with GCC; see the file COPYING3. If not see
|
| 20 |
|
|
<http://www.gnu.org/licenses/>. */
|
| 21 |
|
|
|
| 22 |
|
|
#define TARGET_OBJECT_FORMAT OBJECT_XCOFF
|
| 23 |
|
|
|
| 24 |
|
|
/* The RS/6000 uses the XCOFF format. */
|
| 25 |
|
|
#define XCOFF_DEBUGGING_INFO 1
|
| 26 |
|
|
|
| 27 |
|
|
/* Define if the object format being used is COFF or a superset. */
|
| 28 |
|
|
#define OBJECT_FORMAT_COFF
|
| 29 |
|
|
|
| 30 |
|
|
/* Define the magic numbers that we recognize as COFF.
|
| 31 |
|
|
|
| 32 |
|
|
AIX 4.3 adds U803XTOCMAGIC (0757) for 64-bit objects and AIX V5 adds
|
| 33 |
|
|
U64_TOCMAGIC (0767), but collect2.c does not include files in the
|
| 34 |
|
|
correct order to conditionally define the symbolic name in this macro.
|
| 35 |
|
|
|
| 36 |
|
|
The AIX linker accepts import/export files as object files,
|
| 37 |
|
|
so accept "#!" (0x2321) magic number. */
|
| 38 |
|
|
#define MY_ISCOFF(magic) \
|
| 39 |
|
|
((magic) == U802WRMAGIC || (magic) == U802ROMAGIC \
|
| 40 |
|
|
|| (magic) == U802TOCMAGIC || (magic) == 0757 || (magic) == 0767 \
|
| 41 |
|
|
|| (magic) == 0x2321)
|
| 42 |
|
|
|
| 43 |
|
|
/* We don't have GAS for the RS/6000 yet, so don't write out special
|
| 44 |
|
|
.stabs in cc1plus. */
|
| 45 |
|
|
|
| 46 |
|
|
#define FASCIST_ASSEMBLER
|
| 47 |
|
|
|
| 48 |
|
|
/* We define this to prevent the name mangler from putting dollar signs into
|
| 49 |
|
|
function names. */
|
| 50 |
|
|
|
| 51 |
|
|
#define NO_DOLLAR_IN_LABEL
|
| 52 |
|
|
|
| 53 |
|
|
/* We define this to 0 so that gcc will never accept a dollar sign in a
|
| 54 |
|
|
variable name. This is needed because the AIX assembler will not accept
|
| 55 |
|
|
dollar signs. */
|
| 56 |
|
|
|
| 57 |
|
|
#define DOLLARS_IN_IDENTIFIERS 0
|
| 58 |
|
|
|
| 59 |
|
|
/* AIX .align pseudo-op accept value from 0 to 12, corresponding to
|
| 60 |
|
|
log base 2 of the alignment in bytes; 12 = 4096 bytes = 32768 bits. */
|
| 61 |
|
|
|
| 62 |
|
|
#define MAX_OFILE_ALIGNMENT 32768
|
| 63 |
|
|
|
| 64 |
|
|
/* Default alignment factor for csect directives, chosen to honor
|
| 65 |
|
|
BIGGEST_ALIGNMENT. */
|
| 66 |
|
|
#define XCOFF_CSECT_DEFAULT_ALIGNMENT_STR "4"
|
| 67 |
|
|
|
| 68 |
|
|
/* Return nonzero if this entry is to be written into the constant
|
| 69 |
|
|
pool in a special way. We do so if this is a SYMBOL_REF, LABEL_REF
|
| 70 |
|
|
or a CONST containing one of them. If -mfp-in-toc (the default),
|
| 71 |
|
|
we also do this for floating-point constants. We actually can only
|
| 72 |
|
|
do this if the FP formats of the target and host machines are the
|
| 73 |
|
|
same, but we can't check that since not every file that uses these
|
| 74 |
|
|
target macros includes real.h. We also do this when we can write the
|
| 75 |
|
|
entry into the TOC and the entry is not larger than a TOC entry. */
|
| 76 |
|
|
|
| 77 |
|
|
#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \
|
| 78 |
|
|
(TARGET_TOC \
|
| 79 |
|
|
&& (GET_CODE (X) == SYMBOL_REF \
|
| 80 |
|
|
|| (GET_CODE (X) == CONST && GET_CODE (XEXP (X, 0)) == PLUS \
|
| 81 |
|
|
&& GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF) \
|
| 82 |
|
|
|| GET_CODE (X) == LABEL_REF \
|
| 83 |
|
|
|| (GET_CODE (X) == CONST_INT \
|
| 84 |
|
|
&& GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \
|
| 85 |
|
|
|| (GET_CODE (X) == CONST_DOUBLE \
|
| 86 |
|
|
&& (TARGET_MINIMAL_TOC \
|
| 87 |
|
|
|| (SCALAR_FLOAT_MODE_P (GET_MODE (X)) \
|
| 88 |
|
|
&& ! TARGET_NO_FP_IN_TOC)))))
|
| 89 |
|
|
|
| 90 |
|
|
#define TARGET_ASM_OUTPUT_ANCHOR rs6000_xcoff_asm_output_anchor
|
| 91 |
|
|
#define TARGET_ASM_GLOBALIZE_LABEL rs6000_xcoff_asm_globalize_label
|
| 92 |
|
|
#define TARGET_ASM_INIT_SECTIONS rs6000_xcoff_asm_init_sections
|
| 93 |
|
|
#define TARGET_ASM_RELOC_RW_MASK rs6000_xcoff_reloc_rw_mask
|
| 94 |
|
|
#define TARGET_ASM_NAMED_SECTION rs6000_xcoff_asm_named_section
|
| 95 |
|
|
#define TARGET_ASM_SELECT_SECTION rs6000_xcoff_select_section
|
| 96 |
|
|
#define TARGET_ASM_SELECT_RTX_SECTION rs6000_xcoff_select_rtx_section
|
| 97 |
|
|
#define TARGET_ASM_UNIQUE_SECTION rs6000_xcoff_unique_section
|
| 98 |
|
|
#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
|
| 99 |
|
|
#define TARGET_STRIP_NAME_ENCODING rs6000_xcoff_strip_name_encoding
|
| 100 |
|
|
#define TARGET_SECTION_TYPE_FLAGS rs6000_xcoff_section_type_flags
|
| 101 |
|
|
|
| 102 |
|
|
/* FP save and restore routines. */
|
| 103 |
|
|
#define SAVE_FP_PREFIX "._savef"
|
| 104 |
|
|
#define SAVE_FP_SUFFIX ""
|
| 105 |
|
|
#define RESTORE_FP_PREFIX "._restf"
|
| 106 |
|
|
#define RESTORE_FP_SUFFIX ""
|
| 107 |
|
|
|
| 108 |
|
|
/* Function name to call to do profiling. */
|
| 109 |
|
|
#undef RS6000_MCOUNT
|
| 110 |
|
|
#define RS6000_MCOUNT ".__mcount"
|
| 111 |
|
|
|
| 112 |
|
|
/* This outputs NAME to FILE up to the first null or '['. */
|
| 113 |
|
|
|
| 114 |
|
|
#define RS6000_OUTPUT_BASENAME(FILE, NAME) \
|
| 115 |
|
|
assemble_name ((FILE), (*targetm.strip_name_encoding) (NAME))
|
| 116 |
|
|
|
| 117 |
|
|
/* This is how to output the definition of a user-level label named NAME,
|
| 118 |
|
|
such as the label on a static function or variable NAME. */
|
| 119 |
|
|
|
| 120 |
|
|
#define ASM_OUTPUT_LABEL(FILE,NAME) \
|
| 121 |
|
|
do { RS6000_OUTPUT_BASENAME (FILE, NAME); fputs (":\n", FILE); } while (0)
|
| 122 |
|
|
|
| 123 |
|
|
/* This is how to output a command to make the user-level label named NAME
|
| 124 |
|
|
defined for reference from other files. */
|
| 125 |
|
|
|
| 126 |
|
|
/* Globalizing directive for a label. */
|
| 127 |
|
|
#define GLOBAL_ASM_OP "\t.globl "
|
| 128 |
|
|
|
| 129 |
|
|
#undef TARGET_ASM_FILE_START
|
| 130 |
|
|
#define TARGET_ASM_FILE_START rs6000_xcoff_file_start
|
| 131 |
|
|
#define TARGET_ASM_FILE_END rs6000_xcoff_file_end
|
| 132 |
|
|
#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
|
| 133 |
|
|
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE false
|
| 134 |
|
|
|
| 135 |
|
|
/* This macro produces the initial definition of a function name.
|
| 136 |
|
|
On the RS/6000, we need to place an extra '.' in the function name and
|
| 137 |
|
|
output the function descriptor.
|
| 138 |
|
|
Dollar signs are converted to underscores.
|
| 139 |
|
|
|
| 140 |
|
|
The csect for the function will have already been created when
|
| 141 |
|
|
text_section was selected. We do have to go back to that csect, however.
|
| 142 |
|
|
|
| 143 |
|
|
The third and fourth parameters to the .function pseudo-op (16 and 044)
|
| 144 |
|
|
are placeholders which no longer have any use. */
|
| 145 |
|
|
|
| 146 |
|
|
#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
|
| 147 |
|
|
{ char *buffer = (char *) alloca (strlen (NAME) + 1); \
|
| 148 |
|
|
char *p; \
|
| 149 |
|
|
int dollar_inside = 0; \
|
| 150 |
|
|
strcpy (buffer, NAME); \
|
| 151 |
|
|
p = strchr (buffer, '$'); \
|
| 152 |
|
|
while (p) { \
|
| 153 |
|
|
*p = '_'; \
|
| 154 |
|
|
dollar_inside++; \
|
| 155 |
|
|
p = strchr (p + 1, '$'); \
|
| 156 |
|
|
} \
|
| 157 |
|
|
if (TREE_PUBLIC (DECL)) \
|
| 158 |
|
|
{ \
|
| 159 |
|
|
if (!RS6000_WEAK || !DECL_WEAK (decl)) \
|
| 160 |
|
|
{ \
|
| 161 |
|
|
if (dollar_inside) { \
|
| 162 |
|
|
fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \
|
| 163 |
|
|
fprintf(FILE, "\t.rename %s,\"%s\"\n", buffer, NAME); \
|
| 164 |
|
|
} \
|
| 165 |
|
|
fputs ("\t.globl .", FILE); \
|
| 166 |
|
|
RS6000_OUTPUT_BASENAME (FILE, buffer); \
|
| 167 |
|
|
putc ('\n', FILE); \
|
| 168 |
|
|
} \
|
| 169 |
|
|
} \
|
| 170 |
|
|
else \
|
| 171 |
|
|
{ \
|
| 172 |
|
|
if (dollar_inside) { \
|
| 173 |
|
|
fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \
|
| 174 |
|
|
fprintf(FILE, "\t.rename %s,\"%s\"\n", buffer, NAME); \
|
| 175 |
|
|
} \
|
| 176 |
|
|
fputs ("\t.lglobl .", FILE); \
|
| 177 |
|
|
RS6000_OUTPUT_BASENAME (FILE, buffer); \
|
| 178 |
|
|
putc ('\n', FILE); \
|
| 179 |
|
|
} \
|
| 180 |
|
|
fputs ("\t.csect ", FILE); \
|
| 181 |
|
|
RS6000_OUTPUT_BASENAME (FILE, buffer); \
|
| 182 |
|
|
fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", FILE); \
|
| 183 |
|
|
RS6000_OUTPUT_BASENAME (FILE, buffer); \
|
| 184 |
|
|
fputs (":\n", FILE); \
|
| 185 |
|
|
fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", FILE); \
|
| 186 |
|
|
RS6000_OUTPUT_BASENAME (FILE, buffer); \
|
| 187 |
|
|
fputs (", TOC[tc0], 0\n", FILE); \
|
| 188 |
|
|
in_section = NULL; \
|
| 189 |
|
|
switch_to_section (function_section (DECL)); \
|
| 190 |
|
|
putc ('.', FILE); \
|
| 191 |
|
|
RS6000_OUTPUT_BASENAME (FILE, buffer); \
|
| 192 |
|
|
fputs (":\n", FILE); \
|
| 193 |
|
|
if (write_symbols != NO_DEBUG && !DECL_IGNORED_P (DECL)) \
|
| 194 |
|
|
xcoffout_declare_function (FILE, DECL, buffer); \
|
| 195 |
|
|
}
|
| 196 |
|
|
|
| 197 |
|
|
/* Output a reference to SYM on FILE. */
|
| 198 |
|
|
|
| 199 |
|
|
#define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) \
|
| 200 |
|
|
rs6000_output_symbol_ref (FILE, SYM)
|
| 201 |
|
|
|
| 202 |
|
|
/* This says how to output an external.
|
| 203 |
|
|
Dollar signs are converted to underscores. */
|
| 204 |
|
|
|
| 205 |
|
|
#undef ASM_OUTPUT_EXTERNAL
|
| 206 |
|
|
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
|
| 207 |
|
|
{ char *buffer = (char *) alloca (strlen (NAME) + 1); \
|
| 208 |
|
|
char *p; \
|
| 209 |
|
|
rtx _symref = XEXP (DECL_RTL (DECL), 0); \
|
| 210 |
|
|
int dollar_inside = 0; \
|
| 211 |
|
|
strcpy (buffer, NAME); \
|
| 212 |
|
|
p = strchr (buffer, '$'); \
|
| 213 |
|
|
while (p) { \
|
| 214 |
|
|
*p = '_'; \
|
| 215 |
|
|
dollar_inside++; \
|
| 216 |
|
|
p = strchr (p + 1, '$'); \
|
| 217 |
|
|
} \
|
| 218 |
|
|
if (dollar_inside) { \
|
| 219 |
|
|
fputs ("\t.extern .", FILE); \
|
| 220 |
|
|
RS6000_OUTPUT_BASENAME (FILE, buffer); \
|
| 221 |
|
|
putc ('\n', FILE); \
|
| 222 |
|
|
fprintf(FILE, "\t.rename .%s,\".%s\"\n", buffer, NAME); \
|
| 223 |
|
|
} \
|
| 224 |
|
|
if ((TREE_CODE (DECL) == VAR_DECL \
|
| 225 |
|
|
|| TREE_CODE (DECL) == FUNCTION_DECL) \
|
| 226 |
|
|
&& (NAME)[strlen (NAME) - 1] != ']') \
|
| 227 |
|
|
{ \
|
| 228 |
|
|
XSTR (_symref, 0) = concat (XSTR (_symref, 0), \
|
| 229 |
|
|
(TREE_CODE (DECL) == FUNCTION_DECL \
|
| 230 |
|
|
? "[DS]" : "[RW]"), \
|
| 231 |
|
|
NULL); \
|
| 232 |
|
|
} \
|
| 233 |
|
|
}
|
| 234 |
|
|
|
| 235 |
|
|
/* This is how to output a reference to a user-level label named NAME.
|
| 236 |
|
|
`assemble_name' uses this. */
|
| 237 |
|
|
|
| 238 |
|
|
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
|
| 239 |
|
|
asm_fprintf ((FILE), "%U%s", rs6000_xcoff_strip_dollar (NAME));
|
| 240 |
|
|
|
| 241 |
|
|
/* This is how to output an internal label prefix. rs6000.c uses this
|
| 242 |
|
|
when generating traceback tables. */
|
| 243 |
|
|
|
| 244 |
|
|
#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \
|
| 245 |
|
|
fprintf (FILE, "%s..", PREFIX)
|
| 246 |
|
|
|
| 247 |
|
|
/* This is how to output a label for a jump table. Arguments are the same as
|
| 248 |
|
|
for (*targetm.asm_out.internal_label), except the insn for the jump table is
|
| 249 |
|
|
passed. */
|
| 250 |
|
|
|
| 251 |
|
|
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
|
| 252 |
|
|
{ ASM_OUTPUT_ALIGN (FILE, 2); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
|
| 253 |
|
|
|
| 254 |
|
|
/* This is how to store into the string LABEL
|
| 255 |
|
|
the symbol_ref name of an internal numbered label where
|
| 256 |
|
|
PREFIX is the class of label and NUM is the number within the class.
|
| 257 |
|
|
This is suitable for output with `assemble_name'. */
|
| 258 |
|
|
|
| 259 |
|
|
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
|
| 260 |
|
|
sprintf (LABEL, "*%s..%u", rs6000_xcoff_strip_dollar (PREFIX), (unsigned) (NUM))
|
| 261 |
|
|
|
| 262 |
|
|
/* This is how to output an assembler line to define N characters starting
|
| 263 |
|
|
at P to FILE. */
|
| 264 |
|
|
|
| 265 |
|
|
#define ASM_OUTPUT_ASCII(FILE, P, N) output_ascii ((FILE), (P), (N))
|
| 266 |
|
|
|
| 267 |
|
|
/* This is how to advance the location counter by SIZE bytes. */
|
| 268 |
|
|
|
| 269 |
|
|
#define SKIP_ASM_OP "\t.space "
|
| 270 |
|
|
|
| 271 |
|
|
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
|
| 272 |
|
|
fprintf (FILE, "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n", SKIP_ASM_OP, (SIZE))
|
| 273 |
|
|
|
| 274 |
|
|
/* This says how to output an assembler line
|
| 275 |
|
|
to define a global common symbol. */
|
| 276 |
|
|
|
| 277 |
|
|
#define COMMON_ASM_OP "\t.comm "
|
| 278 |
|
|
|
| 279 |
|
|
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
|
| 280 |
|
|
do { fputs (COMMON_ASM_OP, (FILE)); \
|
| 281 |
|
|
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
|
| 282 |
|
|
if ((ALIGN) > 32) \
|
| 283 |
|
|
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), \
|
| 284 |
|
|
exact_log2 ((ALIGN) / BITS_PER_UNIT)); \
|
| 285 |
|
|
else if ((SIZE) > 4) \
|
| 286 |
|
|
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",3\n", (SIZE)); \
|
| 287 |
|
|
else \
|
| 288 |
|
|
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)); \
|
| 289 |
|
|
} while (0)
|
| 290 |
|
|
|
| 291 |
|
|
/* This says how to output an assembler line
|
| 292 |
|
|
to define a local common symbol.
|
| 293 |
|
|
Alignment cannot be specified, but we can try to maintain
|
| 294 |
|
|
alignment after preceding TOC section if it was aligned
|
| 295 |
|
|
for 64-bit mode. */
|
| 296 |
|
|
|
| 297 |
|
|
#define LOCAL_COMMON_ASM_OP "\t.lcomm "
|
| 298 |
|
|
|
| 299 |
|
|
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
|
| 300 |
|
|
do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \
|
| 301 |
|
|
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
|
| 302 |
|
|
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s\n", \
|
| 303 |
|
|
(TARGET_32BIT ? (SIZE) : (ROUNDED)), \
|
| 304 |
|
|
xcoff_bss_section_name); \
|
| 305 |
|
|
} while (0)
|
| 306 |
|
|
|
| 307 |
|
|
/* This is how we tell the assembler that two symbols have the same value. */
|
| 308 |
|
|
#define SET_ASM_OP "\t.set "
|
| 309 |
|
|
|
| 310 |
|
|
/* This is how we tell the assembler to equate two values. */
|
| 311 |
|
|
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
|
| 312 |
|
|
do { fprintf ((FILE), "%s", SET_ASM_OP); \
|
| 313 |
|
|
RS6000_OUTPUT_BASENAME (FILE, LABEL1); \
|
| 314 |
|
|
fprintf (FILE, ","); \
|
| 315 |
|
|
RS6000_OUTPUT_BASENAME (FILE, LABEL2); \
|
| 316 |
|
|
fprintf (FILE, "\n"); \
|
| 317 |
|
|
} while (0)
|
| 318 |
|
|
|
| 319 |
|
|
/* Used by rs6000_assemble_integer, among others. */
|
| 320 |
|
|
#define DOUBLE_INT_ASM_OP "\t.llong\t"
|
| 321 |
|
|
|
| 322 |
|
|
/* Output before instructions. */
|
| 323 |
|
|
#define TEXT_SECTION_ASM_OP "\t.csect .text[PR]"
|
| 324 |
|
|
|
| 325 |
|
|
/* Output before writable data. */
|
| 326 |
|
|
#define DATA_SECTION_ASM_OP \
|
| 327 |
|
|
"\t.csect .data[RW]," XCOFF_CSECT_DEFAULT_ALIGNMENT_STR
|
| 328 |
|
|
|
| 329 |
|
|
|
| 330 |
|
|
/* Define to prevent DWARF2 unwind info in the data section rather
|
| 331 |
|
|
than in the .eh_frame section. We do this because the AIX linker
|
| 332 |
|
|
would otherwise garbage collect these sections. */
|
| 333 |
|
|
#define EH_FRAME_IN_DATA_SECTION 1
|