--- gcc/config/a29k/a29k.c 2018/04/24 18:15:31 1.1.1.2 +++ gcc/config/a29k/a29k.c 2018/04/24 18:29:19 1.1.1.4 @@ -1,5 +1,5 @@ /* Subroutines used for code generation on AMD Am29000. - Copyright (C) 1987, 88, 90, 91, 92, 1993 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 90-94, 1995 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@nyu.edu) This file is part of GNU CC. @@ -16,7 +16,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 "config.h" @@ -220,7 +221,7 @@ spec_reg_operand (op, mode) return REGNO (op) >= R_BP && REGNO (op) <= R_CR; case MODE_INT: return REGNO (op) >= R_Q && REGNO (op) <= R_EXO; - detault: + default: return 0; } } @@ -233,7 +234,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. */ @@ -282,6 +283,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. */ @@ -790,8 +807,13 @@ incoming_reg (start, count) CLEAR_HARD_REG_BIT (call_fixed_reg_set, i); } - /* Shorten the maximum size of the frame. */ - for (i = R_AR (0) - start - count; i < R_AR (0) - start; i++) + /* Shorten the maximum size of the frame. + Remember that R_AR(-1,-2) are place holders for the caller's lr0,lr1. + Make sure to keep the frame rounded to an even boundary. Rounding up + to an 8 byte boundary will use a slot. Otherwise a frame with 121 local + regs and 5 arguments will overrun the stack (121+1 + 5 + 2 > 128). */ + /* ??? An alternative would be to never allocate one reg. */ + for (i = (R_AR (0) - 2 - start - count) & ~1; i < R_AR (0) - 2 - start; i++) { fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1; SET_HARD_REG_BIT (fixed_reg_set, i); @@ -802,6 +824,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. */ @@ -1055,7 +1104,7 @@ print_operand (file, x, code) { union real_extract u; - bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u); + bcopy ((char *) &CONST_DOUBLE_LOW (x), (char *) &u, sizeof u); fprintf (file, "$double1(%.20e)", u.d); } else if (GET_CODE (x) == REG) @@ -1119,7 +1168,8 @@ print_operand (file, x, code) fprintf (file, "$float"); else fprintf (file, "$double%d", SUBREG_WORD (XEXP (x, 0))); - bcopy (&CONST_DOUBLE_LOW (SUBREG_REG (XEXP (x, 0))), &u, sizeof u); + bcopy ((char *) &CONST_DOUBLE_LOW (SUBREG_REG (XEXP (x, 0))), + (char *) &u, sizeof u); fprintf (file, "(%.20e)", u.d); } @@ -1128,7 +1178,7 @@ print_operand (file, x, code) { union real_extract u; - bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u); + bcopy ((char *) &CONST_DOUBLE_LOW (x), (char *) &u, sizeof u); fprintf (file, "$%s(%.20e)", GET_MODE (x) == SFmode ? "float" : "double0", u.d); }