msp430.c (msp430_handle_option): Move function to msp430-common.c

* config/msp430/msp430.c (msp430_handle_option): Move function
	to msp430-common.c
	(msp430_option_override): Simplify mcu and mcpu option handling.
	(msp430_is_f5_mcu): Rename to msp430_use_f5_series_hwmult.  Add
	support for -mhwmult command line option.
	(has_32bit_hwmult): Rename to use_32bit_hwmult.  Add support for
	-mhwmult command line option.
	(msp430_hwmult_enabled): Delete.
	(msp43o_output_labelref): Add support for -mhwmult command line
	option.
	* config/msp430/msp430.md (mulhisi3, umulhisi3, mulsidi3)
	(umulsidi3): Likewise.
	* config/msp430/msp430.opt (mmcu): Add Report attribute.
	(mcpu, mlarge, msmall): Likewise.
	(mhwmult): New option.
	* config/msp430/msp430-protos.h (msp430_hwmult_enabled): Remove
	prototype.
	(msp430_is_f5_mcu): Remove prototype.
	(msp430_use_f5_series_hwmult): Add prototype.
	* config/msp430/msp430-opts.h: New file.
	* common/config/msp430: New directory.
	* common/config/msp430/msp430-common.c: New file.
	* config.gcc (msp430): Remove target_has_targetm_common.
	* doc/invoke.texi: Document -mhwmult command line option.

From-SVN: r209685
This commit is contained in:
Nick Clifton 2014-04-23 10:35:49 +00:00 committed by Nick Clifton
parent 8f78ecdbe0
commit f796136458
10 changed files with 248 additions and 97 deletions

View File

@ -1,3 +1,30 @@
2014-04-23 Nick Clifton <nickc@redhat.com>
* config/msp430/msp430.c (msp430_handle_option): Move function
to msp430-common.c
(msp430_option_override): Simplify mcu and mcpu option handling.
(msp430_is_f5_mcu): Rename to msp430_use_f5_series_hwmult. Add
support for -mhwmult command line option.
(has_32bit_hwmult): Rename to use_32bit_hwmult. Add support for
-mhwmult command line option.
(msp430_hwmult_enabled): Delete.
(msp43o_output_labelref): Add support for -mhwmult command line
option.
* config/msp430/msp430.md (mulhisi3, umulhisi3, mulsidi3)
(umulsidi3): Likewise.
* config/msp430/msp430.opt (mmcu): Add Report attribute.
(mcpu, mlarge, msmall): Likewise.
(mhwmult): New option.
* config/msp430/msp430-protos.h (msp430_hwmult_enabled): Remove
prototype.
(msp430_is_f5_mcu): Remove prototype.
(msp430_use_f5_series_hwmult): Add prototype.
* config/msp430/msp430-opts.h: New file.
* common/config/msp430: New directory.
* common/config/msp430/msp430-common.c: New file.
* config.gcc (msp430): Remove target_has_targetm_common.
* doc/invoke.texi: Document -mhwmult command line option.
2014-04-23 Nick Clifton <nickc@redhat.com>
* config/i386/cygwin.h (ENDFILE_SPEC): Include

View File

@ -0,0 +1,91 @@
/* Common hooks for Texas Instruments MSP430.
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "tm.h"
#include "common/common-target.h"
#include "common/common-target-def.h"
#include "opts.h"
#include "flags.h"
/* Handle -mcpu= and -mmcu= here. We want to ensure that only one
of these two options - the last specified on the command line -
is passed on to the msp430 backend. */
static bool
msp430_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED,
struct gcc_options *opts_set ATTRIBUTE_UNUSED,
const struct cl_decoded_option *decoded,
location_t loc ATTRIBUTE_UNUSED)
{
switch (decoded->opt_index)
{
case OPT_mcpu_:
if (strcasecmp (decoded->arg, "msp430x") == 0
|| strcasecmp (decoded->arg, "msp430xv2") == 0
|| strcasecmp (decoded->arg, "430x") == 0
|| strcasecmp (decoded->arg, "430xv2") == 0)
{
target_cpu = "msp430x";
target_mcu = NULL;
}
else if (strcasecmp (decoded->arg, "msp430") == 0
|| strcasecmp (decoded->arg, "430") == 0)
{
target_cpu = "msp430";
target_mcu = NULL;
}
else
{
error ("unrecognised argument of -mcpu: %s", decoded->arg);
return false;
}
break;
case OPT_mmcu_:
/* For backwards compatibility we recognise two generic MCU
430X names. However we want to be able to generate special C
preprocessor defines for them, which is why we set target_mcu
to NULL. */
if (strcasecmp (decoded->arg, "msp430") == 0)
{
target_cpu = "msp430";
target_mcu = NULL;
}
else if (strcasecmp (decoded->arg, "msp430x") == 0
|| strcasecmp (decoded->arg, "msp430xv2") == 0)
{
target_cpu = "msp430x";
target_mcu = NULL;
}
else
target_cpu = NULL;
break;
}
return true;
}
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION msp430_handle_option
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;

