public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Saga of m68k PIC continues
@ 2002-12-11 12:57 Peter Barada
  2002-12-11 14:25 ` Jim Wilson
  2002-12-11 16:11 ` Richard Henderson
  0 siblings, 2 replies; 17+ messages in thread
From: Peter Barada @ 2002-12-11 12:57 UTC (permalink / raw)
  To: gcc


I restarted the mind-meld of i386 PIC into m68k, and I've gone through
and modified the following defintions in m68k.h:

LEGITIITMATE_PIC_OPERAND_P
SYMBOLIC_CONST

And modified/created the following functions in m68k.c:

symbolic_operand
local_symbolic_operand
legitimate_pic_address_disp_p
symbolic_reference_mentioned_p
legitimize_pic_address

It builds now, but fails building crtstuff.c with -fPIC:

./xgcc -B./ -B/home/mylocal/xcomp/target/m68k-linux/bin/ -isystem /home/mylocal/xcomp/target/m68k-linux/include -isystem /home/mylocal/xcomp/target/m68k-linux/sys-include -O2 -DIN_GCC -DCROSS_COMPILE   -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -isystem ./include  -I. -I. -I/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc -I/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/. -I/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/config -I/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/../include  -g0 -finhibit-size-directive -fno-inline-functions -fno-exceptions -fPIC \
  -Dinhibit_libc -c /home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/crtstuff.c -DCRT_BEGIN -DCRTSTUFFS_O \
  -o crtbeginS.o
/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/crtstuff.c: In function `__do_global_dtors_aux':
/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/crtstuff.c:286: unrecognizable insn:
(insn 12 115 14 (set (reg/f:SI 32)
        (unspec:SI[ 
                (symbol_ref:SI ("completed.1"))
            ]  6)) -1 (nil)
    (expr_list:REG_EQUAL (const:SI (unspec:SI[ 
                    (symbol_ref:SI ("completed.1"))
                ]  6))
        (nil)))
/home/pbarada/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/crtstuff.c:286: Internal compiler error in extract_insn, at recog.c:2148


The backtrace points to regmove_optimize() being the current pass, and
at this point reload_in_progress *and* reload_complete are both zero,
so the pseudo should be legal.

Since I'm only trying to load the address of the symbol into a
register, I'd expect the movsi and other implicit movsi patterns to
handle it, especially:

(define_insn ""
  ;; Notes: make sure no alternative allows g vs g.
  ;; We don't allow f-regs since fixed point cannot go in them.
  ;; We do allow y and x regs since fixed point is allowed in them.
  [(set (match_operand:SI 0 "nonimmediate_operand" "=g,d,a<,y,!*x*r*m")
        (match_operand:SI 1 "general_src_operand" "daymSKT,n,i,g,*x*r*m"))]

  "!TARGET_5200"
  "*
{
  if (which_alternative == 4)
    return \"fpmove%.l %x1,fpa0\;fpmove%.l fpa0,%x0\";
  if (FPA_REG_P (operands[1]) || FPA_REG_P (operands[0]))
    return \"fpmove%.l %x1,%x0\";
  return output_move_simode (operands);
}")


I found that: 

(unspec:SI[ 
        (symbol_ref:SI ("completed.1"))
    ]  6)

is not accepted by general_operand(which is called form
general_src_operand) which to me seems very strange, especially since
the mode was SImode.

1) Should general_src_operand accept the unspec symbol?
2) If not, does anyone have an idea how I should get this instruction
   recognized? 

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-11 12:57 Saga of m68k PIC continues Peter Barada
@ 2002-12-11 14:25 ` Jim Wilson
  2002-12-11 16:11 ` Richard Henderson
  1 sibling, 0 replies; 17+ messages in thread
From: Jim Wilson @ 2002-12-11 14:25 UTC (permalink / raw)
  To: Peter Barada; +Cc: gcc

UNSPECs aren't normal operands.  They are unspecified operands, and hence are
not handled by any machine independent code.  They must be handled by machine
dependent code.  Usually, you add explicit patterns containing UNSPEC to the
md file to get them recognized.  This allows you to emit code for unusual
operations that can't be directly represented in RTL.  If you can represent
what you want in normal RTL, then you should not be using UNSPECs.

You might be able to write predicates that accept UNSPEC operands.  It isn't
the usual way of using them though.

Don't forget about PREDICATE_CODES.  If you are adding new predicates, or
modifying the operands accepted by a predicate, you need to update this
macro too.

Jim

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

* Re: Saga of m68k PIC continues
  2002-12-11 12:57 Saga of m68k PIC continues Peter Barada
  2002-12-11 14:25 ` Jim Wilson
@ 2002-12-11 16:11 ` Richard Henderson
  2002-12-11 16:19   ` Peter Barada
  1 sibling, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2002-12-11 16:11 UTC (permalink / raw)
  To: Peter Barada; +Cc: gcc

On Wed, Dec 11, 2002 at 03:45:49PM -0500, Peter Barada wrote:
> 1) Should general_src_operand accept the unspec symbol?

Nope.

> 2) If not, does anyone have an idea how I should get this instruction
>    recognized? 

You *may* want to wrap the unspec in a CONST.  That would 
make the thing be recognized by general_operand.  But I
can't tell if that's exactly right, since you've posted
no code.


r~

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

* Re: Saga of m68k PIC continues
  2002-12-11 16:11 ` Richard Henderson
@ 2002-12-11 16:19   ` Peter Barada
  2002-12-12  2:41     ` Richard Henderson
  2002-12-12 12:27     ` Peter Barada
  0 siblings, 2 replies; 17+ messages in thread
From: Peter Barada @ 2002-12-11 16:19 UTC (permalink / raw)
  To: rth; +Cc: Peter.Barada, gcc


>> 1) Should general_src_operand accept the unspec symbol?
>
>Nope.

Ah well, I went and did it anyway, and now it generates code, stuff
that actually looks like its legal(not too efficent mind you).  I
successfully build all of glibc-2.2.5 for m68k using it.
Unfortunately without hardware I can't test it :-(

>
>> 2) If not, does anyone have an idea how I should get this instruction
>>    recognized? 
>
>You *may* want to wrap the unspec in a CONST.  That would 
>make the thing be recognized by general_operand.  But I
>can't tell if that's exactly right, since you've posted
>no code.

I pulled the code from i386.c, so it should do that.  Form a dump of
-fPIC code I see:

