Browse Source

+ added intrinsic support for the WebAssembly cmpxchg atomic operations as well

Nikolay Nikolov 3 years ago
parent
commit
e03b920520
4 changed files with 100 additions and 2 deletions
  1. 9 1
      compiler/wasm32/ccpuinnr.inc
  2. 75 1
      compiler/wasm32/nwasminl.pas
  3. 8 0
      rtl/wasm32/cpuh.inc
  4. 8 0
      rtl/wasm32/cpuinnr.inc

+ 9 - 1
compiler/wasm32/ccpuinnr.inc

@@ -66,5 +66,13 @@
   in_wasm32_i64_atomic_rmw8_xchg_u  = in_cpu_first+45,
   in_wasm32_i64_atomic_rmw16_xchg_u = in_cpu_first+46,
   in_wasm32_i64_atomic_rmw32_xchg_u = in_cpu_first+47,
-  in_wasm32_i64_atomic_rmw_xchg     = in_cpu_first+48
+  in_wasm32_i64_atomic_rmw_xchg     = in_cpu_first+48,
+
+  in_wasm32_i32_atomic_rmw8_cmpxchg_u  = in_cpu_first+49,
+  in_wasm32_i32_atomic_rmw16_cmpxchg_u = in_cpu_first+50,
+  in_wasm32_i32_atomic_rmw_cmpxchg     = in_cpu_first+51,
+  in_wasm32_i64_atomic_rmw8_cmpxchg_u  = in_cpu_first+52,
+  in_wasm32_i64_atomic_rmw16_cmpxchg_u = in_cpu_first+53,
+  in_wasm32_i64_atomic_rmw32_cmpxchg_u = in_cpu_first+54,
+  in_wasm32_i64_atomic_rmw_cmpxchg     = in_cpu_first+55
 

+ 75 - 1
compiler/wasm32/nwasminl.pas

@@ -53,6 +53,7 @@ interface
         procedure second_throw_fpcexception;
         procedure second_atomic_fence;
         procedure second_atomic_rmw_x_y(op: TAsmOp);
+        procedure second_atomic_rmw_x_y_z(op: TAsmOp);
       protected
         function first_sqr_real: tnode; override;
       public
@@ -432,6 +433,43 @@ implementation
         thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
       end;
 
+    procedure twasminlinenode.second_atomic_rmw_x_y_z(op: TAsmOp);
+      begin
+        secondpass(tcallparanode(tcallparanode(tcallparanode(left).right).right).left);
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,
+          tcallparanode(tcallparanode(tcallparanode(left).right).right).left.location,
+          tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,
+          tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,false);
+        thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
+          tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,
+          tcallparanode(tcallparanode(tcallparanode(left).right).right).left.location.register);
+
+        secondpass(tcallparanode(tcallparanode(left).right).left);
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,
+          tcallparanode(tcallparanode(left).right).left.location,
+          tcallparanode(tcallparanode(left).right).left.resultdef,
+          tcallparanode(tcallparanode(left).right).left.resultdef,false);
+        thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
+          tcallparanode(tcallparanode(left).right).left.resultdef,
+          tcallparanode(tcallparanode(left).right).left.location.register);
+
+        secondpass(tcallparanode(left).left);
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,
+          tcallparanode(left).left.location,
+          tcallparanode(left).left.resultdef,
+          tcallparanode(left).left.resultdef,false);
+        thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
+          tcallparanode(left).left.resultdef,
+          tcallparanode(left).left.location.register);
+
+        current_asmdata.CurrAsmList.Concat(taicpu.op_const(op,0));
+        thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,2);
+
+        location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+        location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
+        thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
+      end;
+
 
     function twasminlinenode.first_sqr_real: tnode;
       begin
@@ -530,6 +568,21 @@ implementation
               CheckParameters(2);
               resultdef:=u64inttype;
             end;
+          in_wasm32_i32_atomic_rmw8_cmpxchg_u,
+          in_wasm32_i32_atomic_rmw16_cmpxchg_u,
+          in_wasm32_i32_atomic_rmw_cmpxchg:
+            begin
+              CheckParameters(3);
+              resultdef:=u32inttype;
+            end;
+          in_wasm32_i64_atomic_rmw8_cmpxchg_u,
+          in_wasm32_i64_atomic_rmw16_cmpxchg_u,
+          in_wasm32_i64_atomic_rmw32_cmpxchg_u,
+          in_wasm32_i64_atomic_rmw_cmpxchg:
+            begin
+              CheckParameters(3);
+              resultdef:=u64inttype;
+            end;
           else
             Result:=inherited pass_typecheck_cpu;
         end;
@@ -590,7 +643,14 @@ implementation
           in_wasm32_i64_atomic_rmw8_xchg_u,
           in_wasm32_i64_atomic_rmw16_xchg_u,
           in_wasm32_i64_atomic_rmw32_xchg_u,
-          in_wasm32_i64_atomic_rmw_xchg:
+          in_wasm32_i64_atomic_rmw_xchg,
+          in_wasm32_i32_atomic_rmw8_cmpxchg_u,
+          in_wasm32_i32_atomic_rmw16_cmpxchg_u,
+          in_wasm32_i32_atomic_rmw_cmpxchg,
+          in_wasm32_i64_atomic_rmw8_cmpxchg_u,
+          in_wasm32_i64_atomic_rmw16_cmpxchg_u,
+          in_wasm32_i64_atomic_rmw32_cmpxchg_u,
+          in_wasm32_i64_atomic_rmw_cmpxchg:
             expectloc:=LOC_REGISTER;
           else
             Result:=inherited first_cpu;
