#include "rs6000/rs6000.c"
static int pragma_initialized;
static int initial_optimize_flag;
static int initial_flag_expensive_optimizations;
enum {WHITESPACE_OPTIONAL, WHITESPACE_REQUIRED};
static int skip_whitespace(finput, required_whitespace)
FILE *finput;
int required_whitespace;
{
int c;
c = getc(finput); ungetc (c, finput);
if (! isspace(c))
return (required_whitespace) ? 0 : 1;
do {
c = getc (finput);
} while (isspace(c));
ungetc (c, finput);
return 1;
}
static int getword(finput, buf, buf_size)
FILE *finput;
char *buf;
int buf_size;
{
char *cp = buf;
int c;
while (--buf_size > 0)
{
c = getc (finput);
if (! isalnum (c))
{
ungetc (c, finput);
break;
}
else
*cp++ = c;
}
*cp = 0;
return cp - buf;
}
int
handle_pragma (finput, t)
FILE *finput;
tree t;
{
char *pname;
int c, handled = 0;
if (!pragma_initialized)
{
pragma_initialized = 1;
initial_optimize_flag = optimize;
initial_flag_expensive_optimizations = flag_expensive_optimizations;
}
if (TREE_CODE (t) != IDENTIFIER_NODE)
return 0;
pname = IDENTIFIER_POINTER (t);
if (strcmp(pname, "CC_OPT_ON") == 0)
{
optimize = 1, obey_regdecls = 0, handled = 1;
flag_expensive_optimizations = initial_flag_expensive_optimizations;
warning ("optimization turned on");
}
else if (strcmp(pname, "CC_OPT_OFF") == 0)
{
optimize = 0, obey_regdecls = 1, handled = 1;
flag_expensive_optimizations = 0;
warning ("optimization turned off");
}
else if (strcmp(pname, "CC_OPT_RESTORE") == 0)
{
handled = 1;
if (optimize != initial_optimize_flag)
{
if (initial_optimize_flag)
obey_regdecls = 0;
else
obey_regdecls = 1;
optimize = initial_optimize_flag;
flag_expensive_optimizations = initial_flag_expensive_optimizations;
}
warning ("optimization level restored");
}
else if (strcmp(pname, "CC_WRITABLE_STRINGS") == 0)
flag_writable_strings = 1, handled = 1;
else if (strcmp(pname, "CC_NON_WRITABLE_STRINGS") == 0)
flag_writable_strings = 0, handled = 1;
#ifdef APPLE_MAC68K_ALIGNMENT
else if (strcmp(pname, "options") == 0) {
char buf[128];
int legal = 0;
handled = 1;
if (skip_whitespace (finput, WHITESPACE_OPTIONAL)) {
if (getword (finput, buf, sizeof(buf))) {
if (strcmp (buf, "align") == 0) {
(void)skip_whitespace (finput, WHITESPACE_OPTIONAL);
if (getc(finput) == '=') {
(void)skip_whitespace (finput, WHITESPACE_OPTIONAL);
if (getword (finput, buf, sizeof(buf))) {
if (!strcmp (buf, "mac68k"))
maximum_field_alignment = 16, legal = 1;
if (!strcmp (buf, "power") || !strcmp(buf, "reset"))
maximum_field_alignment = 0, legal = 1;
}
}
}
}
}
if (!legal)
warning ("unrecognised pragma");
}
else if (strcmp(pname, "pack") == 0) {
char buf[128];
int legal = 0;
handled = 1;
if (skip_whitespace (finput, WHITESPACE_OPTIONAL)) {
if (getc (finput) == '(') {
skip_whitespace (finput, WHITESPACE_OPTIONAL);
if (getword (finput, buf, sizeof(buf))) {
skip_whitespace (finput, WHITESPACE_OPTIONAL);
if (getc (finput) == ')') {
long int i = strtol (buf, NULL, 10);
if (i >= 0 && i <= 16)
maximum_field_alignment = i * 8, legal = 1;
}
}
}
}
if (!legal)
warning ("unrecognised pragma");
}
#endif
#if OTHER_NEXT_STUFF
else if (OPT_STRCMP ("SECTION"))
{
char name[1024];
char *q = &(name[0]);
while (isalpha (*p)) p++;
while (*p && (isspace (*p) || (*p == '.'))) p++;
while (*p && !isspace (*p)) *q++ = *p++;
*q = 0;
while (*p && isspace (*p)) p++;
if (*p == 0)
alias_section (name, 0);
else if (*p == '"')
{
char *start = ++p;
while (*p && *p != '"')
{
if (*p == '\\') p++;
p++;
}
*p = 0;
alias_section (name, start);
}
else
{
alias_section (name, p);
}
}
else if (OPT_STRCMP ("CALL_ON_MODULE_BIND"))
{
extern FILE *asm_out_file;
while (isalpha (*p) || *p == '_') p++;
while (*p && isspace (*p)) p++;
if (*p)
{
mod_init_section ();
fprintf (asm_out_file, "\t.long _%s\n", p);
}
}
#endif
return handled;
}
void
ppcasm_output_ascii (file, p, size)
FILE *file;
unsigned char *p;
int size;
{
char *opcode = "DC.B";
int max = 48;
int i;
register int num = 0;
register int quoted = 0;
if (size <= 0)
abort();
fprintf (file, "\t%s\t", opcode);
for (i = 0; i < size; i++)
{
register int c = p[i];
if (num > max)
{
fprintf (file, "%s\n\t%s\t", (quoted) ? "'" : "", opcode);
num = quoted = 0;
}
if (c >= ' ' && c < 0177)
{
if (quoted)
{
if (c == '\'' || c == '\\') {putc(c, file); num++;}
putc (c, file);
num++;
}
else
{
if (num)
{
num += fprintf(file, ", '%c", c);
}
else
{
num += fprintf(file, "'%c", c);
}
if (c == '\'' || c == '\\') {putc(c, file); num++;}
quoted = 1;
}
}
else
{
if (quoted)
{
num += fprintf(file, "', 0x%02x", c);
quoted = 0;
}
else
{
num += fprintf(file, "%s0x%02x", (num) ? ", " : "", c);
}
}
}
fprintf (file, "%s\n", (quoted) ? "'" : "");
}
void ppcasm_output_labelref (file, name)
FILE *file;
char *name;
{
int c;
while (c = *name)
{
if (c == '[' && ( (name[1] == 'R' && name[2] == 'W')
|| (name[1] == 'D' && name[2] == 'S'))
&& name[3] == ']' && name[4] == 0)
{
return;
}
else
{
putc (c, file);
}
++name;
}
}
void
ppcasm_output_prolog (file, size)
FILE *file;
int size;
{
rs6000_stack_t *info = rs6000_stack_info ();
int reg_size = info->reg_size;
char *store_reg;
char *load_reg;
int sp_reg = 1;
int sp_offset = 0;
if (TARGET_32BIT)
{
store_reg = "\t{st|stw} %s,%d(%s)\n";
load_reg = "\t{l|lwz} %s,%d(%s)\n";
}
else
{
store_reg = "\tstd %s,%d(%s)\n";
load_reg = "\tlld %s,%d(%s)\n";
}
if (TARGET_DEBUG_STACK)
debug_stack_info (info);
if (info->first_fp_reg_save < 64 && !FP_SAVE_INLINE (info->first_fp_reg_save))
fprintf (file, "\tIMPORT\t%s%d%s\n\tIMPORT\t%s%d%s\n",
SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
if (rs6000_trunc_used && ! trunc_defined)
{
fprintf (file, "\tIMPORT\t.%s\n\tIMPORT\t.%s\n",
RS6000_ITRUNC, RS6000_UITRUNC);
trunc_defined = 1;
}
if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
{
fputs ("\t.IMPORT\t__mulh\n", file);
fputs ("\t.IMPORT\t__mull\n", file);
fputs ("\t.IMPORT\t__divss\n", file);
fputs ("\t.IMPORT\t__divus\n", file);
fputs ("\t.IMPORT\t__quoss\n", file);
fputs ("\t.IMPORT\t__quous\n", file);
common_mode_defined = 1;
}
if (info->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
{
if (info->total_size < 32767)
sp_offset = info->total_size;
else
sp_reg = 12;
rs6000_allocate_stack_space (file, info->total_size, sp_reg == 12);
}
if (info->lr_save_p)
asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
if (info->cr_save_p && sp_reg != 12)
asm_fprintf (file, "\tmfcr %s\n", reg_names[12]);
if (FP_SAVE_INLINE (info->first_fp_reg_save))
{
int regno = info->first_fp_reg_save;
int loc = info->fp_save_offset + sp_offset;
for ( ; regno < 64; regno++, loc += 8)
asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]);
}
else if (info->first_fp_reg_save != 64)
asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX,
info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT)
{
int regno = info->first_gp_reg_save;
int loc = info->gp_save_offset + sp_offset;
for ( ; regno < 32; regno++, loc += reg_size)
asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]);
}
else if (info->first_gp_reg_save != 32)
asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n",
reg_names[info->first_gp_reg_save],
info->gp_save_offset + sp_offset,
reg_names[sp_reg]);
#ifdef NAME__MAIN
if (info->main_save_p)
{
int regno;
int loc = info->main_save_offset + sp_offset;
int size = info->main_size;
for (regno = 3; size > 0; regno++, loc -= reg_size, size -= reg_size)
asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[sp_reg]);
}
#endif
if (info->lr_save_p)
asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset + sp_offset,
reg_names[sp_reg]);
if (info->cr_save_p)
{
if (sp_reg == 12)
{
asm_fprintf (file, "\tmfcr %s\n", reg_names[0]);
asm_fprintf (file, store_reg, reg_names[0],
info->cr_save_offset + sp_offset,
reg_names[sp_reg]);
}
else
asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset + sp_offset,
reg_names[sp_reg]);
}
if (DEFAULT_ABI == ABI_NT && info->total_size > 4096)
{
if (info->total_size < 32768)
{
int probe_offset = 4096;
while (probe_offset < info->total_size)
{
asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", reg_names[0], -probe_offset, reg_names[1]);
probe_offset += 4096;
}
}
else
{
int probe_iterations = info->total_size / 4096;
static int probe_labelno = 0;
char buf[256];
if (probe_iterations < 32768)
asm_fprintf (file, "\tli %s,%d\n", reg_names[12], probe_iterations);
else
{
asm_fprintf (file, "\tlis %s,%d\n", reg_names[12], probe_iterations >> 16);
if (probe_iterations & 0xffff)
asm_fprintf (file, "\tori %s,%s,%d\n", reg_names[12], reg_names[12],
probe_iterations & 0xffff);
}
asm_fprintf (file, "\tmtctr %s\n", reg_names[12]);
asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
ASM_OUTPUT_INTERNAL_LABEL (file, "LCprobe", probe_labelno);
asm_fprintf (file, "\t{lu|lwzu} %s,-4096(%s)\n", reg_names[0], reg_names[12]);
ASM_GENERATE_INTERNAL_LABEL (buf, "LCprobe", probe_labelno++);
fputs ("\tbdnz ", file);
assemble_name (file, buf);
fputs ("\n", file);
}
}
if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
rs6000_allocate_stack_space (file, info->total_size, FALSE);
if (frame_pointer_needed)
asm_fprintf (file, "\tmr %s,%s\n", reg_names[31], reg_names[1]);
#ifdef NAME__MAIN
if (info->main_p)
{
char *prefix = "";
switch (DEFAULT_ABI)
{
case ABI_AIX: prefix = "."; break;
case ABI_NT: prefix = ".."; break;
}
fprintf (file, "\tbl %s%s\n", prefix, NAME__MAIN);
#ifdef RS6000_CALL_GLUE2
fprintf (file, "\t%s%s%s\n", RS6000_CALL_GLUE2, prefix, NAME_MAIN);
#else
#ifdef RS6000_CALL_GLUE
if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
fprintf (file, "\t%s\n", RS6000_CALL_GLUE);
#endif
#endif
if (info->main_save_p)
{
int regno;
int loc;
int size = info->main_size;
if (info->total_size < 32767)
{
loc = info->total_size + info->main_save_offset;
for (regno = 3; size > 0; regno++, size -= reg_size, loc -= reg_size)
asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[1]);
}
else
{
int neg_size = info->main_save_offset - info->total_size;
loc = 0;
asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n",
reg_names[0], (neg_size >> 16) & 0xffff,
reg_names[0], reg_names[0], neg_size & 0xffff);
asm_fprintf (file, "\t{sf|subf} %s,%s,%s\n", reg_names[0], reg_names[0],
reg_names[1]);
for (regno = 3; size > 0; regno++, size -= reg_size, loc -= reg_size)
asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[0]);
}
}
}
#endif
if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
{
#ifdef USING_SVR4_H
if (!profile_flag)
rs6000_pic_func_labelno = rs6000_pic_labelno;
#endif
rs6000_output_load_toc_table (file, 30);
}
if (DEFAULT_ABI == ABI_NT)
{
assemble_name (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
fputs (".b:\n", file);
}
}
void
ppcasm_output_epilog (file, size)
FILE *file;
int size;
{
rs6000_stack_t *info = rs6000_stack_info ();
char *load_reg = (TARGET_32BIT) ? "\t{l|lwz} %s,%d(%s)\n" : "\tld %s,%d(%s)\n";
rtx insn = get_last_insn ();
int sp_reg = 1;
int sp_offset = 0;
int i;
if (GET_CODE (insn) == NOTE)
insn = prev_nonnote_insn (insn);
if (insn == 0 || GET_CODE (insn) != BARRIER)
{
if (frame_pointer_needed || current_function_calls_alloca
|| info->total_size > 32767)
{
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
sp_reg = 11;
asm_fprintf (file, load_reg, reg_names[sp_reg], 0, reg_names[1]);
}
else if (info->push_p)
{
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS)
sp_offset = info->total_size;
else if (TARGET_NEW_MNEMONICS)
asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], info->total_size);
else
asm_fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], info->total_size, reg_names[1]);
}
if (info->lr_save_p)
asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset + sp_offset, reg_names[sp_reg]);
if (info->cr_save_p)
asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset + sp_offset, reg_names[sp_reg]);
if (info->lr_save_p)
asm_fprintf (file, "\tmtlr %s\n", reg_names[0]);
if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT)
{
int regno = info->first_gp_reg_save;
int loc = info->gp_save_offset + sp_offset;
int reg_size = (TARGET_32BIT) ? 4 : 8;
for ( ; regno < 32; regno++, loc += reg_size)
asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[sp_reg]);
}
else if (info->first_gp_reg_save != 32)
asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n",
reg_names[info->first_gp_reg_save],
info->gp_save_offset + sp_offset,
reg_names[sp_reg]);
if (FP_SAVE_INLINE (info->first_fp_reg_save))
{
int regno = info->first_fp_reg_save;
int loc = info->fp_save_offset + sp_offset;
for ( ; regno < 64; regno++, loc += 8)
asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[sp_reg]);
}
if (info->cr_save_p)
asm_fprintf (file, "\tmtcrf %d,%s\n",
(regs_ever_live[70] != 0) * 0x20
+ (regs_ever_live[71] != 0) * 0x10
+ (regs_ever_live[72] != 0) * 0x8, reg_names[12]);
if (sp_offset)
{
if (TARGET_NEW_MNEMONICS)
asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], sp_offset);
else
asm_fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], sp_offset, reg_names[1]);
}
else if (sp_reg != 1)
asm_fprintf (file, "\tmr %s,%s\n", reg_names[1], reg_names[sp_reg]);
if (info->first_fp_reg_save != 64 && !FP_SAVE_INLINE (info->first_fp_reg_save))
asm_fprintf (file, "\tb %s%d%s\n", RESTORE_FP_PREFIX,
info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
else
asm_fprintf (file, "\t{br|blr}\n");
}
if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive)
{
char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
int fixed_parms, float_parms, parm_info;
int i;
while (*fname == '.')
fname++;
if (*fname == '*')
++fname;
fputs ("@tb_", file);
RS6000_OUTPUT_BASENAME (file, fname);
fputs ("\tDC.L\t0\n", file);
fputs ("\tDC.B\t0,", file);
if (! strcmp (language_string, "GNU C")
|| ! strcmp (language_string, "GNU Obj-C"))
i = 0;
else if (! strcmp (language_string, "GNU F77"))
i = 1;
else if (! strcmp (language_string, "GNU Ada"))
i = 3;
else if (! strcmp (language_string, "GNU Pascal"))
i = 2;
else if (! strcmp (language_string, "GNU C++"))
i = 9;
else
abort ();
fprintf (file, "%d,", i);
fprintf (file, "%d,", (1 << 5) | ((info->first_fp_reg_save != 64) << 1));
fprintf (file, "%d,",
((1 << 6) | (frame_pointer_needed << 5)
| (info->cr_save_p << 1) | (info->lr_save_p)));
fprintf (file, "%d,",
(info->push_p << 7) | (64 - info->first_fp_reg_save));
fprintf (file, "%d,", (32 - first_reg_to_save ()));
{
tree decl;
int next_parm_info_bit;
next_parm_info_bit = 31;
parm_info = 0;
fixed_parms = 0;
float_parms = 0;
for (decl = DECL_ARGUMENTS (current_function_decl);
decl; decl = TREE_CHAIN (decl))
{
rtx parameter = DECL_INCOMING_RTL (decl);
enum machine_mode mode = GET_MODE (parameter);
if (GET_CODE (parameter) == REG)
{
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{
int bits;
float_parms++;
if (mode == SFmode)
bits = 0x2;
else if (mode == DFmode)
bits = 0x3;
else
abort ();
if (next_parm_info_bit > 0)
parm_info |= (bits << (next_parm_info_bit - 1));
next_parm_info_bit -= 2;
}
else
{
fixed_parms += ((GET_MODE_SIZE (mode)
+ (UNITS_PER_WORD - 1))
/ UNITS_PER_WORD);
next_parm_info_bit -= 1;
}
}
}
}
fprintf (file, "%d,", fixed_parms);
fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
if (fixed_parms || float_parms)
fprintf (file, "\tDC.L\t%d\n", parm_info);
fputs ("\tDC.L\t", file);
fputs ("@tb_", file);
RS6000_OUTPUT_BASENAME (file, fname);
fputs (" - .", file);
RS6000_OUTPUT_BASENAME (file, fname);
putc ('\n', file);
fprintf (file, "\tDC.W\t%d\n", strlen (fname));
assemble_string (fname, strlen (fname));
if (frame_pointer_needed)
fputs ("\tDC.B\t31\n", file);
putc ('\n', file);
}
if (DEFAULT_ABI == ABI_NT)
{
RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
fputs (".e:\nFE_MOT_RESVD..", file);
RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
fputs (":\n", file);
}
}
void
ppcasm_output_toc (file, x, labelno)
FILE *file;
rtx x;
int labelno;
{
char buf[256];
char *name = buf;
char *real_name;
rtx base = x;
int offset = 0;
if (TARGET_NO_TOC)
abort ();
if (GET_CODE (x) == CONST_DOUBLE
&& STRICT_ALIGNMENT
&& GET_MODE (x) == DFmode
&& ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
ASM_OUTPUT_ALIGN (file, 3);
}
if (TARGET_ELF && TARGET_MINIMAL_TOC)
{
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
fprintf (file, "%d = .-", labelno);
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCTOC");
fputs ("1\n", file);
}
else
ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode
&& ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC))
{
REAL_VALUE_TYPE rv;
long k[2];
REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
if (TARGET_MINIMAL_TOC)
fprintf (file, "\tDC.L %ld\n\tDC.L %ld\n", k[0], k[1]);
else
fprintf (file, "\tTC FD_%lx_%lx[TC],%ld,%ld\n",
k[0], k[1], k[0], k[1]);
return;
}
else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode
&& ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC))
{
REAL_VALUE_TYPE rv;
long l;
REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
REAL_VALUE_TO_TARGET_SINGLE (rv, l);
if (TARGET_MINIMAL_TOC)
fprintf (file, "\tDC.L %ld\n", l);
else
fprintf (file, "\tTC FS_%lx[TC],%ld\n", l, l);
return;
}
else if (GET_MODE (x) == DImode
&& (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
&& ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC))
{
HOST_WIDE_INT low;
HOST_WIDE_INT high;
if (GET_CODE (x) == CONST_DOUBLE)
{
low = CONST_DOUBLE_LOW (x);
high = CONST_DOUBLE_HIGH (x);
}
else
#if HOST_BITS_PER_WIDE_INT == 32
{
low = INTVAL (x);
high = (low < 0) ? ~0 : 0;
}
#else
{
low = INTVAL (x) & 0xffffffff;
high = (HOST_WIDE_INT) INTVAL (x) >> 32;
}
#endif
if (TARGET_MINIMAL_TOC)
fprintf (file, "\tDC.L %ld\n\tDC.L %ld\n", (long)high, (long)low);
else
fprintf (file, "\tTC ID_%lx_%lx[TC],%ld,%ld\n",
(long)high, (long)low, (long)high, (long)low);
return;
}
if (GET_CODE (x) == CONST)
{
base = XEXP (XEXP (x, 0), 0);
offset = INTVAL (XEXP (XEXP (x, 0), 1));
}
if (GET_CODE (base) == SYMBOL_REF)
name = XSTR (base, 0);
else if (GET_CODE (base) == LABEL_REF)
ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
else if (GET_CODE (base) == CODE_LABEL)
ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
else
abort ();
STRIP_NAME_ENCODING (real_name, name);
if (TARGET_MINIMAL_TOC)
fputs ("\tDC.L\t", file);
else
{
fprintf (file, "\tTC\t%s", real_name);
if (offset < 0)
fprintf (file, "__Offs__N%d", - offset);
else if (offset)
fprintf (file, "__Offs__P%d", offset);
fputs ("[TC],", file);
}
if (!strncmp ("_vt.", name, 4))
{
RS6000_OUTPUT_BASENAME (file, name);
if (offset < 0)
fprintf (file, "%d", offset);
else if (offset > 0)
fprintf (file, "+%d", offset);
}
else
output_addr_const (file, x);
putc ('\n', file);
}