summaryrefslogtreecommitdiff
path: root/gcc/config/msp430/msp430.c
diff options
context:
space:
mode:
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>2014-03-03 17:17:49 +0000
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>2014-03-03 17:17:49 +0000
commit6956ee35b6221bfa531771346492af363908142d (patch)
tree2fd020bfa81b3679eaedb7ba2bde0d3f37502ad7 /gcc/config/msp430/msp430.c
parentdd872ef1bf1974505dcc4b8f720aeaa18d0c3d00 (diff)
downloadgcc-6956ee35b6221bfa531771346492af363908142d.tar.gz
* config/rl78/rl78-real.md (cbranchsi4_real_signed): Add
anti-cacnonical alternatives. (negandhi3_real): New pattern. * config/rl78/rl78-virt.md (negandhi3_virt): New pattern. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208282 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/msp430/msp430.c')
-rw-r--r--gcc/config/msp430/msp430.c276
1 files changed, 180 insertions, 96 deletions
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 97fa3f5a18b..80a17a6e31e 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -51,16 +51,15 @@
#include "msp430-protos.h"
#include "dumpfile.h"
#include "opts.h"
-
static void msp430_compute_frame_info (void);
-/* Run-time Target Specification */
+/* Run-time Target Specification. */
-bool msp430x = false;
+bool msp430x = true;
struct GTY(()) machine_function
{
@@ -111,65 +110,63 @@ msp430_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED,
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE msp430_option_override
-/* This list provides a set of known MCU names that support the MSP430X
- ISA. The list has been provided by TI and should be kept in sync with
- the ones in:
-
- gcc/config/msp430/t-msp430
- gas/config/tc-msp430.c
-
- FIXME: We ought to read the names in from a file at run, rather
- than having them built in like this. Also such a file should be
- shared with gas. */
-
-static const char * msp430x_names [] =
-{
- "cc430f5123", "cc430f5125", "cc430f5133", "cc430f5135", "cc430f5137",
- "cc430f5143", "cc430f5145", "cc430f5147", "cc430f6125", "cc430f6126",
- "cc430f6127", "cc430f6135", "cc430f6137", "cc430f6143", "cc430f6145",
- "cc430f6147", "msp430bt5190", "msp430cg4616", "msp430cg4617", "msp430cg4618",
- "msp430cg4619", "msp430f2416", "msp430f2417", "msp430f2418", "msp430f2419",
- "msp430f2616", "msp430f2617", "msp430f2618", "msp430f2619", "msp430f4616",
- "msp430f46161", "msp430f4617", "msp430f46171", "msp430f4618", "msp430f46181",
- "msp430f4619", "msp430f46191", "msp430f47126", "msp430f47127", "msp430f47163",
- "msp430f47166", "msp430f47167", "msp430f47173", "msp430f47176", "msp430f47177",
- "msp430f47183", "msp430f47186", "msp430f47187", "msp430f47193", "msp430f47196",
- "msp430f47197", "msp430f5131", "msp430f5132", "msp430f5151", "msp430f5152",
- "msp430f5171", "msp430f5172", "msp430f5212", "msp430f5213", "msp430f5214",
- "msp430f5217", "msp430f5218", "msp430f5219", "msp430f5222", "msp430f5223",
- "msp430f5224", "msp430f5227", "msp430f5228", "msp430f5229", "msp430f5304",
- "msp430f5308", "msp430f5309", "msp430f5310", "msp430f5324", "msp430f5325",
- "msp430f5326", "msp430f5327", "msp430f5328", "msp430f5329", "msp430f5333",
- "msp430f5335", "msp430f5336", "msp430f5338", "msp430f5340", "msp430f5341",
- "msp430f5342", "msp430f5358", "msp430f5359", "msp430f5418", "msp430f5418a",
- "msp430f5419", "msp430f5419a", "msp430f5435", "msp430f5435a", "msp430f5436",
- "msp430f5436a", "msp430f5437", "msp430f5437a", "msp430f5438", "msp430f5438a",
- "msp430f5500", "msp430f5501", "msp430f5502", "msp430f5503", "msp430f5504",
- "msp430f5505", "msp430f5506", "msp430f5507", "msp430f5508", "msp430f5509",
- "msp430f5510", "msp430f5513", "msp430f5514", "msp430f5515", "msp430f5517",
- "msp430f5519", "msp430f5521", "msp430f5522", "msp430f5524", "msp430f5525",
- "msp430f5526", "msp430f5527", "msp430f5528", "msp430f5529", "msp430f5630",
- "msp430f5631", "msp430f5632", "msp430f5633", "msp430f5634", "msp430f5635",
- "msp430f5636", "msp430f5637", "msp430f5638", "msp430f5658", "msp430f5659",
- "msp430f6433", "msp430f6435", "msp430f6436", "msp430f6438", "msp430f6458",
- "msp430f6459", "msp430f6630", "msp430f6631", "msp430f6632", "msp430f6633",
- "msp430f6634", "msp430f6635", "msp430f6636", "msp430f6637", "msp430f6638",
- "msp430f6658", "msp430f6659", "msp430f6720", "msp430f6721", "msp430f6723",
- "msp430f6724", "msp430f6725", "msp430f6726", "msp430f6730", "msp430f6731",
- "msp430f6733", "msp430f6734", "msp430f6735", "msp430f6736", "msp430f6745",
- "msp430f67451", "msp430f6746", "msp430f67461", "msp430f6747", "msp430f67471",
- "msp430f6748", "msp430f67481", "msp430f6749", "msp430f67491", "msp430f6765",
- "msp430f67651", "msp430f6766", "msp430f67661", "msp430f6767", "msp430f67671",
- "msp430f6768", "msp430f67681", "msp430f6769", "msp430f67691", "msp430f6775",
- "msp430f67751", "msp430f6776", "msp430f67761", "msp430f6777", "msp430f67771",
- "msp430f6778", "msp430f67781", "msp430f6779", "msp430f67791", "msp430fg4616",
- "msp430fg4617", "msp430fg4618", "msp430fg4619", "msp430fr5720", "msp430fr5721",
- "msp430fr5722", "msp430fr5723", "msp430fr5724", "msp430fr5725", "msp430fr5726",
- "msp430fr5727", "msp430fr5728", "msp430fr5729", "msp430fr5730", "msp430fr5731",
- "msp430fr5732", "msp430fr5733", "msp430fr5734", "msp430fr5735", "msp430fr5736",
- "msp430fr5737", "msp430fr5738", "msp430fr5739", "msp430fr5949", "msp430fr5969",
- "msp430sl5438a","msp430x241x", "msp430x26x", "msp430x461x1", "msp430x46x",
- "msp430x471x3", "msp430x471x6", "msp430x471x7", "msp430xg46x"
+static const char * msp430_mcu_names [] =
+{
+"msp430afe221", "msp430afe222", "msp430afe223", "msp430afe231",
+"msp430afe232", "msp430afe233", "msp430afe251", "msp430afe252",
+"msp430afe253", "msp430c091", "msp430c092", "msp430c111",
+"msp430c1111", "msp430c112", "msp430c1121", "msp430c1331",
+"msp430c1351", "msp430c311s", "msp430c312", "msp430c313",
+"msp430c314", "msp430c315", "msp430c323", "msp430c325",
+"msp430c336", "msp430c337", "msp430c412", "msp430c413",
+"msp430e112", "msp430e313", "msp430e315", "msp430e325",
+"msp430e337", "msp430f110", "msp430f1101", "msp430f1101a",
+"msp430f1111", "msp430f1111a", "msp430f112", "msp430f1121",
+"msp430f1121a", "msp430f1122", "msp430f1132", "msp430f122",
+"msp430f1222", "msp430f123", "msp430f1232", "msp430f133",
+"msp430f135", "msp430f147", "msp430f1471", "msp430f148",
+"msp430f1481", "msp430f149", "msp430f1491", "msp430f155",
+"msp430f156", "msp430f157", "msp430f1610", "msp430f1611",
+"msp430f1612", "msp430f167", "msp430f168", "msp430f169",
+"msp430f2001", "msp430f2002", "msp430f2003", "msp430f2011",
+"msp430f2012", "msp430f2013", "msp430f2101", "msp430f2111",
+"msp430f2112", "msp430f2121", "msp430f2122", "msp430f2131",
+"msp430f2132", "msp430f2232", "msp430f2234", "msp430f2252",
+"msp430f2254", "msp430f2272", "msp430f2274", "msp430f233",
+"msp430f2330", "msp430f235", "msp430f2350", "msp430f2370",
+"msp430f2410", "msp430f247", "msp430f2471", "msp430f248",
+"msp430f2481", "msp430f249", "msp430f2491", "msp430f412",
+"msp430f413", "msp430f4132", "msp430f415", "msp430f4152",
+"msp430f417", "msp430f423", "msp430f423a", "msp430f425",
+"msp430f4250", "msp430f425a", "msp430f4260", "msp430f427",
+"msp430f4270", "msp430f427a", "msp430f435", "msp430f4351",
+"msp430f436", "msp430f4361", "msp430f437", "msp430f4371",
+"msp430f438", "msp430f439", "msp430f447", "msp430f448",
+"msp430f4481", "msp430f449", "msp430f4491", "msp430f477",
+"msp430f478", "msp430f4783", "msp430f4784", "msp430f479",
+"msp430f4793", "msp430f4794", "msp430fe423", "msp430fe4232",
+"msp430fe423a", "msp430fe4242", "msp430fe425", "msp430fe4252",
+"msp430fe425a", "msp430fe427", "msp430fe4272", "msp430fe427a",
+"msp430fg4250", "msp430fg4260", "msp430fg4270", "msp430fg437",
+"msp430fg438", "msp430fg439", "msp430fg477", "msp430fg478",
+"msp430fg479", "msp430fw423", "msp430fw425", "msp430fw427",
+"msp430fw428", "msp430fw429", "msp430g2001", "msp430g2101",
+"msp430g2102", "msp430g2111", "msp430g2112", "msp430g2113",
+"msp430g2121", "msp430g2131", "msp430g2132", "msp430g2152",
+"msp430g2153", "msp430g2201", "msp430g2202", "msp430g2203",
+"msp430g2210", "msp430g2211", "msp430g2212", "msp430g2213",
+"msp430g2221", "msp430g2230", "msp430g2231", "msp430g2232",
+"msp430g2233", "msp430g2252", "msp430g2253", "msp430g2302",
+"msp430g2303", "msp430g2312", "msp430g2313", "msp430g2332",
+"msp430g2333", "msp430g2352", "msp430g2353", "msp430g2402",
+"msp430g2403", "msp430g2412", "msp430g2413", "msp430g2432",
+"msp430g2433", "msp430g2444", "msp430g2452", "msp430g2453",
+"msp430g2513", "msp430g2533", "msp430g2544", "msp430g2553",
+"msp430g2744", "msp430g2755", "msp430g2855", "msp430g2955",
+"msp430i2020", "msp430i2021", "msp430i2030", "msp430i2031",
+"msp430i2040", "msp430i2041", "msp430l092", "msp430p112",
+"msp430p313", "msp430p315", "msp430p315s", "msp430p325",
+"msp430p337", "msp430tch5e"
};
/* Generate a C preprocessor symbol based upon the MCU selected by the user.
@@ -200,35 +197,47 @@ msp430_option_override (void)
if (target_cpu)
{
if (strcasecmp (target_cpu, "msp430x") == 0
- || strcasecmp (target_cpu, "msp430xv2") == 0)
+ || strcasecmp (target_cpu, "msp430xv2") == 0
+ || strcasecmp (target_cpu, "430x") == 0
+ || strcasecmp (target_cpu, "430xv2") == 0)
msp430x = true;
+ else if (strcasecmp (target_cpu, "msp430") == 0
+ || strcasecmp (target_cpu, "430") == 0)
+ msp430x = false;
+ else
+ error ("unrecognised argument of -mcpu: %s", target_cpu);
}
-
+
if (target_mcu)
{
- unsigned i;
+ int i;
- for (i = ARRAY_SIZE (msp430x_names); i--;)
- if (strcasecmp (target_mcu, msp430x_names[i]) == 0)
- {
- msp430x = true;
- break;
- }
- /* Note - it is not an error if we did not recognize the MCU
- name. The msp430x_names array only contains those MCU names
- which are currently known to use the MSP430X ISA. There are
- lots of other MCUs which just use the MSP430 ISA. */
-
- /* We also recognise two generic MCU 430X names. They do not
- appear in the msp430x_names table as we want to be able to
- generate special C preprocessor defines for them. That is
- why we set target_mcu to NULL. */
- if (strcasecmp (target_mcu, "msp430x") == 0
- || strcasecmp (target_mcu, "msp430xv2") == 0)
+ /* If we are given an MCU name, we assume that it supports 430X.
+ Then we check to see if it is one of the known MCUs that only
+ 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 = true;
+ 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;
+ }
+ /* It is not an error if we do not match the MCU name. There are
+ hundreds of them. */
}
if (TARGET_LARGE && !msp430x)
@@ -974,6 +983,8 @@ is_attr_func (const char * attr)
bool
msp430_is_interrupt_func (void)
{
+ if (current_function_decl == NULL)
+ return false;
return is_attr_func ("interrupt");
}
@@ -1315,13 +1326,13 @@ msp430_expand_prologue (void)
if (flag_stack_usage_info)
current_function_static_stack_size = cfun->machine->framesize;
-
+
if (crtl->args.pretend_args_size)
{
rtx note;
gcc_assert (crtl->args.pretend_args_size == 2);
-
+
p = emit_insn (gen_grow_and_swap ());
/* Document the stack decrement... */
@@ -1376,7 +1387,7 @@ msp430_expand_prologue (void)
else
addr = stack_pointer_rtx;
- XVECEXP (note, 0, j + 1) =
+ XVECEXP (note, 0, j + 1) =
F (gen_rtx_SET (VOIDmode,
gen_rtx_MEM (Pmode, addr),
gen_rtx_REG (Pmode, i - j)) );
@@ -1803,7 +1814,6 @@ static const struct
/* GCC does not use helper functions for negation */
/* Integer multiply, divide, remainder. */
- /* Note: gcc doesn't know about hardware multiply options (yet?) */
{ "__mulhi3", "__mspabi_mpyi" },
{ "__mulsi3", "__mspabi_mpyl" },
{ "__muldi3", "__mspabi_mpyll" },
@@ -1835,6 +1845,58 @@ static const struct
{ NULL, NULL }
};
+/* Returns true if the current MCU is an F5xxx series. */
+bool
+msp430_is_f5_mcu (void)
+{
+ if (target_mcu == NULL)
+ 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)
+{
+ static const char * known_32bit_mult_mcus [] =
+ {
+ "msp430f4783", "msp430f4793", "msp430f4784",
+ "msp430f4794", "msp430f47126", "msp430f47127",
+ "msp430f47163", "msp430f47173", "msp430f47183",
+ "msp430f47193", "msp430f47166", "msp430f47176",
+ "msp430f47186", "msp430f47196", "msp430f47167",
+ "msp430f47177", "msp430f47187", "msp430f47197"
+ };
+ int i;
+ if (target_mcu == NULL)
+ return false;
+
+ for (i = ARRAY_SIZE (known_32bit_mult_mcus); i--;)
+ if (strcasecmp (target_mcu, known_32bit_mult_mcus[i]) == 0)
+ return true;
+
+ 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
@@ -1843,12 +1905,34 @@ msp430_output_labelref (FILE *file, const char *name)
int i;
for (i = 0; helper_function_name_mappings [i].gcc_name; i++)
- if (! strcmp (helper_function_name_mappings [i].gcc_name, name))
+ if (strcmp (helper_function_name_mappings [i].gcc_name, name) == 0)
{
- fputs (helper_function_name_mappings [i].ti_name, file);
- return;
+ name = helper_function_name_mappings [i].ti_name;
+ break;
}
+ /* 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 (strcmp ("__mspabi_mpyi", name) == 0)
+ {
+ if (msp430_is_f5_mcu ())
+ name = "__mulhi2_f5";
+ else
+ name = "__mulhi2";
+ }
+ else if (strcmp ("__mspabi_mpyl", name) == 0)
+ {
+ if (msp430_is_f5_mcu ())
+ name = "__mulsi2_f5";
+ else if (has_32bit_hw_mult ())
+ name = "__mulsi2_hw32";
+ else
+ name = "__mulsi2";
+ }
+ }
+
fputs (name, file);
}
@@ -2065,7 +2149,7 @@ msp430_print_operand (FILE * file, rtx op, int letter)
op = gen_rtx_REG (Pmode, REGNO (op) + 2);
break;
case CONST_INT:
- op = GEN_INT (INTVAL (op) >> 32);
+ op = GEN_INT ((long long) INTVAL (op) >> 32);
letter = 0;
break;
default:
@@ -2083,7 +2167,7 @@ msp430_print_operand (FILE * file, rtx op, int letter)
op = gen_rtx_REG (Pmode, REGNO (op) + 3);
break;
case CONST_INT:
- op = GEN_INT (INTVAL (op) >> 48);
+ op = GEN_INT ((long long) INTVAL (op) >> 48);
letter = 0;
break;
default:
@@ -2203,7 +2287,7 @@ msp430x_extendhisi (rtx * operands)
if (! msp430x)
/* Note: This sequence is approximately the same length as invoking a helper
function to perform the sign-extension, as in:
-
+
MOV.W %1, %L0
MOV.W %1, r12
CALL __mspabi_srai_15
@@ -2212,7 +2296,7 @@ msp430x_extendhisi (rtx * operands)
but this version does not involve any function calls or using argument
registers, so it reduces register pressure. */
return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 10-bytes. */
-
+
if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
/* High word of dest == source word. */
return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0"; /* 6-bytes. */
@@ -2235,11 +2319,11 @@ msp430x_logical_shift_right (rtx amount)
|| INTVAL (amount) >= 16)
return "# nop logical shift.";
- if (INTVAL (amount) > 0
+ if (INTVAL (amount) > 0
&& INTVAL (amount) < 5)
return "rrum.w\t%2, %0"; /* Two bytes. */
- if (INTVAL (amount) > 4
+ if (INTVAL (amount) > 4
&& INTVAL (amount) < 9)
return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */