Browse Source

+ generate the .functype directive for the llvm-mc wasm assembler

git-svn-id: branches/wasm@46711 -
nickysn 5 years ago
parent
commit
76f1b8cf60
4 changed files with 117 additions and 2 deletions
  1. 3 1
      compiler/aasmtai.pas
  2. 34 0
      compiler/aggas.pas
  3. 34 0
      compiler/wasm32/aasmcpu.pas
  4. 46 1
      compiler/wasm32/hlcgcpu.pas

+ 3 - 1
compiler/aasmtai.pas

@@ -94,6 +94,7 @@ interface
 {$ifdef wasm}
 {$ifdef wasm}
           ait_importexport,
           ait_importexport,
           ait_local,
           ait_local,
+          ait_functype,
 {$endif}
 {$endif}
           { SEH directives used in ARM,MIPS and x86_64 COFF targets }
           { SEH directives used in ARM,MIPS and x86_64 COFF targets }
           ait_seh_directive,
           ait_seh_directive,
@@ -240,6 +241,7 @@ interface
 {$ifdef wasm}
 {$ifdef wasm}
           'importexport',
           'importexport',
           'local',
           'local',
+          'functype',
 {$endif}
 {$endif}
           'cfi',
           'cfi',
           'seh_directive',
           'seh_directive',
@@ -351,7 +353,7 @@ interface
                      ait_llvmmetadatarefoperand,
                      ait_llvmmetadatarefoperand,
 {$endif llvm}
 {$endif llvm}
 {$ifdef wasm}
 {$ifdef wasm}
-                     ait_importexport, ait_local,
+                     ait_importexport,ait_local,ait_functype,
 {$endif wasm}
 {$endif wasm}
                      ait_seh_directive,
                      ait_seh_directive,
                      ait_cfi,
                      ait_cfi,

+ 34 - 0
compiler/aggas.pas

@@ -801,6 +801,38 @@ implementation
             end;
             end;
         end;
         end;
 
 
