]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: gcc: fix builtin_apply return value
authorMax Filippov <jcmvbkbc@gmail.com>
Sun, 11 Sep 2022 00:31:07 +0000 (17:31 -0700)
committerMax Filippov <jcmvbkbc@gmail.com>
Mon, 12 Sep 2022 12:01:05 +0000 (05:01 -0700)
xtensa may use up to 4 registers to return a value from a function, but
recognition of only one register in the xtensa_function_value_regno_p
and missing untyped_call pattern result in that only one register is
saved by the __builtin_apply and returned by the __builtin_apply_return.

gcc/
* config/xtensa/xtensa.cc (xtensa_function_value_regno_p):
Recognize all 4 return registers.
* config/xtensa/xtensa.h (GP_RETURN_REG_COUNT): New definition.
* config/xtensa/xtensa.md (untyped_call): New pattern.

gcc/config/xtensa/xtensa.cc
gcc/config/xtensa/xtensa.h
gcc/config/xtensa/xtensa.md

index ac52c015a94c2b07a0715d665381c5264daf6545..f1b3331ea558cb6bfa785608ee69a64f608ccef1 100644 (file)
@@ -4472,7 +4472,7 @@ xtensa_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
 static bool
 xtensa_function_value_regno_p (const unsigned int regno)
 {
-  return (regno == GP_RETURN);
+  return (regno >= GP_RETURN && regno < GP_RETURN + GP_RETURN_REG_COUNT);
 }
 
 /* The static chain is passed in memory.  Provide rtx giving 'mem'
index 0f3006d7af8fdb30b90c45ce6a9a61097c70f27c..16e3d55e89632ae6bb47f32354a1e10ea595a766 100644 (file)
@@ -488,6 +488,7 @@ enum reg_class
    point, and values of coprocessor and user-defined modes.  */
 #define GP_RETURN (GP_REG_FIRST + 2 + WINDOW_SIZE)
 #define GP_OUTGOING_RETURN (GP_REG_FIRST + 2)
+#define GP_RETURN_REG_COUNT 4
 
 /* Symbolic macros for the first/last argument registers.  */
 #define GP_ARG_FIRST (GP_REG_FIRST + 2)
index f722ea562891d9ecfe9919f438a3fa315c9555d0..608110c20bcb9c133090285f8ab6efcecd770e86 100644 (file)
    (set_attr "mode"    "none")
    (set_attr "length"  "3")])
 
+(define_expand "untyped_call"
+  [(parallel [(call (match_operand 0 "")
+                   (const_int 0))
+             (match_operand 1 "")
+             (match_operand 2 "")])]
+  ""
+{
+  int i;
+
+  emit_call_insn (gen_call (operands[0], const0_rtx));
+
+  for (i = 0; i < XVECLEN (operands[2], 0); i++)
+    {
+      rtx set = XVECEXP (operands[2], 0, i);
+      emit_move_insn (SET_DEST (set), SET_SRC (set));
+    }
+
+  emit_insn (gen_blockage ());
+  DONE;
+})
+
 (define_insn "entry"
   [(set (reg:SI A1_REG)
        (unspec_volatile:SI [(match_operand:SI 0 "const_int_operand" "i")]