--- gcc/config/a29k/a29k.c 2018/04/24 18:10:25 1.1.1.1 +++ gcc/config/a29k/a29k.c 2018/04/24 18:21:48 1.1.1.3 @@ -1,5 +1,5 @@ /* Subroutines used for code generation on AMD Am29000. - Copyright (C) 1987, 1988, 1990, 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 90, 91, 92, 93, 1994 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) This file is part of GNU CC. @@ -233,7 +233,7 @@ accum_reg_operand (op, mode) enum machine_mode mode; { return (GET_CODE (op) == REG - && REGNO (op) >= R_ACC (0) && REGNO (op) <= R_ACC (3)); + && REGNO (op) >= R_ACU (0) && REGNO (op) <= R_ACU (3)); } /* Returns 1 if OP is a normal data register. */ @@ -259,7 +259,8 @@ gpc_reg_operand (op, mode) else return 0; - return regno >= FIRST_PSEUDO_REGISTER || regno < R_BP; + return (regno >= FIRST_PSEUDO_REGISTER || regno < R_BP + || (regno >= R_KR (0) && regno <= R_KR (31))); } /* Returns 1 if OP is either an 8-bit constant integer or a general register. @@ -281,6 +282,22 @@ srcb_operand (op, mode) return gpc_reg_operand (op, mode); } +int +cmplsrcb_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + if (GET_CODE (op) == CONST_INT + && (mode == QImode + || (INTVAL (op) & 0xffffff00) == 0xffffff00)) + return 1; + + if (GET_MODE (op) != mode && mode != VOIDmode) + return 0; + + return gpc_reg_operand (op, mode); +} + /* Return 1 if OP is either an immediate or a general register. This is used for the input operand of mtsr/mtrsim. */ @@ -332,7 +349,9 @@ call_operand (op, mode) { case SYMBOL_REF: return (TARGET_SMALL_MEMORY - || ! strcmp (XSTR (op, 0), current_function_name)); + || (! TARGET_LARGE_MEMORY + && ((GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_FLAG (op)) + || ! strcmp (XSTR (op, 0), current_function_name)))); case CONST_INT: return (unsigned HOST_WIDE_INT) INTVAL (op) < 0x40000; @@ -739,7 +758,10 @@ secondary_reload_class (class, mode, in) /* Otherwise, we can place anything into GENERAL_REGS and can put GENERAL_REGS into anything. */ - if (class == GENERAL_REGS || (regno != -1 && regno < R_BP)) + if (class == GENERAL_REGS + || (regno != -1 + && (regno < R_BP + || (regno >= R_KR (0) && regno <= R_KR (31))))) return NO_REGS; /* We can place 16-bit constants into a special register. */ @@ -769,9 +791,14 @@ incoming_reg (start, count) { int i; + /* We only use 16 argument registers, so truncate at the end of the + area. */ + if (start + count > 16) + count = 16 - start; + if (! TARGET_NO_REUSE_ARGS) /* Mark all the used registers as not fixed and saved over calls. */ - for (i = R_AR (start); i < R_AR (16) && i < R_AR (start + count); i++) + for (i = R_AR (start); i < R_AR (start + count); i++) { fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 0; CLEAR_HARD_REG_BIT (fixed_reg_set, i); @@ -791,6 +818,33 @@ incoming_reg (start, count) return R_AR (start); } +/* Add CLOBBERs to CALL_INSN_FUNCTION_USAGE chain of INSN indicating + that LR2 up to, but not including, OP are clobbered. If OP is + zero, indicate all parameter registers are clobbered. */ + +void +a29k_clobbers_to (insn, op) + rtx insn; + rtx op; +{ + int i; + int high_regno; + + if (op == 0) + high_regno = R_LR (18); + else if (GET_CODE (op) != REG || REGNO (op) < R_LR (0) + || REGNO (op) > R_LR (18)) + abort (); + else + high_regno = REGNO (op); + + for (i = R_LR (2); i < high_regno; i++) + CALL_INSN_FUNCTION_USAGE (insn) + = gen_rtx (EXPR_LIST, VOIDmode, + gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, i)), + CALL_INSN_FUNCTION_USAGE (insn)); +} + /* These routines are used in finding insns to fill delay slots in the epilogue. */ @@ -1020,7 +1074,16 @@ print_operand (file, x, code) output_addr_const (file, x); if (dbr_sequence_length () == 0) { - if (GET_CODE (x) == SYMBOL_REF + /* If this doesn't have its delay slot filled, see if we need to + put the last insn of the prolog in it. If not, see if this is + a recursive call. If so, we can put the first insn of its + prolog in the delay slot. Otherwise, write a nop. */ + if (a29k_last_prologue_insn) + { + fprintf (file, "\n\t%s", a29k_last_prologue_insn); + a29k_last_prologue_insn = 0; + } + else if (GET_CODE (x) == SYMBOL_REF && ! strcmp (XSTR (x, 0), current_function_name)) fprintf (file, "+4\n\t%s,%d", a29k_regstack_size >= 64 ? "const gr121" : "sub gr1,gr1", @@ -1184,6 +1247,16 @@ output_prolog (file, size) a29k_debug_reg_map[R_AR (i)] = R_LR (a29k_regstack_size + i + 2); } + /* If using kernel register map, swap numbers for kernel and user + registers. */ + if (TARGET_KERNEL_REGISTERS) + for (i = 0; i < 32; i++) + { + int tem = a29k_debug_reg_map[i]; + a29k_debug_reg_map[i] = a29k_debug_reg_map[R_KR (i)]; + a29k_debug_reg_map[R_KR (i)] = tem; + } + /* Compute memory stack size. Add in number of bytes that the we should push and pretend the caller did and the size of outgoing arguments. Then round to a doubleword boundary. */