ソースを参照

+ add optimizer units (empty for now) for the WebAssembly target

Nikolay Nikolov 10 ヶ月 前
コミット
a7be888255

+ 1 - 1
compiler/Makefile

@@ -715,7 +715,7 @@ ifeq ($(PPC_TARGET),riscv64)
 override LOCALOPT+=-Furiscv
 endif
 ifeq ($(PPC_TARGET),wasm32)
-override LOCALOPT+=-dNOOPT
+override LOCALOPT+=-Fuwasm32
 endif
 ifeq ($(PPC_TARGET),loongarch64)
 override LOCALOPT+=-Fuloongarch64

+ 1 - 1
compiler/Makefile.fpc

@@ -485,7 +485,7 @@ endif
 
 # WASM32 specific
 ifeq ($(PPC_TARGET),wasm32)
-override LOCALOPT+=-dNOOPT
+override LOCALOPT+=-Fuwasm32
 endif
 
 # LoongArch64 specific

+ 13 - 13
compiler/aoptobj.pas

@@ -416,9 +416,9 @@ Unit AoptObj;
 
         { If a group of labels are clustered, change the jump to point to the last one that is still referenced }
         function CollapseLabelCluster(jump: tai; var lbltai: tai): TAsmLabel;
-{$ifndef JVM}
+{$if not defined(JVM) and not defined(WASM)}
         function OptimizeConditionalJump(CJLabel: TAsmLabel; var p: tai; hp1: tai; var stoploop: Boolean): Boolean;
-{$endif JVM}
+{$endif not JVM and not WASM}
 
         { Function to determine if the jump optimisations can be performed }
         function CanDoJumpOpts: Boolean; virtual;
@@ -2091,7 +2091,7 @@ Unit AoptObj;
           end;
       end;
 
-{$ifndef JVM}
+{$if not defined(JVM) and not defined(WASM)}
     function TAOptObj.OptimizeConditionalJump(CJLabel: TAsmLabel; var p: tai; hp1: tai; var stoploop: Boolean): Boolean;
       var
         hp2: tai;
@@ -2306,7 +2306,7 @@ Unit AoptObj;
           end;
 
       end;
-{$endif JVM}
+{$endif not JVM and not WASM}
 
     function TAOptObj.CollapseZeroDistJump(var p: tai; ThisLabel: TAsmLabel): Boolean;
       var
@@ -2393,10 +2393,10 @@ Unit AoptObj;
                         { Might have caused some earlier labels to become dead }
                         stoploop := False;
                     end
-{$ifndef JVM}
+{$if not defined(JVM) and not defined(WASM)}
                   else if (taicpu(p).opcode {$ifdef z80}in{$else}={$endif} aopt_condjmp) then
                     ThisPassResult := OptimizeConditionalJump(ThisLabel, p, hp1, stoploop)
-{$endif JVM}
+{$endif not JVM and not WASM}
                     ;
                 end;
 
@@ -2422,7 +2422,7 @@ Unit AoptObj;
 
       var p1: tai;
           p2: tai;
-{$if not defined(MIPS) and not defined(riscv64) and not defined(riscv32) and not defined(JVM) and not defined(loongarch64)}
+{$if not defined(MIPS) and not defined(riscv64) and not defined(riscv32) and not defined(JVM) and not defined(loongarch64) and not defined(WASM)}
           p3: tai;
 {$endif}
           ThisLabel, l: tasmlabel;
@@ -2469,9 +2469,9 @@ Unit AoptObj;
                       Exit;
                   end;
 
-{$if not defined(MIPS) and not defined(riscv64) and not defined(riscv32) and not defined(JVM) and not defined(loongarch64)}
+{$if not defined(MIPS) and not defined(riscv64) and not defined(riscv32) and not defined(JVM) and not defined(loongarch64) and not defined(WASM)}
                 p3 := p2;
-{$endif not MIPS and not RV64 and not RV32 and not JVM and not loongarch64}
+{$endif not MIPS and not RV64 and not RV32 and not JVM and not loongarch64 and not WASM}
 
                 if { the next instruction after the label where the jump hp arrives}
                    { is unconditional or of the same type as hp, so continue       }
@@ -2480,7 +2480,7 @@ Unit AoptObj;
                    { TODO: For anyone with experience with MIPS or RISC-V, please add support for tracing
                      conditional jumps. [Kit] }
 
-{$if not defined(MIPS) and not defined(riscv64) and not defined(riscv32) and not defined(JVM) and not defined(loongarch64)}
+{$if not defined(MIPS) and not defined(riscv64) and not defined(riscv32) and not defined(JVM) and not defined(loongarch64) and not defined(WASM)}
   { for MIPS, it isn't enough to check the condition; first operands must be same, too. }
                    or
                    condition_in(hp.condition, taicpu(p1).condition) or
@@ -2498,7 +2498,7 @@ Unit AoptObj;
                      ) and
                      SetAndTest(p2,p1)
                    )
