Browse Source

[PATCH 30/83] removing jvm specific reference fields, adding memory operations

From 0ffafdd49d7150798c1250308edc37cfe1582c50 Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Sun, 15 Sep 2019 23:49:55 -0400

git-svn-id: branches/wasm@45907 -
nickysn 5 years ago
parent
commit
0a91394d65
5 changed files with 99 additions and 145 deletions
  1. 5 5
      compiler/cgutils.pas
  2. 8 16
      compiler/wasm/agwat.pas
  3. 14 0
      compiler/wasm/cpubase.pas
  4. 72 120
      compiler/wasm/hlcgcpu.pas
  5. 0 4
      compiler/wasm/rgcpu.pas

+ 5 - 5
compiler/cgutils.pas

@@ -107,11 +107,11 @@ unit cgutils;
          checkcast: boolean;
 {$endif jvm}
 {$ifdef wasm}
-        arrayreftype: tarrayreftype;
-        indexbase: tregister;
-        indexsymbol: tasmsymbol;
-        indexoffset: aint;
-        checkcast: boolean;
+        //arrayreftype: tarrayreftype;
+        //indexbase: tregister;
+        //indexsymbol: tasmsymbol;
+        //indexoffset: aint;
+        //checkcast: boolean;
 {$endif wasm}
          volatility: tvolatilityset;
          alignment : byte;

+ 8 - 16
compiler/wasm/agwat.pas

@@ -123,8 +123,7 @@ implementation
 
      function getreferencestring(var ref : treference) : ansistring;
        begin
-         if (ref.arrayreftype<>art_none) or
-            (ref.index<>NR_NO) then
+         if (ref.index<>NR_NO) then
            internalerror(2010122809);
          if assigned(ref.symbol) then
            begin
@@ -132,9 +131,11 @@ implementation
              // ref.base can be <> NR_NO in case an instance field is loaded.
              // This register is not part of this instruction, it will have
              // been placed on the stack by the previous one.
-             if (ref.offset<>0) then
-               internalerror(2010122811);
-             result:=GetWasmName(ref.symbol.name);
+
+             if ref.symbol.typ in [AT_DATA] then begin
+               result := 'offset='+tostr(ref.offset)
+             end else
+               result:=GetWasmName(ref.symbol.name);
            end
          else
            begin
@@ -206,8 +207,6 @@ implementation
     var
       cpu : taicpu;
       i   : integer;
-    const
-      ExplicitOffset = [a_i32_load, a_i32_store];
     begin
       //writer.AsmWriteLn('instr');
       //writeln('>',taicpu(hp).opcode);
@@ -224,15 +223,7 @@ implementation
           for i:=0 to cpu.ops-1 do
             begin
               writer.AsmWrite(#9);
-              if (cpu.oper[i]^.typ = top_ref) and
-                (cpu.opcode in ExplicitOffset) then begin
-                writer.AsmWrite('offset=');
-                writer.AsmWrite(tostr(cpu.oper[i]^.ref^.offset));
-                writer.AsmWrite(' ;;');
-                writer.AsmWrite('alignment=');
-                writer.AsmWrite(tostr(cpu.oper[i]^.ref^.alignment));
-              end else
-                writer.AsmWrite(getopstr(cpu.oper[i]^));
+              writer.AsmWrite(getopstr(cpu.oper[i]^));
             end;
         end;
 
@@ -554,6 +545,7 @@ implementation
         end;
         writer.MarkEmpty;
         writer.AsmWriteLn('(module ');
+        writer.AsmWriteLn('(memory 32768) ;; todo: this should be imported or based on the directives ');
 
         { print all global variables }
         //WriteSymtableVarSyms(current_module.globalsymtable);

+ 14 - 0
compiler/wasm/cpubase.pas

@@ -100,6 +100,20 @@ uses
         ,a_f32_store, a_f64_store
       ];
 
+      AsmOp_Load = [
+         a_i32_load,
+         a_i32_load8_s,  a_i32_load8_u,
+         a_i32_load16_s, a_i32_load16_u,
+         a_i64_load,
+         a_i64_load8_s,  a_i64_load8_u,
+         a_i64_load16_s, a_i64_load16_u,
+         a_i64_load32_s, a_i64_load32_u,
+         a_f32_load, a_f64_load
+      ];
+
+      AsmOp_LoadStore = AsmOp_Load + AsmOp_Store;
+
+
 {*****************************************************************************
                                   Registers
 *****************************************************************************}