(insn 9 39 11 (set (reg/f:SI 0 %d0 [32])
        (const:SI (unspec:SI[ 
                    (symbol_ref:SI ("a"))
                ]  6))) 29 {*m68k.md:1007} (nil)
    (expr_list:REG_EQUIV (const:SI (unspec:SI[ 
                    (symbol_ref:SI ("a"))
                ]  6))
        (nil)))

so the unspec is wrapped in a const.

Here's everthing I've done to get to this point.  Its not pretty, and
nowehere near complete.  Any suggestions on which way to go from
here will be much apprecieated.

[pbarada: ~/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/config/m68k] > cvs diff -Nu m68k-protos.h m68k.h m68k.c m68k.md
Index: m68k-protos.h
===================================================================
RCS file: /usr/local/wavemark/cvs/archives/cross-linux-tools/gcc-3.2.1/gcc/config/m68k/m68k-protos.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 m68k-protos.h
--- m68k-protos.h	2002/11/25 23:46:44	1.1.1.1
+++ m68k-protos.h	2002/12/12 00:05:15
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler.  Sun 68000/68020 version.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -47,6 +47,8 @@
 extern int strict_low_part_peephole_ok PARAMS ((enum machine_mode, rtx, rtx));
 
 /* Functions from m68k.c used in macros.  */
+extern int symbolic_reference_mentioned_p PARAMS ((rtx));
+extern int legitimate_pic_address_disp_p PARAMS ((rtx));
 extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
 extern int const_int_cost PARAMS ((rtx));
 extern int standard_68881_constant_p PARAMS ((rtx));
Index: m68k.h
===================================================================
RCS file: /usr/local/wavemark/cvs/archives/cross-linux-tools/gcc-3.2.1/gcc/config/m68k/m68k.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 m68k.h
--- m68k.h	2002/11/25 23:46:44	1.1.1.1
+++ m68k.h	2002/12/12 00:05:16
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler.
    Sun 68000/68020 version.
-   Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2002,
    2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
@@ -280,7 +280,7 @@
 #define OVERRIDE_OPTIONS		\
 {					\
   override_options();			\
-  if (! TARGET_68020 && flag_pic == 2)	\
+  if (! (TARGET_68020 || TARGET_5200) && flag_pic == 2)	\
     error("-fPIC is not currently supported on the 68000 or 68010\n");	\
   if (TARGET_PCREL && flag_pic == 0)	\
     flag_pic = 1;			\
@@ -1305,6 +1305,16 @@
 #define PCREL_GENERAL_OPERAND_OK (TARGET_PCREL)
 #endif
 
+#if 1
+#define LEGITIMATE_PIC_OPERAND_P(X)		\
+  (! SYMBOLIC_CONST (X)				\
+   || legitimate_pic_address_disp_p (X))
+
+#define SYMBOLIC_CONST(X)	\
+  (GET_CODE (X) == SYMBOL_REF						\
+   || GET_CODE (X) == LABEL_REF						\
+   || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
+#else
 #define LEGITIMATE_PIC_OPERAND_P(X)	\
   ((! symbolic_operand (X, VOIDmode)				\
     && ! (GET_CODE (X) == CONST_DOUBLE && mem_for_const_double (X) != 0	\
@@ -1313,6 +1323,7 @@
 			       VOIDmode))) 				\
    || (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_FLAG (X))		\
    || PCREL_GENERAL_OPERAND_OK)
+#endif
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
Index: m68k.c
===================================================================
RCS file: /usr/local/wavemark/cvs/archives/cross-linux-tools/gcc-3.2.1/gcc/config/m68k/m68k.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 m68k.c
--- m68k.c	2002/11/25 23:46:44	1.1.1.1
+++ m68k.c	2002/12/12 00:05:16
@@ -1,5 +1,5 @@
 /* Subroutines for insn-output.c for Motorola 68000 family.
-   Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of GNU CC.
@@ -124,6 +124,12 @@
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
+#if 1
+/* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
+static char internal_label_prefix[16];
+static int internal_label_prefix_len;
+#endif
+
 /* Sometimes certain combinations of command options do not make
    sense on a particular target machine.  You can define a macro
    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
@@ -174,6 +180,15 @@
       else
 	m68k_align_funcs = i;
     }
+
+  /* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix.  */
+  {
+    char *p;
+    ASM_GENERATE_INTERNAL_LABEL (internal_label_prefix, "LX", 0);
+    p = strchr (internal_label_prefix, 'X');
+    internal_label_prefix_len = p - internal_label_prefix;
+    *p = '\0';
+  }
 }
 \f
 /* This function generates the assembly code for function entry.
@@ -341,11 +356,22 @@
 
   if (flag_pic && current_function_uses_pic_offset_table)
     {
-      fprintf (stream, "\tmove.l #__GLOBAL_OFFSET_TABLE_, %s\n",
-	       reg_names[PIC_OFFSET_TABLE_REGNUM]);
-      fprintf (stream, "\tlea.l (pc,%s.l),%s\n",
-	       reg_names[PIC_OFFSET_TABLE_REGNUM],
-	       reg_names[PIC_OFFSET_TABLE_REGNUM]);
+      if (TARGET_5200)
+        {
+          asm_fprintf (stream, "\tmovel %0I_GLOBAL_OFFSET_TABLE_@GOTPC, %s\n",
+                       reg_names[PIC_OFFSET_TABLE_REGNUM]);
+          asm_fprintf (stream, "\tlea %Rpc@(-6,%s:l),%s\n",
+                       reg_names[PIC_OFFSET_TABLE_REGNUM],
+                       reg_names[PIC_OFFSET_TABLE_REGNUM]);
+        }
+      else
+        {
+          fprintf (stream, "\tmove.l #__GLOBAL_OFFSET_TABLE_, %s\n",
+                   reg_names[PIC_OFFSET_TABLE_REGNUM]);
+          fprintf (stream, "\tlea.l (pc,%s.l),%s\n",
+                   reg_names[PIC_OFFSET_TABLE_REGNUM],
+                   reg_names[PIC_OFFSET_TABLE_REGNUM]);
+        }
     }
 }
 
@@ -1901,6 +1927,7 @@
 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
    reference and a constant.  */
 
+#if 1
 int
 symbolic_operand (op, mode)
      register rtx op;
@@ -1914,6 +1941,50 @@
 
     case CONST:
       op = XEXP (op, 0);