View File

@ -2108,7 +2108,6 @@ msp430*-*-*)
tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
c_target_objs="msp430-c.o"
cxx_target_objs="msp430-c.o"
target_has_targetm_common=no
tmake_file="${tmake_file} msp430/t-msp430"
;;
nds32le-*-*)

View File

@ -0,0 +1,32 @@
/* GCC option-handling definitions for the TI MSP430
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef MSP430_OPTS_H
#define MSP430_OPTS_H
enum msp430_hwmult_types
{
NONE,
AUTO,
SMALL,
LARGE,
F5SERIES
};
#endif

View File

@ -30,11 +30,9 @@ const char * msp430x_extendhisi (rtx *);
void msp430_fixup_compare_operands (enum machine_mode, rtx *);
int msp430_hard_regno_mode_ok (int, enum machine_mode);
int msp430_hard_regno_nregs (int, enum machine_mode);
bool msp430_hwmult_enabled (void);
rtx msp430_incoming_return_addr_rtx (void);
void msp430_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int);
int msp430_initial_elimination_offset (int, int);
bool msp430_is_f5_mcu (void);
bool msp430_is_interrupt_func (void);
const char * msp430x_logical_shift_right (rtx);
const char * msp430_mcu_name (void);
@ -45,5 +43,6 @@ rtx msp430_return_addr_rtx (int);
void msp430_split_movsi (rtx *);
void msp430_start_function (FILE *, const char *, tree);
rtx msp430_subreg (enum machine_mode, rtx, enum machine_mode, int);
bool msp430_use_f5_series_hwmult (void);
#endif /* GCC_MSP430_PROTOS_H */

View File