+ 72 - 120
compiler/wasm/hlcgcpu.pas

@@ -623,22 +623,6 @@ implementation
                (fromloc.reference.base<>current_procinfo.framepointer) and
                (fromloc.reference.base<>NR_STACK_POINTER_REG) then
               g_allocload_reg_reg(list,voidpointertype,fromloc.reference.base,toloc.reference.base,R_ADDRESSREGISTER);
-            case fromloc.reference.arrayreftype of
-              art_indexreg:
-                begin
-                  { all array indices in Java are 32 bit ints }
-                  g_allocload_reg_reg(list,s32inttype,fromloc.reference.index,toloc.reference.index,R_INTREGISTER);
-                end;
-              art_indexref:
-                begin
-                  { base register of the address of the index -> pointer }
-                  if (fromloc.reference.indexbase<>NR_NO) and
-                     (fromloc.reference.indexbase<>NR_STACK_POINTER_REG) then
-                    g_allocload_reg_reg(list,voidpointertype,fromloc.reference.indexbase,toloc.reference.indexbase,R_ADDRESSREGISTER);
-                end;
-              else
-                ;
-            end;
           end;
         else
           inherited;
@@ -1015,93 +999,46 @@ implementation
       { fake location that indicates the value is already on the stack? }
       if (ref.base=NR_EVAL_STACK_BASE) then
         exit;