+      if (GET_CODE (op) == SYMBOL_REF
+	  || GET_CODE (op) == LABEL_REF
+	  || (GET_CODE (op) == UNSPEC
+	      && (XINT (op, 1) == 6
+		  || XINT (op, 1) == 7
+		  || XINT (op, 1) == 15)))
+	return 1;
+      if (GET_CODE (op) != PLUS
+	  || GET_CODE (XEXP (op, 1)) != CONST_INT)
+	return 0;
+
+      op = XEXP (op, 0);
+      if (GET_CODE (op) == SYMBOL_REF
+	  || GET_CODE (op) == LABEL_REF)
+	return 1;
+      /* Only @GOTOFF gets offsets.  */
+      if (GET_CODE (op) != UNSPEC
+	  || XINT (op, 1) != 7)
+	return 0;
+
+      op = XVECEXP (op, 0, 0);
+      if (GET_CODE (op) == SYMBOL_REF
+	  || GET_CODE (op) == LABEL_REF)
+	return 1;
+      return 0;
+
+    default:
+      return 0;
+    }
+}
+#else
+int
+symbolic_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  switch (GET_CODE (op))
+    {
+    case SYMBOL_REF:
+    case LABEL_REF:
+      return 1;
+
+    case CONST:
+      op = XEXP (op, 0);
       return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
 	       || GET_CODE (XEXP (op, 0)) == LABEL_REF)
 	      && GET_CODE (XEXP (op, 1)) == CONST_INT);
@@ -1928,6 +1999,7 @@
       return 0;
     }
 }
+#endif
 \f
 /* Check for sign_extend or zero_extend.  Used for bit-count operands.  */
 
@@ -1949,6 +2021,110 @@
 }
 
 \f
+
+#if 1
+/* Return true if OP is a symbolic operand that resolves locally.  */
+
+static int
+local_symbolic_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  if (GET_CODE (op) == LABEL_REF)
+    return 1;
+
+  if (GET_CODE (op) == CONST
+      && GET_CODE (XEXP (op, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
+    op = XEXP (XEXP (op, 0), 0);
+
+  if (GET_CODE (op) != SYMBOL_REF)
+    return 0;
+
+  /* These we've been told are local by varasm and encode_section_info
+     respectively.  */
+  if (CONSTANT_POOL_ADDRESS_P (op) || SYMBOL_REF_FLAG (op))
+    return 1;
+
+  /* There is, however, a not insubstantial body of code in the rest of
+     the compiler that assumes it can just stick the results of 
+     ASM_GENERATE_INTERNAL_LABEL in a symbol_ref and have done.  */
+  /* ??? This is a hack.  Should update the body of the compiler to
+     always create a DECL an invoke ENCODE_SECTION_INFO.  */
+  if (strncmp (XSTR (op, 0), internal_label_prefix,
+	       internal_label_prefix_len) == 0)
+    return 1;
+
+  return 0;
+}
+
+/* Determine if a given CONST RTX is a valid memory displacement
+   in PIC mode.  */
+
+int
+legitimate_pic_address_disp_p (disp)
+     register rtx disp;
+{
+  if (GET_CODE (disp) != CONST)
+    return 0;
+  disp = XEXP (disp, 0);
+
+  if (GET_CODE (disp) == PLUS)
+    {
+      if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
+	return 0;
+      disp = XEXP (disp, 0);
+    }
+
+  if (GET_CODE (disp) != UNSPEC
+      || XVECLEN (disp, 0) != 1)
+    return 0;
+
+  /* Must be @GOT or @GOTOFF.  */
+  switch (XINT (disp, 1))
+    {
+    case 6: /* @GOT */
+      return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
+
+    case 7: /* @GOTOFF */
+      return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
+    }
+    
+  return 0;
+}
+
+/* Returns 1 if OP contains a symbol reference */
+
+int
+symbolic_reference_mentioned_p (op)
+     rtx op;
+{
+  register const char *fmt;
+  register int i;
+
+  if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
+    return 1;
+
+  fmt = GET_RTX_FORMAT (GET_CODE (op));
+  for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
+    {
+      if (fmt[i] == 'E')
+	{
+	  register int j;
+
+	  for (j = XVECLEN (op, i) - 1; j >= 0; j--)
+	    if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
+	      return 1;
+	}
+
+      else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
+	return 1;
+    }
+
+  return 0;
+}
+
+#endif
 /* Legitimize PIC addresses.  If the address is already
    position-independent, we return ORIG.  Newly generated
    position-independent addresses go to REG.  If we need more
@@ -1989,6 +2165,122 @@
    That (in a nutshell) is how *all* symbol and label references are 
    handled.  */
 
+#if 1
+rtx
+legitimize_pic_address (orig, mode, reg)
+     rtx orig, reg;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  rtx addr = orig;
+  rtx pic_ref = addr;
+  rtx base;
+
+  /* First handle a simple SYMBOL_REF or LABEL_REF */
+  if (local_symbolic_operand(addr, Pmode))
+    {
+      if (reg == 0)
+	abort ();
+
+      if (TARGET_5200)
+        {
+          pic_ref = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 7);
+          pic_ref = gen_rtx_CONST (Pmode, pic_ref);
+          /* Now move the symbol into a register(w/o using emit_move_insn) */
+          RTX_UNCHANGING_P (pic_ref) = 1;
+          emit_insn (gen_rtx_SET (Pmode, reg, pic_ref));
+          pic_ref = gen_rtx_MEM (Pmode,
+                                 gen_rtx_PLUS (Pmode,
+                                               pic_offset_table_rtx, reg));
+        }
+      else
+        {
+          pic_ref = gen_rtx_MEM (Pmode,
+                                 gen_rtx_PLUS (Pmode,
+                                               pic_offset_table_rtx, addr));
+        }
+      current_function_uses_pic_offset_table = 1;
+      RTX_UNCHANGING_P (pic_ref) = 1;
+      emit_move_insn (reg, pic_ref);
+      return reg;
+    }
+  else if (GET_CODE (addr) == SYMBOL_REF)
+    {
+      /* This symbol must be referenced via a load from the
+         Global Offset Table (@GOT).  */
+
+      current_function_uses_pic_offset_table = 1;
+      pic_ref = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 6);
+      pic_ref = gen_rtx_CONST (Pmode, pic_ref);
+      pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pic_ref);
+      pic_ref = gen_rtx_MEM (Pmode, pic_ref);
+      RTX_UNCHANGING_P (pic_ref) = 1;
+      /*      set_mem_alias_set (new, ix86_GOT_alias_set ()); */
+
+      if (reg == 0)
+        reg = gen_reg_rtx (Pmode);
+      emit_move_insn (reg, pic_ref);
+      pic_ref = reg;
+    }
+  else 
+    {
+      if (GET_CODE (addr) == CONST)
+	{
+	  addr = XEXP (addr, 0);
+
+	  /* We must match stuff we generate before.  Assume the only
+	     unspecs that can get here are ours.  Not that we could do
+	     anything with them anyway...  */
+	  if (GET_CODE (addr) == UNSPEC
+	      || (GET_CODE (addr) == PLUS
+		  && GET_CODE (XEXP (addr, 0)) == UNSPEC))
+	    return addr;
+	  if (GET_CODE (addr) != PLUS)
+	    abort ();
+	}
+      if (GET_CODE (addr) == PLUS)
+	{
+	  rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
+
+	  /* Check first to see if this is a constant offset from a @GOTOFF
+	     symbol reference.  */
+	  if (local_symbolic_operand (op0, Pmode)
+	      && GET_CODE (op1) == CONST_INT)
+	    {
+              current_function_uses_pic_offset_table = 1;
+              pic_ref = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 7);
+              pic_ref = gen_rtx_PLUS (Pmode, pic_ref, op1);
+              pic_ref = gen_rtx_CONST (Pmode, pic_ref);
+              pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pic_ref);
+              
+              if (reg != 0)
+                {
+                  emit_move_insn (reg, pic_ref);
+                  pic_ref = reg;
+                }
+	    }
+	  else
+	    {
+	      base = legitimize_pic_address (XEXP (addr, 0), mode, reg);
+	      pic_ref  = legitimize_pic_address (XEXP (addr, 1),
+					     mode, base == reg ? NULL_RTX : reg);
+
+	      if (GET_CODE (pic_ref) == CONST_INT)
+		pic_ref = plus_constant (base, INTVAL (pic_ref));
+	      else
+		{
+		  if (GET_CODE (pic_ref) == PLUS && CONSTANT_P (XEXP (pic_ref, 1)))
+		    {
+		      base = gen_rtx_PLUS (Pmode, base, XEXP (pic_ref, 0));
+		      pic_ref = XEXP (pic_ref, 1);
+		    }
+		  pic_ref = gen_rtx_PLUS (Pmode, base, pic_ref);
+		}
+	    }
+	}
+    }
+  return pic_ref;
+}
+#else
 rtx
 legitimize_pic_address (orig, mode, reg)
      rtx orig, reg;