-{$endif not MIPS and not RV64 and not RV32 and not JVM and not loongarch64}
+{$endif not MIPS and not RV64 and not RV32 and not JVM and not loongarch64 and not WASM}
                    then
                   begin
                     { quick check for loops of the form "l5: ; jmp l5" }
@@ -2527,7 +2527,7 @@ Unit AoptObj;
                     GetFinalDestination := True;
                     Exit;
                   end
-{$if not defined(MIPS) and not defined(riscv64) and not defined(riscv32) and not defined(JVM) and not defined(loongarch64)}
+{$if not defined(MIPS) and not defined(riscv64) and not defined(riscv32) and not defined(JVM) and not defined(loongarch64) and not defined(WASM)}
                 else
                   if condition_in(inverse_cond(hp.condition), taicpu(p1).condition) then
                     begin
@@ -2564,7 +2564,7 @@ Unit AoptObj;
                       GetFinalDestination := True;
                       Exit;
                     end;
-{$endif not MIPS and not RV64 and not RV32 and not JVM and not loongarch64}
+{$endif not MIPS and not RV64 and not RV32 and not JVM and not loongarch64 and not WASM}
               end;
           end;
 

+ 0 - 1
compiler/ppcwasm32.lpi

@@ -63,7 +63,6 @@
         <StopAfterErrCount Value="50"/>
       </ConfigFile>
       <CustomOptions Value="-dwasm32
--dnoopt
 -dEXTDEBUG"/>
       <OtherDefines Count="4">
         <Define0 Value="wasm32"/>

+ 46 - 0
compiler/wasm32/aoptcpu.pas

@@ -0,0 +1,46 @@
+{
+    Copyright (c) 1998-2004 by Jonas Maebe
+
+    This unit calls the optimization procedures to optimize the assembler
+    code for WebAssembly
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+
+unit aoptcpu;
+
+{$i fpcdefs.inc}
+
+interface
+
+uses cpubase, aasmtai, aopt;
+
+type
+  TCpuAsmOptimizer = class(TAsmOptimizer)
+  end;
+
+implementation
+
+uses
+  globals,
+  globtype,
+  aasmcpu;
+
+begin
+  casmoptimizer := TCpuAsmOptimizer;
+end.
+

+ 109 - 0
compiler/wasm32/aoptcpub.pas

@@ -0,0 +1,109 @@
+ {
+    Copyright (c) 1998-2004 by Jonas Maebe, member of the Free Pascal
+    Development Team
+
+    This unit contains several types and constants necessary for the
+    optimizer to work on the WebAssembly architecture
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+Unit aoptcpub; { Assembler OPTimizer CPU specific Base }
+
+{$i fpcdefs.inc}
+
+{ enable the following define if memory references can have a scaled index }
+{ define RefsHaveScale}
+
+{ enable the following define if memory references can have a segment }
+{ override                                                            }
+{ define RefsHaveSegment}
+
+Interface
+
+Uses
+  cpubase,aasmcpu,AOptBase;
+
+Type
+
+{ type of a normal instruction }
+  TInstr = Taicpu;
+  PInstr = ^TInstr;
+
+{ ************************************************************************* }
+{ **************************** TCondRegs ********************************** }
+{ ************************************************************************* }
+{ Info about the conditional registers                                      }
+  TCondRegs = Object
+    Constructor Init;
+    Destructor Done;
+  End;
+
+{ ************************************************************************* }
+{ **************************** TAoptBaseCpu ******************************* }
+{ ************************************************************************* }
+
+  TAoptBaseCpu = class(TAoptBase)
+  End;
+
+
+{ ************************************************************************* }
+{ ******************************* Constants ******************************* }
+{ ************************************************************************* }
+Const
+
+{ the maximum number of things (registers, memory, ...) a single instruction }
+{ changes                                                                    }
+
+  MaxCh = 3;
+
+{Oper index of operand that contains the source (reference) with a load }
+{instruction                                                            }
+
+  LoadSrc = 0;
+
+{Oper index of operand that contains the destination (register) with a load }
+{instruction                                                                }
+
+  LoadDst = 1;
+
+{Oper index of operand that contains the source (register) with a store }
+{instruction                                                            }
+
+  StoreSrc = 0;
+
+{Oper index of operand that contains the destination (reference) with a load }
+{instruction                                                                 }
+
+  StoreDst = 1;
+
+  aopt_uncondjmp = a_br;
+  aopt_condjmp = a_br_if;
+
+Implementation
+
+{ ************************************************************************* }
+{ **************************** TCondRegs ********************************** }
+{ ************************************************************************* }
+Constructor TCondRegs.init;
+Begin
+End;
+
+Destructor TCondRegs.Done; {$ifdef inl} inline; {$endif inl}
+Begin
+End;
+
+End.