Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
2b7972b0
Commit
2b7972b0
authored
Apr 28, 1998
by
Michael Meissner
Committed by
Michael Meissner
Apr 28, 1998
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update m32r port
From-SVN: r19465
parent
77be0cab
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
941 additions
and
144 deletions
+941
-144
gcc/ChangeLog
+57
-0
gcc/config/m32r/m32r.c
+419
-75
gcc/config/m32r/m32r.h
+190
-33
gcc/config/m32r/m32r.md
+271
-34
gcc/config/m32r/t-m32r
+2
-0
gcc/configure
+1
-1
gcc/configure.in
+1
-1
No files found.
gcc/ChangeLog
View file @
2b7972b0
Tue Apr 28 08:55:26 1998 Michael Meissner <meissner@cygnus.com>
* m32r.c (*_oper{and|ator}): Change enum arguments and return
values to int, so they can be prototyped even in files that don't
include rtl.h.
({small,large}_insn_p): Ditto.
(m32r_select_cc_mode): Ditto.
(gen_compare): Ditto.
(function_arg_partial_nregs): Ditto.
(m32r_setup_incoming_varargs): Ditto.
(init_reg_tables): Add prototype.
(m32r_frame_info): Add prolog_size field.
(m32r_compute_frame_size): Calculate the size of the prologue.
(m32r_first_insn_address): Return prologue size.
(m32r_output_function_prologue): Calculate frame size before
printing out information. Print out the prologue size.
* m32r.h: Prototype all functions in m32r.c.
(FIRST_INSN_ADDRESS): Declare, returning prologue size.
* m32r.md (bcc functions): Cast enum's to int.
* m32r.c (conditional_move_operand): Silence a debug message.
({small,long}_insn): New predicates.
* m32r.h (TARGET_M32R): New macro.
(PREDICATE_CODES): Rearrange somewhat, add small_insn/long_insn.
(HAIFA_P): Define as 1/0 depending on whether the Haifa scheduler
was selected.
(ISSUE_RATE): Define as 2.
* m32r.md (insn_size): New attribute.
({,rev_}branch_insn): Add .s qualifier to branches believed to be
short.
(m32r): New attribute.
* configure.in (enable_haifa): Switch m32r to Haifa by default.
* configure: Regenerate.
(Changes from Nick Clifton <nickc@cygnus.com>)
* m32r.h (EXTRA_CONSTRAINT): Implement 'S' constraint to perfoirm
the equivalent of a negated 'I' constraint.
(PRESERVE_DEATH_INFO_REGNO_P): Define in order to allow peephole
optimisation to work.
* m32r.md (cmp_ne_small_const_insn): Use 'S' constriant rather
than 'I' since the value is negated.
(peephole): Add peephole optimisation to cope with optimization of
divide and subtracts of the same operands.
* m32r.c zero_and_one, emit_cond_move): Add support for MVFC.
* m32r.h: Ditto.
* m32r.md: Ditto.
* m32r.h (PREDICATE_CODES): Add declaration of machine specific
predicates.
Tue Apr 28 07:25:53 1998 Manfred Hollstein <manfred@s-direktnet.de>
Tue Apr 28 07:25:53 1998 Manfred Hollstein <manfred@s-direktnet.de>
* Makefile.in (libgcc2.ready): Revert last patch (Apr 24).
* Makefile.in (libgcc2.ready): Revert last patch (Apr 24).
...
...
gcc/config/m32r/m32r.c
View file @
2b7972b0
/* Subroutines used for code generation on the Mitsubishi M32R cpu.
/* Subroutines used for code generation on the Mitsubishi M32R cpu.
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Copyright (C) 1996, 1997
, 1998
Free Software Foundation, Inc.
This file is part of GNU CC.
This file is part of GNU CC.
...
@@ -41,8 +41,6 @@ rtx m32r_compare_op0, m32r_compare_op1;
...
@@ -41,8 +41,6 @@ rtx m32r_compare_op0, m32r_compare_op1;
/* Array of valid operand punctuation characters. */
/* Array of valid operand punctuation characters. */
char
m32r_punct_chars
[
256
];
char
m32r_punct_chars
[
256
];
static
void
init_reg_tables
();
/* Selected code model. */
/* Selected code model. */
char
*
m32r_model_string
=
M32R_MODEL_DEFAULT
;
char
*
m32r_model_string
=
M32R_MODEL_DEFAULT
;
enum
m32r_model
m32r_model
;
enum
m32r_model
m32r_model
;
...
@@ -51,6 +49,10 @@ enum m32r_model m32r_model;
...
@@ -51,6 +49,10 @@ enum m32r_model m32r_model;
char
*
m32r_sdata_string
=
M32R_SDATA_DEFAULT
;
char
*
m32r_sdata_string
=
M32R_SDATA_DEFAULT
;
enum
m32r_sdata
m32r_sdata
;
enum
m32r_sdata
m32r_sdata
;
/* Forward declaration. */
static
void
init_reg_tables
PROTO
((
void
));
/* Called by OVERRIDE_OPTIONS to initialize various things. */
/* Called by OVERRIDE_OPTIONS to initialize various things. */
void
void
...
@@ -84,6 +86,7 @@ m32r_init ()
...
@@ -84,6 +86,7 @@ m32r_init ()
m32r_sdata
=
M32R_SDATA_USE
;
m32r_sdata
=
M32R_SDATA_USE
;
else
else
error
(
"bad value (%s) for -msdata switch"
,
m32r_sdata_string
);
error
(
"bad value (%s) for -msdata switch"
,
m32r_sdata_string
);
}
}
/* Vectors to keep interesting information about registers where it can easily
/* Vectors to keep interesting information about registers where it can easily
...
@@ -95,7 +98,8 @@ m32r_init ()
...
@@ -95,7 +98,8 @@ m32r_init ()
they all fit (as bit numbers) in a 32 bit word (again). Each real mode is
they all fit (as bit numbers) in a 32 bit word (again). Each real mode is
mapped into one m32r_mode_class mode. */
mapped into one m32r_mode_class mode. */
enum
m32r_mode_class
{
enum
m32r_mode_class
{
C_MODE
,
C_MODE
,
S_MODE
,
D_MODE
,
T_MODE
,
O_MODE
,
S_MODE
,
D_MODE
,
T_MODE
,
O_MODE
,
SF_MODE
,
DF_MODE
,
TF_MODE
,
OF_MODE
SF_MODE
,
DF_MODE
,
TF_MODE
,
OF_MODE
...
@@ -113,9 +117,11 @@ enum m32r_mode_class {
...
@@ -113,9 +117,11 @@ enum m32r_mode_class {
/* Modes for quad-word and smaller quantities. */
/* Modes for quad-word and smaller quantities. */
#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
/* Value is 1 if register/mode pair is acceptable on arc. */
/* Value is 1 if register/mode pair is acceptable on arc. */
unsigned
int
m32r_hard_regno_mode_ok
[
FIRST_PSEUDO_REGISTER
]
=
{
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
S_MODES
,
C_MODES
...
@@ -412,21 +418,23 @@ m32r_init_expanders ()
...
@@ -412,21 +418,23 @@ m32r_init_expanders ()
/* Acceptable arguments to the call insn. */
/* Acceptable arguments to the call insn. */
int
int
call_address_operand
(
op
,
mode
)
call_address_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
return
symbolic_operand
(
op
,
mode
);
return
symbolic_operand
(
op
,
int_
mode
);
/* Constants and values in registers are not OK, because
/* Constants and values in registers are not OK, because
the m32r BL instruction can only support PC relative branching. */
the m32r BL instruction can only support PC relative branching. */
}
}
int
int
call_operand
(
op
,
mode
)
call_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
if
(
GET_CODE
(
op
)
!=
MEM
)
if
(
GET_CODE
(
op
)
!=
MEM
)
return
0
;
return
0
;
op
=
XEXP
(
op
,
0
);
op
=
XEXP
(
op
,
0
);
...
@@ -436,9 +444,9 @@ call_operand (op, mode)
...
@@ -436,9 +444,9 @@ call_operand (op, mode)
/* Returns 1 if OP is a symbol reference. */
/* Returns 1 if OP is a symbol reference. */
int
int
symbolic_operand
(
op
,
mode
)
symbolic_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
switch
(
GET_CODE
(
op
))
switch
(
GET_CODE
(
op
))
{
{
...
@@ -446,6 +454,7 @@ symbolic_operand (op, mode)
...
@@ -446,6 +454,7 @@ symbolic_operand (op, mode)
case
LABEL_REF
:
case
LABEL_REF
:
case
CONST
:
case
CONST
:
return
1
;
return
1
;
default
:
default
:
return
0
;
return
0
;
}
}
...
@@ -454,9 +463,9 @@ symbolic_operand (op, mode)
...
@@ -454,9 +463,9 @@ symbolic_operand (op, mode)
/* Return 1 if OP is a reference to an object in .sdata/.sbss. */
/* Return 1 if OP is a reference to an object in .sdata/.sbss. */
int
int
small_data_operand
(
op
,
mode
)
small_data_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
if
(
!
TARGET_SDATA_USE
)
if
(
!
TARGET_SDATA_USE
)
return
0
;
return
0
;
...
@@ -477,9 +486,9 @@ small_data_operand (op, mode)
...
@@ -477,9 +486,9 @@ small_data_operand (op, mode)
/* Return 1 if OP is a symbol that can use 24 bit addressing. */
/* Return 1 if OP is a symbol that can use 24 bit addressing. */
int
int
addr24_operand
(
op
,
mode
)
addr24_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
if
(
GET_CODE
(
op
)
==
LABEL_REF
)
if
(
GET_CODE
(
op
)
==
LABEL_REF
)
return
TARGET_ADDR24
;
return
TARGET_ADDR24
;
...
@@ -509,24 +518,24 @@ addr24_operand (op, mode)
...
@@ -509,24 +518,24 @@ addr24_operand (op, mode)
/* Return 1 if OP is a symbol that needs 32 bit addressing. */
/* Return 1 if OP is a symbol that needs 32 bit addressing. */
int
int
addr32_operand
(
op
,
mode
)
addr32_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
if
(
GET_CODE
(
op
)
==
LABEL_REF
)
if
(
GET_CODE
(
op
)
==
LABEL_REF
)
return
TARGET_ADDR32
;
return
TARGET_ADDR32
;
if
(
GET_CODE
(
op
)
==
SYMBOL_REF
)
if
(
GET_CODE
(
op
)
==
SYMBOL_REF
)
return
(
!
addr24_operand
(
op
)
return
(
!
addr24_operand
(
op
,
int_mode
)
&&
!
small_data_operand
(
op
));
&&
!
small_data_operand
(
op
,
int_mode
));
if
(
GET_CODE
(
op
)
==
CONST
if
(
GET_CODE
(
op
)
==
CONST
&&
GET_CODE
(
XEXP
(
op
,
0
))
==
PLUS
&&
GET_CODE
(
XEXP
(
op
,
0
))
==
PLUS
&&
GET_CODE
(
XEXP
(
XEXP
(
op
,
0
),
0
))
==
SYMBOL_REF
&&
GET_CODE
(
XEXP
(
XEXP
(
op
,
0
),
0
))
==
SYMBOL_REF
&&
GET_CODE
(
XEXP
(
XEXP
(
op
,
0
),
1
))
==
CONST_INT
)
&&
GET_CODE
(
XEXP
(
XEXP
(
op
,
0
),
1
))
==
CONST_INT
)
{
{
return
(
!
addr24_operand
(
op
)
return
(
!
addr24_operand
(
op
,
int_mode
)
&&
!
small_data_operand
(
op
));
&&
!
small_data_operand
(
op
,
int_mode
));
}
}
return
0
;
return
0
;
...
@@ -535,9 +544,9 @@ addr32_operand (op, mode)
...
@@ -535,9 +544,9 @@ addr32_operand (op, mode)
/* Return 1 if OP is a function that can be called with the `bl' insn. */
/* Return 1 if OP is a function that can be called with the `bl' insn. */
int
int
call26_operand
(
op
,
mode
)
call26_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
if
(
GET_CODE
(
op
)
==
SYMBOL_REF
)
if
(
GET_CODE
(
op
)
==
SYMBOL_REF
)
return
!
LARGE_NAME_P
(
XSTR
(
op
,
0
));
return
!
LARGE_NAME_P
(
XSTR
(
op
,
0
));
...
@@ -548,9 +557,9 @@ call26_operand (op, mode)
...
@@ -548,9 +557,9 @@ call26_operand (op, mode)
/* Returns 1 if OP is an acceptable operand for seth/add3. */
/* Returns 1 if OP is an acceptable operand for seth/add3. */
int
int
seth_add3_operand
(
op
,
mode
)
seth_add3_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
if
(
GET_CODE
(
op
)
==
SYMBOL_REF
if
(
GET_CODE
(
op
)
==
SYMBOL_REF
||
GET_CODE
(
op
)
==
LABEL_REF
)
||
GET_CODE
(
op
)
==
LABEL_REF
)
...
@@ -570,9 +579,9 @@ seth_add3_operand (op, mode)
...
@@ -570,9 +579,9 @@ seth_add3_operand (op, mode)
useful in comparisons. */
useful in comparisons. */
int
int
cmp_int16_operand
(
op
,
mode
)
cmp_int16_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
return
0
;
return
0
;
...
@@ -581,10 +590,10 @@ cmp_int16_operand (op, mode)
...
@@ -581,10 +590,10 @@ cmp_int16_operand (op, mode)
/* Return true if OP is an unsigned 16 bit immediate value. */
/* Return true if OP is an unsigned 16 bit immediate value. */
static
int
int
uint16_operand
(
op
,
mode
)
uint16_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
return
0
;
return
0
;
...
@@ -594,10 +603,12 @@ uint16_operand (op, mode)
...
@@ -594,10 +603,12 @@ uint16_operand (op, mode)
/* Return true if OP is a register or signed 8 bit value. */
/* Return true if OP is a register or signed 8 bit value. */
int
int
reg_or_int16_operand
(
op
,
mode
)
reg_or_int16_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
if
(
GET_CODE
(
op
)
==
REG
||
GET_CODE
(
op
)
==
SUBREG
)
if
(
GET_CODE
(
op
)
==
REG
||
GET_CODE
(
op
)
==
SUBREG
)
return
register_operand
(
op
,
mode
);
return
register_operand
(
op
,
mode
);
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
...
@@ -608,10 +619,12 @@ reg_or_int16_operand (op, mode)
...
@@ -608,10 +619,12 @@ reg_or_int16_operand (op, mode)
/* Return true if OP is a register or an unsigned 16 bit value. */
/* Return true if OP is a register or an unsigned 16 bit value. */
int
int
reg_or_uint16_operand
(
op
,
mode
)
reg_or_uint16_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
if
(
GET_CODE
(
op
)
==
REG
||
GET_CODE
(
op
)
==
SUBREG
)
if
(
GET_CODE
(
op
)
==
REG
||
GET_CODE
(
op
)
==
SUBREG
)
return
register_operand
(
op
,
mode
);
return
register_operand
(
op
,
mode
);
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
...
@@ -622,10 +635,12 @@ reg_or_uint16_operand (op, mode)
...
@@ -622,10 +635,12 @@ reg_or_uint16_operand (op, mode)
/* Return true if OP is a register or signed 16 bit value for compares. */
/* Return true if OP is a register or signed 16 bit value for compares. */
int
int
reg_or_cmp_int16_operand
(
op
,
mode
)
reg_or_cmp_int16_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
if
(
GET_CODE
(
op
)
==
REG
||
GET_CODE
(
op
)
==
SUBREG
)
if
(
GET_CODE
(
op
)
==
REG
||
GET_CODE
(
op
)
==
SUBREG
)
return
register_operand
(
op
,
mode
);
return
register_operand
(
op
,
mode
);
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
...
@@ -636,9 +651,9 @@ reg_or_cmp_int16_operand (op, mode)
...
@@ -636,9 +651,9 @@ reg_or_cmp_int16_operand (op, mode)
/* 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
two_insn_const_operand
(
op
,
mode
)
two_insn_const_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
if
(
GET_CODE
(
op
)
!=
CONST_INT
)
return
0
;
return
0
;
...
@@ -653,15 +668,16 @@ two_insn_const_operand (op, mode)
...
@@ -653,15 +668,16 @@ two_insn_const_operand (op, mode)
move source. */
move source. */
int
int
move_src_operand
(
op
,
mode
)
move_src_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
switch
(
GET_CODE
(
op
))
switch
(
GET_CODE
(
op
))
{
{
case
SYMBOL_REF
:
case
SYMBOL_REF
:
case
CONST
:
case
CONST
:
return
addr24_operand
(
op
,
mode
);
return
addr24_operand
(
op
,
int_
mode
);
case
CONST_INT
:
case
CONST_INT
:
/* ??? We allow more cse opportunities if we only allow constants
/* ??? We allow more cse opportunities if we only allow constants
loadable with one insn, and split the rest into two. The instances
loadable with one insn, and split the rest into two. The instances
...
@@ -704,10 +720,11 @@ move_src_operand (op, mode)
...
@@ -704,10 +720,11 @@ move_src_operand (op, mode)
move source. */
move source. */
int
int
move_double_src_operand
(
op
,
mode
)
move_double_src_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
switch
(
GET_CODE
(
op
))
switch
(
GET_CODE
(
op
))
{
{
case
CONST_INT
:
case
CONST_INT
:
...
@@ -722,7 +739,7 @@ move_double_src_operand (op, mode)
...
@@ -722,7 +739,7 @@ move_double_src_operand (op, mode)
/* (subreg (mem ...) ...) can occur here if the inner part was once a
/* (subreg (mem ...) ...) can occur here if the inner part was once a
pseudo-reg and is now a stack slot. */
pseudo-reg and is now a stack slot. */
if
(
GET_CODE
(
SUBREG_REG
(
op
))
==
MEM
)
if
(
GET_CODE
(
SUBREG_REG
(
op
))
==
MEM
)
return
move_double_src_operand
(
SUBREG_REG
(
op
),
mode
);
return
move_double_src_operand
(
SUBREG_REG
(
op
),
int_
mode
);
else
else
return
register_operand
(
op
,
mode
);
return
register_operand
(
op
,
mode
);
case
MEM
:
case
MEM
:
...
@@ -739,10 +756,11 @@ move_double_src_operand (op, mode)
...
@@ -739,10 +756,11 @@ move_double_src_operand (op, mode)
/* Return true if OP is an acceptable argument for a move destination. */
/* Return true if OP is an acceptable argument for a move destination. */
int
int
move_dest_operand
(
op
,
mode
)
move_dest_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
switch
(
GET_CODE
(
op
))
switch
(
GET_CODE
(
op
))
{
{
case
REG
:
case
REG
:
...
@@ -805,9 +823,9 @@ easy_df_const (op)
...
@@ -805,9 +823,9 @@ easy_df_const (op)
/* Return 1 if OP is an EQ or NE comparison operator. */
/* Return 1 if OP is an EQ or NE comparison operator. */
int
int
eqne_comparison_operator
(
op
,
mode
)
eqne_comparison_operator
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
rtx_code
code
=
GET_CODE
(
op
);
enum
rtx_code
code
=
GET_CODE
(
op
);
...
@@ -819,9 +837,9 @@ eqne_comparison_operator (op, mode)
...
@@ -819,9 +837,9 @@ eqne_comparison_operator (op, mode)
/* Return 1 if OP is a signed comparison operator. */
/* Return 1 if OP is a signed comparison operator. */
int
int
signed_comparison_operator
(
op
,
mode
)
signed_comparison_operator
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
enum
rtx_code
code
=
GET_CODE
(
op
);
enum
rtx_code
code
=
GET_CODE
(
op
);
...
@@ -835,35 +853,70 @@ signed_comparison_operator (op, mode)
...
@@ -835,35 +853,70 @@ signed_comparison_operator (op, mode)
This is used in insn length calcs. */
This is used in insn length calcs. */
int
int
memreg_operand
(
op
,
mode
)
memreg_operand
(
op
,
int_
mode
)
rtx
op
;
rtx
op
;
enum
machine_mode
mode
;
int
int_
mode
;
{
{
return
GET_CODE
(
op
)
==
MEM
&&
GET_CODE
(
XEXP
(
op
,
0
))
==
REG
;
return
GET_CODE
(
op
)
==
MEM
&&
GET_CODE
(
XEXP
(
op
,
0
))
==
REG
;
}
}
/* Return non-zero if the operand is an insn that is a small insn.
Allow const_int 0 as well, which is a placeholder for NOP slots. */
int
small_insn_p
(
op
,
int_mode
)
rtx
op
;
int
int_mode
;
{
if
(
GET_CODE
(
op
)
==
CONST_INT
&&
INTVAL
(
op
)
==
0
)
return
1
;
if
(
GET_RTX_CLASS
(
GET_CODE
(
op
))
!=
'i'
)
return
0
;
return
get_attr_length
(
op
)
==
2
;
}
/* Return non-zero if the operand is an insn that is a large insn. */
int
large_insn_p
(
op
,
int_mode
)
rtx
op
;
int
int_mode
;
{
if
(
GET_RTX_CLASS
(
GET_CODE
(
op
))
!=
'i'
)
return
0
;
return
get_attr_length
(
op
)
!=
2
;
}
/* Comparisons. */
/* Comparisons. */
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. */
return the mode to be used for the comparison. */
enum
machine_mode
int
m32r_select_cc_mode
(
op
,
x
,
y
)
m32r_select_cc_mode
(
op
,
x
,
y
)
enum
rtx_code
op
;
int
op
;
rtx
x
,
y
;
rtx
x
,
y
;
{
{
return
CCmode
;
return
(
int
)
CCmode
;
}
}
/* X and Y are two things to compare using CODE. Emit the compare insn and
/* X and Y are two things to compare using CODE. Emit the compare insn and
return the rtx for compare [arg0 of the if_then_else]. */
return the rtx for compare [arg0 of the if_then_else].
If need_compare is true then the comparison insn must be generated, rather
than being susummed into the following branch instruction. */
rtx
rtx
gen_compare
(
code
,
x
,
y
)
gen_compare
(
int_code
,
x
,
y
,
need_compare
)
enum
rtx_code
code
;
int
int_
code
;
rtx
x
;
rtx
x
;
rtx
y
;
rtx
y
;
int
need_compare
;
{
{
enum
rtx_code
code
=
(
enum
rtx_code
)
int_code
;
enum
rtx_code
compare_code
;
enum
rtx_code
compare_code
;
enum
rtx_code
branch_code
;
enum
rtx_code
branch_code
;
enum
machine_mode
mode
=
SELECT_CC_MODE
(
code
,
x
,
y
);
enum
machine_mode
mode
=
SELECT_CC_MODE
(
code
,
x
,
y
);
...
@@ -884,7 +937,122 @@ gen_compare (code, x, y)
...
@@ -884,7 +937,122 @@ gen_compare (code, x, y)
case
GEU
:
compare_code
=
LTU
;
branch_code
=
EQ
;
break
;
case
GEU
:
compare_code
=
LTU
;
branch_code
=
EQ
;
break
;
}
}
if
(
!
TARGET_OLD_COMPARE
)
if
(
need_compare
)
{
switch
(
compare_code
)
{
case
EQ
:
if
(
GET_CODE
(
y
)
==
CONST_INT
&&
CMP_INT16_P
(
INTVAL
(
y
))
/* reg equal to small const. */
&&
y
!=
const0_rtx
)
{
rtx
tmp
=
gen_reg_rtx
(
SImode
);
emit_insn
(
gen_cmp_ne_small_const_insn
(
tmp
,
x
,
y
));
x
=
tmp
;
y
=
const0_rtx
;
}
else
if
(
CONSTANT_P
(
y
))
/* reg equal to const. */
{
rtx
tmp
=
force_reg
(
GET_MODE
(
x
),
y
);
y
=
tmp
;
}
if
(
register_operand
(
y
,
SImode
)
/* reg equal to reg. */
||
y
==
const0_rtx
)
/* req equal to zero. */
{
emit_insn
(
gen_cmp_eqsi_insn
(
x
,
y
));
return
gen_rtx
(
code
,
mode
,
cc_reg
,
const0_rtx
);
}
break
;
case
LT
:
if
(
register_operand
(
y
,
SImode
)
||
(
GET_CODE
(
y
)
==
CONST_INT
&&
CMP_INT16_P
(
INTVAL
(
y
))))
{
rtx
tmp
=
gen_reg_rtx
(
SImode
);
/* reg compared to reg. */
switch
(
code
)
{
case
LT
:
emit_insn
(
gen_cmp_ltsi_insn
(
x
,
y
));
code
=
EQ
;
break
;
case
LE
:
if
(
y
==
const0_rtx
)
tmp
=
const1_rtx
;
else
emit_insn
(
gen_cmp_ne_small_const_insn
(
tmp
,
y
,
const1_rtx
));
emit_insn
(
gen_cmp_ltsi_insn
(
x
,
tmp
));
code
=
EQ
;
break
;
case
GT
:
if
(
GET_CODE
(
y
)
==
CONST_INT
)
tmp
=
gen_rtx
(
PLUS
,
SImode
,
y
,
const1_rtx
);
else
emit_insn
(
gen_cmp_ne_small_const_insn
(
tmp
,
y
,
const1_rtx
));
emit_insn
(
gen_cmp_ltsi_insn
(
x
,
tmp
));
code
=
NE
;
break
;
case
GE
:
emit_insn
(
gen_cmp_ltsi_insn
(
x
,
y
));
code
=
NE
;
break
;
default
:
abort
();
}
return
gen_rtx
(
code
,
mode
,
cc_reg
,
const0_rtx
);
}
break
;
case
LTU
:
if
(
register_operand
(
y
,
SImode
)
||
(
GET_CODE
(
y
)
==
CONST_INT
&&
CMP_INT16_P
(
INTVAL
(
y
))))
{
rtx
tmp
=
gen_reg_rtx
(
SImode
);
/* reg (unsigned) compared to reg. */
switch
(
code
)
{
case
LTU
:
emit_insn
(
gen_cmp_ltusi_insn
(
x
,
y
));
code
=
EQ
;
break
;
case
LEU
:
if
(
y
==
const0_rtx
)
tmp
=
const1_rtx
;
else
emit_insn
(
gen_cmp_ne_small_const_insn
(
tmp
,
y
,
const1_rtx
));
emit_insn
(
gen_cmp_ltusi_insn
(
x
,
tmp
));
code
=
EQ
;
break
;
case
GTU
:
if
(
GET_CODE
(
y
)
==
CONST_INT
)
tmp
=
gen_rtx
(
PLUS
,
SImode
,
y
,
const1_rtx
);
else
emit_insn
(
gen_cmp_ne_small_const_insn
(
tmp
,
y
,
const1_rtx
));
emit_insn
(
gen_cmp_ltusi_insn
(
x
,
tmp
));
code
=
NE
;
break
;
case
GEU
:
emit_insn
(
gen_cmp_ltusi_insn
(
x
,
y
));
code
=
NE
;
break
;
default
:
abort
();
}
return
gen_rtx
(
code
,
mode
,
cc_reg
,
const0_rtx
);
}
break
;
default
:
abort
();
}
}
else
if
(
!
TARGET_OLD_COMPARE
)
{
{
/* reg/reg equal comparison */
/* reg/reg equal comparison */
if
(
compare_code
==
EQ
if
(
compare_code
==
EQ
...
@@ -950,12 +1118,13 @@ gen_compare (code, x, y)
...
@@ -950,12 +1118,13 @@ gen_compare (code, x, y)
/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro. */
/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro. */
int
int
function_arg_partial_nregs
(
cum
,
mode
,
type
,
named
)
function_arg_partial_nregs
(
cum
,
int_
mode
,
type
,
named
)
CUMULATIVE_ARGS
*
cum
;
CUMULATIVE_ARGS
*
cum
;
enum
machine_mode
mode
;
int
int_
mode
;
tree
type
;
tree
type
;
int
named
;
int
named
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
int
ret
;
int
ret
;
int
size
=
(((
mode
==
BLKmode
&&
type
)
int
size
=
(((
mode
==
BLKmode
&&
type
)
?
int_size_in_bytes
(
type
)
?
int_size_in_bytes
(
type
)
...
@@ -979,13 +1148,14 @@ function_arg_partial_nregs (cum, mode, type, named)
...
@@ -979,13 +1148,14 @@ function_arg_partial_nregs (cum, mode, type, named)
and mode MODE, and we rely on this fact. */
and mode MODE, and we rely on this fact. */
void
void
m32r_setup_incoming_varargs
(
cum
,
mode
,
type
,
pretend_size
,
no_rtl
)
m32r_setup_incoming_varargs
(
cum
,
int_
mode
,
type
,
pretend_size
,
no_rtl
)
CUMULATIVE_ARGS
*
cum
;
CUMULATIVE_ARGS
*
cum
;
enum
machine_mode
mode
;
int
int_
mode
;
tree
type
;
tree
type
;
int
*
pretend_size
;
int
*
pretend_size
;
int
no_rtl
;
int
no_rtl
;
{
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
int
first_anon_arg
;
int
first_anon_arg
;
if
(
no_rtl
)
if
(
no_rtl
)
...
@@ -1128,6 +1298,7 @@ struct m32r_frame_info
...
@@ -1128,6 +1298,7 @@ struct m32r_frame_info
unsigned
int
args_size
;
/* # bytes that outgoing arguments take up */
unsigned
int
args_size
;
/* # bytes that outgoing arguments take up */
unsigned
int
reg_size
;
/* # bytes needed to store regs */
unsigned
int
reg_size
;
/* # bytes needed to store regs */
unsigned
int
var_size
;
/* # bytes that variables take up */
unsigned
int
var_size
;
/* # bytes that variables take up */
unsigned
int
prolog_size
;
/* # bytes that the prologue takes up */
unsigned
int
gmask
;
/* mask of saved gp registers */
unsigned
int
gmask
;
/* mask of saved gp registers */
unsigned
int
save_fp
;
/* nonzero if fp must be saved */
unsigned
int
save_fp
;
/* nonzero if fp must be saved */
unsigned
int
save_lr
;
/* nonzero if lr (return addr) must be saved */
unsigned
int
save_lr
;
/* nonzero if lr (return addr) must be saved */
...
@@ -1153,6 +1324,9 @@ static struct m32r_frame_info zero_frame_info;
...
@@ -1153,6 +1324,9 @@ static struct m32r_frame_info zero_frame_info;
#define MUST_SAVE_FRAME_POINTER (regs_ever_live[FRAME_POINTER_REGNUM])
#define MUST_SAVE_FRAME_POINTER (regs_ever_live[FRAME_POINTER_REGNUM])
#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM])
#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM])
#define SHORT_INSN_SIZE 2
/* size of small instructions */
#define LONG_INSN_SIZE 4
/* size of long instructions */
/* Return the bytes needed to compute the frame pointer from the current
/* Return the bytes needed to compute the frame pointer from the current
stack pointer.
stack pointer.
...
@@ -1164,7 +1338,7 @@ m32r_compute_frame_size (size)
...
@@ -1164,7 +1338,7 @@ m32r_compute_frame_size (size)
{
{
int
regno
;
int
regno
;
unsigned
int
total_size
,
var_size
,
args_size
,
pretend_size
,
extra_size
;
unsigned
int
total_size
,
var_size
,
args_size
,
pretend_size
,
extra_size
;
unsigned
int
reg_size
;
unsigned
int
reg_size
,
prolog_size
,
frame_size
;
unsigned
int
gmask
;
unsigned
int
gmask
;
enum
m32r_function_type
fn_type
;
enum
m32r_function_type
fn_type
;
int
interrupt_p
;
int
interrupt_p
;
...
@@ -1175,6 +1349,7 @@ m32r_compute_frame_size (size)
...
@@ -1175,6 +1349,7 @@ m32r_compute_frame_size (size)
extra_size
=
FIRST_PARM_OFFSET
(
0
);
extra_size
=
FIRST_PARM_OFFSET
(
0
);
total_size
=
extra_size
+
pretend_size
+
args_size
+
var_size
;
total_size
=
extra_size
+
pretend_size
+
args_size
+
var_size
;
reg_size
=
0
;
reg_size
=
0
;
prolog_size
=
0
;
gmask
=
0
;
gmask
=
0
;
/* See if this is an interrupt handler. Call used registers must be saved
/* See if this is an interrupt handler. Call used registers must be saved
...
@@ -1204,6 +1379,33 @@ m32r_compute_frame_size (size)
...
@@ -1204,6 +1379,33 @@ m32r_compute_frame_size (size)
handler will do the right thing if this changes total_size. */
handler will do the right thing if this changes total_size. */
total_size
=
M32R_STACK_ALIGN
(
total_size
);
total_size
=
M32R_STACK_ALIGN
(
total_size
);
/* Calculate prologue size. Obviously any changes to
m32r_output_function_prologue must be mirrored here. */
if
(
pretend_size
)
prolog_size
+=
SHORT_INSN_SIZE
;
/* addi sp,-pretend_size */
prolog_size
+=
SHORT_INSN_SIZE
*
(
reg_size
/
UNITS_PER_WORD
);
/* pushes */
frame_size
=
total_size
-
(
pretend_size
+
reg_size
);
if
(
frame_size
==
0
)
;
/* nothing to do */
else
if
(
frame_size
<=
128
)
prolog_size
+=
SHORT_INSN_SIZE
;
/* addi sp,-<frame> */
else
{
if
((
prolog_size
%
LONG_INSN_SIZE
)
!=
0
)
prolog_size
+=
SHORT_INSN_SIZE
;
/* nop */
if
(
frame_size
<=
32768
)
prolog_size
+=
LONG_INSN_SIZE
;
/* add3 sp,sp,-<frame> */
else
prolog_size
+=
(
LONG_INSN_SIZE
/* ld24 tmp,<frame>/sub sp,tmp */
+
SHORT_INSN_SIZE
);
}
if
(
frame_pointer_needed
)
prolog_size
+=
SHORT_INSN_SIZE
;
/* mv fp,sp */
/* Save computed information. */
/* Save computed information. */
current_frame_info
.
total_size
=
total_size
;
current_frame_info
.
total_size
=
total_size
;
current_frame_info
.
extra_size
=
extra_size
;
current_frame_info
.
extra_size
=
extra_size
;
...
@@ -1211,6 +1413,7 @@ m32r_compute_frame_size (size)
...
@@ -1211,6 +1413,7 @@ m32r_compute_frame_size (size)
current_frame_info
.
var_size
=
var_size
;
current_frame_info
.
var_size
=
var_size
;
current_frame_info
.
args_size
=
args_size
;
current_frame_info
.
args_size
=
args_size
;
current_frame_info
.
reg_size
=
reg_size
;
current_frame_info
.
reg_size
=
reg_size
;
current_frame_info
.
prolog_size
=
prolog_size
;
current_frame_info
.
gmask
=
gmask
;
current_frame_info
.
gmask
=
gmask
;
current_frame_info
.
initialized
=
reload_completed
;
current_frame_info
.
initialized
=
reload_completed
;
...
@@ -1218,7 +1421,22 @@ m32r_compute_frame_size (size)
...
@@ -1218,7 +1421,22 @@ m32r_compute_frame_size (size)
return
total_size
;
return
total_size
;
}
}
/* Set up the stack and frame pointer (if desired) for the function. */
/* When the `length' insn attribute is used, this macro specifies the
value to be assigned to the address of the first insn in a
function. If not specified, 0 is used. */
int
m32r_first_insn_address
()
{
if
(
!
current_frame_info
.
initialized
)
m32r_compute_frame_size
(
get_frame_size
());
return
current_frame_info
.
prolog_size
;
}
/* Set up the stack and frame pointer (if desired) for the function.
Note, if this is changed, you need to mirror the changes in
m32r_compute_frame_size which calculates the prolog size. */
void
void
m32r_output_function_prologue
(
file
,
size
)
m32r_output_function_prologue
(
file
,
size
)
...
@@ -1239,17 +1457,19 @@ m32r_output_function_prologue (file, size)
...
@@ -1239,17 +1457,19 @@ m32r_output_function_prologue (file, size)
ASM_COMMENT_START
);
ASM_COMMENT_START
);
}
}
total_size
=
(
!
current_frame_info
.
initialized
?
m32r_compute_frame_size
(
size
)
:
current_frame_info
.
total_size
);
/* This is only for the human reader. */
/* This is only for the human reader. */
fprintf
(
file
,
"
\t
%s BEGIN PROLOGUE %s vars= %d, regs= %d, args= %d, extra= %d
\n
"
,
fprintf
(
file
,
ASM_COMMENT_START
,
ASM_COMMENT_START
,
"
\t
%s BEGIN PROLOGUE, vars= %d, regs= %d, args= %d, extra= %d, prolog= %d
\n
"
,
ASM_COMMENT_START
,
current_frame_info
.
var_size
,
current_frame_info
.
var_size
,
current_frame_info
.
reg_size
/
4
,
current_frame_info
.
reg_size
/
4
,
current_frame_info
.
args_size
,
current_frame_info
.
args_size
,
current_frame_info
.
extra_size
);
current_frame_info
.
extra_size
,
current_frame_info
.
prolog_size
);
total_size
=
(
!
current_frame_info
.
initialized
?
m32r_compute_frame_size
(
size
)
:
current_frame_info
.
total_size
);
/* These cases shouldn't happen. Catch them now. */
/* These cases shouldn't happen. Catch them now. */
if
(
total_size
==
0
&&
gmask
)
if
(
total_size
==
0
&&
gmask
)
...
@@ -1767,3 +1987,127 @@ m32r_print_operand_address (file, addr)
...
@@ -1767,3 +1987,127 @@ m32r_print_operand_address (file, addr)
break
;
break
;
}
}
}
}
/* Return true if the operands are the constants 0 and 1. */
int
zero_and_one
(
operand1
,
operand2
)
rtx
operand1
;
rtx
operand2
;
{
return
GET_CODE
(
operand1
)
==
CONST_INT
&&
GET_CODE
(
operand2
)
==
CONST_INT
&&
(
((
INTVAL
(
operand1
)
==
0
)
&&
(
INTVAL
(
operand2
)
==
1
))
||
((
INTVAL
(
operand1
)
==
1
)
&&
(
INTVAL
(
operand2
)
==
0
)));
}
/* Return non-zero if the operand is suitable for use in a conditional move sequence. */
int
conditional_move_operand
(
operand
,
int_mode
)
rtx
operand
;
int
int_mode
;
{
enum
machine_mode
mode
=
(
enum
machine_mode
)
int_mode
;
/* Only defined for simple integers so far... */
if
(
mode
!=
SImode
&&
mode
!=
HImode
&&
mode
!=
QImode
)
return
FALSE
;
/* At the moment we can hanndle moving registers and loading constants. */
/* To be added: Addition/subtraction/bitops/multiplication of registers. */
switch
(
GET_CODE
(
operand
))
{
case
REG
:
return
1
;
case
CONST_INT
:
return
INT8_P
(
INTVAL
(
operand
));
default
:
#if 0
fprintf (stderr, "Test for cond move op of type: %s\n",
GET_RTX_NAME (GET_CODE (operand)));
#endif
return
0
;
}
}
/* Return true if the code is a test of the carry bit */
int
carry_compare_operand
(
op
,
int_mode
)
rtx
op
;
int
int_mode
;
{
rtx
x
;
if
(
GET_MODE
(
op
)
!=
CCmode
&&
GET_MODE
(
op
)
!=
VOIDmode
)
return
FALSE
;
if
(
GET_CODE
(
op
)
!=
NE
&&
GET_CODE
(
op
)
!=
EQ
)
return
FALSE
;
x
=
XEXP
(
op
,
0
);
if
(
GET_CODE
(
x
)
!=
REG
||
REGNO
(
x
)
!=
CARRY_REGNUM
)
return
FALSE
;
x
=
XEXP
(
op
,
1
);
if
(
GET_CODE
(
x
)
!=
CONST_INT
||
INTVAL
(
x
)
!=
0
)
return
FALSE
;
return
TRUE
;
}
/* Generate the correct assembler code to handle the conditional loading of a
value into a register. It is known that the operands satisfy the
conditional_move_operand() function above. The destination is operand[0].
The condition is operand [1]. The 'true' value is operand [2] and the
'false' value is operand [3]. */
char
*
emit_cond_move
(
operands
,
insn
)
rtx
*
operands
;
rtx
insn
;
{
static
char
buffer
[
100
];
buffer
[
0
]
=
0
;
/* Destination must be a register. */
if
(
GET_CODE
(
operands
[
0
])
!=
REG
)
abort
();
if
(
!
conditional_move_operand
(
operands
[
2
],
SImode
))
abort
();
if
(
!
conditional_move_operand
(
operands
[
3
],
SImode
))
abort
();
/* Check to see if the test is reversed. */
if
(
GET_CODE
(
operands
[
1
])
==
NE
)
{
rtx
tmp
=
operands
[
2
];
operands
[
2
]
=
operands
[
3
];
operands
[
3
]
=
tmp
;
}
/* Catch a special case where 0 or 1 is being loaded into the destination.
Since we already have these values in the C bit we can use a special
instruction. */
if
(
zero_and_one
(
operands
[
2
],
operands
[
3
]))
{
char
*
dest
=
reg_names
[
REGNO
(
operands
[
0
])];
sprintf
(
buffer
,
"mvfc %s, cbr"
,
dest
);
/* If the true value was '0' then we need to invert the results of the move. */
if
(
INTVAL
(
operands
[
2
])
==
0
)
sprintf
(
buffer
+
strlen
(
buffer
),
"
\n\t
xor3 %s, %s, #1"
,
dest
,
dest
);
return
buffer
;
}
return
buffer
;
}
gcc/config/m32r/m32r.h
View file @
2b7972b0
/* Definitions of target machine for GNU compiler, Mitsubishi M32R cpu.
/* Definitions of target machine for GNU compiler, Mitsubishi M32R cpu.
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Copyright (C) 1996, 1997
, 1998
Free Software Foundation, Inc.
This file is part of GNU CC.
This file is part of GNU CC.
...
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA. */
...
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA. */
/* Print subsidiary information on the compiler version in use. */
/* Print subsidiary information on the compiler version in use. */
#define TARGET_VERSION fprintf (stderr, " (m32r)")
#define TARGET_VERSION fprintf (stderr, " (m32r)")
/* Switch Recognition by gcc.c. Add -G xx support */
/* Switch Recognition by gcc.c. Add -G xx support */
#undef SWITCH_TAKES_ARG
#undef SWITCH_TAKES_ARG
...
@@ -48,17 +49,18 @@ Boston, MA 02111-1307, USA. */
...
@@ -48,17 +49,18 @@ Boston, MA 02111-1307, USA. */
/* __M32R__ is defined by the existing compiler so we use that. */
/* __M32R__ is defined by the existing compiler so we use that. */
#define CPP_PREDEFINES "-Acpu(m32r) -Amachine(m32r) -D__M32R__"
#define CPP_PREDEFINES "-Acpu(m32r) -Amachine(m32r) -D__M32R__"
/* Additional flags for the preprocessor. */
#define CPP_SPEC ""
#define CC1_SPEC "%{G*}"
#define CC1_SPEC "%{G*}"
#undef ASM_SPEC
/* Options to pass on to the assembler. */
#undef ASM_SPEC
#define ASM_SPEC "%{v}"
#if 0 /* not supported yet */
#if 0 /* not supported yet */
#undef ASM_SPEC
#define ASM_SPEC "%{v} %{mrelax:-relax}"
#define ASM_SPEC "%{v} %{mrelax:-relax}"
#else
#define ASM_SPEC "%{v}"
#endif
#endif
#undef ASM_FINAL_SPEC
#undef ASM_FINAL_SPEC
...
@@ -72,9 +74,11 @@ Boston, MA 02111-1307, USA. */
...
@@ -72,9 +74,11 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared:crt0.o%s crtsysc.o%s} crtinit.o%s"
#define STARTFILE_SPEC "%{!shared:crt0.o%s crtsysc.o%s} crtinit.o%s"
#undef ENDFILE_SPEC
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtfini.o%s"
#define ENDFILE_SPEC "crtfini.o%s"
#undef LIB_SPEC
#undef LIB_SPEC
/* Run-time compilation parameters selecting different hardware subsets. */
/* Run-time compilation parameters selecting different hardware subsets. */
...
@@ -105,6 +109,10 @@ extern int target_flags;
...
@@ -105,6 +109,10 @@ extern int target_flags;
#define TARGET_OLD_COMPARE_MASK 8
#define TARGET_OLD_COMPARE_MASK 8
#define TARGET_OLD_COMPARE (target_flags & TARGET_OLD_COMPARE_MASK)
#define TARGET_OLD_COMPARE (target_flags & TARGET_OLD_COMPARE_MASK)
/* Target machine to compile for. */
#define TARGET_M32R 1
/* 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 }
...
@@ -147,6 +155,8 @@ extern int target_flags;
...
@@ -147,6 +155,8 @@ extern int target_flags;
extern
char
*
m32r_model_string
;
extern
char
*
m32r_model_string
;
extern
char
*
m32r_sdata_string
;
extern
char
*
m32r_sdata_string
;
#define TARGET_OPTIONS \
#define TARGET_OPTIONS \
{ \
{ \
{ "model=", &m32r_model_string }, \
{ "model=", &m32r_model_string }, \
...
@@ -239,10 +249,10 @@ extern enum m32r_sdata m32r_sdata;
...
@@ -239,10 +249,10 @@ extern enum m32r_sdata m32r_sdata;
#define M32R_SDATA_DEFAULT "none"
#define M32R_SDATA_DEFAULT "none"
/* Define this macro as a C expression for the initializer of an array of
/* Define this macro as a C expression for the initializer of an array of
string to tell the driver program which options are defaults for this
string
s
to tell the driver program which options are defaults for this
target and thus do not need to be handled specially when using
target and thus do not need to be handled specially when using
`MULTILIB_OPTIONS'. */
`MULTILIB_OPTIONS'. */
#define MULTILIB_DEFAULTS { "mmodel=small" }
#define MULTILIB_DEFAULTS { "mmodel=small"
, "m32r"
}
/* Sometimes certain combinations of command options do not make
/* Sometimes certain combinations of command options do not make
sense on a particular target machine. You can define a macro
sense on a particular target machine. You can define a macro
...
@@ -253,8 +263,6 @@ extern enum m32r_sdata m32r_sdata;
...
@@ -253,8 +263,6 @@ extern enum m32r_sdata m32r_sdata;
Don't use this macro to turn on various extra optimizations for
Don't use this macro to turn on various extra optimizations for
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
extern
void
m32r_init
();
#define OVERRIDE_OPTIONS \
#define OVERRIDE_OPTIONS \
do { \
do { \
/* These need to be done at start up. It's convenient to do them here. */
\
/* These need to be done at start up. It's convenient to do them here. */
\
...
@@ -404,7 +412,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
...
@@ -404,7 +412,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
All registers that the compiler knows about must be given numbers,
All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers. */
even those that are not normally considered general registers. */
#define FIRST_PSEUDO_REGISTER 18
#define FIRST_PSEUDO_REGISTER 18
/* 1 for registers that have pervasive standard uses
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
and are not available for the register allocator.
...
@@ -420,6 +428,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
...
@@ -420,6 +428,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
16 - arg pointer
16 - arg pointer
17 - carry flag
17 - carry flag
By default, the extension registers are not available. */
By default, the extension registers are not available. */
#define FIXED_REGISTERS \
#define FIXED_REGISTERS \
...
@@ -427,6 +436,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
...
@@ -427,6 +436,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
0, 0, 0, 0, 0, 0, 0, 1, \
0, 0, 0, 0, 0, 0, 0, 1, \
1, 0 }
1, 0 }
/* 1 for registers not available across function calls.
/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
These must include the FIXED_REGISTERS and also any
registers that can be used without being saved.
registers that can be used without being saved.
...
@@ -439,6 +449,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
...
@@ -439,6 +449,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \
0, 0, 0, 0, 0, 0, 1, 1, \
0, 0, 0, 0, 0, 0, 1, 1, \
1, 1 }
1, 1 }
/* Zero or more C statements that may conditionally modify two variables
/* Zero or more C statements that may conditionally modify two variables
`fixed_regs' and `call_used_regs' (both of type `char []') after they
`fixed_regs' and `call_used_regs' (both of type `char []') after they
have been initialized from the two preceding macros.
have been initialized from the two preceding macros.
...
@@ -531,11 +542,12 @@ enum reg_class {
...
@@ -531,11 +542,12 @@ enum reg_class {
#define REG_CLASS_CONTENTS \
#define REG_CLASS_CONTENTS \
{ {0}, {0x20000}, {0x1ffff}, {0x3ffff} }
{ {0}, {0x20000}, {0x1ffff}, {0x3ffff} }
/* The same information, inverted:
/* The same information, inverted:
Return the class number of the smallest class containing
Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
reg number REGNO. This could be a conditional expression
or could index an array. */
or could index an array. */
extern
enum
reg_class
m32r_regno_reg_class
[];
extern
enum
reg_class
m32r_regno_reg_class
[
FIRST_PSEUDO_REGISTER
];
#define REGNO_REG_CLASS(REGNO) \
#define REGNO_REG_CLASS(REGNO) \
(m32r_regno_reg_class[REGNO])
(m32r_regno_reg_class[REGNO])
...
@@ -622,7 +634,11 @@ extern enum reg_class m32r_regno_reg_class[];
...
@@ -622,7 +634,11 @@ extern enum reg_class m32r_regno_reg_class[];
C. If C is not defined as an extra constraint, the value returned should
C. If C is not defined as an extra constraint, the value returned should
be 0 regardless of VALUE. */
be 0 regardless of VALUE. */
/* Q is for symbolic addresses loadable with ld24.
/* Q is for symbolic addresses loadable with ld24.
R is for symbolic addresses when ld24 can't be used. */
R is for symbolic addresses when ld24 can't be used.
S is for an 8 bit signed integer in the range +128 to -127 */
#define INVERTED_SIGNED_8BIT(VAL) ((VAL) >= -127 && (VAL) <= 128)
#define EXTRA_CONSTRAINT(VALUE, C) \
#define EXTRA_CONSTRAINT(VALUE, C) \
((C) == 'Q' \
((C) == 'Q' \
? ((TARGET_ADDR24 && GET_CODE (VALUE) == LABEL_REF) \
? ((TARGET_ADDR24 && GET_CODE (VALUE) == LABEL_REF) \
...
@@ -630,6 +646,8 @@ extern enum reg_class m32r_regno_reg_class[];
...
@@ -630,6 +646,8 @@ extern enum reg_class m32r_regno_reg_class[];
: (C) == 'R' \
: (C) == 'R' \
? ((TARGET_ADDR32 && GET_CODE (VALUE) == LABEL_REF) \
? ((TARGET_ADDR32 && GET_CODE (VALUE) == LABEL_REF) \
|| addr32_operand (VALUE, VOIDmode)) \
|| addr32_operand (VALUE, VOIDmode)) \
: (C) == 'S' \
? ((GET_CODE (VALUE) == CONST_INT) && INVERTED_SIGNED_8BIT (INTVAL (VALUE))) \
: 0)
: 0)
/* Stack layout and stack pointer usage. */
/* Stack layout and stack pointer usage. */
...
@@ -717,6 +735,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
...
@@ -717,6 +735,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
#define CARRY_REGNUM 17
#define CARRY_REGNUM 17
#define M32R_MAX_INT_REGS 16
#define M32R_MAX_INT_REGS 16
#define GPR_P(REGNO) ((unsigned) (REGNO) < M32R_MAX_INT_REGS)
#define GPR_P(REGNO) ((unsigned) (REGNO) < M32R_MAX_INT_REGS)
/* Eliminating the frame and arg pointers. */
/* Eliminating the frame and arg pointers. */
...
@@ -907,7 +926,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
...
@@ -907,7 +926,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
compiler when this occurs, and how many of the words should go in
compiler when this occurs, and how many of the words should go in
registers. */
registers. */
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
function_arg_partial_nregs (&CUM,
(int)
MODE, TYPE, NAMED)
/* A C expression that indicates when an argument must be passed by
/* A C expression that indicates when an argument must be passed by
reference. If nonzero for an argument, a copy of that argument is
reference. If nonzero for an argument, a copy of that argument is
...
@@ -1218,9 +1237,8 @@ do { \
...
@@ -1218,9 +1237,8 @@ do { \
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. */
return the mode to be used for the comparison. */
extern
enum
machine_mode
m32r_select_cc_mode
();
#define SELECT_CC_MODE(OP, X, Y) \
#define SELECT_CC_MODE(OP, X, Y) \
m32r_select_cc_mode (OP, X, Y
)
((enum machine_mode)m32r_select_cc_mode ((int)OP, X, Y)
)
/* Return non-zero if SELECT_CC_MODE will never return MODE for a
/* Return non-zero if SELECT_CC_MODE will never return MODE for a
floating point inequality comparison. */
floating point inequality comparison. */
...
@@ -1313,6 +1331,38 @@ m32r_select_cc_mode (OP, X, Y)
...
@@ -1313,6 +1331,38 @@ m32r_select_cc_mode (OP, X, Y)
the improvement wasn't significant and in a couple of cases caused a
the improvement wasn't significant and in a couple of cases caused a
significant de-optimization. */
significant de-optimization. */
/* #define ENABLE_REGMOVE_PASS */
/* #define ENABLE_REGMOVE_PASS */
/* A C statement (sans semicolon) to update the integer variable COST based on
the relationship between INSN that is dependent on DEP_INSN through the
dependence LINK. The default is to make no adjustment to COST. This can be
used for example to specify to the scheduler that an output- or
anti-dependence does not incur the same cost as a data-dependence. */
/* #define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
(COST) = m32r_adjust_cost (INSN, LINK, DEP_INSN, COST) */
/* A C statement (sans semicolon) to update the integer scheduling
priority `INSN_PRIORITY(INSN)'. Reduce the priority to execute
the INSN earlier, increase the priority to execute INSN later.
Do not define this macro if you do not need to adjust the
scheduling priorities of insns. */
/* #define ADJUST_PRIORITY (INSN) */
/* Macro to determine whether the Haifa scheduler is used. */
#ifdef HAIFA
#define HAIFA_P 1
#else
#define HAIFA_P 0
#endif
/* Indicate how many instructions can be issued at the same time. */
#define ISSUE_RATE 2
/* When the `length' insn attribute is used, this macro specifies the
value to be assigned to the address of the first insn in a
function. If not specified, 0 is used. */
#define FIRST_INSN_ADDRESS m32r_first_insn_address ()
/* Section selection. */
/* Section selection. */
...
@@ -1344,7 +1394,7 @@ DTORS_SECTION_FUNCTION \
...
@@ -1344,7 +1394,7 @@ DTORS_SECTION_FUNCTION \
SDATA_SECTION_FUNCTION \
SDATA_SECTION_FUNCTION \
SBSS_SECTION_FUNCTION
SBSS_SECTION_FUNCTION
#define SDATA_SECTION_FUNCTION
\
#define SDATA_SECTION_FUNCTION
\
void \
void \
sdata_section () \
sdata_section () \
{ \
{ \
...
@@ -1355,7 +1405,7 @@ sdata_section () \
...
@@ -1355,7 +1405,7 @@ sdata_section () \
} \
} \
} \
} \
#define SBSS_SECTION_FUNCTION
\
#define SBSS_SECTION_FUNCTION
\
void \
void \
sbss_section () \
sbss_section () \
{ \
{ \
...
@@ -1429,7 +1479,6 @@ extern void m32r_select_section ();
...
@@ -1429,7 +1479,6 @@ extern void m32r_select_section ();
|| MEDIUM_NAME_P (SYMBOL_NAME) \
|| MEDIUM_NAME_P (SYMBOL_NAME) \
|| LARGE_NAME_P (SYMBOL_NAME))
|| LARGE_NAME_P (SYMBOL_NAME))
extern
void
m32r_encode_section_info
();
#define ENCODE_SECTION_INFO(DECL) m32r_encode_section_info (DECL)
#define ENCODE_SECTION_INFO(DECL) m32r_encode_section_info (DECL)
/* Decode SYM_NAME and store the real name part in VAR, sans
/* Decode SYM_NAME and store the real name part in VAR, sans
...
@@ -1487,7 +1536,6 @@ do { \
...
@@ -1487,7 +1536,6 @@ do { \
/* Control the assembler format that we output. */
/* Control the assembler format that we output. */
/* Output at beginning of assembler file. */
/* Output at beginning of assembler file. */
extern
void
m32r_asm_file_start
();
#define ASM_FILE_START(FILE) m32r_asm_file_start (FILE)
#define ASM_FILE_START(FILE) m32r_asm_file_start (FILE)
/* A C string constant describing how to begin a comment in the target
/* A C string constant describing how to begin a comment in the target
...
@@ -1582,7 +1630,7 @@ do { \
...
@@ -1582,7 +1630,7 @@ do { \
#undef ASM_OUTPUT_LABELREF
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
do { \
do { \
char *real_name; \
char *
real_name; \
STRIP_NAME_ENCODING (real_name, (NAME)); \
STRIP_NAME_ENCODING (real_name, (NAME)); \
fprintf (FILE, "%s%s", USER_LABEL_PREFIX, real_name); \
fprintf (FILE, "%s%s", USER_LABEL_PREFIX, real_name); \
} while (0)
} while (0)
...
@@ -1713,8 +1761,6 @@ do { \
...
@@ -1713,8 +1761,6 @@ do { \
handling the required alignment of the variable. The alignment is
handling the required alignment of the variable. The alignment is
specified as the number of bits. */
specified as the number of bits. */
extern void sbss_section ();
#undef ASM_OUTPUT_ALIGNED_LOCAL
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { \
do { \
...
@@ -1833,35 +1879,146 @@ do { \
...
@@ -1833,35 +1879,146 @@ do { \
/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
is a valid machine specific attribute for DECL.
is a valid machine specific attribute for DECL.
The attributes in ATTRIBUTES have previously been assigned to TYPE. */
The attributes in ATTRIBUTES have previously been assigned to TYPE. */
extern
int
m32r_valid_machine_attribute
();
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
m32r_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
m32r_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
/* A C expression that returns zero if the attributes on TYPE1 and TYPE2 are
/* A C expression that returns zero if the attributes on TYPE1 and TYPE2 are
incompatible, one if they are compatible, and two if they are
incompatible, one if they are compatible, and two if they are
nearly compatible (which causes a warning to be generated). */
nearly compatible (which causes a warning to be generated). */
extern
int
m32r_comp_type_attributes
();
#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
m32r_comp_type_attributes (TYPE1, TYPE2)
m32r_comp_type_attributes (TYPE1, TYPE2)
/* Give newly defined TYPE some default attributes. */
/* Give newly defined TYPE some default attributes. */
extern
void
m32r_set_default_type_attributes
();
#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
m32r_set_default_type_attributes (TYPE)
m32r_set_default_type_attributes (TYPE)
/* Define the information needed to generate branch and scc insns. This is
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. Note that we can't use "rtx" here
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
since it hasn't been defined! */
extern
struct
rtx_def
*
m32r_compare_op0
,
*
m32r_compare_op1
;
extern
struct
rtx_def
*
m32r_compare_op0
;
extern
struct
rtx_def
*
m32r_compare_op1
;
/* Define the function that build the compare insn for scc and bcc. */
extern
struct
rtx_def
*
gen_compare
();
/* M32R function types. */
/* M32R function types. */
enum
m32r_function_type
{
enum
m32r_function_type
{
M32R_FUNCTION_UNKNOWN
,
M32R_FUNCTION_NORMAL
,
M32R_FUNCTION_INTERRUPT
M32R_FUNCTION_UNKNOWN
,
M32R_FUNCTION_NORMAL
,
M32R_FUNCTION_INTERRUPT
};
};
#define M32R_INTERRUPT_P(TYPE) \
#define M32R_INTERRUPT_P(TYPE) \
((TYPE) == M32R_FUNCTION_INTERRUPT)
((TYPE) == M32R_FUNCTION_INTERRUPT)
/* Compute the type of a function from its DECL. */
enum
m32r_function_type
m32r_compute_function_type
();
/* Define this if you have defined special-purpose predicates in the
file `MACHINE.c'. This macro is called within an initializer of an
array of structures. The first field in the structure is the name
of a predicate and the second field is an array of rtl codes. For
each predicate, list all rtl codes that can be in expressions
matched by the predicate. The list should have a trailing comma. */
#define PREDICATE_CODES \
{ "conditional_move_operand", { REG, SUBREG, CONST_INT }}, \
{ "carry_compare_operand", { EQ, NE }}, \
{ "eqne_comparison_operator", { EQ, NE }}, \
{ "signed_comparison_operator", { EQ, NE, LT, LE, GT, GE }}, \
{ "move_dest_operand", { REG, SUBREG, MEM }}, \
{ "move_src_operand", { REG, SUBREG, MEM, CONST_INT, \
CONST_DOUBLE, LABEL_REF, CONST, \
SYMBOL_REF }}, \
{ "move_double_src_operand", { REG, SUBREG, MEM, CONST_INT, \
CONST_DOUBLE }}, \
{ "two_insn_const_operand", { CONST_INT }}, \
{ "symbolic_operand", { SYMBOL_REF, LABEL_REF, CONST }}, \
{ "reg_or_int16_operand", { REG, SUBREG, CONST_INT }}, \
{ "reg_or_uint16_operand", { REG, SUBREG, CONST_INT }}, \
{ "reg_or_cmp_int16_operand", { REG, SUBREG, CONST_INT }}, \
{ "reg_or_zero_operand", { REG, SUBREG, CONST_INT }}, \
{ "cmp_int16_operand", { CONST_INT }}, \
{ "call_address_operand", { SYMBOL_REF, LABEL_REF, CONST }}, \
{ "small_insn_p", { INSN, CALL_INSN, JUMP_INSN }}, \
{ "large_insn_p", { INSN, CALL_INSN, JUMP_INSN }},
/* Functions declared in m32r.c */
#ifndef PROTO
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
#define PROTO(ARGS) ARGS
#else
#define PROTO(ARGS) ()
#endif
#endif
#ifdef BUFSIZE
/* stdio.h has been included, ok to use FILE * */
#define STDIO_PROTO(ARGS) PROTO(ARGS)
#else
#define STDIO_PROTO(ARGS) ()
#endif
#ifndef TREE_CODE
union
tree_node
;
#define Tree union tree_node *
#else
#define Tree tree
#endif
#ifndef RTX_CODE
struct
rtx_def
;
#define Rtx struct rtx_def *
#else
#define Rtx rtx
#endif
extern
void
sbss_section
PROTO
((
void
));
extern
void
sdata_section
PROTO
((
void
));
extern
void
m32r_init
PROTO
((
void
));
extern
int
m32r_valid_machine_decl_attribute
PROTO
((
Tree
,
Tree
,
Tree
,
Tree
));
extern
int
m32r_comp_type_attributes
PROTO
((
Tree
,
Tree
));
extern
void
m32r_select_section
PROTO
((
Tree
,
int
));
extern
void
m32r_encode_section_info
PROTO
((
Tree
));
extern
void
m32r_init_expanders
PROTO
((
void
));
extern
int
call_address_operand
PROTO
((
Rtx
,
int
));
extern
int
call_operand
PROTO
((
Rtx
,
int
));
extern
int
symbolic_operand
PROTO
((
Rtx
,
int
));
extern
int
small_data_operand
PROTO
((
Rtx
,
int
));
extern
int
addr24_operand
PROTO
((
Rtx
,
int
));
extern
int
addr32_operand
PROTO
((
Rtx
,
int
));
extern
int
call26_operand
PROTO
((
Rtx
,
int
));
extern
int
seth_add3_operand
PROTO
((
Rtx
,
int
));
extern
int
cmp_int16_operand
PROTO
((
Rtx
,
int
));
extern
int
uint16_operand
PROTO
((
Rtx
,
int
));
extern
int
reg_or_int16_operand
PROTO
((
Rtx
,
int
));
extern
int
reg_or_uint16_operand
PROTO
((
Rtx
,
int
));
extern
int
reg_or_cmp_nt16_operand
PROTO
((
Rtx
,
int
));
extern
int
two_insn_const_operand
PROTO
((
Rtx
,
int
));
extern
int
move_src_operand
PROTO
((
Rtx
,
int
));
extern
int
move_double_src_operand
PROTO
((
Rtx
,
int
));
extern
int
move_dest_operand
PROTO
((
Rtx
,
int
));
extern
int
easy_di_const
PROTO
((
Rtx
));
extern
int
easy_df_const
PROTO
((
Rtx
));
extern
int
eqne_comparison_operator
PROTO
((
Rtx
,
int
));
extern
int
signed_comparison_operator
PROTO
((
Rtx
,
int
));
extern
int
memreg_operand
PROTO
((
Rtx
,
int
));
extern
int
small_insn_p
PROTO
((
Rtx
,
int
));
extern
int
large_insn_p
PROTO
((
Rtx
,
int
));
extern
int
m32r_select_cc_mode
PROTO
((
int
,
Rtx
,
Rtx
));
extern
Rtx
gen_compare
PROTO
((
int
,
Rtx
,
Rtx
,
int
));
extern
int
function_arg_partial_nregs
PROTO
((
CUMULATIVE_ARGS
*
,
int
,
Tree
,
int
));
extern
void
m32r_setup_incoming_varargs
PROTO
((
CUMULATIVE_ARGS
*
,
int
,
Tree
,
int
*
,
int
));
extern
int
m32r_address_code
PROTO
((
Rtx
));
extern
enum
m32r_function_type
m32r_compute_function_type
PROTO
((
Tree
));
extern
unsigned
m32r_compute_frame_size
PROTO
((
int
));
extern
int
m32r_first_insn_address
PROTO
((
void
));
extern
void
m32r_output_function_prologue
STDIO_PROTO
((
FILE
*
,
int
));
extern
void
m32r_output_function_epilogue
STDIO_PROTO
((
FILE
*
,
int
));
extern
void
m32r_finalize_pic
PROTO
((
void
));
extern
void
m32r_initialize_trampoline
PROTO
((
Rtx
,
Rtx
,
Rtx
));
extern
void
m32r_asm_file_start
STDIO_PROTO
((
FILE
*
));
extern
void
m32r_print_operand
STDIO_PROTO
((
FILE
*
,
Rtx
,
int
));
extern
void
m32r_print_operand_address
STDIO_PROTO
((
FILE
*
,
Rtx
));
extern
int
zero_and_one
PROTO
((
Rtx
,
Rtx
));
extern
int
conditional_move_operand
PROTO
((
Rtx
,
int
));
extern
int
carry_compare_operand
PROTO
((
Rtx
,
int
));
extern
char
*
emit_cond_move
PROTO
((
Rtx
*
,
Rtx
));
/* Needed by a peephole optimisation. */
#define PRESERVE_DEATH_INFO_REGNO_P(regno) (regno < FIRST_PSEUDO_REGISTER)
gcc/config/m32r/m32r.md
View file @
2b7972b0
;; Machine description of the Mitsubishi M32R cpu for GNU C compiler
;; Machine description of the Mitsubishi M32R cpu for GNU C compiler
;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
;; Copyright (C) 1996, 1997
, 1998
Free Software Foundation, Inc.
;; This file is part of GNU CC.
;; This file is part of GNU CC.
...
@@ -65,11 +65,135 @@
...
@@ -65,11 +65,135 @@
(define_asm_attributes
(define_asm_attributes
[
(set_attr "length" "4")
[
(set_attr "length" "4")
(set_attr "type" "multi")])
(set_attr "type" "multi")])
;; Whether an instruction is 16-bit or 32-bit
(define_attr "insn_size" "short,long"
(if_then_else (eq_attr "length" "2")
(const_string "short")
(const_string "long")))
(define_attr "m32r" "no,yes"
(const (symbol_ref "(TARGET_M32R != 0)")))
;; ::::::::::::::::::::
;; ::
;; :: Function Units
;; ::
;; ::::::::::::::::::::
;; On most RISC machines, there are instructions whose results are not
;; available for a specific number of cycles. Common cases are instructions
;; that load data from memory. On many machines, a pipeline stall will result
;; if the data is referenced too soon after the load instruction.
;; In addition, many newer microprocessors have multiple function units,
;; usually one for integer and one for floating point, and often will incur
;; pipeline stalls when a result that is needed is not yet ready.
;; The descriptions in this section allow the specification of how much time
;; must elapse between the execution of an instruction and the time when its
;; result is used. It also allows specification of when the execution of an
;; instruction will delay execution of similar instructions due to function
;; unit conflicts.
;; For the purposes of the specifications in this section, a machine is divided
;; into "function units", each of which execute a specific class of
;; instructions in first-in-first-out order. Function units that accept one
;; instruction each cycle and allow a result to be used in the succeeding
;; instruction (usually via forwarding) need not be specified. Classic RISC
;; microprocessors will normally have a single function unit, which we can call
;;
`memory'. The newer "superscalar" processors will often have function units
;; for floating point operations, usually at least a floating point adder and
;; multiplier.
;; Each usage of a function units by a class of insns is specified with a
;; `
define_function_unit' expression, which looks like this:
;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY
;; ISSUE-DELAY
[
CONFLICT-LIST
]
)
;; NAME is a string giving the name of the function unit.
;; MULTIPLICITY is an integer specifying the number of identical units in the
;; processor. If more than one unit is specified, they will be scheduled
;; independently. Only truly independent units should be counted; a pipelined
;; unit should be specified as a single unit. (The only common example of a
;; machine that has multiple function units for a single instruction class that
;; are truly independent and not pipelined are the two multiply and two
;; increment units of the CDC 6600.)
;; SIMULTANEITY specifies the maximum number of insns that can be executing in
;; each instance of the function unit simultaneously or zero if the unit is
;; pipelined and has no limit.
;; All
`define_function_unit' definitions referring to function unit NAME must
;; have the same name and values for MULTIPLICITY and SIMULTANEITY.
;; TEST is an attribute test that selects the insns we are describing in this
;; definition. Note that an insn may use more than one function unit and a
;; function unit may be specified in more than one `
define_function_unit'.
;; READY-DELAY is an integer that specifies the number of cycles after which
;; the result of the instruction can be used without introducing any stalls.
;; ISSUE-DELAY is an integer that specifies the number of cycles after the
;; instruction matching the TEST expression begins using this unit until a
;; subsequent instruction can begin. A cost of N indicates an N-1 cycle delay.
;; A subsequent instruction may also be delayed if an earlier instruction has a
;; longer READY-DELAY value. This blocking effect is computed using the
;; SIMULTANEITY, READY-DELAY, ISSUE-DELAY, and CONFLICT-LIST terms. For a
;; normal non-pipelined function unit, SIMULTANEITY is one, the unit is taken
;; to block for the READY-DELAY cycles of the executing insn, and smaller
;; values of ISSUE-DELAY are ignored.
;; CONFLICT-LIST is an optional list giving detailed conflict costs for this
;; unit. If specified, it is a list of condition test expressions to be
;; applied to insns chosen to execute in NAME following the particular insn
;; matching TEST that is already executing in NAME. For each insn in the list,
;; ISSUE-DELAY specifies the conflict cost; for insns not in the list, the cost
;; is zero. If not specified, CONFLICT-LIST defaults to all instructions that
;; use the function unit.
;; Typical uses of this vector are where a floating point function unit can
;; pipeline either single- or double-precision operations, but not both, or
;; where a memory unit can pipeline loads, but not stores, etc.
;; As an example, consider a classic RISC machine where the result of a load
;; instruction is not available for two cycles (a single "delay" instruction is
;; required) and where only one load instruction can be executed
;; simultaneously. This would be specified as:
;; (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
;; For the case of a floating point function unit that can pipeline
;; either single or double precision, but not both, the following could be
;; specified:
;;
;; (define_function_unit "fp" 1 0
;; (eq_attr "type" "sp_fp") 4 4
;;
[
(eq_attr "type" "dp_fp")
]
)
;;
;; (define_function_unit "fp" 1 0
;; (eq_attr "type" "dp_fp") 4 4
;;
[
(eq_attr "type" "sp_fp")
]
)
;; Note: The scheduler attempts to avoid function unit conflicts and uses all
;; the specifications in the
`define_function_unit' expression. It has
;; recently come to our attention that these specifications may not allow
;; modeling of some of the newer "superscalar" processors that have insns using
;; multiple pipelined units. These insns will cause a potential conflict for
;; the second unit used during their execution and there is no way of
;; representing that conflict. We welcome any examples of how function unit
;; conflicts work in such processors and suggestions for their representation.
;; Function units of the M32R
;; Function units of the M32R
;; Units that take one cycle do not need to be specified.
;; Units that take one cycle do not need to be specified.
;; (define_function_unit {name} {
num-units} {n-users
} {test}
;; (define_function_unit {name} {
multiplicity} {simulataneity
} {test}
;; {ready-delay} {issue-delay} [{conflict-list}])
;; {ready-delay} {issue-delay} [{conflict-list}])
;; References to loaded registers should wait a cycle.
;; References to loaded registers should wait a cycle.
...
@@ -94,6 +218,7 @@
...
@@ -94,6 +218,7 @@
(not (eq_attr "length" "2"))
(not (eq_attr "length" "2"))
1 0
1 0
[(eq_attr "length" "2")])
[(eq_attr "length" "2")])
;; Expand prologue as RTL
;; Expand prologue as RTL
;; ??? Unfinished.
;; ??? Unfinished.
...
@@ -915,6 +1040,7 @@
...
@@ -915,6 +1040,7 @@
DONE;
DONE;
}")
}")
;; 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.
...
@@ -924,10 +1050,23 @@
...
@@ -924,10 +1050,23 @@
(eq:CC (match_operand:SI 0 "register_operand" "r,r")
(eq:CC (match_operand:SI 0 "register_operand" "r,r")
(match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
(match_operand:SI 1 "reg_or_cmp_int16_operand" "r,P")))
(clobber (match_scratch:SI 2 "=&r,&r"))]
(clobber (match_scratch:SI 2 "=&r,&r"))]
"TARGET_OLD_COMPARE"
""
"@
"*
mv %2,%0
\;
sub %2,%1
\;
cmpui %2,#1
{
add3 %2,%0,%#%N1
\;
cmpui %2,#1"
if (which_alternative == 0)
{
return \"mv %2,%0\;sub %2,%1\;cmpui %2,#1\";
}
else
{
if (INTVAL (operands [1]) == 0)
return \"cmpui %0, #1\";
else if (REGNO (operands [2]) == REGNO (operands [0]))
return \"addi %0,%#%N1\;cmpui %2,#1\";
else
return \"add3 %2,%0,%#%N1\;cmpui %2,#1\";
}
}"
[(set_attr "type" "compare,compare")
[(set_attr "type" "compare,compare")
(set_attr "length" "8,8")])
(set_attr "length" "8,8")])
...
@@ -939,17 +1078,23 @@
...
@@ -939,17 +1078,23 @@
"@
"@
cmp %0,%1
cmp %0,%1
cmpi %0,%#%1"
cmpi %0,%#%1"
[
(set_attr "type" "compare")
]
)
[(set_attr "type" "compare,compare")
(set_attr "length" "4,6")])
(define_insn "cmp_ltusi_insn"
(define_insn "cmp_ltusi_insn"
[(set (reg:CC 17)
[(set (reg:CC 17)
(ltu:CC (match_operand:SI 0 "register_operand" "r,r")
(ltu:CC (match_operand:SI 0 "register_operand" "r,r")
(match_operand:SI 1 "reg_or_uint16_operand" "r,K")))]
(match_operand:SI 1 "reg_or_uint16_operand" "r,K")))]
""
""
"@
"*
cmpu %0,%1
{
cmpui %0,%#%1"
if (which_alternative == 0)
[
(set_attr "type" "compare")
]
)
return \"cmpu %0,%1\";
else
return \"cmpui %0,%#%1\";
}"
[(set_attr "type" "compare")
(set_attr "length" "4,6")])
;; 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.
...
@@ -957,13 +1102,15 @@
...
@@ -957,13 +1102,15 @@
;; it contains 0/non-zero.
;; it contains 0/non-zero.
(define_insn "cmp_ne_small_const_insn"
(define_insn "cmp_ne_small_const_insn"
[
(set (match_operand:SI 0 "register_operand" "=r")
[(set (match_operand:SI 0 "register_operand" "=r
,r
")
(ne:SI (match_operand:SI 1 "register_operand" "r")
(ne:SI (match_operand:SI 1 "register_operand" "
0,
r")
(match_operand:SI 2 "cmp_int16_operand" "P")))]
(match_operand:SI 2 "cmp_int16_operand" "
S,
P")))]
""
""
"add3 %0,%1,%#%N2"
"@
addi %0,%#%N2
add3 %0,%1,%#%N2"
[(set_attr "type" "compare")
[(set_attr "type" "compare")
(set_attr "length" "4")])
(set_attr "length" "
2,
4")])
;; These control RTL generation for conditional jump insns.
;; These control RTL generation for conditional jump insns.
...
@@ -975,7 +1122,7 @@
...
@@ -975,7 +1122,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
EQ, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)EQ, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "bne"
(define_expand "bne"
...
@@ -986,7 +1133,7 @@
...
@@ -986,7 +1133,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
NE, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)NE, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "bgt"
(define_expand "bgt"
...
@@ -997,7 +1144,7 @@
...
@@ -997,7 +1144,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
GT, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)GT, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "ble"
(define_expand "ble"
...
@@ -1008,7 +1155,7 @@
...
@@ -1008,7 +1155,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
LE, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)LE, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "bge"
(define_expand "bge"
...
@@ -1019,7 +1166,7 @@
...
@@ -1019,7 +1166,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
GE, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)GE, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "blt"
(define_expand "blt"
...
@@ -1030,7 +1177,7 @@
...
@@ -1030,7 +1177,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
LT, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)LT, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "bgtu"
(define_expand "bgtu"
...
@@ -1041,7 +1188,7 @@
...
@@ -1041,7 +1188,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
GTU, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)GTU, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "bleu"
(define_expand "bleu"
...
@@ -1052,7 +1199,7 @@
...
@@ -1052,7 +1199,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
LEU, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)LEU, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "bgeu"
(define_expand "bgeu"
...
@@ -1063,7 +1210,7 @@
...
@@ -1063,7 +1210,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
GEU, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)GEU, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
(define_expand "bltu"
(define_expand "bltu"
...
@@ -1074,7 +1221,7 @@
...
@@ -1074,7 +1221,7 @@
""
""
"
"
{
{
operands
[
1
]
= gen_compare (
LTU, m32r_compare_op0, m32r_compare_op1
);
operands[1] = gen_compare (
(int)LTU, m32r_compare_op0, m32r_compare_op1, FALSE
);
}")
}")
;; Now match both normal and inverted jump.
;; Now match both normal and inverted jump.
...
@@ -1088,10 +1235,11 @@
...
@@ -1088,10 +1235,11 @@
""
""
"*
"*
{
{
if (GET_CODE (operands
[
1
]
) == NE)
static char instruction[40];
return
\"
bc %l0
\"
;
sprintf (instruction, \"%s%s %%l0\",
else
(GET_CODE (operands[1]) == NE) ? \"bc\" : \"bnc\",
return
\"
bnc %l0
\"
;
(get_attr_length (insn) == 2) ? \".s\" : \"\");
return instruction;
}"
}"
[(set_attr "type" "branch")
[(set_attr "type" "branch")
; We use 400/800 instead of 512,1024 to account for inaccurate insn
; We use 400/800 instead of 512,1024 to account for inaccurate insn
...
@@ -1116,10 +1264,11 @@
...
@@ -1116,10 +1264,11 @@
""
""
"*
"*
{
{
if (GET_CODE (operands
[
1
]
) == EQ)
static char instruction[40];
return
\"
bc %l0
\"
;
sprintf (instruction, \"%s%s %%l0\",
else
(GET_CODE (operands[1]) == EQ) ? \"bc\" : \"bnc\",
return
\"
bnc %l0
\"
;
(get_attr_length (insn) == 2) ? \".s\" : \"\");
return instruction;
}"
}"
[(set_attr "type" "branch")
[(set_attr "type" "branch")
; We use 400/800 instead of 512,1024 to account for inaccurate insn
; We use 400/800 instead of 512,1024 to account for inaccurate insn
...
@@ -1452,6 +1601,51 @@
...
@@ -1452,6 +1601,51 @@
"
*
return
\"
nop ; flush-icache
\"
;"
"
*
return
\"
nop ; flush-icache
\"
;"
[
(set_attr "type" "misc")
]
)
[
(set_attr "type" "misc")
]
)
;; Conditional move instructions
;; Based on those done for the d10v
(define_expand "movsicc"
[
(set (match_operand:SI 0 "register_operand" "r")
(if_then_else:SI (match_operand 1 "" "")
(match_operand:SI 2 "conditional_move_operand" "O")
(match_operand:SI 3 "conditional_move_operand" "O")
)
)
]
""
"
{
if (! zero_and_one (operands
[
2
]
, operands
[
3
]
))
FAIL;
/
* Generate the comparision that will set the carry flag. *
/
operands
[
1
]
= gen_compare ((int)GET_CODE (operands
[
1
]
), m32r_compare_op0,
m32r_compare_op1, TRUE);
/
* See other movsicc pattern below for reason why. *
/
emit_insn (gen_blockage());
}")
;; Generate the conditional instructions based on how the carry flag is examined.
(define_insn "
*
movsicc_internal"
[
(set (match_operand:SI 0 "register_operand" "r")
(if_then_else:SI (match_operand 1 "carry_compare_operand" "")
(match_operand:SI 2 "conditional_move_operand" "O")
(match_operand:SI 3 "conditional_move_operand" "O")
)
)]
"zero_and_one (operands
[
2
]
, operands
[
3
]
)"
"
*
return emit_cond_move (operands, insn);"
[
(set_attr "type" "move")
(set_attr "length" "8")
]
)
;; Split up troublesome insns for better scheduling.
;; Split up troublesome insns for better scheduling.
;; Peepholes go at the end.
;; Peepholes go at the end.
...
@@ -1467,3 +1661,46 @@
...
@@ -1467,3 +1661,46 @@
"st %1,@+%0"
"st %1,@+%0"
[
(set_attr "type" "store")
[
(set_attr "type" "store")
(set_attr "length" "2")])
(set_attr "length" "2")])
;; This case is triggered by compiling this code:
;;
;; extern void sub(int
*
);
;; void main (void)
;; {
;; int i=2,j=3,k;
;; while (i < j) sub(
&k);
;; i = j / k;
;; sub(
&i);
;; i = j - k;
;; sub(
&i);
;; }
;;
;; Without the peephole the following assembler is generated for the
;; divide and subtract expressions:
;;
;; div r5,r4
;; mv r4,r5
;; st r4,@(4,sp)
;; bl sub
;;
;; Simialr code is produced for the subtract expression. With this
;; peephole the redundant move is eliminated.
;;
;; This optimisation onbly works if PRESERVE_DEATH_INFO_REGNO_P is
;; defined in m32r.h
(define_peephole
[
(set (match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "register_operand" "r")
)
(set (mem:SI (plus: SI (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "immediate_operand" "J")))
(match_dup 0)
)
]
"dead_or_set_p (insn, operands
[
0
]
)"
"st %1,@(%3,%2)"
[
(set_attr "type" "store")
(set_attr "length" "4")
]
)
gcc/config/m32r/t-m32r
View file @
2b7972b0
...
@@ -39,6 +39,7 @@ crtfini.o: $(srcdir)/config/m32r/initfini.c $(GCC_PASSES) $(CONFIG_H)
...
@@ -39,6 +39,7 @@ 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 -c $(srcdir)/config/m32r/initfini.c -o crtfini.o
-g0 -c $(srcdir)/config/m32r/initfini.c -o 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
...
@@ -48,6 +49,7 @@ MULTILIB_OPTIONS = mmodel=small/mmodel=medium
...
@@ -48,6 +49,7 @@ MULTILIB_OPTIONS = mmodel=small/mmodel=medium
MULTILIB_DIRNAMES = small medium
MULTILIB_DIRNAMES = small medium
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.
...
...
gcc/configure
View file @
2b7972b0
...
@@ -4580,7 +4580,7 @@ fi
...
@@ -4580,7 +4580,7 @@ fi
if
[
x
$enable_haifa
=
x
]
if
[
x
$enable_haifa
=
x
]
then
then
case
$target
in
case
$target
in
alpha
*
-
*
|
hppa1.?-
*
|
powerpc
*
-
*
|
rs6000-
*
|
*
sparc-
*
)
alpha
*
-
*
|
hppa1.?-
*
|
powerpc
*
-
*
|
rs6000-
*
|
*
sparc-
*
|
m32r
*
-
*
)
enable_haifa
=
yes
;;
enable_haifa
=
yes
;;
esac
esac
fi
fi
...
...
gcc/configure.in
View file @
2b7972b0
...
@@ -2891,7 +2891,7 @@ fi
...
@@ -2891,7 +2891,7 @@ fi
if [[ x$enable_haifa = x ]]
if [[ x$enable_haifa = x ]]
then
then
case $target in
case $target in
alpha*-* | hppa1.?-* | powerpc*-* | rs6000-* | *sparc-*)
alpha*-* | hppa1.?-* | powerpc*-* | rs6000-* | *sparc-*
| m32r*-*
)
enable_haifa=yes;;
enable_haifa=yes;;
esac
esac
fi
fi
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment