Commit de41e41c by Ben Elliston Committed by Catherine Moore

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 <amacleod@redhat.com>
Co-Authored-By: Catherine Moore <clm@redhat.com>
Co-Authored-By: Michael Meissner <meissner@redhat.com>
Co-Authored-By: Nick Clifton <nickc@redhat.com>
Co-Authored-By: Richard Henderson <rth@redhat.com>

From-SVN: r46881
parent a3d87e92
2001-11-09 Ben Elliston <bje@redhat.com>
Michael Meissner <meissner@redhat.com>
Andrew MacLeod <amacleod@redhat.com>
Richard Henderson <rth@redhat.com>
Nick Clifton <nickc@redhat.com>
Catherine Moore <clm@redhat.com>
* 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 <jakub@redhat.com> 2001-11-09 Jakub Jelinek <jakub@redhat.com>
* config/sparc/sparc.md (movdf): Avoid calling validize_mem during * config/sparc/sparc.md (movdf): Avoid calling validize_mem during
......
...@@ -90,6 +90,8 @@ extern int m32r_block_immediate_operand PARAMS ((rtx, Mmode)); ...@@ -90,6 +90,8 @@ extern int m32r_block_immediate_operand PARAMS ((rtx, Mmode));
extern int extend_operand PARAMS ((rtx, Mmode)); extern int extend_operand PARAMS ((rtx, Mmode));
extern int reg_or_eq_int16_operand PARAMS ((rtx, Mmode)); extern int reg_or_eq_int16_operand PARAMS ((rtx, Mmode));
extern int int8_operand PARAMS ((rtx, Mmode)); extern int int8_operand PARAMS ((rtx, Mmode));
extern int reg_or_zero_operand PARAMS ((rtx, Mmode));
#endif /* HAVE_MACHINE_MODES */ #endif /* HAVE_MACHINE_MODES */
#ifdef TREE_CODE #ifdef TREE_CODE
......
...@@ -171,7 +171,7 @@ unsigned int m32r_hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] = ...@@ -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, T_MODES, T_MODES, T_MODES,
T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, S_MODES, S_MODES, S_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]; unsigned int m32r_mode_class [NUM_MACHINE_MODES];
...@@ -462,6 +462,10 @@ m32r_encode_section_info (decl) ...@@ -462,6 +462,10 @@ m32r_encode_section_info (decl)
strcpy (newstr + 1, str); strcpy (newstr + 1, str);
*newstr = prefix; *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; XSTR (XEXP (rtl, 0), 0) = newstr;
} }
} }
...@@ -734,6 +738,22 @@ reg_or_cmp_int16_operand (op, mode) ...@@ -734,6 +738,22 @@ reg_or_cmp_int16_operand (op, mode)
return CMP_INT16_P (INTVAL (op)); 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. */ /* Return true if OP is a const_int requiring two instructions to load. */
int int
......
...@@ -40,6 +40,58 @@ Boston, MA 02111-1307, USA. */ ...@@ -40,6 +40,58 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC #undef ENDFILE_SPEC
#undef SUBTARGET_SWITCHES #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. */ /* Print subsidiary information on the compiler version in use. */
#ifndef TARGET_VERSION #ifndef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (m32r)") #define TARGET_VERSION fprintf (stderr, " (m32r)")
...@@ -161,6 +213,12 @@ extern int target_flags; ...@@ -161,6 +213,12 @@ extern int target_flags;
/* Target machine to compile for. */ /* Target machine to compile for. */
#define TARGET_M32R 1 #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. /* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces, This is a list in braces of pairs in braces,
each pair being { "NAME", VALUE } each pair being { "NAME", VALUE }
...@@ -513,7 +571,7 @@ extern enum m32r_sdata m32r_sdata; ...@@ -513,7 +571,7 @@ extern enum m32r_sdata m32r_sdata;
16 - arg pointer 16 - arg pointer
17 - carry flag 17 - carry flag
18 - accumulator 18 - accumulator
19 - accumulator 1 in the m32r/x
By default, the extension registers are not available. */ By default, the extension registers are not available. */
#ifndef SUBTARGET_FIXED_REGISTERS #ifndef SUBTARGET_FIXED_REGISTERS
...@@ -2051,6 +2109,7 @@ enum m32r_function_type ...@@ -2051,6 +2109,7 @@ enum m32r_function_type
matched by the predicate. The list should have a trailing comma. */ matched by the predicate. The list should have a trailing comma. */
#define PREDICATE_CODES \ #define PREDICATE_CODES \
{ "reg_or_zero_operand", { REG, SUBREG, CONST_INT }}, \
{ "conditional_move_operand", { REG, SUBREG, CONST_INT }}, \ { "conditional_move_operand", { REG, SUBREG, CONST_INT }}, \
{ "carry_compare_operand", { EQ, NE }}, \ { "carry_compare_operand", { EQ, NE }}, \
{ "eqne_comparison_operator", { EQ, NE }}, \ { "eqne_comparison_operator", { EQ, NE }}, \
......
...@@ -69,6 +69,26 @@ ...@@ -69,6 +69,26 @@
(define_attr "m32r" "no,yes" (define_attr "m32r" "no,yes"
(const (symbol_ref "(TARGET_M32R != 0)"))) (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 @@ ...@@ -218,6 +238,36 @@
3 0 3 0
[(eq_attr "insn_size" "short")]) [(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 ;; Expand prologue as RTL
(define_expand "prologue" (define_expand "prologue"
...@@ -1126,6 +1176,17 @@ ...@@ -1126,6 +1176,17 @@
DONE; 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 ;; 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 ;; comparison. There isn't a "compare equal" instruction so cmp_eqsi_insn
;; is quite inefficient. However, it is rarely used. ;; is quite inefficient. However, it is rarely used.
...@@ -1177,6 +1238,7 @@ ...@@ -1177,6 +1238,7 @@
[(set_attr "type" "int2,int4") [(set_attr "type" "int2,int4")
(set_attr "length" "2,4")]) (set_attr "length" "2,4")])
;; reg == small constant comparisons are best handled by putting the result ;; reg == small constant comparisons are best handled by putting the result
;; of the comparison in a tmp reg and then using beqz/bnez. ;; of the comparison in a tmp reg and then using beqz/bnez.
;; ??? The result register doesn't contain 0/STORE_FLAG_VALUE, ;; ??? The result register doesn't contain 0/STORE_FLAG_VALUE,
...@@ -1448,7 +1510,7 @@ ...@@ -1448,7 +1510,7 @@
"" ""
"* "*
{ {
const char *br,*invbr; char *br,*invbr;
char asmtext[40]; char asmtext[40];
switch (GET_CODE (operands[1])) switch (GET_CODE (operands[1]))
...@@ -1495,7 +1557,7 @@ ...@@ -1495,7 +1557,7 @@
"" ""
"* "*
{ {
const char *br,*invbr; char *br,*invbr;
char asmtext[40]; char asmtext[40];
switch (GET_CODE (operands[1])) switch (GET_CODE (operands[1]))
...@@ -1550,6 +1612,14 @@ ...@@ -1550,6 +1612,14 @@
if (! register_operand (op1, mode)) if (! register_operand (op1, mode))
op1 = force_reg (mode, op1); 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) if (GET_CODE (op2) == CONST_INT && INTVAL (op2) == 0)
{ {
emit_insn (gen_seq_zero_insn (op0, op1)); emit_insn (gen_seq_zero_insn (op0, op1));
...@@ -1563,6 +1633,29 @@ ...@@ -1563,6 +1633,29 @@
DONE; 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" (define_insn "seq_zero_insn"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(eq:SI (match_operand:SI 1 "register_operand" "r") (eq:SI (match_operand:SI 1 "register_operand" "r")
......
...@@ -36,17 +36,30 @@ crtfini.o: $(srcdir)/config/m32r/initfini.c $(GCC_PASSES) $(CONFIG_H) ...@@ -36,17 +36,30 @@ crtfini.o: $(srcdir)/config/m32r/initfini.c $(GCC_PASSES) $(CONFIG_H)
-DCRT_FINI -finhibit-size-directive -fno-inline-functions \ -DCRT_FINI -finhibit-size-directive -fno-inline-functions \
-g0 -mmodel=medium -c $(srcdir)/config/m32r/initfini.c -o crtfini.o -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. # -mmodel={small,medium} requires separate libraries.
# We don't build libraries for the large model, instead we use the medium # 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 # libraries. The only difference is that the large model can handle jumps
# more than 26 signed bits away. # more than 26 signed bits away.
MULTILIB_OPTIONS = mmodel=small/mmodel=medium MULTILIB_OPTIONS = mmodel=small/mmodel=medium m32r/m32rx
MULTILIB_DIRNAMES = small medium MULTILIB_DIRNAMES = small medium m32r m32rx
MULTILIB_MATCHES = mmodel?medium=mmodel?large MULTILIB_MATCHES = mmodel?medium=mmodel?large
# Set MULTILIB_EXTRA_OPTS so shipped libraries have small data in .sdata and # Set MULTILIB_EXTRA_OPTS so shipped libraries have small data in .sdata and
# SHN_M32R_SCOMMON. # SHN_M32R_SCOMMON.
# This is important for objects referenced in system header files. # This is important for objects referenced in system header files.
......
...@@ -402,7 +402,7 @@ in the following sections. ...@@ -402,7 +402,7 @@ in the following sections.
@emph{M32R/D Options} @emph{M32R/D Options}
@gccoptlist{ @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}} -G @var{num}}
@emph{M88K Options} @emph{M88K Options}
...@@ -6227,6 +6227,10 @@ This option makes symbolic debugging impossible. ...@@ -6227,6 +6227,10 @@ This option makes symbolic debugging impossible.
These @option{-m} options are defined for Mitsubishi M32R/D architectures: These @option{-m} options are defined for Mitsubishi M32R/D architectures:
@table @gcctabopt @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 @item -mcode-model=small
@opindex mcode-model=small @opindex mcode-model=small
Assume all objects live in the lower 16MB of memory (so that their addresses Assume all objects live in the lower 16MB of memory (so that their addresses
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment