]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gcn: Add __builtin_gcn_{get_stack_limit,first_call_this_thread_p}
authorTobias Burnus <tobias@codesourcery.com>
Wed, 23 Nov 2022 10:42:42 +0000 (11:42 +0100)
committerTobias Burnus <tobias@codesourcery.com>
Wed, 23 Nov 2022 10:42:42 +0000 (11:42 +0100)
The new builtins have been added for newlib to reduce dependency on
compiler-internal implementation choices of GCC in newlibs' getreent.c.

gcc/ChangeLog:

* config/gcn/gcn-builtins.def (FIRST_CALL_THIS_THREAD_P,
GET_STACK_LIMIT): Add new builtins.
* config/gcn/gcn.cc (gcn_expand_builtin_1): Expand them.
* config/gcn/gcn.md (prologue_use): Add "register_operand" as
arg to match_operand.
(prologue_use_di): New; DI insn_and_split variant of the former.

Co-Authored-By: Andrew Stubbs <ams@codesourcery.com>
(cherry picked from commit d6bbca7b78745915d98bb1324d79de6a1e6dc801)

gcc/ChangeLog.omp
gcc/config/gcn/gcn-builtins.def
gcc/config/gcn/gcn.cc
gcc/config/gcn/gcn.md

index fd420ef3431918176ff0f06065fd6dce3c44b3b6..959768f9df8d33ca9f0005d792e7ad9e52ff63a7 100644 (file)
@@ -1,3 +1,16 @@
+2022-11-23  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2022-11-22  Tobias Burnus  <tobias@codesourcery.com>
+                   Andrew Stubbs  <ams@codesourcery.com>
+
+       * config/gcn/gcn-builtins.def (FIRST_CALL_THIS_THREAD_P,
+       GET_STACK_LIMIT): Add new builtins.
+       * config/gcn/gcn.cc (gcn_expand_builtin_1): Expand them.
+       * config/gcn/gcn.md (prologue_use): Add "register_operand" as
+       arg to match_operand.
+       (prologue_use_di): New; DI insn_and_split variant of the former.
+
 2022-11-18  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index eeeaebf9013256afaf8c17b56efc6eaab0edbf61..f1cf30bbc94dc6d40ad009bf7ba12764a1e3d72e 100644 (file)
@@ -160,8 +160,12 @@ DEF_BUILTIN (ACC_BARRIER, -1, "acc_barrier", B_INSN, _A1 (GCN_BTI_VOID),
 
 /* Kernel inputs.  */
 
+DEF_BUILTIN (FIRST_CALL_THIS_THREAD_P, -1, "first_call_this_thread_p", B_INSN,
+            _A1 (GCN_BTI_BOOL), gcn_expand_builtin_1)
 DEF_BUILTIN (KERNARG_PTR, -1, "kernarg_ptr", B_INSN, _A1 (GCN_BTI_VOIDPTR),
             gcn_expand_builtin_1)
+DEF_BUILTIN (GET_STACK_LIMIT, -1, "get_stack_limit", B_INSN,
+            _A1 (GCN_BTI_VOIDPTR), gcn_expand_builtin_1)
 
 #undef _A1
 #undef _A2
index 0d076aaa1a503f88019f35b0f98f92f1fc78be5a..48a80ba103c1cfcf9f8014472d304a5fa5ffc3f0 100644 (file)
@@ -4526,6 +4526,45 @@ gcn_expand_builtin_1 (tree exp, rtx target, rtx /*subtarget */ ,
       emit_insn (gen_gcn_wavefront_barrier ());
       return target;
 
+    case GCN_BUILTIN_GET_STACK_LIMIT:
+      {
+       /* stackbase = (stack_segment_decr & 0x0000ffffffffffff)
+                       + stack_wave_offset);
+          seg_size = dispatch_ptr->private_segment_size;
+          stacklimit = stackbase + seg_size*64;
+          with segsize = *(uint32_t *) ((char *) dispatch_ptr
+                                      + 6*sizeof(int16_t) + 3*sizeof(int32_t));
+          cf. struct hsa_kernel_dispatch_packet_s in the HSA doc.  */
+       rtx ptr;
+       if (cfun->machine->args.reg[DISPATCH_PTR_ARG] >= 0
+           && cfun->machine->args.reg[PRIVATE_SEGMENT_BUFFER_ARG] >= 0)
+         {
+           rtx size_rtx = gen_rtx_REG (DImode,
+                            cfun->machine->args.reg[DISPATCH_PTR_ARG]);
+           size_rtx = gen_rtx_MEM (SImode,
+                                   gen_rtx_PLUS (DImode, size_rtx,
+                                                 GEN_INT (6*2 + 3*4)));
+           size_rtx = gen_rtx_MULT (SImode, size_rtx, GEN_INT (64));
+
+           ptr = gen_rtx_REG (DImode,
+                   cfun->machine->args.reg[PRIVATE_SEGMENT_BUFFER_ARG]);
+           ptr = gen_rtx_AND (DImode, ptr, GEN_INT (0x0000ffffffffffff));
+           ptr = gen_rtx_PLUS (DImode, ptr, size_rtx);
+           if (cfun->machine->args.reg[PRIVATE_SEGMENT_WAVE_OFFSET_ARG] >= 0)
+             {
+               rtx off;
+               off = gen_rtx_REG (SImode,
+                     cfun->machine->args.reg[PRIVATE_SEGMENT_WAVE_OFFSET_ARG]);
+               ptr = gen_rtx_PLUS (DImode, ptr, off);
+             }
+         }
+       else
+         {
+           ptr = gen_reg_rtx (DImode);
+           emit_move_insn (ptr, const0_rtx);
+         }
+       return ptr;
+      }
     case GCN_BUILTIN_KERNARG_PTR:
       {
        rtx ptr;
@@ -4539,7 +4578,36 @@ gcn_expand_builtin_1 (tree exp, rtx target, rtx /*subtarget */ ,
          }
        return ptr;
       }
-
+    case GCN_BUILTIN_FIRST_CALL_THIS_THREAD_P:
+      {
+       /* Stash a marker in the unused upper 16 bits of s[0:1] to indicate
+          whether it was the first call.  */
+       rtx result = gen_reg_rtx (BImode);
+       emit_move_insn (result, const0_rtx);
+       if (cfun->machine->args.reg[PRIVATE_SEGMENT_BUFFER_ARG] >= 0)
+         {
+           rtx not_first = gen_label_rtx ();
+           rtx reg = gen_rtx_REG (DImode,
+                       cfun->machine->args.reg[PRIVATE_SEGMENT_BUFFER_ARG]);
+           rtx cmp = force_reg (DImode,
+                                gen_rtx_LSHIFTRT (DImode, reg, GEN_INT (48)));
+           emit_insn (gen_cstoresi4 (result, gen_rtx_NE (BImode, cmp,
+                                                         GEN_INT(12345)),
+                                     cmp, GEN_INT(12345)));
+           emit_jump_insn (gen_cjump (not_first, gen_rtx_EQ (BImode, result,
+                                                             const0_rtx),
+                                      result));
+           emit_move_insn (reg,
+             force_reg (DImode,
+               gen_rtx_IOR (DImode,
+                            gen_rtx_AND (DImode, reg,
+                                         GEN_INT (0x0000ffffffffffffL)),
+                            GEN_INT (12345L << 48))));
+           emit_insn (gen_prologue_use (reg));
+           emit_label (not_first);
+         }
+       return result;
+      }
     default:
       gcc_unreachable ();
     }
index da617cb19ad0e9e1088e44357748a2317f47006f..f31c20471daff2fc241d7d62f6fb0947b9c172ce 100644 (file)
 ;; {{{ Prologue/Epilogue
 
 (define_insn "prologue_use"
-  [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
+  [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_PROLOGUE_USE)]
   ""
   ""
   [(set_attr "length" "0")])
 
+(define_insn_and_split "prologue_use_di"
+  [(unspec_volatile [(match_operand:DI 0 "register_operand")] UNSPECV_PROLOGUE_USE)]
+  ""
+  "#"
+  "reload_completed"
+  [(unspec_volatile [(match_dup 0)] UNSPECV_PROLOGUE_USE)
+   (unspec_volatile [(match_dup 1)] UNSPECV_PROLOGUE_USE)]
+  {
+    operands[1] = gcn_operand_part (DImode, operands[0], 1);
+    operands[0] = gcn_operand_part (DImode, operands[0], 0);
+  }
+  [(set_attr "length" "0")])
+
 (define_expand "prologue"
   [(const_int 0)]
   ""