--- gcc/config/m88k/m88k.c 2018/04/24 18:13:59 1.1.1.2 +++ gcc/config/m88k/m88k.c 2018/04/24 18:27:44 1.1.1.4 @@ -1,8 +1,7 @@ /* Subroutines for insn-output.c for Motorola 88000. - Copyright (C) 1988, 1989, 1990, 1991 Free Software Foundation, Inc. + Copyright (C) 1988, 92, 93, 94, 1995 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@mcc.com) - Enhanced by Michael Meissner (meissner@osf.org) - Version 2 port by Tom Wood (Tom_Wood@NeXT.com) + Currently maintained by (gcc@dg-rtp.dg.com) This file is part of GNU CC. @@ -18,7 +17,8 @@ GNU General Public License for more deta You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #include #include @@ -47,27 +47,26 @@ extern char *ctime (); extern int flag_traditional; extern FILE *asm_out_file; -static char out_sccs_id[] = "@(#)m88k.c 2.3.3.2 12/16/92 08:26:06"; -static char tm_sccs_id [] = TM_SCCS_ID; +static char out_rcs_id[] = "$What: <@(#) m88k.c,v 1.8> $"; +static char tm_rcs_id [] = TM_RCS_ID; char *m88k_pound_sign = ""; /* Either # for SVR4 or empty for SVR3 */ char *m88k_short_data; char *m88k_version; char m88k_volatile_code; -int m88k_gp_threshold; +unsigned m88k_gp_threshold = 0; int m88k_prologue_done = 0; /* Ln directives can now be emitted */ int m88k_function_number = 0; /* Counter unique to each function */ int m88k_fp_offset = 0; /* offset of frame pointer if used */ int m88k_stack_size = 0; /* size of allocated stack (including frame) */ int m88k_case_index; -int m88k_version_0300; /* Version is at least 03.00 */ rtx m88k_compare_reg; /* cmp output pseudo register */ rtx m88k_compare_op0; /* cmpsi operand 0 */ rtx m88k_compare_op1; /* cmpsi operand 1 */ -enum attr_cpu m88k_cpu; /* target cpu */ +enum processor_type m88k_cpu; /* target cpu */ /* Determine what instructions are needed to manufacture the integer VALUE in the given MODE. */ @@ -225,6 +224,10 @@ emit_move_sequence (operands, mode, scra register rtx operand0 = operands[0]; register rtx operand1 = operands[1]; + if (CONSTANT_P (operand1) && flag_pic + && pic_address_needs_scratch (operand1)) + operands[1] = operand1 = legitimize_address (1, operand1, 0, 0); + /* Handle most common case first: storing into a register. */ if (register_operand (operand0, mode)) { @@ -314,10 +317,16 @@ legitimize_address (pic, orig, reg, scra temp = ((reload_in_progress || reload_completed) ? reg : gen_reg_rtx (Pmode)); - emit_insn (gen_rtx (SET, VOIDmode, - temp, gen_rtx (HIGH, SImode, addr))); - emit_insn (gen_rtx (SET, VOIDmode, - temp, gen_rtx (LO_SUM, SImode, temp, addr))); + emit_insn (gen_rtx (SET, VOIDmode, temp, + gen_rtx (HIGH, SImode, + gen_rtx (UNSPEC, SImode, + gen_rtvec (1, addr), + 0)))); + emit_insn (gen_rtx (SET, VOIDmode, temp, + gen_rtx (LO_SUM, SImode, temp, + gen_rtx (UNSPEC, SImode, + gen_rtvec (1, addr), + 0)))); addr = temp; } new = gen_rtx (MEM, Pmode, @@ -356,7 +365,7 @@ legitimize_address (pic, orig, reg, scra if (GET_CODE (addr) == CONST_INT) { - if (SMALL_INT (addr)) + if (ADD_INT (addr)) return plus_constant_for_output (base, INTVAL (addr)); else if (! reload_in_progress && ! reload_completed) addr = force_reg (Pmode, addr); @@ -491,9 +500,9 @@ expand_block_move (dest_mem, src_mem, op int bytes = (constp ? INTVAL (operands[2]) : 0); int target = (int) m88k_cpu; - assert (CPU_M88100 == 0); - assert (CPU_M88110 == 1); - assert (CPU_M88000 == 2); + assert (PROCESSOR_M88100 == 0); + assert (PROCESSOR_M88110 == 1); + assert (PROCESSOR_M88000 == 2); if (constp && bytes <= 0) return; @@ -590,7 +599,7 @@ block_move_loop (dest, dest_mem, src, sr offset_rtx)); RTX_UNCHANGING_P (value_rtx) = RTX_UNCHANGING_P (src_mem); MEM_VOLATILE_P (value_rtx) = MEM_VOLATILE_P (src_mem); - MEM_IN_STRUCT_P (value_rtx) = 1; + MEM_IN_STRUCT_P (value_rtx) = MEM_IN_STRUCT_P (src_mem); emit_insn (gen_call_movstrsi_loop (gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (entry_name)), @@ -647,7 +656,7 @@ block_move_no_loop (dest, dest_mem, src, offset_rtx)); RTX_UNCHANGING_P (value_rtx) = RTX_UNCHANGING_P (src_mem); MEM_VOLATILE_P (value_rtx) = MEM_VOLATILE_P (src_mem); - MEM_IN_STRUCT_P (value_rtx) = 1; + MEM_IN_STRUCT_P (value_rtx) = MEM_IN_STRUCT_P (src_mem); value_reg = ((((most - (size - remainder)) / align) & 1) == 0 ? (align == 8 ? 6 : 5) : 4); @@ -720,7 +729,7 @@ block_move_sequence (dest, dest_mem, src gen_rtx (CONST_INT, SImode, offset_ld))); RTX_UNCHANGING_P (srcp) = RTX_UNCHANGING_P (src_mem); MEM_VOLATILE_P (srcp) = MEM_VOLATILE_P (src_mem); - MEM_IN_STRUCT_P (srcp) = 1; + MEM_IN_STRUCT_P (srcp) = MEM_IN_STRUCT_P (src_mem); emit_insn (gen_rtx (SET, VOIDmode, temp[next], srcp)); offset_ld += amount[next]; active[next] = TRUE; @@ -735,7 +744,7 @@ block_move_sequence (dest, dest_mem, src gen_rtx (CONST_INT, SImode, offset_st))); RTX_UNCHANGING_P (dstp) = RTX_UNCHANGING_P (dest_mem); MEM_VOLATILE_P (dstp) = MEM_VOLATILE_P (dest_mem); - MEM_IN_STRUCT_P (dstp) = 1; + MEM_IN_STRUCT_P (dstp) = MEM_IN_STRUCT_P (dest_mem); emit_insn (gen_rtx (SET, VOIDmode, dstp, temp[phase])); offset_st += amount[phase]; } @@ -1266,7 +1275,7 @@ arith64_operand (op, mode) { return (register_operand (op, mode) || GET_CODE (op) == CONST_INT - || (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DImode)); + || (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)); } int @@ -1341,7 +1350,7 @@ real_or_0_operand (op, mode) && op == CONST0_RTX (mode))); } -/* Return true if OP is valid to use in the context of logic aritmethic +/* Return true if OP is valid to use in the context of logic arithmetic on condition codes. */ int @@ -1553,7 +1562,7 @@ output_file_start (file, f_options, f_le ASM_FIRST_LINE (file); if (TARGET_88110 - && m88k_version != 0 && strcmp (m88k_version, "04.00") >= 0) + && TARGET_SVR4) fprintf (file, "\t%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 @@ -2021,7 +2030,7 @@ m88k_end_epilogue (stream, size) PUT_OCS_FUNCTION_END (stream); /* If the last insn isn't a BARRIER, we must write a return insn. This - should only happen if the function has no prologe and no body. */ + should only happen if the function has no prologue and no body. */ if (GET_CODE (insn) == NOTE) insn = prev_nonnote_insn (insn); if (insn == 0 || GET_CODE (insn) != BARRIER) @@ -2608,7 +2617,7 @@ m88k_builtin_saveregs (arglist) change_address (addr, Pmode, plus_constant (XEXP (addr, 0), fixed * UNITS_PER_WORD)), - 8 - fixed, (8 - fixed) * UNITS_PER_WORD); + 8 - fixed, UNITS_PER_WORD * (8 - fixed)); /* Return the address of the va_list constructor, but don't put it in a register. This fails when not optimizing and produces worse code when @@ -2640,17 +2649,15 @@ emit_bcnd (op, label) rtx label; { if (m88k_compare_op1 == const0_rtx) - emit_jump_insn (optimize - ? gen_bxx (emit_test (op, VOIDmode), label) - : gen_bcnd (gen_rtx (op, VOIDmode, - m88k_compare_op0, const0_rtx), - label)); + emit_jump_insn( gen_bcnd ( + gen_rtx (op, VOIDmode,m88k_compare_op0, const0_rtx), + label)); else if (m88k_compare_op0 == const0_rtx) - emit_jump_insn (optimize - ? gen_bxx (emit_test (op, VOIDmode), label) - : gen_bcnd (gen_rtx (swap_condition (op), VOIDmode, - m88k_compare_op1, const0_rtx), - label)); + emit_jump_insn( gen_bcnd( + gen_rtx( + swap_condition (op), + VOIDmode, m88k_compare_op1, const0_rtx), + label)); else if (op != EQ && op != NE) emit_jump_insn (gen_bxx (emit_test (op, VOIDmode), label)); else @@ -2939,6 +2946,11 @@ print_operand (file, x, code) output_address (x); else if (xc == MEM) output_address (XEXP (x, 0)); + else if (flag_pic && xc == UNSPEC) + { + output_addr_const (file, XVECEXP (x, 0, 0)); + fputs ("#got_rel", file); + } else if (xc == CONST_DOUBLE) output_operand_lossage ("operand is const_double"); else @@ -3049,12 +3061,6 @@ print_operand_address (file, addr) reg_names[0], reg_names[REGNO (XEXP (addr, 0))]); break; - case LSHIFT: - fprintf (file, "%s,%shi16(", reg_names[0], m88k_pound_sign); - output_addr_const (file, XEXP (addr, 0)); - fputc (')', file); - break; - case CONST_INT: fprintf (file, "%s,%d", reg_names[0], INTVAL (addr)); break; @@ -3071,3 +3077,49 @@ print_operand_address (file, addr) output_addr_const (file, addr); } } + +/* Return true if X is an address which needs a temporary register when + reloaded while generating PIC code. */ + +int +pic_address_needs_scratch (x) + rtx x; +{ + /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ + if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && ! ADD_INT (XEXP (XEXP (x, 0), 1))) + return 1; + + return 0; +} + +/* Returns 1 if OP is either a symbol reference or a sum of a symbol + reference and a constant. */ + +int +symbolic_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + switch (GET_CODE (op)) + { + case SYMBOL_REF: + case LABEL_REF: + return 1; + + case CONST: + op = XEXP (op, 0); + return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF + || GET_CODE (XEXP (op, 0)) == LABEL_REF) + && GET_CODE (XEXP (op, 1)) == CONST_INT); + + /* ??? This clause seems to be irrelevant. */ + case CONST_DOUBLE: + return GET_MODE (op) == mode; + + default: + return 0; + } +}