From c32ab325fd2bf4e7b4a365b5c2c7bfe7460ddf3f Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Tue, 14 Oct 2014 17:35:03 -0400 Subject: [PATCH] msp430-modes.def (PSI): Add. * config/msp430/msp430-modes.def (PSI): Add. * config/msp430/msp430-protos.h (msp430_hard_regno_nregs_has_padding): New. (msp430_hard_regno_nregs_with_padding): New. * config/msp430/msp430.c (msp430_scalar_mode_supported_p): New. (msp430_hard_regno_nregs_has_padding): New. (msp430_hard_regno_nregs_with_padding): New. (msp430_unwind_word_mode): Use PSImode instead of SImode. (msp430_addr_space_legitimate_address_p): New. (msp430_asm_integer): New. (msp430_init_dwarf_reg_sizes_extra): New. (msp430_print_operand): Use X suffix for PSImode even in small model. * config/msp430/msp430.h (POINTER_SIZE): Use 20 bits, not 32. (PTR_SIZE): ...but 4 bytes for EH. (SIZE_TYPE): Use __int20. (PTRDIFF_TYPE): Likewise. (INCOMING_FRAME_SP_OFFSET): Adjust. * config/msp430/msp430.md (movqi_topbyte): New. (movpsi): Use fixed suffixes. (movsipsi2): Enable for 430X, not large model. (extendhipsi2): Likewise. (zero_extendhisi2): Likewise. (zero_extendhisipsi2): Likewise. (extend_and_shift1_hipsi2): Likewise. (extendpsisi2): Likewise. (*bitbranch4_z): Fix suffix logic. From-SVN: r216225 --- gcc/ChangeLog | 29 ++++++++ gcc/config/msp430/msp430-modes.def | 1 + gcc/config/msp430/msp430-protos.h | 3 + gcc/config/msp430/msp430.c | 113 ++++++++++++++++++++++++++++- gcc/config/msp430/msp430.h | 13 ++-- gcc/config/msp430/msp430.md | 29 +++++--- 6 files changed, 168 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ba494ac856..830c12f25c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2014-10-14 DJ Delorie + + * config/msp430/msp430-modes.def (PSI): Add. + + * config/msp430/msp430-protos.h (msp430_hard_regno_nregs_has_padding): New. + (msp430_hard_regno_nregs_with_padding): New. + * config/msp430/msp430.c (msp430_scalar_mode_supported_p): New. + (msp430_hard_regno_nregs_has_padding): New. + (msp430_hard_regno_nregs_with_padding): New. + (msp430_unwind_word_mode): Use PSImode instead of SImode. + (msp430_addr_space_legitimate_address_p): New. + (msp430_asm_integer): New. + (msp430_init_dwarf_reg_sizes_extra): New. + (msp430_print_operand): Use X suffix for PSImode even in small model. + * config/msp430/msp430.h (POINTER_SIZE): Use 20 bits, not 32. + (PTR_SIZE): ...but 4 bytes for EH. + (SIZE_TYPE): Use __int20. + (PTRDIFF_TYPE): Likewise. + (INCOMING_FRAME_SP_OFFSET): Adjust. + * config/msp430/msp430.md (movqi_topbyte): New. + (movpsi): Use fixed suffixes. + (movsipsi2): Enable for 430X, not large model. + (extendhipsi2): Likewise. + (zero_extendhisi2): Likewise. + (zero_extendhisipsi2): Likewise. + (extend_and_shift1_hipsi2): Likewise. + (extendpsisi2): Likewise. + (*bitbranch4_z): Fix suffix logic. + 2014-10-14 Eric Botcazou PR ada/62019 diff --git a/gcc/config/msp430/msp430-modes.def b/gcc/config/msp430/msp430-modes.def index 4e94a6df597..d170e48eb64 100644 --- a/gcc/config/msp430/msp430-modes.def +++ b/gcc/config/msp430/msp430-modes.def @@ -1,3 +1,4 @@ /* 20-bit address */ PARTIAL_INT_MODE (SI, 20, PSI); +INT_N (PSI, 20); diff --git a/gcc/config/msp430/msp430-protos.h b/gcc/config/msp430/msp430-protos.h index f0b8aea0306..6cdce097e51 100644 --- a/gcc/config/msp430/msp430-protos.h +++ b/gcc/config/msp430/msp430-protos.h @@ -30,6 +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); +int msp430_hard_regno_nregs_has_padding (int, enum machine_mode); +int msp430_hard_regno_nregs_with_padding (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); diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 3dec9aa0341..6e9405d5fb5 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -228,6 +228,21 @@ msp430_option_override (void) optimize_size = 1; } +#undef TARGET_SCALAR_MODE_SUPPORTED_P +#define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p + +static bool +msp430_scalar_mode_supported_p (enum machine_mode m) +{ + if (m == PSImode && msp430x) + return true; +#if 0 + if (m == TImode) + return true; +#endif + return default_scalar_mode_supported_p (m); +} + /* Storage Layout */ @@ -257,6 +272,27 @@ msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, / UNITS_PER_WORD); } +/* Implements HARD_REGNO_NREGS_HAS_PADDING. */ +int +msp430_hard_regno_nregs_has_padding (int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + if (mode == PSImode && msp430x) + return 1; + return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) + / UNITS_PER_WORD); +} + +/* Implements HARD_REGNO_NREGS_WITH_PADDING. */ +int +msp430_hard_regno_nregs_with_padding (int regno ATTRIBUTE_UNUSED, + enum machine_mode mode) +{ + if (mode == PSImode) + return 2; + return msp430_hard_regno_nregs (regno, mode); +} + /* Implements HARD_REGNO_MODE_OK. */ int msp430_hard_regno_mode_ok (int regno ATTRIBUTE_UNUSED, @@ -370,7 +406,7 @@ msp430_addr_space_pointer_mode (addr_space_t addrspace) static enum machine_mode msp430_unwind_word_mode (void) { - return TARGET_LARGE ? SImode : HImode; + return TARGET_LARGE ? PSImode : HImode; } /* Determine if one named address space is a subset of another. */ @@ -885,6 +921,52 @@ msp430_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, } } +#undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P +#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P msp430_addr_space_legitimate_address_p + +bool +msp430_addr_space_legitimate_address_p (enum machine_mode mode, + rtx x, + bool strict, + addr_space_t as ATTRIBUTE_UNUSED) +{ + return msp430_legitimate_address_p (mode, x, strict); +} + +#undef TARGET_ASM_INTEGER +#define TARGET_ASM_INTEGER msp430_asm_integer +static bool +msp430_asm_integer (rtx x, unsigned int size, int aligned_p) +{ + int c = GET_CODE (x); + + if (size == 3 && GET_MODE (x) == PSImode) + size = 4; + + switch (size) + { + case 4: + if (c == SYMBOL_REF || c == CONST || c == LABEL_REF || c == CONST_INT) + { + fprintf (asm_out_file, "\t.long\t"); + output_addr_const (asm_out_file, x); + fputc ('\n', asm_out_file); + return true; + } + break; + } + return default_assemble_integer (x, size, aligned_p); +} + +#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA +#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra +static bool +msp430_asm_output_addr_const_extra (FILE *file, rtx x) +{ + debug_rtx(x); + return false; +} + #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant @@ -1753,6 +1835,33 @@ msp430_expand_eh_return (rtx eh_handler) emit_move_insn (tmp, ra); } +#undef TARGET_INIT_DWARF_REG_SIZES_EXTRA +#define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra +void +msp430_init_dwarf_reg_sizes_extra (tree address) +{ + int i; + rtx addr = expand_normal (address); + rtx mem = gen_rtx_MEM (BLKmode, addr); + + if (!msp430x) + return; + + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + { + unsigned int dnum = DWARF_FRAME_REGNUM (i); + unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1); + + if (rnum < DWARF_FRAME_REGISTERS) + { + HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode); + + emit_move_insn (adjust_address (mem, QImode, offset), + gen_int_mode (4, QImode)); + } + } +} + /* This is a list of MD patterns that implement fixed-count shifts. */ static struct { @@ -2485,7 +2594,7 @@ msp430_print_operand (FILE * file, rtx op, int letter) case 'X': /* This is used to turn, for example, an ADD opcode into an ADDX opcode when we're using 20-bit addresses. */ - if (TARGET_LARGE) + if (TARGET_LARGE || GET_MODE (op) == PSImode) fprintf (file, "X"); /* We don't care which operand we use, but we want 'X' in the MD file, so we do it this way. */ diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h index 70196e2e7d9..89e225df2a1 100644 --- a/gcc/config/msp430/msp430.h +++ b/gcc/config/msp430/msp430.h @@ -127,10 +127,9 @@ extern bool msp430x; #define MAX_REGS_PER_ADDRESS 1 #define Pmode (TARGET_LARGE ? PSImode : HImode) -/* Note: 32 is a lie. Large pointers are actually 20-bits wide. But gcc - thinks that any non-power-of-2 pointer size equates to BLKmode, which - causes all kinds of problems... */ -#define POINTER_SIZE (TARGET_LARGE ? 32 : 16) +#define POINTER_SIZE (TARGET_LARGE ? 20 : 16) +/* This is just for .eh_frame, to match bfd. */ +#define PTR_SIZE (TARGET_LARGE ? 4 : 2) #define POINTERS_EXTEND_UNSIGNED 1 #define ADDR_SPACE_NEAR 1 @@ -154,9 +153,9 @@ extern bool msp430x; /* Layout of Source Language Data Types */ #undef SIZE_TYPE -#define SIZE_TYPE (TARGET_LARGE ? "long unsigned int" : "unsigned int") +#define SIZE_TYPE (TARGET_LARGE ? "__int20 unsigned" : "unsigned int") #undef PTRDIFF_TYPE -#define PTRDIFF_TYPE (TARGET_LARGE ? "long int" : "int") +#define PTRDIFF_TYPE (TARGET_LARGE ? "__int20" : "int") #undef WCHAR_TYPE #define WCHAR_TYPE "long int" #undef WCHAR_TYPE_SIZE @@ -378,7 +377,7 @@ typedef struct #undef DWARF2_ADDR_SIZE #define DWARF2_ADDR_SIZE 4 -#define INCOMING_FRAME_SP_OFFSET (POINTER_SIZE / BITS_PER_UNIT) +#define INCOMING_FRAME_SP_OFFSET (TARGET_LARGE ? 4 : 2) #undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md index 991d5797358..60e7b6ff142 100644 --- a/gcc/config/msp430/msp430.md +++ b/gcc/config/msp430/msp430.md @@ -179,6 +179,13 @@ MOV%X1.B\t%1, %0" ) +(define_insn "movqi_topbyte" + [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=r") + (subreg:QI (match_operand:PSI 1 "msp_general_operand" "r") 2))] + "msp430x" + "PUSHM.A\t#1,%1 { POPM.W\t#1,%0 { POPM.W\t#1,%0" +) + (define_insn "movqi" [(set (match_operand:QI 0 "msp_nonimmediate_operand" "=rYs,rm") (match_operand:QI 1 "msp_general_operand" "riYs,rmi"))] @@ -223,9 +230,9 @@ (match_operand:PSI 1 "msp_general_operand" "riYa,r,rmi"))] "" "@ - MOV%Q0\t%1, %0 - MOV%Q0\t%1, %0 - MOV%X0.%Q0\t%1, %0") + MOVA\t%1, %0 + MOVA\t%1, %0 + MOVX.A\t%1, %0") ; This pattern is identical to the truncsipsi2 pattern except ; that it uses a SUBREG instead of a TRUNC. It is needed in @@ -237,7 +244,7 @@ (define_insn "movsipsi2" [(set (match_operand:PSI 0 "register_operand" "=r") (subreg:PSI (match_operand:SI 1 "register_operand" "r") 0))] - "TARGET_LARGE" + "msp430x" "PUSH.W\t%H1 { PUSH.W\t%L1 { POPM.A #1, %0 ; Move reg-pair %L1:%H1 into pointer %0" ) @@ -567,7 +574,7 @@ (define_insn "extendhipsi2" [(set (match_operand:PSI 0 "nonimmediate_operand" "=r") (subreg:PSI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) 0))] - "TARGET_LARGE" + "msp430x" "RLAM.A #4, %0 { RRAM.A #4, %0" ) @@ -578,14 +585,14 @@ (define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")))] - "TARGET_LARGE" + "msp430x" "MOV.W\t#0,%H0" ) (define_insn "zero_extendhisipsi2" [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r") (subreg:PSI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r")) 0))] - "TARGET_LARGE" + "msp430x" "@ AND.W\t#-1,%0 MOV.W\t%1,%0" @@ -595,7 +602,7 @@ [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0) (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) (const_int 1)))] - "TARGET_LARGE" + "msp430x" "RLAM.A #4, %0 { RRAM.A #3, %0" ) @@ -603,7 +610,7 @@ [(set (subreg:SI (match_operand:PSI 0 "nonimmediate_operand" "=r") 0) (ashift:SI (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0")) (const_int 2)))] - "TARGET_LARGE" + "msp430x" "RLAM.A #4, %0 { RRAM.A #2, %0" ) @@ -648,7 +655,7 @@ (define_insn "extendpsisi2" [(set (match_operand:SI 0 "register_operand" "=r") (sign_extend:SI (match_operand:PSI 1 "register_operand" "r")))] - "TARGET_LARGE" + "msp430x" "* /* The intention here is that we copy the bottom 16-bits of %1 into %L0 (zeroing the top four bits). Then we copy the @@ -1177,7 +1184,7 @@ (clobber (reg:BI CARRY)) ] "" - "BIT%x0%X0%b0\t%1, %0 { JEQ\t%l2" + "BIT%x0%b0\t%1, %0 { JEQ\t%l2" ) (define_insn "*bitbranch4" -- 2.30.2