X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fm88k%2Fm88k.c;h=c1c2146603e90bdea5dca6d2ca76f35a4c6f4d4b;hb=a1657b9503b2bb2757a1a44de16747af6a14e10a;hp=555d49f23a530d891caf5840b09ebd477d8356f4;hpb=63c906ceb9803a4ce5079a3037e86315b5a874b7;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/m88k/m88k.c b/gcc/config/m88k/m88k.c index 555d49f23a5..c1c2146603e 100644 --- a/gcc/config/m88k/m88k.c +++ b/gcc/config/m88k/m88k.c @@ -1,6 +1,6 @@ /* Subroutines for insn-output.c for Motorola 88000. - Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 - Free Software Foundation, Inc. + Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@mcc.com) Currently maintained by (gcc@dg-rtp.dg.com) @@ -29,17 +29,19 @@ Boston, MA 02111-1307, USA. */ #include "real.h" #include "insn-config.h" #include "conditions.h" -#include "insn-flags.h" #include "output.h" #include "insn-attr.h" #include "tree.h" #include "function.h" -#include "c-tree.h" #include "expr.h" +#include "libfuncs.h" +#include "c-tree.h" #include "flags.h" #include "recog.h" #include "toplev.h" #include "tm_p.h" +#include "target.h" +#include "target-def.h" extern int flag_traditional; extern FILE *asm_out_file; @@ -61,6 +63,43 @@ rtx m88k_compare_op0; /* cmpsi operand 0 */ rtx m88k_compare_op1; /* cmpsi operand 1 */ enum processor_type m88k_cpu; /* target cpu */ + +static void m88k_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT)); +static void m88k_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT)); +static void m88k_output_function_end_prologue PARAMS ((FILE *)); +static void m88k_output_function_begin_epilogue PARAMS ((FILE *)); +#if defined (CTOR_LIST_BEGIN) && !defined (OBJECT_FORMAT_ELF) +static void m88k_svr3_asm_out_constructor PARAMS ((rtx, int)); +static void m88k_svr3_asm_out_destructor PARAMS ((rtx, int)); +#endif + +static int m88k_adjust_cost PARAMS ((rtx, rtx, rtx, int)); + +/* Initialize the GCC target structure. */ +#undef TARGET_ASM_BYTE_OP +#define TARGET_ASM_BYTE_OP "\tbyte\t" +#undef TARGET_ASM_ALIGNED_HI_OP +#define TARGET_ASM_ALIGNED_HI_OP "\thalf\t" +#undef TARGET_ASM_ALIGNED_SI_OP +#define TARGET_ASM_ALIGNED_SI_OP "\tword\t" +#undef TARGET_ASM_UNALIGNED_HI_OP +#define TARGET_ASM_UNALIGNED_HI_OP "\tuahalf\t" +#undef TARGET_ASM_UNALIGNED_SI_OP +#define TARGET_ASM_UNALIGNED_SI_OP "\tuaword\t" + +#undef TARGET_ASM_FUNCTION_PROLOGUE +#define TARGET_ASM_FUNCTION_PROLOGUE m88k_output_function_prologue +#undef TARGET_ASM_FUNCTION_END_PROLOGUE +#define TARGET_ASM_FUNCTION_END_PROLOGUE m88k_output_function_end_prologue +#undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE +#define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE m88k_output_function_begin_epilogue +#undef TARGET_ASM_FUNCTION_EPILOGUE +#define TARGET_ASM_FUNCTION_EPILOGUE m88k_output_function_epilogue + +#undef TARGET_SCHED_ADJUST_COST +#define TARGET_SCHED_ADJUST_COST m88k_adjust_cost + +struct gcc_target targetm = TARGET_INITIALIZER; /* Determine what instructions are needed to manufacture the integer VALUE in the given MODE. */ @@ -363,7 +402,7 @@ legitimize_address (pic, orig, reg, scratch) if (GET_CODE (addr) == CONST_INT) { if (ADD_INT (addr)) - return plus_constant_for_output (base, INTVAL (addr)); + return plus_constant (base, INTVAL (addr)); else if (! reload_in_progress && ! reload_completed) addr = force_reg (Pmode, addr); /* We can't create any new registers during reload, so use the @@ -457,15 +496,15 @@ legitimize_address (pic, orig, reg, scratch) #define MOVSTR_SI_LIMIT_88110 72 #define MOVSTR_DI_LIMIT_88110 72 -static enum machine_mode mode_from_align[] = +static const enum machine_mode mode_from_align[] = {VOIDmode, QImode, HImode, VOIDmode, SImode, VOIDmode, VOIDmode, VOIDmode, DImode}; -static int max_from_align[] = {0, MOVSTR_QI, MOVSTR_HI, 0, MOVSTR_SI, - 0, 0, 0, MOVSTR_DI}; -static int all_from_align[] = {0, MOVSTR_QI, MOVSTR_ODD_HI, 0, MOVSTR_ODD_SI, - 0, 0, 0, MOVSTR_ODD_DI}; +static const int max_from_align[] = {0, MOVSTR_QI, MOVSTR_HI, 0, MOVSTR_SI, + 0, 0, 0, MOVSTR_DI}; +static const int all_from_align[] = {0, MOVSTR_QI, MOVSTR_ODD_HI, 0, + MOVSTR_ODD_SI, 0, 0, 0, MOVSTR_ODD_DI}; -static int best_from_align[3][9] = { +static const int best_from_align[3][9] = { {0, MOVSTR_QI_LIMIT_88100, MOVSTR_HI_LIMIT_88100, 0, MOVSTR_SI_LIMIT_88100, 0, 0, 0, MOVSTR_DI_LIMIT_88100}, {0, MOVSTR_QI_LIMIT_88110, MOVSTR_HI_LIMIT_88110, 0, MOVSTR_SI_LIMIT_88110, @@ -853,12 +892,12 @@ output_call (operands, addr) rtx low, high; const char *last; rtx dest = XEXP (SET_SRC (PATTERN (jump)), 0); - int delta = 4 * (insn_addresses[INSN_UID (dest)] - - insn_addresses[INSN_UID (seq_insn)] + int delta = 4 * (INSN_ADDRESSES (INSN_UID (dest)) + - INSN_ADDRESSES (INSN_UID (seq_insn)) - 2); #if (MONITOR_GCC & 0x2) /* How often do long branches happen? */ if ((unsigned) (delta + 0x8000) >= 0x10000) - warning ("Internal gcc monitor: short-branch(%x)", delta); + warning ("internal gcc monitor: short-branch(%x)", delta); #endif /* Delete the jump. */ @@ -955,7 +994,7 @@ output_short_branch_defs (stream) ASM_GENERATE_INTERNAL_LABEL (low, "L", CODE_LABEL_NUMBER (XEXP (sb_low, 0))); /* This will change as the assembler requirements become known. */ - fprintf (stream, "\t%s\t %s,%s-%s\n", + fprintf (stream, "%s%s,%s-%s\n", SET_ASM_OP, &name[1], &high[1], &low[1]); } if (sb_name || sb_high || sb_low) @@ -1039,8 +1078,8 @@ mostly_false_jump (jump_insn, condition) insnj = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0))); else insnj = jump_insn; - if (insn_addresses[INSN_UID (insnj)] - > insn_addresses[INSN_UID (target_label)]) + if (INSN_ADDRESSES (INSN_UID (insnj)) + > INSN_ADDRESSES (INSN_UID (target_label))) return 0; /* EQ tests are usually false and NE tests are usually true. Also, @@ -1153,7 +1192,7 @@ legitimize_operand (op, mode) if (GET_CODE (op) == CONST_DOUBLE) { - bcopy (&CONST_DOUBLE_LOW (op), &u.r, sizeof u); + memcpy (&u.r, &CONST_DOUBLE_LOW (op), sizeof u); if (u.d.exponent != 0x7ff /* NaN */ && u.d.mantissa2 == 0 /* Mantissa fits */ && (u.s.exponent1 == 0x8 || u.s.exponent1 == 0x7) /* Exponent fits */ @@ -1475,16 +1514,16 @@ pc_or_label_ref (op, mode) /* This definition must match lang_independent_options from toplev.c. */ struct m88k_lang_independent_options { - const char *string; - int *variable; - int on_value; - const char *description; + const char *const string; + int *const variable; + const int on_value; + const char *const description; }; static void output_options PARAMS ((FILE *, - struct m88k_lang_independent_options *, + const struct m88k_lang_independent_options *, int, - struct m88k_lang_independent_options *, + const struct m88k_lang_independent_options *, int, int, int, const char *, const char *, const char *)); @@ -1506,14 +1545,15 @@ output_option (file, sep, type, name, indent, pos, max) return pos + fprintf (file, "%s%s%s", sep, type, name); } -static struct { const char *name; int value; } m_options[] = TARGET_SWITCHES; +static const struct { const char *const name; const int value; } m_options[] = +TARGET_SWITCHES; static void output_options (file, f_options, f_len, W_options, W_len, pos, max, sep, indent, term) FILE *file; - struct m88k_lang_independent_options *f_options; - struct m88k_lang_independent_options *W_options; + const struct m88k_lang_independent_options *f_options; + const struct m88k_lang_independent_options *W_options; int f_len, W_len; int pos; int max; @@ -1531,9 +1571,6 @@ output_options (file, f_options, f_len, W_options, W_len, pos = output_option (file, sep, "-traditional", "", indent, pos, max); if (profile_flag) pos = output_option (file, sep, "-p", "", indent, pos, max); - if (profile_block_flag) - pos = output_option (file, sep, "-a", "", indent, pos, max); - for (j = 0; j < f_len; j++) if (*f_options[j].variable == f_options[j].on_value) pos = output_option (file, sep, "-f", f_options[j].string, @@ -1544,7 +1581,7 @@ output_options (file, f_options, f_len, W_options, W_len, pos = output_option (file, sep, "-W", W_options[j].string, indent, pos, max); - for (j = 0; j < (long) (sizeof m_options / sizeof m_options[0]); j++) + for (j = 0; j < (long) ARRAY_SIZE (m_options); j++) if (m_options[j].name[0] != '\0' && m_options[j].value > 0 && ((m_options[j].value & target_flags) @@ -1562,8 +1599,8 @@ output_options (file, f_options, f_len, W_options, W_len, void output_file_start (file, f_options, f_len, W_options, W_len) FILE *file; - struct m88k_lang_independent_options *f_options; - struct m88k_lang_independent_options *W_options; + const struct m88k_lang_independent_options *f_options; + const struct m88k_lang_independent_options *W_options; int f_len, W_len; { register int pos; @@ -1571,11 +1608,10 @@ output_file_start (file, f_options, f_len, W_options, W_len) ASM_FIRST_LINE (file); if (TARGET_88110 && TARGET_SVR4) - fprintf (file, "\t%s\n", REQUIRES_88110_ASM_OP); + fprintf (file, "%s\n", REQUIRES_88110_ASM_OP); output_file_directive (file, main_input_filename); - /* Switch to the data section so that the coffsem symbol and the - gcc2_compiled. symbol aren't in the text section. */ - data_section (); + /* Switch to the data section so that the coffsem symbol + isn't in the text section. */ ASM_COFFSEM (file); if (TARGET_IDENTIFY_REVISION) @@ -1583,7 +1619,7 @@ output_file_start (file, f_options, f_len, W_options, W_len) char indent[256]; time_t now = time ((time_t *)0); - sprintf (indent, "]\"\n\t%s\t \"@(#)%s [", IDENT_ASM_OP, main_input_filename); + sprintf (indent, "]\"\n%s\"@(#)%s [", IDENT_ASM_OP, main_input_filename); fprintf (file, indent+3); pos = fprintf (file, "gcc %s, %.24s,", version_string, ctime (&now)); #if 1 @@ -1607,7 +1643,7 @@ output_ascii (file, opcode, max, p, size) FILE *file; const char *opcode; int max; - const unsigned char *p; + const char *p; int size; { int i; @@ -1615,14 +1651,14 @@ output_ascii (file, opcode, max, p, size) register int num = 0; - fprintf (file, "\t%s\t \"", opcode); + fprintf (file, "%s\"", opcode); for (i = 0; i < size; i++) { - register int c = p[i]; + register int c = (unsigned char) p[i]; if (num > max) { - fprintf (file, "\"\n\t%s\t \"", opcode); + fprintf (file, "\"\n%s\"", opcode); num = 0; } @@ -1634,9 +1670,9 @@ output_ascii (file, opcode, max, p, size) num += 2; in_escape = 0; } - else if (in_escape && c >= '0' && c <= '9') + else if (in_escape && ISDIGIT (c)) { - /* If a digit follows an octal-escape, the Vax assembler fails + /* If a digit follows an octal-escape, the VAX assembler fails to stop reading the escape after three digits. Continue to output the values as an octal-escape until a non-digit is found. */ @@ -1777,7 +1813,8 @@ static int prologue_marked; (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1)) /* Establish the position of the FP relative to the SP. This is done - either during FUNCTION_PROLOGUE or by INITIAL_ELIMINATION_OFFSET. */ + either during output_function_prologue() or by + INITIAL_ELIMINATION_OFFSET. */ void m88k_layout_frame () @@ -1786,12 +1823,12 @@ m88k_layout_frame () frame_laid_out++; - bzero ((char *) &save_regs[0], sizeof (save_regs)); + memset ((char *) &save_regs[0], 0, sizeof (save_regs)); sp_size = nregs = nxregs = 0; frame_size = get_frame_size (); /* Since profiling requires a call, make sure r1 is saved. */ - if (profile_flag || profile_block_flag) + if (current_function_profile) save_regs[1] = 1; /* If we are producing debug information, store r1 and r30 where the @@ -1873,15 +1910,10 @@ m88k_layout_frame () int need = ((m88k_stack_size ? STACK_UNIT_BOUNDARY - STARTING_FRAME_OFFSET : 0) - (frame_size % STACK_UNIT_BOUNDARY)); - if (need) - { - if (need < 0) - need += STACK_UNIT_BOUNDARY; - (void) assign_stack_local (BLKmode, need, BITS_PER_UNIT); - frame_size = get_frame_size (); - } + if (need < 0) + need += STACK_UNIT_BOUNDARY; m88k_stack_size - = ROUND_CALL_BLOCK_SIZE (m88k_stack_size + frame_size + = ROUND_CALL_BLOCK_SIZE (m88k_stack_size + frame_size + need + current_function_pretend_args_size); } } @@ -1931,10 +1963,10 @@ uses_arg_area_p () return 0; } -void -m88k_begin_prologue (stream, size) +static void +m88k_output_function_prologue (stream, size) FILE *stream ATTRIBUTE_UNUSED; - int size ATTRIBUTE_UNUSED; + HOST_WIDE_INT size ATTRIBUTE_UNUSED; { if (TARGET_OMIT_LEAF_FRAME_POINTER && ! quiet_flag && leaf_function_p ()) fprintf (stderr, "$"); @@ -1942,8 +1974,8 @@ m88k_begin_prologue (stream, size) m88k_prologue_done = 1; /* it's ok now to put out ln directives */ } -void -m88k_end_prologue (stream) +static void +m88k_output_function_end_prologue (stream) FILE *stream; { if (TARGET_OCS_DEBUG_INFO && !prologue_marked) @@ -1993,7 +2025,7 @@ m88k_expand_prologue () { rtx return_reg = gen_rtx_REG (SImode, 1); rtx label = gen_label_rtx (); - rtx temp_reg; + rtx temp_reg = NULL_RTX; if (! save_regs[1]) { @@ -2007,20 +2039,20 @@ m88k_expand_prologue () if (! save_regs[1]) emit_move_insn (return_reg, temp_reg); } - if (profile_flag || profile_block_flag) + if (current_function_profile) emit_insn (gen_blockage ()); } /* This function generates the assembly code for function exit, - on machines that need it. Args are same as for FUNCTION_PROLOGUE. + on machines that need it. The function epilogue should not depend on the current stack pointer! It should use the frame pointer only, if there is a frame pointer. This is mandatory because of alloca; we also take advantage of it to omit stack adjustments before returning. */ -void -m88k_begin_epilogue (stream) +static void +m88k_output_function_begin_epilogue (stream) FILE *stream; { if (TARGET_OCS_DEBUG_INFO && !epilogue_marked && prologue_marked) @@ -2030,10 +2062,10 @@ m88k_begin_epilogue (stream) epilogue_marked = 1; } -void -m88k_end_epilogue (stream, size) +static void +m88k_output_function_epilogue (stream, size) FILE *stream; - int size ATTRIBUTE_UNUSED; + HOST_WIDE_INT size ATTRIBUTE_UNUSED; { rtx insn = get_last_insn (); @@ -2265,7 +2297,7 @@ m88k_debugger_offset (reg, offset) #if (MONITOR_GCC & 0x10) /* Watch for suspicious symbolic locations. */ if (! (GET_CODE (reg) == REG && REGNO (reg) >= FIRST_PSEUDO_REGISTER)) - warning ("Internal gcc error: Can't express symbolic location"); + warning ("internal gcc error: Can't express symbolic location"); #endif return 0; } @@ -2343,7 +2375,8 @@ output_tdesc (file, offset) tdesc_section (); - fprintf (file, "\t%s\t %d,%d", INT_ASM_OP, /* 8:0,22:(20 or 16),2:2 */ + /* 8:0,22:(20 or 16),2:2 */ + fprintf (file, "%s%d,%d", integer_asm_op (4, TRUE), (((xmask != 0) ? 20 : 16) << 2) | 2, flag_pic ? 2 : 1); @@ -2384,7 +2417,7 @@ output_function_profiler (file, labelno, name, savep) { char label[256]; char dbi[256]; - const char *temp = (savep ? reg_names[2] : reg_names[10]); + const char *const temp = (savep ? reg_names[2] : reg_names[10]); /* Remember to update FUNCTION_PROFILER_LENGTH. */ @@ -2583,7 +2616,7 @@ m88k_function_arg (args_so_far, mode, type, named) struct rtx_def * m88k_builtin_saveregs () { - rtx addr, dest; + rtx addr; tree fntype = TREE_TYPE (current_function_decl); int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) @@ -2594,37 +2627,22 @@ m88k_builtin_saveregs () variable_args_p = 1; fixed = 0; - if (CONSTANT_P (current_function_arg_offset_rtx)) - { - fixed = (XINT (current_function_arg_offset_rtx, 0) - + argadj) / UNITS_PER_WORD; - } + if (GET_CODE (current_function_arg_offset_rtx) == CONST_INT) + fixed = ((INTVAL (current_function_arg_offset_rtx) + argadj) + / UNITS_PER_WORD); /* Allocate the register space, and store it as the __va_reg member. */ addr = assign_stack_local (BLKmode, 8 * UNITS_PER_WORD, -1); - MEM_ALIAS_SET (addr) = get_varargs_alias_set (); + set_mem_alias_set (addr, get_varargs_alias_set ()); RTX_UNCHANGING_P (addr) = 1; RTX_UNCHANGING_P (XEXP (addr, 0)) = 1; /* Now store the incoming registers. */ if (fixed < 8) - { - dest = change_address (addr, Pmode, - plus_constant (XEXP (addr, 0), - fixed * UNITS_PER_WORD)); - move_block_from_reg (2 + fixed, dest, 8 - fixed, - UNITS_PER_WORD * (8 - fixed)); - - if (current_function_check_memory_usage) - { - emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, - dest, ptr_mode, - GEN_INT (UNITS_PER_WORD * (8 - fixed)), - TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_RW), - TYPE_MODE (integer_type_node)); - } - } + move_block_from_reg (2 + fixed, + adjust_address (addr, Pmode, fixed * UNITS_PER_WORD), + 8 - fixed, + UNITS_PER_WORD * (8 - fixed)); /* Return the address of the save area, but don't put it in a register. This fails when not optimizing and produces worse code @@ -2861,7 +2879,7 @@ print_operand (file, x, code) if (sequencep) { if (code < 'B' || code > 'E') - output_operand_lossage ("%R not followed by %B/C/D/E"); + output_operand_lossage ("%%R not followed by %%B/C/D/E"); if (reversep) xc = reverse_condition (xc); sequencep = 0; @@ -2929,43 +2947,43 @@ print_operand (file, x, code) value >>= 16; case 'x': /* print the lower 16 bits of the integer constant in hex */ if (xc != CONST_INT) - output_operand_lossage ("invalid %x/X value"); + output_operand_lossage ("invalid %%x/X value"); fprintf (file, "0x%x", value & 0xffff); return; case 'H': /* print the low 16 bits of the negated integer constant */ if (xc != CONST_INT) - output_operand_lossage ("invalid %H value"); + output_operand_lossage ("invalid %%H value"); value = -value; case 'h': /* print the register or low 16 bits of the integer constant */ if (xc == REG) goto reg; if (xc != CONST_INT) - output_operand_lossage ("invalid %h value"); + output_operand_lossage ("invalid %%h value"); fprintf (file, "%d", value & 0xffff); return; case 'Q': /* print the low 8 bits of the negated integer constant */ if (xc != CONST_INT) - output_operand_lossage ("invalid %Q value"); + output_operand_lossage ("invalid %%Q value"); value = -value; case 'q': /* print the register or low 8 bits of the integer constant */ if (xc == REG) goto reg; if (xc != CONST_INT) - output_operand_lossage ("invalid %q value"); + output_operand_lossage ("invalid %%q value"); fprintf (file, "%d", value & 0xff); return; case 'w': /* print the integer constant (X == 32 ? 0 : 32 - X) */ if (xc != CONST_INT) - output_operand_lossage ("invalid %o value"); + output_operand_lossage ("invalid %%o value"); fprintf (file, "%d", value == 32 ? 0 : 32 - value); return; case 'p': /* print the logarithm of the integer constant */ if (xc != CONST_INT || (value = exact_log2 (value)) < 0) - output_operand_lossage ("invalid %p value"); + output_operand_lossage ("invalid %%p value"); fprintf (file, "%d", value); return; @@ -2978,12 +2996,12 @@ print_operand (file, x, code) register int top, bottom; if (xc != CONST_INT) - output_operand_lossage ("invalid %s/S value"); + output_operand_lossage ("invalid %%s/S value"); /* All the "one" bits must be contiguous. If so, MASK will be a power of two or zero. */ mask = (uval | (uval - 1)) + 1; if (!(uval && POWER_OF_2_or_0 (mask))) - output_operand_lossage ("invalid %s/S value"); + output_operand_lossage ("invalid %%s/S value"); top = mask ? exact_log2 (mask) : 32; bottom = exact_log2 (uval & ~(uval - 1)); fprintf (file,"%d<%d>", top - bottom, bottom); @@ -2994,7 +3012,7 @@ print_operand (file, x, code) if (xc == LABEL_REF) output_addr_const (file, x); else if (xc != PC) - output_operand_lossage ("invalid %P operand"); + output_operand_lossage ("invalid %%P operand"); return; case 'L': /* print 0 or 1 if operand is label_ref and then... */ @@ -3025,7 +3043,7 @@ print_operand (file, x, code) case LE: fputs ("le0", file); return; case LT: fputs ("lt0", file); return; case GE: fputs ("ge0", file); return; - default: output_operand_lossage ("invalid %B value"); + default: output_operand_lossage ("invalid %%B value"); } case 'C': /* bb0/bb1 branch values for comparisons */ @@ -3042,7 +3060,7 @@ print_operand (file, x, code) case LEU: fputs ("ls", file); return; case LTU: fputs ("lo", file); return; case GEU: fputs ("hs", file); return; - default: output_operand_lossage ("invalid %C value"); + default: output_operand_lossage ("invalid %%C value"); } case 'D': /* bcnd branch values for float comparisons */ @@ -3055,7 +3073,7 @@ print_operand (file, x, code) case LE: fputs ("0xe", file); return; case LT: fputs ("0x4", file); return; case GE: fputs ("0xb", file); return; - default: output_operand_lossage ("invalid %D value"); + default: output_operand_lossage ("invalid %%D value"); } case 'E': /* bcnd branch values for special integers */ @@ -3063,12 +3081,12 @@ print_operand (file, x, code) { case EQ: fputs ("0x8", file); return; case NE: fputs ("0x7", file); return; - default: output_operand_lossage ("invalid %E value"); + default: output_operand_lossage ("invalid %%E value"); } case 'd': /* second register of a two register pair */ if (xc != REG) - output_operand_lossage ("`%d' operand isn't a register"); + output_operand_lossage ("`%%d' operand isn't a register"); fputs (reg_names[REGNO (x) + 1], file); return; @@ -3079,7 +3097,7 @@ print_operand (file, x, code) return; } else if (xc != REG) - output_operand_lossage ("invalid %r value"); + output_operand_lossage ("invalid %%r value"); case 0: name: if (xc == REG) @@ -3271,3 +3289,61 @@ symbolic_operand (op, mode) return 0; } } + +#if defined (CTOR_LIST_BEGIN) && !defined (OBJECT_FORMAT_ELF) +static void +m88k_svr3_asm_out_constructor (symbol, priority) + rtx symbol; + int priority ATTRIBUTE_UNUSED; +{ + const char *name = XSTR (symbol, 0); + + init_section (); + fprintf (asm_out_file, "\tor.u\t r13,r0,hi16("); + assemble_name (asm_out_file, name); + fprintf (asm_out_file, ")\n\tor\t r13,r13,lo16("); + assemble_name (asm_out_file, name); + fprintf (asm_out_file, ")\n\tsubu\t r31,r31,%d\n\tst\t r13,r31,%d\n", + STACK_BOUNDARY / BITS_PER_UNIT, REG_PARM_STACK_SPACE (0)); +} + +static void +m88k_svr3_asm_out_destructor (symbol, priority) + rtx symbol; + int priority ATTRIBUTE_UNUSED; +{ + int i; + + fini_section (); + assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1); + for (i = 1; i < 4; i++) + assemble_integer (constm1_rtx, UNITS_PER_WORD, BITS_PER_WORD, 1); +} +#endif /* INIT_SECTION_ASM_OP && ! OBJECT_FORMAT_ELF */ + +/* Adjust the cost of INSN based on the relationship between INSN that + is dependent on DEP_INSN through the dependence LINK. The default + is to make no adjustment to COST. + + On the m88k, ignore the cost of anti- and output-dependencies. On + the m88100, a store can issue two cycles before the value (not the + address) has finished computing. */ + +static int +m88k_adjust_cost (insn, link, dep, cost) + rtx insn; + rtx link; + rtx dep; + int cost; +{ + if (REG_NOTE_KIND (link) != 0) + return 0; /* Anti or output dependence. */ + + if (! TARGET_88100 + && recog_memoized (insn) >= 0 + && get_attr_type (insn) == TYPE_STORE + && SET_SRC (PATTERN (insn)) == SET_DEST (PATTERN (dep))) + return cost - 4; /* 88110 store reservation station. */ + + return cost; +}