This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: m32r/x support
- To: nickc at cygnus dot com
- Subject: RFA: m32r/x support
- From: Catherine Moore <clm at redhat dot com>
- Date: Wed, 07 Nov 2001 07:37:29 -0800
- Cc: clm at cygnus dot com, gcc-patches at gcc dot gnu dot org
2001-11-07 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>
* rtl.def (GROUP_PARALLEL, GROUP_SEQUENCE): New.
* m32r.c: Add support for m32rx processor.
* m32r.h: Ditto.
* m32r.md: Ditto.
* t-m32r: Ditto.
* m32r-protos.h: Add prototypes for m32rx functions.
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.def,v
retrieving revision 1.50
diff -p -r1.50 rtl.def
*** rtl.def 2001/11/03 16:28:33 1.50
--- rtl.def 2001/11/06 15:34:12
*************** DEF_RTL_EXPR(SEQUENCE, "sequence", "E",
*** 333,338 ****
--- 333,348 ----
/* Refers to the address of its argument. This is only used in alias.c. */
DEF_RTL_EXPR(ADDRESS, "address", "e", 'm')
+ /* Express a group of insns that are executed in parallel.
+ 1st operand: Vector of insns.
+ 2nd operand: Available for scheduler use. */
+ DEF_RTL_EXPR(GROUP_PARALLEL, "group_parallel", "E0", 'g')
+
+ /* Express a group of insns that are executed in sequence.
+ 1st operand: Vector of insns.
+ 2nd operand: Available for scheduler use. */
+ DEF_RTL_EXPR(GROUP_SEQUENCE, "group_sequence", "E0", 'g')
+
/* ----------------------------------------------------------------------
Expressions used for insn attributes. These also do not appear in
actual rtl code in the compiler.
Index: m32r-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/m32r/m32r-protos.h,v
retrieving revision 1.7
diff -p -r1.7 m32r-protos.h
*** m32r-protos.h 2001/08/18 20:25:52 1.7
--- m32r-protos.h 2001/11/06 15:34:32
*************** extern int m32r_block_immediate_opera
*** 90,95 ****
--- 90,97 ----
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
Index: m32r.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/m32r/m32r.c,v
retrieving revision 1.34
diff -p -r1.34 m32r.c
*** m32r.c 2001/09/21 01:27:05 1.34
--- m32r.c 2001/11/06 15:34:33
*************** unsigned int m32r_hard_regno_mode_ok[FIR
*** 171,177 ****
{
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
};
unsigned int m32r_mode_class [NUM_MACHINE_MODES];
--- 171,177 ----
{
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, A_MODES
};
unsigned int m32r_mode_class [NUM_MACHINE_MODES];
*************** m32r_encode_section_info (decl)
*** 462,467 ****
--- 462,471 ----
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;
}
}
*************** reg_or_cmp_int16_operand (op, mode)
*** 732,737 ****
--- 736,757 ----
if (GET_CODE (op) != CONST_INT)
return 0;
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. */
Index: m32r.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/m32r/m32r.h,v
retrieving revision 1.47
diff -p -r1.47 m32r.h
*** m32r.h 2001/10/19 22:27:30 1.47
--- m32r.h 2001/11/06 15:34:33
*************** Boston, MA 02111-1307, USA. */
*** 40,45 ****
--- 40,97 ----
#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)")
*************** extern int target_flags;
*** 161,166 ****
--- 213,224 ----
/* 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 }
*************** extern enum m32r_sdata m32r_sdata;
*** 513,519 ****
16 - arg pointer
17 - carry flag
18 - accumulator
!
By default, the extension registers are not available. */
#ifndef SUBTARGET_FIXED_REGISTERS
--- 571,577 ----
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
*************** enum m32r_function_type
*** 2051,2056 ****
--- 2109,2115 ----
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 }}, \
Index: m32r.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/m32r/m32r.md,v
retrieving revision 1.20
diff -p -r1.20 m32r.md
*** m32r.md 2001/11/04 02:12:10 1.20
--- m32r.md 2001/11/06 15:34:34
***************
*** 69,74 ****
--- 69,94 ----
(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,223 ****
--- 238,308 ----
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")])
+
+ ;; Instruction grouping
+
+ (define_insn "*small_sequence"
+ [(group_sequence [(match_insn 0 "small_insn_p")
+ (match_insn 1 "small_insn_p")])]
+ ""
+ "*
+ {
+ abort ();
+ }"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")])
+
+ (define_insn "*small_parallel"
+ [(group_parallel [(match_insn 0 "small_insn_p")
+ (match_insn 1 "small_insn_p")])]
+ "TARGET_M32RX"
+ "*
+ {
+ abort ();
+ }"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")])
+
+ (define_insn "*long_group"
+ [(group_sequence [(match_insn 0 "large_insn_p")])]
+ ""
+ "*
+ {
+ abort ();
+ }"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")])
+
;; Expand prologue as RTL
(define_expand "prologue"
***************
*** 1126,1139 ****
DONE;
}")
;; 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")))
(clobber (match_scratch:SI 2 "=&r,&r"))]
""
"*
--- 1211,1235 ----
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")))
(clobber (match_scratch:SI 2 "=&r,&r"))]
""
"*
***************
*** 1157,1164 ****
(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")))]
""
"@
cmp %0,%1
--- 1253,1260 ----
(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")))]
""
"@
cmp %0,%1
***************
*** 1168,1175 ****
(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")))]
""
"@
cmpu %0,%1
--- 1264,1271 ----
(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")))]
""
"@
cmpu %0,%1
***************
*** 1177,1182 ****
--- 1273,1279 ----
[(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,1454 ****
""
"*
{
! const char *br,*invbr;
char asmtext[40];
switch (GET_CODE (operands[1]))
--- 1545,1551 ----
""
"*
{
! char *br,*invbr;
char asmtext[40];
switch (GET_CODE (operands[1]))
***************
*** 1495,1501 ****
""
"*
{
! const char *br,*invbr;
char asmtext[40];
switch (GET_CODE (operands[1]))
--- 1592,1598 ----
""
"*
{
! char *br,*invbr;
char asmtext[40];
switch (GET_CODE (operands[1]))
***************
*** 1550,1555 ****
--- 1647,1660 ----
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));
***************
*** 1562,1567 ****
--- 1667,1695 ----
emit_insn (gen_seq_insn (op0, op1, op2));
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")
Index: t-m32r
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/m32r/t-m32r,v
retrieving revision 1.6
diff -p -r1.6 t-m32r
*** t-m32r 2001/05/17 03:16:00 1.6
--- t-m32r 2001/11/06 15:34:34
*************** crtfini.o: $(srcdir)/config/m32r/initfin
*** 36,51 ****
-DCRT_FINI -finhibit-size-directive -fno-inline-functions \
-g0 -mmodel=medium -c $(srcdir)/config/m32r/initfini.c -o 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_MATCHES = mmodel?medium=mmodel?large
-
# Set MULTILIB_EXTRA_OPTS so shipped libraries have small data in .sdata and
# SHN_M32R_SCOMMON.
--- 36,64 ----
-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 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.