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
This commit is contained in:
Ben Elliston 2001-11-09 14:57:50 +00:00 committed by Catherine Moore
parent a3d87e92eb
commit de41e41c42
7 changed files with 219 additions and 14 deletions

View File

@ -1,3 +1,17 @@
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>
* config/sparc/sparc.md (movdf): Avoid calling validize_mem during

View File

@ -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

View File

@ -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

View File

@ -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 }}, \

View File

@ -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")

View File

@ -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.

View File

@ -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