@@ -2038,6 +2330,7 @@
     }
   return pic_ref;
 }
+#endif
 
 \f
 typedef enum { MOVL, SWAP, NEGW, NOTW, NOTB, MOVQ } CONST_METHOD;
@@ -3394,6 +3687,40 @@
 
    */
 
+static void output_pic_addr_const(file, op)
+     FILE *file;
+     rtx op;
+{
+  if (GET_CODE (op) == CONST)
+    op = XEXP(op, 0);
+  if (GET_CODE (op) == UNSPEC)
+    {
+       if (XVECLEN (op, 0) != 1)
+	abort ();
+       output_pic_addr_const (file, XVECEXP (op, 0, 0));
+       switch (XINT (op, 1))
+	{
+	case 6:
+	  fputs ("@GOT", file);
+	  break;
+	case 7:
+	  fputs ("@GOTOFF", file);
+	  break;
+	case 8:
+	  fputs ("@PLT", file);
+	  break;
+	case 15:
+	  fputs ("@GOTPCREL(%RIP)", file);
+	  break;
+	default:
+	  output_operand_lossage ("invalid UNSPEC as operand");
+	  break;
+	}
+    }
+  else
+    output_addr_const(file, op);    
+}
+
 void
 print_operand (file, op, letter)
      FILE *file;		/* file to write to */
@@ -3466,7 +3793,10 @@
       if (GET_CODE (op) != MEM || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
           || !TARGET_PCREL) 
 	abort ();
-      output_addr_const (file, XEXP (op, 0));
+      if (flag_pic)
+        output_pic_addr_const (file, XEXP (op, 0));
+      else
+        output_addr_const (file, XEXP (op, 0));
     }
   else if (GET_CODE (op) == REG)
     {
@@ -3540,7 +3870,10 @@
 	  && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
 	print_operand_address (file, op);
       else
-	output_addr_const (file, op);
+        if (flag_pic)
+          output_pic_addr_const (file, op);
+        else
+          output_addr_const (file, op);
     }
 }
 
@@ -4065,6 +4398,11 @@
 	  || GET_CODE (XEXP (op, 0)) == LABEL_REF
 	  || GET_CODE (XEXP (op, 0)) == CONST))
     return 1;
+#if 1
+  /* Accept symols */
+  if (symbolic_operand(op, mode) || local_symbolic_operand(op, mode))
+    return 1;
+#endif
   return general_operand (op, mode);
 }
 
Index: m68k.md
===================================================================
RCS file: /usr/local/wavemark/cvs/archives/cross-linux-tools/gcc-3.2.1/gcc/config/m68k/m68k.md,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 m68k.md
--- m68k.md	2002/11/25 23:46:44	1.1.1.1
+++ m68k.md	2002/12/12 00:05:16
@@ -273,6 +273,13 @@
 
 ;;- END FPA Explanation Section.
 
+/* Defien the constants being used by the unspec */
+(define_constants [
+  (UNSPEC_SIN		1)
+  (UNSPEC_COS		2)
+  (UNSPEC_GOT		3)
+  (UNSPEC_GOTOFF	4)
+])
 
 ;;- Some of these insn's are composites of several m68000 op codes.
 ;;- The assembler (or final @@??) insures that the appropriate one is
