OSDN Git Service

* config/xtensa/xtensa-protos.h (xtensa_return_addr): Declare.
authorbwilson <bwilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Jun 2002 04:33:41 +0000 (04:33 +0000)
committerbwilson <bwilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Jun 2002 04:33:41 +0000 (04:33 +0000)
        config/xtensa/xtensa.c (xtensa_return_addr): New function.
        config/xtensa/xtensa.h (RETURN_ADDR_RTX): Use xtensa_return_addr.
        config/xtensa/xtensa.md (fix_return_addr): New pattern.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55020 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/xtensa/xtensa-protos.h
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h
gcc/config/xtensa/xtensa.md

index 9d1a0a0..973df1e 100644 (file)
@@ -1,3 +1,10 @@
+2002-06-26  Bob Wilson  <bob.wilson@acm.org>
+
+       * config/xtensa/xtensa-protos.h (xtensa_return_addr): Declare.
+       config/xtensa/xtensa.c (xtensa_return_addr): New function.
+       config/xtensa/xtensa.h (RETURN_ADDR_RTX): Use xtensa_return_addr.
+       config/xtensa/xtensa.md (fix_return_addr): New pattern.
+
 2002-06-26  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * mips.c (coprocessor_operand, coprocessor2_operand,
index 76cf73c..bb640bb 100644 (file)
@@ -86,6 +86,7 @@ extern void print_operand_address PARAMS ((FILE *, rtx));
 extern void xtensa_output_literal
   PARAMS ((FILE *, rtx, enum machine_mode, int labelno));
 extern void xtensa_reorg PARAMS ((rtx));
+extern rtx xtensa_return_addr PARAMS ((int, rtx));
 extern rtx xtensa_builtin_saveregs PARAMS ((void));
 extern enum reg_class xtensa_preferred_reload_class
   PARAMS ((rtx, enum reg_class));
index dd9ad7d..bf669da 100644 (file)
@@ -2281,6 +2281,33 @@ xtensa_function_epilogue (file, size)
 }
 
 
+rtx
+xtensa_return_addr (count, frame)
+     int count;
+     rtx frame;
+{
+  rtx result, retaddr;
+
+  if (count == -1)
+    retaddr = gen_rtx_REG (Pmode, 0);
+  else
+    {
+      rtx addr = plus_constant (frame, -4 * UNITS_PER_WORD);
+      addr = memory_address (Pmode, addr);
+      retaddr = gen_reg_rtx (Pmode);
+      emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
+    }
+
+  /* The 2 most-significant bits of the return address on Xtensa hold
+     the register window size.  To get the real return address, these
+     bits must be replaced with the high bits from the current PC.  */
+
+  result = gen_reg_rtx (Pmode);
+  emit_insn (gen_fix_return_addr (result, retaddr));
+  return result;
+}
+
+
 /* Create the va_list data type.
    This structure is set up by __builtin_saveregs.  The __va_reg
    field points to a stack-allocated region holding the contents of the
index e98c2c6..22fcb79 100644 (file)
@@ -1060,8 +1060,7 @@ typedef struct xtensa_args {
    we currently need to ensure that there is a frame pointer when these
    builtin functions are used. */
 
-#define SETUP_FRAME_ADDRESSES() \
-  xtensa_setup_frame_addresses ()
+#define SETUP_FRAME_ADDRESSES  xtensa_setup_frame_addresses
 
 /* A C expression whose value is RTL representing the address in a
    stack frame where the pointer to the caller's frame is stored.
@@ -1085,22 +1084,8 @@ typedef struct xtensa_args {
 
 /* A C expression whose value is RTL representing the value of the
    return address for the frame COUNT steps up from the current
-   frame, after the prologue.  FRAMEADDR is the frame pointer of the
-   COUNT frame, or the frame pointer of the COUNT - 1 frame if
-   'RETURN_ADDR_IN_PREVIOUS_FRAME' is defined.
-
-   The 2 most-significant bits of the return address on Xtensa hold
-   the register window size.  To get the real return address, these bits
-   must be masked off and replaced with the high bits from the current
-   PC.  Since it is unclear how the __builtin_return_address function
-   is used, the current code does not do this masking and simply returns
-   the raw return address from the a0 register. */
-#define RETURN_ADDR_RTX(count, frame)                                  \
-  ((count) == -1                                                       \
-   ? gen_rtx_REG (Pmode, 0)                                            \
-   : gen_rtx_MEM (Pmode, memory_address                                        \
-                 (Pmode, plus_constant (frame, -4 * UNITS_PER_WORD))))
-
+   frame, after the prologue.  */
+#define RETURN_ADDR_RTX  xtensa_return_addr
 
 /* Addressing modes, and classification of registers for them.  */
 
index 771edd5..cf07ffc 100644 (file)
@@ -34,6 +34,7 @@
   (UNSPEC_NSAU         1)
   (UNSPEC_NOP          2)
   (UNSPEC_PLT          3)
+  (UNSPEC_RET_ADDR     4)
   (UNSPECV_SET_FP      1)
 ])
 
    (set_attr "mode"    "SI")
    (set_attr "length"  "6,6")])
 
+
 ;;
 ;;  ....................
 ;;
    (set_attr "mode"    "none")
    (set_attr "length"  "0")])
 
+;; The fix_return_addr pattern sets the high 2 bits of an address in a
+;; register to match the high bits of the current PC.
+
+(define_insn "fix_return_addr"
+  [(set (match_operand:SI 0 "register_operand" "=a")
+       (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
+                  UNSPEC_RET_ADDR))
+   (clobber (match_scratch:SI 2 "=r"))
+   (clobber (match_scratch:SI 3 "=r"))]
+  ""
+  "mov\\t%2, a0\;call0\\t0f\;.align\\t4\;0:\;mov\\t%3, a0\;mov\\ta0, %2\;\
+srli\\t%3, %3, 30\;slli\\t%0, %1, 2\;ssai\\t2\;src\\t%0, %3, %0"
+  [(set_attr "type"    "multi")
+   (set_attr "mode"    "SI")
+   (set_attr "length"  "24")])
+
+
 ;;
 ;;  ....................
 ;;