msp430-modes.def (PSI): Add.
authorDJ Delorie <dj@redhat.com>
Tue, 14 Oct 2014 21:35:03 +0000 (17:35 -0400)
committerDJ Delorie <dj@gcc.gnu.org>
Tue, 14 Oct 2014 21:35:03 +0000 (17:35 -0400)
* 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.
(*bitbranch<mode>4_z): Fix suffix logic.

From-SVN: r216225

gcc/ChangeLog
gcc/config/msp430/msp430-modes.def
gcc/config/msp430/msp430-protos.h
gcc/config/msp430/msp430.c
gcc/config/msp430/msp430.h
gcc/config/msp430/msp430.md

index 2ba494ac85688fd3efe50ced3637a35e19d26142..830c12f25c13af22980a958f1a50614cd72215eb 100644 (file)
@@ -1,3 +1,32 @@
+2014-10-14  DJ Delorie  <dj@redhat.com>
+
+       * 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.
+       (*bitbranch<mode>4_z): Fix suffix logic.
+
 2014-10-14  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR ada/62019
index 4e94a6df5975f7815eddfddd36f4882e1da4fb72..d170e48eb643bbc417e910eca31334e3cc24be7f 100644 (file)
@@ -1,3 +1,4 @@
 /* 20-bit address */
 PARTIAL_INT_MODE (SI, 20, PSI);
 
+INT_N (PSI, 20);
index f0b8aea0306b095fc3077b2c77d4100f0c33c544..6cdce097e5126f3940530537bafebe863909444e 100644 (file)
@@ -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);
index 3dec9aa03414f359489716ddf6640ec3fdf3fa6f..6e9405d5fb58ef0557db6d4fd837b3702456a674 100644 (file)
@@ -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);
+}
+
 \f
 
 /* 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.  */
index 70196e2e7d97fe6f03de2953664ce20402c1ce56..89e225df2a142ffefeff1e2cbacad543b7ae9c58 100644 (file)
@@ -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
index 991d579735890784adfbc0336c7b9c82afee4167..60e7b6ff14208adba43fa17364060127841932ee 100644 (file)
    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"))]
        (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
 (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"
 )
 
 (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"
 )
 
 (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"
   [(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"
 )
 
   [(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"
 )
 
 (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
    (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 "*bitbranch<mode>4"