@@ -948,6 +955,29 @@
   ""
   "
 {
+#if 1
+    /* if PIC, push symbol into a register and then do the add */
+    if (flag_pic)
+      {
+        if (!reload_in_progress)
+          {
+            /* If the destination is a symbol,
+               push its address into a register */
+            if (symbolic_operand (operands[0], SImode))
+              operands[0] = force_reg (SImode, XEXP (operands[0], 0));
+            else if (GET_CODE (operands[0]) == MEM
+                     && symbolic_operand (XEXP (operands[0], 0), SImode))
+              operands[0] = gen_rtx (MEM, SImode,
+                                     force_reg (SImode, XEXP (operands[0], 0)));
+          }
+
+        if (symbolic_operand (operands[1], SImode))
+          {
+            rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
+            operands[1] = legitimize_pic_address (operands[1], SImode, temp);
+          }
+      }
+#else
   if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
     {
       /* The source is an address which requires PIC relocation.
@@ -968,6 +998,7 @@
 	operands[0] = gen_rtx (MEM, SImode,
 			       force_reg (SImode, XEXP (operands[0], 0)));
     }
+#endif
 }")
 
 ;; General case of fullword move.  The register constraints
@@ -8315,7 +8346,7 @@
 
 (define_insn "sinsf2"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
-	(unspec:SF [(match_operand:SF 1 "general_operand" "fm")] 1))]
+	(unspec:SF [(match_operand:SF 1 "general_operand" "fm")] UNSPEC_SIN))]
   "TARGET_68881 && flag_unsafe_math_optimizations"
   "*
 {
@@ -8327,7 +8358,7 @@
 
 (define_insn "sindf2"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
-	(unspec:DF [(match_operand:DF 1 "general_operand" "fm")] 1))]
+	(unspec:DF [(match_operand:DF 1 "general_operand" "fm")] UNSPEC_SIN))]
   "TARGET_68881 && flag_unsafe_math_optimizations"
   "*
 {
@@ -8339,13 +8370,13 @@
 
 (define_insn "sinxf2"
   [(set (match_operand:XF 0 "nonimmediate_operand" "=f")
-	(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 1))]
+	(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] UNSPEC_SIN))]
   "TARGET_68881 && flag_unsafe_math_optimizations"
   "fsin%.x %1,%0")
 
 (define_insn "cossf2"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=f")
-	(unspec:SF [(match_operand:SF 1 "general_operand" "fm")] 2))]
+	(unspec:SF [(match_operand:SF 1 "general_operand" "fm")] UNSPEC_COS))]
   "TARGET_68881 && flag_unsafe_math_optimizations"
   "*
 {
@@ -8357,7 +8388,7 @@
 
 (define_insn "cosdf2"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=f")
-	(unspec:DF [(match_operand:DF 1 "general_operand" "fm")] 2))]
+	(unspec:DF [(match_operand:DF 1 "general_operand" "fm")] UNSPEC_COS))]
   "TARGET_68881 && flag_unsafe_math_optimizations"
   "*
 {
@@ -8369,7 +8400,7 @@
 
 (define_insn "cosxf2"
   [(set (match_operand:XF 0 "nonimmediate_operand" "=f")
-	(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] 2))]
+	(unspec:XF [(match_operand:XF 1 "nonimmediate_operand" "fm")] UNSPEC_COS))]
   "TARGET_68881 && flag_unsafe_math_optimizations"
   "fcos%.x %1,%0")
 
[pbarada: ~/work/cvs-wavemark/cross-linux-tools/gcc-3.2.1/gcc/config/m68k] > 

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-11 16:19   ` Peter Barada
@ 2002-12-12  2:41     ` Richard Henderson
  2002-12-12  5:11       ` Andreas Schwab
  2002-12-12 12:27     ` Peter Barada
  1 sibling, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2002-12-12  2:41 UTC (permalink / raw)
  To: Peter Barada; +Cc: Peter.Barada, gcc

On Wed, Dec 11, 2002 at 07:11:05PM -0500, Peter Barada wrote:
> +	case 7:
> +	  fputs ("@GOTOFF", file);
> +	  break;

Note that m68k doesn't have @GOTOFF.  The equivalent there
is pc-relative addressing modes.

Ideally, m68k pic code generation would use @GOTPC, a-la

	extern int foo;
	foo = 1;

	movel	(%pc, foo@GOTPC), %a0
	moveql	#1, (%a0)

	static int bar, baz;
	bar = baz;

	lea	(%pc, bar), %a0
	movel	(%pc, baz), (%a0)

I can't really think of any reason that 68020+ would
actually need a pic register.  For 68000 and coldfire
I guess you need one because of the limited range of
the pc-relative offsets.


r~

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

* Re: Saga of m68k PIC continues
  2002-12-12  2:41     ` Richard Henderson
@ 2002-12-12  5:11       ` Andreas Schwab
  2002-12-12 11:24         ` Richard Henderson
  0 siblings, 1 reply; 17+ messages in thread
From: Andreas Schwab @ 2002-12-12  5:11 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Peter Barada, Peter.Barada, gcc

Richard Henderson <rth@redhat.com> writes:

|> On Wed, Dec 11, 2002 at 07:11:05PM -0500, Peter Barada wrote:
|> > +	case 7:
|> > +	  fputs ("@GOTOFF", file);
|> > +	  break;
|> 
|> Note that m68k doesn't have @GOTOFF.  The equivalent there
|> is pc-relative addressing modes.
|> 
|> Ideally, m68k pic code generation would use @GOTPC, a-la
|> 
|> 	extern int foo;
|> 	foo = 1;
|> 
|> 	movel	(%pc, foo@GOTPC), %a0
|> 	moveql	#1, (%a0)
|> 
|> 	static int bar, baz;
|> 	bar = baz;
|> 
|> 	lea	(%pc, bar), %a0
|> 	movel	(%pc, baz), (%a0)
|> 
|> I can't really think of any reason that 68020+ would
|> actually need a pic register.

For -fPIC there is probably no difference, but full 32-bit pc-relative is
still less efficient than register+16 bit offset, so with -fpic the use of
the pic register is usually faster.  Note also that pc-relative addresses
cannot be used as destination operand.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: Saga of m68k PIC continues
  2002-12-12  5:11       ` Andreas Schwab
@ 2002-12-12 11:24         ` Richard Henderson
  2002-12-12 11:28           ` Andreas Schwab
  0 siblings, 1 reply; 17+ messages in thread
From: Richard Henderson @ 2002-12-12 11:24 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Peter Barada, Peter.Barada, gcc

On Thu, Dec 12, 2002 at 11:41:23AM +0100, Andreas Schwab wrote:
> For -fPIC there is probably no difference, but full 32-bit pc-relative is
> still less efficient than register+16 bit offset, so with -fpic the use of
> the pic register is usually faster.

Even though you've got to have an extra memory load?  I mean, for
a *static* variable, your choices for computing the address are

	movel	foo@GOT.w(%a5), %a0
or
	lea	foo(%pc), %a0

And of course the later can be used in a source address directly.
Well, I suppose technically both of them can, since you've got
double-indirect memory addresses, but I can't imagine that that's
lightning quick.

> Note also that pc-relative addresses cannot be used as destination operand.

Indeed.  A very unfortunate asymmetry.  But it looks like we
already model this with general_src_operand and the S and T
constraints.


r~

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

* Re: Saga of m68k PIC continues
  2002-12-12 11:24         ` Richard Henderson
@ 2002-12-12 11:28           ` Andreas Schwab
  0 siblings, 0 replies; 17+ messages in thread
From: Andreas Schwab @ 2002-12-12 11:28 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Peter Barada, Peter.Barada, gcc

Richard Henderson <rth@redhat.com> writes:

|> On Thu, Dec 12, 2002 at 11:41:23AM +0100, Andreas Schwab wrote:
|> > For -fPIC there is probably no difference, but full 32-bit pc-relative is
|> > still less efficient than register+16 bit offset, so with -fpic the use of
|> > the pic register is usually faster.
|> 
|> Even though you've got to have an extra memory load?  I mean, for
|> a *static* variable, your choices for computing the address are

For a static variable you are right.  I was thinking about non-static
variables, i.e @GOT vs @GOTPC.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: Saga of m68k PIC continues
  2002-12-11 16:19   ` Peter Barada
  2002-12-12  2:41     ` Richard Henderson
@ 2002-12-12 12:27     ` Peter Barada
  2002-12-12 12:44       ` Jan Hubicka
  1 sibling, 1 reply; 17+ messages in thread
From: Peter Barada @ 2002-12-12 12:27 UTC (permalink / raw)
  To: Peter.Barada; +Cc: rth, Peter.Barada, gcc


>
>> 2) If not, does anyone have an idea how I should get this instruction
>>    recognized? 
>
>You *may* want to wrap the unspec in a CONST.  That would 
>make the thing be recognized by general_operand.  But I
>can't tell if that's exactly right, since you've posted
>no code.

Using the extremely simple test program:

extern int foo;
void z(void)
{
  foo = 1;
}

Compiled with -fPIC -O2 -S, I get:

z:
	link.w %a6,#0
	move.l %a5,-(%sp)
	lea (%pc, _GLOBAL_OFFSET_TABLE_@GOTPC), %a5
	lea foo,%a0
	moveq.l #1,%d0
	move.l %d0,(%a0)
	move.l (%sp)+,%a5
	unlk %a6
	rts

Looks like the -fPIC stuff failed and completely due to something
betwwen zz.c.03.jump and zz.c.08.cse converting the (const (uspec:SI
[...] 3)) into (uspec:SI [...] 3).

From the debug output, I see the following:

From zz.c.00.rtl I see:

(note 2 0 3 NOTE_INSN_DELETED)

(note 3 2 4 NOTE_INSN_FUNCTION_BEG)

(note 4 3 5 NOTE_INSN_DELETED)

(note 5 4 6 NOTE_INSN_DELETED)

(note 6 5 9 NOTE_INSN_DELETED)

(insn 9 6 11 (set (reg:SI 30)
        (const:SI (unspec:SI[ 
                    (symbol_ref:SI ("foo"))
                ]  3))) -1 (nil)
    (expr_list:REG_EQUAL (const:SI (unspec:SI[ 
                    (symbol_ref:SI ("foo"))
                ]  3))
        (nil)))

(insn 11 9 13 (set (reg/f:SI 29)
        (mem/u:SI (plus:SI (reg:SI 13 %a5)
                (reg:SI 30)) [0 S4 A8])) -1 (nil)
    (expr_list:REG_EQUAL (symbol_ref:SI ("foo"))
        (nil)))

(insn 13 11 14 (set (mem/f:SI (reg/f:SI 29) [2 foo+0 S4 A16])
        (const_int 1 [0x1])) -1 (nil)
    (nil))

(note 14 13 16 NOTE_INSN_FUNCTION_END)


Which looks the same in zz.c.03.jump.  From zz.c.08.cse I see:

(note 2 0 3 NOTE_INSN_DELETED)

(note 3 2 17 NOTE_INSN_FUNCTION_BEG)

(note 17 3 11 [bb 0] NOTE_INSN_BASIC_BLOCK)

(insn 11 17 13 (set (reg/f:SI 29)
        (symbol_ref:SI ("foo"))) 29 {*m68k.md:1011} (nil)
    (expr_list:REG_EQUAL (symbol_ref:SI ("foo"))
        (nil)))

(insn 13 11 14 (set (mem/f:SI (reg/f:SI 29) [2 foo+0 S4 A16])
        (const_int 1 [0x1])) 29 {*m68k.md:1011} (nil)
    (nil))


Note the removal of the (const ... ) in insn 11.

Any ideas where this is being stripped off?

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-12 12:27     ` Peter Barada
@ 2002-12-12 12:44       ` Jan Hubicka
  2002-12-12 12:44         ` Peter Barada
  0 siblings, 1 reply; 17+ messages in thread
From: Jan Hubicka @ 2002-12-12 12:44 UTC (permalink / raw)
  To: Peter Barada; +Cc: Peter.Barada, rth, gcc

> 
> >
> >> 2) If not, does anyone have an idea how I should get this instruction
> >>    recognized? 
> >
> >You *may* want to wrap the unspec in a CONST.  That would 
> >make the thing be recognized by general_operand.  But I
> >can't tell if that's exactly right, since you've posted
> >no code.
> 
> Using the extremely simple test program:
> 
> extern int foo;
> void z(void)
> {
>   foo = 1;
> }
> 
> Compiled with -fPIC -O2 -S, I get:
> 
> z:
> 	link.w %a6,#0
> 	move.l %a5,-(%sp)
> 	lea (%pc, _GLOBAL_OFFSET_TABLE_@GOTPC), %a5
> 	lea foo,%a0
> 	moveq.l #1,%d0
> 	move.l %d0,(%a0)
> 	move.l (%sp)+,%a5
> 	unlk %a6
> 	rts
> 
> Looks like the -fPIC stuff failed and completely due to something
> betwwen zz.c.03.jump and zz.c.08.cse converting the (const (uspec:SI
> [...] 3)) into (uspec:SI [...] 3).
> 
> >From the debug output, I see the following:
> 
> >From zz.c.00.rtl I see:
> 
> (note 2 0 3 NOTE_INSN_DELETED)
> 
> (note 3 2 4 NOTE_INSN_FUNCTION_BEG)
> 
> (note 4 3 5 NOTE_INSN_DELETED)
> 
> (note 5 4 6 NOTE_INSN_DELETED)
> 
> (note 6 5 9 NOTE_INSN_DELETED)
> 
> (insn 9 6 11 (set (reg:SI 30)
>         (const:SI (unspec:SI[ 
>                     (symbol_ref:SI ("foo"))
>                 ]  3))) -1 (nil)
>     (expr_list:REG_EQUAL (const:SI (unspec:SI[ 
>                     (symbol_ref:SI ("foo"))
>                 ]  3))
>         (nil)))
> 
> (insn 11 9 13 (set (reg/f:SI 29)
>         (mem/u:SI (plus:SI (reg:SI 13 %a5)
>                 (reg:SI 30)) [0 S4 A8])) -1 (nil)
>     (expr_list:REG_EQUAL (symbol_ref:SI ("foo"))
>         (nil)))
> 
> (insn 13 11 14 (set (mem/f:SI (reg/f:SI 29) [2 foo+0 S4 A16])
>         (const_int 1 [0x1])) -1 (nil)
>     (nil))
> 
> (note 14 13 16 NOTE_INSN_FUNCTION_END)
> 
> 
> Which looks the same in zz.c.03.jump.  From zz.c.08.cse I see:
> 
> (note 2 0 3 NOTE_INSN_DELETED)
> 
> (note 3 2 17 NOTE_INSN_FUNCTION_BEG)
> 
> (note 17 3 11 [bb 0] NOTE_INSN_BASIC_BLOCK)
> 
> (insn 11 17 13 (set (reg/f:SI 29)
>         (symbol_ref:SI ("foo"))) 29 {*m68k.md:1011} (nil)
>     (expr_list:REG_EQUAL (symbol_ref:SI ("foo"))
>         (nil)))
> 
> (insn 13 11 14 (set (mem/f:SI (reg/f:SI 29) [2 foo+0 S4 A16])
>         (const_int 1 [0x1])) 29 {*m68k.md:1011} (nil)
>     (nil))
> 
> 
> Note the removal of the (const ... ) in insn 11.
> 
> Any ideas where this is being stripped off?
GCC will happily put in the subreg when your machine description accept
it.  There are hooks defining valid addresses and constants and these
must refuse invalid stuff, like (symbol_ref:SI ("foo") is for PIC.

Honza
> 
> -- 
> Peter Barada                                   Peter.Barada@motorola.com
> Wizard                                         781-852-2768 (direct)
> WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-12 12:44       ` Jan Hubicka
@ 2002-12-12 12:44         ` Peter Barada
  2002-12-12 13:00           ` Jan Hubicka
  0 siblings, 1 reply; 17+ messages in thread
From: Peter Barada @ 2002-12-12 12:44 UTC (permalink / raw)
  To: jh; +Cc: Peter.Barada, Peter.Barada, rth, gcc


>> Note the removal of the (const ... ) in insn 11.
>> 
>> Any ideas where this is being stripped off?
>
>GCC will happily put in the subreg when your machine description accept
>it.

I don't see how subregs take care of -fPIC and (unspec ...).  Could
you explain?

>There are hooks defining valid addresses and constants and these
>must refuse invalid stuff, like (symbol_ref:SI ("foo") is for PIC.

Do you mean that GO_IF_LEGITIMATE_ADDRESS needs to reject a raw
(symbol_ref:SI ("foo")) if in pic mode,  which would then force the
addr to be pushed through LEGITIMIZE_ADDRESS(I think) where it would
spot the raw symbol_ref in pic mode and by wrap it in a (const
(uspec:SI [...] 3))? 

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-12 12:44         ` Peter Barada
@ 2002-12-12 13:00           ` Jan Hubicka
  2002-12-12 13:46             ` Peter Barada
  2002-12-12 13:50             ` Peter Barada
  0 siblings, 2 replies; 17+ messages in thread
From: Jan Hubicka @ 2002-12-12 13:00 UTC (permalink / raw)
  To: Peter Barada; +Cc: jh, Peter.Barada, rth, gcc

> 
> >> Note the removal of the (const ... ) in insn 11.
> >> 
> >> Any ideas where this is being stripped off?
> >
> >GCC will happily put in the subreg when your machine description accept
> >it.
> 
> I don't see how subregs take care of -fPIC and (unspec ...).  Could
> you explain?
Oops, I meant symbol_ref, of course...
> 
> >There are hooks defining valid addresses and constants and these
> >must refuse invalid stuff, like (symbol_ref:SI ("foo") is for PIC.
> 
> Do you mean that GO_IF_LEGITIMATE_ADDRESS needs to reject a raw
> (symbol_ref:SI ("foo")) if in pic mode,  which would then force the
> addr to be pushed through LEGITIMIZE_ADDRESS(I think) where it would
> spot the raw symbol_ref in pic mode and by wrap it in a (const
> (uspec:SI [...] 3))? 
Yes, and additionally you need LEGITIMATE_PIC_OPERAND_P to reject
symbol_ref as immediate operands.

Honza
> 
> -- 
> Peter Barada                                   Peter.Barada@motorola.com
> Wizard                                         781-852-2768 (direct)
> WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-12 13:00           ` Jan Hubicka
@ 2002-12-12 13:46             ` Peter Barada
  2002-12-12 14:32               ` Jim Wilson
  2002-12-12 13:50             ` Peter Barada
  1 sibling, 1 reply; 17+ messages in thread
From: Peter Barada @ 2002-12-12 13:46 UTC (permalink / raw)
  To: jh; +Cc: Peter.Barada, jh, Peter.Barada, rth, gcc


>> >GCC will happily put in the subreg when your machine description accept
>> >it.
>> 
>> I don't see how subregs take care of -fPIC and (unspec ...).  Could
>> you explain?
>Oops, I meant symbol_ref, of course...

Ok, that makes more sense.

>> Do you mean that GO_IF_LEGITIMATE_ADDRESS needs to reject a raw
>> (symbol_ref:SI ("foo")) if in pic mode,  which would then force the
>> addr to be pushed through LEGITIMIZE_ADDRESS(I think) where it would
>> spot the raw symbol_ref in pic mode and by wrap it in a (const
>> (uspec:SI [...] 3))? 
>Yes, and additionally you need LEGITIMATE_PIC_OPERAND_P to reject
>symbol_ref as immediate operands.

I've got:

int
legitimate_pic_operand_p (op)
     rtx op;
{
  if (!SYMBOLIC_CONST (op))
    return 1;
  return legitimate_pic_address_disp_p (op);
}

int
legitimate_pic_address_disp_p (disp)
     register rtx disp;
{
  if (GET_CODE (disp) != CONST)
    return 0;
  disp = XEXP (disp, 0);

  if (GET_CODE (disp) == PLUS)
    {
      if (GET_CODE (XEXP (disp, 1)) != CONST_INT)
	return 0;
      disp = XEXP (disp, 0);
    }

  if (GET_CODE (disp) != UNSPEC
      || XVECLEN (disp, 0) != 1)
    return 0;

  /* Must be @GOT or @GOTOFF.  */
  switch (XINT (disp, 1))
    {
    case 6: /* @GOT */
      return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;

    case 7: /* @GOTOFF */
      return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
    }
    
  return 0;
}

And it doesn't stop on a breakpoint at legitimate_pic_operand_p()
while compiling the really simple program so that's not what's
stripping off the (const ... ).

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-12 13:00           ` Jan Hubicka
  2002-12-12 13:46             ` Peter Barada
@ 2002-12-12 13:50             ` Peter Barada
  2002-12-12 13:59               ` Jan Hubicka
  2002-12-12 14:57               ` Richard Henderson
  1 sibling, 2 replies; 17+ messages in thread
From: Peter Barada @ 2002-12-12 13:50 UTC (permalink / raw)
  To: jh; +Cc: Peter.Barada, jh, Peter.Barada, rth, gcc


While looking at the PIC code, I'm wondering if there is a way to
suppress setting up the global_table register if:

1) the funciton is static
2) the function's address is not taken
3) the function is a leaf.

If so then:
	lea (%pc, _GLOBAL_OFFSET_TABLE_@GOTPC), %a5

doesn't need to be done in the function prologue since all callers to
the function have already setup %a5.  As long as the function doesn't
modify %a5, everthing should just work...

-- 
Peter Barada                                   Peter.Barada@motorola.com
Wizard                                         781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-12 13:50             ` Peter Barada
@ 2002-12-12 13:59               ` Jan Hubicka
  2002-12-12 14:57               ` Richard Henderson
  1 sibling, 0 replies; 17+ messages in thread
From: Jan Hubicka @ 2002-12-12 13:59 UTC (permalink / raw)
  To: Peter Barada; +Cc: jh, Peter.Barada, rth, gcc

> 
> While looking at the PIC code, I'm wondering if there is a way to
> suppress setting up the global_table register if:
> 
> 1) the funciton is static
> 2) the function's address is not taken
> 3) the function is a leaf.

