Browse Source

+ added WASI multithreading helper for setting the stack pointer for the linear stack

Nikolay Nikolov 2 years ago
parent
commit
cdba427bcf

+ 3 - 1
compiler/wasm32/ccpuinnr.inc

@@ -97,5 +97,7 @@
 
 
   in_wasm32_tls_size  = in_cpu_first+73,
   in_wasm32_tls_size  = in_cpu_first+73,
   in_wasm32_tls_align = in_cpu_first+74,
   in_wasm32_tls_align = in_cpu_first+74,
-  in_wasm32_tls_base  = in_cpu_first+75
+  in_wasm32_tls_base  = in_cpu_first+75,
+
+  in_wasm32_set_base_pointer = in_cpu_first+76
 
 

+ 2 - 1
compiler/wasm32/hlcgcpu.pas

@@ -2052,7 +2052,8 @@ implementation
       g_procdef(list,pd);
       g_procdef(list,pd);
 
 
       ttgwasm(tg).allocframepointer(list,pd.frame_pointer_ref);
       ttgwasm(tg).allocframepointer(list,pd.frame_pointer_ref);
-      ttgwasm(tg).allocbasepointer(list,pd.base_pointer_ref);
+      if pd.base_pointer_ref.base<>NR_LOCAL_STACK_POINTER_REG then
+        ttgwasm(tg).allocbasepointer(list,pd.base_pointer_ref);
 
 
       g_fingerprint(list);
       g_fingerprint(list);
 
 

+ 30 - 1
compiler/wasm32/nwasminl.pas

@@ -59,6 +59,7 @@ interface
         procedure second_atomic_rmw_x_y(op: TAsmOp);
         procedure second_atomic_rmw_x_y(op: TAsmOp);
         procedure second_atomic_rmw_x_y_z(op: TAsmOp);
         procedure second_atomic_rmw_x_y_z(op: TAsmOp);
         procedure second_tls_get(const SymStr: string);
         procedure second_tls_get(const SymStr: string);
+        procedure second_set_base_pointer;
       protected
       protected
         function first_sqr_real: tnode; override;
         function first_sqr_real: tnode; override;
       public
       public
@@ -72,12 +73,14 @@ interface
 implementation
 implementation
 
 
     uses
     uses
+      procinfo,
       ninl,ncal,compinnr,
       ninl,ncal,compinnr,
       aasmbase,aasmdata,aasmcpu,
       aasmbase,aasmdata,aasmcpu,
       cgbase,cgutils,
       cgbase,cgutils,
       hlcgobj,hlcgcpu,
       hlcgobj,hlcgcpu,
       defutil,pass_2,verbose,
       defutil,pass_2,verbose,
-      symtype,symdef;
+      symtype,symdef,symcpu,
+      tgobj,tgcpu;
 
 
 {*****************************************************************************
 {*****************************************************************************
                                twasminlinenode
                                twasminlinenode
@@ -557,6 +560,24 @@ implementation
       end;
       end;
 
 
 
 
+    procedure twasminlinenode.second_set_base_pointer;
+      var
+        pd: tcpuprocdef;
+      begin
+        location_reset(location,LOC_VOID,OS_NO);
+        secondpass(left);
+
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
+        thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,left.resultdef,left.location.register);
+
+        pd:=tcpuprocdef(current_procinfo.procdef);
+        if pd.base_pointer_ref.base<>NR_LOCAL_STACK_POINTER_REG then
+          ttgwasm(tg).allocbasepointer(current_asmdata.CurrAsmList,pd.base_pointer_ref);
+        current_asmdata.CurrAsmList.Concat(taicpu.op_ref(a_local_set,pd.base_pointer_ref));
+        thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
+      end;
+
+
     function twasminlinenode.first_sqr_real: tnode;
     function twasminlinenode.first_sqr_real: tnode;
       begin
       begin
         expectloc:=LOC_FPUREGISTER;
         expectloc:=LOC_FPUREGISTER;
@@ -568,6 +589,11 @@ implementation
       begin
       begin
         Result:=nil;
         Result:=nil;
         case inlinenumber of
         case inlinenumber of
+          in_wasm32_set_base_pointer:
+            begin
+              CheckParameters(1);
+              resultdef:=voidtype;
+            end;
           in_wasm32_memory_size:
           in_wasm32_memory_size:
             begin
             begin
               CheckParameters(0);
               CheckParameters(0);
@@ -730,6 +756,7 @@ implementation
           in_wasm32_memory_size,
           in_wasm32_memory_size,
           in_wasm32_memory_grow:
           in_wasm32_memory_grow:
             expectloc:=LOC_REGISTER;
             expectloc:=LOC_REGISTER;
+          in_wasm32_set_base_pointer,
           in_wasm32_memory_fill,
           in_wasm32_memory_fill,
           in_wasm32_memory_copy,
           in_wasm32_memory_copy,
           in_wasm32_unreachable,
           in_wasm32_unreachable,
@@ -967,6 +994,8 @@ implementation
             second_tls_get(TLS_ALIGN_SYM);
             second_tls_get(TLS_ALIGN_SYM);
           in_wasm32_tls_base:
           in_wasm32_tls_base:
             second_tls_get(TLS_BASE_SYM);
             second_tls_get(TLS_BASE_SYM);
+          in_wasm32_set_base_pointer:
+            second_set_base_pointer;
           else
           else
             inherited pass_generate_code_cpu;
             inherited pass_generate_code_cpu;
         end;
         end;

+ 6 - 1
rtl/wasi/systhrd.inc

@@ -267,6 +267,11 @@ end;
   ----------------------------------------------------------------------}
   ----------------------------------------------------------------------}
 
 
 
 