@ -95,18 +95,6 @@ msp430_init_machine_status (void)
return m;
}
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION msp430_handle_option
bool
msp430_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED,
struct gcc_options *opts_set ATTRIBUTE_UNUSED,
const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
location_t loc ATTRIBUTE_UNUSED)
{
return true;
}
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE msp430_option_override
@ -196,19 +184,14 @@ msp430_option_override (void)
if (target_cpu)
{
if (strcasecmp (target_cpu, "msp430x") == 0
|| strcasecmp (target_cpu, "msp430xv2") == 0
|| strcasecmp (target_cpu, "430x") == 0
|| strcasecmp (target_cpu, "430xv2") == 0)
if (strcasecmp (target_cpu, "msp430x") == 0)
msp430x = true;
else if (strcasecmp (target_cpu, "msp430") == 0
|| strcasecmp (target_cpu, "430") == 0)
else /* target_cpu == "msp430" - already handled by the front end. */
msp430x = false;
else
error ("unrecognised argument of -mcpu: %s", target_cpu);
}
if (target_mcu)
/* Note - the front end has already ensured at most
one of target_cpu and target_mcu will be set. */
else if (target_mcu)
{
int i;
@ -217,25 +200,12 @@ msp430_option_override (void)
supports 430. */
msp430x = true;
/* For backwards compatibility we recognise two generic MCU
430X names. However we want to be able to generate special C
preprocessor defines for them, which is why we set target_mcu
to NULL. */
if (strcasecmp (target_mcu, "msp430") == 0)
{
msp430x = false;
target_mcu = NULL;
}
else if (strcasecmp (target_mcu, "msp430x") == 0
|| strcasecmp (target_mcu, "msp430xv2") == 0)
target_mcu = NULL;
else
for (i = ARRAY_SIZE (msp430_mcu_names); i--;)
if (strcasecmp (msp430_mcu_names[i], target_mcu) == 0)
{
msp430x = false;
break;
}
for (i = ARRAY_SIZE (msp430_mcu_names); i--;)
if (strcasecmp (msp430_mcu_names[i], target_mcu) == 0)
{
msp430x = false;
break;
}
/* It is not an error if we do not match the MCU name. There are
hundreds of them. */
}
@ -1847,16 +1817,20 @@ static const struct
/* Returns true if the current MCU is an F5xxx series. */
bool
msp430_is_f5_mcu (void)
msp430_use_f5_series_hwmult (void)
{
if (target_mcu == NULL)
if (msp430_hwmult_type == F5SERIES)
return true;
if (target_mcu == NULL || msp430_hwmult_type != AUTO)
return false;
return strncasecmp (target_mcu, "msp430f5", 8) == 0;
}
/* Returns true id the current MCU has a second generation 32-bit hardware multiplier. */
static bool
has_32bit_hw_mult (void)
use_32bit_hwmult (void)
{
static const char * known_32bit_mult_mcus [] =
{
@ -1868,7 +1842,11 @@ has_32bit_hw_mult (void)
"msp430f47177", "msp430f47187", "msp430f47197"
};
int i;
if (target_mcu == NULL)
if (msp430_hwmult_type == LARGE)
return true;
if (target_mcu == NULL || msp430_hwmult_type != AUTO)
return false;
for (i = ARRAY_SIZE (known_32bit_mult_mcus); i--;)
@ -1878,25 +1856,6 @@ has_32bit_hw_mult (void)
return false;
}
/* Returns true if hardware multiply is supported by the chosen MCU. */
bool
msp430_hwmult_enabled (void)
{
if (target_mcu == NULL)
return false;
if (!ENABLE_HWMULT)
return false;
if (msp430_is_interrupt_func ())
return false;
if (msp430_is_f5_mcu () || has_32bit_hw_mult ())
return true;
return false;
}
/* This function does the same as the default, but it will replace GCC
function names with the MSPABI-specified ones. */
void
@ -1913,20 +1872,20 @@ msp430_output_labelref (FILE *file, const char *name)
/* If we have been given a specific MCU name then we may be
able to make use of its hardware multiply capabilities. */
if (msp430_hwmult_enabled ())
if (msp430_hwmult_type != NONE)
{
if (strcmp ("__mspabi_mpyi", name) == 0)
{
if (msp430_is_f5_mcu ())
if (msp430_use_f5_series_hwmult ())
name = "__mulhi2_f5";
else
name = "__mulhi2";
}
else if (strcmp ("__mspabi_mpyl", name) == 0)
{
if (msp430_is_f5_mcu ())
if (msp430_use_f5_series_hwmult ())
name = "__mulsi2_f5";
else if (has_32bit_hw_mult ())
else if (use_32bit_hwmult ())
name = "__mulsi2_hw32";
else
name = "__mulsi2";

View File

@ -1321,12 +1321,12 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
(sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
"optimize > 2 && msp430_hwmult_enabled ()"
"optimize > 2 && msp430_hwmult_type != NONE && ! msp430_is_interrupt_func ()"
"*
if (msp430_is_f5_mcu ())
return \"MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0\";
if (msp430_use_f5_series_hwmult ())
return \"PUSH.W sr { DINT { MOV.W %1, &0x04C2 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
else
return \"MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0\";
return \"PUSH.W sr { DINT { MOV.W %1, &0x0132 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
"
)
@ -1334,12 +1334,12 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0"))
(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
"optimize > 2 && msp430_hwmult_enabled ()"
"optimize > 2 && msp430_hwmult_type != NONE"
"*
if (msp430_is_f5_mcu ())
return \"MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0\";
if (msp430_use_f5_series_hwmult ())
return \"PUSH.W sr { DINT { MOV.W %1, &0x04C0 { MOV.W %2, &0x04C8 { MOV.W &0x04CA, %L0 { MOV.W &0x04CC, %H0 { POP.W sr\";
else
return \"MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0\";
return \"PUSH.W sr { DINT { MOV.W %1, &0x0130 { MOV.W %2, &0x0138 { MOV.W &0x013A, %L0 { MOV.W &0x013C, %H0 { POP.W sr\";
"
)
@ -1347,12 +1347,12 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
"optimize > 2 && msp430_hwmult_enabled ()"
"optimize > 2 && msp430_hwmult_type != NONE"
"*
if (msp430_is_f5_mcu ())
return \"MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0\";
if (msp430_use_f5_series_hwmult ())
return \"PUSH.W sr { DINT { MOV.W %L1, &0x04D4 { MOV.W %H1, &0x04D6 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
else
return \"MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0\";
return \"PUSH.W sr { DINT { MOV.W %L1, &0x0144 { MOV.W %H1, &0x0146 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
"
)
@ -1360,11 +1360,11 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
"optimize > 2 && msp430_hwmult_enabled ()"
"optimize > 2 && msp430_hwmult_type != NONE"
"*
if (msp430_is_f5_mcu ())
return \"MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0\";
if (msp430_use_f5_series_hwmult ())
return \"PUSH.W sr { DINT { MOV.W %L1, &0x04D0 { MOV.W %H1, &0x04D2 { MOV.W %L2, &0x04E0 { MOV.W %H2, &0x04E2 { MOV.W &0x04E4, %A0 { MOV.W &0x04E6, %B0 { MOV.W &0x04E8, %C0 { MOV.W &0x04EA, %D0 { POP.W sr\";
else
return \"MOV.W %L1, &0x0140 { MOV.W %H1, &0x0141 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0\";
return \"PUSH.W sr { DINT { MOV.W %L1, &0x0140 { MOV.W %H1, &0x0141 { MOV.W %L2, &0x0150 { MOV.W %H2, &0x0152 { MOV.W &0x0154, %A0 { MOV.W &0x0156, %B0 { MOV.W &0x0158, %C0 { MOV.W &0x015A, %D0 { POP.W sr\";
"
)