@@ -699,6 +759,20 @@ implementation
             second_atomic_rmw_x_y(a_i64_atomic_rmw32_xchg_u);
           in_wasm32_i64_atomic_rmw_xchg:
             second_atomic_rmw_x_y(a_i64_atomic_rmw_xchg);
+          in_wasm32_i32_atomic_rmw8_cmpxchg_u:
+            second_atomic_rmw_x_y_z(a_i32_atomic_rmw8_cmpxchg_u);
+          in_wasm32_i32_atomic_rmw16_cmpxchg_u:
+            second_atomic_rmw_x_y_z(a_i32_atomic_rmw16_cmpxchg_u);
+          in_wasm32_i32_atomic_rmw_cmpxchg:
+            second_atomic_rmw_x_y_z(a_i32_atomic_rmw_cmpxchg);
+          in_wasm32_i64_atomic_rmw8_cmpxchg_u:
+            second_atomic_rmw_x_y_z(a_i64_atomic_rmw8_cmpxchg_u);
+          in_wasm32_i64_atomic_rmw16_cmpxchg_u:
+            second_atomic_rmw_x_y_z(a_i64_atomic_rmw16_cmpxchg_u);
+          in_wasm32_i64_atomic_rmw32_cmpxchg_u:
+            second_atomic_rmw_x_y_z(a_i64_atomic_rmw32_cmpxchg_u);
+          in_wasm32_i64_atomic_rmw_cmpxchg:
+            second_atomic_rmw_x_y_z(a_i64_atomic_rmw_cmpxchg);
           else
             inherited pass_generate_code_cpu;
         end;

+ 8 - 0
rtl/wasm32/cpuh.inc

@@ -73,3 +73,11 @@ function fpc_wasm32_i64_atomic_rmw16_xchg_u(Dest: PWord; x: Word): qword;[intern
 function fpc_wasm32_i64_atomic_rmw32_xchg_u(Dest: PLongWord; x: LongWord): qword;[internproc:fpc_in_wasm32_i64_atomic_rmw_xchg];
 function fpc_wasm32_i64_atomic_rmw_xchg(Dest: PQWord; x: QWord): QWord;[internproc:fpc_in_wasm32_i64_atomic_rmw_xchg];
 
+function fpc_wasm32_i32_atomic_rmw8_cmpxchg_u(Dest: PByte; Expected, Replacement: LongWord): LongWord;[internproc:fpc_in_wasm32_i32_atomic_rmw8_cmpxchg_u];
+function fpc_wasm32_i32_atomic_rmw16_cmpxchg_u(Dest: PWord; Expected, Replacement: LongWord): LongWord;[internproc:fpc_in_wasm32_i32_atomic_rmw16_cmpxchg_u];
+function fpc_wasm32_i32_atomic_rmw_cmpxchg_u(Dest: PLongWord; Expected, Replacement: LongWord): LongWord;[internproc:fpc_in_wasm32_i32_atomic_rmw_cmpxchg];
+function fpc_wasm32_i64_atomic_rmw8_cmpxchg_u(Dest: PByte; Expected, Replacement: QWord): QWord;[internproc:fpc_in_wasm32_i64_atomic_rmw8_cmpxchg_u];
+function fpc_wasm32_i64_atomic_rmw16_cmpxchg_u(Dest: PWord; Expected, Replacement: QWord): QWord;[internproc:fpc_in_wasm32_i64_atomic_rmw16_cmpxchg_u];
+function fpc_wasm32_i64_atomic_rmw32_cmpxchg_u(Dest: PWord; Expected, Replacement: QWord): QWord;[internproc:fpc_in_wasm32_i64_atomic_rmw32_cmpxchg_u];
+function fpc_wasm32_i64_atomic_rmw_cmpxchg_u(Dest: PLongWord; Expected, Replacement: QWord): QWord;[internproc:fpc_in_wasm32_i64_atomic_rmw_cmpxchg];
+

+ 8 - 0
rtl/wasm32/cpuinnr.inc

@@ -68,3 +68,11 @@
   fpc_in_wasm32_i64_atomic_rmw32_xchg_u = fpc_in_cpu_first+47;
   fpc_in_wasm32_i64_atomic_rmw_xchg     = fpc_in_cpu_first+48;
 
+  fpc_in_wasm32_i32_atomic_rmw8_cmpxchg_u  = fpc_in_cpu_first+49;
+  fpc_in_wasm32_i32_atomic_rmw16_cmpxchg_u = fpc_in_cpu_first+50;
+  fpc_in_wasm32_i32_atomic_rmw_cmpxchg     = fpc_in_cpu_first+51;
+  fpc_in_wasm32_i64_atomic_rmw8_cmpxchg_u  = fpc_in_cpu_first+52;
+  fpc_in_wasm32_i64_atomic_rmw16_cmpxchg_u = fpc_in_cpu_first+53;
+  fpc_in_wasm32_i64_atomic_rmw32_cmpxchg_u = fpc_in_cpu_first+54;
+  fpc_in_wasm32_i64_atomic_rmw_cmpxchg     = fpc_in_cpu_first+55;
+