+procedure FPCWasmThreadSetStackPointer(Address: Pointer); [public, alias: 'FPC_WASM_THREAD_SET_STACK_POINTER'];
+begin
+  fpc_wasm32_set_base_pointer(Address);
+end;
+
 // Javascript definition: TThreadInitInstanceFunction = Function(IsWorkerThread : Longint; IsMainThread : Integer; CanBlock : Integer) : Integer;
 // Javascript definition: TThreadInitInstanceFunction = Function(IsWorkerThread : Longint; IsMainThread : Integer; CanBlock : Integer) : Integer;
 
 
 Function FPCWasmThreadInit(IsWorkerThread : Longint; IsMainThread : Longint; CanBlock : Longint) : Longint; [public, alias: 'FPC_WASM_THREAD_INIT'];
 Function FPCWasmThreadInit(IsWorkerThread : Longint; IsMainThread : Longint; CanBlock : Longint) : Longint; [public, alias: 'FPC_WASM_THREAD_INIT'];
@@ -295,7 +300,7 @@ begin
   Result:=tthreadfunc(RunFunction)(args);
   Result:=tthreadfunc(RunFunction)(args);
 end;
 end;
 
 
-exports FPCWasmThreadInit, FPCWasmThreadEntry;
+exports FPCWasmThreadSetStackPointer, FPCWasmThreadInit, FPCWasmThreadEntry;
 
 
 Function thread_spawn(thread_id : PInteger; attrs: Pointer; thread_start_func : Pointer; args : Pointer) : LongInt;  external 'FPCThreading' name 'thread_spawn';
 Function thread_spawn(thread_id : PInteger; attrs: Pointer; thread_start_func : Pointer; args : Pointer) : LongInt;  external 'FPCThreading' name 'thread_spawn';
 
 

+ 1 - 0
rtl/wasm32/cpuh.inc

@@ -107,3 +107,4 @@ function fpc_wasm32_tls_size: SizeUInt;[internproc:fpc_in_wasm32_tls_size];
 function fpc_wasm32_tls_align: SizeUInt;[internproc:fpc_in_wasm32_tls_align];
 function fpc_wasm32_tls_align: SizeUInt;[internproc:fpc_in_wasm32_tls_align];
 function fpc_wasm32_tls_base: Pointer;[internproc:fpc_in_wasm32_tls_base];
 function fpc_wasm32_tls_base: Pointer;[internproc:fpc_in_wasm32_tls_base];
 
 
+procedure fpc_wasm32_set_base_pointer(Address: Pointer);[internproc:fpc_in_wasm32_set_base_pointer];

+ 1 - 0
rtl/wasm32/cpuinnr.inc

@@ -99,3 +99,4 @@
   fpc_in_wasm32_tls_align = fpc_in_cpu_first+74;
   fpc_in_wasm32_tls_align = fpc_in_cpu_first+74;
   fpc_in_wasm32_tls_base  = fpc_in_cpu_first+75;
   fpc_in_wasm32_tls_base  = fpc_in_cpu_first+75;
 
 
+  fpc_in_wasm32_set_base_pointer = fpc_in_cpu_first+76;