You can take a look at the i386.  3) can be easilly handled via
current_function_is_leaf.
> 
> If so then:
> 	lea (%pc, _GLOBAL_OFFSET_TABLE_@GOTPC), %a5
> 
> doesn't need to be done in the function prologue since all callers to
> the function have already setup %a5.  As long as the function doesn't
> modify %a5, everthing should just work...
You can bypass a5 setup by optimizing call to static functions into PC
relative calls, see of SYMBOL_REF_FLAG in i386...
I don't think we handle the scheme with function addresses not taken and
these two tricks are incompatible....

Honza
> 
> -- 
> Peter Barada                                   Peter.Barada@motorola.com
> Wizard                                         781-852-2768 (direct)
> WaveMark Solutions(wholly owned by Motorola)   781-270-0193 (fax)

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

* Re: Saga of m68k PIC continues
  2002-12-12 13:46             ` Peter Barada
@ 2002-12-12 14:32               ` Jim Wilson
  0 siblings, 0 replies; 17+ messages in thread
From: Jim Wilson @ 2002-12-12 14:32 UTC (permalink / raw)
  To: Peter Barada; +Cc: Peter.Barada, gcc

LEGITIMATE_PIC_OPERAND_P is mainly used during reload.  You need to set things
up so that your predicates do not accept a symbol_ref as a valid operand.
You may need to modify the CONSTANT_ADDRESS_P macro that I mentioned a day or
two ago.  You probably need to step through recog and figure out which
predicate is doing the wrong thing, and then figure out which macro to modify
to fix it.