View File

@ -7,19 +7,19 @@ Target Mask(ASM_HEX)
Force assembly output to always use hex constants
mmcu=
Target ToLower Joined RejectNegative Var(target_mcu)
Target Report ToLower Joined RejectNegative Var(target_mcu)
Specify the MCU to build for.
mcpu=
Target Joined RejectNegative Var(target_cpu)
Target Report Joined RejectNegative Var(target_cpu)
Specify the ISA to build for: msp430, mdsp430x, msp430xv2
mlarge
Target Mask(LARGE) RejectNegative
Target Report Mask(LARGE) RejectNegative
Select large model - 20-bit addresses/pointers
msmall
Target InverseMask(LARGE) RejectNegative
Target Report InverseMask(LARGE) RejectNegative
Select small model - 16-bit addresses/pointers (default)
mrelax
@ -33,6 +33,27 @@ minrt
Target Report Mask(MINRT) RejectNegative
Use a minimum runtime (no static initializers or ctors) for memory-constrained devices.
mhwmult
Target Report Var(ENABLE_HWMULT, 1) Init(1)
Enable hardware multiply (except in interrupt routines)
HeaderInclude
config/msp430/msp430-opts.h
mhwmult=
Target Joined RejectNegative Report ToLower Var(msp430_hwmult_type) Enum(msp430_hwmult_types) Init(AUTO)
Specify the type of hardware multiply to support
Enum
Name(msp430_hwmult_types) Type(enum msp430_hwmult_types)
EnumValue
Enum(msp430_hwmult_types) String(none) Value(NONE)
EnumValue
Enum(msp430_hwmult_types) String(auto) Value(AUTO)
EnumValue
Enum(msp430_hwmult_types) String(16bit) Value(SMALL)
EnumValue
Enum(msp430_hwmult_types) String(32bit) Value(LARGE)
EnumValue
Enum(msp430_hwmult_types) String(f5series) Value(F5SERIES)

View File

@ -42,8 +42,8 @@
)
(define_insn "*movhi_virt"
[(set (match_operand:HI 0 "nonimmediate_operand" "=vYS,v,Wfr")
(match_operand:HI 1 "general_operand" "viYS,Wfr,v"))]
[(set (match_operand:HI 0 "nonimmediate_operand" "=vS, Y, v, Wfr")
(match_operand:HI 1 "general_operand" "viYS, viS, Wfr, v"))]
"rl78_virt_insns_ok ()"
"v.movw %0, %1"
[(set_attr "valloc" "op1")]

View File

@ -826,7 +826,8 @@ Objective-C and Objective-C++ Dialects}.
@gccoptlist{-meb -mel -mno-crt0}
@emph{MSP430 Options}
@gccoptlist{-msim -masm-hex -mmcu= -mcpu= -mlarge -msmall -mrelax}
@gccoptlist{-msim -masm-hex -mmcu= -mcpu= -mlarge -msmall -mrelax @gol
-mhwmult=}
@emph{NDS32 Options}
@gccoptlist{-mbig-endian -mlittle-endian @gol
@ -18242,6 +18243,28 @@ This option is passed to the assembler and linker, and allows the
linker to perform certain optimizations that cannot be done until
the final link.
@item mhwmult=
@opindex mhwmult=
Describes the type of hardware multiply supported by the target.
Accepted values are @code{none} for no hardware multiply, @code{16bit}
for the original 16-bit-only multiply supported by early MCUs.
@code{32bit} for the 16/32-bit multiply supported by later MCUs and
@code{f5series} for the 16/32-bit multiply supported by F5-series MCUs.
A value of @code{auto} can also be given. This tells GCC to deduce
the hardware multiply support based upon the MCU name provided by the
@option{-mmcu} option. If no @option{-mmcu} option is specified then
@code{32bit} hardware multiply support is assumed. @code{auto} is the
default setting.
Hardware multiplies are normally performed by calling a library
routine. This saves space in the generated code. When compiling at
@code{-O3} or higher however the hardware multiplier is invoked
inline. This makes for bigger, but faster code.
The hardware multiply routines disable interrupts whilst running and
restore the previous interrupt state when they finish. This makes
them safe to use inside interrupt handlers as well as in normal code.
@end table
@node NDS32 Options