Browse Source

+ added support for params and results in tai_wasmstruc_if.ConvertToBrIf

Nikolay Nikolov 1 year ago
parent
commit
d911e462b2
1 changed files with 79 additions and 4 deletions
  1. 79 4
      compiler/wasm32/aasmcpu.pas

+ 79 - 4
compiler/wasm32/aasmcpu.pas

@@ -43,6 +43,7 @@ uses
     type
       twasmstruc_stack = class;
       TAsmMapFunc = function(ai: tai; blockstack: twasmstruc_stack): tai of object;
+      TWasmLocalAllocator = function(wbt: TWasmBasicType): Integer of object;
 
       { taicpu }
 
@@ -100,7 +101,7 @@ uses
         function getcopy:TLinkedListItem;override;
         procedure Map(f: TAsmMapFunc; blockstack: twasmstruc_stack);override;
         procedure ConvertToFlatList(l: TAsmList);override;
-        procedure ConvertToBrIf(list: TAsmList);
+        procedure ConvertToBrIf(list: TAsmList; local_alloc: TWasmLocalAllocator);
       end;
 
       { tai_wasmstruc_block }
@@ -427,10 +428,78 @@ uses
           l.concat(tai_label.create(FLabel));
       end;
 
-    procedure tai_wasmstruc_if.ConvertToBrIf(list: TAsmList);
+    procedure tai_wasmstruc_if.ConvertToBrIf(list: TAsmList; local_alloc: TWasmLocalAllocator);
       var
-        then_label: TAsmLabel;
         res_ft: TWasmFuncType;
+        save_if_reg: Integer;
+        save_param_reg: array of Integer;
+        save_result_reg: array of Integer;
+
+        procedure AllocateLocalsForSavingParamsAndResult;
+          var
+            i: Integer;
+          begin
+            if not assigned(res_ft) then
+              exit;
+            if length(res_ft.params)<>0 then
+              begin
+                save_if_reg:=local_alloc(wbt_i32);
+                SetLength(save_param_reg,length(res_ft.params));
+                for i:=low(res_ft.params) to high(res_ft.params) do
+                  save_param_reg[i]:=local_alloc(res_ft.params[i]);
+              end;
+            if length(res_ft.results)<>0 then
+              begin
+                SetLength(save_result_reg,length(res_ft.results));
+                for i:=low(res_ft.results) to high(res_ft.results) do
+                  save_result_reg[i]:=local_alloc(res_ft.results[i]);
+              end;
+          end;
+
+        procedure SaveParams;
+          var
+            i: Integer;
+          begin
+            if (not assigned(res_ft)) or (length(res_ft.params)=0) then
+              exit;
+            list.concat(taicpu.op_const(a_local_set,save_if_reg));
+            for i:=high(res_ft.params) downto low(res_ft.params) do
+              list.concat(taicpu.op_const(a_local_set,save_param_reg[i]));
+            list.concat(taicpu.op_const(a_local_get,save_if_reg));
+          end;
+
+        procedure RestoreParams;
+          var
+            i: Integer;
+          begin
+            if (not assigned(res_ft)) or (length(res_ft.params)=0) then
+              exit;
+            for i:=low(res_ft.params) to high(res_ft.params) do
+              list.concat(taicpu.op_const(a_local_get,save_param_reg[i]));
+          end;
+
+        procedure SaveResults;
+          var
+            i: Integer;
+          begin
+            if (not assigned(res_ft)) or (length(res_ft.results)=0) then
+              exit;
+            for i:=high(res_ft.results) downto low(res_ft.results) do
+              list.concat(taicpu.op_const(a_local_set,save_result_reg[i]));
+          end;
+
+        procedure RestoreResults;
+          var
+            i: Integer;
+          begin
+            if (not assigned(res_ft)) or (length(res_ft.results)=0) then
+              exit;
+            for i:=low(res_ft.results) to high(res_ft.results) do
+              list.concat(taicpu.op_const(a_local_get,save_result_reg[i]));
+          end;
+
+      var
+        then_label: TAsmLabel;
       begin
         if if_instr.ops>1 then
           internalerror(2023101701);
@@ -438,16 +507,22 @@ uses
           res_ft:=if_instr.oper[0]^.functype
         else
           res_ft:=nil;
-        // TODO: handle res_ft
+        AllocateLocalsForSavingParamsAndResult;
 
         current_asmdata.getjumplabel(then_label);
+        SaveParams;
         list.concat(taicpu.op_sym(a_br_if,then_label));
+        RestoreParams;
         if assigned(else_asmlist) then
           list.concatList(else_asmlist);
+        SaveResults;
         list.concat(taicpu.op_sym(a_br, FLabel));
         list.concat(tai_label.create(then_label));
+        RestoreParams;
         list.concatList(then_asmlist);
+        SaveResults;
         list.concat(tai_label.create(FLabel));
+        RestoreResults;
       end;
 
     { tai_wasmstruc_block }