public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* m32c support for named addr spaces branch
@ 2009-10-15  4:17 DJ Delorie
  2009-10-15 18:07 ` Ulrich Weigand
  0 siblings, 1 reply; 34+ messages in thread
From: DJ Delorie @ 2009-10-15  4:17 UTC (permalink / raw)
  To: gcc-patches


In case anyone's interested, here's preliminary support for named
address spaces for the m32c-elf target.  It's relative to the branch,
but with the (hopefully) looming approval of the merge to mainline,
I'm holding off on committing it.

The only thing I haven't gotten it to do is this addressing mode,
which I think would help m16c a lot:

  (mem (plus:SI (zero_extendhisi:SI (reg:HI)) (symbol_ref)))

GCC instead uses sign extension, which isn't what the chip does:

(plus:SI (sign_extend:SI (reg:HI 28))
    (symbol_ref:SI ("far_int_array") [flags 0x40] <var_decl 0xb7f830b8 far_int_array>))


Index: m32c.c
===================================================================
--- m32c.c	(revision 152757)
+++ m32c.c	(working copy)
@@ -70,12 +70,13 @@ static int interrupt_p (tree node);
 static bool m32c_asm_integer (rtx, unsigned int, int);
 static int m32c_comp_type_attributes (const_tree, const_tree);
 static bool m32c_fixed_condition_code_regs (unsigned int *, unsigned int *);
 static struct machine_function *m32c_init_machine_status (void);
 static void m32c_insert_attributes (tree, tree *);
 static bool m32c_legitimate_address_p (enum machine_mode, rtx, bool);
+static bool m32c_addr_space_legitimate_address_p (enum machine_mode, rtx, bool, addr_space_t);
 static bool m32c_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
 				    const_tree, bool);
 static bool m32c_promote_prototypes (const_tree);
 static int m32c_pushm_popm (Push_Pop_Type);
 static bool m32c_strict_argument_naming (CUMULATIVE_ARGS *);
 static rtx m32c_struct_value_rtx (tree, int);
@@ -111,12 +112,20 @@ static GTY(()) rtx patternr[30];
 #define IS_MEM_REGNO(regno) ((regno) >= MEM0_REGNO && (regno) <= MEM7_REGNO)
 #define IS_MEM_REG(rtx) (GET_CODE (rtx) == REG && IS_MEM_REGNO (REGNO (rtx)))
 
 #define IS_CR_REGNO(regno) ((regno) >= SB_REGNO && (regno) <= PC_REGNO)
 #define IS_CR_REG(rtx) (GET_CODE (rtx) == REG && IS_CR_REGNO (REGNO (rtx)))
 
+static int
+far_addr_space_p (rtx x)
+{
+  if (GET_CODE (x) != MEM)
+    return 0;
+  return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR;
+}
+
 /* We do most RTX matching by converting the RTX into a string, and
    using string compares.  This vastly simplifies the logic in many of
    the functions in this file.
 
    On exit, pattern[] has the encoded string (use RTX_IS("...") to
    compare it) and patternr[] has pointers to the nodes in the RTX
@@ -504,12 +513,18 @@ m32c_conditional_register_usage (void)
 	{
 	  fixed_regs[MEM0_REGNO + i] = 1;
 	  CLEAR_HARD_REG_BIT (reg_class_contents[MEM_REGS], MEM0_REGNO + i);
 	}
     }
 
+  if (TARGET_A16)
+    {
+      SET_HARD_REG_BIT (reg_class_contents[SI_REGS], A0_REGNO);
+      SET_HARD_REG_BIT (reg_class_contents[SI_REGS], A1_REGNO);
+    }
+
   /* M32CM and M32C preserve more registers across function calls.  */
   if (TARGET_A24)
     {
       call_used_regs[R1_REGNO] = 0;
       call_used_regs[R2_REGNO] = 0;
       call_used_regs[R3_REGNO] = 0;
@@ -535,13 +550,13 @@ m32c_hard_regno_nregs_1 (int regno, enum
     return (GET_MODE_SIZE (mode) + 1) / 2;
 
   if (GET_MODE_SIZE (mode) <= 1)
     return nregs_table[regno].qi_regs;
   if (GET_MODE_SIZE (mode) <= 2)
     return nregs_table[regno].hi_regs;
-  if (regno == A0_REGNO && mode == PSImode && TARGET_A16)
+  if (regno == A0_REGNO && mode == SImode && TARGET_A16)
     return 2;
   if ((GET_MODE_SIZE (mode) <= 3 || mode == PSImode) && TARGET_A24)
     return nregs_table[regno].pi_regs;
   if (GET_MODE_SIZE (mode) <= 4)
     return nregs_table[regno].si_regs;
   if (GET_MODE_SIZE (mode) <= 8)
@@ -1044,12 +1059,25 @@ m32c_extra_constraint_p2 (rtx value, cha
 	      && !(INTVAL (patternr[1]) & ~0x1fff));
     }
   else if (memcmp (str, "S1", 2) == 0)
     {
       return r1h_operand (value, QImode);
     }
+  else if (memcmp (str, "SF", 2) == 0)
+    {
+      if (! far_addr_space_p (value))
+	return 0;
+      return ((RTX_IS ("mr")
+	       && IS_REG (patternr[1], A0_REGNO)
+	       && GET_MODE (patternr[1]) == SImode)
+	      || (RTX_IS ("m+ri")
+		  && (IS_REG (patternr[2], A0_REGNO))
+		  && GET_MODE (patternr[2]) == HImode)
+	      || RTX_IS ("ms")
+	      );
+    }
 
   gcc_assert (str[0] != 'S');
 
   if (memcmp (str, "Rpa", 2) == 0)
     return GET_CODE (value) == PARALLEL;
 
@@ -1788,12 +1816,15 @@ bool
 m32c_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
 {
   int mode_adjust;
   if (CONSTANT_P (x))
     return 1;
 
+  if (GET_MODE (x) != HImode)
+    return 0;
+
   /* Wide references to memory will be split after reload, so we must
      ensure that all parts of such splits remain legitimate
      addresses.  */
   mode_adjust = GET_MODE_SIZE (mode) - 1;
 
   /* allowing PLUS yields mem:HI(plus:SI(mem:SI(plus:SI in m32c_split_move */
@@ -2048,12 +2079,191 @@ int
 m32c_legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
 {
   return 1;
 }
 
 
+/* Return the appropriate mode for a named address pointer.  */
+#undef TARGET_ADDR_SPACE_POINTER_MODE
+#define TARGET_ADDR_SPACE_POINTER_MODE m32c_addr_space_pointer_mode
+static enum machine_mode
+m32c_addr_space_pointer_mode (addr_space_t addrspace)
+{
+  switch (addrspace)
+    {
+    case ADDR_SPACE_GENERIC:
+      return TARGET_A24 ? PSImode : HImode;
+    case ADDR_SPACE_FAR:
+      return SImode;
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Return the appropriate mode for a named address address.  */
+#undef TARGET_ADDR_SPACE_ADDRESS_MODE
+#define TARGET_ADDR_SPACE_ADDRESS_MODE m32c_addr_space_address_mode
+static enum machine_mode
+m32c_addr_space_address_mode (addr_space_t addrspace)
+{
+  switch (addrspace)
+    {
+    case ADDR_SPACE_GENERIC:
+      return TARGET_A24 ? PSImode : HImode;
+    case ADDR_SPACE_FAR:
+      return SImode;
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* Like m32c_legitimate_address_p, except with named addresses.  */
+#undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
+#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
+  m32c_addr_space_legitimate_address_p
+static bool
+m32c_addr_space_legitimate_address_p (enum machine_mode mode, rtx x,
+				      bool strict, addr_space_t as)
+{
+  if (as == ADDR_SPACE_FAR)
+    {
+      if (TARGET_A24)
+	return 0;
+      debug_rtx(x);
+      encode_pattern (x);
+      if (RTX_IS ("r"))
+	{
+	  if (GET_MODE (x) != SImode)
+	    return 0;
+	  switch (REGNO (patternr[0]))
+	    {
+	    case A0_REGNO:
+	      return 1;
+
+	    default:
+	      if (IS_PSEUDO (patternr[0], strict))
+		return 1;
+	      return 0;
+	    }
+	}
+#if 1
+      if (RTX_IS ("+ri"))
+	{
+	  int rn = REGNO (patternr[1]);
+	  HOST_WIDE_INT offs = INTVAL (patternr[2]);
+	  if (GET_MODE (patternr[1]) != HImode)
+	    return 0;
+	  switch (rn)
+	    {
+	    case A0_REGNO:
+	      return (offs >= 0 && offs <= 0xfffff);
+
+	    default:
+	      if (IS_PSEUDO (patternr[1], strict))
+		return 1;
+	      return 0;
+	    }
+	}
+      if (RTX_IS ("+rs"))
+	{
+	  int rn = REGNO (patternr[1]);
+	  if (GET_MODE (patternr[1]) != HImode)
+	    return 0;
+	  switch (rn)
+	    {
+	    case A0_REGNO:
+	      return 1;
+
+	    default:
+	      if (IS_PSEUDO (patternr[1], strict))
+		return 1;
+	      return 0;
+	    }
+	}
+#endif
+      if (RTX_IS ("s"))
+	{
+	  return 1;
+	}
+      return 0;
+    }
+
+  else if (as != ADDR_SPACE_GENERIC)
+    gcc_unreachable ();
+
+  return m32c_legitimate_address_p (mode, x, strict);
+}
+
+/* Like m32c_legitimate_address, except with named address support.  */
+#undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
+#define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS m32c_addr_space_legitimize_address
+static rtx
+m32c_addr_space_legitimize_address (rtx x, rtx oldx, enum machine_mode mode,
+				    addr_space_t as)
+{
+  if (as != ADDR_SPACE_GENERIC)
+    {
+      if (GET_CODE (x) != REG)
+	{
+	  x = force_reg (SImode, x);
+	}
+      return x;
+    }
+
+  return m32c_legitimize_address (x, oldx, mode);
+}
+
+/* Determine if one named address space is a subset of another.  */
+#undef TARGET_ADDR_SPACE_SUBSET_P
+#define TARGET_ADDR_SPACE_SUBSET_P m32c_addr_space_subset_p
+static bool
+m32c_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
+{
+  gcc_assert (subset == ADDR_SPACE_GENERIC || subset == ADDR_SPACE_FAR);
+  gcc_assert (superset == ADDR_SPACE_GENERIC || superset == ADDR_SPACE_FAR);
+
+  if (subset == superset)
+    return true;
+
+  else
+    return (subset == ADDR_SPACE_GENERIC && superset == ADDR_SPACE_FAR);
+}
+
+#undef TARGET_ADDR_SPACE_CONVERT
+#define TARGET_ADDR_SPACE_CONVERT m32c_addr_space_convert
+/* Convert from one address space to another.  */
+static rtx
+m32c_addr_space_convert (rtx op, tree from_type, tree to_type)
+{
+  addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
+  addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
+  rtx result;
+
+  gcc_assert (from_as == ADDR_SPACE_GENERIC || from_as == ADDR_SPACE_FAR);
+  gcc_assert (to_as == ADDR_SPACE_GENERIC || to_as == ADDR_SPACE_FAR);
+
+  if (to_as == ADDR_SPACE_GENERIC && from_as == ADDR_SPACE_FAR)
+    {
+      /* This is unpredictable, as we're truncating off usable address
+	 bits.  */
+
+      result = gen_reg_rtx (HImode);
+      emit_move_insn (result, simplify_subreg (HImode, op, SImode, 0));
+      return result;
+    }
+  else if (to_as == ADDR_SPACE_FAR && from_as == ADDR_SPACE_GENERIC)
+    {
+      /* This always works.  */
+      result = gen_reg_rtx (SImode);
+      emit_insn (gen_zero_extendhisi2 (result, op));
+      return result;
+    }
+  else
+    gcc_unreachable ();
+}
+
 /* Condition Code Status */
 
 #undef TARGET_FIXED_CONDITION_CODE_REGS
 #define TARGET_FIXED_CONDITION_CODE_REGS m32c_fixed_condition_code_regs
 static bool
 m32c_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
@@ -3315,12 +3525,17 @@ m32c_split_move (rtx * operands, enum ma
      point, so it's safe to set it to 3 even with define_insn.  */
   /* None of the chips can move SI operands to sp-relative addresses,
      so we always split those.  */
   if (m32c_extra_constraint_p (operands[0], 'S', "Ss"))
     split_all = 3;
 
+  if (TARGET_A16
+      && (far_addr_space_p (operands[0])
+	  || far_addr_space_p (operands[1])))
+    split_all |= 1;
+
   /* We don't need to split these.  */
   if (TARGET_A24
       && split_all != 3
       && (mode == SImode || mode == PSImode)
       && !(GET_CODE (operands[1]) == MEM
 	   && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
Index: m32c.h
===================================================================
--- m32c.h	(revision 152757)
+++ m32c.h	(working copy)
@@ -582,12 +582,19 @@ typedef struct m32c_cumulative_args
 #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
 	if (m32c_legitimize_reload_address(&(X),MODE,OPNUM,TYPE,IND_LEVELS)) \
 	  goto WIN;
 
 #define LEGITIMATE_CONSTANT_P(X) m32c_legitimate_constant_p (X)
 
+/* Address spaces.  */
+#define ADDR_SPACE_FAR	1
+
+/* Named address space keywords.  */
+#define TARGET_ADDR_SPACE_KEYWORDS ADDR_SPACE_KEYWORD ("__far", ADDR_SPACE_FAR)
+
+
 /* Condition Code Status */
 
 #define REVERSIBLE_CC_MODE(MODE) 1
 
 /* Describing Relative Costs of Operations */
 
Index: mov.md
===================================================================
--- mov.md	(revision 152757)
+++ mov.md	(working copy)
@@ -29,51 +29,54 @@
 ;; the stack.
 
 ;; Match push/pop before mov.b for passing char as arg,
 ;; e.g. stdlib/efgcvt.c.
 (define_insn "movqi_op"
   [(set (match_operand:QI 0 "m32c_nonimmediate_operand"
-			  "=Rqi*Rmm, <,          RqiSd*Rmm, SdSs,    Rqi*Rmm, Sd")
+			  "=SF,Rhi*RmmSd, Rqi*Rmm, <,          RqiSd*Rmm, SdSs,    Rqi*Rmm, Sd")
 	(match_operand:QI 1 "m32c_any_operand"
-			  "iRqi*Rmm, iRqiSd*Rmm, >,         Rqi*Rmm, SdSs,    i"))]
+			  "Rhi*RmmSd,SF, iRqi*Rmm, iRqiSd*Rmm, >,         Rqi*Rmm, SdSs,    i"))]
   "m32c_mov_ok (operands, QImode)"
   "@
+    lde.b\t%1,%0
+    ste.b\t%1,%0
     mov.b\t%1,%0
     push.b\t%1
     pop.b\t%0
     mov.b\t%1,%0
     mov.b\t%1,%0
     mov.b\t%1,%0"
-  [(set_attr "flags" "sz,*,*,sz,sz,sz")]
+  [(set_attr "flags" "sz,sz,sz,*,*,sz,sz,sz")]
   )
 
 (define_expand "movqi"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=RqiSd*Rmm")
 	(match_operand:QI 1 "general_operand" "iRqiSd*Rmm"))]
   ""
   "if (m32c_prepare_move (operands, QImode)) DONE;"
   )
 
-
 (define_insn "movhi_op"
   [(set (match_operand:HI 0 "m32c_nonimmediate_operand"
-			  "=Rhi*Rmm,     Sd, SdSs,   *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr")
+			  "=SF,Rhi*RmmSd, Rhi*Rmm,     Sd, SdSs,   *Rcr, RhiSd*Rmm, <, RhiSd*Rmm, <, *Rcr")
 	(match_operand:HI 1 "m32c_any_operand"
-			  "iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))]
+			  " Rhi*RmmSd,SF, iRhi*RmmSdSs, i, Rhi*Rmm, RhiSd*Rmm, *Rcr, iRhiSd*Rmm, >, *Rcr, >"))]
   "m32c_mov_ok (operands, HImode)"
   "@
+   lde.w\t%1,%0
+   ste.w\t%1,%0
    mov.w\t%1,%0
    mov.w\t%1,%0
    mov.w\t%1,%0
    ldc\t%1,%0
    stc\t%1,%0
    push.w\t%1
    pop.w\t%0
    pushc\t%1
    popc\t%0"
-  [(set_attr "flags" "sz,sz,sz,n,n,n,n,n,n")]
+  [(set_attr "flags" "sz,sz,sz,sz,sz,n,n,n,n,n,n")]
   )
 
 (define_expand "movhi"
   [(set (match_operand:HI 0 "m32c_nonimmediate_operand" "=RhiSd*Rmm")
 	(match_operand:HI 1 "m32c_any_operand" "iRhiSd*Rmm"))]
   ""
Index: addsub.md
===================================================================
--- addsub.md	(revision 152757)
+++ addsub.md	(working copy)
@@ -90,15 +90,23 @@
     { 
     case 0:
       return \"add.w %X2,%h0\;adcf.w %H0\";
     case 1:
       return \"add.w %X2,%h0\;adcf.w %H0\";
     case 2:
-      output_asm_insn (\"add.w %X2,%h0\",operands);
-      operands[2]= GEN_INT (INTVAL (operands[2]) >> 16);
-      return \"adc.w %X2,%H0\";
+      if (GET_CODE (operands[2]) == SYMBOL_REF)
+        {
+          output_asm_insn (\"add.w #%%lo(%d2),%h0\",operands);
+          return \"adc.w #%%hi(%d2),%H0\";
+        }
+      else
+        {
+          output_asm_insn (\"add.w %X2,%h0\",operands);
+          operands[2]= GEN_INT (INTVAL (operands[2]) >> 16);
+          return \"adc.w %X2,%H0\";
+        }
     case 3:
       return \"add.w %h2,%h0\;adc.w %H2,%H0\";
     case 4:
       output_asm_insn (\"add.w %X2,%h0\",operands);
       operands[2]= GEN_INT (INTVAL (operands[2]) >> 16);
       return \"adc.w %X2,%H0\";

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2009-11-17 16:48 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-15  4:17 m32c support for named addr spaces branch DJ Delorie
2009-10-15 18:07 ` Ulrich Weigand
2009-10-15 18:11   ` DJ Delorie
2009-10-16 14:19     ` Ulrich Weigand
2009-10-16 18:22       ` DJ Delorie
2009-10-16 22:05       ` DJ Delorie
2009-10-19 14:28         ` Ulrich Weigand
2009-10-19 14:36           ` Richard Guenther
2009-10-19 17:45             ` Ulrich Weigand
2009-10-19 20:57               ` DJ Delorie
2009-10-20  9:27                 ` Richard Guenther
2009-10-20 18:10                   ` DJ Delorie
2009-10-21 10:20                     ` Richard Guenther
2009-10-27 18:32                       ` Ulrich Weigand
2009-10-28 11:29                         ` Richard Guenther
2009-10-29 18:32                           ` Fix PR tree-optimization/41857 (Re: m32c support for named addr spaces branch) Ulrich Weigand
2009-10-30  9:51                             ` Richard Guenther
2009-11-02  9:38                               ` Zdenek Dvorak
2009-11-16 20:07                                 ` [patch] Fix regression (Re: Fix PR tree-optimization/41857) Ulrich Weigand
2009-11-17 15:40                                   ` Richard Guenther
2009-11-17 16:03                                     ` Zdenek Dvorak
2009-11-17 16:14                                       ` Richard Guenther
2009-11-17 16:29                                         ` Zdenek Dvorak
2009-11-17 16:31                                           ` Richard Guenther
2009-11-17 16:51                                             ` Zdenek Dvorak
2009-10-30 15:55                           ` m32c support for named addr spaces branch Ulrich Weigand
2009-10-16 23:57       ` DJ Delorie
2009-10-19 14:50         ` Ulrich Weigand
2009-10-29 18:37           ` [patch] Address-space-aware base registers (Re: m32c support for named addr spaces branch) Ulrich Weigand
2009-10-29 19:54             ` DJ Delorie
2009-10-29 20:18             ` DJ Delorie
2009-10-29 21:33               ` Ulrich Weigand
2009-10-29 22:50                 ` DJ Delorie
2009-10-30 14:51                   ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).