@@ -368,25 +368,30 @@
(match_test "mips_const_vector_same_bytes_p (op, mode)")))
(define_memory_constraint "ZC"
- "A memory operand whose address is formed by a base register and offset
- that is suitable for use in instructions with the same addressing mode
- as @code{ll} and @code{sc}."
+ "When compiling R6 code, this constraint matches a memory operand whose
+ address is formed from a base register and a 9-bit offset.
+ When compiling microMIPS code, this constraint matches a memory operand
+ whose address is formed from a base register and a 12-bit offset.
+ When not compiling for microMIPS nor R6, @code{ZC} is equivalent to
+ @code{R}.
+ These operands can be used for instructions such as @code{ll} and
+ @code{sc}."
(and (match_code "mem")
- (if_then_else
- (match_test "TARGET_MICROMIPS")
- (match_test "umips_12bit_offset_address_p (XEXP (op, 0), mode)")
- (if_then_else (match_test "ISA_HAS_9BIT_DISPLACEMENT")
- (match_test "mips_9bit_offset_address_p (XEXP (op, 0), mode)")
- (match_test "mips_address_insns (XEXP (op, 0), mode, false)")))))
+ (if_then_else (match_test "ISA_HAS_9BIT_DISPLACEMENT")
+ (match_test "mips_9bit_offset_address_p (XEXP (op, 0), mode)")
+ (if_then_else
+ (match_test "TARGET_MICROMIPS")
+ (match_test "umips_12bit_offset_address_p (XEXP (op, 0), mode)")
+ (match_test "mips_address_insns (XEXP (op, 0), mode, false)")))))
(define_address_constraint "ZD"
"An address suitable for a @code{prefetch} instruction, or for any other
instruction with the same addressing mode as @code{prefetch}."
- (if_then_else (match_test "TARGET_MICROMIPS")
- (match_test "umips_12bit_offset_address_p (op, mode)")
- (if_then_else (match_test "ISA_HAS_9BIT_DISPLACEMENT")
- (match_test "mips_9bit_offset_address_p (op, mode)")
- (match_test "mips_address_insns (op, mode, false)"))))
+ (if_then_else (match_test "ISA_HAS_9BIT_DISPLACEMENT")
+ (match_test "mips_9bit_offset_address_p (op, mode)")
+ (if_then_else (match_test "TARGET_MICROMIPS")
+ (match_test "umips_12bit_offset_address_p (op, mode)")
+ (match_test "mips_address_insns (op, mode, false)"))))
(define_memory_constraint "ZR"
"@internal
new file mode 100644
@@ -0,0 +1,229 @@
+;; DFA-based pipeline description for MIPS32 models M6200.
+;;
+;; Copyright (C) 2024 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
+;; <http://www.gnu.org/licenses/>.
+
+(define_automaton "m62_alu_pipe, m62_mdu_pipe, m62_fpu_pipe")
+(define_cpu_unit "m62_mul" "m62_mdu_pipe")
+(define_cpu_unit "m62_alu" "m62_alu_pipe")
+(define_cpu_unit "m62_fpu" "m62_fpu_pipe")
+
+;; --------------------------------------------------------------
+;; ALU Instructions
+;; --------------------------------------------------------------
+
+;; ALU: Logicals
+(define_insn_reservation "m62_int_logical" 1
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "logical,move,signext,slt"))
+ "m62_alu")
+
+;; Arithmetics
+(define_insn_reservation "m62_int" 1
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "arith,const,shift,clz"))
+ "m62_alu")
+
+(define_insn_reservation "m62_int_nop" 0
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "nop"))
+ "nothing")
+
+;; Conditional move
+(define_insn_reservation "m62_int_cmove" 1
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "condmove")
+ (eq_attr "mode" "SI,DI")))
+ "m62_alu")
+
+;; Call
+(define_insn_reservation "m62_int_call" 1
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "call"))
+ "m62_alu")
+
+;; branch/jump
+(define_insn_reservation "m62_int_jump" 1
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "branch,jump"))
+ "m62_alu")
+
+;; loads: lb, lbu, lh, lhu, ll, lw, lwl, lwr, lwpc, lwxs
+;; prefetch: prefetch, prefetchx
+(define_insn_reservation "m62_int_load" 2
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "load,multimem,prefetch,prefetchx"))
+ "m62_alu")
+
+;; stores
+(define_insn_reservation "m62_int_store" 1
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "store,multimem"))
+ "m62_alu")
+
+;; load->next use : 2 cycles (Default)
+;; load->load base: 3 cycles
+;; load->store base: 3 cycles
+;; load->store: 1 cycles
+(define_bypass 3 "m62_int_load" "m62_int_load")
+(define_bypass 3 "m62_int_load" "m62_int_store" "!mips_store_data_bypass_p")
+(define_bypass 1 "m62_int_load" "m62_int_store" "mips_store_data_bypass_p")
+
+;; ALU->load base: 2 cycles
+;; ALU->store base: 2 cycles
+(define_bypass 2 "m62_int" "m62_int_load")
+(define_bypass 2 "m62_int_logical" "m62_int_load")
+(define_bypass 2 "m62_int_cmove" "m62_int_load")
+(define_bypass 2 "m62_int" "m62_int_store" "!mips_store_data_bypass_p")
+(define_bypass 2 "m62_int_logical" "m62_int_store" "!mips_store_data_bypass_p")
+(define_bypass 2 "m62_int_cmove" "m62_int_store" "!mips_store_data_bypass_p")
+
+;; --------------------------------------------------------------
+;; MDU Instructions
+;; --------------------------------------------------------------
+
+;; High performance fully pipelined multiplier
+;; MUL to GPR
+(define_insn_reservation "m62_int_mul3" 2
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "imul3,imul3nc"))
+ "(m62_alu*2)+(m62_mul*2)")
+
+
+;; div
+(define_insn_reservation "m62_int_div_si" 34
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "idiv,idiv3"))
+ "m62_alu+m62_mul*34")
+
+(define_bypass 2 "m62_int" "m62_int_mul3")
+(define_bypass 3 "m62_int_load" "m62_int_mul3")
+
+(define_bypass 3 "m62_int_mul3" "m62_int_store" "!mips_store_data_bypass_p")
+(define_bypass 3 "m62_int_mul3" "m62_int_load")
+
+(define_bypass 36 "m62_int_div_si" "m62_int_store" "!mips_store_data_bypass_p")
+(define_bypass 36 "m62_int_div_si" "m62_int_load")
+
+;; --------------------------------------------------------------
+;; Floating Point Instructions
+;; --------------------------------------------------------------
+
+;; fadd, fabs, fneg
+(define_insn_reservation "m62_fadd" 4
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "fadd,fabs,fneg"))
+ "m62_fpu")
+
+;; fmove
+(define_insn_reservation "m62_fmove" 4
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "fmove"))
+ "m62_fpu")
+
+;; conditional move
+(define_insn_reservation "m62_fp_cmove" 4
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "condmove")
+ (eq_attr "mode" "SF,DF")))
+ "m62_fpu")
+
+;; fload
+(define_insn_reservation "m62_fload" 3
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "fpload,fpidxload"))
+ "m62_fpu")
+
+;; fstore
+(define_insn_reservation "m62_fstore" 1
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "fpstore,fpidxstore"))
+ "m62_fpu")
+
+;; fmul, fmadd
+(define_insn_reservation "m62_fmul_sf" 4
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "fmul,fmadd")
+ (eq_attr "mode" "SF")))
+ "m62_fpu")
+
+(define_insn_reservation "m62_fmul_df" 5
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "fmul,fmadd")
+ (eq_attr "mode" "DF")))
+ "m62_fpu*2")
+
+;; fdiv, fsqrt
+(define_insn_reservation "m62_fdiv_sf" 17
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "fdiv,fsqrt")
+ (eq_attr "mode" "SF")))
+ "m62_fpu*14")
+
+(define_insn_reservation "m62_fdiv_df" 32
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "fdiv,fsqrt")
+ (eq_attr "mode" "DF")))
+ "m62_fpu*29")
+
+;; frsqrt
+(define_insn_reservation "m62_frsqrt_sf" 17
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "frsqrt")
+ (eq_attr "mode" "SF")))
+ "m62_fpu*14")
+
+(define_insn_reservation "m62_frsqrt_df" 35
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "frsqrt")
+ (eq_attr "mode" "DF")))
+ "m62_fpu*31")
+
+;; fcmp
+(define_insn_reservation "m62_fcmp" 4
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "fcmp"))
+ "m62_fpu")
+
+;; fcvt
+;; cvt.s.d
+(define_insn_reservation "m62_fcvt_6" 6
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "fcvt")
+ (eq_attr "cnv_mode" "D2S")))
+ "m62_fpu")
+
+;; trunc
+(define_insn_reservation "m62_fcvt_5" 5
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "fcvt")
+ (eq_attr "cnv_mode" "D2I,S2I")))
+ "m62_fpu")
+
+;; cvt
+(define_insn_reservation "m62_fcvt_4" 4
+ (and (eq_attr "cpu" "m6200")
+ (and (eq_attr "type" "fcvt")
+ (eq_attr "cnv_mode" "S2D,I2D,I2S")))
+ "m62_fpu")
+
+;; mtc, mfc
+(define_insn_reservation "m62_move_to_from_c1" 2
+ (and (eq_attr "cpu" "m6200")
+ (eq_attr "type" "mtc, mfc"))
+ "m62_fpu")
@@ -152,6 +152,9 @@ MIPS_CPU ("p5600", PROCESSOR_P5600, MIPS_ISA_MIPS32R5, (PTF_AVOID_BRANCHLIKELY_S
MIPS_CPU ("m5100", PROCESSOR_M5100, MIPS_ISA_MIPS32R5, PTF_AVOID_BRANCHLIKELY_SPEED)
MIPS_CPU ("m5101", PROCESSOR_M5100, MIPS_ISA_MIPS32R5, PTF_AVOID_BRANCHLIKELY_SPEED)
+/* MIPS32 Release 6 processors. */
+MIPS_CPU ("m6201", PROCESSOR_M6200, MIPS_ISA_MIPS32R6, 0)
+
/* MIPS64 processors. */
MIPS_CPU ("5kc", PROCESSOR_5KC, MIPS_ISA_MIPS64, 0)
MIPS_CPU ("5kf", PROCESSOR_5KF, MIPS_ISA_MIPS64, 0)
@@ -1152,8 +1152,21 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
"ISA_HAS_DSP"
- "%*bposge%1\t%0%/"
- [(set_attr "type" "branch")])
+{
+ if (TARGET_DSPR3 && TARGET_CB_MAYBE)
+ return "%*bposge%1%:\t%0";
+ else
+ return "%*bposge%1\t%0%/";
+}
+ [(set_attr "type" "branch")
+ (set (attr "compact_form") (if_then_else (match_test "TARGET_DSPR3
+ && TARGET_CB_MAYBE")
+ (const_string "maybe")
+ (const_string "never")))
+ (set (attr "hazard") (if_then_else (match_test "TARGET_DSPR3
+ && TARGET_CB_MAYBE")
+ (const_string "forbidden_slot")
+ (const_string "none")))])
(define_expand "mips_madd<u>"
[(set (match_operand:DI 0 "register_operand")
@@ -643,71 +643,74 @@ EnumValue
Enum(mips_arch_opt_value) String(m5101) Value(88) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(5kc) Value(89) Canonical
+Enum(mips_arch_opt_value) String(m6201) Value(89) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(r5kc) Value(89)
+Enum(mips_arch_opt_value) String(5kc) Value(90) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(5kf) Value(90) Canonical
+Enum(mips_arch_opt_value) String(r5kc) Value(90)
EnumValue
-Enum(mips_arch_opt_value) String(r5kf) Value(90)
+Enum(mips_arch_opt_value) String(5kf) Value(91) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(20kc) Value(91) Canonical
+Enum(mips_arch_opt_value) String(r5kf) Value(91)
EnumValue
-Enum(mips_arch_opt_value) String(r20kc) Value(91)
+Enum(mips_arch_opt_value) String(20kc) Value(92) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(sb1) Value(92) Canonical
+Enum(mips_arch_opt_value) String(r20kc) Value(92)
EnumValue
-Enum(mips_arch_opt_value) String(sb1a) Value(93) Canonical
+Enum(mips_arch_opt_value) String(sb1) Value(93) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(sr71000) Value(94) Canonical
+Enum(mips_arch_opt_value) String(sb1a) Value(94) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(sr71k) Value(94)
+Enum(mips_arch_opt_value) String(sr71000) Value(95) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(xlr) Value(95) Canonical
+Enum(mips_arch_opt_value) String(sr71k) Value(95)
EnumValue
-Enum(mips_arch_opt_value) String(loongson3a) Value(96) Canonical
+Enum(mips_arch_opt_value) String(xlr) Value(96) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(gs464) Value(97) Canonical
+Enum(mips_arch_opt_value) String(loongson3a) Value(97) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(gs464e) Value(98) Canonical
+Enum(mips_arch_opt_value) String(gs464) Value(98) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(gs264e) Value(99) Canonical
+Enum(mips_arch_opt_value) String(gs464e) Value(99) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(octeon) Value(100) Canonical
+Enum(mips_arch_opt_value) String(gs264e) Value(100) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(octeon+) Value(101) Canonical
+Enum(mips_arch_opt_value) String(octeon) Value(101) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(octeon2) Value(102) Canonical
+Enum(mips_arch_opt_value) String(octeon+) Value(102) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(octeon3) Value(103) Canonical
+Enum(mips_arch_opt_value) String(octeon2) Value(103) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(xlp) Value(104) Canonical
+Enum(mips_arch_opt_value) String(octeon3) Value(104) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(i6400) Value(105) Canonical
+Enum(mips_arch_opt_value) String(xlp) Value(105) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(i6500) Value(106) Canonical
+Enum(mips_arch_opt_value) String(i6400) Value(106) Canonical
EnumValue
-Enum(mips_arch_opt_value) String(p6600) Value(107) Canonical
+Enum(mips_arch_opt_value) String(i6500) Value(107) Canonical
+
+EnumValue
+Enum(mips_arch_opt_value) String(p6600) Value(108) Canonical
@@ -1164,7 +1164,20 @@ static const struct mips_rtx_cost_data
COSTS_N_INSNS (8), /* int_div_di */
2, /* branch_cost */
4 /* memory_latency */
- }
+ },
+ { /* M6200 */
+ COSTS_N_INSNS (4), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult_sf */
+ COSTS_N_INSNS (5), /* fp_mult_df */
+ COSTS_N_INSNS (17), /* fp_div_sf */
+ COSTS_N_INSNS (32), /* fp_div_df */
+ COSTS_N_INSNS (5), /* int_mult_si */
+ COSTS_N_INSNS (5), /* int_mult_di */
+ COSTS_N_INSNS (34), /* int_div_si */
+ COSTS_N_INSNS (68), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ }
};
static rtx mips_find_pic_call_symbol (rtx_insn *, rtx, bool);
@@ -5400,7 +5413,12 @@ mips_output_move (rtx dest, rtx src)
/* Moves to HI are handled by special .md insns. */
if (REGNO (dest) == LO_REGNUM)
- return "mtlo\t%z1";
+ {
+ if (ISA_HAS_MULT)
+ return "mtlo\t%z1";
+ else
+ return "mtlo\t%z1,$ac0";
+ }
if (DSP_ACC_REG_P (REGNO (dest)))
{
@@ -5453,7 +5471,10 @@ mips_output_move (rtx dest, rtx src)
-mfix-vr4130. */
if (ISA_HAS_MACCHI)
return dbl_p ? "dmacc\t%0,%.,%." : "macc\t%0,%.,%.";
- return "mflo\t%0";
+ if (ISA_HAS_MULT)
+ return "mflo\t%0";
+ else
+ return "mflo\t%0,$ac0";
}
if (DSP_ACC_REG_P (REGNO (src)))
@@ -19008,7 +19029,7 @@ mips_mult_zero_zero_cost (struct mips_sim *state, bool setting)
static void
mips_set_fast_mult_zero_zero_p (struct mips_sim *state)
{
- if (TARGET_MIPS16 || !ISA_HAS_HILO)
+ if (TARGET_MIPS16 || (!ISA_HAS_HILO && !TARGET_DSP))
/* No MTLO or MTHI available for MIPS16. Also, when there are no HI or LO
registers then there is no reason to zero them, arbitrarily choose to
say that "MULT $0,$0" would be faster. */
@@ -19404,7 +19425,7 @@ mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
/* Ignore zero-length instructions (barriers and the like). */
ninsns = get_attr_length (insn) / 4;
- if (ninsns == 0)
+ if (get_attr_length (insn) == 0)
return;
/* Work out how many nops are needed. Note that we only care about
@@ -19419,7 +19440,8 @@ mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
branch instruction was not in a sequence (as the sequence would
imply it is not actually a compact branch anyway) and the current
insn is not an inline asm, and can't go in a delay slot. */
- else if (*fs_delay && get_attr_can_delay (insn) == CAN_DELAY_NO
+ else if (TARGET_FORBIDDEN_SLOTS && *fs_delay
+ && get_attr_can_delay (insn) == CAN_DELAY_NO
&& GET_CODE (PATTERN (after)) != SEQUENCE
&& GET_CODE (pattern) != ASM_INPUT
&& asm_noperands (pattern) < 0)
@@ -20446,6 +20468,7 @@ static void
mips_option_override (void)
{
int i, regno, mode;
+ unsigned int is_micromips;
if (OPTION_SET_P (mips_isa_option))
mips_isa_option_info = &mips_cpu_info_table[mips_isa_option];
@@ -20466,6 +20489,7 @@ mips_option_override (void)
/* Save the base compression state and process flags as though we
were generating uncompressed code. */
mips_base_compression_flags = TARGET_COMPRESSION;
+ is_micromips = TARGET_MICROMIPS;
target_flags &= ~TARGET_COMPRESSION;
mips_base_code_readable = mips_code_readable;
@@ -20706,7 +20730,7 @@ mips_option_override (void)
if (!ISA_HAS_DELAY_SLOTS && mips_cb == MIPS_CB_NEVER)
{
error ("unsupported combination: %qs%s %s",
- mips_arch_info->name, TARGET_MICROMIPS ? " -mmicromips" : "",
+ mips_arch_info->name, is_micromips ? " -mmicromips" : "",
"-mcompact-branches=never");
}
@@ -20863,12 +20887,16 @@ mips_option_override (void)
if (TARGET_DSPR2)
TARGET_DSP = true;
- if (TARGET_DSP && mips_isa_rev >= 6)
+ if (is_micromips && mips_isa_rev >= 6
+ && (TARGET_DSP || TARGET_DSPR2)
+ && !TARGET_DSPR3)
+ error ("unsupported combination: -mmicromips -mips32r6 %s, use "
+ "-mdspr3 instead", TARGET_DSPR2 ? "-mdspr2" : "-mdsp");
+
+ if (TARGET_DSPR3)
{
- error ("the %qs architecture does not support DSP instructions",
- mips_arch_info->name);
- TARGET_DSP = false;
- TARGET_DSPR2 = false;
+ TARGET_DSP = true;
+ TARGET_DSPR2 = true;
}
/* Make sure that when TARGET_LOONGSON_MMI is true, TARGET_HARD_FLOAT_ABI
@@ -21064,7 +21092,7 @@ mips_conditional_register_usage (void)
else
accessible_reg_set &= ~reg_class_contents[DSP_ACC_REGS];
- if (!ISA_HAS_HILO)
+ if (!ISA_HAS_HILO && !ISA_HAS_DSP)
accessible_reg_set &= ~reg_class_contents[MD_REGS];
if (!TARGET_HARD_FLOAT)
@@ -116,6 +116,9 @@ struct mips_cpu_info {
/* Run-time compilation parameters selecting different hardware subsets. */
+/* True if we are targetting micromips R6 onwards. */
+#define TARGET_MICROMIPS_R6 (TARGET_MICROMIPS && mips_isa_rev >= 6)
+
/* True if we are generating position-independent VxWorks RTP code. */
#define TARGET_RTP_PIC (TARGET_VXWORKS_RTP && flag_pic)
@@ -509,6 +512,11 @@ struct mips_cpu_info {
builtin_define ("__mips_dspr2"); \
builtin_define ("__mips_dsp_rev=2"); \
} \
+ else if (TARGET_DSPR3) \
+ { \
+ builtin_define ("__mips_dspr3"); \
+ builtin_define ("__mips_dsp_rev=3"); \
+ } \
else \
builtin_define ("__mips_dsp_rev=1"); \
} \
@@ -838,7 +846,7 @@ struct mips_cpu_info {
|march=interaptiv: -mips32r2} \
%{march=mips32r3: -mips32r3} \
%{march=mips32r5|march=p5600|march=m5100|march=m5101: -mips32r5} \
- %{march=mips32r6: -mips32r6} \
+ %{march=mips32r6|march=m6201: -mips32r6} \
%{march=mips64|march=5k*|march=20k*|march=sb1*|march=sr71000 \
|march=xlr: -mips64} \
%{march=mips64r2|march=loongson3a|march=gs464|march=gs464e|march=gs264e \
@@ -862,7 +870,8 @@ struct mips_cpu_info {
"%{mhard-float|msoft-float|mno-float|march=mips*:; \
march=vr41*|march=m4k|march=4k*|march=24kc|march=24kec \
|march=34kc|march=34kn|march=74kc|march=1004kc|march=5kc \
- |march=m14k*|march=m5101|march=octeon|march=xlr: -msoft-float; \
+ |march=m14k*|march=m5101|march=m6201|march=octeon \
+ |march=xlr: -msoft-float; \
march=*: -mhard-float}"
/* A spec condition that matches 32-bit options. It only works if
@@ -886,7 +895,7 @@ struct mips_cpu_info {
/* Infer a -mnan=2008 setting from a -mips argument. */
#define MIPS_ISA_NAN2008_SPEC \
"%{mnan*:;mips32r6|mips64r6:-mnan=2008; \
- march=m51*|mclib=small|mclib=tiny:%{!msoft-float:-mnan=2008}}"
+ mmicromips|march=m51*|mclib=small|mclib=tiny:%{!msoft-float:-mnan=2008}}"
#if (MIPS_ABI_DEFAULT == ABI_O64 \
|| MIPS_ABI_DEFAULT == ABI_N32 \
@@ -955,7 +964,9 @@ struct mips_cpu_info {
"%{!mno-dsp: \
%{march=24ke*|march=34kc*|march=34kf*|march=34kx*|march=1004k* \
|march=interaptiv: -mdsp} \
- %{march=74k*|march=m14ke*: %{!mno-dspr2: -mdspr2 -mdsp}}}"
+ %{march=74k*|march=m14ke*: %{!mno-dspr2: -mdspr2 -mdsp}}}" \
+ "%{!mforbidden-slots: \
+ %{mips32r6|mips64r6:%{mmicromips:-mno-forbidden-slots}}}"
#define MIPS_ASE_LOONGSON_MMI_SPEC \
"%{!mno-loongson-mmi: \
@@ -1011,7 +1022,8 @@ struct mips_cpu_info {
#define ISA_HAS_JR (mips_isa_rev <= 5)
-#define ISA_HAS_DELAY_SLOTS 1
+#define ISA_HAS_DELAY_SLOTS (mips_isa_rev <= 5 \
+ || !TARGET_MICROMIPS)
#define ISA_HAS_COMPACT_BRANCHES (mips_isa_rev >= 6)
@@ -1295,7 +1307,8 @@ struct mips_cpu_info {
&& mips_isa_rev >= 2)
/* ISA has lwxs instruction (load w/scaled index address. */
-#define ISA_HAS_LWXS ((TARGET_SMARTMIPS || TARGET_MICROMIPS) \
+#define ISA_HAS_LWXS ((TARGET_SMARTMIPS \
+ || (TARGET_MICROMIPS && mips_isa_rev <= 5)) \
&& !TARGET_MIPS16)
/* ISA has lbx, lbux, lhx, lhx, lhux, lwx, lwux, or ldx instruction. */
@@ -1459,6 +1472,7 @@ struct mips_cpu_info {
%{mdmx} %{mno-mdmx:-no-mdmx} \
%{mdsp} %{mno-dsp} \
%{mdspr2} %{mno-dspr2} \
+%{mdspr3} %{mno-dspr3} \
%{mmcu} %{mno-mcu} \
%{meva} %{mno-eva} \
%{mvirt} %{mno-virt} \
@@ -1483,6 +1497,7 @@ struct mips_cpu_info {
%{modd-spreg} %{mno-odd-spreg} \
%{mshared} %{mno-shared} \
%{msym32} %{mno-sym32} \
+%{mforbidden-slots} \
%{mtune=*}" \
FP_ASM_SPEC "\
%{mmips16e2} \
@@ -3185,9 +3200,8 @@ while (0)
asm (SECTION_OP "\n\
.set push\n\
.set nomips16\n\
- .set noreorder\n\
bal 1f\n\
- nop\n\
+ .set noreorder\n\
1: .cpload $31\n\
.set reorder\n\
la $25, " USER_LABEL_PREFIX #FUNC "\n\
@@ -3199,11 +3213,8 @@ while (0)
asm (SECTION_OP "\n\
.set push\n\
.set nomips16\n\
- .set noreorder\n\
bal 1f\n\
- nop\n\
-1: .set reorder\n\
- .cpsetup $31, $2, 1b\n\
+1: .cpsetup $31, $2, 1b\n\
la $25, " USER_LABEL_PREFIX #FUNC "\n\
jalr $25\n\
.set pop\n\
@@ -3213,11 +3224,8 @@ while (0)
asm (SECTION_OP "\n\
.set push\n\
.set nomips16\n\
- .set noreorder\n\
bal 1f\n\
- nop\n\
-1: .set reorder\n\
- .cpsetup $31, $2, 1b\n\
+1: .cpsetup $31, $2, 1b\n\
dla $25, " USER_LABEL_PREFIX #FUNC "\n\
jalr $25\n\
.set pop\n\
@@ -72,6 +72,7 @@
m5100
i6400
p6600
+ m6200
])
(define_c_enum "unspec" [
@@ -1182,6 +1183,7 @@
(include "p5600.md")
(include "m5100.md")
(include "p6600.md")
+(include "m6200.md")
(include "4k.md")
(include "5k.md")
(include "20kc.md")
@@ -2116,7 +2118,7 @@
[(set (match_operand:DI 0 "muldiv_target_operand" "=ka")
(mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d"))
(any_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
- "!TARGET_64BIT && (!TARGET_FIX_R4000 || ISA_HAS_DSP) && ISA_HAS_MULT"
+ "!TARGET_64BIT && ((!TARGET_FIX_R4000 && ISA_HAS_MULT) || ISA_HAS_DSP)"
{
if (ISA_HAS_DSP_MULT)
return "mult<u>\t%q0,%1,%2";
@@ -5467,7 +5469,8 @@
(unspec:GPR [(match_operand:HILO 1 "hilo_operand" "x")]
UNSPEC_MFHI))]
""
- { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; }
+ { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." :
+ ISA_HAS_MULT ? "mfhi\t%0" : "mfhi\t%0,$ac0"; }
[(set_attr "type" "mfhi")
(set_attr "mode" "<GPR:MODE>")])
@@ -5480,7 +5483,12 @@
(match_operand:GPR 2 "register_operand" "l")]
UNSPEC_MTHI))]
""
- "mthi\t%z1"
+ {
+ if (ISA_HAS_MULT)
+ return "mthi\t%z1";
+ else
+ return "mthi\t%z1, $ac0";
+ }
[(set_attr "type" "mthi")
(set_attr "mode" "SI")])
@@ -5730,7 +5738,12 @@
{
mips_expand_synci_loop (operands[0], operands[1]);
emit_insn (gen_sync ());
- emit_insn (PMODE_INSN (gen_clear_hazard, ()));
+ if (TARGET_MICROMIPS_R6)
+ emit_insn (PMODE_INSN (gen_clear_hazard_ur6, ()));
+ else if (ISA_HAS_R6MUL)
+ emit_insn (PMODE_INSN (gen_clear_hazard_r6, ()));
+ else
+ emit_insn (PMODE_INSN (gen_clear_hazard, ()));
}
else if (mips_cache_flush_func && mips_cache_flush_func[0])
{
@@ -5767,11 +5780,36 @@
return "%(%<bal\t1f\n"
"\tnop\n"
"1:\t<d>addiu\t$31,$31,12\n"
- "\tjr.hb\t$31\n"
- "\tnop%>%)";
+ "\tjr.hb\t$31\n"
+ "\tnop%>%)";
}
[(set_attr "insn_count" "5")])
+(define_insn "clear_hazard_ur6_<mode>"
+ [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
+ (clobber (match_scratch:P 0 "=d"))]
+ "ISA_HAS_SYNCI && TARGET_MICROMIPS_R6"
+{
+ return "%(%<auipc\t%0,%%pcrel_hi(1f)\n"
+ "\t<d>addiu\t%0,%0,%%pcrel_lo(1f+4)\n"
+ "\tjrc.hb\t%0\n"
+ "1:%>%)";
+}
+ [(set_attr "insn_count" "3")])
+
+(define_insn "clear_hazard_r6_<mode>"
+ [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD)
+ (clobber (match_scratch:P 0 "=d"))]
+ "ISA_HAS_SYNCI && ISA_HAS_R6MUL && !TARGET_MICROMIPS_R6"
+{
+ return "%(%<auipc\t%0,%%pcrel_hi(1f)\n"
+ "\t<d>addiu\t%0,%0,%%pcrel_lo(1f+4)\n"
+ "\tjr.hb\t%0\n"
+ "\tnop\n"
+ "1:%>%)";
+}
+ [(set_attr "insn_count" "4")])
+
;; Cache operations for R4000-style caches.
(define_insn "mips_cache"
[(set (mem:BLK (scratch))
@@ -6074,11 +6112,22 @@
(pc)))]
"TARGET_HARD_FLOAT"
{
- return mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("b%F1", "%Z2%0"),
- MIPS_BRANCH ("b%W1", "%Z2%0"));
+ if (TARGET_MICROMIPS_R6)
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH_C ("b%F1", "%Z2%0"),
+ MIPS_BRANCH_C ("b%W1", "%Z2%0"));
+ else
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH ("b%F1", "%Z2%0"),
+ MIPS_BRANCH ("b%W1", "%Z2%0"));
}
- [(set_attr "type" "branch")])
+ [(set_attr "type" "branch")
+ (set (attr "compact_form") (if_then_else (match_test "TARGET_MICROMIPS_R6")
+ (const_string "always")
+ (const_string "never")))
+ (set (attr "hazard") (if_then_else (match_test "TARGET_MICROMIPS_R6")
+ (const_string "forbidden_slot")
+ (const_string "none")))])
(define_insn "*branch_fp_inverted_<mode>"
[(set (pc)
@@ -6090,11 +6139,22 @@
(label_ref (match_operand 0 "" ""))))]
"TARGET_HARD_FLOAT"
{
- return mips_output_conditional_branch (insn, operands,
- MIPS_BRANCH ("b%W1", "%Z2%0"),
- MIPS_BRANCH ("b%F1", "%Z2%0"));
+ if (TARGET_MICROMIPS_R6)
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH_C ("b%W1", "%Z2%0"),
+ MIPS_BRANCH_C ("b%F1", "%Z2%0"));
+ else
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH ("b%W1", "%Z2%0"),
+ MIPS_BRANCH ("b%F1", "%Z2%0"));
}
- [(set_attr "type" "branch")])
+ [(set_attr "type" "branch")
+ (set (attr "compact_form") (if_then_else (match_test "TARGET_MICROMIPS_R6")
+ (const_string "always")
+ (const_string "never")))
+ (set (attr "hazard") (if_then_else (match_test "TARGET_MICROMIPS_R6")
+ (const_string "forbidden_slot")
+ (const_string "none")))])
;; Conditional branches on ordered comparisons with zero.
@@ -123,6 +123,10 @@ mdspr2
Target Var(TARGET_DSPR2)
Use MIPS-DSP REV 2 instructions.
+mdspr3
+Target Var(TARGET_DSPR3)
+Use MIPS-DSP Rev 3 instructions.
+
mdebug
Target Var(TARGET_DEBUG_MODE) Undocumented
@@ -529,3 +533,6 @@ Enum(mips_lib_setting) String(small) Value(MIPS_LIB_SMALL)
EnumValue
Enum(mips_lib_setting) String(tiny) Value(MIPS_LIB_TINY)
+
+mforbidden-slots
+Target Undocumented Var(TARGET_FORBIDDEN_SLOTS) Init(1)
@@ -10,3 +10,7 @@ mipsel-r6-hard-newlib/lib64
mipsel-r6-soft-newlib/lib
mipsel-r6-soft-newlib/lib32
mipsel-r6-soft-newlib/lib64
+micromips-r6-hard-newlib/lib
+micromipsel-r6-hard-newlib/lib
+micromips-r6-soft-newlib/lib
+micromipsel-r6-soft-newlib/lib
@@ -8,3 +8,7 @@ mipsel-r6-hard/lib
mipsel-r6-soft/lib
mipsel-r6-hard/lib32
mipsel-r6-hard/lib64
+micromips-r6-hard/lib
+micromips-r6-soft/lib
+micromipsel-r6-hard/lib
+micromipsel-r6-soft/lib
@@ -107,6 +107,23 @@ MULTILIB_REQUIRED += mips64r6/mabi=64/EL/msoft-float/mnan=2008
MULTILIB_OSDIRNAMES += mips64r6/mabi.64/EL/msoft-float/mnan.2008=
MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!mipsel-r6-soft$(is_newlib)/lib64
+# microMIPS32R6 - We will not include any 64 bit microMIPS combinations
+MULTILIB_REQUIRED += mips32r6/mmicromips/mabi=32/EB/mnan=2008
+MULTILIB_OSDIRNAMES += mips32r6/mmicromips/mabi.32/EB/mnan.2008=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromips-r6-hard$(is_newlib)/lib
+MULTILIB_REQUIRED += mips32r6/mmicromips/mabi=32/EB/msoft-float/mnan=2008
+MULTILIB_OSDIRNAMES += mips32r6/mmicromips/mabi.32/EB/msoft-float/mnan.2008=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromips-r6-soft$(is_newlib)/lib
+
+MULTILIB_REQUIRED += mips32r6/mmicromips/mabi=32/EL/mnan=2008
+MULTILIB_OSDIRNAMES += mips32r6/mmicromips/mabi.32/EL/mnan.2008=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromipsel-r6-hard$(is_newlib)
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)/lib
+MULTILIB_REQUIRED += mips32r6/mmicromips/mabi=32/EL/msoft-float/mnan=2008
+MULTILIB_OSDIRNAMES += mips32r6/mmicromips/mabi.32/EL/msoft-float/mnan.2008=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromipsel-r6-soft$(is_newlib)
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)/lib
+
# MIPS32R2/MIPS64R2
MULTILIB_REQUIRED += mips32r2/mabi=32/EB
MULTILIB_OSDIRNAMES += mips32r2/mabi.32/EB=!mips-r2-hard$(is_newlib)/lib
@@ -379,6 +396,19 @@ MULTILIB_REUSE += mclib.tiny/mips32r2/mabi.32/EL/msoft-float=mclib.tiny/
MULTILIB_REUSE := $(MULTILIB_REUSE)mips64r2/mabi.32/EL/msoft-float
# microMIPS Small/Tiny C library variants
+MULTILIB_REQUIRED += mclib=small/mips32r6/mmicromips/mabi=32/EB/mnan=2008
+MULTILIB_OSDIRNAMES += mclib.small/mips32r6/mmicromips/mabi.32/EB/mnan.2008=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromips-r6-hard-small/lib
+MULTILIB_REQUIRED += mclib=small/mips32r6/mmicromips/mabi=32/EL/mnan=2008
+MULTILIB_OSDIRNAMES += mclib.small/mips32r6/mmicromips/mabi.32/EL/mnan.2008=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromipsel-r6-hard-small/lib
+MULTILIB_REQUIRED += mclib=small/mips32r6/mmicromips/mabi=32/EB/msoft-float
+MULTILIB_OSDIRNAMES += mclib.small/mips32r6/mmicromips/mabi.32/EB/msoft-float=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromips-r6-soft-small/lib
+MULTILIB_REQUIRED += mclib=small/mips32r6/mmicromips/mabi=32/EL/msoft-float
+MULTILIB_OSDIRNAMES += mclib.small/mips32r6/mmicromips/mabi.32/EL/msoft-float=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromipsel-r6-soft-small/lib
+
MULTILIB_REQUIRED += mclib=small/mips32r2/mmicromips/mabi=32/EB/mnan=2008
MULTILIB_OSDIRNAMES += mclib.small/mips32r2/mmicromips/mabi.32/EB/mnan.2008=
MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromips-r2-hard-nan2008-small
@@ -394,6 +424,19 @@ MULTILIB_REQUIRED += mclib=small/mips32r2/mmicromips/mabi=32/EL/msoft-float
MULTILIB_OSDIRNAMES += mclib.small/mips32r2/mmicromips/mabi.32/EL/msoft-float=
MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromipsel-r2-soft-small/lib
+MULTILIB_REQUIRED += mclib=tiny/mips32r6/mmicromips/mabi=32/EB/mnan=2008
+MULTILIB_OSDIRNAMES += mclib.tiny/mips32r6/mmicromips/mabi.32/EB/mnan.2008=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromips-r6-hard-tiny/lib
+MULTILIB_REQUIRED += mclib=tiny/mips32r6/mmicromips/mabi=32/EL/mnan=2008
+MULTILIB_OSDIRNAMES += mclib.tiny/mips32r6/mmicromips/mabi.32/EL/mnan.2008=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromipsel-r6-hard-tiny/lib
+MULTILIB_REQUIRED += mclib=tiny/mips32r6/mmicromips/mabi=32/EB/msoft-float
+MULTILIB_OSDIRNAMES += mclib.tiny/mips32r6/mmicromips/mabi.32/EB/msoft-float=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromips-r6-soft-tiny/lib
+MULTILIB_REQUIRED += mclib=tiny/mips32r6/mmicromips/mabi=32/EL/msoft-float
+MULTILIB_OSDIRNAMES += mclib.tiny/mips32r6/mmicromips/mabi.32/EL/msoft-float=
+MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromipsel-r6-soft-tiny/lib
+
MULTILIB_REQUIRED += mclib=tiny/mips32r2/mmicromips/mabi=32/EB/mnan=2008
MULTILIB_OSDIRNAMES += mclib.tiny/mips32r2/mmicromips/mabi.32/EB/mnan.2008=
MULTILIB_OSDIRNAMES := $(MULTILIB_OSDIRNAMES)!micromips-r2-hard-nan2008-tiny/lib
@@ -28195,7 +28195,7 @@ The processor names are:
@samp{gs464e}, @samp{gs264e},
@samp{m4k},
@samp{m14k}, @samp{m14kc}, @samp{m14ke}, @samp{m14kec},
-@samp{m5100}, @samp{m5101},
+@samp{m5100}, @samp{m5101}, @samp{m6201},
@samp{octeon}, @samp{octeon+}, @samp{octeon2}, @samp{octeon3},
@samp{orion},
@samp{p5600}, @samp{p6600},
@@ -2992,9 +2992,14 @@ Floating-point zero.
An address that can be used in a non-macro load or store.
@item ZC
-A memory operand whose address is formed by a base register and offset
-that is suitable for use in instructions with the same addressing mode
-as @code{ll} and @code{sc}.
+When compiling R6 code, this constraint matches a memory operand whose
+address is formed from a base register and a 9-bit offset.
+When compiling microMIPS code, this constraint matches a memory operand
+whose address is formed from a base register and a 12-bit offset.
+When not compiling for microMIPS nor R6, @code{ZC} is equivalent to
+@code{R}.
+These operands can be used for instructions such as @code{ll} and
+@code{sc}.
@item ZD
An address suitable for a @code{prefetch} instruction, or for any other
@@ -1437,7 +1437,6 @@ proc mips-dg-options { args } {
}
}
if { $isa_rev > 5 } {
- mips_make_test_option options "-mno-dsp"
mips_make_test_option options "-mno-mips16"
if { [mips_have_test_option_p options "-mdsp"] } {
mips_make_test_option options "-mfp64"