-      if ref.arrayreftype=art_none then
-        begin
-          { non-array accesses cannot have an index reg }
-          if ref.index<>NR_NO then
-            internalerror(2010120509);
-          if (ref.base<>NR_NO) then
-            begin
-              if (ref.base<>NR_STACK_POINTER_REG) then
-                begin
-                  { regular field -> load self on the stack }
-                  a_load_reg_stack(list,voidpointertype,ref.base);
-                  if dup then
-                    begin
-                      internalerror(2019083002);
-                      //todo: add duplicate
-                      //list.concat(taicpu.op_none(a_dup));
-                      incstack(list,1);
-                    end;
-                  { field name/type encoded in symbol, no index/offset }
-                  if not assigned(ref.symbol) or
-                     (ref.offset<>0) then
-                    internalerror(2010120524);
-                  result:=1;
-                end
-              else
-                begin
-                  { local variable -> offset encoded in opcode and nothing to
-                    do here, except for checking that it's a valid reference }
-                  if assigned(ref.symbol) then
-                    internalerror(2010120523);
-                end;
-            end
-          else
-            begin
-              { static field -> nothing to do here, except for validity check }
-              if not assigned(ref.symbol) or
-                 (ref.offset<>0) then
-                internalerror(2010120525);
-            end;
-        end
-      else
-        begin
-          { arrays have implicit dereference -> pointer to array must have been
-            loaded into base reg }
-          if (ref.base=NR_NO) or
-             (ref.base=NR_STACK_POINTER_REG) then
-            internalerror(2010120511);
-          if assigned(ref.symbol) then
-            internalerror(2010120512);
-
-          { stack: ... -> ..., arrayref, index }
-          { load array base address }
-          a_load_reg_stack(list,voidpointertype,ref.base);
-          { index can either be in a register, or located in a simple memory
-            location (since we have to load it anyway) }
-          case ref.arrayreftype of
-            art_indexreg:
-              begin
-                if ref.index=NR_NO then
-                  internalerror(2010120513);
-                { all array indices in Java are 32 bit ints }
-                a_load_reg_stack(list,s32inttype,ref.index);
-              end;
-            art_indexref:
+        { non-array accesses cannot have an index reg }
+        if ref.index<>NR_NO then
+          internalerror(2010120509);
+        if (ref.base<>NR_NO) then
+          begin
+            if (ref.base<>NR_STACK_POINTER_REG) then
               begin
-                cgutils.reference_reset_base(href,ref.indexbase,ref.indexoffset,ref.temppos,4,ref.volatility);
-                href.symbol:=ref.indexsymbol;
-                a_load_ref_stack(list,s32inttype,href,prepare_stack_for_ref(list,href,false));
-              end;
-            art_indexconst:
+                { regular field -> load self on the stack }
+                a_load_reg_stack(list,voidpointertype,ref.base);
+                if dup then
+                  begin
+                    internalerror(2019083002);
+                    //todo: add duplicate
+                    //list.concat(taicpu.op_none(a_dup));
+                    incstack(list,1);
+                  end;
+                { field name/type encoded in symbol, no index/offset }
+                if not assigned(ref.symbol) or
+                   (ref.offset<>0) then
+                  internalerror(2010120524);
+                result:=1;
+              end
+            else
               begin
-                a_load_const_stack(list,s32inttype,ref.indexoffset,R_INTREGISTER);
+                { local variable -> offset encoded in opcode and nothing to
+                  do here, except for checking that it's a valid reference }
+                if assigned(ref.symbol) then
+                  internalerror(2010120523);
               end;
-            else
-              internalerror(2011012001);
-          end;
-          { adjustment of the index }
-          if ref.offset<>0 then
-            a_op_const_stack(list,OP_ADD,s32inttype,ref.offset);
-          if dup then
+          end
+        else
+          begin
+            { static field -> nothing to do here, except for validity check }
+            {if not assigned(ref.symbol) or
+               (ref.offset<>0) then
             begin
-              internalerror(2019083002); // todo: missing dups
-              //list.concat(taicpu.op_none(a_dup2));
-              incstack(list,2);
-            end;
-          result:=2;
-        end;
+              Dump_Stack(output, 0); //ncgld
+              internalerror(2010120525);
+            end;}
+          end;
     end;
 
   procedure thlcgwasm.a_load_const_reg(list: TAsmList; tosize: tdef; a: tcgint; register: tregister);
@@ -1115,7 +1052,7 @@ implementation
       extra_slots: longint;
     begin
       extra_slots:=prepare_stack_for_ref(list,ref,false);
-      a_load_const_stack_intern(list,tosize,a,def2regtyp(tosize),(ref.arrayreftype<>art_none) or assigned(ref.symbol));
+      a_load_const_stack_intern(list,tosize,a,def2regtyp(tosize),assigned(ref.symbol));
       a_load_stack_ref(list,tosize,ref,extra_slots);
     end;
 
@@ -1126,7 +1063,7 @@ implementation
       extra_slots:=prepare_stack_for_ref(list,ref,false);
       a_load_reg_stack(list,fromsize,register);
       if def2regtyp(fromsize)=R_INTREGISTER then
-        resize_stack_int_val(list,fromsize,tosize,(ref.arrayreftype<>art_none) or assigned(ref.symbol));
+        resize_stack_int_val(list,fromsize,tosize,assigned(ref.symbol));
       a_load_stack_ref(list,tosize,ref,extra_slots);
     end;
 
@@ -1161,7 +1098,7 @@ implementation
       extra_sslots:=prepare_stack_for_ref(list,sref,false);
       a_load_ref_stack(list,fromsize,sref,extra_sslots);
       if def2regtyp(fromsize)=R_INTREGISTER then
-        resize_stack_int_val(list,fromsize,tosize,(dref.arrayreftype<>art_none) or assigned(dref.symbol));
+        resize_stack_int_val(list,fromsize,tosize,assigned(dref.symbol));
       a_load_stack_ref(list,tosize,dref,extra_dslots);
     end;
 
@@ -1197,8 +1134,7 @@ implementation
       a_op_const_stack(list,op,size,a);
       { for android verifier }
       if (def2regtyp(size)=R_INTREGISTER) and
-         ((ref.arrayreftype<>art_none) or
-          assigned(ref.symbol)) then
+         (assigned(ref.symbol)) then
         resize_stack_int_val(list,size,size,true);
       a_load_stack_ref(list,size,ref,extra_slots);
     end;
@@ -1816,8 +1752,6 @@ implementation
                 base address of the array }
               location_reset_ref(tmploc,LOC_REFERENCE,OS_ADDR,4,ref.volatility);
               cgutils.reference_reset_base(tmploc.reference,getaddressregister(list,java_jlobject),0,tmploc.reference.temppos,4,ref.volatility);
-              tmploc.reference.arrayreftype:=art_indexconst;
-              tmploc.reference.indexoffset:=0;
               a_load_loc_reg(list,java_jlobject,java_jlobject,l,tmploc.reference.base);
             end
           else
@@ -1992,10 +1926,10 @@ implementation
       if ref.base=NR_EVAL_STACK_BASE then
         exit;
       opc:=loadstoreopcref(size,false,ref,finishandval);
-      if ref.arrayreftype=art_none then
-        list.concat(taicpu.op_ref(opc,ref))
-      else
-        list.concat(taicpu.op_none(opc));
+      if opc in AsmOp_LoadStore then
+        list.Concat(taicpu.op_const(a_i32_const, 0)); //todo: this should not be 0, this should be reference to a global "memory"
+
+      list.concat(taicpu.op_ref(opc,ref));
       { avoid problems with getting the size of an open array etc }
       if wasmimplicitpointertype(size) then
         size:=java_jlobject;
@@ -2026,10 +1960,12 @@ implementation
       if (ref.base=NR_EVAL_STACK_BASE) then
         exit;
       opc:=loadstoreopcref(size,true,ref,finishandval);
-      if ref.arrayreftype=art_none then
-        list.concat(taicpu.op_ref(opc,ref))
-      else
-        list.concat(taicpu.op_none(opc));
+
+      if opc in AsmOp_LoadStore then
+        list.Concat(taicpu.op_const(a_i32_const, 0)); //todo: this should not be 0, this should be reference to a global "memory"
+
+      list.concat(taicpu.op_ref(opc,ref));
+
       { avoid problems with getting the size of an open array etc }
       if wasmimplicitpointertype(size) then
         size:=java_jlobject;
@@ -2044,10 +1980,11 @@ implementation
 
   function thlcgwasm.loadstoreopcref(def: tdef; isload: boolean; const ref: treference; out finishandval: tcgint): tasmop;
     const
-                     { isload  static }
-      getputopc: array[boolean,boolean] of tasmop =
-        ((a_set_local,a_set_global),
-         (a_get_local,a_get_global));
+                          {iisload}
+      getputmem8  : array [boolean] of TAsmOp = (a_i32_store8,  a_i32_load8_u  );
+      getputmem16 : array [boolean] of TAsmOp = (a_i32_store16, a_i32_load16_u );
+      getputmem32 : array [boolean] of TAsmOp = (a_i32_store,   a_i32_load     );
+      getputmem64 : array [boolean] of TAsmOp = (a_i64_store,   a_i64_load     );
     begin
       if assigned(ref.symbol) then
         begin
@@ -2055,7 +1992,22 @@ implementation
             field, then ref.base contains the self pointer, otherwise
             ref.base=NR_NO. In both cases, the symbol contains all other
             information (combined field name and type descriptor) }
