diff --unified -rN a/config.sub b/config.sub --- a/config.sub 2018-01-03 05:25:18.000000000 +0100 +++ b/config.sub 2019-04-11 11:48:30.936991476 +0200 @@ -632,6 +632,10 @@ basic_machine=ymp-cray os=unicos ;; + psp) + basic_machine=mipsallegrexel-psp + os=elf + ;; *) basic_machine=$1 os= @@ -644,6 +648,10 @@ case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. + mipsallegrexel-*) + cpu=mipsallegrexel + vendor=psp + ;; w89k) cpu=hppa1.1 vendor=winbond @@ -1210,6 +1218,7 @@ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ + | mipsallegrex | mipsallegrexel \ | mmix \ | mn10200 | mn10300 \ | moxie \ diff --unified -rN a/gcc/config/mips/allegrex.md b/gcc/config/mips/allegrex.md --- a/gcc/config/mips/allegrex.md 1970-01-01 01:00:00.000000000 +0100 +++ b/gcc/config/mips/allegrex.md 2019-04-11 11:48:30.936991476 +0200 @@ -0,0 +1,172 @@ +;; Sony ALLEGREX instructions. +;; Copyright (C) 2005 Free Software Foundation, Inc. +;; +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; GCC is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING. If not, write to +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +(define_c_enum "unspec" [ + UNSPEC_CLO + UNSPEC_CTO + UNSPEC_CACHE + UNSPEC_CEIL_W_S + UNSPEC_FLOOR_W_S + UNSPEC_ROUND_W_S +]) + +;; Multiply Add and Subtract. +;; Note: removed clobbering for madd and msub (testing needed) + +(define_insn "allegrex_madd" + [(set (match_operand:SI 0 "register_operand" "+l") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d")) + (match_dup 0)))] + "TARGET_ALLEGREX" + "madd\t%1,%2" + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) + +(define_insn "allegrex_msub" + [(set (match_operand:SI 0 "register_operand" "+l") + (minus:SI (match_dup 0) + (mult:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d"))))] + "TARGET_ALLEGREX" + "msub\t%1,%2" + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) + + +;; Min and max. + +(define_insn "sminsi3" + [(set (match_operand:SI 0 "register_operand" "=d") + (smin:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d")))] + "TARGET_ALLEGREX" + "min\t%0,%1,%2" + [(set_attr "type" "arith") + (set_attr "mode" "SI")]) + +(define_insn "smaxsi3" + [(set (match_operand:SI 0 "register_operand" "=d") + (smax:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d")))] + "TARGET_ALLEGREX" + "max\t%0,%1,%2" + [(set_attr "type" "arith") + (set_attr "mode" "SI")]) + + +;; Extended shift instructions. + +(define_insn "allegrex_bitrev" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:SI 1 "register_operand" "d")] + UNSPEC_BITREV))] + "TARGET_ALLEGREX" + "bitrev\t%0,%1" + [(set_attr "type" "arith") + (set_attr "mode" "SI")]) + +;; Count leading ones, count trailing zeros, and count trailing ones (clz is +;; already defined). + +(define_insn "allegrex_clo" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:SI 1 "register_operand" "d")] + UNSPEC_CLO))] + "TARGET_ALLEGREX" + "clo\t%0,%1" + [(set_attr "type" "clz") + (set_attr "mode" "SI")]) + +;;(define_expand "ctzsi2" +;; [(set (match_operand:SI 0 "register_operand") +;; (ctz:SI (match_operand:SI 1 "register_operand")))] +;; "TARGET_ALLEGREX" +;;{ +;; rtx r1; +;; +;; r1 = gen_reg_rtx (SImode); +;; emit_insn (gen_allegrex_bitrev (r1, operands[1])); +;; emit_insn (gen_clzsi2 (operands[0], r1)); +;; DONE; +;;}) + +(define_expand "allegrex_cto" + [(set (match_operand:SI 0 "register_operand") + (unspec:SI [(match_operand:SI 1 "register_operand")] + UNSPEC_CTO))] + "TARGET_ALLEGREX" +{ + rtx r1; + + r1 = gen_reg_rtx (SImode); + emit_insn (gen_allegrex_bitrev (r1, operands[1])); + emit_insn (gen_allegrex_clo (operands[0], r1)); + DONE; +}) + + +;; Misc. + +(define_insn "allegrex_sync" + [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)] + "TARGET_ALLEGREX" + "sync" + [(set_attr "type" "unknown") + (set_attr "mode" "none")]) + +(define_insn "allegrex_cache" + [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "") + (match_operand:SI 1 "register_operand" "d")] + UNSPEC_CACHE)] + "TARGET_ALLEGREX" + "cache\t%0,0(%1)" + [(set_attr "type" "unknown") + (set_attr "mode" "none")]) + + +;; Floating-point builtins. + +(define_insn "allegrex_ceil_w_s" + [(set (match_operand:SI 0 "register_operand" "=f") + (unspec:SI [(match_operand:SF 1 "register_operand" "f")] + UNSPEC_CEIL_W_S))] + "TARGET_ALLEGREX" + "ceil.w.s\t%0,%1" + [(set_attr "type" "fcvt") + (set_attr "mode" "SF")]) + +(define_insn "allegrex_floor_w_s" + [(set (match_operand:SI 0 "register_operand" "=f") + (unspec:SI [(match_operand:SF 1 "register_operand" "f")] + UNSPEC_FLOOR_W_S))] + "TARGET_ALLEGREX" + "floor.w.s\t%0,%1" + [(set_attr "type" "fcvt") + (set_attr "mode" "SF")]) + +(define_insn "allegrex_round_w_s" + [(set (match_operand:SI 0 "register_operand" "=f") + (unspec:SI [(match_operand:SF 1 "register_operand" "f")] + UNSPEC_ROUND_W_S))] + "TARGET_ALLEGREX" + "round.w.s\t%0,%1" + [(set_attr "type" "fcvt") + (set_attr "mode" "SF")]) diff --unified -rN a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c --- a/gcc/config/mips/mips.c 2018-03-01 12:37:35.000000000 +0100 +++ b/gcc/config/mips/mips.c 2019-04-11 11:48:30.936991476 +0200 @@ -253,7 +253,12 @@ MIPS_BUILTIN_MSA_TEST_BRANCH, /* For generating bposge32 branch instructions in MIPS32 DSP ASE. */ - MIPS_BUILTIN_BPOSGE32 + MIPS_BUILTIN_BPOSGE32, + + /* The builtin corresponds to the ALLEGREX cache instruction. Operand 0 + is the function code (must be less than 32) and operand 1 is the base + address. */ + MIPS_BUILTIN_CACHE }; /* Invoke MACRO (COND) for each C.cond.fmt condition. */ @@ -460,6 +465,10 @@ normal branch. */ static bool mips_branch_likely; +/* Preferred stack boundary for proper stack vars alignment */ +unsigned int mips_preferred_stack_boundary; +unsigned int mips_preferred_stack_align; + /* The current instruction-set architecture. */ enum processor mips_arch; const struct mips_cpu_info *mips_arch_info; @@ -820,6 +829,9 @@ 1, /* branch_cost */ 4 /* memory_latency */ }, + { /* Allegrex */ + DEFAULT_COSTS + }, { /* Loongson-2E */ DEFAULT_COSTS }, @@ -15181,6 +15193,7 @@ AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2) AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_VECTORS) AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN) +AVAIL_NON_MIPS16 (allegrex, TARGET_ALLEGREX) AVAIL_NON_MIPS16 (msa, TARGET_MSA) /* Construct a mips_builtin_description from the given arguments. @@ -15278,6 +15291,30 @@ MIPS_BUILTIN (bposge, f, "bposge" #VALUE, \ MIPS_BUILTIN_BPOSGE ## VALUE, MIPS_SI_FTYPE_VOID, AVAIL) +/* Define a MIPS_BUILTIN_DIRECT function for instruction CODE_FOR_allegrex_. + FUNCTION_TYPE and TARGET_FLAGS are builtin_description fields. */ +#define DIRECT_ALLEGREX_BUILTIN(INSN, FUNCTION_TYPE, TARGET_FLAGS) \ + { CODE_FOR_allegrex_ ## INSN, MIPS_FP_COND_f, "__builtin_allegrex_" #INSN, \ + MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, mips_builtin_avail_allegrex } + +/* Same as the above, but mapped to an instruction that doesn't share the + NAME. NAME is the name of the builtin without the builtin prefix. */ +#define DIRECT_ALLEGREX_NAMED_BUILTIN(NAME, INSN, FUNCTION_TYPE, TARGET_FLAGS) \ + { CODE_FOR_ ## INSN, MIPS_FP_COND_f, "__builtin_allegrex_" #NAME, \ + MIPS_BUILTIN_DIRECT, FUNCTION_TYPE, mips_builtin_avail_allegrex } + +/* Define a MIPS_BUILTIN_DIRECT_NO_TARGET function for instruction + CODE_FOR_allegrex_. FUNCTION_TYPE and TARGET_FLAGS are + builtin_description fields. */ +#define DIRECT_ALLEGREX_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, TARGET_FLAGS) \ + { CODE_FOR_allegrex_ ## INSN, MIPS_FP_COND_f, "__builtin_allegrex_" #INSN, \ + MIPS_BUILTIN_DIRECT_NO_TARGET, FUNCTION_TYPE, mips_builtin_avail_allegrex } + +/* Define a builtin with a specific function TYPE. */ +#define SPECIAL_ALLEGREX_BUILTIN(TYPE, INSN, FUNCTION_TYPE, TARGET_FLAGS) \ + { CODE_FOR_allegrex_ ## INSN, MIPS_FP_COND_f, "__builtin_allegrex_" #INSN, \ + MIPS_BUILTIN_ ## TYPE, FUNCTION_TYPE, mips_builtin_avail_allegrex } + /* Define a Loongson MIPS_BUILTIN_DIRECT function __builtin_loongson_ for instruction CODE_FOR_loongson_. FUNCTION_TYPE is a builtin_description field. */ @@ -15753,6 +15790,38 @@ DIRECT_BUILTIN (dpsqx_s_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32), DIRECT_BUILTIN (dpsqx_sa_w_ph, MIPS_DI_FTYPE_DI_V2HI_V2HI, dspr2_32), +/* Builtin functions for the Sony ALLEGREX processor. + + These have the `__builtin_allegrex_' prefix instead of `__builtin_mips_' + to maintain compatibility with Sony's ALLEGREX GCC port. + + Some of the builtins may seem redundant, but they are the same as the + builtins defined in the Sony compiler. I chose to map redundant and + trivial builtins to the original instruction instead of creating + duplicate patterns specifically for the ALLEGREX (as Sony does). */ + + DIRECT_ALLEGREX_BUILTIN(bitrev, MIPS_SI_FTYPE_SI, 0), + DIRECT_ALLEGREX_NAMED_BUILTIN(clz, clzsi2, MIPS_SI_FTYPE_SI, 0), + DIRECT_ALLEGREX_BUILTIN(clo, MIPS_SI_FTYPE_SI, 0), + //DIRECT_ALLEGREX_NAMED_BUILTIN(ctz, ctzsi2, MIPS_SI_FTYPE_SI, 0), + DIRECT_ALLEGREX_BUILTIN(cto, MIPS_SI_FTYPE_SI, 0), + DIRECT_ALLEGREX_NAMED_BUILTIN(rotr, rotrsi3, MIPS_SI_FTYPE_SI_SI, 0), + DIRECT_ALLEGREX_NAMED_BUILTIN(rotl, rotlsi3, MIPS_SI_FTYPE_SI_SI, 0), + + DIRECT_ALLEGREX_NAMED_BUILTIN(seb, extendqisi2, MIPS_SI_FTYPE_QI, 0), + DIRECT_ALLEGREX_NAMED_BUILTIN(seh, extendhisi2, MIPS_SI_FTYPE_HI, 0), + DIRECT_ALLEGREX_NAMED_BUILTIN(max, smaxsi3, MIPS_SI_FTYPE_SI_SI, 0), + DIRECT_ALLEGREX_NAMED_BUILTIN(min, sminsi3, MIPS_SI_FTYPE_SI_SI, 0), + + DIRECT_ALLEGREX_NO_TARGET_BUILTIN(sync, MIPS_VOID_FTYPE_VOID, 0), + SPECIAL_ALLEGREX_BUILTIN(CACHE, cache, MIPS_VOID_FTYPE_SI_SI, 0), + + DIRECT_ALLEGREX_NAMED_BUILTIN(sqrt_s, sqrtsf2, MIPS_SF_FTYPE_SF, 0), + DIRECT_ALLEGREX_BUILTIN(ceil_w_s, MIPS_SI_FTYPE_SF, 0), + DIRECT_ALLEGREX_BUILTIN(floor_w_s, MIPS_SI_FTYPE_SF, 0), + DIRECT_ALLEGREX_BUILTIN(round_w_s, MIPS_SI_FTYPE_SF, 0), + DIRECT_ALLEGREX_NAMED_BUILTIN(trunc_w_s, fix_truncsfsi2_insn, MIPS_SI_FTYPE_SF, 0), + /* Builtin functions for ST Microelectronics Loongson-2E/2F cores. */ LOONGSON_BUILTIN (packsswh, MIPS_V4HI_FTYPE_V2SI_V2SI), LOONGSON_BUILTIN (packsshb, MIPS_V8QI_FTYPE_V4HI_V4HI), @@ -16441,6 +16510,7 @@ #define MIPS_ATYPE_UQI unsigned_intQI_type_node #define MIPS_ATYPE_HI intHI_type_node #define MIPS_ATYPE_SI intSI_type_node +#define MIPS_ATYPE_QI intQI_type_node #define MIPS_ATYPE_USI unsigned_intSI_type_node #define MIPS_ATYPE_DI intDI_type_node #define MIPS_ATYPE_UDI unsigned_intDI_type_node @@ -17112,6 +17182,26 @@ const1_rtx, const0_rtx); } +/* Expand a __builtin_allegrex_cache() function. Make sure the passed + cache function code is less than 32. */ + +static rtx +mips_expand_builtin_cache (enum insn_code icode, rtx target, tree exp) +{ + int argno; + struct expand_operand ops[2]; + + for (argno = 0; argno < 2; argno++) + mips_prepare_builtin_arg (&ops[argno], exp, argno); + + if (GET_CODE(ops[0].value) != CONST_INT || + INTVAL(ops[0].value) < 0 || INTVAL(ops[0].value) > 0x1f) + error("Invalid first argument for cache builtin (0 <= arg <= 31)"); + + emit_insn(mips_expand_builtin_insn (icode, 2, ops, false)); + return target; +} + /* Implement TARGET_EXPAND_BUILTIN. */ static rtx @@ -17160,6 +17250,9 @@ case MIPS_BUILTIN_BPOSGE32: return mips_expand_builtin_bposge (d->builtin_type, target); + + case MIPS_BUILTIN_CACHE: + return mips_expand_builtin_cache (d->icode, target, exp); } gcc_unreachable (); } @@ -20212,6 +20305,22 @@ if (TARGET_HARD_FLOAT_ABI && TARGET_MIPS5900) REAL_MODE_FORMAT (SFmode) = &spu_single_format; + /* Validate -mpreferred-stack-boundary= value, or provide default. + The default of 128-bit is for newABI else 64-bit. */ + mips_preferred_stack_boundary = (TARGET_NEWABI ? 128 : 64); + mips_preferred_stack_align = (TARGET_NEWABI ? 16 : 8); + if (mips_preferred_stack_boundary_string) + { + i = atoi (mips_preferred_stack_boundary_string); + if (i < 2 || i > 12) + error ("-mpreferred-stack-boundary=%d is not between 2 and 12", i); + else + { + mips_preferred_stack_align = (1 << i); + mips_preferred_stack_boundary = mips_preferred_stack_align * 8; + } + } + mips_register_frame_header_opt (); } diff --unified -rN a/gcc/config/mips/mips-cpus.def b/gcc/config/mips/mips-cpus.def --- a/gcc/config/mips/mips-cpus.def 2018-01-03 11:03:58.000000000 +0100 +++ b/gcc/config/mips/mips-cpus.def 2019-04-11 11:48:30.936991476 +0200 @@ -62,6 +62,7 @@ /* MIPS II processors. */ MIPS_CPU ("r6000", PROCESSOR_R6000, 2, 0) +MIPS_CPU ("allegrex", PROCESSOR_ALLEGREX, 2, 0) /* MIPS III processors. */ MIPS_CPU ("r4000", PROCESSOR_R4000, 3, 0) diff --unified -rN a/gcc/config/mips/mips-ftypes.def b/gcc/config/mips/mips-ftypes.def --- a/gcc/config/mips/mips-ftypes.def 2018-01-03 11:03:58.000000000 +0100 +++ b/gcc/config/mips/mips-ftypes.def 2019-04-11 11:48:30.936991476 +0200 @@ -44,6 +44,8 @@ DEF_MIPS_FTYPE (3, (DI, DI, V2HI, V2HI)) DEF_MIPS_FTYPE (3, (DI, DI, V4QI, V4QI)) DEF_MIPS_FTYPE (2, (DI, POINTER, SI)) +DEF_MIPS_FTYPE (1, (SI, HI)) +DEF_MIPS_FTYPE (1, (SI, SF)) DEF_MIPS_FTYPE (2, (DI, SI, SI)) DEF_MIPS_FTYPE (2, (DI, USI, USI)) DEF_MIPS_FTYPE (2, (DI, V2DI, UQI)) @@ -63,6 +65,7 @@ DEF_MIPS_FTYPE (1, (SI, SI)) DEF_MIPS_FTYPE (2, (SI, SI, SI)) DEF_MIPS_FTYPE (3, (SI, SI, SI, SI)) +DEF_MIPS_FTYPE (1, (SI, QI)) DEF_MIPS_FTYPE (1, (SI, UQI)) DEF_MIPS_FTYPE (1, (SI, UV16QI)) DEF_MIPS_FTYPE (1, (SI, UV2DI)) @@ -281,6 +284,7 @@ DEF_MIPS_FTYPE (3, (VOID, V2DI, CVPOINTER, SI)) DEF_MIPS_FTYPE (2, (VOID, V2HI, V2HI)) DEF_MIPS_FTYPE (2, (VOID, V4QI, V4QI)) +DEF_MIPS_FTYPE (1, (VOID, VOID)) DEF_MIPS_FTYPE (3, (VOID, V4SF, POINTER, SI)) DEF_MIPS_FTYPE (3, (VOID, V4SI, CVPOINTER, SI)) DEF_MIPS_FTYPE (3, (VOID, V8HI, CVPOINTER, SI)) diff --unified -rN a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h --- a/gcc/config/mips/mips.h 2018-01-03 11:03:58.000000000 +0100 +++ b/gcc/config/mips/mips.h 2019-04-11 11:48:30.936991476 +0200 @@ -285,6 +285,7 @@ #define TARGET_SB1 (mips_arch == PROCESSOR_SB1 \ || mips_arch == PROCESSOR_SB1A) #define TARGET_SR71K (mips_arch == PROCESSOR_SR71000) +#define TARGET_ALLEGREX (mips_arch == PROCESSOR_ALLEGREX) #define TARGET_XLP (mips_arch == PROCESSOR_XLP) /* Scheduling target defines. */ @@ -315,6 +316,7 @@ || mips_tune == PROCESSOR_OCTEON3) #define TUNE_SB1 (mips_tune == PROCESSOR_SB1 \ || mips_tune == PROCESSOR_SB1A) +#define TUNE_ALLEGREX (mips_tune == PROCESSOR_ALLEGREX) #define TUNE_P5600 (mips_tune == PROCESSOR_P5600) #define TUNE_I6400 (mips_tune == PROCESSOR_I6400) @@ -1018,6 +1020,9 @@ && !TARGET_MIPS5900 \ && !TARGET_MIPS16) +/* ISA has just the integer condition move instructions (movn,movz) */ +#define ISA_HAS_INT_CONDMOVE (TARGET_ALLEGREX) + /* ISA has the mips4 FP condition code instructions: FP-compare to CC, branch on CC, and move (both FP and non-FP) on CC. */ #define ISA_HAS_8CC (ISA_MIPS4 \ @@ -1053,6 +1058,7 @@ /* ISA has conditional trap instructions. */ #define ISA_HAS_COND_TRAP (!ISA_MIPS1 \ + && !TARGET_ALLEGREX \ && !TARGET_MIPS16) /* ISA has conditional trap with immediate instructions. */ @@ -1112,7 +1118,8 @@ #define ISA_HAS_IEEE_754_2008 (mips_isa_rev >= 2) /* ISA has count leading zeroes/ones instruction (not implemented). */ -#define ISA_HAS_CLZ_CLO (mips_isa_rev >= 1 && !TARGET_MIPS16) +#define ISA_HAS_CLZ_CLO ((mips_isa_rev >= 1 && !TARGET_MIPS16) \ + || TARGET_ALLEGREX) /* ISA has three operand multiply instructions that put the high part in an accumulator: mulhi or mulhiu. */ @@ -1154,6 +1161,7 @@ || TARGET_MIPS5400 \ || TARGET_MIPS5500 \ || TARGET_SR71K \ + || TARGET_ALLEGREX \ || TARGET_SMARTMIPS) \ && !TARGET_MIPS16) @@ -1183,10 +1191,12 @@ #define ISA_HAS_TRUNC_W (!ISA_MIPS1) /* ISA includes the MIPS32r2 seb and seh instructions. */ -#define ISA_HAS_SEB_SEH (mips_isa_rev >= 2 && !TARGET_MIPS16) +#define ISA_HAS_SEB_SEH ((mips_isa_rev >= 2 && !TARGET_MIPS16) \ + || TARGET_ALLEGREX) /* ISA includes the MIPS32/64 rev 2 ext and ins instructions. */ -#define ISA_HAS_EXT_INS (mips_isa_rev >= 2 && !TARGET_MIPS16) +#define ISA_HAS_EXT_INS ((mips_isa_rev >= 2 && !TARGET_MIPS16) \ + || TARGET_ALLEGREX) /* ISA has instructions for accessing top part of 64-bit fp regs. */ #define ISA_HAS_MXHC1 (!TARGET_FLOAT32 \ @@ -1249,7 +1259,8 @@ #define ISA_HAS_HILO_INTERLOCKS (mips_isa_rev >= 1 \ || TARGET_MIPS5500 \ || TARGET_MIPS5900 \ - || TARGET_LOONGSON_2EF) + || TARGET_LOONGSON_2EF \ + || TARGET_ALLEGREX) /* ISA includes synci, jr.hb and jalr.hb. */ #define ISA_HAS_SYNCI (mips_isa_rev >= 2 && !TARGET_MIPS16) @@ -2365,7 +2376,7 @@ `crtl->outgoing_args_size'. */ #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 -#define STACK_BOUNDARY (TARGET_NEWABI ? 128 : 64) +#define STACK_BOUNDARY (mips_preferred_stack_boundary) /* Symbolic macros for the registers used to return integer and floating point values. */ @@ -2492,7 +2503,7 @@ /* Treat LOC as a byte offset from the stack pointer and round it up to the next fully-aligned offset. */ #define MIPS_STACK_ALIGN(LOC) \ - (TARGET_NEWABI ? ROUND_UP ((LOC), 16) : ROUND_UP ((LOC), 8)) + (ROUND_UP ((LOC), mips_preferred_stack_align)) /* Output assembler code to FILE to increment profiler label # LABELNO @@ -3141,6 +3152,9 @@ " TEXT_SECTION_ASM_OP); #endif +extern unsigned int mips_preferred_stack_boundary; +extern unsigned int mips_preferred_stack_align; + #ifndef HAVE_AS_TLS #define HAVE_AS_TLS 0 #endif diff --unified -rN a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md --- a/gcc/config/mips/mips.md 2018-01-03 11:03:58.000000000 +0100 +++ b/gcc/config/mips/mips.md 2019-04-11 11:48:30.940991455 +0200 @@ -35,6 +35,7 @@ 74kf2_1 74kf1_1 74kf3_2 + allegrex loongson_2e loongson_2f loongson_3a @@ -810,6 +811,7 @@ (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT && !TARGET_LOONGSON_2EF + && !TARGET_ALLEGREX && !TARGET_MIPS5900")]) ;; This mode iterator allows :FPCC to be used anywhere that an FP condition @@ -2248,11 +2250,11 @@ (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))] - "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSP)" + "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSP || TARGET_ALLEGREX)" { if (ISA_HAS_DSP_MULT) return "msub\t%q0,%1,%2"; - else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB) + else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB || TARGET_ALLEGREX) return "msub\t%1,%2"; else return "msac\t$0,%1,%2"; @@ -2522,14 +2524,14 @@ (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) (match_operand:DI 3 "muldiv_target_operand" "0")))] - "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSP) + "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSP || TARGET_ALLEGREX) && !TARGET_64BIT" { if (TARGET_MAD) return "mad\t%1,%2"; else if (ISA_HAS_DSP_MULT) return "madd\t%q0,%1,%2"; - else if (GENERATE_MADD_MSUB || TARGET_MIPS5500) + else if (GENERATE_MADD_MSUB || TARGET_MIPS5500 || TARGET_ALLEGREX) return "madd\t%1,%2"; else /* See comment in *macc. */ @@ -3173,6 +3175,33 @@ ;; ;; .................... ;; +;; FIND FIRST BIT INSTRUCTION +;; +;; .................... +;; + +(define_expand "ffs2" + [(set (match_operand:GPR 0 "register_operand" "") + (ffs:GPR (match_operand:GPR 1 "register_operand" "")))] + "ISA_HAS_CLZ_CLO" +{ + rtx r1, r2, r3, r4; + + r1 = gen_reg_rtx (mode); + r2 = gen_reg_rtx (mode); + r3 = gen_reg_rtx (mode); + r4 = gen_reg_rtx (mode); + emit_insn (gen_neg2 (r1, operands[1])); + emit_insn (gen_and3 (r2, operands[1], r1)); + emit_insn (gen_clz2 (r3, r2)); + emit_move_insn (r4, GEN_INT (GET_MODE_BITSIZE (mode))); + emit_insn (gen_sub3 (operands[0], r4, r3)); + DONE; +}) + +;; +;; .................... +;; ;; NEGATION and ONE'S COMPLEMENT ;; ;; .................... @@ -3225,6 +3254,25 @@ (set_attr "compression" "micromips,*") (set_attr "mode" "")]) +(define_expand "rotl3" + [(set (match_operand:GPR 0 "register_operand") + (rotate:GPR (match_operand:GPR 1 "register_operand") + (match_operand:SI 2 "arith_operand")))] + "ISA_HAS_ROR" +{ + rtx temp; + + if (GET_CODE (operands[2]) == CONST_INT) + temp = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (operands[2])); + else + { + temp = gen_reg_rtx (mode); + emit_insn (gen_neg2 (temp, operands[2])); + } + emit_insn (gen_rotr3 (operands[0], operands[1], temp)); + DONE; +}) + ;; ;; .................... ;; @@ -7196,7 +7244,7 @@ (const_int 0)]) (match_operand:GPR 2 "reg_or_0_operand" "dJ,0") (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))] - "ISA_HAS_CONDMOVE" + "ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE" "@ mov%T4\t%0,%z2,%1 mov%t4\t%0,%z3,%1" @@ -7274,7 +7322,7 @@ (if_then_else:GPR (match_dup 5) (match_operand:GPR 2 "reg_or_0_operand") (match_operand:GPR 3 "reg_or_0_operand")))] - "ISA_HAS_CONDMOVE || ISA_HAS_SEL" + "ISA_HAS_CONDMOVE || ISA_HAS_SEL || ISA_HAS_INT_CONDMOVE" { if (!ISA_HAS_FP_CONDMOVE && !INTEGRAL_MODE_P (GET_MODE (XEXP (operands[1], 0)))) @@ -7694,6 +7742,9 @@ ; The MIPS MSA Instructions. (include "mips-msa.md") +; Sony ALLEGREX instructions. +(include "allegrex.md") + (define_c_enum "unspec" [ UNSPEC_ADDRESS_FIRST ]) diff --unified -rN a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt --- a/gcc/config/mips/mips.opt 2018-01-03 11:03:58.000000000 +0100 +++ b/gcc/config/mips/mips.opt 2019-04-11 11:48:30.940991455 +0200 @@ -428,6 +428,10 @@ Target Report Var(flag_frame_header_optimization) Optimization Optimize frame header. +mpreferred-stack-boundary= +Target RejectNegative Joined Var(mips_preferred_stack_boundary_string) +Attempt to keep stack aligned to this power of 2 + noasmopt Driver diff --unified -rN a/gcc/config/mips/psp.h b/gcc/config/mips/psp.h --- a/gcc/config/mips/psp.h 1970-01-01 01:00:00.000000000 +0100 +++ b/gcc/config/mips/psp.h 2019-04-11 11:48:30.940991455 +0200 @@ -0,0 +1,33 @@ +/* Support for Sony's Playstation Portable (PSP). + Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Marcus R. Brown + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Override the startfile spec to include crt0.o. */ +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "crt0%O%s crti%O%s crtbegin%O%s" + +#undef SUBTARGET_CPP_SPEC +#define SUBTARGET_CPP_SPEC "-DPSP=1 -D__psp__=1 -D_PSP=1" + +/* Get rid of the .pdr section. */ +#undef SUBTARGET_ASM_SPEC +#define SUBTARGET_ASM_SPEC "-mno-pdr" + +#include "../newlib-stdint.h" diff --unified -rN a/gcc/config/mips/t-allegrex b/gcc/config/mips/t-allegrex --- a/gcc/config/mips/t-allegrex 1970-01-01 01:00:00.000000000 +0100 +++ b/gcc/config/mips/t-allegrex 2019-04-11 11:48:30.940991455 +0200 @@ -0,0 +1,29 @@ +# Suppress building libgcc1.a, since the MIPS compiler port is complete +# and does not need anything from libgcc1.a. +LIBGCC1 = +CROSS_LIBGCC1 = + +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o +# Don't let CTOR_LIST end up in sdata section. +CRTSTUFF_T_CFLAGS = -G 0 + +# Assemble startup files. +$(T)crti.o: $(srcdir)/config/mips/crti.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \ + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/mips/crti.asm + +$(T)crtn.o: $(srcdir)/config/mips/crtn.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \ + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/mips/crtn.asm + +# We must build libgcc2.a with -G 0, in case the user wants to link +# without the $gp register. +TARGET_LIBGCC2_CFLAGS = -G 0 + +# Build the libraries for both hard and soft floating point + +MULTILIB_OPTIONS = +MULTILIB_DIRNAMES = + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib diff --unified -rN a/gcc/config.gcc b/gcc/config.gcc --- a/gcc/config.gcc 2019-01-29 16:31:10.000000000 +0100 +++ b/gcc/config.gcc 2019-04-11 11:48:40.704941394 +0200 @@ -2318,6 +2318,18 @@ tm_file="elfos.h newlib-stdint.h ${tm_file} mips/r3900.h mips/elf.h" tmake_file="mips/t-r3900" ;; +mipsallegrex-*-elf* | mipsallegrexel-*-elf*) + tm_file="elfos.h ${tm_file} mips/elf.h" + tmake_file=mips/t-allegrex; + target_cpu_default="MASK_SINGLE_FLOAT|MASK_DIVIDE_BREAKS" + tm_defines="MIPS_ISA_DEFAULT=2 MIPS_CPU_STRING_DEFAULT=\\\"allegrex\\\" MIPS_ABI_DEFAULT=ABI_EABI" + case ${target} in + mipsallegrex*-psp-elf*) + tm_file="${tm_file} mips/psp.h"; + ;; + esac + use_fixproto=yes + ;; mmix-knuth-mmixware) tm_file="${tm_file} newlib-stdint.h" use_gcc_stdint=wrap diff --unified -rN a/libcpp/Makefile.in b/libcpp/Makefile.in --- a/libcpp/Makefile.in 2019-02-22 15:22:13.000000000 +0100 +++ b/libcpp/Makefile.in 2019-04-11 11:48:30.940991455 +0200 @@ -208,8 +208,8 @@ # Note that we put the dependencies into a .Tpo file, then move them # into place if the compile succeeds. We need this because gcc does # not atomically write the dependency output file. -COMPILE = $(COMPILE.base) -o $@ -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Tpo -POSTCOMPILE = @mv $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +COMPILE = $(COMPILE.base) -o $@ +POSTCOMPILE = else COMPILE = source='$<' object='$@' libtool=no DEPDIR=$(DEPDIR) $(DEPMODE) \ $(depcomp) $(COMPILE.base) diff --unified -rN a/libgcc/config/mips/psp.h b/libgcc/config/mips/psp.h --- a/libgcc/config/mips/psp.h 1970-01-01 01:00:00.000000000 +0100 +++ b/libgcc/config/mips/psp.h 2019-04-11 11:48:30.940991455 +0200 @@ -0,0 +1,31 @@ +/* Support for Sony's Playstation Portable (PSP). + Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Marcus R. Brown + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Override the startfile spec to include crt0.o. */ +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "crt0%O%s crti%O%s crtbegin%O%s" + +#undef SUBTARGET_CPP_SPEC +#define SUBTARGET_CPP_SPEC "-DPSP=1 -D__psp__=1 -D_PSP=1" + +/* Get rid of the .pdr section. */ +#undef SUBTARGET_ASM_SPEC +#define SUBTARGET_ASM_SPEC "-mno-pdr" diff --unified -rN a/libgcc/config/mips/t-allegrex b/libgcc/config/mips/t-allegrex --- a/libgcc/config/mips/t-allegrex 1970-01-01 01:00:00.000000000 +0100 +++ b/libgcc/config/mips/t-allegrex 2019-04-11 11:48:30.940991455 +0200 @@ -0,0 +1,20 @@ +# Suppress building libgcc1.a, since the MIPS compiler port is complete +# and does not need anything from libgcc1.a. +LIBGCC1 = +CROSS_LIBGCC1 = + +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o +# Don't let CTOR_LIST end up in sdata section. +CRTSTUFF_T_CFLAGS = -G 0 + +# We must build libgcc2.a with -G 0, in case the user wants to link +# without the $gp register. +TARGET_LIBGCC2_CFLAGS = -G 0 + +# Build the libraries for both hard and soft floating point + +MULTILIB_OPTIONS = +MULTILIB_DIRNAMES = + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib diff --unified -rN a/libgcc/config/t-hardfp-sf b/libgcc/config/t-hardfp-sf --- a/libgcc/config/t-hardfp-sf 1970-01-01 01:00:00.000000000 +0100 +++ b/libgcc/config/t-hardfp-sf 2019-04-11 11:48:30.968991312 +0200 @@ -0,0 +1,32 @@ +# Copyright (C) 2014 Free Software Foundation, Inc. + +# This file is part of GCC. + +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. + +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +hardfp_float_modes := sf +# di and ti are provided by libgcc2.c where needed. +hardfp_int_modes := si +hardfp_extensions := +hardfp_truncations := + +# Emulate 64 bit float: +FPBIT = true +DPBIT = true +# Don't build functions handled by 32 bit hardware: +LIB2FUNCS_EXCLUDE = _addsub_sf _mul_sf _div_sf \ + _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \ + _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf \ + _thenan_sf _sf_to_usi _usi_to_sf diff --unified -rN a/libgcc/config.host b/libgcc/config.host --- a/libgcc/config.host 2018-04-06 22:04:17.000000000 +0200 +++ b/libgcc/config.host 2019-04-11 11:48:30.968991312 +0200 @@ -140,11 +140,15 @@ cpu_type=microblaze ;; mips*-*-*) - # All MIPS targets provide a full set of FP routines. cpu_type=mips tmake_file="mips/t-mips" if test "${libgcc_cv_mips_hard_float}" = yes; then - tmake_file="${tmake_file} t-hardfp-sfdf t-hardfp" + if test "${libgcc_cv_mips_single_float}" = yes; then + tmake_file="${tmake_file} t-hardfp-sf" + else + tmake_file="${tmake_file} t-hardfp-sfdf" + fi + tmake_file="${tmake_file} t-hardfp" else tmake_file="${tmake_file} t-softfp-sfdf" fi @@ -959,6 +963,14 @@ mipstx39-*-elf* | mipstx39el-*-elf*) tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16" ;; +mips*-psp*) + tmake_file="${tmake_file} mips/t-allegrex" + target_cpu_default="MASK_SINGLE_FLOAT|MASK_DIVIDE_BREAKS" + tm_file="${tm_file} mips/psp.h" + extra_parts="$extra_parts crti.o crtn.o" + use_fixproto=yes + tm_defines="MIPS_ISA_DEFAULT=2 MIPS_CPU_STRING_DEFAULT=\\\"allegrex\\\" MIPS_ABI_DEFAULT=ABI_EABI" + ;; mmix-knuth-mmixware) extra_parts="crti.o crtn.o crtbegin.o crtend.o" tmake_file="${tmake_file} ${cpu_type}/t-${cpu_type}" diff --unified -rN a/libgcc/configure b/libgcc/configure --- a/libgcc/configure 2018-04-24 18:45:26.000000000 +0200 +++ b/libgcc/configure 2019-04-11 11:48:30.968991312 +0200 @@ -4957,6 +4957,26 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_mips_hard_float" >&5 $as_echo "$libgcc_cv_mips_hard_float" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target is single-float" >&5 +$as_echo_n "checking whether the target is single-float... " >&6; } +if test "${libgcc_cv_mips_single_float+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __mips_single_float + #error FOO + #endif +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + libgcc_cv_mips_single_float=yes +else + libgcc_cv_mips_single_float=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_mips_single_float" >&5 +$as_echo "$libgcc_cv_mips_single_float" >&6; } esac case ${host} in diff --unified -rN a/libgcc/configure.ac b/libgcc/configure.ac --- a/libgcc/configure.ac 2018-02-28 09:59:15.000000000 +0100 +++ b/libgcc/configure.ac 2019-04-11 11:48:30.968991312 +0200 @@ -296,6 +296,14 @@ #endif], [libgcc_cv_mips_hard_float=yes], [libgcc_cv_mips_hard_float=no])]) + AC_CACHE_CHECK([whether the target is single-float], + [libgcc_cv_mips_single_float], + [AC_COMPILE_IFELSE( + [#ifndef __mips_single_float + #error FOO + #endif], + [libgcc_cv_mips_single_float=yes], + [libgcc_cv_mips_single_float=no])]) esac case ${host} in diff --unified -rN a/libgcc/crtstuff.c b/libgcc/crtstuff.c --- a/libgcc/crtstuff.c 2018-01-03 11:03:58.000000000 +0100 +++ b/libgcc/crtstuff.c 2019-04-11 11:48:30.968991312 +0200 @@ -47,7 +47,7 @@ /* Target machine header files require this define. */ #define IN_LIBGCC2 - +#define USED_FOR_TARGET /* FIXME: Including auto-host is incorrect, but until we have identified the set of defines that need to go into auto-target.h, this will have to do. */