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> 2014-01-17 Richard Biener <rguenther@suse.de>
PR rtl-optimization/38518 PR rtl-optimization/38518
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
))) )))
(define_constraint "Yc" (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") (and (match_code "mem")
(match_code "mem" "0") (match_code "mem" "0")
(not (ior (not (ior
......
...@@ -178,12 +178,12 @@ static const char * msp430x_names [] = ...@@ -178,12 +178,12 @@ static const char * msp430x_names [] =
const char * const char *
msp430_mcu_name (void) msp430_mcu_name (void)
{ {
if (target_cpu) if (target_mcu)
{ {
unsigned int i; unsigned int i;
static char mcu_name [64]; 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--;) for (i = strlen (mcu_name); i--;)
mcu_name[i] = TOUPPER (mcu_name[i]); mcu_name[i] = TOUPPER (mcu_name[i]);
return mcu_name; return mcu_name;
...@@ -199,10 +199,17 @@ msp430_option_override (void) ...@@ -199,10 +199,17 @@ msp430_option_override (void)
if (target_cpu) if (target_cpu)
{ {
if (strcasecmp (target_cpu, "msp430x") == 0
|| strcasecmp (target_cpu, "msp430xv2") == 0)
msp430x = true;
}
if (target_mcu)
{
unsigned i; unsigned i;
for (i = ARRAY_SIZE (msp430x_names); 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; msp430x = true;
break; break;
...@@ -214,10 +221,14 @@ msp430_option_override (void) ...@@ -214,10 +221,14 @@ msp430_option_override (void)
/* We also recognise two generic MCU 430X names. They do not /* We also recognise two generic MCU 430X names. They do not
appear in the msp430x_names table as we want to be able to appear in the msp430x_names table as we want to be able to
generate special C preprocessor defines for them. */ generate special C preprocessor defines for them. That is
if (strcasecmp (target_cpu, "msp430x") == 0 why we set target_mcu to NULL. */
|| strcasecmp (target_cpu, "msp430xv2") == 0) if (strcasecmp (target_mcu, "msp430x") == 0
msp430x = true; || strcasecmp (target_mcu, "msp430xv2") == 0)
{
msp430x = true;
target_mcu = NULL;
}
} }
if (TARGET_LARGE && !msp430x) if (TARGET_LARGE && !msp430x)
...@@ -1093,11 +1104,11 @@ msp430_attr (tree * node, ...@@ -1093,11 +1104,11 @@ msp430_attr (tree * node,
break; break;
case INTEGER_CST: 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 /* Allow the attribute to be added - the linker script
being used may still recognise this value. */ being used may still recognise this value. */
warning (OPT_Wattributes, 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); name);
break; break;
...@@ -1458,11 +1469,9 @@ msp430_expand_epilogue (int is_eh) ...@@ -1458,11 +1469,9 @@ msp430_expand_epilogue (int is_eh)
if (msp430x) if (msp430x)
{ {
/* Note: With TARGET_LARGE we still use POPM as POPX.A is two /* Note: With TARGET_LARGE we still use
bytes bigger. POPM as POPX.A is two bytes bigger. */
Note: See the popm pattern for the explanation of the strange emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1),
arguments. */
emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (~(seq - 1)),
GEN_INT (count))); GEN_INT (count)));
i += count - 1; i += count - 1;
} }
...@@ -2186,7 +2195,7 @@ msp430x_extendhisi (rtx * operands) ...@@ -2186,7 +2195,7 @@ msp430x_extendhisi (rtx * operands)
{ {
if (REGNO (operands[0]) == REGNO (operands[1])) if (REGNO (operands[0]) == REGNO (operands[1]))
/* Low word of dest == source word. */ /* 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) if (! msp430x)
/* Note: This sequence is approximately the same length as invoking a helper /* Note: This sequence is approximately the same length as invoking a helper
...@@ -2199,14 +2208,14 @@ msp430x_extendhisi (rtx * operands) ...@@ -2199,14 +2208,14 @@ msp430x_extendhisi (rtx * operands)
but this version does not involve any function calls or using argument but this version does not involve any function calls or using argument
registers, so it reduces register pressure. */ 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])) if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
/* High word of dest == source word. */ /* 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. */ /* 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. */ /* Likewise for logical right shifts. */
......
...@@ -52,7 +52,7 @@ extern bool msp430x; ...@@ -52,7 +52,7 @@ extern bool msp430x;
#define ENDFILE_SPEC "crtend.o%s crtn.o%s -lgcc" #define ENDFILE_SPEC "crtend.o%s crtn.o%s -lgcc"
#define ASM_SPEC "-mP " /* Enable polymorphic instructions. */ \ #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. */ \ "%{mrelax=-mQ} " /* Pass the relax option on to the assembler. */ \
"%{mlarge:-ml} " /* Tell the assembler if we are building for the LARGE pointer model. */ \ "%{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. */ \ "%{!msim:-md} %{msim:%{mlarge:-md}}" /* Copy data from ROM to RAM if necessary. */ \
......
...@@ -111,11 +111,7 @@ ...@@ -111,11 +111,7 @@
;; Operand1 is actually a register, but we cannot accept (REG...) because the ;; Operand1 is actually a register, but we cannot accept (REG...) because the
;; cprop_hardreg pass can and will renumber registers even inside ;; cprop_hardreg pass can and will renumber registers even inside
;; unspec_volatiles. So we take an integer register number parameter and ;; 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 ;; fudge it to be a register name when we generate the assembler.
;; 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...)
;; ;;
;; The pushm pattern does not have this problem because of all of the ;; 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. ;; frame info cruft attached to it, so cprop_hardreg leaves it alone.
...@@ -124,7 +120,7 @@ ...@@ -124,7 +120,7 @@
(match_operand 1 "immediate_operand" "i") (match_operand 1 "immediate_operand" "i")
(match_operand 2 "immediate_operand" "i")] UNS_POPM)] (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 ;; The next two patterns are here to support a "feature" of how GCC implements
...@@ -230,7 +226,7 @@ ...@@ -230,7 +226,7 @@
[(set (match_operand:PSI 0 "register_operand" "=r") [(set (match_operand:PSI 0 "register_operand" "=r")
(subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))] (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))]
"TARGET_LARGE" "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 @@ ...@@ -275,7 +271,7 @@
(plus:SI (match_operand:SI 1 "register_operand" "0") (plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand 2 "general_operand" "rmi")))] (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" (define_insn "addsi3"
...@@ -318,7 +314,7 @@ ...@@ -318,7 +314,7 @@
(define_insn "addhi3_cy" (define_insn "addhi3_cy"
[(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm") [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm")
(plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0") (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) (set (reg:BI CARRY)
(truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
(zero_extend:SI (match_dup 2))) (zero_extend:SI (match_dup 2)))
...@@ -331,9 +327,9 @@ ...@@ -331,9 +327,9 @@
) )
(define_insn "addhi3_cy_i" (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") (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) (set (reg:BI CARRY)
(truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1)) (truncate:BI (lshiftrt:SI (plus:SI (zero_extend:SI (match_dup 1))
(match_operand 3 "immediate_operand" "i,i")) (match_operand 3 "immediate_operand" "i,i"))
...@@ -349,7 +345,7 @@ ...@@ -349,7 +345,7 @@
(define_insn "addchi4_cy" (define_insn "addchi4_cy"
[(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm") [(set (match_operand:HI 0 "msp_nonimmediate_operand" "=r,rm")
(plus:HI (plus:HI (match_operand:HI 1 "msp_nonimmediate_operand" "%0,0") (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)))) (zero_extend:HI (reg:BI CARRY))))
] ]
"" ""
...@@ -516,7 +512,7 @@ ...@@ -516,7 +512,7 @@
) )
(define_insn "zero_extendqihi2" (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")))] (zero_extend:HI (match_operand:QI 1 "msp_nonimmediate_operand" "0,0")))]
"" ""
"@ "@
...@@ -536,7 +532,7 @@ ...@@ -536,7 +532,7 @@
) )
(define_insn "zero_extendhipsi2" (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")))] (zero_extend:PSI (match_operand:HI 1 "msp_nonimmediate_operand" "rm,r")))]
"" ""
"MOVX\t%1, %0" "MOVX\t%1, %0"
...@@ -621,9 +617,9 @@ ...@@ -621,9 +617,9 @@
stored in the stack slot will be the value *after* the stored in the stack slot will be the value *after* the
stack pointer has been decremented. So allow for that stack pointer has been decremented. So allow for that
here. */ 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 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 @@ ...@@ -642,9 +638,9 @@
it right by 16 bits, to get the top four bits of the pointer it right by 16 bits, to get the top four bits of the pointer
sign-extended in %H0. */ sign-extended in %H0. */
if (REGNO (operands[0]) == REGNO (operands[1])) 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 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 @@ ...@@ -654,7 +650,7 @@
[(set (match_operand:PSI 0 "register_operand" "=r") [(set (match_operand:PSI 0 "register_operand" "=r")
(truncate:PSI (match_operand:SI 1 "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 @@ ...@@ -1304,8 +1300,8 @@
"" ""
"* "*
if (REGNO (operands[0]) != REGNO (operands[1])) 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 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) ...@@ -7,8 +7,12 @@ Target Mask(ASM_HEX)
Force assembly output to always use hex constants Force assembly output to always use hex constants
mmcu= mmcu=
Target Joined RejectNegative Var(target_mcu)
Specify the MCU to build for.
mcpu=
Target Joined RejectNegative Var(target_cpu) 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 mlarge
Target Mask(LARGE) RejectNegative Target Mask(LARGE) RejectNegative
......
...@@ -824,7 +824,7 @@ Objective-C and Objective-C++ Dialects}. ...@@ -824,7 +824,7 @@ Objective-C and Objective-C++ Dialects}.
@gccoptlist{-meb -mel -mno-crt0} @gccoptlist{-meb -mel -mno-crt0}
@emph{MSP430 Options} @emph{MSP430 Options}
@gccoptlist{-msim -masm-hex -mmcu= -mlarge -msmall -mrelax} @gccoptlist{-msim -masm-hex -mmcu= -mcpu= -mlarge -msmall -mrelax}
@emph{NDS32 Options} @emph{NDS32 Options}
@gccoptlist{-mbig-endian -mlittle-endian @gol @gccoptlist{-mbig-endian -mlittle-endian @gol
...@@ -18124,21 +18124,25 @@ testsuite and/or aesthetic purposes. ...@@ -18124,21 +18124,25 @@ testsuite and/or aesthetic purposes.
@item -mmcu= @item -mmcu=
@opindex mmcu= @opindex mmcu=
Select the MCU to target. If the MCU supports the MSP430X ISA or the Select the MCU to target. This is used to create a C preprocessor
MSP430Xv2 ISA then gcc will make use of the extra instructions. A C symbol based upon the MCU name, converted to upper case and pre- and
preprocessor symbol will be defined based upon the MCU name, converted post- fixed with @code{__}. This in turn will be used by the
to upper case and pre- and post- fixed with @code{__}. @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: In addition two scripts will be added to the linker command line:
@code{memory.ld} and @code{peripherals.ld}, with a search path based @code{memory.ld} and @code{peripherals.ld}, with a search path based
upon the MCU name. 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. 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 @item -msim
@opindex msim @opindex msim
Link to the simulator runtime libraries and linker script. Overrides 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