+{$ifdef WASM}
+      procedure WriteFuncType(hp:tai_functype);
+        var
+          wasm_basic_typ: TWasmBasicType;
+          first: boolean;
+        begin
+          writer.AsmWrite(#9'.functype'#9);
+          writer.AsmWrite(tai_functype(hp).funcname);
+          writer.AsmWrite(' (');
+          first:=true;
+          for wasm_basic_typ in tai_functype(hp).params do
+            begin
+              if first then
+                first:=false
+              else
+                writer.AsmWrite(',');
+              writer.AsmWrite(gas_wasm_basic_type_str[wasm_basic_typ]);
+            end;
+          writer.AsmWrite(') -> (');
+          first:=true;
+          for wasm_basic_typ in tai_functype(hp).results do
+            begin
+              if first then
+                first:=false
+              else
+                writer.AsmWrite(',');
+              writer.AsmWrite(gas_wasm_basic_type_str[wasm_basic_typ]);
+            end;
+          writer.AsmWriteLn(')');
+        end;
+{$endif WASM}
+
     var
     var
       ch       : char;
       ch       : char;
       lasthp,
       lasthp,
@@ -1564,6 +1596,8 @@ implementation
                  end;
                  end;
                writer.AsmLn;
                writer.AsmLn;
              end;
              end;
+           ait_functype:
+             WriteFuncType(tai_functype(hp));
            ait_importexport:
            ait_importexport:
              begin
              begin
                writer.AsmWriteLn(asminfo^.comment+'TODO: ait_importexport');
                writer.AsmWriteLn(asminfo^.comment+'TODO: ait_importexport');

+ 34 - 0
compiler/wasm32/aasmcpu.pas

@@ -108,6 +108,17 @@ uses
         constructor create(abasictype: TWasmBasicType; const aname: string = '');
         constructor create(abasictype: TWasmBasicType; const aname: string = '');
       end;
       end;
 
 
+      { tai_functype }
+
+      tai_functype = class(tai)
+        funcname: string;
+        params: array of TWasmBasicType;
+        results: array of TWasmBasicType;
+        constructor create(const afuncname: string = '');
+        procedure add_param(param: TWasmBasicType);
+        procedure add_result(res: TWasmBasicType);
+      end;
+
     procedure InitAsm;
     procedure InitAsm;
     procedure DoneAsm;
     procedure DoneAsm;
 
 
@@ -116,6 +127,29 @@ uses
 
 
 implementation
 implementation
 
 
+    { tai_functype }
+
+    constructor tai_functype.create(const afuncname: string = '');
+      begin
+        inherited Create;
+        typ:=ait_functype;
+        funcname:=afuncname;
+      end;
+
+
+    procedure tai_functype.add_param(param: TWasmBasicType);
+      begin
+        SetLength(params,Length(params)+1);
+        params[High(params)]:=param;
+      end;
+
+
+    procedure tai_functype.add_result(res: TWasmBasicType);
+      begin
+       SetLength(results,Length(results)+1);
+       results[High(results)]:=res;
+      end;
+
     { tai_local }
     { tai_local }
 
 
     constructor tai_local.create(abasictype: TWasmBasicType; const aname: string);
     constructor tai_local.create(abasictype: TWasmBasicType; const aname: string);

+ 46 - 1
compiler/wasm32/hlcgcpu.pas

@@ -254,7 +254,7 @@ implementation
     defutil,
     defutil,
     aasmtai,aasmcpu,
     aasmtai,aasmcpu,
     symtable,symcpu,
     symtable,symcpu,
-    procinfo,cpuinfo,cgcpu,tgobj;
+    procinfo,cpuinfo,cgcpu,tgobj,tgcpu;
 
 
   const
   const
     TOpCG2IAsmOp : array[topcg] of TAsmOp=(
     TOpCG2IAsmOp : array[topcg] of TAsmOp=(
@@ -1624,7 +1624,52 @@ implementation
     end;
     end;
 
 
   procedure thlcgwasm.g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);
   procedure thlcgwasm.g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);
+    var
+      functype: tai_functype;
+      pd: tprocdef;
+      i: integer;
+      prm: tcpuparavarsym;
+      bt: TWasmBasicType;
     begin
     begin
+      pd:=current_procinfo.procdef;
+      functype:=tai_functype.create(pd.mangledname);
+      if Assigned(pd.paras) and (pd.paras.Count>0) then
+        begin
+          for i:=0 to pd.paras.Count-1 do
+            begin
+              prm := tcpuparavarsym(pd.paras[i]);
+              case prm.paraloc[callerside].Size of
+                OS_8..OS_32, OS_S8..OS_S32:
+                  functype.add_param(wbt_i32);
+                OS_64, OS_S64:
+                  functype.add_param(wbt_i64);
+                OS_F32:
+                  functype.add_param(wbt_f32);
+                OS_F64:
+                  functype.add_param(wbt_f64);
+              else
+                // unsupported calleeside parameter type
+                Internalerror(2019093001);
+              end;
+            end;
+        end;
+      if Assigned(pd.returndef) and (pd.returndef.size>0) then
+        begin
+          if not defToWasmBasic(pd.returndef,bt) then
+            bt:=wbt_i32;
+          case bt of
+            wbt_i64:
+              functype.add_result(wbt_i64);
+            wbt_f32:
+              functype.add_result(wbt_f32);
+            wbt_f64:
+              functype.add_result(wbt_f64);
+          else
+            functype.add_result(wbt_i32);
+          end;
+        end;
+      list.Concat(functype);
+
       { the localsize is based on tg.lasttemp -> already in terms of stack
       { the localsize is based on tg.lasttemp -> already in terms of stack
         slots rather than bytes }
         slots rather than bytes }
       //list.concat(tai_directive.Create(asd_jlimit,'locals '+tostr(localsize)));
       //list.concat(tai_directive.Create(asd_jlimit,'locals '+tostr(localsize)));