diff options
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/config/msp430/msp430.c | 84 | ||||
-rw-r--r-- | gcc/config/msp430/msp430.md | 63 |
3 files changed, 115 insertions, 47 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5162aa..b9d4c35 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2013-09-26 Nick Clifton <nickc@redhat.com> + + * config/msp430/msp430.c (msp430_expand_epilogue): Fix compile + time warning message. + (msp430_print_operand_raw): Delete unused letter parameter. + (TARGET_PRINT_OPERAND_ADDRESS): Define. + (msp430_print_operand_address): New function. + (msp430_print_operand): Move address printing code from here to + new function. + * config/msp430/msp430.md (movsipsi2): Add comment in generated + assembler. + (zero_extendpsisi2): Likewise. + (extendpsisi2): New pattern. + (andneghi3): New pattern. + 2013-09-26 Yvan Roux <yvan.roux@linaro.org> * config/aarch64/aarch64.opt (mlra): New option. diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 9384d32..ae6e6a9 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1291,7 +1291,7 @@ msp430_expand_epilogue (int is_eh) if (cfun->machine->need_to_save [10]) { /* Check for a helper function. */ - helper_n = 7; /* for when the loop below never sees a match. */ + helper_n = 7; /* For when the loop below never sees a match. */ for (i = 9; i >= 4; i--) if (!cfun->machine->need_to_save [i]) { @@ -1354,7 +1354,7 @@ msp430_expand_epilogue (int is_eh) && ! is_critical_func () && crtl->args.pretend_args_size == 0 /* Calling the helper takes as many bytes as the POP;RET sequence. */ - && helper_n != 1 + && helper_n > 1 && !is_eh) { emit_insn (gen_epilogue_helper (GEN_INT (helper_n))); @@ -1494,7 +1494,7 @@ msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variant /* Note that the INTVAL is limited in value and length by the conditional above. */ int len = strlen (helper_name) + 4; helper_const = (char *) xmalloc (len); - snprintf (helper_const, len, "%s_%ld", helper_name, (int) INTVAL (operands[2])); + snprintf (helper_const, len, "%s_%d", helper_name, (int) INTVAL (operands[2])); } emit_move_insn (gen_rtx_REG (arg1mode, 12), @@ -1722,12 +1722,10 @@ msp430_output_labelref (FILE *file, const char *name) fputs (name, file); } -#undef TARGET_PRINT_OPERAND -#define TARGET_PRINT_OPERAND msp430_print_operand +/* Common code for msp430_print_operand... */ -/* Common code for msp430_print_operand(). */ static void -msp430_print_operand_raw (FILE * file, rtx op, int letter ATTRIBUTE_UNUSED) +msp430_print_operand_raw (FILE * file, rtx op) { int i; @@ -1759,6 +1757,45 @@ msp430_print_operand_raw (FILE * file, rtx op, int letter ATTRIBUTE_UNUSED) } } +#undef TARGET_PRINT_OPERAND_ADDRESS +#define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr + +/* Output to stdio stream FILE the assembler syntax for an + instruction operand that is a memory reference whose address + is ADDR. */ + +static void +msp430_print_operand_addr (FILE * file, rtx addr) +{ + switch (GET_CODE (addr)) + { + case PLUS: + msp430_print_operand_raw (file, XEXP (addr, 1)); + gcc_assert (REG_P (XEXP (addr, 0))); + fprintf (file, "(%s)", reg_names [REGNO (XEXP (addr, 0))]); + return; + + case REG: + fprintf (file, "@"); + break; + + case CONST: + case CONST_INT: + case SYMBOL_REF: + case LABEL_REF: + fprintf (file, "&"); + break; + + default: + break; + } + + msp430_print_operand_raw (file, addr); +} + +#undef TARGET_PRINT_OPERAND +#define TARGET_PRINT_OPERAND msp430_print_operand + static void msp430_print_operand (FILE * file, rtx op, int letter) { @@ -1803,7 +1840,7 @@ msp430_print_operand (FILE * file, rtx op, int letter) case GT: fprintf (file, "GE"); break; case LE: fprintf (file, "L"); break; default: - msp430_print_operand_raw (file, op, letter); + msp430_print_operand_raw (file, op); break; } return; @@ -1815,7 +1852,7 @@ msp430_print_operand (FILE * file, rtx op, int letter) case GT: fprintf (file, "L"); break; case LE: fprintf (file, "GE"); break; default: - msp430_print_operand_raw (file, op, letter); + msp430_print_operand_raw (file, op); break; } return; @@ -1897,38 +1934,18 @@ msp430_print_operand (FILE * file, rtx op, int letter) fprintf (file, "%d", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) - 2); - return ; + return; } switch (GET_CODE (op)) { case REG: - msp430_print_operand_raw (file, op, letter); + msp430_print_operand_raw (file, op); break; case MEM: addr = XEXP (op, 0); - switch (GET_CODE (addr)) - { - case REG: - fprintf (file, "@%s", reg_names [REGNO (addr)]); - break; - case PLUS: - msp430_print_operand_raw (file, XEXP (addr, 1), letter); - fprintf (file, "(%s)", reg_names [REGNO (XEXP (addr, 0))]); - break; - case CONST: - case CONST_INT: - case SYMBOL_REF: - case LABEL_REF: - fprintf (file, "&"); - msp430_print_operand_raw (file, addr, letter); - break; - - default: - print_rtl (file, addr); - break; - } + msp430_print_operand_addr (file, addr); break; case CONST_INT: @@ -1937,7 +1954,7 @@ msp430_print_operand (FILE * file, rtx op, int letter) case LABEL_REF: if (letter == 0) fprintf (file, "#"); - msp430_print_operand_raw (file, op, letter); + msp430_print_operand_raw (file, op); break; case EQ: fprintf (file, "EQ"); break; @@ -1951,7 +1968,6 @@ msp430_print_operand (FILE * file, rtx op, int letter) print_rtl (file, op); break; } - } diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md index a258867..22a3953 100644 --- a/gcc/config/msp430/msp430.md +++ b/gcc/config/msp430/msp430.md @@ -190,8 +190,8 @@ ) (define_expand "movsi" - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (match_operand:SI 1 "general_operand" ""))] + [(set (match_operand:SI 0 "nonimmediate_operand") + (match_operand:SI 1 "general_operand"))] "" "" ) @@ -230,7 +230,7 @@ [(set (match_operand:PSI 0 "register_operand" "=r") (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))] "TARGET_LARGE" - "PUSH.W %H1 { PUSH.W %1 { POPM.A #1, %0" + "PUSH.W\t%H1 { PUSH.W %L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0" ) ;;------------------------------------------------------------ @@ -326,8 +326,8 @@ ] "" "@ - ADD %2, %1 ; cy - ADD%X0 %2, %1 ; cy" + ADD\t%2, %1 ; cy + ADD%X0\t%2, %1 ; cy" ) (define_insn "addhi3_cy_i" @@ -341,8 +341,8 @@ ] "" "@ - ADD %2, %1 ; cy - ADD%X0 %2, %1 ; cy" + ADD\t%2, %1 ; cy + ADD%X0\t%2, %1 ; cy" ) ; Version of addhi that adds the carry, for SImode adds. @@ -354,8 +354,8 @@ ] "" "@ - ADDC %2, %1 - ADDC%X0 %2, %1" + ADDC\t%2, %1 + ADDC%X0\t%2, %1" ) ; Split an SImode add into two HImode adds, keeping track of the carry @@ -621,9 +621,30 @@ stored in the stack slot will be the value *after* the stack pointer has been decremented. So allow for that here. */ - return \"PUSHM.A #1, %1 { ADDX.W #4, @r1 { POPX.W %0 { POPX.W %H0\"; + return \"PUSHM.A\t#1, %1 { ADDX.W #4, @r1 { POPX.W %L0 { POPX.W %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\"; + " +) + +;; We also need to be able to sign-extend pointer types (eg ptrdiff_t). +;; Since (we assume) pushing a 20-bit value onto the stack zero-extends +;; it, we use a different method here. + +(define_insn "extendpsisi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))] + "TARGET_LARGE" + "* + /* The intention here is that we copy the bottom 16-bits of + %1 into %L0 (zeroing the top four bits). Then we copy the + entire 20-bits of %1 into %H0 and then arithmetically shift + 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\"; else - return \"PUSHM.A #1, %1 { POPX.W %0 { POPX.W %H0\"; + return \"MOV.W \t%1, %L0 { MOVX.A %1, %H0 { RPT #16 { RRAX.A %H0 ; sign extend pointer in %1 into %L0:%H0\"; " ) @@ -926,7 +947,7 @@ (define_expand "call" [(call:HI (match_operand 0 "") - (match_operand 1 ""))] + (match_operand 1 ""))] "" "" ) @@ -966,7 +987,7 @@ ;; placeholder should get expanded into a regular-type epilogue that ;; also does the EH return. (define_expand "eh_return" - [(match_operand:HI 0 "" "")] + [(match_operand:HI 0 "")] "" "msp430_expand_eh_return (operands[0]); emit_jump_insn (gen_msp430_eh_epilogue ()); @@ -1272,3 +1293,19 @@ "" "BIS.W\t%0, %O0(SP)" ) + +;; For some reason GCC is generating (set (reg) (and (neg (reg)) (int))) +;; very late on in the compilation and not splitting it into separate +;; instructions, so we provide a pattern to support it here. +(define_insn "andneghi3" + [(set (match_operand:HI 0 "register_operand" "=r") + (and:HI (neg:HI (match_operand:HI 1 "register_operand" "r")) + (match_operand 2 "immediate_operand" "n")))] + "" + "* + if (REGNO (operands[0]) != REGNO (operands[1])) + return \"MOV.W\t%1, %0 { SUB.W #0, %0 { AND.W %2, %0\"; + else + return \"SUB.W\t#0, %0 { AND.W %2, %0\"; + " + ) |