mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-10 07:56:43 +08:00
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:
parent
a3d87e92eb
commit
de41e41c42
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 }}, \
|
||||
|
@ -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")
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user