Commit d4f283a1 by Nick Clifton Committed by Nick Clifton

msp430.opt: (mcpu): New option.

	* config/msp430/msp430.opt: (mcpu): New option.
	* config/msp430/msp430.c (msp430_mcu_name): Use target_mcu.
	(msp430_option_override): Parse target_cpu.  If the MCU name
	matches a generic string, clear target_mcu.
	(msp430_attr): Allow numeric interrupt values up to 63.
	(msp430_expand_epilogue): No longer invert operand 1 of gen_popm.
	* config/msp430/msp430.h (ASM_SPEC): Convert -mcpu into a -mmcu
	option.
	* config/msp430/t-msp430: (MULTILIB_MATCHES): Remove mcu matches.
	Add mcpu matches.
	* config/msp430/msp430.md (popm): Use %J rather than %I.
	(addsi3): Use msp430_nonimmediate_operand for operand 2.
	(addhi_cy_i): Use immediate_operand for operand 2.
	* doc/invoke.texi: Document -mcpu option.

From-SVN: r206705
parent 7be64667
2014-01-17 Nick Clifton <nickc@redhat.com>
* config/msp430/msp430.opt: (mcpu): New option.
* config/msp430/msp430.c (msp430_mcu_name): Use target_mcu.
(msp430_option_override): Parse target_cpu. If the MCU name
matches a generic string, clear target_mcu.
(msp430_attr): Allow numeric interrupt values up to 63.
(msp430_expand_epilogue): No longer invert operand 1 of gen_popm.
* config/msp430/msp430.h (ASM_SPEC): Convert -mcpu into a -mmcu
option.
* config/msp430/t-msp430: (MULTILIB_MATCHES): Remove mcu matches.
Add mcpu matches.
* config/msp430/msp430.md (popm): Use %J rather than %I.
(addsi3): Use msp430_nonimmediate_operand for operand 2.
(addhi_cy_i): Use immediate_operand for operand 2.
* doc/invoke.texi: Document -mcpu option.
2014-01-17 Richard Biener <rguenther@suse.de>
PR rtl-optimization/38518
......
......@@ -72,7 +72,7 @@
)))
(define_constraint "Yc"
"Memory reference, for CALL - we can't use SP"
"Memory reference, for CALL - we can't use SP."
(and (match_code "mem")
(match_code "mem" "0")
(not (ior
......
......@@ -178,12 +178,12 @@ static const char * msp430x_names [] =
const char *
msp430_mcu_name (void)
{
if (target_cpu)
if (target_mcu)
{
unsigned int i;
static char mcu_name [64];
snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_cpu);
snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_mcu);
for (i = strlen (mcu_name); i--;)
mcu_name[i] = TOUPPER (mcu_name[i]);
return mcu_name;
......@@ -199,10 +199,17 @@ msp430_option_override (void)
if (target_cpu)
{
if (strcasecmp (target_cpu, "msp430x") == 0
|| strcasecmp (target_cpu, "msp430xv2") == 0)
msp430x = true;
}
if (target_mcu)
{
unsigned i;
for (i = ARRAY_SIZE (msp430x_names); i--;)
if (strcasecmp (target_cpu, msp430x_names[i]) == 0)
if (strcasecmp (target_mcu, msp430x_names[i]) == 0)
{
msp430x = true;
break;
......@@ -214,10 +221,14 @@ msp430_option_override (void)
/* 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. */
if (strcasecmp (target_cpu, "msp430x") == 0
|| strcasecmp (target_cpu, "msp430xv2") == 0)
msp430x = true;
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)
{
msp430x = true;
target_mcu = NULL;
}
}
if (TARGET_LARGE && !msp430x)
......@@ -1093,11 +1104,11 @@ msp430_attr (tree * node,
break;
case INTEGER_CST:
if (TREE_INT_CST_LOW (value) > 31)
if (TREE_INT_CST_LOW (value) > 63)
/* Allow the attribute to be added - the linker script
being used may still recognise this value. */
warning (OPT_Wattributes,
"numeric argument of %qE attribute must be in range 0..31",
"numeric argument of %qE attribute must be in range 0..63",
name);
break;
......@@ -1458,11 +1469,9 @@ msp430_expand_epilogue (int is_eh)
if (msp430x)
{
/* Note: With TARGET_LARGE we still use POPM as POPX.A is two
bytes bigger.
Note: See the popm pattern for the explanation of the strange
arguments. */
emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (~(seq - 1)),
/* Note: With TARGET_LARGE we still use
POPM as POPX.A is two bytes bigger. */
emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1),
GEN_INT (count)));
i += count - 1;
}
......@@ -2186,7 +2195,7 @@ msp430x_extendhisi (rtx * operands)
{
if (REGNO (operands[0]) == REGNO (operands[1]))
/* Low word of dest == source word. */
return "BIT.W #0x8000, %L0 { SUBC.W %H0, %H0 { INV.W %H0, %H0"; /* 8-bytes. */
return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 8-bytes. */
if (! msp430x)
/* Note: This sequence is approximately the same length as invoking a helper
......@@ -2199,14 +2208,14 @@ 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 %1, %L0 { BIT.W #0x8000, %L0 { SUBC.W %H0, %H0 { INV.W %H0, %H0"; /* 10-bytes. */
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 %1, %L0 { RPT #15 { RRAX.W %H0"; /* 6-bytes. */
return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0"; /* 6-bytes. */
/* No overlap between dest and source. */
return "MOV.W %1, %L0 { MOV.W %1, %H0 { RPT #15 { RRAX.W %H0"; /* 8-bytes. */
return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0"; /* 8-bytes. */
}
/* Likewise for logical right shifts. */
......
......@@ -52,7 +52,7 @@ extern bool msp430x;
#define ENDFILE_SPEC "crtend.o%s crtn.o%s -lgcc"
#define ASM_SPEC "-mP " /* Enable polymorphic instructions. */ \
"%{mmcu=msp430x:-mmcu=msp430X;mmcu=*:-mmcu=%*} " /* Pass the MCU type on to the assembler. */ \
"%{mcpu=*:-mmcu=%*}%{!mcpu=*:%{mmcu=*:-mmcu=%*}} " /* Pass the CPU type on to the assembler. */ \
"%{mrelax=-mQ} " /* Pass the relax option on to the assembler. */ \
"%{mlarge:-ml} " /* Tell the assembler if we are building for the LARGE pointer model. */ \
"%{!msim:-md} %{msim:%{mlarge:-md}}" /* Copy data from ROM to RAM if necessary. */ \
......
......@@ -111,11 +111,7 @@
;; Operand1 is actually a register, but we cannot accept (REG...) because the
;; cprop_hardreg pass can and will renumber registers even inside
;; unspec_volatiles. So we take an integer register number parameter and
;; fudge it to be a register name when we generate the assembler. We use %I
;; because that is the only operator that will omit the # prefix to an
;; integer value. Unfortunately it also inverts the integer value, so we
;; have pre-invert it when generating this insn. (We could of course add a
;; new operator, eg %J, just for this pattern...)
;; fudge it to be a register name when we generate the assembler.
;;
;; The pushm pattern does not have this problem because of all of the
;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
......@@ -124,7 +120,7 @@
(match_operand 1 "immediate_operand" "i")
(match_operand 2 "immediate_operand" "i")] UNS_POPM)]
""
"POPM%b0\t%2, r%I1"
"POPM%b0\t%2, r%J1"
)
;; The next two patterns are here to support a "feature" of how GCC implements
......@@ -230,7 +226,7 @@
[(set (match_operand:PSI 0 "register_operand" "=r")
(subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
"TARGET_LARGE"
"PUSH.W\t%H1 { PUSH.W %L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
"PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0"
)
;;------------------------------------------------------------
......@@ -275,7 +271,7 @@
(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand 2 "general_operand" "rmi")))]
""
"ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W %H0 { PUSH.W %L0 { POPM.A #1, %0"
"ADD.W\t%L2, %L0 { ADDC.W\t%H2, %H0 { PUSH.W\t%H0 { PUSH.W\t%L0 { POPM.A\t#1, %0"
)
(define_insn "addsi3"
......@@ -318,7 +314,7 @@
(define_insn "addhi3_cy"
[(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm")
(plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
(match_operand:HI 2 "msp_general_operand" "r,rm")))
(match_operand:HI 2 "msp_nonimmediate_operand" "r,rm")))
(set (reg:BI CARRY)
(truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
(zero_extend:SI (match_dup 2)))
......@@ -331,9 +327,9 @@
)
(define_insn "addhi3_cy_i"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
(match_operand:HI 2 "general_operand" "i,i")))
(match_operand:HI 2 "immediate_operand" "i,i")))
(set (reg:BI CARRY)
(truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
(match_operand 3 "immediate_operand" "i,i"))
......@@ -349,7 +345,7 @@
(define_insn "addchi4_cy"
[(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm")
(plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0")
(match_operand:HI 2 "msp_general_operand" "ri,rmi"))
(match_operand:HI 2 "msp_general_operand" "ri,rmi"))
(zero_extend:HI (reg:BI CARRY))))
]
""
......@@ -516,7 +512,7 @@
)
(define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m")
[(set (match_operand:HI 0 "msp_nonimmediate_operand" "=rYs,m")
(zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
""
"@
......@@ -536,7 +532,7 @@
)
(define_insn "zero_extendhipsi2"
[(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,m")
[(set (match_operand:PSI 0 "msp_nonimmediate_operand" "=r,m")
(zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
""
"MOVX\t%1, %0"
......@@ -621,9 +617,9 @@
stored in the stack slot will be the value *after* the
stack pointer has been decremented. So allow for that
here. */
return \"PUSHM.A\t#1, %1 { ADDX.W #4, @r1 { POPX.W %L0 { POPX.W %H0 ; get stack pointer into %L0:%H0\";
return \"PUSHM.A\t#1, %1 { ADDX.W\t#4, @r1 { POPX.W\t%L0 { POPX.W\t%H0 ; get stack pointer into %L0:%H0\";
else
return \"PUSHM.A\t#1, %1 { POPX.W %L0 { POPX.W %H0 ; move pointer in %1 into reg-pair %L0:%H0\";
return \"PUSHM.A\t#1, %1 { POPX.W\t%L0 { POPX.W\t%H0 ; move pointer in %1 into reg-pair %L0:%H0\";
"
)
......@@ -642,9 +638,9 @@
it right by 16 bits, to get the top four bits of the pointer
sign-extended in %H0. */
if (REGNO (operands[0]) == REGNO (operands[1]))
return \"MOVX.A\t%1, %H0 { MOV.W %1, %L0 { RPT #16 { RRAX.A %H0 ; sign extend pointer in %1 into %L0:%H0\";
return \"MOVX.A\t%1, %H0 { MOV.W\t%1, %L0 { RPT\t#16 { RRAX.A\t%H0 ; sign extend pointer in %1 into %L0:%H0\";
else
return \"MOV.W \t%1, %L0 { MOVX.A %1, %H0 { RPT #16 { RRAX.A %H0 ; sign extend pointer in %1 into %L0:%H0\";
return \"MOV.W\t%1, %L0 { MOVX.A\t%1, %H0 { RPT\t#16 { RRAX.A\t%H0 ; sign extend pointer in %1 into %L0:%H0\";
"
)
......@@ -654,7 +650,7 @@
[(set (match_operand:PSI 0 "register_operand" "=r")
(truncate:PSI (match_operand:SI 1 "register_operand" "r")))]
""
"PUSH.W %H1 { PUSH.W %1 { POPM.A #1, %0"
"PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A\t#1, %L0"
)
;;------------------------------------------------------------
......@@ -1304,8 +1300,8 @@
""
"*
if (REGNO (operands[0]) != REGNO (operands[1]))
return \"MOV.W\t%1, %0 { SUB.W #0, %0 { AND.W %2, %0\";
return \"MOV.W\t%1, %0 { SUB.W\t#0, %0 { AND.W\t%2, %0\";
else
return \"SUB.W\t#0, %0 { AND.W %2, %0\";
return \"SUB.W\t#0, %0 { AND.W\t%2, %0\";
"
)
......@@ -7,8 +7,12 @@ Target Mask(ASM_HEX)
Force assembly output to always use hex constants
mmcu=
Target Joined RejectNegative Var(target_mcu)
Specify the MCU to build for.
mcpu=
Target Joined RejectNegative Var(target_cpu)
Specify the cpu to build for. If the name begins with 'msp430x' then the 430X instructions are enabled
Specify the ISA to build for: msp430, mdsp430x, msp430xv2
mlarge
Target Mask(LARGE) RejectNegative
......
......@@ -824,7 +824,7 @@ Objective-C and Objective-C++ Dialects}.
@gccoptlist{-meb -mel -mno-crt0}
@emph{MSP430 Options}
@gccoptlist{-msim -masm-hex -mmcu= -mlarge -msmall -mrelax}
@gccoptlist{-msim -masm-hex -mmcu= -mcpu= -mlarge -msmall -mrelax}
@emph{NDS32 Options}
@gccoptlist{-mbig-endian -mlittle-endian @gol
......@@ -18124,21 +18124,25 @@ testsuite and/or aesthetic purposes.
@item -mmcu=
@opindex mmcu=
Select the MCU to target. If the MCU supports the MSP430X ISA or the
MSP430Xv2 ISA then gcc will make use of the extra instructions. A C
preprocessor symbol will be defined based upon the MCU name, converted
to upper case and pre- and post- fixed with @code{__}.
Select the MCU to target. This is used to create a C preprocessor
symbol based upon the MCU name, converted to upper case and pre- and
post- fixed with @code{__}. This in turn will be used by the
@code{msp430.h} header file to select an MCU specific supplimentary
header file.
In addition two scripts will be added to the linker command line:
@code{memory.ld} and @code{peripherals.ld}, with a search path based
upon the MCU name.
Note that there are three ``generic'' MCUs: @code{msp430},
@code{msp430x} and @code{msp430xv2}, which can be used if a specific
MCU is not being targeted.
This option is also passed on to the assembler.
@item -mcpu=
@opindex -mcpu=
Specific the ISA to use. Accepted values are @code{msp430},
@code{msp430x} and @code{msp430xv2}. This option is needed in order
to ensure that the correct instructions are generated and that the
correct libraries are linked in.
@item -msim
@opindex msim
Link to the simulator runtime libraries and linker script. Overrides
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment