From de41e41c4289c76cfbc3153411638eefac8104a1 Mon Sep 17 00:00:00 2001 From: Ben Elliston Date: Fri, 9 Nov 2001 14:57:50 +0000 Subject: m32r.c: Add support for m32rx processor. * m32r.c: Add support for m32rx processor. * m32r.h: Ditto. * m32r.md: Ditto. * t-m32r: Ditto. * m32r-protos.h: Add prototypes for m32rx functions. * doc/invoke.texi: Document -m32rx option. Co-Authored-By: Andrew MacLeod Co-Authored-By: Catherine Moore Co-Authored-By: Michael Meissner Co-Authored-By: Nick Clifton Co-Authored-By: Richard Henderson From-SVN: r46881 --- gcc/ChangeLog | 14 ++++++ gcc/config/m32r/m32r-protos.h | 2 + gcc/config/m32r/m32r.c | 22 ++++++++- gcc/config/m32r/m32r.h | 61 ++++++++++++++++++++++- gcc/config/m32r/m32r.md | 109 ++++++++++++++++++++++++++++++++++++++---- gcc/config/m32r/t-m32r | 19 ++++++-- gcc/doc/invoke.texi | 6 ++- 7 files changed, 219 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index add0d82..ddb272e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2001-11-09 Ben Elliston + Michael Meissner + Andrew MacLeod + Richard Henderson + Nick Clifton + Catherine Moore + + * m32r.c: Add support for m32rx processor. + * m32r.h: Ditto. + * m32r.md: Ditto. + * t-m32r: Ditto. + * m32r-protos.h: Add prototypes for m32rx functions. + * doc/invoke.texi: Document -m32rx option. + 2001-11-09 Jakub Jelinek * config/sparc/sparc.md (movdf): Avoid calling validize_mem during diff --git a/gcc/config/m32r/m32r-protos.h b/gcc/config/m32r/m32r-protos.h index fd93040..8b51ea1 100644 --- a/gcc/config/m32r/m32r-protos.h +++ b/gcc/config/m32r/m32r-protos.h @@ -90,6 +90,8 @@ extern int m32r_block_immediate_operand PARAMS ((rtx, Mmode)); extern int extend_operand PARAMS ((rtx, Mmode)); extern int reg_or_eq_int16_operand PARAMS ((rtx, Mmode)); extern int int8_operand PARAMS ((rtx, Mmode)); +extern int reg_or_zero_operand PARAMS ((rtx, Mmode)); + #endif /* HAVE_MACHINE_MODES */ #ifdef TREE_CODE diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c index f1ed72d..9ff0081 100644 --- a/gcc/config/m32r/m32r.c +++ b/gcc/config/m32r/m32r.c @@ -171,7 +171,7 @@ unsigned int m32r_hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] = { T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, S_MODES, S_MODES, S_MODES, - S_MODES, C_MODES, A_MODES + S_MODES, C_MODES, A_MODES, A_MODES }; unsigned int m32r_mode_class [NUM_MACHINE_MODES]; @@ -462,6 +462,10 @@ m32r_encode_section_info (decl) strcpy (newstr + 1, str); *newstr = prefix; + /* Note - we cannot leave the string in the ggc_alloc'ed space. + It must reside in the stringtable's domain. */ + newstr = (char *) ggc_alloc_string (newstr, len + 2); + XSTR (XEXP (rtl, 0), 0) = newstr; } } @@ -734,6 +738,22 @@ reg_or_cmp_int16_operand (op, mode) return CMP_INT16_P (INTVAL (op)); } +/* Return true if OP is a register or the constant 0. */ + +int +reg_or_zero_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG) + return register_operand (op, mode); + + if (GET_CODE (op) != CONST_INT) + return 0; + + return INTVAL (op) == 0; +} + /* Return true if OP is a const_int requiring two instructions to load. */ int diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h index 7a810ae..8d15250 100644 --- a/gcc/config/m32r/m32r.h +++ b/gcc/config/m32r/m32r.h @@ -40,6 +40,58 @@ Boston, MA 02111-1307, USA. */ #undef ENDFILE_SPEC #undef SUBTARGET_SWITCHES + +/* M32R/X overrides. */ +/* Print subsidiary information on the compiler version in use. */ +#define TARGET_VERSION fprintf (stderr, " (m32r/x)"); + +/* Additional flags for the preprocessor. */ +#define CPP_CPU_SPEC "%{m32rx:-D__M32RX__} %{m32r:-U__M32RX__}" + +/* Assembler switches. */ +#define ASM_CPU_SPEC \ +"%{m32r} %{m32rx} %{!O0: %{O*: -O}} --no-warn-explicit-parallel-conflicts" + +/* Use m32rx specific crt0/crtinit/crtfini files. */ +#define STARTFILE_CPU_SPEC "%{!shared:crt0.o%s} %{m32rx:m32rx/crtinit.o%s} %{!m32rx:crtinit.o%s}" +#define ENDFILE_CPU_SPEC "-lgloss %{m32rx:m32rx/crtfini.o%s} %{!m32rx:crtfini.o%s}" + +/* Extra machine dependent switches. */ +#define SUBTARGET_SWITCHES \ + { "32rx", TARGET_M32RX_MASK, "Compile for the m32rx" }, \ + { "32r", -TARGET_M32RX_MASK, "" }, + +/* Define this macro as a C expression for the initializer of an array of + strings to tell the driver program which options are defaults for this + target and thus do not need to be handled specially when using + `MULTILIB_OPTIONS'. */ +#define SUBTARGET_MULTILIB_DEFAULTS , "m32r" + +/* Number of additional registers the subtarget defines. */ +#define SUBTARGET_NUM_REGISTERS 1 + +/* 1 for registers that cannot be allocated. */ +#define SUBTARGET_FIXED_REGISTERS , 1 + +/* 1 for registers that are not available across function calls. */ +#define SUBTARGET_CALL_USED_REGISTERS , 1 + +/* Order to allocate model specific registers. */ +#define SUBTARGET_REG_ALLOC_ORDER , 19 + +/* Registers which are accumulators. */ +#define SUBTARGET_REG_CLASS_ACCUM 0x80000 + +/* All registers added. */ +#define SUBTARGET_REG_CLASS_ALL SUBTARGET_REG_CLASS_ACCUM + +/* Additional accumulator registers. */ +#define SUBTARGET_ACCUM_P(REGNO) ((REGNO) == 19) + +/* Define additional register names. */ +#define SUBTARGET_REGISTER_NAMES , "a1" +/* end M32R/X overrides. */ + /* Print subsidiary information on the compiler version in use. */ #ifndef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (m32r)") @@ -161,6 +213,12 @@ extern int target_flags; /* Target machine to compile for. */ #define TARGET_M32R 1 +/* Support extended instruction set. */ +#define TARGET_M32RX_MASK (1 << 5) +#define TARGET_M32RX (target_flags & TARGET_M32RX_MASK) +#undef TARGET_M32R +#define TARGET_M32R (! TARGET_M32RX) + /* Macro to define tables used to set the flags. This is a list in braces of pairs in braces, each pair being { "NAME", VALUE } @@ -513,7 +571,7 @@ extern enum m32r_sdata m32r_sdata; 16 - arg pointer 17 - carry flag 18 - accumulator - + 19 - accumulator 1 in the m32r/x By default, the extension registers are not available. */ #ifndef SUBTARGET_FIXED_REGISTERS @@ -2051,6 +2109,7 @@ enum m32r_function_type matched by the predicate. The list should have a trailing comma. */ #define PREDICATE_CODES \ +{ "reg_or_zero_operand", { REG, SUBREG, CONST_INT }}, \ { "conditional_move_operand", { REG, SUBREG, CONST_INT }}, \ { "carry_compare_operand", { EQ, NE }}, \ { "eqne_comparison_operator", { EQ, NE }}, \ diff --git a/gcc/config/m32r/m32r.md b/gcc/config/m32r/m32r.md index 5b8bac9..470a05d 100644 --- a/gcc/config/m32r/m32r.md +++ b/gcc/config/m32r/m32r.md @@ -69,6 +69,26 @@ (define_attr "m32r" "no,yes" (const (symbol_ref "(TARGET_M32R != 0)"))) +(define_attr "m32rx" "no,yes" + (const (symbol_ref "(TARGET_M32RX != 0)"))) + +(define_attr "m32rx_pipeline" "either,s,o,long,m32r" + (cond [(eq_attr "m32rx" "no") + (const_string "m32r") + + (eq_attr "insn_size" "!short") + (const_string "long")] + + (cond [(eq_attr "type" "int2") + (const_string "either") + + (eq_attr "type" "load2,store2,shift2,uncond_branch,branch,call") + (const_string "o") + + (eq_attr "type" "mul2") + (const_string "s")] + + (const_string "long")))) ;; :::::::::::::::::::: ;; :: @@ -218,6 +238,36 @@ 3 0 [(eq_attr "insn_size" "short")]) +(define_function_unit "left" 1 1 + (and (eq_attr "m32rx_pipeline" "o,either") + (eq_attr "type" "!load2")) + 1 0 + [(eq_attr "insn_size" "long")]) + +(define_function_unit "left" 1 1 ;; load delay of 1 clock for mem execution + 1 clock for WB + (and (eq_attr "m32rx_pipeline" "o,either") + (eq_attr "type" "load2")) + 3 0 + [(eq_attr "insn_size" "long")]) + +(define_function_unit "right" 1 1 + (eq_attr "m32rx_pipeline" "s,either") + 1 0 + [(eq_attr "insn_size" "long")]) + +(define_function_unit "long" 1 1 + (and (eq_attr "m32rx" "yes") + (and (eq_attr "insn_size" "long") + (eq_attr "type" "!load4,load8"))) + 2 0 + [(eq_attr "insn_size" "short")]) + +(define_function_unit "long" 1 1 ;; load delay of 1 clock for mem execution + 1 clock for WB + (and (eq_attr "m32rx" "yes") + (and (eq_attr "insn_size" "long") + (eq_attr "type" "load4,load8"))) + 3 0 + [(eq_attr "insn_size" "short")]) ;; Expand prologue as RTL (define_expand "prologue" @@ -1126,14 +1176,25 @@ DONE; }") +(define_insn "cmp_eqsi_zero_insn" + [(set (reg:SI 17) + (eq:SI (match_operand:SI 0 "register_operand" "r,r") + (match_operand:SI 1 "reg_or_zero_operand" "r,P")))] + "TARGET_M32RX" + "@ + cmpeq %0, %1 + cmpz %0" + [(set_attr "type" "int4") + (set_attr "length" "4")]) + ;; The cmp_xxx_insn patterns set the condition bit to the result of the ;; comparison. There isn't a "compare equal" instruction so cmp_eqsi_insn ;; is quite inefficient. However, it is rarely used. (define_insn "cmp_eqsi_insn" [(set (reg:SI 17) - (eq:SI (match_operand:SI 0 "register_operand" "r,r") - (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P"))) + (eq:SI (match_operand:SI 0 "register_operand" "r,r") + (match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P"))) (clobber (match_scratch:SI 2 "=&r,&r"))] "" "* @@ -1157,8 +1218,8 @@ (define_insn "cmp_ltsi_insn" [(set (reg:SI 17) - (lt:SI (match_operand:SI 0 "register_operand" "r,r") - (match_operand:SI 1 "reg_or_int16_operand" "r,J")))] + (lt:SI (match_operand:SI 0 "register_operand" "r,r") + (match_operand:SI 1 "reg_or_int16_operand" "r,J")))] "" "@ cmp %0,%1 @@ -1168,8 +1229,8 @@ (define_insn "cmp_ltusi_insn" [(set (reg:SI 17) - (ltu:SI (match_operand:SI 0 "register_operand" "r,r") - (match_operand:SI 1 "reg_or_int16_operand" "r,J")))] + (ltu:SI (match_operand:SI 0 "register_operand" "r,r") + (match_operand:SI 1 "reg_or_int16_operand" "r,J")))] "" "@ cmpu %0,%1 @@ -1177,6 +1238,7 @@ [(set_attr "type" "int2,int4") (set_attr "length" "2,4")]) + ;; reg == small constant comparisons are best handled by putting the result ;; of the comparison in a tmp reg and then using beqz/bnez. ;; ??? The result register doesn't contain 0/STORE_FLAG_VALUE, @@ -1448,7 +1510,7 @@ "" "* { - const char *br,*invbr; + char *br,*invbr; char asmtext[40]; switch (GET_CODE (operands[1])) @@ -1495,7 +1557,7 @@ "" "* { - const char *br,*invbr; + char *br,*invbr; char asmtext[40]; switch (GET_CODE (operands[1])) @@ -1550,6 +1612,14 @@ if (! register_operand (op1, mode)) op1 = force_reg (mode, op1); + if (TARGET_M32RX) + { + if (! reg_or_zero_operand (op2, mode)) + op2 = force_reg (mode, op2); + + emit_insn (gen_seq_insn_m32rx (op0, op1, op2)); + DONE; + } if (GET_CODE (op2) == CONST_INT && INTVAL (op2) == 0) { emit_insn (gen_seq_zero_insn (op0, op1)); @@ -1563,6 +1633,29 @@ DONE; }") +(define_insn "seq_insn_m32rx" + [(set (match_operand:SI 0 "register_operand" "=r") + (eq:SI (match_operand:SI 1 "register_operand" "%r") + (match_operand:SI 2 "reg_or_zero_operand" "rP"))) + (clobber (reg:SI 17))] + "TARGET_M32RX" + "#" + [(set_attr "type" "multi") + (set_attr "length" "6")]) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (eq:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "reg_or_zero_operand" ""))) + (clobber (reg:SI 17))] + "TARGET_M32RX" + [(set (reg:SI 17) + (eq:SI (match_dup 1) + (match_dup 2))) + (set (match_dup 0) + (reg:SI 17))] + "") + (define_insn "seq_zero_insn" [(set (match_operand:SI 0 "register_operand" "=r") (eq:SI (match_operand:SI 1 "register_operand" "r") diff --git a/gcc/config/m32r/t-m32r b/gcc/config/m32r/t-m32r index 79e8945..e7d56af 100644 --- a/gcc/config/m32r/t-m32r +++ b/gcc/config/m32r/t-m32r @@ -36,17 +36,30 @@ crtfini.o: $(srcdir)/config/m32r/initfini.c $(GCC_PASSES) $(CONFIG_H) -DCRT_FINI -finhibit-size-directive -fno-inline-functions \ -g0 -mmodel=medium -c $(srcdir)/config/m32r/initfini.c -o crtfini.o +m32rx: + mkdir $@ + +m32rx/crtinit.o: m32rx $(srcdir)/config/m32r/initfini.c $(GCC_PASSES) $(CONFIG_H) + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \ + -DCRT_INIT -finhibit-size-directive -fno-inline-functions \ + -g0 -mmodel=medium -c $(srcdir)/config/m32r/initfini.c -m32rx \ + -o m32rx/crtinit.o + +m32rx/crtfini.o: m32rx $(srcdir)/config/m32r/initfini.c $(GCC_PASSES) $(CONFIG_H) + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \ + -DCRT_FINI -finhibit-size-directive -fno-inline-functions \ + -g0 -mmodel=medium -c $(srcdir)/config/m32r/initfini.c -m32rx \ + -o m32rx/crtfini.o # -mmodel={small,medium} requires separate libraries. # We don't build libraries for the large model, instead we use the medium # libraries. The only difference is that the large model can handle jumps # more than 26 signed bits away. -MULTILIB_OPTIONS = mmodel=small/mmodel=medium -MULTILIB_DIRNAMES = small medium +MULTILIB_OPTIONS = mmodel=small/mmodel=medium m32r/m32rx +MULTILIB_DIRNAMES = small medium m32r m32rx MULTILIB_MATCHES = mmodel?medium=mmodel?large - # Set MULTILIB_EXTRA_OPTS so shipped libraries have small data in .sdata and # SHN_M32R_SCOMMON. # This is important for objects referenced in system header files. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9ad11f4..059464a 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -402,7 +402,7 @@ in the following sections. @emph{M32R/D Options} @gccoptlist{ --mcode-model=@var{model-type} -msdata=@var{sdata-type} @gol +-mm32rx -mcode-model=@var{model-type} -msdata=@var{sdata-type} @gol -G @var{num}} @emph{M88K Options} @@ -6227,6 +6227,10 @@ This option makes symbolic debugging impossible. These @option{-m} options are defined for Mitsubishi M32R/D architectures: @table @gcctabopt +@item -mm32rx +@opindex mm32rx +Generate code for the M32R/X. The default is to generate code for the M32R. + @item -mcode-model=small @opindex mcode-model=small Assume all objects live in the lower 16MB of memory (so that their addresses -- cgit v1.1