-          result:=getputopc[isload,ref.base=NR_NO];
+          if ref.base = NR_NO then begin
+            case def.size of
+              1: result := getputmem8[isload];
+              2: result := getputmem16[isload];
+              4: result := getputmem32[isload];
+              8: result := getputmem64[isload];
+              //todo: floats?
+            else
+              Internalerror(201909150001);
+            end;
+          end else if isload then
+            result := a_set_local
+          else
+            result := a_get_local;
+
+          //result:=getputopc[isload,ref.base=NR_NO];
           finishandval:=-1;
           { erase sign extension for byte/smallint loads }
           if (def2regtyp(def)=R_INTREGISTER) and
@@ -2070,7 +2022,7 @@ implementation
             end;
         end
       else
-        result:=loadstoreopc(def,isload,ref.arrayreftype<>art_none,finishandval);
+        result:=loadstoreopc(def,isload,false,finishandval);
     end;
 
   function thlcgwasm.loadstoreopc(def: tdef; isload, isarray: boolean; out finishandval: tcgint): tasmop;

+ 0 - 4
compiler/wasm/rgcpu.pas

@@ -159,10 +159,6 @@ implementation
                     exit(true);
                   if (getsupreg(taicpu(p).oper[0]^.ref^.index)=sr) then
                     exit(true);
-                  if (getsupreg(taicpu(p).oper[0]^.ref^.indexbase)=sr) then
-                    exit(true);
-                  if (getsupreg(taicpu(p).oper[0]^.ref^.indexbase)=sr) then
-                    exit(true);
                 end;
               else
                 ;