The const isn't being stripped off anywhere.  What is happening is that cse
is seeing the REG_EQUAL note, and deciding that the contents of the REG_EQUAL
note are cheaper than SET_SRC, and thus replacing the SET_SRC with the
REG_EQUAL note.  That is what cse is supposed to do.  To prevent cse from
doing this, you have to make the symbol_ref be an invalid operand, so that
the substitution won't succeed.

Jim

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

* Re: Saga of m68k PIC continues
  2002-12-12 13:50             ` Peter Barada
  2002-12-12 13:59               ` Jan Hubicka
@ 2002-12-12 14:57               ` Richard Henderson
  1 sibling, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2002-12-12 14:57 UTC (permalink / raw)
  To: Peter Barada; +Cc: jh, Peter.Barada, gcc

On Thu, Dec 12, 2002 at 04:39:25PM -0500, Peter Barada wrote:
> While looking at the PIC code, I'm wondering if there is a way to
> suppress setting up the global_table register if:
> 
> 1) the funciton is static
> 2) the function's address is not taken
> 3) the function is a leaf.

Would be very nice, no?  Too bad we don't have (2).

Other ports want this as well...



r~

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

end of thread, other threads:[~2002-12-12 22:34 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-11 12:57 Saga of m68k PIC continues Peter Barada
2002-12-11 14:25 ` Jim Wilson
2002-12-11 16:11 ` Richard Henderson
2002-12-11 16:19   ` Peter Barada
2002-12-12  2:41     ` Richard Henderson
2002-12-12  5:11       ` Andreas Schwab
2002-12-12 11:24         ` Richard Henderson
2002-12-12 11:28           ` Andreas Schwab
2002-12-12 12:27     ` Peter Barada
2002-12-12 12:44       ` Jan Hubicka
2002-12-12 12:44         ` Peter Barada
2002-12-12 13:00           ` Jan Hubicka
2002-12-12 13:46             ` Peter Barada
2002-12-12 14:32               ` Jim Wilson
2002-12-12 13:50             ` Peter Barada
2002-12-12 13:59               ` Jan Hubicka
2002-12-12 14:57               ` Richard Henderson

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).