Browse Source

Merge branch source:main into stepped_window_arrangement_v2

Margers 4 months ago
parent
commit
ab0363149e
100 changed files with 2599 additions and 772 deletions
  1. 30 4
      Makefile
  2. 66 12
      compiler/Makefile
  3. 2 2
      compiler/Makefile.fpc
  4. 1 1
      compiler/aarch64/agcpugas.pas
  5. 3 1
      compiler/aggas.pas
  6. 4 1
      compiler/arm/aoptcpu.pas
  7. 24 13
      compiler/avr/aasmcpu.pas
  8. 5 5
      compiler/defutil.pas
  9. 7 3
      compiler/globtype.pas
  10. 18 6
      compiler/i386/aoptcpu.pas
  11. 16 16
      compiler/i386/cpuinfo.pas
  12. 2 0
      compiler/i8086/aoptcpu.pas
  13. 2 0
      compiler/loongarch64/aoptcpu.pas
  14. 8 2
      compiler/m68k/aoptcpu.pas
  15. 10 9
      compiler/m68k/cpuinfo.pas
  16. 1 1
      compiler/m68k/n68kadd.pas
  17. 1 1
      compiler/m68k/n68kcnv.pas
  18. 1 1
      compiler/m68k/n68kmat.pas
  19. 3 1
      compiler/mips/aoptcpu.pas
  20. 5 2
      compiler/msg/errore.msg
  21. 125 111
      compiler/ncgcal.pas
  22. 4 1
      compiler/ncgcon.pas
  23. 4 0
      compiler/ncgmem.pas
  24. 2 0
      compiler/ncnv.pas
  25. 2 1
      compiler/ogwasm.pas
  26. 4 1
      compiler/options.pas
  27. 3 1
      compiler/parser.pas
  28. 6 1
      compiler/rautils.pas
  29. 2 1
      compiler/riscv/aasmcpu.pas
  30. 5 5
      compiler/riscv/agrvgas.pas
  31. 199 125
      compiler/riscv/aoptcpurv.pas
  32. 1 1
      compiler/riscv/nrvutil.pas
  33. 2 0
      compiler/riscv32/cgcpu.pas
  34. 6 3
      compiler/riscv32/cpuinfo.pas
  35. 3 1
      compiler/riscv64/aoptcpu.pas
  36. 6 0
      compiler/riscv64/cgcpu.pas
  37. 6 3
      compiler/riscv64/cpuinfo.pas
  38. 3 1
      compiler/sparcgen/aoptcpu.pas
  39. 13 4
      compiler/symcreat.pas
  40. 4 2
      compiler/systems.inc
  41. 12 10
      compiler/systems.pas
  42. 160 9
      compiler/systems/i_wasi.pas
  43. 4 1
      compiler/systems/t_bsd.pas
  44. 11 4
      compiler/systems/t_darwin.pas
  45. 1 2
      compiler/systems/t_msdos.pas
  46. 9 3
      compiler/systems/t_wasi.pas
  47. 1 1
      compiler/systems/t_win.pas
  48. 43 7
      compiler/utils/Makefile
  49. 3 0
      compiler/utils/msg2inc.pp
  50. 7 4
      compiler/utils/ppuutils/ppudump.pp
  51. 1 1
      compiler/wasm32/agbinaryen.pas
  52. 9 9
      compiler/wasm32/agllvmmc.pas
  53. 1 1
      compiler/wasm32/agwasa.pas
  54. 8 4
      compiler/wasm32/cpupi.pas
  55. 1 1
      compiler/wasm32/hlcgcpu.pas
  56. 45 0
      compiler/wasm32/nwasmcal.pas
  57. 17 4
      compiler/wasm32/nwasminl.pas
  58. 0 2
      compiler/wasm32/nwasmset.pas
  59. 124 95
      compiler/x86/aoptx86.pas
  60. 18 6
      compiler/x86_64/aoptcpu.pas
  61. 4 3
      compiler/x86_64/cpuinfo.pas
  62. 3 1
      compiler/xtensa/aoptcpu.pas
  63. 2 0
      compiler/z80/aoptcpu.pas
  64. 34 4
      installer/Makefile
  65. 15 3
      packages/Makefile
  66. 26 3
      packages/build/Makefile.pkg
  67. 1 1
      packages/bzip2/fpmake.pp
  68. 2 0
      packages/cairo/fpmake.pp
  69. 24 4
      packages/cdrom/examples/Makefile
  70. 1 1
      packages/chm/fpmake.pp
  71. 1 1
      packages/chm/src/chmwriter.pas
  72. 24 4
      packages/dbus/examples/Makefile
  73. 40 4
      packages/fcl-base/examples/Makefile
  74. 1 1
      packages/fcl-base/fpmake.pp
  75. 1 1
      packages/fcl-css/fpmake.pp
  76. 62 13
      packages/fcl-css/src/fpcssparser.pp
  77. 154 62
      packages/fcl-css/src/fpcssresolver.pas
  78. 237 25
      packages/fcl-css/src/fpcssresparser.pas
  79. 1 6
      packages/fcl-css/src/fpcssscanner.pp
  80. 1 2
      packages/fcl-css/tests/tccssparser.pp
  81. 238 10
      packages/fcl-css/tests/tccssresolver.pp
  82. 3 5
      packages/fcl-css/tests/tccssscanner.pp
  83. 1 1
      packages/fcl-db/fpmake.pp
  84. 47 7
      packages/fcl-db/src/base/Makefile
  85. 38 6
      packages/fcl-db/src/codegen/Makefile
  86. 40 6
      packages/fcl-db/src/datadict/Makefile
  87. 52 8
      packages/fcl-db/src/dbase/Makefile
  88. 40 6
      packages/fcl-db/src/export/Makefile
  89. 26 4
      packages/fcl-db/src/json/Makefile
  90. 38 6
      packages/fcl-db/src/memds/Makefile
  91. 33 5
      packages/fcl-db/src/paradox/Makefile
  92. 31 5
      packages/fcl-db/src/sdf/Makefile
  93. 45 7
      packages/fcl-db/src/sql/Makefile
  94. 38 6
      packages/fcl-db/src/sqldb/Makefile
  95. 33 5
      packages/fcl-db/src/sqldb/interbase/Makefile
  96. 34 17
      packages/fcl-db/src/sqldb/interbase/ibconnection.pp
  97. 31 5
      packages/fcl-db/src/sqldb/mssql/Makefile
  98. 40 6
      packages/fcl-db/src/sqldb/mysql/Makefile
  99. 33 5
      packages/fcl-db/src/sqldb/odbc/Makefile
  100. 40 6
      packages/fcl-db/src/sqldb/oracle/Makefile

+ 30 - 4
Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: help
 default: help
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -842,7 +842,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_DIRS+=compiler rtl utils packages installer
 override TARGET_DIRS+=compiler rtl utils packages installer
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_DIRS+=compiler rtl utils packages installer
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_DIRS+=compiler rtl utils packages installer
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_DIRS+=compiler rtl utils packages installer
 override TARGET_DIRS+=compiler rtl utils packages installer
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1418,7 +1424,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2900,7 +2912,21 @@ TARGET_DIRS_UTILS=1
 TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_INSTALLER=1
 TARGET_DIRS_INSTALLER=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+TARGET_DIRS_COMPILER=1
+TARGET_DIRS_RTL=1
+TARGET_DIRS_UTILS=1
+TARGET_DIRS_PACKAGES=1
+TARGET_DIRS_INSTALLER=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+TARGET_DIRS_COMPILER=1
+TARGET_DIRS_RTL=1
+TARGET_DIRS_UTILS=1
+TARGET_DIRS_PACKAGES=1
+TARGET_DIRS_INSTALLER=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
 TARGET_DIRS_RTL=1
 TARGET_DIRS_UTILS=1
 TARGET_DIRS_UTILS=1

+ 66 - 12
compiler/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -372,8 +372,8 @@ unexport FPC_VERSION FPC_COMPILERINFO
 CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 aarch64 sparc64 riscv32 riscv64 xtensa z80 wasm32 loongarch64
 CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 aarch64 sparc64 riscv32 riscv64 xtensa z80 wasm32 loongarch64
 BETATARGETS=mips64 mips64el
 BETATARGETS=mips64 mips64el
 ALLTARGETS=$(CYCLETARGETS)
 ALLTARGETS=$(CYCLETARGETS)
-NO_NATIVE_COMPILER_OS_LIST=amstradcpc embedded freertos gba macosclassic msdos msxdos nds palmos sinclairql symbian watcom wii win16 zxspectrum ps1
-NO_NATIVE_COMPILER_CPU_LIST=avr i8086 jvm z80 wasm32
+NO_NATIVE_COMPILER_OS_LIST=amstradcpc embedded freertos gba macosclassic msdos msxdos nds palmos sinclairql symbian watcom wii win16 zxspectrum ps1 wasip2
+NO_NATIVE_COMPILER_CPU_LIST=avr i8086 jvm z80
 ifneq ($(CPU_SOURCE),$(CPU_TARGET))
 ifneq ($(CPU_SOURCE),$(CPU_TARGET))
 ifneq ($(findstring $(CPU_TARGET),$(NO_NATIVE_COMPILER_CPU_LIST)),)
 ifneq ($(findstring $(CPU_TARGET),$(NO_NATIVE_COMPILER_CPU_LIST)),)
 NoNativeBinaries=1
 NoNativeBinaries=1
@@ -1024,7 +1024,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_DIRS+=utils
 override TARGET_DIRS+=utils
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_DIRS+=utils
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_DIRS+=utils
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_DIRS+=utils
 override TARGET_DIRS+=utils
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1363,7 +1369,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_PROGRAMS+=pp
 override TARGET_PROGRAMS+=pp
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_PROGRAMS+=pp
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_PROGRAMS+=pp
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_PROGRAMS+=pp
 override TARGET_PROGRAMS+=pp
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1703,7 +1715,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2042,7 +2060,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2381,7 +2405,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET)
 override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET)
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET)
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET)
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET)
 override COMPILER_TARGETDIR+=$(CPU_UNITDIR)/bin/$(FULL_TARGET)
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2720,7 +2750,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -3295,7 +3331,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -3847,7 +3889,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -4863,7 +4911,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 TARGET_DIRS_UTILS=1
 TARGET_DIRS_UTILS=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+TARGET_DIRS_UTILS=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+TARGET_DIRS_UTILS=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 TARGET_DIRS_UTILS=1
 TARGET_DIRS_UTILS=1
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)

+ 2 - 2
compiler/Makefile.fpc

@@ -41,9 +41,9 @@ BETATARGETS=mips64 mips64el
 ALLTARGETS=$(CYCLETARGETS)
 ALLTARGETS=$(CYCLETARGETS)
 
 
 # All OS targets that do not support native compiler
 # All OS targets that do not support native compiler
-NO_NATIVE_COMPILER_OS_LIST=amstradcpc embedded freertos gba macosclassic msdos msxdos nds palmos sinclairql symbian watcom wii win16 zxspectrum ps1
+NO_NATIVE_COMPILER_OS_LIST=amstradcpc embedded freertos gba macosclassic msdos msxdos nds palmos sinclairql symbian watcom wii win16 zxspectrum ps1 wasip2
 # All CPU targets that do not support native compiler
 # All CPU targets that do not support native compiler
-NO_NATIVE_COMPILER_CPU_LIST=avr i8086 jvm z80 wasm32
+NO_NATIVE_COMPILER_CPU_LIST=avr i8086 jvm z80
 
 
 # Don't compile a native compiler & utilities for targets
 # Don't compile a native compiler & utilities for targets
 # which do not support it
 # which do not support it

+ 1 - 1
compiler/aarch64/agcpugas.pas

@@ -895,7 +895,7 @@ unit agcpugas;
             idtxt  : 'AS-CLANG';
             idtxt  : 'AS-CLANG';
             asmbin : 'clang';
             asmbin : 'clang';
             asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $MARCHOPT $EXTRAOPT -x assembler $ASM';
             asmcmd : '-x assembler -c -target $TRIPLET -o $OBJ $MARCHOPT $EXTRAOPT -x assembler $ASM';
-            supported_targets : [system_aarch64_win64];
+            supported_targets : [system_aarch64_freebsd,system_aarch64_linux,system_aarch64_android,system_aarch64_embedded,system_aarch64_win64];
             flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm,af_supports_hlcfi];
             flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_llvm,af_supports_hlcfi];
             labelprefix : '.L';
             labelprefix : '.L';
             labelmaxlen : -1;
             labelmaxlen : -1;

+ 3 - 1
compiler/aggas.pas

@@ -565,7 +565,9 @@ implementation
              if atype<>sec_toc then
              if atype<>sec_toc then
                writer.AsmWrite('.csect ');
                writer.AsmWrite('.csect ');
            end;
            end;
-         system_wasm32_wasi,
+         system_wasm32_wasip1,
+         system_wasm32_wasip1threads,
+         system_wasm32_wasip2,
          system_wasm32_embedded:
          system_wasm32_embedded:
            begin
            begin
              writer.AsmWrite('.section ');
              writer.AsmWrite('.section ');

+ 4 - 1
compiler/arm/aoptcpu.pas

@@ -25,8 +25,11 @@ Unit aoptcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
+{$ifdef EXTDEBUG}
+{$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
+
 { $define DEBUG_PREREGSCHEDULER}
 { $define DEBUG_PREREGSCHEDULER}
-{ $define DEBUG_AOPTCPU}
 
 
 Interface
 Interface
 
 

+ 24 - 13
compiler/avr/aasmcpu.pas

@@ -478,11 +478,11 @@ implementation
                         firstinstruction:=curtai;
                         firstinstruction:=curtai;
                       case taicpu(curtai).opcode of
                       case taicpu(curtai).opcode of
                         A_BRxx:
                         A_BRxx:
-                          if (taicpu(curtai).oper[0]^.typ=top_ref) and ((taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset>64) or
-                            (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset<-63)) then
+                          if (taicpu(curtai).oper[0]^.typ=top_ref) and ((taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset>63*2) or
+                            (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset<-64*2)) then
                             begin
                             begin
                               if inasmblock then
                               if inasmblock then
-                                Message(asmw_e_brxx_out_of_range)
+                                MessagePos1(taicpu(curtai).fileinfo,asmw_e_destination_out_of_range,'BR'+uppercond2str[taicpu(curtai).condition])
                               else
                               else
                                 begin
                                 begin
                                   current_asmdata.getjumplabel(l);
                                   current_asmdata.getjumplabel(l);
@@ -497,18 +497,29 @@ implementation
                                   again:=true;
                                   again:=true;
                                 end;
                                 end;
                             end;
                             end;
+                        A_RJMP:
+                          if inasmblock and (taicpu(curtai).oper[0]^.typ=top_ref) and
+                            not(taicpu(curtai).oper[0]^.ref^.symbol.typ=AT_FUNCTION) and
+                            ((taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset>2047*2) or
+                            (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset<-2048*2)) then
+                            begin
+                              MessagePos1(taicpu(curtai).fileinfo,asmw_e_destination_out_of_range,'RJMP');
+                            end;
                         A_JMP:
                         A_JMP:
                           { replace JMP by RJMP? ...
                           { replace JMP by RJMP? ...
-                            ... but do not mess with asm block }
-                          if not(inasmblock) and (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset<=2048) and
-                          (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset>=-2047) and
-                          { jmps to function go outside the currently considered scope, so do not mess with them.
-                            Those are generated by the peephole optimizer from call/ret sequences }
-                          not(taicpu(curtai).oper[0]^.ref^.symbol.typ=AT_FUNCTION) then
-                          begin
-                            taicpu(curtai).opcode:=A_RJMP;
-                            again:=true;
-                          end;
+                            ... but do not mess with asm block.
+                            Replacing JMP with RJMP shorten the distance to the destination
+                            in the reverse direction by 2 bytes, hence checking against a
+                            distance of -2049*2 bytes. }
+                          if not(inasmblock) and (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset<=2047*2) and
+                            (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset>=-2049*2) and
+                            { jmps to function go outside the currently considered scope, so do not mess with them.
+                              Those are generated by the peephole optimizer from call/ret sequences }
+                            not(taicpu(curtai).oper[0]^.ref^.symbol.typ=AT_FUNCTION) then
+                            begin
+                              taicpu(curtai).opcode:=A_RJMP;
+                              again:=true;
+                            end;
                         A_STS:
                         A_STS:
                           begin
                           begin
                             if current_settings.cputype in [cpu_avrtiny, cpu_avr1] then
                             if current_settings.cputype in [cpu_avrtiny, cpu_avr1] then

+ 5 - 5
compiler/defutil.pas

@@ -1068,7 +1068,7 @@ implementation
                     is_chararray(tpointerdef(p).pointeddef)));
                     is_chararray(tpointerdef(p).pointeddef)));
       end;
       end;
 
 
-    { true if p is a pchar def }
+    { true if p is a pwidechar def }
     function is_pwidechar(p : tdef) : boolean;
     function is_pwidechar(p : tdef) : boolean;
       begin
       begin
         is_pwidechar:=(p.typ=pointerdef) and
         is_pwidechar:=(p.typ=pointerdef) and
@@ -1551,12 +1551,12 @@ implementation
     function is_vector(p : tdef) : boolean;
     function is_vector(p : tdef) : boolean;
       begin
       begin
         result:=(p.typ=arraydef) and
         result:=(p.typ=arraydef) and
-                (tarraydef(p).is_hwvector or
+                (tarraydef(p).is_hwvector { or
                  (not(is_special_array(p)) and
                  (not(is_special_array(p)) and
-                  (tarraydef(p).elementdef.typ in [floatdef,orddef]) {and
+                  (tarraydef(p).elementdef.typ in [floatdef,orddef]) and
                   (tarraydef(p).elementdef.typ=floatdef) and
                   (tarraydef(p).elementdef.typ=floatdef) and
-                  (tfloatdef(tarraydef(p).elementdef).floattype in [s32real,s64real])}
-                 )
+                  (tfloatdef(tarraydef(p).elementdef).floattype in [s32real,s64real])
+                 ) }
                 );
                 );
       end;
       end;
 
 

+ 7 - 3
compiler/globtype.pas

@@ -329,7 +329,10 @@ interface
          ts_wasm_native_exceptions,
          ts_wasm_native_exceptions,
          { support multithreading via the WebAssembly threading proposal:
          { support multithreading via the WebAssembly threading proposal:
            https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md }
            https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md }
-         ts_wasm_threads
+         ts_wasm_threads,
+         { use saturating (nontrapping) float to int conversion instructions:
+           https://github.com/WebAssembly/spec/blob/main/proposals/nontrapping-float-to-int-conversion/Overview.md }
+         ts_wasm_saturating_float_to_int
        );
        );
        ttargetswitches = set of ttargetswitch;
        ttargetswitches = set of ttargetswitch;
 
 
@@ -432,7 +435,7 @@ interface
           hasvalue: boolean;
           hasvalue: boolean;
           { target switch can be used only globally }
           { target switch can be used only globally }
           isglobal: boolean;
           isglobal: boolean;
-          define: string[30];
+          define: string[32];
        end;
        end;
 
 
     const
     const
@@ -469,7 +472,8 @@ interface
          (name: 'BFEXCEPTIONS';        hasvalue: false; isglobal: true ; define: 'FPC_WASM_BRANCHFUL_EXCEPTIONS'),
          (name: 'BFEXCEPTIONS';        hasvalue: false; isglobal: true ; define: 'FPC_WASM_BRANCHFUL_EXCEPTIONS'),
          (name: 'JSEXCEPTIONS';        hasvalue: false; isglobal: true ; define: 'FPC_WASM_JS_EXCEPTIONS'),
          (name: 'JSEXCEPTIONS';        hasvalue: false; isglobal: true ; define: 'FPC_WASM_JS_EXCEPTIONS'),
          (name: 'WASMEXCEPTIONS';      hasvalue: false; isglobal: true ; define: 'FPC_WASM_NATIVE_EXCEPTIONS'),
          (name: 'WASMEXCEPTIONS';      hasvalue: false; isglobal: true ; define: 'FPC_WASM_NATIVE_EXCEPTIONS'),
-         (name: 'WASMTHREADS';         hasvalue: false; isglobal: true ; define: 'FPC_WASM_THREADS')
+         (name: 'WASMTHREADS';         hasvalue: false; isglobal: true ; define: 'FPC_WASM_THREADS'),
+         (name: 'SATURATINGFLOATTOINT';hasvalue: false; isglobal: false; define: 'FPC_WASM_SATURATING_FLOAT_TO_INT')
        );
        );
 
 
        { switches being applied to all CPUs at the given level }
        { switches being applied to all CPUs at the given level }

+ 18 - 6
compiler/i386/aoptcpu.pas

@@ -276,9 +276,15 @@ unit aoptcpu;
             if not Result then
             if not Result then
               begin
               begin
                 if (p.typ in SkipInstr) then
                 if (p.typ in SkipInstr) then
-                  UpdateUsedRegs(p);
-
-                p := tai(p.Next);
+                  begin
+                    UpdateUsedRegs(p);
+                    p := tai(p.Next);
+                  end
+                else
+                  begin
+                    p := tai(p.Next);
+                    UpdateUsedRegs(p);
+                  end;
                 Result := True;
                 Result := True;
               end;
               end;
           end;
           end;
@@ -340,9 +346,15 @@ unit aoptcpu;
             if not Result then
             if not Result then
               begin
               begin
                 if (p.typ in SkipInstr) then
                 if (p.typ in SkipInstr) then
-                  UpdateUsedRegs(p);
-
-                p := tai(p.Next);
+                  begin
+                    UpdateUsedRegs(p);
+                    p := tai(p.Next);
+                  end
+                else
+                  begin
+                    p := tai(p.Next);
+                    UpdateUsedRegs(p);
+                  end;
                 Result := True;
                 Result := True;
               end;
               end;
           end;
           end;

+ 16 - 16
compiler/i386/cpuinfo.pas

@@ -196,9 +196,9 @@ type
        CPUX86_HAS_CMOV,         { CMOVcc instructions are available }
        CPUX86_HAS_CMOV,         { CMOVcc instructions are available }
        CPUX86_HAS_SSEUNIT,      { SSE instructions are available }
        CPUX86_HAS_SSEUNIT,      { SSE instructions are available }
        CPUX86_HAS_SSE2,         { SSE2 instructions are available }
        CPUX86_HAS_SSE2,         { SSE2 instructions are available }
+       CPUX86_HAS_SSSE3,        { SSSE3 instructions are available }
        CPUX86_HAS_SSE4_1,       { SSE 4.1 instructions are available }
        CPUX86_HAS_SSE4_1,       { SSE 4.1 instructions are available }
        CPUX86_HAS_SSE4_2,       { SSE 4.2 instructions are available }
        CPUX86_HAS_SSE4_2,       { SSE 4.2 instructions are available }
-       CPUX86_HAS_SSSE3,        { SSSE3 instructions are available }
        CPUX86_HAS_BMI1,         { BMI1 instructions are available }
        CPUX86_HAS_BMI1,         { BMI1 instructions are available }
        CPUX86_HAS_BMI2,         { BMI2 instructions are available }
        CPUX86_HAS_BMI2,         { BMI2 instructions are available }
        CPUX86_HAS_CMPXCHG16B,   { CMPXCHG16B is available (not on i386, only for less ifdefs in the compiler }
        CPUX86_HAS_CMPXCHG16B,   { CMPXCHG16B is available (not on i386, only for less ifdefs in the compiler }
@@ -249,22 +249,22 @@ type
      { cpu_Pentium3  } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT],
      { cpu_Pentium3  } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT],
      { cpu_Pentium4  } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2],
      { cpu_Pentium4  } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2],
      { cpu_PentiumM  } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2],
      { cpu_PentiumM  } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2],
-     { cpu_core_i    } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT],
+     { cpu_core_i    } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT],
      { cpu_bobcat    } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_POPCNT,CPUX86_HAS_LZCNT],
      { cpu_bobcat    } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_POPCNT,CPUX86_HAS_LZCNT],
-     { cpu_core_avx  } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT],
-     { cpu_jaguar    } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_piledriver} [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_excavator } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_core_avx2 } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_zen       } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_zen2      } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_skylake_x } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_icelake   } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_icelake_client } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_icelake_server } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_zen3      } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_zen4      } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
-     { cpu_zen5      } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE]
+     { cpu_core_avx  } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT],
+     { cpu_jaguar    } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_piledriver} [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_excavator } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_core_avx2 } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_zen       } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_zen2      } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_skylake_x } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_icelake   } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_icelake_client } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_icelake_server } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_zen3      } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_zen4      } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
+     { cpu_zen5      } [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT,CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE]
    );
    );
 
 
    fpu_capabilities : array[tfputype] of set of tfpuflags = (
    fpu_capabilities : array[tfputype] of set of tfpuflags = (

+ 2 - 0
compiler/i8086/aoptcpu.pas

@@ -25,7 +25,9 @@ unit aoptcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
+{$ifdef EXTDEBUG}
 {$define DEBUG_AOPTCPU}
 {$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
   Interface
   Interface
 
 

+ 2 - 0
compiler/loongarch64/aoptcpu.pas

@@ -27,7 +27,9 @@ interface
 
 
 {$I fpcdefs.inc}
 {$I fpcdefs.inc}
 
 
+{$ifdef EXTDEBUG}
 {$define DEBUG_AOPTCPU}
 {$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
 uses
 uses
   cpubase,
   cpubase,

+ 8 - 2
compiler/m68k/aoptcpu.pas

@@ -25,7 +25,9 @@ unit aoptcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
+{$ifdef EXTDEBUG}
 {$define DEBUG_AOPTCPU}
 {$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
   Interface
   Interface
 
 
@@ -570,8 +572,12 @@ unit aoptcpu;
                 end;
                 end;
               { CMP #0,<ea> equals to TST <ea>, just shorter and TST is more flexible anyway }
               { CMP #0,<ea> equals to TST <ea>, just shorter and TST is more flexible anyway }
               A_CMP,A_CMPI:
               A_CMP,A_CMPI:
-                if (taicpu(p).oper[0]^.typ = top_const) and
-                   (taicpu(p).oper[0]^.val = 0) then
+                if ((taicpu(p).oper[0]^.typ = top_const) and
+                    (taicpu(p).oper[0]^.val = 0)) and
+                   ((taicpu(p).oper[1]^.typ = top_ref) or
+                    ((taicpu(p).oper[1]^.typ = top_reg) and
+                     not (isaddressregister(taicpu(p).oper[1]^.reg) and
+                      not (CPUM68K_HAS_TSTAREG in cpu_capabilities[current_settings.cputype])))) then
                   begin
                   begin
                     DebugMsg('Optimizer: CMP #0 to TST',p);
                     DebugMsg('Optimizer: CMP #0 to TST',p);
                     taicpu(p).opcode:=A_TST;
                     taicpu(p).opcode:=A_TST;

+ 10 - 9
compiler/m68k/cpuinfo.pas

@@ -171,7 +171,8 @@ type
       CPUM68K_HAS_INDEXWORD,    { CPU supports indexing with 16bit index                    }
       CPUM68K_HAS_INDEXWORD,    { CPU supports indexing with 16bit index                    }
       CPUM68K_HAS_BYTEWORDMATH, { CPU supports supports 8 and 16bit aritmetic operations    }
       CPUM68K_HAS_BYTEWORDMATH, { CPU supports supports 8 and 16bit aritmetic operations    }
       CPUM68K_HAS_BITFIELD,     { CPU supports bitfield instructions                        }
       CPUM68K_HAS_BITFIELD,     { CPU supports bitfield instructions                        }
-      CPUM68K_HAS_LONGENCODING  { CPU supports long instruction encoding (i.e. non-CF)      }
+      CPUM68K_HAS_LONGENCODING, { CPU supports long instruction encoding (i.e. non-CF)      }
+      CPUM68K_HAS_TSTAREG       { CPU supports TST on address registers                     }
      );
      );
 
 
   tfpuflags =
   tfpuflags =
@@ -187,14 +188,14 @@ const
   cpu_capabilities : array[tcputype] of set of tcpuflags =
   cpu_capabilities : array[tcputype] of set of tcpuflags =
     ( { cpu_none     } [],
     ( { cpu_none     } [],
       { cpu_68000    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_TAS,CPUM68K_HAS_ROLROR,CPUM68K_HAS_MULIMM,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_BYTEWORDMATH,CPUM68K_HAS_LONGENCODING],
       { cpu_68000    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_TAS,CPUM68K_HAS_ROLROR,CPUM68K_HAS_MULIMM,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_BYTEWORDMATH,CPUM68K_HAS_LONGENCODING],
-      { cpu_68020    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_RTD,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_ROLROR,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_BASEDISP,CPUM68K_HAS_LONGLINK,CPUM68K_HAS_MULIMM,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_64BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_64BITDIV,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_INDEXSCALE8,CPUM68K_HAS_INDEXWORD,CPUM68K_HAS_BYTEWORDMATH,CPUM68K_HAS_BITFIELD,CPUM68K_HAS_LONGENCODING],
-      { cpu_68040    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_RTD,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_ROLROR,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_BASEDISP,CPUM68K_HAS_LONGLINK,CPUM68K_HAS_MULIMM,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_64BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_64BITDIV,CPUM68K_HAS_MOVE16,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_INDEXSCALE8,CPUM68K_HAS_INDEXWORD,CPUM68K_HAS_BYTEWORDMATH,CPUM68K_HAS_BITFIELD,CPUM68K_HAS_LONGENCODING],
-      { cpu_68060    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_RTD,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_ROLROR,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_BASEDISP,CPUM68K_HAS_LONGLINK,CPUM68K_HAS_MULIMM,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_MOVE16,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_INDEXSCALE8,CPUM68K_HAS_INDEXWORD,CPUM68K_HAS_BYTEWORDMATH,CPUM68K_HAS_BITFIELD,CPUM68K_HAS_LONGENCODING],
-      { cpu_isaa     } [CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE],
-      { cpu_isaap    } [CPUM68K_HAS_BRAL,CPUM68K_HAS_BYTEREV,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE],
-      { cpu_isab     } [CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_MVSMVZ,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE],
-      { cpu_isac     } [CPUM68K_HAS_TAS,CPUM68K_HAS_BYTEREV,CPUM68K_HAS_MVSMVZ,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE],
-      { cpu_cfv4e    } [CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_MVSMVZ,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE]
+      { cpu_68020    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_RTD,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_ROLROR,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_BASEDISP,CPUM68K_HAS_LONGLINK,CPUM68K_HAS_MULIMM,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_64BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_64BITDIV,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_INDEXSCALE8,CPUM68K_HAS_INDEXWORD,CPUM68K_HAS_BYTEWORDMATH,CPUM68K_HAS_BITFIELD,CPUM68K_HAS_LONGENCODING,CPUM68K_HAS_TSTAREG],
+      { cpu_68040    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_RTD,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_ROLROR,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_BASEDISP,CPUM68K_HAS_LONGLINK,CPUM68K_HAS_MULIMM,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_64BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_64BITDIV,CPUM68K_HAS_MOVE16,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_INDEXSCALE8,CPUM68K_HAS_INDEXWORD,CPUM68K_HAS_BYTEWORDMATH,CPUM68K_HAS_BITFIELD,CPUM68K_HAS_LONGENCODING,CPUM68K_HAS_TSTAREG],
+      { cpu_68060    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_RTD,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_ROLROR,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_BASEDISP,CPUM68K_HAS_LONGLINK,CPUM68K_HAS_MULIMM,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_MOVE16,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_INDEXSCALE8,CPUM68K_HAS_INDEXWORD,CPUM68K_HAS_BYTEWORDMATH,CPUM68K_HAS_BITFIELD,CPUM68K_HAS_LONGENCODING,CPUM68K_HAS_TSTAREG],
+      { cpu_isaa     } [CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_TSTAREG],
+      { cpu_isaap    } [CPUM68K_HAS_BRAL,CPUM68K_HAS_BYTEREV,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_TSTAREG],
+      { cpu_isab     } [CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_MVSMVZ,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_TSTAREG],
+      { cpu_isac     } [CPUM68K_HAS_TAS,CPUM68K_HAS_BYTEREV,CPUM68K_HAS_MVSMVZ,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_TSTAREG],
+      { cpu_cfv4e    } [CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_MVSMVZ,CPUM68K_HAS_UNALIGNED,CPUM68K_HAS_32BITMUL,CPUM68K_HAS_16BITDIV,CPUM68K_HAS_32BITDIV,CPUM68K_HAS_REMSREMU,CPUM68K_HAS_INDEXSCALE,CPUM68K_HAS_TSTAREG]
     );
     );
 
 
   { on m68k, Motorola provided a software-library, which provides full '881/2 instruction set
   { on m68k, Motorola provided a software-library, which provides full '881/2 instruction set

+ 1 - 1
compiler/m68k/n68kadd.pas

@@ -525,7 +525,7 @@ implementation
            else
            else
              begin
              begin
                hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
                hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
-               if (current_settings.cputype = cpu_mc68000) and isaddressregister(left.location.register) then
+               if (not (CPUM68K_HAS_TSTAREG in cpu_capabilities[current_settings.cputype])) and isaddressregister(left.location.register) then
                  begin
                  begin
                    tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,cmpsize);
                    tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,cmpsize);
                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_ADDR,cmpsize,left.location.register,tmpreg);
                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_ADDR,cmpsize,left.location.register,tmpreg);

+ 1 - 1
compiler/m68k/n68kcnv.pas

@@ -276,7 +276,7 @@ implementation
                   end
                   end
                 else
                 else
                   begin
                   begin
-                    if (current_settings.cputype = cpu_mc68000) and isaddressregister(left.location.register) then
+                    if (not (CPUM68K_HAS_TSTAREG in cpu_capabilities[current_settings.cputype])) and isaddressregister(left.location.register) then
                       begin
                       begin
                         hreg2:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
                         hreg2:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
                         cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_ADDR,opsize,left.location.register,hreg2);
                         cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_ADDR,opsize,left.location.register,hreg2);

+ 1 - 1
compiler/m68k/n68kmat.pas

@@ -121,7 +121,7 @@ implementation
                   else
                   else
                     begin
                     begin
                       hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,true);
                       hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,true);
-                      if (current_settings.cputype = cpu_mc68000) and isaddressregister(left.location.register) then
+                      if (not (CPUM68K_HAS_TSTAREG in cpu_capabilities[current_settings.cputype])) and isaddressregister(left.location.register) then
                         begin
                         begin
                           hreg:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
                           hreg:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
                           cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_ADDR,opsize,left.location.register,hreg);
                           cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_ADDR,opsize,left.location.register,hreg);

+ 3 - 1
compiler/mips/aoptcpu.pas

@@ -25,7 +25,9 @@ unit aoptcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
-{ $define DEBUG_AOPTCPU}
+{$ifdef EXTDEBUG}
+{$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
   Interface
   Interface
 
 

+ 5 - 2
compiler/msg/errore.msg

@@ -3079,7 +3079,7 @@ asmw_e_32bit_not_supported=08029_E_Asm: 32 bit references not supported
 asmw_f_code_segment_too_large=08030_F_Code segment too large
 asmw_f_code_segment_too_large=08030_F_Code segment too large
 asmw_f_data_segment_too_large=08031_F_Data segment too large
 asmw_f_data_segment_too_large=08031_F_Data segment too large
 asmw_e_instruction_not_supported_by_cpu=08032_E_Instruction not supported by the selected instruction set
 asmw_e_instruction_not_supported_by_cpu=08032_E_Instruction not supported by the selected instruction set
-asmw_e_brxx_out_of_range=08033_E_Asm: conditional branch destination is out of range
+asmw_e_destination_out_of_range=08033_E_Asm: $1 destination is out of range
 asmw_e_illegal_use_of_rip=08034_E_Asm: RIP cannot be used as index register or with another register in a reference
 asmw_e_illegal_use_of_rip=08034_E_Asm: RIP cannot be used as index register or with another register in a reference
 asmw_e_seh_invalid_data_size=08035_F_Illegal function size for SEH function
 asmw_e_seh_invalid_data_size=08035_F_Illegal function size for SEH function
 asmw_e_illegal_use_of_sp=08036_E_Asm: ESP/RSP cannot be used as index register
 asmw_e_illegal_use_of_sp=08036_E_Asm: ESP/RSP cannot be used as index register
@@ -4135,6 +4135,7 @@ W*3CTbfexceptions_        Enable the branchful exception support for WebAssembly
 W*3CTjsexceptions_        Enable the JavaScript-based exception support for WebAssembly (experimental)
 W*3CTjsexceptions_        Enable the JavaScript-based exception support for WebAssembly (experimental)
 W*3CTwasmexceptions_      Enable the native WebAssembly exceptions support
 W*3CTwasmexceptions_      Enable the native WebAssembly exceptions support
 W*3CTwasmthreads_         Enable WebAssembly threads support (experimental)
 W*3CTwasmthreads_         Enable WebAssembly threads support (experimental)
+W*3CTsaturatingfloattoint_ Use saturating (non-trapping) float-to-int conversion instructions
 J*2Cv_Var/out parameter copy-out checking
 J*2Cv_Var/out parameter copy-out checking
 A*2CV<x>_Set section threadvar model to <x>
 A*2CV<x>_Set section threadvar model to <x>
 **2CX_Create also smartlinked library
 **2CX_Create also smartlinked library
@@ -4413,7 +4414,9 @@ Z*2Tmsxdos_MSX-DOS
 Z*2Tzxspectrum_ZX Spectrum
 Z*2Tzxspectrum_ZX Spectrum
 # wasm32 targets
 # wasm32 targets
 W*2Tembedded_Embedded
 W*2Tembedded_Embedded
-W*2Twasi_The WebAssembly System Interface (WASI)
+W*2Twasip1_The WebAssembly System Interface Preview 1 (WASI 0.1)
+W*2Twasip1threads_The WebAssembly System Interface Preview 1 with Multithreading (WASI 0.1 + wasi-threads)
+W*2Twasip2_The WebAssembly System Interface Preview 2 (WASI 0.2) (experimental)
 # end of targets section
 # end of targets section
 **1t<x>_Target architecture
 **1t<x>_Target architecture
 **2*_ * Defines FPC_SUBTARGET_<x> 
 **2*_ * Defines FPC_SUBTARGET_<x> 

+ 125 - 111
compiler/ncgcal.pas

@@ -40,6 +40,9 @@ interface
           procedure push_formal_para;virtual;
           procedure push_formal_para;virtual;
           procedure push_copyout_para;virtual;abstract;
           procedure push_copyout_para;virtual;abstract;
           function maybe_push_unused_para:boolean;virtual;
           function maybe_push_unused_para:boolean;virtual;
+
+          procedure secondcallparan_do_secondpass;
+          procedure secondcallparan_after_secondpass;
        public
        public
           tempcgpara : tcgpara;
           tempcgpara : tcgpara;
 
 
@@ -317,127 +320,138 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcgcallparanode.secondcallparan;
-      var
-         pushaddr: boolean;
+    procedure tcgcallparanode.secondcallparan_do_secondpass;
       begin
       begin
-         if not(assigned(parasym)) then
-           internalerror(200304242);
+        if assigned(fparainit) then
+          secondpass(fparainit);
+        secondpass(left);
+      end;
 
 
-         { Skip nothingn nodes which are used after disabling
-           a parameter }
-         if (left.nodetype<>nothingn) then
-           begin
-             if assigned(fparainit) then
-               secondpass(fparainit);
-             secondpass(left);
 
 
-             hlcg.maybe_change_load_node_reg(current_asmdata.CurrAsmList,left,true);
+    procedure tcgcallparanode.secondcallparan_after_secondpass;
+      var
+        pushaddr: boolean;
+      begin
+        hlcg.maybe_change_load_node_reg(current_asmdata.CurrAsmList,left,true);
 
 
-             paramanager.createtempparaloc(current_asmdata.CurrAsmList,aktcallnode.procdefinition.proccalloption,parasym,not followed_by_stack_tainting_call_cached,tempcgpara);
+        paramanager.createtempparaloc(current_asmdata.CurrAsmList,aktcallnode.procdefinition.proccalloption,parasym,not followed_by_stack_tainting_call_cached,tempcgpara);
 
 
-             { handle varargs first, because parasym is not valid }
-             if (cpf_varargs_para in callparaflags) then
-               begin
-                 if paramanager.push_addr_param(vs_value,left.resultdef,
-                        aktcallnode.procdefinition.proccalloption) then
-                   push_addr_para
-                 else
-                   push_value_para;
-               end
-             { hidden parameters }
-             else if (vo_is_hidden_para in parasym.varoptions) then
-               begin
-                 { don't push a node that already generated a pointer type
-                   by address for implicit hidden parameters }
-                 pushaddr:=(vo_is_funcret in parasym.varoptions) or
-                   { pass "this" in C++ classes explicitly as pointer
-                     because push_addr_param might not be true for them }
-                   (is_cppclass(parasym.vardef) and (vo_is_self in parasym.varoptions)) or
-                    (
-                      (
-                        not(left.resultdef.typ in [pointerdef,classrefdef]) or
-                        (
-                          { allow pointerdefs (as self) to be passed as addr
-                            param if the method is part of a type helper which
-                            extends a pointer type }
-                          (vo_is_self in parasym.varoptions) and
-                          (aktcallnode.procdefinition.owner.symtabletype=objectsymtable) and
-                          (is_objectpascal_helper(tdef(aktcallnode.procdefinition.owner.defowner))) and
-                          (tobjectdef(aktcallnode.procdefinition.owner.defowner).extendeddef.typ=pointerdef)
-                        )
-                      ) and
-                     paramanager.push_addr_param(parasym.varspez,parasym.vardef,
-                         aktcallnode.procdefinition.proccalloption));
-
-                 if pushaddr then
+        { handle varargs first, because parasym is not valid }
+        if (cpf_varargs_para in callparaflags) then
+          begin
+            if paramanager.push_addr_param(vs_value,left.resultdef,
+                   aktcallnode.procdefinition.proccalloption) then
+              push_addr_para
+            else
+              push_value_para;
+          end
+        { hidden parameters }
+        else if (vo_is_hidden_para in parasym.varoptions) then
+          begin
+            { don't push a node that already generated a pointer type
+              by address for implicit hidden parameters }
+            pushaddr:=(vo_is_funcret in parasym.varoptions) or
+              { pass "this" in C++ classes explicitly as pointer
+                because push_addr_param might not be true for them }
+              (is_cppclass(parasym.vardef) and (vo_is_self in parasym.varoptions)) or
+               (
+                 (
+                   not(left.resultdef.typ in [pointerdef,classrefdef]) or
+                   (
+                     { allow pointerdefs (as self) to be passed as addr
+                       param if the method is part of a type helper which
+                       extends a pointer type }
+                     (vo_is_self in parasym.varoptions) and
+                     (aktcallnode.procdefinition.owner.symtabletype=objectsymtable) and
+                     (is_objectpascal_helper(tdef(aktcallnode.procdefinition.owner.defowner))) and
+                     (tobjectdef(aktcallnode.procdefinition.owner.defowner).extendeddef.typ=pointerdef)
+                   )
+                 ) and
+                paramanager.push_addr_param(parasym.varspez,parasym.vardef,
+                    aktcallnode.procdefinition.proccalloption));
+
+            if pushaddr then
+              begin
+                { objects or advanced records could be located in registers if they are the result of a type case, see e.g. webtbs\tw26075.pp }
+                if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
+                  hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
+                push_addr_para
+              end
+            else
+              push_value_para;
+          end
+        { formal def }
+        else if (parasym.vardef.typ=formaldef) then
+          push_formal_para
+        { Normal parameter }
+        else if paramanager.push_copyout_param(parasym.varspez,parasym.vardef,
+                    aktcallnode.procdefinition.proccalloption) then
+          push_copyout_para
+        else
+          begin
+            { don't push a node that already generated a pointer type
+              by address for implicit hidden parameters }
+            if (not(
+                    (vo_is_hidden_para in parasym.varoptions) and
+                    (left.resultdef.typ in [pointerdef,classrefdef])
+                   ) and
+                paramanager.push_addr_param(parasym.varspez,parasym.vardef,
+                    aktcallnode.procdefinition.proccalloption)) and
+                { dyn. arrays passed to an array of const must be passed by value, see tests/webtbs/tw4219.pp }
+                not(
+                    is_array_of_const(parasym.vardef) and
+                    is_dynamic_array(left.resultdef)
+                   ) then
+              begin
+                 { Passing a var parameter to a var parameter, we can
+                   just push the address transparently }
+                 if (left.nodetype=loadn) and
+                    (tloadnode(left).is_addr_param_load) then
                    begin
                    begin
-                     { objects or advanced records could be located in registers if they are the result of a type case, see e.g. webtbs\tw26075.pp }
-                     if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
-                       hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
-                     push_addr_para
+                     if (left.location.reference.index<>NR_NO) or
+                        (left.location.reference.offset<>0) then
+                       internalerror(200410107);
+                     hlcg.a_load_reg_cgpara(current_asmdata.CurrAsmList,cpointerdef.getreusable(left.resultdef),left.location.reference.base,tempcgpara)
                    end
                    end
                  else
                  else
-                   push_value_para;
-               end
-             { formal def }
-             else if (parasym.vardef.typ=formaldef) then
-               push_formal_para
-             { Normal parameter }
-             else if paramanager.push_copyout_param(parasym.varspez,parasym.vardef,
-                         aktcallnode.procdefinition.proccalloption) then
-               push_copyout_para
-             else
-               begin
-                 { don't push a node that already generated a pointer type
-                   by address for implicit hidden parameters }
-                 if (not(
-                         (vo_is_hidden_para in parasym.varoptions) and
-                         (left.resultdef.typ in [pointerdef,classrefdef])
-                        ) and
-                     paramanager.push_addr_param(parasym.varspez,parasym.vardef,
-                         aktcallnode.procdefinition.proccalloption)) and
-                     { dyn. arrays passed to an array of const must be passed by value, see tests/webtbs/tw4219.pp }
-                     not(
-                         is_array_of_const(parasym.vardef) and
-                         is_dynamic_array(left.resultdef)
-                        ) then
                    begin
                    begin
-                      { Passing a var parameter to a var parameter, we can
-                        just push the address transparently }
-                      if (left.nodetype=loadn) and
-                         (tloadnode(left).is_addr_param_load) then
-                        begin
-                          if (left.location.reference.index<>NR_NO) or
-                             (left.location.reference.offset<>0) then
-                            internalerror(200410107);
-                          hlcg.a_load_reg_cgpara(current_asmdata.CurrAsmList,cpointerdef.getreusable(left.resultdef),left.location.reference.base,tempcgpara)
-                        end
-                      else
-                        begin
-                          { Force to be in memory }
-                          if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
-                            hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
-                          push_addr_para;
-                        end;
-                   end
-                 else
-                   push_value_para;
-               end;
+                     { Force to be in memory }
+                     if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
+                       hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
+                     push_addr_para;
+                   end;
+              end
+            else
+              push_value_para;
+          end;
+
+        { update return location in callnode when this is the function
+          result }
+        if assigned(parasym) and
+           (
+             { for type helper/record constructor check that it is self parameter }
+             (
+               (vo_is_self in parasym.varoptions) and
+               (aktcallnode.procdefinition.proctypeoption=potype_constructor) and
+               (parasym.vardef.typ<>objectdef)
+             ) or
+             (vo_is_funcret in parasym.varoptions)
+           ) then
+          location_copy(aktcallnode.location,left.location);
+      end;
+
+
+    procedure tcgcallparanode.secondcallparan;
+      begin
+         if not(assigned(parasym)) then
+           internalerror(200304242);
 
 
-             { update return location in callnode when this is the function
-               result }
-             if assigned(parasym) and
-                (
-                  { for type helper/record constructor check that it is self parameter }
-                  (
-                    (vo_is_self in parasym.varoptions) and
-                    (aktcallnode.procdefinition.proctypeoption=potype_constructor) and
-                    (parasym.vardef.typ<>objectdef)
-                  ) or
-                  (vo_is_funcret in parasym.varoptions)
-                ) then
-               location_copy(aktcallnode.location,left.location);
+         { Skip nothingn nodes which are used after disabling
+           a parameter }
+         if (left.nodetype<>nothingn) then
+           begin
+             secondcallparan_do_secondpass;
+             secondcallparan_after_secondpass;
            end;
            end;
 
 
          { next parameter }
          { next parameter }

+ 4 - 1
compiler/ncgcon.pas

@@ -134,7 +134,10 @@ implementation
              { :-(, we must generate a new entry }
              { :-(, we must generate a new entry }
              if not(assigned(lab_real)) then
              if not(assigned(lab_real)) then
                begin
                begin
-                  current_asmdata.getlocaldatalabel(lastlabel);
+                  if create_smartlink_library then
+                    current_asmdata.getglobaldatalabel(lastlabel)
+                  else
+                    current_asmdata.getlocaldatalabel(lastlabel);
                   entry^.Data:=lastlabel;
                   entry^.Data:=lastlabel;
                   lab_real:=lastlabel;
                   lab_real:=lastlabel;
                   maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]);
                   maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]);

+ 4 - 0
compiler/ncgmem.pas

@@ -974,6 +974,10 @@ implementation
                    hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
                    hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
                    location_copy(location,left.location);
                    location_copy(location,left.location);
                  end;
                  end;
+               LOC_CONSTANT:  { Usually 'nil' }
+                 begin
+                   hlcg.reference_reset_base(location.reference,left.resultdef,NR_NO,left.location.value,ctempposinvalid,location.reference.alignment,[]);
+                 end;
                LOC_INVALID:
                LOC_INVALID:
                  Internalerror(2019061101);
                  Internalerror(2019061101);
                else
                else

+ 2 - 0
compiler/ncnv.pas

@@ -1048,7 +1048,9 @@ implementation
         i: ttypeconvnodeflag;
         i: ttypeconvnodeflag;
       begin
       begin
         inherited printnodeinfo(t);
         inherited printnodeinfo(t);
+        write(t,', totypedef = ',totypedef.GetTypeName);
         write(t,', convtype = ',convtype);
         write(t,', convtype = ',convtype);
+        write(t,', assignment_side = ',assignment_side);
         write(t,', convnodeflags = [');
         write(t,', convnodeflags = [');
         first:=true;
         first:=true;
         for i:=low(ttypeconvnodeflag) to high(ttypeconvnodeflag) do
         for i:=low(ttypeconvnodeflag) to high(ttypeconvnodeflag) do

+ 2 - 1
compiler/ogwasm.pas

@@ -6497,7 +6497,8 @@ implementation
             idtxt  : 'WASM';
             idtxt  : 'WASM';
             asmbin : '';
             asmbin : '';
             asmcmd : '';
             asmcmd : '';
-            supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+            supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,
+                                 system_wasm32_wasip2];
             flags : [af_outputbinary,af_smartlink_sections];
             flags : [af_outputbinary,af_smartlink_sections];
             labelprefix : '..@';
             labelprefix : '..@';
             labelmaxlen : -1;
             labelmaxlen : -1;

+ 4 - 1
compiler/options.pas

@@ -509,7 +509,7 @@ const
      begin
      begin
       if not abiinfo[abi].supported then
       if not abiinfo[abi].supported then
         continue;
         continue;
-      if abiinfo[abi].name<>'' then;
+      if abiinfo[abi].name<>'' then
         WriteLn(xmloutput,'      <abi name="',abiinfo[abi].name, '"/>');
         WriteLn(xmloutput,'      <abi name="',abiinfo[abi].name, '"/>');
      end;
      end;
     WriteLn(xmloutput,'    </abis>');
     WriteLn(xmloutput,'    </abis>');
@@ -4956,6 +4956,9 @@ begin
   if tf_x86_far_procs_push_odd_bp in target_info.flags then
   if tf_x86_far_procs_push_odd_bp in target_info.flags then
     if not UpdateTargetSwitchStr('FARPROCSPUSHODDBP', init_settings.targetswitches, true) then
     if not UpdateTargetSwitchStr('FARPROCSPUSHODDBP', init_settings.targetswitches, true) then
       InternalError(2013092802);
       InternalError(2013092802);
+  if tf_wasm_threads in target_info.flags then
+    if not UpdateTargetSwitchStr('WASMTHREADS', init_settings.targetswitches, true) then
+      InternalError(2025022701);
 
 
   { Use standard Android NDK prefixes when cross-compiling }
   { Use standard Android NDK prefixes when cross-compiling }
   if (source_info.system<>target_info.system) and (target_info.system in systems_android) then
   if (source_info.system<>target_info.system) and (target_info.system in systems_android) then

+ 3 - 1
compiler/parser.pas

@@ -199,7 +199,9 @@ implementation
                if heapsize=0 then
                if heapsize=0 then
                  heapsize:=65536;
                  heapsize:=65536;
              end;
              end;
-           system_wasm32_wasi:
+           system_wasm32_wasip1,
+           system_wasm32_wasip1threads,
+           system_wasm32_wasip2:
              begin
              begin
                if ts_wasm_threads in init_settings.targetswitches then
                if ts_wasm_threads in init_settings.targetswitches then
                  maxheapsize:=256*1024*1024
                  maxheapsize:=256*1024*1024

+ 6 - 1
compiler/rautils.pas

@@ -1781,7 +1781,12 @@ Begin
       begin
       begin
         if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
         if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
           begin
           begin
-            Tlabelsym(sym).nonlocal:=true;
+{$ifndef LLVM}
+	    { LLVM compiler requires that the static label RawThunkEnd
+             in packages/rtl-objpas/src/rtti.pp unit is set to nonlocal }
+            if (srsymtable.symtabletype=globalsymtable) or create_smartlink_library then
+{$endif LLVM}
+              Tlabelsym(sym).nonlocal:=true;
             if emit then
             if emit then
               include(current_procinfo.flags,pi_has_interproclabel);
               include(current_procinfo.flags,pi_has_interproclabel);
           end;
           end;

+ 2 - 1
compiler/riscv/aasmcpu.pas

@@ -571,7 +571,8 @@ uses cutils, cclasses;
 
 
           A_ADDIW,A_SLLIW,A_SRLIW,A_SRAIW,
           A_ADDIW,A_SLLIW,A_SRLIW,A_SRAIW,
           A_ADDW,A_SLLW,A_SRLW,A_SUBW,A_SRAW,
           A_ADDW,A_SLLW,A_SRLW,A_SUBW,A_SRAW,
-          A_LD,A_LWU:
+          A_LD,A_LWU,
+          A_ZEXT_B,A_ZEXT_H,A_ZEXT_W,A_SEXT_B,A_SEXT_H,A_SEXT_W:
             if opnr=0 then
             if opnr=0 then
               result:=operand_write
               result:=operand_write
             else
             else

+ 5 - 5
compiler/riscv/agrvgas.pas

@@ -231,14 +231,14 @@ unit agrvgas;
 
 
     function TRVGNUAssembler.MakeCmdLine: TCmdStr;
     function TRVGNUAssembler.MakeCmdLine: TCmdStr;
       const
       const
-        arch_str: array[boolean,tcputype] of string[10] = (
+        arch_str: array[boolean,tcputype] of string[18] = (
 {$ifdef RISCV32}
 {$ifdef RISCV32}
-          ('','rv32imac','rv32ima','rv32im','rv32i','rv32e','rv32imc','rv32imafdc','rv32imafd','rv32ec','rv32gc'),
-          ('','rv32imafdc','rv32imafd','rv32imfd','rv32ifd','rv32efd','rv32imcfd','rv32imafdc','rv32imafd','rv32ecfd','rv32gc')
+          ('','rv32imac','rv32ima','rv32im','rv32i','rv32e','rv32imc','rv32imafdc','rv32imafd','rv32ec','rv32gc','rv32gc_zba_zbb_zbs'),
+          ('','rv32imafdc','rv32imafd','rv32imfd','rv32ifd','rv32efd','rv32imcfd','rv32imafdc','rv32imafd','rv32ecfd','rv32gc','rv32gc_zba_zbb_zbs')
 {$endif RISCV32}
 {$endif RISCV32}
 {$ifdef RISCV64}
 {$ifdef RISCV64}
-          ('','rv64imac','rv64ima','rv64im','rv64i','rv64imafdc','rv64imafd','rv64gc'),
-          ('','rv64imafdc','rv64imafd','rv64imfd','rv64ifd','rv64imafdc','rv64imafd','rv64gc')
+          ('','rv64imac','rv64ima','rv64im','rv64i','rv64imafdc','rv64imafd','rv64gc','rv64gc_zba_zbb_zbs'),
+          ('','rv64imafdc','rv64imafd','rv64imfd','rv64ifd','rv64imafdc','rv64imafd','rv64gc','rv64gc_zba_zbb_zbs')
 {$endif RISCV64}
 {$endif RISCV64}
         );
         );
       begin
       begin

+ 199 - 125
compiler/riscv/aoptcpurv.pas

@@ -27,7 +27,9 @@ interface
 
 
 {$I fpcdefs.inc}
 {$I fpcdefs.inc}
 
 
-{ $define DEBUG_AOPTCPU}
+{$ifdef EXTDEBUG}
+{$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
 uses
 uses
   cpubase,
   cpubase,
@@ -46,14 +48,18 @@ type
     procedure DebugMsg(const s: string; p: tai);
     procedure DebugMsg(const s: string; p: tai);
 
 
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
+
     function OptPass1OP(var p: tai): boolean;
     function OptPass1OP(var p: tai): boolean;
     function OptPass1FOP(var p: tai;mvop: tasmop): boolean;
     function OptPass1FOP(var p: tai;mvop: tasmop): boolean;
     function OptPass1FSGNJ(var p: tai;mvop: tasmop): boolean;
     function OptPass1FSGNJ(var p: tai;mvop: tasmop): boolean;
     function OptPass1SLTx(var p: tai): boolean;
     function OptPass1SLTx(var p: tai): boolean;
     function OptPass1SLTI(var p: tai): boolean;
     function OptPass1SLTI(var p: tai): boolean;
-
+    function OptPass1Andi(var p: tai): boolean;
+    function OptPass1SLTIU(var p: tai): boolean;
+    function OptPass1SxxI(var p: tai): boolean;
     function OptPass1Add(var p: tai): boolean;
     function OptPass1Add(var p: tai): boolean;
     function OptPass1Sub(var p: tai): boolean;
     function OptPass1Sub(var p: tai): boolean;
+
     procedure RemoveInstr(var orig: tai; moveback: boolean=true);
     procedure RemoveInstr(var orig: tai; moveback: boolean=true);
   end;
   end;
 
 
@@ -335,6 +341,7 @@ implementation
           dealloc x
           dealloc x
         To
         To
           addi z, y, #+#
           addi z, y, #+#
+          dealloc x
       }
       }
       else if (taicpu(p).ops=3) and
       else if (taicpu(p).ops=3) and
          (taicpu(p).oper[2]^.typ=top_const) and
          (taicpu(p).oper[2]^.typ=top_const) and
@@ -347,6 +354,7 @@ implementation
          (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
          (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
          RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
          RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
         begin
         begin
+          AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs);
           taicpu(hp1).loadreg(1,taicpu(p).oper[1]^.reg);
           taicpu(hp1).loadreg(1,taicpu(p).oper[1]^.reg);
           taicpu(hp1).loadconst(2, taicpu(p).oper[2]^.val+taicpu(hp1).oper[2]^.val);
           taicpu(hp1).loadconst(2, taicpu(p).oper[2]^.val+taicpu(hp1).oper[2]^.val);
 
 
@@ -431,7 +439,7 @@ implementation
          GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
          GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
          ((MatchInstruction(hp1, [A_SUB,A_ADD,A_SLL,A_SRL,A_SLT,A_AND,A_OR,
          ((MatchInstruction(hp1, [A_SUB,A_ADD,A_SLL,A_SRL,A_SLT,A_AND,A_OR,
             A_ADDI,A_ANDI,A_ORI,A_SRAI,A_SRLI,A_SLLI,A_XORI,A_MUL,
             A_ADDI,A_ANDI,A_ORI,A_SRAI,A_SRLI,A_SLLI,A_XORI,A_MUL,
-            A_DIV,A_DIVU,A_REM,A_REMU
+            A_DIV,A_DIVU,A_REM,A_REMU,A_SLTI,A_SLTIU
             {$ifdef riscv64},A_ADDIW,A_SLLIW,A_SRLIW,A_SRAIW,
             {$ifdef riscv64},A_ADDIW,A_SLLIW,A_SRLIW,A_SRAIW,
             A_ADDW,A_SLLW,A_SRLW,A_SUBW,A_SRAW,
             A_ADDW,A_SLLW,A_SRLW,A_SUBW,A_SRAW,
             A_DIVUW,A_DIVW,A_REMW,A_REMUW{$endif}]
             A_DIVUW,A_DIVW,A_REMW,A_REMUW{$endif}]
@@ -617,32 +625,198 @@ implementation
       if (taicpu(p).ops=3) and
       if (taicpu(p).ops=3) and
          (taicpu(p).oper[2]^.typ=top_const) and
          (taicpu(p).oper[2]^.typ=top_const) and
          (taicpu(p).oper[2]^.val=0) and
          (taicpu(p).oper[2]^.val=0) and
-         GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
-         (hp1.typ=ait_instruction) and
-         (taicpu(hp1).opcode=A_Bxx) and
-         (taicpu(hp1).ops=3) and
-         (taicpu(hp1).oper[0]^.typ=top_reg) and
-         (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
-         (taicpu(hp1).oper[1]^.typ=top_reg) and
-         (taicpu(hp1).oper[1]^.reg=NR_X0) and
-         (taicpu(hp1).condition in [C_NE,C_EQ]) and
-         (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
-         RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
+         GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then
         begin
         begin
-          taicpu(hp1).loadreg(0,taicpu(p).oper[1]^.reg);
-          taicpu(hp1).loadreg(1,NR_X0);
+{
+           we cannot do this optimization yet as we don't know if taicpu(p).oper[0]^.reg isn't used after taking the branch
+
+          if MatchInstruction(hp1,A_Bxx) and
+            (taicpu(hp1).ops=3) and
+            (taicpu(hp1).oper[0]^.typ=top_reg) and
+            (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
+            (taicpu(hp1).oper[1]^.typ=top_reg) and
+            (taicpu(hp1).oper[1]^.reg=NR_X0) and
+            (taicpu(hp1).condition in [C_NE,C_EQ]) and
+            (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
+            RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
+            begin
+              taicpu(hp1).loadreg(0,taicpu(p).oper[1]^.reg);
+              taicpu(hp1).loadreg(1,NR_X0);
+
+              if taicpu(hp1).condition=C_NE then
+                taicpu(hp1).condition:=C_LT
+              else
+                taicpu(hp1).condition:=C_GE;
+
+              DebugMsg('Peephole Slti0B2B performed', hp1);
+
+              RemoveInstr(p);
+
+              result:=true;
+              exit;
+            end
+          else } if MatchInstruction(hp1,A_ANDI) and
+            (taicpu(hp1).ops=3) and
+            (taicpu(hp1).oper[2]^.val>0) and
+            MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[0]^) and
+            (not RegModifiedBetween(taicpu(hp1).oper[0]^.reg, p,hp1)) then
+            begin
+              DebugMsg('Peephole SltiAndi2Slti performed', hp1);
+
+              AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs);
+
+              taicpu(p).loadreg(0,taicpu(hp1).oper[0]^.reg);
+              RemoveInstr(hp1);
+
+              result:=true;
+              exit;
+            end;
+        end;
+      { in all other branches we exit before }
+      result:=OptPass1OP(p);
+    end;
+
+
+  function TRVCpuAsmOptimizer.OptPass1Andi(var p: tai): boolean;
+    var
+      hp1: tai;
+    begin
+      result:=false;
+      {
+        Changes
+          andi x, y, #
+          andi z, x, #
+          dealloc x
+        To
+          andi z, y, # and #
+      }
+      if (taicpu(p).ops=3) and
+         (taicpu(p).oper[2]^.typ=top_const) and
+         GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then
+        begin
+          if MatchInstruction(hp1,A_ANDI) and
+            (taicpu(hp1).ops=3) and
+            MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) and
+            (taicpu(hp1).oper[2]^.typ=top_const) and
+            is_imm12(taicpu(p).oper[2]^.val and taicpu(hp1).oper[2]^.val) and
+            (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
+            RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
+            begin
+              taicpu(hp1).loadreg(1,taicpu(p).oper[1]^.reg);
+              taicpu(hp1).loadconst(2, taicpu(p).oper[2]^.val and taicpu(hp1).oper[2]^.val);
 
 
-          if taicpu(hp1).condition=C_NE then
-            taicpu(hp1).condition:=C_LT
+              DebugMsg('Peephole AndiAndi2Andi performed', hp1);
+
+              RemoveInstr(p);
+
+              result:=true;
+            end
+{$ifndef RISCV32}
+          else if MatchInstruction(hp1,A_ADDIW) and
+            (taicpu(hp1).ops=3) and
+            MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) and
+            (taicpu(hp1).oper[2]^.typ=top_const) and
+            (taicpu(hp1).oper[2]^.val=0) and
+             is_imm12(taicpu(p).oper[2]^.val) and
+            (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
+            RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
+            begin
+              taicpu(p).loadreg(0,taicpu(hp1).oper[0]^.reg);
+
+              DebugMsg('Peephole AndiAddwi02Andi performed', hp1);
+
+              RemoveInstr(hp1);
+
+              result:=true;
+             end
+{$endif RISCV32}
           else
           else
-            taicpu(hp1).condition:=C_GE;
+            result:=OptPass1OP(p);
+        end
+      else
+        result:=OptPass1OP(p);
+    end;
 
 
-          DebugMsg('Peephole Slti0B2B performed', hp1);
 
 
-          RemoveInstr(p);
+  function TRVCpuAsmOptimizer.OptPass1SLTIU(var p: tai): boolean;
+    var
+      hp1: tai;
+    begin
+      result:=false;
+      {
+        Turn
+          sltiu x,y,1
+          beq/ne x,x0,...
+          dealloc x
+        Into
+          bne y,x0,...
+      }
+      if (taicpu(p).ops=3) and
+         (taicpu(p).oper[2]^.typ=top_const) and
+         (taicpu(p).oper[2]^.val=1) and
+         GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then
+         begin
+{
+           we cannot do this optimization yet as we don't know if taicpu(p).oper[0]^.reg isn't used after taking the branch
+
+           if MatchInstruction(hp1,A_Bxx,[C_NE,C_EQ]) and
+             (taicpu(hp1).ops=3) and
+             MatchOperand(taicpu(hp1).oper[0]^,taicpu(p).oper[0]^) and
+             MatchOperand(taicpu(hp1).oper[1]^,NR_X0) and
+             (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
+             RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
+             begin
+               taicpu(hp1).loadreg(0,taicpu(p).oper[1]^.reg);
+               taicpu(hp1).condition:=inverse_cond(taicpu(hp1).condition);
+
+               DebugMsg('Peephole Sltiu0B2B performed', hp1);
+
+               RemoveInstr(p);
+
+               result:=true;
+               exit;
+             end
+           else } if MatchInstruction(hp1,A_ANDI) and
+             (taicpu(hp1).ops=3) and
+             (taicpu(hp1).oper[2]^.val>0) and
+             MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[0]^) and
+             (not RegModifiedBetween(taicpu(hp1).oper[0]^.reg, p,hp1)) then
+             begin
+               DebugMsg('Peephole SltiuAndi2Sltiu performed', hp1);
+
+               AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs);
+
+               taicpu(p).loadreg(0,taicpu(hp1).oper[0]^.reg);
+               RemoveInstr(hp1);
+
+               result:=true;
+               exit;
+             end;
+         end;
+      { in all other branches we exit before }
+      result:=OptPass1OP(p);
+    end;
+
 
 
+  function TRVCpuAsmOptimizer.OptPass1SxxI(var p: tai): boolean;
+    begin
+      result:=false;
+      if (taicpu(p).oper[2]^.val=0) and
+        MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) then
+        begin
+          DebugMsg('Peephole S*LI x,x,0 to nop performed', p);
+          RemoveInstr(p);
           result:=true;
           result:=true;
-        end;
+        end
+      else if (taicpu(p).oper[2]^.val=0) then
+        begin
+          { this enables further optimizations }
+          DebugMsg('Peephole S*LI x,y,0 to addi performed', p);
+          taicpu(p).opcode:=A_ADDI;
+          result:=true;
+        end
+      else
+        result:=OptPass1OP(p);
     end;
     end;
 
 
 
 
@@ -660,95 +834,12 @@ implementation
               A_SUB:
               A_SUB:
                 result:=OptPass1Sub(p);
                 result:=OptPass1Sub(p);
               A_ANDI:
               A_ANDI:
-                begin
-                  {
-                    Changes
-                      andi x, y, #
-                      andi z, x, #
-                      dealloc x
-                    To
-                      andi z, y, # and #
-                  }
-                  if (taicpu(p).ops=3) and
-                     (taicpu(p).oper[2]^.typ=top_const) and
-                     GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then
-                    begin
-                      if MatchInstruction(hp1,A_ANDI) and
-                        (taicpu(hp1).ops=3) and
-                        MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) and
-                        (taicpu(hp1).oper[2]^.typ=top_const) and
-                        is_imm12(taicpu(p).oper[2]^.val and taicpu(hp1).oper[2]^.val) and
-                        (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
-                        RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
-                        begin
-                          taicpu(hp1).loadreg(1,taicpu(p).oper[1]^.reg);
-                          taicpu(hp1).loadconst(2, taicpu(p).oper[2]^.val and taicpu(hp1).oper[2]^.val);
-
-                          DebugMsg('Peephole AndiAndi2Andi performed', hp1);
-
-                          RemoveInstr(p);
-
-                          result:=true;
-                        end
-{$ifndef RISCV32}
-                      else if MatchInstruction(hp1,A_ADDIW) and
-                        (taicpu(hp1).ops=3) and
-                        MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) and
-                        (taicpu(hp1).oper[2]^.typ=top_const) and
-                        (taicpu(hp1).oper[2]^.val=0) and
-                         is_imm12(taicpu(p).oper[2]^.val) and
-                        (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
-                        RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
-                        begin
-                          taicpu(p).loadreg(0,taicpu(hp1).oper[0]^.reg);
-
-                          DebugMsg('Peephole AndiAddwi02Andi performed', hp1);
-
-                          RemoveInstr(hp1);
-
-                          result:=true;
-                         end
-{$endif RISCV32}
-                      else
-                        result:=OptPass1OP(p);
-                    end
-                  else
-                    result:=OptPass1OP(p);
-                end;
+                result:=OptPass1Andi(p);
               A_SLT,
               A_SLT,
               A_SLTU:
               A_SLTU:
                 result:=OptPass1SLTx(p);
                 result:=OptPass1SLTx(p);
               A_SLTIU:
               A_SLTIU:
-                begin
-                  {
-                    Turn
-                      sltiu x,y,1
-                      beq/ne x,x0,...
-                      dealloc x
-                    Into
-                      bne y,x0,...
-                  }
-                  if (taicpu(p).ops=3) and
-                     (taicpu(p).oper[2]^.typ=top_const) and
-                     (taicpu(p).oper[2]^.val=1) and
-                     GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
-                     MatchInstruction(hp1,A_Bxx,[C_NE,C_EQ]) and
-                     (taicpu(hp1).ops=3) and
-                     MatchOperand(taicpu(hp1).oper[0]^,taicpu(p).oper[0]^) and
-                     MatchOperand(taicpu(hp1).oper[1]^,NR_X0) and
-                     (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p,hp1)) and
-                     RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
-                    begin
-                      taicpu(hp1).loadreg(0,taicpu(p).oper[1]^.reg);
-                      taicpu(hp1).condition:=inverse_cond(taicpu(hp1).condition);
-
-                      DebugMsg('Peephole Sltiu0B2B performed', hp1);
-
-                      RemoveInstr(p);
-
-                      result:=true;
-                    end;
-                end;
+                result:=OptPass1SLTIU(p);
               A_LA,
               A_LA,
               A_LUI,
               A_LUI,
               A_LB,
               A_LB,
@@ -806,24 +897,7 @@ implementation
               A_SRAI,
               A_SRAI,
               A_SRLI,
               A_SRLI,
               A_SLLI:
               A_SLLI:
-                begin
-                  if (taicpu(p).oper[2]^.val=0) and
-                    MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) then
-                    begin
-                      DebugMsg('Peephole S*LI x,x,0 to nop performed', p);
-                      RemoveInstr(p);
-                      result:=true;
-                    end
-                  else if (taicpu(p).oper[2]^.val=0) then
-                    begin
-                      { this enables further optimizations }
-                      DebugMsg('Peephole S*LI x,y,0 to addi performed', p);
-                      taicpu(p).opcode:=A_ADDI;
-                      result:=true;
-                    end
-                  else
-                    result:=OptPass1OP(p);
-                end;
+                result:=OptPass1SxxI(p);
               A_SLTI:
               A_SLTI:
                 result:=OptPass1SLTI(p);
                 result:=OptPass1SLTI(p);
               A_FADD_S,
               A_FADD_S,

+ 1 - 1
compiler/riscv/nrvutil.pas

@@ -90,7 +90,7 @@ implementation
           if CPURV_HAS_ZICOND in cpu_capabilities[current_settings.cputype] then
           if CPURV_HAS_ZICOND in cpu_capabilities[current_settings.cputype] then
             attr_arch:=attr_arch+'_zicond1p0';
             attr_arch:=attr_arch+'_zicond1p0';
           if CPURV_HAS_CSR_INSTRUCTIONS in cpu_capabilities[current_settings.cputype] then
           if CPURV_HAS_CSR_INSTRUCTIONS in cpu_capabilities[current_settings.cputype] then
-            attr_arch:=attr_arch+'_zicrs2p0';
+            attr_arch:=attr_arch+'_zicsr2p0';
           if CPURV_HAS_FETCH_FENCE in cpu_capabilities[current_settings.cputype] then
           if CPURV_HAS_FETCH_FENCE in cpu_capabilities[current_settings.cputype] then
             attr_arch:=attr_arch+'_zifencei2p0';
             attr_arch:=attr_arch+'_zifencei2p0';
           if CPURV_HAS_ZMMUL in cpu_capabilities[current_settings.cputype] then
           if CPURV_HAS_ZMMUL in cpu_capabilities[current_settings.cputype] then

+ 2 - 0
compiler/riscv32/cgcpu.pas

@@ -125,6 +125,8 @@ unit cgcpu;
             list.concat(ai);
             list.concat(ai);
             rg[R_INTREGISTER].add_move_instruction(ai);
             rg[R_INTREGISTER].add_move_instruction(ai);
           end
           end
+        else if (CPURV_HAS_ZBB in cpu_capabilities[current_settings.cputype]) and (tcgsize2unsigned[tosize]=OS_32) and (fromsize=OS_S8) then
+          list.Concat(taicpu.op_reg_reg(A_SEXT_B,reg2,reg1))
         else if (tcgsize2unsigned[tosize]=OS_32) and (fromsize=OS_8) then
         else if (tcgsize2unsigned[tosize]=OS_32) and (fromsize=OS_8) then
           list.Concat(taicpu.op_reg_reg_const(A_ANDI,reg2,reg1,$FF))
           list.Concat(taicpu.op_reg_reg_const(A_ANDI,reg2,reg1,$FF))
         else if (tosize=OS_8) and (fromsize<>OS_8) then
         else if (tosize=OS_8) and (fromsize<>OS_8) then

+ 6 - 3
compiler/riscv32/cpuinfo.pas

@@ -44,7 +44,8 @@ Type
        cpu_rv32imafdc,
        cpu_rv32imafdc,
        cpu_rv32imafd,
        cpu_rv32imafd,
        cpu_rv32ec,
        cpu_rv32ec,
-       cpu_rv32gc
+       cpu_rv32gc,
+       cpu_rv32gcb
       );
       );
 
 
    tfputype =
    tfputype =
@@ -178,7 +179,8 @@ Const
      'RV32IMAFDC',
      'RV32IMAFDC',
      'RV32IMAFD',
      'RV32IMAFD',
      'RV32EC',
      'RV32EC',
-     'RV32GC'
+     'RV32GC',
+     'RV32GCB'
    );
    );
 
 
    fputypestr : array[tfputype] of string[8] = (         
    fputypestr : array[tfputype] of string[8] = (         
@@ -241,7 +243,8 @@ Const
        { cpu_rv32imafdc} [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_F,CPURV_HAS_D],
        { cpu_rv32imafdc} [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_F,CPURV_HAS_D],
        { cpu_rv32imafd } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_F,CPURV_HAS_D],
        { cpu_rv32imafd } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_F,CPURV_HAS_D],
        { cpu_rv32ec    } [CPURV_HAS_16REGISTERS,CPURV_HAS_COMPACT],
        { cpu_rv32ec    } [CPURV_HAS_16REGISTERS,CPURV_HAS_COMPACT],
-       { cpu_rv32gc    } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_F,CPURV_HAS_D]
+       { cpu_rv32gc    } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_F,CPURV_HAS_D],
+       { cpu_rv32gc    } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_F,CPURV_HAS_D,CPURV_HAS_ZBA,CPURV_HAS_ZBB,CPURV_HAS_ZBS]
      );
      );
 
 
 Implementation
 Implementation

+ 3 - 1
compiler/riscv64/aoptcpu.pas

@@ -27,7 +27,9 @@ interface
 
 
 {$I fpcdefs.inc}
 {$I fpcdefs.inc}
 
 
-{ $define DEBUG_AOPTCPU}
+{$ifdef EXTDEBUG}
+{$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
 uses
 uses
   cpubase,
   cpubase,

+ 6 - 0
compiler/riscv64/cgcpu.pas

@@ -102,6 +102,12 @@ implementation
           list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0))
           list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0))
         else if (tosize=OS_S32) and (tcgsize2unsigned[fromsize]=OS_64) then
         else if (tosize=OS_S32) and (tcgsize2unsigned[fromsize]=OS_64) then
           list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0))
           list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0))
+        else if (CPURV_HAS_ZBA in cpu_capabilities[current_settings.cputype]) and (tosize=OS_32) and (tcgsize2unsigned[fromsize]=OS_64) then
+          list.Concat(taicpu.op_reg_reg(A_ZEXT_W,reg2,reg1))
+        else if (CPURV_HAS_ZBB in cpu_capabilities[current_settings.cputype]) and (tcgsize2unsigned[tosize]=OS_64) and (fromsize=OS_S8) then
+          list.Concat(taicpu.op_reg_reg(A_SEXT_B,reg2,reg1))
+        else if (CPURV_HAS_ZBB in cpu_capabilities[current_settings.cputype]) and (tosize=OS_S8) and (tcgsize2unsigned[fromsize]=OS_64) then
+          list.Concat(taicpu.op_reg_reg(A_SEXT_B,reg2,reg1))
         else if (CPURV_HAS_ZBB in cpu_capabilities[current_settings.cputype]) and (tcgsize2unsigned[tosize]=OS_64) and (fromsize=OS_S16) then
         else if (CPURV_HAS_ZBB in cpu_capabilities[current_settings.cputype]) and (tcgsize2unsigned[tosize]=OS_64) and (fromsize=OS_S16) then
           list.Concat(taicpu.op_reg_reg(A_SEXT_H,reg2,reg1))
           list.Concat(taicpu.op_reg_reg(A_SEXT_H,reg2,reg1))
         else if (CPURV_HAS_ZBB in cpu_capabilities[current_settings.cputype]) and (tosize=OS_S16) and (tcgsize2unsigned[fromsize]=OS_64) then
         else if (CPURV_HAS_ZBB in cpu_capabilities[current_settings.cputype]) and (tosize=OS_S16) and (tcgsize2unsigned[fromsize]=OS_64) then

+ 6 - 3
compiler/riscv64/cpuinfo.pas

@@ -40,7 +40,8 @@ type
     cpu_rv64i,
     cpu_rv64i,
     cpu_rv64imafdc,
     cpu_rv64imafdc,
     cpu_rv64imafd,
     cpu_rv64imafd,
-    cpu_rv64gc
+    cpu_rv64gc,
+    cpu_rv64gcb
   );
   );
 
 
   tfputype =
   tfputype =
@@ -96,7 +97,8 @@ Const
     'RV64I',
     'RV64I',
     'RV64IMAFDC',
     'RV64IMAFDC',
     'RV64IMAFD',
     'RV64IMAFD',
-    'RV64GC'
+    'RV64GC',
+    'RV64GCB'
     );
     );
 
 
   fputypestr: array[tfputype] of string[8] = (
   fputypestr: array[tfputype] of string[8] = (
@@ -157,7 +159,8 @@ Const
        { cpu_rv64i      } [],
        { cpu_rv64i      } [],
        { cpu_rv64imafdc } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_F,CPURV_HAS_D],
        { cpu_rv64imafdc } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_F,CPURV_HAS_D],
        { cpu_rv64imafd  } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_F,CPURV_HAS_D],
        { cpu_rv64imafd  } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_F,CPURV_HAS_D],
-       { cpu_rv64gc     } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_CSR_INSTRUCTIONS,CPURV_HAS_FETCH_FENCE,CPURV_HAS_F,CPURV_HAS_D]
+       { cpu_rv64gc     } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_CSR_INSTRUCTIONS,CPURV_HAS_FETCH_FENCE,CPURV_HAS_F,CPURV_HAS_D],
+       { cpu_rv64gcb    } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT,CPURV_HAS_CSR_INSTRUCTIONS,CPURV_HAS_FETCH_FENCE,CPURV_HAS_F,CPURV_HAS_D,CPURV_HAS_ZBA,CPURV_HAS_ZBB,CPURV_HAS_ZBS]
      );
      );
 
 
 implementation
 implementation

+ 3 - 1
compiler/sparcgen/aoptcpu.pas

@@ -25,7 +25,9 @@ unit aoptcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
-{ $define DEBUG_AOPTCPU}
+{$ifdef EXTDEBUG}
+{$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
   Interface
   Interface
 
 

+ 13 - 4
compiler/symcreat.pas

@@ -1229,8 +1229,13 @@ implementation
     end;
     end;
 
 
   function get_method_paramtype(vardef  : Tdef; asPointer : Boolean; out isAnonymousArrayDef : Boolean) : ansistring; forward;
   function get_method_paramtype(vardef  : Tdef; asPointer : Boolean; out isAnonymousArrayDef : Boolean) : ansistring; forward;
-  function str_parse_method(str: ansistring): tprocdef; forward;
 
 
+  function str_parse_method(str: ansistring; allowgenericid : boolean): tprocdef; forward;
+
+  function str_parse_method(str: ansistring): tprocdef;
+  begin
+     Result:=str_parse_method(str,false);
+  end;
 
 
   procedure implement_invoke_helper(cn : string;pd: tprocdef; idx : integer);
   procedure implement_invoke_helper(cn : string;pd: tprocdef; idx : integer);
 
 
@@ -1299,7 +1304,7 @@ implementation
         end;
         end;
       str:=str+');'#10;
       str:=str+');'#10;
       str:=str+'end;'#10;
       str:=str+'end;'#10;
-      pd.invoke_helper:=str_parse_method(str);
+      pd.invoke_helper:=str_parse_method(str,true);
   end;
   end;
 
 
   procedure add_synthetic_method_implementations_for_st(st: tsymtable);
   procedure add_synthetic_method_implementations_for_st(st: tsymtable);
@@ -1638,11 +1643,12 @@ implementation
     objdef.hiddenclassdef:=def;
     objdef.hiddenclassdef:=def;
   end;
   end;
 
 
-  function str_parse_method(str: ansistring): tprocdef;
+  function str_parse_method(str: ansistring; allowgenericid : boolean): tprocdef;
    var
    var
      oldparse_only: boolean;
      oldparse_only: boolean;
      tmpstr: ansistring;
      tmpstr: ansistring;
      flags : tread_proc_flags;
      flags : tread_proc_flags;
+     oldallow : boolean;
 
 
    begin
    begin
     Message1(parser_d_internal_parser_string,str);
     Message1(parser_d_internal_parser_string,str);
@@ -1652,6 +1658,8 @@ implementation
     str:=str+'const;';
     str:=str+'const;';
     block_type:=bt_none;
     block_type:=bt_none;
     { inject the string in the scanner }
     { inject the string in the scanner }
+    oldallow:=current_scanner.allowgenericid;
+    current_scanner.allowgenericid:=allowgenericid;
     current_scanner.substitutemacro('hidden_interface_method',@str[1],length(str),current_scanner.line_no,current_scanner.inputfile.ref_index,true);
     current_scanner.substitutemacro('hidden_interface_method',@str[1],length(str),current_scanner.line_no,current_scanner.inputfile.ref_index,true);
     current_scanner.readtoken(false);
     current_scanner.readtoken(false);
     Result:=read_proc([],Nil);
     Result:=read_proc([],Nil);
@@ -1660,6 +1668,7 @@ implementation
     current_scanner.closeinputfile;
     current_scanner.closeinputfile;
     current_scanner.nextfile;
     current_scanner.nextfile;
     current_scanner.tempopeninputfile;
     current_scanner.tempopeninputfile;
+    current_scanner.allowgenericid:=oldallow;
    end;
    end;
 
 
 
 
@@ -1744,7 +1753,7 @@ implementation
     if HaveResult then
     if HaveResult then
       str:=str+'  Result:=res;'#10;
       str:=str+'  Result:=res;'#10;
     str:=str+'end;'#10;
     str:=str+'end;'#10;
-    pd:=str_parse_method(str);
+    pd:=str_parse_method(str,true);
   end;
   end;
 
 
   procedure implement_thunkclass_interfacevmtoffset(cn : shortstring; objdef : tobjectdef; offs : integer);
   procedure implement_thunkclass_interfacevmtoffset(cn : shortstring; objdef : tobjectdef; offs : integer);

+ 4 - 2
compiler/systems.inc

@@ -206,7 +206,7 @@
              system_aarch64_darwin,     { 111 }
              system_aarch64_darwin,     { 111 }
              system_z80_amstradcpc,     { 112 }
              system_z80_amstradcpc,     { 112 }
              system_m68k_sinclairql,    { 113 }
              system_m68k_sinclairql,    { 113 }
-             system_wasm32_wasi,        { 114 }
+             system_wasm32_wasip1,      { 114 }
              system_aarch64_freebsd,    { 115 }
              system_aarch64_freebsd,    { 115 }
              system_aarch64_embedded,   { 116 }
              system_aarch64_embedded,   { 116 }
              system_mips64_linux,       { 117 }
              system_mips64_linux,       { 117 }
@@ -215,7 +215,9 @@
              system_loongarch64_linux,  { 120 }
              system_loongarch64_linux,  { 120 }
              system_aarch64_iphonesim,  { 121 }
              system_aarch64_iphonesim,  { 121 }
              system_m68k_human68k,      { 122 }
              system_m68k_human68k,      { 122 }
-             system_mipsel_ps1          { 123 }
+             system_mipsel_ps1,         { 123 }
+             system_wasm32_wasip1threads,{ 124 }
+             system_wasm32_wasip2       { 125 }
        );
        );
 
 
      type
      type

+ 12 - 10
compiler/systems.pas

@@ -181,15 +181,16 @@ interface
             { units are initialized by direct calls and not table driven,
             { units are initialized by direct calls and not table driven,
               in particular for a small amount of units, this results in smaller
               in particular for a small amount of units, this results in smaller
               executables }
               executables }
-            tf_init_final_units_by_calls
+            tf_init_final_units_by_calls,
+            { indicates that the default value of the ts_wasm_threads target switch is 'on' for this target }
+            tf_wasm_threads
        );
        );
-
        psysteminfo = ^tsysteminfo;
        psysteminfo = ^tsysteminfo;
        { using packed causes bus errors on processors which require alignment }
        { using packed causes bus errors on processors which require alignment }
        tsysteminfo = record
        tsysteminfo = record
           system       : tsystem;
           system       : tsystem;
-          name         : string[39];
-          shortname    : string[12];
+          name         : string[88];
+          shortname    : string[14];
           flags        : set of tsystemflags;
           flags        : set of tsystemflags;
           cpu          : tsystemcpu;
           cpu          : tsystemcpu;
           unit_env     : string[16];
           unit_env     : string[16];
@@ -296,7 +297,8 @@ interface
        systems_darwin = systems_ios + systems_iphonesim + systems_macosx;
        systems_darwin = systems_ios + systems_iphonesim + systems_macosx;
 
 
        { all WebAssembly systems }
        { all WebAssembly systems }
-       systems_wasm = [system_wasm32_embedded,system_wasm32_wasi];
+       systems_wasm = [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,
+                       system_wasm32_wasip2];
 
 
        {all solaris systems }
        {all solaris systems }
        systems_solaris = [system_sparc_solaris, system_i386_solaris,
        systems_solaris = [system_sparc_solaris, system_i386_solaris,
@@ -398,8 +400,8 @@ interface
                                    system_riscv32_linux,system_riscv64_linux,
                                    system_riscv32_linux,system_riscv64_linux,
                                    system_aarch64_win64,
                                    system_aarch64_win64,
                                    system_z80_zxspectrum,system_z80_msxdos,
                                    system_z80_zxspectrum,system_z80_msxdos,
-                                   system_wasm32_wasi,system_loongarch64_linux,
-                                   system_mipsel_ps1
+                                   system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2,
+                                   system_loongarch64_linux,system_mipsel_ps1
                                   ]+systems_darwin+systems_amigalike;
                                   ]+systems_darwin+systems_amigalike;
 
 
        { all systems that use the PE+ header in the PE/COFF file
        { all systems that use the PE+ header in the PE/COFF file
@@ -557,8 +559,8 @@ interface
        target_res  : tresinfo;
        target_res  : tresinfo;
        target_dbg  : tdbginfo;
        target_dbg  : tdbginfo;
        target_cpu_string,
        target_cpu_string,
-       target_os_string   : string[12]; { for rtl/<X>/,fcl/<X>/, etc. }
-       target_full_string : string[24];
+       target_os_string   : string[14]; { for rtl/<X>/,fcl/<X>/, etc. }
+       target_full_string : string[28];
 
 
     function set_target(t:tsystem):boolean;
     function set_target(t:tsystem):boolean;
     function set_target_asm(t:tasm):boolean;
     function set_target_asm(t:tasm):boolean;
@@ -1182,7 +1184,7 @@ begin
 {$endif aarch64}
 {$endif aarch64}
 
 
 {$ifdef wasm32}
 {$ifdef wasm32}
-  default_target(system_wasm32_wasi);
+  default_target(system_wasm32_wasip1);
 {$endif wasm32}
 {$endif wasm32}
 
 
 {$ifdef z80}
 {$ifdef z80}

+ 160 - 9
compiler/systems/i_wasi.pas

@@ -29,19 +29,164 @@ unit i_wasi;
        systems,rescmn;
        systems,rescmn;
 
 
     const
     const
-        system_wasm32_wasi_info : tsysteminfo =
+        system_wasm32_wasip1_info : tsysteminfo =
           (
           (
-            system       : system_wasm32_wasi;
-            name         : 'The WebAssembly System Interface (WASI)';
-            shortname    : 'Wasi';
+            system       : system_wasm32_wasip1;
+            name         : 'The WebAssembly System Interface Preview 1 (WASI 0.1)';
+            shortname    : 'Wasip1';
+            flags        : [tf_needs_symbol_size,tf_needs_symbol_type,
+                            tf_files_case_sensitive,tf_no_pic_supported,
+                            tf_smartlink_sections,tf_has_winlike_resources,
+                            { avoid the creation of threadvar tables }
+                            tf_section_threadvars];
+            cpu          : cpu_wasm32;
+            unit_env     : '';
+            extradefines : 'WASI';
+            exeext       : '.wasm';
+            defext       : '.def';
+            scriptext    : '.sh';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.wat';
+            objext       : '.o';
+            resext       : '';
+            resobjext    : '.or';
+            sharedlibext : ''; // keep it empty! The sharedlibext drives the export module name
+                               // if this is populated, then the name should be cleared when generating import
+            staticlibext : '.a';
+            staticlibprefix : '';
+            sharedlibprefix : '';
+            sharedClibext : '.wasm';
+            staticClibext : '.wasm';
+            staticClibprefix : '';
+            sharedClibprefix : '';
+            importlibprefix : '';
+            importlibext : '.wasm';
+            Cprefix      : '';
+            newline      : #10;
+            dirsep       : '/';
+            assem        : as_wasm32_wasm;
+            assemextern  : as_wasm32_llvm_mc;
+            link         : ld_int_wasi;
+            linkextern   : ld_wasi;
+            ar           : ar_none;
+            res          : res_wasm;
+            dbg          : dbg_dwarf2;
+            script       : script_unix;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 0;
+                loopalign       : 0;
+                jumpalign       : 0;
+                jumpalignskipmax    : 0;
+                coalescealign   : 0;
+                coalescealignskipmax: 0;
+                constalignmin   : 4;
+                constalignmax   : 16;
+                varalignmin     : 4;
+                varalignmax     : 16;
+                localalignmin   : 4;
+                localalignmax   : 16;
+                recordalignmin  : 0;
+                recordalignmax  : 16;
+                maxCrecordalign : 16
+              );
+            first_parm_offset : 0;
+            stacksize   : 8*1024*1024;
+            stackalign   : 16;
+            abi          : abi_default;
+            llvmdatalayout : 'todo';
+          );
+
+
+        system_wasm32_wasip1threads_info : tsysteminfo =
+          (
+            system       : system_wasm32_wasip1threads;
+            name         : 'The WebAssembly System Interface Preview 1 with Multithreading (WASI 0.1 + wasi-threads)';
+            shortname    : 'Wasip1threads';
+            flags        : [tf_needs_symbol_size,tf_needs_symbol_type,
+                            tf_files_case_sensitive,tf_no_pic_supported,
+                            tf_smartlink_sections,tf_has_winlike_resources,
+                            { avoid the creation of threadvar tables }
+                            tf_section_threadvars,
+                            tf_wasm_threads];
+            cpu          : cpu_wasm32;
+            unit_env     : '';
+            extradefines : 'WASI;WASIP1';
+            exeext       : '.wasm';
+            defext       : '.def';
+            scriptext    : '.sh';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.wat';
+            objext       : '.o';
+            resext       : '';
+            resobjext    : '.or';
+            sharedlibext : ''; // keep it empty! The sharedlibext drives the export module name
+                               // if this is populated, then the name should be cleared when generating import
+            staticlibext : '.a';
+            staticlibprefix : '';
+            sharedlibprefix : '';
+            sharedClibext : '.wasm';
+            staticClibext : '.wasm';
+            staticClibprefix : '';
+            sharedClibprefix : '';
+            importlibprefix : '';
+            importlibext : '.wasm';
+            Cprefix      : '';
+            newline      : #10;
+            dirsep       : '/';
+            assem        : as_wasm32_wasm;
+            assemextern  : as_wasm32_llvm_mc;
+            link         : ld_int_wasi;
+            linkextern   : ld_wasi;
+            ar           : ar_none;
+            res          : res_wasm;
+            dbg          : dbg_dwarf2;
+            script       : script_unix;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 0;
+                loopalign       : 0;
+                jumpalign       : 0;
+                jumpalignskipmax    : 0;
+                coalescealign   : 0;
+                coalescealignskipmax: 0;
+                constalignmin   : 4;
+                constalignmax   : 16;
+                varalignmin     : 4;
+                varalignmax     : 16;
+                localalignmin   : 4;
+                localalignmax   : 16;
+                recordalignmin  : 0;
+                recordalignmax  : 16;
+                maxCrecordalign : 16
+              );
+            first_parm_offset : 0;
+            stacksize   : 8*1024*1024;
+            stackalign   : 16;
+            abi          : abi_default;
+            llvmdatalayout : 'todo';
+          );
+
+
+        system_wasm32_wasip2_info : tsysteminfo =
+          (
+            system       : system_wasm32_wasip2;
+            name         : 'The WebAssembly System Interface Preview 2 (WASI 0.2)';
+            shortname    : 'Wasip2';
             flags        : [tf_under_development,tf_needs_symbol_size,tf_needs_symbol_type,
             flags        : [tf_under_development,tf_needs_symbol_size,tf_needs_symbol_type,
-                            tf_files_case_sensitive,
+                            tf_files_case_sensitive,tf_no_pic_supported,
                             tf_smartlink_sections,tf_has_winlike_resources,
                             tf_smartlink_sections,tf_has_winlike_resources,
                             { avoid the creation of threadvar tables }
                             { avoid the creation of threadvar tables }
                             tf_section_threadvars];
                             tf_section_threadvars];
             cpu          : cpu_wasm32;
             cpu          : cpu_wasm32;
             unit_env     : '';
             unit_env     : '';
-            extradefines : '';
+            extradefines : 'WASI';
             exeext       : '.wasm';
             exeext       : '.wasm';
             defext       : '.def';
             defext       : '.def';
             scriptext    : '.sh';
             scriptext    : '.sh';
@@ -105,8 +250,14 @@ unit i_wasi;
 
 
 initialization
 initialization
 {$ifdef CPUWASM32}
 {$ifdef CPUWASM32}
-  {$ifdef wasi}
-    set_source_info(system_wasm32_wasi_info);
-  {$endif wasi}
+  {$ifdef wasip1}
+    set_source_info(system_wasm32_wasip1_info);
+  {$endif wasip1}
+  {$ifdef wasip1threads}
+    set_source_info(system_wasm32_wasip1threads_info);
+  {$endif wasip1threads}
+  {$ifdef wasip2}
+    set_source_info(system_wasm32_wasip2_info);
+  {$endif wasip1}
 {$endif CPUWASM32}
 {$endif CPUWASM32}
 end.
 end.

+ 4 - 1
compiler/systems/t_bsd.pas

@@ -468,7 +468,10 @@ begin
 
 
   if target_info.system=system_i386_freebsd then
   if target_info.system=system_i386_freebsd then
     begin
     begin
-      targetstr:='-b elf32-i386-freebsd';
+      if cs_link_lld in current_settings.globalswitches then
+        targetstr:='-b elf'
+      else
+        targetstr:='-b elf32-i386-freebsd';
       emulstr:='-m elf_i386_fbsd';
       emulstr:='-m elf_i386_fbsd';
     end
     end
   else
   else

+ 11 - 4
compiler/systems/t_darwin.pas

@@ -111,7 +111,14 @@ implementation
 
 
 
 
     procedure tlinkerdarwin.SetDefaultInfo;
     procedure tlinkerdarwin.SetDefaultInfo;
+      var
+        LdProgram : string;
       begin
       begin
+        if cs_link_lld in current_settings.globalswitches then
+          LdProgram:='ld64.lld'
+        else
+          LdProgram:='ld';
+
         with Info do
         with Info do
          begin
          begin
   {$ifndef cpu64bitaddr}
   {$ifndef cpu64bitaddr}
@@ -129,16 +136,16 @@ implementation
              programs with problems that require Valgrind will have more
              programs with problems that require Valgrind will have more
              than 60KB of data (first 4KB of address space is always invalid)
              than 60KB of data (first 4KB of address space is always invalid)
            }
            }
-           ExeCmd[1]:='ld $PRTOBJ $TARGET $OPT $STATIC $GCSECTIONS $STRIP $MAP $LTO $ORDERSYMS $RPATH -L. -o $EXE $ARCH $VERSION $SYSROOT $LIBSEARCHPATH $FILELIST $LIBRARIES';
+           ExeCmd[1]:=LdProgram+' $PRTOBJ $TARGET $OPT $STATIC $GCSECTIONS $STRIP $MAP $LTO $ORDERSYMS $RPATH -L. -o $EXE $ARCH $VERSION $SYSROOT $LIBSEARCHPATH $FILELIST $LIBRARIES';
            if not(cs_gdb_valgrind in current_settings.globalswitches) then
            if not(cs_gdb_valgrind in current_settings.globalswitches) then
              ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
              ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';
   {$else ndef cpu64bitaddr}
   {$else ndef cpu64bitaddr}
-           ExeCmd[1]:='ld $PRTOBJ $TARGET $OPT $STATIC $GCSECTIONS $STRIP $MAP $LTO $ORDERSYMS $RPATH -L. -o $EXE $ARCH $VERSION $SYSROOT $LIBSEARCHPATH $FILELIST $LIBRARIES';
+           ExeCmd[1]:=LdProgram+' $PRTOBJ $TARGET $OPT $STATIC $GCSECTIONS $STRIP $MAP $LTO $ORDERSYMS $RPATH -L. -o $EXE $ARCH $VERSION $SYSROOT $LIBSEARCHPATH $FILELIST $LIBRARIES';
   {$endif ndef cpu64bitaddr}
   {$endif ndef cpu64bitaddr}
            if (apptype<>app_bundle) then
            if (apptype<>app_bundle) then
-             DllCmd[1]:='ld $PRTOBJ $TARGET $OPT $GCSECTIONS $MAP $LTO $ORDERSYMS $RPATH -dynamic -dylib -L. -o $EXE $ARCH $VERSION $SYSROOT $LIBSEARCHPATH $FILELIST $LIBRARIES'
+             DllCmd[1]:=LdProgram+' $PRTOBJ $TARGET $OPT $GCSECTIONS $MAP $LTO $ORDERSYMS $RPATH -dynamic -dylib -L. -o $EXE $ARCH $VERSION $SYSROOT $LIBSEARCHPATH $FILELIST $LIBRARIES'
            else
            else
-             DllCmd[1]:='ld $PRTOBJ $TARGET $OPT $GCSECTIONS $MAP $LTO $ORDERSYMS $RPATH -dynamic -bundle -L. -o $EXE $ARCH $VERSION $SYRSROOT $LIBSEARCHPATH $FILELIST $LIBRARIES';
+             DllCmd[1]:=LdProgram+' $PRTOBJ $TARGET $OPT $GCSECTIONS $MAP $LTO $ORDERSYMS $RPATH -dynamic -bundle -L. -o $EXE $ARCH $VERSION $SYRSROOT $LIBSEARCHPATH $FILELIST $LIBRARIES';
            DllCmd[2]:='strip -x $EXE';
            DllCmd[2]:='strip -x $EXE';
            DynamicLinker:='';
            DynamicLinker:='';
          end;
          end;

+ 1 - 2
compiler/systems/t_msdos.pas

@@ -449,8 +449,7 @@ begin
   BlockWrite(f,maxalloc,2);
   BlockWrite(f,maxalloc,2);
   close(f);
   close(f);
   {$pop}
   {$pop}
-  if ioresult<>0 then;
-    Result:=true;
+  Result:=ioresult=0;
 end;
 end;
 
 
 {****************************************************************************
 {****************************************************************************

+ 9 - 3
compiler/systems/t_wasi.pas

@@ -395,9 +395,15 @@ begin
 end;
 end;
 
 
 initialization
 initialization
-  RegisterTarget(system_wasm32_wasi_info);
-  RegisterImport(system_wasm32_wasi, timportlibwasi);
-  RegisterExport(system_wasm32_wasi, texportlibwasi);
+  RegisterTarget(system_wasm32_wasip1_info);
+  RegisterImport(system_wasm32_wasip1, timportlibwasi);
+  RegisterExport(system_wasm32_wasip1, texportlibwasi);
+  RegisterTarget(system_wasm32_wasip1threads_info);
+  RegisterImport(system_wasm32_wasip1threads, timportlibwasi);
+  RegisterExport(system_wasm32_wasip1threads, texportlibwasi);
+  RegisterTarget(system_wasm32_wasip2_info);
+  RegisterImport(system_wasm32_wasip2, timportlibwasi);
+  RegisterExport(system_wasm32_wasip2, texportlibwasi);
   RegisterLinker(ld_int_wasi,TInternalLinkerWasi);
   RegisterLinker(ld_int_wasi,TInternalLinkerWasi);
   RegisterLinker(ld_wasi, tlinkerwasi);
   RegisterLinker(ld_wasi, tlinkerwasi);
   RegisterRes(res_wasm_info,TWinLikeResourceFile);
   RegisterRes(res_wasm_info,TWinLikeResourceFile);

+ 1 - 1
compiler/systems/t_win.pas

@@ -1797,7 +1797,7 @@ implementation
         freemem(zerobuf,maxfillsize);
         freemem(zerobuf,maxfillsize);
         close(f);
         close(f);
         {$pop}
         {$pop}
-        if ioresult<>0 then;
+        if ioresult<>0 then
           postprocessexecutable:=true;
           postprocessexecutable:=true;
       end;
       end;
 
 

+ 43 - 7
compiler/utils/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -663,7 +663,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins
 override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins
 override TARGET_PROGRAMS+=fpc ppufiles ppudump ppumove mka64ins mkarmins mkx86ins msg2inc mkx86inl mkz80ins
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1002,7 +1008,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override CLEAN_UNITS+=ppu crc
 override CLEAN_UNITS+=ppu crc
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override CLEAN_UNITS+=ppu crc
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override CLEAN_UNITS+=ppu crc
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override CLEAN_UNITS+=ppu crc
 override CLEAN_UNITS+=ppu crc
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1342,7 +1354,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_UNITDIR+=..
 override COMPILER_UNITDIR+=..
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_UNITDIR+=..
 override COMPILER_UNITDIR+=..
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1681,7 +1699,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_SOURCEDIR+=..
 override COMPILER_SOURCEDIR+=..
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_SOURCEDIR+=..
 override COMPILER_SOURCEDIR+=..
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2258,7 +2282,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2810,7 +2840,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)

+ 3 - 0
compiler/utils/msg2inc.pp

@@ -28,6 +28,9 @@ program msg2inc;
 {$ifdef macos}
 {$ifdef macos}
   {$define EOL_ONE_CHAR}
   {$define EOL_ONE_CHAR}
 {$endif}
 {$endif}
+{$ifdef wasi}
+  {$define EOL_ONE_CHAR}
+{$endif}
 
 
 const
 const
   version='1.00';
   version='1.00';

+ 7 - 4
compiler/utils/ppuutils/ppudump.pp

@@ -240,7 +240,7 @@ const
   { 111 } 'Darwin-AArch64',
   { 111 } 'Darwin-AArch64',
   { 112 } 'AmstradCPC-Z80',
   { 112 } 'AmstradCPC-Z80',
   { 113 } 'SinclairQL-m68k',
   { 113 } 'SinclairQL-m68k',
-  { 114 } 'WASI-WASM32',
+  { 114 } 'WASIp1-WASM32',
   { 115 } 'FreeBSD-AArch64',
   { 115 } 'FreeBSD-AArch64',
   { 116 } 'Embedded-aarch64',
   { 116 } 'Embedded-aarch64',
   { 117 } 'Linux-MIPS64',
   { 117 } 'Linux-MIPS64',
@@ -249,7 +249,9 @@ const
   { 120 } 'Linux-LoongArch64',
   { 120 } 'Linux-LoongArch64',
   { 121 } 'iPhoneSim-AArch64',
   { 121 } 'iPhoneSim-AArch64',
   { 122 } 'Human68k-m68k',
   { 122 } 'Human68k-m68k',
-  { 123 } 'PS1-mipsel'
+  { 123 } 'PS1-mipsel',
+  { 124 } 'WASIp1threads-WASM32',
+  { 125 } 'WASIp2-WASM32'
   );
   );
 
 
 const
 const
@@ -2239,7 +2241,7 @@ var
        end; *)
        end; *)
 
 
 const
 const
-    targetswitchname : array[ttargetswitch] of string[37] =
+    targetswitchname : array[ttargetswitch] of string[77] =
        { global target-specific switches }
        { global target-specific switches }
        ('Target None', {ts_none}
        ('Target None', {ts_none}
          { generate code that results in smaller TOCs than normal (AIX) }
          { generate code that results in smaller TOCs than normal (AIX) }
@@ -2285,7 +2287,8 @@ const
         'Branchful exceptions support', {ts_wasm_bf_exceptions}
         'Branchful exceptions support', {ts_wasm_bf_exceptions}
         'JavaScript-based exception support', {ts_wasm_js_exceptions}
         'JavaScript-based exception support', {ts_wasm_js_exceptions}
         'Native WebAssembly exceptions support', {ts_wasm_native_exceptions}
         'Native WebAssembly exceptions support', {ts_wasm_native_exceptions}
-        'WebAssembly threads support' {ts_wasm_threads}
+        'WebAssembly threads support', {ts_wasm_threads}
+        'Use WebAssembly saturating (nontrapping) float to int conversion instructions' {ts_wasm_saturating_float_to_int}
        );
        );
     moduleswitchname : array[tmoduleswitch] of string[40] =
     moduleswitchname : array[tmoduleswitch] of string[40] =
        ('Module None', {cs_modulenone,}
        ('Module None', {cs_modulenone,}

+ 1 - 1
compiler/wasm32/agbinaryen.pas

@@ -590,7 +590,7 @@ implementation
          idtxt  : 'BINARYEN';
          idtxt  : 'BINARYEN';
          asmbin : 'wasm-as';
          asmbin : 'wasm-as';
          asmcmd : '$ASM $EXTRAOPT';
          asmcmd : '$ASM $EXTRAOPT';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [];
          flags : [];
          labelprefix : 'L';
          labelprefix : 'L';
          labelmaxlen : -1;
          labelmaxlen : -1;

+ 9 - 9
compiler/wasm32/agllvmmc.pas

@@ -438,7 +438,7 @@ implementation
          idtxt  : 'LLVM-MC-10';
          idtxt  : 'LLVM-MC-10';
          asmbin : 'llvm-mc-10';
          asmbin : 'llvm-mc-10';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics --filetype=obj -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics --filetype=obj -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;
@@ -451,7 +451,7 @@ implementation
          idtxt  : 'LLVM-MC-11';
          idtxt  : 'LLVM-MC-11';
          asmbin : 'llvm-mc-11';
          asmbin : 'llvm-mc-11';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;
@@ -464,7 +464,7 @@ implementation
          idtxt  : 'LLVM-MC-12';
          idtxt  : 'LLVM-MC-12';
          asmbin : 'llvm-mc-12';
          asmbin : 'llvm-mc-12';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;
@@ -489,7 +489,7 @@ implementation
          idtxt  : 'LLVM-MC-13';
          idtxt  : 'LLVM-MC-13';
          asmbin : 'llvm-mc-13';
          asmbin : 'llvm-mc-13';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;
@@ -506,7 +506,7 @@ implementation
          idtxt  : 'LLVM-MC-14';
          idtxt  : 'LLVM-MC-14';
          asmbin : 'llvm-mc-14';
          asmbin : 'llvm-mc-14';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;
@@ -525,7 +525,7 @@ implementation
          idtxt  : 'LLVM-MC-15';
          idtxt  : 'LLVM-MC-15';
          asmbin : 'llvm-mc-15';
          asmbin : 'llvm-mc-15';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;
@@ -541,7 +541,7 @@ implementation
          idtxt  : 'LLVM-MC-16';
          idtxt  : 'LLVM-MC-16';
          asmbin : 'llvm-mc-16';
          asmbin : 'llvm-mc-16';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;
@@ -561,7 +561,7 @@ implementation
          idtxt  : 'LLVM-MC-17';
          idtxt  : 'LLVM-MC-17';
          asmbin : 'llvm-mc-17';
          asmbin : 'llvm-mc-17';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;
@@ -577,7 +577,7 @@ implementation
          idtxt  : 'LLVM-MC';
          idtxt  : 'LLVM-MC';
          asmbin : 'llvm-mc';
          asmbin : 'llvm-mc';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [af_smartlink_sections];
          flags : [af_smartlink_sections];
          labelprefix : '.L';
          labelprefix : '.L';
          labelmaxlen : -1;
          labelmaxlen : -1;

+ 1 - 1
compiler/wasm32/agwasa.pas

@@ -1094,7 +1094,7 @@ implementation
          idtxt  : 'WASA';
          idtxt  : 'WASA';
          asmbin : 'wasa';
          asmbin : 'wasa';
          asmcmd : '-r --no-canonicalize-leb128s -o $OBJ $EXTRAOPT $ASM';
          asmcmd : '-r --no-canonicalize-leb128s -o $OBJ $EXTRAOPT $ASM';
-         supported_targets : [system_wasm32_embedded,system_wasm32_wasi];
+         supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
          flags : [];
          flags : [];
          labelprefix : 'L';
          labelprefix : 'L';
          labelmaxlen : -1;
          labelmaxlen : -1;

+ 8 - 4
compiler/wasm32/cpupi.pas

@@ -714,10 +714,14 @@ implementation
                 asmlist.Remove(hp);
                 asmlist.Remove(hp);
                 if hp.typ=ait_label then
                 if hp.typ=ait_label then
                   begin
                   begin
-                    curr_block:=TAsmList.Create;
-                    blocks.Add(tai_label(hp).labsym.Name,curr_block);
-                  end;
-                curr_block.Concat(hp);
+                    if (tai_label(hp).labsym.is_used) then
+                      begin
+                        curr_block:=TAsmList.Create;
+                        blocks.Add(tai_label(hp).labsym.Name,curr_block);
+                      end;
+                  end
+                else
+                  curr_block.Concat(hp);
               end;
               end;
           until not assigned(hp);
           until not assigned(hp);
           { asmlist is now empty }
           { asmlist is now empty }

+ 1 - 1
compiler/wasm32/hlcgcpu.pas

@@ -1452,7 +1452,7 @@ implementation
       extra_slots:=prepare_stack_for_ref(list,tmpref,false);
       extra_slots:=prepare_stack_for_ref(list,tmpref,false);
       a_load_ref_stack(list,fromsize,tmpref,extra_slots);
       a_load_ref_stack(list,fromsize,tmpref,extra_slots);
 
 
-      if def2regtyp(fromsize)=R_INTREGISTER then
+      if def2regtyp(fromsize) in [R_INTREGISTER,R_ADDRESSREGISTER] then
         resize_stack_int_val(list,fromsize,tosize,false);
         resize_stack_int_val(list,fromsize,tosize,false);
       a_load_stack_reg(list,tosize,register);
       a_load_stack_reg(list,tosize,register);
     end;
     end;

+ 45 - 0
compiler/wasm32/nwasmcal.pas

@@ -34,6 +34,11 @@ interface
        { twasmcallparanode }
        { twasmcallparanode }
 
 
        twasmcallparanode = class(tcgcallparanode)
        twasmcallparanode = class(tcgcallparanode)
+       private
+         procedure secondpass_all;
+         procedure push_all;
+       public
+         procedure secondcallparan;override;
        end;
        end;
 
 
        { twasmcallnode }
        { twasmcallnode }
@@ -52,6 +57,46 @@ implementation
     uses
     uses
       globals, globtype, verbose, aasmdata, defutil, tgobj, hlcgcpu, symconst, symsym, symcpu;
       globals, globtype, verbose, aasmdata, defutil, tgobj, hlcgcpu, symconst, symsym, symcpu;
 
 
+      { twasmcallparanode }
+
+        procedure twasmcallparanode.secondpass_all;
+          begin
+            { Skip nothingn nodes which are used after disabling
+              a parameter }
+            if (left.nodetype<>nothingn) then
+              secondcallparan_do_secondpass;
+
+            { next parameter }
+            if assigned(right) then
+              twasmcallparanode(right).secondpass_all;
+          end;
+
+        procedure twasmcallparanode.push_all;
+          begin
+            { Skip nothingn nodes which are used after disabling
+              a parameter }
+            if (left.nodetype<>nothingn) then
+              secondcallparan_after_secondpass;
+
+            { next parameter }
+            if assigned(right) then
+              twasmcallparanode(right).push_all;
+          end;
+
+        procedure twasmcallparanode.secondcallparan;
+          begin
+            if not(assigned(parasym)) then
+              internalerror(200304242);
+
+            { On WebAssembly we generate code for evaluating all the parameters
+              first, and then we push them only after we've evaluated them all.
+              This is because the evaluation phase can generate labels, which
+              wreaks havoc in our 'goto' label resolution algorithm, when there
+              are labels at different stack heights. }
+            secondpass_all;
+            push_all;
+          end;
+
       { twasmcallnode }
       { twasmcallnode }
 
 
     function twasmcallnode.pass_typecheck:tnode;
     function twasmcallnode.pass_typecheck:tnode;

+ 17 - 4
compiler/wasm32/nwasminl.pas

@@ -73,6 +73,7 @@ interface
 implementation
 implementation
 
 
     uses
     uses
+      globtype,globals,
       procinfo,
       procinfo,
       ninl,ncal,compinnr,
       ninl,ncal,compinnr,
       aasmbase,aasmdata,aasmcpu,
       aasmbase,aasmdata,aasmcpu,
@@ -203,9 +204,15 @@ implementation
 
 
         case left.location.size of
         case left.location.size of
           OS_F32:
           OS_F32:
-            current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f32_s));
+            if ts_wasm_saturating_float_to_int in current_settings.targetswitches then
+              current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_sat_f32_s))
+            else
+              current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f32_s));
           OS_F64:
           OS_F64:
-            current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f64_s));
+            if ts_wasm_saturating_float_to_int in current_settings.targetswitches then
+              current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_sat_f64_s))
+            else
+              current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f64_s));
           else
           else
             internalerror(2021092904);
             internalerror(2021092904);
         end;
         end;
@@ -227,12 +234,18 @@ implementation
           OS_F32:
           OS_F32:
             begin
             begin
               current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f32_nearest));
               current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f32_nearest));
-              current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f32_s));
+              if ts_wasm_saturating_float_to_int in current_settings.targetswitches then
+                current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_sat_f32_s))
+              else
+                current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f32_s));
             end;
             end;
           OS_F64:
           OS_F64:
             begin
             begin
               current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f64_nearest));
               current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f64_nearest));
-              current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f64_s));
+              if ts_wasm_saturating_float_to_int in current_settings.targetswitches then
+                current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_sat_f64_s))
+              else
+                current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f64_s));
             end
             end
           else
           else
             internalerror(2021092905);
             internalerror(2021092905);

+ 0 - 2
compiler/wasm32/nwasmset.pas

@@ -105,8 +105,6 @@ implementation
                   _Label := endlabel;
                   _Label := endlabel;
                   Exit;
                   Exit;
                 end;
                 end;
-              goton:
-                InternalError(2021011801);
               blockn:
               blockn:
                 begin
                 begin
                   Block := TBlockNode(Block).Left;
                   Block := TBlockNode(Block).Left;

+ 124 - 95
compiler/x86/aoptx86.pas

@@ -4369,6 +4369,13 @@ unit aoptx86;
                               begin
                               begin
                                 taicpu(hp2).loadreg(0, p_SourceReg);
                                 taicpu(hp2).loadreg(0, p_SourceReg);
 
 
+                                TransferUsedRegs(TmpUsedRegs);
+                                UpdateUsedRegsBetween(TmpUsedRegs, tai(p.Next), hp1);
+                                { Make sure the register is allocated between these instructions
+                                  even though it doesn't change value, since it may cause
+                                  optimisations on a later pass to behave incorrectly. (Fixes #41155) }
+                                AllocRegBetween(p_SourceReg, hp1, hp2, TmpUsedRegs);
+
                                 DebugMsg(SPeepholeOptimization + 'Optimised register duplication and memory read (MovMovMov2MovMovMov)', p);
                                 DebugMsg(SPeepholeOptimization + 'Optimised register duplication and memory read (MovMovMov2MovMovMov)', p);
                                 Result := True;
                                 Result := True;
                                 if taicpu(hp2).oper[1]^.reg = p_TargetReg then
                                 if taicpu(hp2).oper[1]^.reg = p_TargetReg then
@@ -4379,11 +4386,6 @@ unit aoptx86;
                                   end
                                   end
                                 else
                                 else
                                   begin
                                   begin
-                                    { Check to see if %reg2 is no longer in use }
-                                    TransferUsedRegs(TmpUsedRegs);
-                                    UpdateUsedRegsBetween(TmpUsedRegs, tai(p.Next), hp1);
-                                    UpdateUsedRegsBetween(TmpUsedRegs, tai(hp1.Next), hp2);
-
                                     if not RegUsedAfterInstruction(p_TargetReg, hp2, TmpUsedRegs) then
                                     if not RegUsedAfterInstruction(p_TargetReg, hp2, TmpUsedRegs) then
                                       begin
                                       begin
                                         DebugMsg(SPeepholeOptimization + 'Mov2Nop 5b done', p);
                                         DebugMsg(SPeepholeOptimization + 'Mov2Nop 5b done', p);
@@ -6423,7 +6425,12 @@ unit aoptx86;
                       (
                       (
                         { Don't optimise if size is a concern and the intermediate register remains in use }
                         { Don't optimise if size is a concern and the intermediate register remains in use }
                         IntermediateRegDiscarded or
                         IntermediateRegDiscarded or
-                        not (cs_opt_size in current_settings.optimizerswitches)
+                        (
+                          not (cs_opt_size in current_settings.optimizerswitches) and
+                          { If the intermediate register is not discarded, it must not
+                            appear in the first LEA's reference.  (Fixes #41166) }
+                          not RegInRef(taicpu(p).oper[1]^.reg, taicpu(p).oper[0]^.ref^)
+                        )
                       ) and
                       ) and
                       (taicpu(hp1).oper[0]^.ref^.index = taicpu(p).oper[1]^.reg) and
                       (taicpu(hp1).oper[0]^.ref^.index = taicpu(p).oper[1]^.reg) and
                       (
                       (
@@ -6520,7 +6527,12 @@ unit aoptx86;
                     if (
                     if (
                         { Don't optimise if size is a concern and the intermediate register remains in use }
                         { Don't optimise if size is a concern and the intermediate register remains in use }
                         IntermediateRegDiscarded or
                         IntermediateRegDiscarded or
-                        not (cs_opt_size in current_settings.optimizerswitches)
+                        (
+                          not (cs_opt_size in current_settings.optimizerswitches) and
+                          { If the intermediate register is not discarded, it must not
+                            appear in the first LEA's reference.  (Fixes #41166) }
+                          not RegInRef(taicpu(p).oper[1]^.reg, taicpu(p).oper[0]^.ref^)
+                        )
                       ) and
                       ) and
                       (
                       (
                         (
                         (
@@ -15552,6 +15564,7 @@ unit aoptx86;
         NewRef: TReference;
         NewRef: TReference;
         Distance: Cardinal;
         Distance: Cardinal;
         TempTracking: TAllUsedRegs;
         TempTracking: TAllUsedRegs;
+        DoAddMov2Lea: Boolean;
 
 
         { This entire nested function is used in an if-statement below, but we
         { This entire nested function is used in an if-statement below, but we
           want to avoid all the used reg transfers and GetNextInstruction calls
           want to avoid all the used reg transfers and GetNextInstruction calls
@@ -15561,10 +15574,11 @@ unit aoptx86;
             hp2: tai;
             hp2: tai;
           begin
           begin
             TransferUsedRegs(TmpUsedRegs);
             TransferUsedRegs(TmpUsedRegs);
-            hp2 := p;
-            repeat
-              UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next));
-            until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+            if (cs_opt_level3 in current_settings.optimizerswitches) then
+              UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
+            else
+              { p and hp1 will be adjacent }
+              UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
 
 
             Result := not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs);
             Result := not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs);
           end;
           end;
@@ -15613,31 +15627,28 @@ unit aoptx86;
               begin
               begin
                 { Update the register tracking to the MOV instruction }
                 { Update the register tracking to the MOV instruction }
                 CopyUsedRegs(TempTracking);
                 CopyUsedRegs(TempTracking);
-                hp2 := p;
-                repeat
-                  UpdateUsedRegs(tai(hp2.Next));
-                until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+                if (cs_opt_level3 in current_settings.optimizerswitches) then
+                  UpdateUsedRegsBetween(UsedRegs, p, hp1)
+                else
+                  { p and hp1 will be adjacent }
+                  UpdateUsedRegs(UsedRegs, tai(p.Next));
+
+                hp2 := hp1;
+                if OptPass2MOV(hp1) then
+                  Include(OptsToCheck, aoc_ForceNewIteration);
+
+                { Reset the tracking to the current instruction }
+                RestoreUsedRegs(TempTracking);
+                ReleaseUsedRegs(TempTracking);
 
 
                 { if hp1 <> hp2 after the call, then hp1 got removed, so let
                 { if hp1 <> hp2 after the call, then hp1 got removed, so let
                   OptPass2ADD get called again }
                   OptPass2ADD get called again }
-                if OptPass2MOV(hp1) and (hp1 <> hp2) then
-                  begin
-                    { Reset the tracking to the current instruction }
-                    RestoreUsedRegs(TempTracking);
-                    ReleaseUsedRegs(TempTracking);
 
 
+                if (hp1 <> hp2) then
+                  begin
                     Result := True;
                     Result := True;
                     Exit;
                     Exit;
                   end;
                   end;
-
-                { Reset the tracking to the current instruction }
-                RestoreUsedRegs(TempTracking);
-                ReleaseUsedRegs(TempTracking);
-
-                { If OptPass2MOV returned True, we don't need to set Result to
-                  True if hp1 didn't change because the ADD instruction didn't
-                  get modified and we'll be evaluating hp1 again when the
-                  peephole optimizer reaches it }
               end;
               end;
 
 
             { Change:
             { Change:
@@ -15726,22 +15737,34 @@ unit aoptx86;
               (
               (
                 { Instructions are guaranteed to be adjacent on -O2 and under }
                 { Instructions are guaranteed to be adjacent on -O2 and under }
                 not (cs_opt_level3 in current_settings.optimizerswitches) or
                 not (cs_opt_level3 in current_settings.optimizerswitches) or
-                not RegUsedBetween(taicpu(hp1).oper[1]^.reg, p, hp1)
+                (
+                  { If the flags are used, don't make the optimisation,
+                    otherwise they will be scrambled.  Fixes #41148 }
+                  (
+                    not RegInUsedRegs(NR_DEFAULTFLAGS, UsedRegs) or
+                    not RegUsedBetween(NR_DEFAULTFLAGS, p, hp1)
+                  ) and
+                  not RegUsedBetween(taicpu(hp1).oper[1]^.reg, p, hp1)
+                )
               ) then
               ) then
               begin
               begin
                 TransferUsedRegs(TmpUsedRegs);
                 TransferUsedRegs(TmpUsedRegs);
-                hp2 := p;
-                repeat
-                  UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next));
-                until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+                if (cs_opt_level3 in current_settings.optimizerswitches) then
+                  UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
+                else
+                  { p and hp1 will be adjacent }
+                  UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
 
 
                 if (
                 if (
+                    SetAndTest(
+                      (
+                        not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
+                        not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
+                      ),
+                      DoAddMov2Lea
+                    ) or
                     { Don't do AddMov2LeaAdd under -Os, but do allow AddMov2Lea }
                     { Don't do AddMov2LeaAdd under -Os, but do allow AddMov2Lea }
-                    not (cs_opt_size in current_settings.optimizerswitches) or
-                    (
-                      not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
-                      not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
-                    )
+                    not (cs_opt_size in current_settings.optimizerswitches)
                   ) then
                   ) then
                   begin
                   begin
                     { Change the MOV instruction to a LEA instruction, and update the
                     { Change the MOV instruction to a LEA instruction, and update the
@@ -15755,8 +15778,18 @@ unit aoptx86;
                     taicpu(hp1).opcode := A_LEA;
                     taicpu(hp1).opcode := A_LEA;
                     taicpu(hp1).loadref(0, NewRef);
                     taicpu(hp1).loadref(0, NewRef);
 
 
-                    if RegUsedAfterInstruction(NewRef.base, hp1, TmpUsedRegs) or
-                      RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) then
+                    if DoAddMov2Lea then
+                      begin
+                        { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
+                        DebugMsg(SPeepholeOptimization + 'AddMov2Lea', hp1);
+
+                        if (cs_opt_level3 in current_settings.optimizerswitches) then
+                          { hp1 may not be the immediate next instruction under -O3 }
+                          RemoveCurrentp(p)
+                        else
+                          RemoveCurrentp(p, hp1);
+                      end
+                    else
                       begin
                       begin
                         hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween }
                         hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween }
 
 
@@ -15767,17 +15800,6 @@ unit aoptx86;
 
 
                         DebugMsg(SPeepholeOptimization + 'AddMov2LeaAdd', p);
                         DebugMsg(SPeepholeOptimization + 'AddMov2LeaAdd', p);
                         p := hp1;
                         p := hp1;
-                      end
-                    else
-                      begin
-                        { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
-                        DebugMsg(SPeepholeOptimization + 'AddMov2Lea', hp1);
-
-                        if (cs_opt_level3 in current_settings.optimizerswitches) then
-                          { hp1 may not be the immediate next instruction under -O3 }
-                          RemoveCurrentp(p)
-                        else
-                          RemoveCurrentp(p, hp1);
                       end;
                       end;
 
 
                     Result := True;
                     Result := True;
@@ -15903,6 +15925,7 @@ unit aoptx86;
         NewRef: TReference;
         NewRef: TReference;
         Distance: Cardinal;
         Distance: Cardinal;
         TempTracking: TAllUsedRegs;
         TempTracking: TAllUsedRegs;
+        DoSubMov2Lea: Boolean;
 
 
       begin
       begin
         Result := False;
         Result := False;
@@ -15948,31 +15971,28 @@ unit aoptx86;
               begin
               begin
                 { Update the register tracking to the MOV instruction }
                 { Update the register tracking to the MOV instruction }
                 CopyUsedRegs(TempTracking);
                 CopyUsedRegs(TempTracking);
-                hp2 := p;
-                repeat
-                  UpdateUsedRegs(tai(hp2.Next));
-                until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+                if (cs_opt_level3 in current_settings.optimizerswitches) then
+                  UpdateUsedRegsBetween(UsedRegs, p, hp1)
+                else
+                  { p and hp1 will be adjacent }
+                  UpdateUsedRegs(UsedRegs, tai(p.Next));
 
 
+                hp2 := hp1;
+                if OptPass2MOV(hp1) then
+                  Include(OptsToCheck, aoc_ForceNewIteration);
+
+                { Reset the tracking to the current instruction }
+                RestoreUsedRegs(TempTracking);
+                ReleaseUsedRegs(TempTracking);
+	 
                 { if hp1 <> hp2 after the call, then hp1 got removed, so let
                 { if hp1 <> hp2 after the call, then hp1 got removed, so let
                   OptPass2SUB get called again }
                   OptPass2SUB get called again }
-                if OptPass2MOV(hp1) and (hp1 <> hp2) then
-                  begin
-                    { Reset the tracking to the current instruction }
-                    RestoreUsedRegs(TempTracking);
-                    ReleaseUsedRegs(TempTracking);
 
 
+                if (hp1 <> hp2) then
+                  begin
                     Result := True;
                     Result := True;
                     Exit;
                     Exit;
                   end;
                   end;
-
-                { Reset the tracking to the current instruction }
-                RestoreUsedRegs(TempTracking);
-                ReleaseUsedRegs(TempTracking);
-
-                { If OptPass2MOV returned True, we don't need to set Result to
-                  True if hp1 didn't change because the SUB instruction didn't
-                  get modified and we'll be evaluating hp1 again when the
-                  peephole optimizer reaches it }
               end;
               end;
 
 
             { Change:
             { Change:
@@ -15991,22 +16011,34 @@ unit aoptx86;
               (
               (
                 { Instructions are guaranteed to be adjacent on -O2 and under }
                 { Instructions are guaranteed to be adjacent on -O2 and under }
                 not (cs_opt_level3 in current_settings.optimizerswitches) or
                 not (cs_opt_level3 in current_settings.optimizerswitches) or
-                not RegUsedBetween(taicpu(hp1).oper[1]^.reg, p, hp1)
+                (
+                  { If the flags are used, don't make the optimisation,
+                    otherwise they will be scrambled.  Fixes #41148 }
+                  (
+                    not RegInUsedRegs(NR_DEFAULTFLAGS, UsedRegs) or
+                    not RegUsedBetween(NR_DEFAULTFLAGS, p, hp1)
+                  ) and
+                  not RegUsedBetween(taicpu(hp1).oper[1]^.reg, p, hp1)
+                )
               ) then
               ) then
               begin
               begin
                 TransferUsedRegs(TmpUsedRegs);
                 TransferUsedRegs(TmpUsedRegs);
-                hp2 := p;
-                repeat
-                  UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next));
-                until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+                if (cs_opt_level3 in current_settings.optimizerswitches) then
+                  UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
+                else
+                  { p and hp1 will be adjacent }
+                  UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
 
 
                 if (
                 if (
+                    SetAndTest(
+                      (
+                        not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
+                        not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
+                      ),
+                      DoSubMov2Lea
+                    ) or
                     { Don't do SubMov2LeaSub under -Os, but do allow SubMov2Lea }
                     { Don't do SubMov2LeaSub under -Os, but do allow SubMov2Lea }
-                    not (cs_opt_size in current_settings.optimizerswitches) or
-                    (
-                      not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
-                      not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
-                    )
+                    not (cs_opt_size in current_settings.optimizerswitches)
                   ) then
                   ) then
                   begin
                   begin
                     { Change the MOV instruction to a LEA instruction, and update the
                     { Change the MOV instruction to a LEA instruction, and update the
@@ -16019,10 +16051,18 @@ unit aoptx86;
                     taicpu(hp1).opcode := A_LEA;
                     taicpu(hp1).opcode := A_LEA;
                     taicpu(hp1).loadref(0, NewRef);
                     taicpu(hp1).loadref(0, NewRef);
 
 
-                    TransferUsedRegs(TmpUsedRegs);
-                    UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
-                    if RegUsedAfterInstruction(NewRef.base, hp1, TmpUsedRegs) or
-                      RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) then
+                    if DoSubMov2Lea then
+                      begin
+                        { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
+                        DebugMsg(SPeepholeOptimization + 'SubMov2Lea', hp1);
+
+                        if (cs_opt_level3 in current_settings.optimizerswitches) then
+                          { hp1 may not be the immediate next instruction under -O3 }
+                          RemoveCurrentp(p)
+                        else
+                          RemoveCurrentp(p, hp1);
+                      end
+                    else
                       begin
                       begin
                         hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween }
                         hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween }
 
 
@@ -16033,17 +16073,6 @@ unit aoptx86;
 
 
                         DebugMsg(SPeepholeOptimization + 'SubMov2LeaSub', p);
                         DebugMsg(SPeepholeOptimization + 'SubMov2LeaSub', p);
                         p := hp1;
                         p := hp1;
-                      end
-                    else
-                      begin
-                        { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
-                        DebugMsg(SPeepholeOptimization + 'SubMov2Lea', hp1);
-
-                        if (cs_opt_level3 in current_settings.optimizerswitches) then
-                          { hp1 may not be the immediate next instruction under -O3 }
-                          RemoveCurrentp(p)
-                        else
-                          RemoveCurrentp(p, hp1);
                       end;
                       end;
 
 
                     Result := True;
                     Result := True;

+ 18 - 6
compiler/x86_64/aoptcpu.pas

@@ -199,9 +199,15 @@ uses
             if not Result then
             if not Result then
               begin
               begin
                 if (p.typ in SkipInstr) then
                 if (p.typ in SkipInstr) then
-                  UpdateUsedRegs(p);
-
-                p := tai(p.Next);
+                  begin
+                    UpdateUsedRegs(p);
+                    p := tai(p.Next);
+                  end
+                else
+                  begin
+                    p := tai(p.Next);
+                    UpdateUsedRegs(p);
+                  end;
                 Result := True;
                 Result := True;
               end;
               end;
           end;
           end;
@@ -259,9 +265,15 @@ uses
             if not Result then
             if not Result then
               begin
               begin
                 if (p.typ in SkipInstr) then
                 if (p.typ in SkipInstr) then
-                  UpdateUsedRegs(p);
-
-                p := tai(p.Next);
+                  begin
+                    UpdateUsedRegs(p);
+                    p := tai(p.Next);
+                  end
+                else
+                  begin
+                    p := tai(p.Next);
+                    UpdateUsedRegs(p);
+                  end;
                 Result := True;
                 Result := True;
               end;
               end;
           end;
           end;

+ 4 - 3
compiler/x86_64/cpuinfo.pas

@@ -220,6 +220,7 @@ type
        CPUX86_HAS_CMOV,         { CMOVcc instructions are available }
        CPUX86_HAS_CMOV,         { CMOVcc instructions are available }
        CPUX86_HAS_SSEUNIT,      { SSE instructions are available }
        CPUX86_HAS_SSEUNIT,      { SSE instructions are available }
        CPUX86_HAS_SSE2,         { SSE2 instructions are available }
        CPUX86_HAS_SSE2,         { SSE2 instructions are available }
+       CPUX86_HAS_SSSE3,        { SSSE3 instructions are available }
        CPUX86_HAS_SSE4_1,       { SSE 4.1 instructions are available }
        CPUX86_HAS_SSE4_1,       { SSE 4.1 instructions are available }
        CPUX86_HAS_BMI1,         { BMI1 instructions are available }
        CPUX86_HAS_BMI1,         { BMI1 instructions are available }
        CPUX86_HAS_BMI2,         { BMI2 instructions are available }
        CPUX86_HAS_BMI2,         { BMI2 instructions are available }
@@ -269,7 +270,7 @@ type
 
 
  const
  const
    cpu_x86_64_v1_flags = [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2];
    cpu_x86_64_v1_flags = [CPUX86_HAS_BSWAP,CPUX86_HAS_BTX,CPUX86_HAS_CMOV,CPUX86_HAS_SSEUNIT,CPUX86_HAS_SSE2];
-   cpu_x86_64_v2_flags = cpu_x86_64_v1_flags+[CPUX86_HAS_CMPXCHG16B,CPUX86_HAS_LAHF_SAHF,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT];
+   cpu_x86_64_v2_flags = cpu_x86_64_v1_flags+[CPUX86_HAS_CMPXCHG16B,CPUX86_HAS_LAHF_SAHF,CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT];
    cpu_x86_64_v3_flags = cpu_x86_64_v2_flags+[CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE,CPUX86_HAS_OSXSAVE]; { most is in the fpu flags here }
    cpu_x86_64_v3_flags = cpu_x86_64_v2_flags+[CPUX86_HAS_BMI1,CPUX86_HAS_BMI2,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE,CPUX86_HAS_OSXSAVE]; { most is in the fpu flags here }
    cpu_x86_64_v4_flags = cpu_x86_64_v3_flags; { everything is in the fpu flags here }
    cpu_x86_64_v4_flags = cpu_x86_64_v3_flags; { everything is in the fpu flags here }
 
 
@@ -278,10 +279,10 @@ type
      { Athlon64      } cpu_x86_64_v1_flags,
      { Athlon64      } cpu_x86_64_v1_flags,
      { cpu_x86_64    } cpu_x86_64_v1_flags,
      { cpu_x86_64    } cpu_x86_64_v1_flags,
      { cpu_x86_64_v1 } cpu_x86_64_v1_flags,
      { cpu_x86_64_v1 } cpu_x86_64_v1_flags,
-     { cpu_core_i    } cpu_x86_64_v1_flags+[CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT],
+     { cpu_core_i    } cpu_x86_64_v1_flags+[CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT],
      { cpu_x86_64_v2 } cpu_x86_64_v2_flags,
      { cpu_x86_64_v2 } cpu_x86_64_v2_flags,
      { cpu_bobcat    } cpu_x86_64_v1_flags+[CPUX86_HAS_POPCNT,CPUX86_HAS_LZCNT],
      { cpu_bobcat    } cpu_x86_64_v1_flags+[CPUX86_HAS_POPCNT,CPUX86_HAS_LZCNT],
-     { cpu_core_avx  } cpu_x86_64_v1_flags+[CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT],
+     { cpu_core_avx  } cpu_x86_64_v1_flags+[CPUX86_HAS_SSSE3,CPUX86_HAS_SSE4_1,CPUX86_HAS_POPCNT],
      { cpu_jaguar    } cpu_x86_64_v2_flags+[CPUX86_HAS_BMI1,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
      { cpu_jaguar    } cpu_x86_64_v2_flags+[CPUX86_HAS_BMI1,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
      { cpu_piledriver} cpu_x86_64_v2_flags+[CPUX86_HAS_BMI1,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
      { cpu_piledriver} cpu_x86_64_v2_flags+[CPUX86_HAS_BMI1,CPUX86_HAS_LZCNT,CPUX86_HAS_MOVBE],
      { cpu_excavator } cpu_x86_64_v3_flags,
      { cpu_excavator } cpu_x86_64_v3_flags,

+ 3 - 1
compiler/xtensa/aoptcpu.pas

@@ -25,7 +25,9 @@ Unit aoptcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
-{ $define DEBUG_AOPTCPU}
+{$ifdef EXTDEBUG}
+{$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
 Interface
 Interface
 
 

+ 2 - 0
compiler/z80/aoptcpu.pas

@@ -26,7 +26,9 @@ Unit aoptcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
+{$ifdef EXTDEBUG}
 {$define DEBUG_AOPTCPU}
 {$define DEBUG_AOPTCPU}
+{$endif EXTDEBUG}
 
 
 Interface
 Interface
 
 

+ 34 - 4
installer/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -734,7 +734,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override CLEAN_UNITS+=scroll insthelp
 override CLEAN_UNITS+=scroll insthelp
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override CLEAN_UNITS+=scroll insthelp
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override CLEAN_UNITS+=scroll insthelp
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override CLEAN_UNITS+=scroll insthelp
 override CLEAN_UNITS+=scroll insthelp
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1373,7 +1379,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2513,7 +2525,25 @@ REQUIRE_PACKAGES_UNZIP=1
 REQUIRE_PACKAGES_RTL-EXTRA=1
 REQUIRE_PACKAGES_RTL-EXTRA=1
 REQUIRE_PACKAGES_IDE=1
 REQUIRE_PACKAGES_IDE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_RTL-UNICODE=1
+REQUIRE_PACKAGES_RTL-CONSOLE=1
+REQUIRE_PACKAGES_FV=1
+REQUIRE_PACKAGES_UNZIP=1
+REQUIRE_PACKAGES_RTL-EXTRA=1
+REQUIRE_PACKAGES_IDE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_RTL-UNICODE=1
+REQUIRE_PACKAGES_RTL-CONSOLE=1
+REQUIRE_PACKAGES_FV=1
+REQUIRE_PACKAGES_UNZIP=1
+REQUIRE_PACKAGES_RTL-EXTRA=1
+REQUIRE_PACKAGES_IDE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL-UNICODE=1
 REQUIRE_PACKAGES_RTL-UNICODE=1
 REQUIRE_PACKAGES_RTL-CONSOLE=1
 REQUIRE_PACKAGES_RTL-CONSOLE=1

+ 15 - 3
packages/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -931,7 +931,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -1483,7 +1489,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)

+ 26 - 3
packages/build/Makefile.pkg

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -366,6 +366,7 @@ FPMAKE_SKIP_CONFIG=-n
 FPCFPMAKE=$(FPC)
 FPCFPMAKE=$(FPC)
 endif
 endif
 endif
 endif
+override PACKAGE_NAME=fcl
 override PACKAGE_VERSION=3.3.1
 override PACKAGE_VERSION=3.3.1
 FPMAKE_BIN_CLEAN=$(wildcard ./fpmake$(SRCEXEEXT))
 FPMAKE_BIN_CLEAN=$(wildcard ./fpmake$(SRCEXEEXT))
 ifdef OS_TARGET
 ifdef OS_TARGET
@@ -906,7 +907,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -1948,7 +1955,23 @@ REQUIRE_PACKAGES_HASH=1
 REQUIRE_PACKAGES_LIBTAR=1
 REQUIRE_PACKAGES_LIBTAR=1
 REQUIRE_PACKAGES_FPMKUNIT=1
 REQUIRE_PACKAGES_FPMKUNIT=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_LIBTAR=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PASZLIB=1
+REQUIRE_PACKAGES_FCL-PROCESS=1
+REQUIRE_PACKAGES_HASH=1
+REQUIRE_PACKAGES_LIBTAR=1
+REQUIRE_PACKAGES_FPMKUNIT=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_PASZLIB=1
 REQUIRE_PACKAGES_PASZLIB=1
 REQUIRE_PACKAGES_FCL-PROCESS=1
 REQUIRE_PACKAGES_FCL-PROCESS=1

+ 1 - 1
packages/bzip2/fpmake.pp

@@ -28,7 +28,7 @@ begin
     P.Email := '';
     P.Email := '';
     P.Description := 'BZip2 decompression unit.';
     P.Description := 'BZip2 decompression unit.';
     P.NeedLibC:= true;
     P.NeedLibC:= true;
-    P.OSes := P.OSes - [embedded,nativent,msdos,win16,macosclassic,palmos,zxspectrum,msxdos,amstradcpc,sinclairql,ps1];
+    P.OSes := P.OSes - [embedded,nativent,msdos,win16,macosclassic,palmos,zxspectrum,msxdos,amstradcpc,sinclairql,ps1,wasip2];
     if Defaults.CPU=jvm then
     if Defaults.CPU=jvm then
       P.OSes := P.OSes - [java,android];
       P.OSes := P.OSes - [java,android];
 
 

+ 2 - 0
packages/cairo/fpmake.pp

@@ -21,6 +21,8 @@ begin
     P.License := 'Library: MPL 1.1 + LGPL-2.1, header: LGPL with modification, ';
     P.License := 'Library: MPL 1.1 + LGPL-2.1, header: LGPL with modification, ';
     P.HomepageURL := 'www.freepascal.org';
     P.HomepageURL := 'www.freepascal.org';
     P.OSes := [beos,haiku,freebsd,solaris,netbsd,openbsd,linux,win32,win64,aix,dragonfly,android];
     P.OSes := [beos,haiku,freebsd,solaris,netbsd,openbsd,linux,win32,win64,aix,dragonfly,android];
+    if Defaults.CPU=jvm then
+      P.OSes := P.OSes - [android];
     // Do not build cairo on iPhone (=arm-darwin)
     // Do not build cairo on iPhone (=arm-darwin)
     if Defaults.CPU<>arm then
     if Defaults.CPU<>arm then
       P.OSes := P.OSes + [darwin];
       P.OSes := P.OSes + [darwin];

+ 24 - 4
packages/cdrom/examples/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -660,7 +660,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_PROGRAMS+=getdiscid showcds
 override TARGET_PROGRAMS+=getdiscid showcds
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_PROGRAMS+=getdiscid showcds
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_PROGRAMS+=getdiscid showcds
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_PROGRAMS+=getdiscid showcds
 override TARGET_PROGRAMS+=getdiscid showcds
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1236,7 +1242,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -1886,7 +1898,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_CDROM=1
 REQUIRE_PACKAGES_CDROM=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_CDROM=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_CDROM=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_CDROM=1
 REQUIRE_PACKAGES_CDROM=1
 endif
 endif

+ 1 - 1
packages/chm/fpmake.pp

@@ -25,7 +25,7 @@ begin
     P.Email := '';
     P.Email := '';
     P.Description := 'Standalone CHM reader and writer library';
     P.Description := 'Standalone CHM reader and writer library';
     P.NeedLibC:= false;
     P.NeedLibC:= false;
-    P.OSes := P.OSes - [embedded,nativent,msdos,win16,macosclassic,palmos,atari,zxspectrum,msxdos,amstradcpc,watcom,sinclairql,human68k,ps1];
+    P.OSes := P.OSes - [embedded,nativent,msdos,win16,macosclassic,palmos,atari,zxspectrum,msxdos,amstradcpc,watcom,sinclairql,human68k,ps1,wasip2];
     if Defaults.CPU=jvm then
     if Defaults.CPU=jvm then
       P.OSes := P.OSes - [java,android];
       P.OSes := P.OSes - [java,android];
 
 

+ 1 - 1
packages/chm/src/chmwriter.pas

@@ -1138,7 +1138,7 @@ end;
 
 
 procedure TChmWriter.WriteSTRINGS;
 procedure TChmWriter.WriteSTRINGS;
 begin
 begin
-  if FStringsStream.Size = 0 then;
+  if FStringsStream.Size = 0 then
     FStringsStream.WriteByte(0);
     FStringsStream.WriteByte(0);
   FStringsStream.Position := 0;
   FStringsStream.Position := 0;
   PostAddStreamToArchive('#STRINGS', '/', FStringsStream);
   PostAddStreamToArchive('#STRINGS', '/', FStringsStream);

+ 24 - 4
packages/dbus/examples/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -660,7 +660,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_PROGRAMS+=busexample
 override TARGET_PROGRAMS+=busexample
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_PROGRAMS+=busexample
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_PROGRAMS+=busexample
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_PROGRAMS+=busexample
 override TARGET_PROGRAMS+=busexample
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1236,7 +1242,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -1886,7 +1898,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_DBUS=1
 REQUIRE_PACKAGES_DBUS=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_DBUS=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_DBUS=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_DBUS=1
 REQUIRE_PACKAGES_DBUS=1
 endif
 endif

+ 40 - 4
packages/fcl-base/examples/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -660,7 +660,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_PROGRAMS+=stringl dparser fstream mstream list threads testrtf cfgtest xmldump htdump testez tidea b64test b64test2 b64enc b64dec restest testz testz2 istream doecho testol testcont txmlreg testreg tstelcmd testapp testcgi testbs testbf cachetest poolmm1 poolmm2 tarmakercons tarmakerconsgzip avltreetest testmime decodeascii85 encodeascii85
 override TARGET_PROGRAMS+=stringl dparser fstream mstream list threads testrtf cfgtest xmldump htdump testez tidea b64test b64test2 b64enc b64dec restest testz testz2 istream doecho testol testcont txmlreg testreg tstelcmd testapp testcgi testbs testbf cachetest poolmm1 poolmm2 tarmakercons tarmakerconsgzip avltreetest testmime decodeascii85 encodeascii85
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_PROGRAMS+=stringl dparser fstream mstream list threads testrtf cfgtest xmldump htdump testez tidea b64test b64test2 b64enc b64dec restest testz testz2 istream doecho testol testcont txmlreg testreg tstelcmd testapp testcgi testbs testbf cachetest poolmm1 poolmm2 tarmakercons tarmakerconsgzip avltreetest testmime decodeascii85 encodeascii85
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_PROGRAMS+=stringl dparser fstream mstream list threads testrtf cfgtest xmldump htdump testez tidea b64test b64test2 b64enc b64dec restest testz testz2 istream doecho testol testcont txmlreg testreg tstelcmd testapp testcgi testbs testbf cachetest poolmm1 poolmm2 tarmakercons tarmakerconsgzip avltreetest testmime decodeascii85 encodeascii85
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_PROGRAMS+=stringl dparser fstream mstream list threads testrtf cfgtest xmldump htdump testez tidea b64test b64test2 b64enc b64dec restest testz testz2 istream doecho testol testcont txmlreg testreg tstelcmd testapp testcgi testbs testbf cachetest poolmm1 poolmm2 tarmakercons tarmakerconsgzip avltreetest testmime decodeascii85 encodeascii85
 override TARGET_PROGRAMS+=stringl dparser fstream mstream list threads testrtf cfgtest xmldump htdump testez tidea b64test b64test2 b64enc b64dec restest testz testz2 istream doecho testol testcont txmlreg testreg tstelcmd testapp testcgi testbs testbf cachetest poolmm1 poolmm2 tarmakercons tarmakerconsgzip avltreetest testmime decodeascii85 encodeascii85
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1236,7 +1242,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2670,7 +2682,31 @@ REQUIRE_PACKAGES_FCL-REGISTRY=1
 REQUIRE_PACKAGES_FCL-WEB=1
 REQUIRE_PACKAGES_FCL-WEB=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-FPCUNIT=1
+REQUIRE_PACKAGES_FCL-IMAGE=1
+REQUIRE_PACKAGES_FCL-NET=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-REGISTRY=1
+REQUIRE_PACKAGES_FCL-WEB=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-FPCUNIT=1
+REQUIRE_PACKAGES_FCL-IMAGE=1
+REQUIRE_PACKAGES_FCL-NET=1
+REQUIRE_PACKAGES_FCL-PASSRC=1
+REQUIRE_PACKAGES_FCL-REGISTRY=1
+REQUIRE_PACKAGES_FCL-WEB=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-DB=1
 REQUIRE_PACKAGES_FCL-DB=1

+ 1 - 1
packages/fcl-base/fpmake.pp

@@ -27,7 +27,7 @@ begin
     P.Email := '';
     P.Email := '';
     P.Description := 'Base library of Free Component Libraries (FCL), FPC''s OOP library.';
     P.Description := 'Base library of Free Component Libraries (FCL), FPC''s OOP library.';
     P.NeedLibC:= false;
     P.NeedLibC:= false;
-    P.OSes:=AllOSes-[embedded,msdos,win16,macosclassic,palmos,zxspectrum,msxdos,amstradcpc,sinclairql,human68k,ps1];
+    P.OSes:=AllOSes-[embedded,msdos,win16,macosclassic,palmos,zxspectrum,msxdos,amstradcpc,sinclairql,human68k,ps1,wasip2];
     if Defaults.CPU=jvm then
     if Defaults.CPU=jvm then
       P.OSes := P.OSes - [java,android];
       P.OSes := P.OSes - [java,android];
 
 

+ 1 - 1
packages/fcl-css/fpmake.pp

@@ -28,7 +28,7 @@ begin
     P.Email := '';
     P.Email := '';
     P.Description := 'CSS parsing and utility functions.';
     P.Description := 'CSS parsing and utility functions.';
     P.NeedLibC:= false;
     P.NeedLibC:= false;
-    P.OSes:=AllOSes-[embedded,msdos,win16,macosclassic,palmos,zxspectrum,msxdos,amstradcpc,sinclairql,human68k,ps1];
+    P.OSes:=AllOSes-[embedded,msdos,win16,macosclassic,palmos,zxspectrum,msxdos,amstradcpc,sinclairql,human68k,ps1,wasip2];
     if Defaults.CPU=jvm then
     if Defaults.CPU=jvm then
       P.OSes := P.OSes - [java,android];
       P.OSes := P.OSes - [java,android];
 
 

+ 62 - 13
packages/fcl-css/src/fpcssparser.pp

@@ -86,8 +86,9 @@ Type
     function ParseHashIdentifier : TCSSHashIdentifierElement; virtual;
     function ParseHashIdentifier : TCSSHashIdentifierElement; virtual;
     function ParseClassName : TCSSClassNameElement; virtual;
     function ParseClassName : TCSSClassNameElement; virtual;
     function ParseParenthesis: TCSSElement; virtual;
     function ParseParenthesis: TCSSElement; virtual;
-    function ParsePseudo: TCSSElement; virtual;
-    Function ParseRuleBody(aRule: TCSSRuleElement; aIsAt : Boolean = False) : integer; virtual;
+    function ParsePseudoClass: TCSSElement; virtual;
+    function ParsePseudoElement: TCSSElement; virtual;
+    function ParseRuleBody(aRule: TCSSRuleElement; aIsAt : Boolean = False) : integer; virtual;
     function ParseInteger: TCSSElement; virtual;
     function ParseInteger: TCSSElement; virtual;
     function ParseFloat: TCSSElement; virtual;
     function ParseFloat: TCSSElement; virtual;
     function ParseString: TCSSElement; virtual;
     function ParseString: TCSSElement; virtual;
@@ -928,7 +929,7 @@ begin
   GetNextToken;
   GetNextToken;
 end;
 end;
 
 
-function TCSSParser.ParsePseudo: TCSSElement;
+function TCSSParser.ParsePseudoClass: TCSSElement;
 
 
 Var
 Var
   aPseudo : TCSSPseudoClassElement;
   aPseudo : TCSSPseudoClassElement;
@@ -947,6 +948,20 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TCSSParser.ParsePseudoElement: TCSSElement;
+begin
+  if CurrentToken<>ctkDOUBLECOLON then
+    raise Exception.Create('20250224201230');
+  GetNextToken;
+  case CurrentToken of
+  ctkIDENTIFIER: Result:=ParseIdentifier;
+  ctkFUNCTION: Result:=ParseCall('',false);
+  else
+    DoWarnExpectedButGot('pseudo element name');
+    Result:=nil;
+  end;
+end;
+
 function TCSSParser.ParseRuleBody(aRule: TCSSRuleElement; aIsAt: Boolean = false): integer;
 function TCSSParser.ParseRuleBody(aRule: TCSSRuleElement; aIsAt: Boolean = false): integer;
 
 
 Var
 Var
@@ -1162,7 +1177,7 @@ begin
     ctkEOF: exit(nil);
     ctkEOF: exit(nil);
     ctkLPARENTHESIS: Result:=ParseParenthesis;
     ctkLPARENTHESIS: Result:=ParseParenthesis;
     ctkURL: Result:=ParseURL;
     ctkURL: Result:=ParseURL;
-    ctkPSEUDO: Result:=ParsePseudo;
+    ctkPSEUDO: Result:=ParsePseudoClass;
     ctkLBRACE: Result:=ParseRule;
     ctkLBRACE: Result:=ParseRule;
     ctkLBRACKET: Result:=ParseArray(Nil);
     ctkLBRACKET: Result:=ParseArray(Nil);
     ctkMinus,
     ctkMinus,
@@ -1191,6 +1206,28 @@ end;
 
 
 function TCSSParser.ParseSelector: TCSSElement;
 function TCSSParser.ParseSelector: TCSSElement;
 
 
+  function ParseBinaryPseudoElement(var El: TCSSElement): boolean;
+  var
+    Bin: TCSSBinaryElement;
+  begin
+    Bin:=TCSSBinaryElement(CreateElement(CSSBinaryElementClass));
+    Bin.Left:=El;
+    El:=Bin;
+    Bin.Operation:=boDoubleColon;
+    Bin.Right:=ParsePseudoElement;
+    Result:=Bin.Right<>nil;
+  end;
+
+  function ParseUnaryPseudoElement: TCSSElement;
+  var
+    Un: TCSSUnaryElement;
+  begin
+    Un:=TCSSUnaryElement(CreateElement(CSSUnaryElementClass));
+    Result:=Un;
+    Un.Operation:=uoDoubleColon;
+    Un.Right:=ParsePseudoElement;
+  end;
+
   function ParseSub: TCSSElement;
   function ParseSub: TCSSElement;
   begin
   begin
     Result:=nil;
     Result:=nil;
@@ -1200,8 +1237,9 @@ function TCSSParser.ParseSelector: TCSSElement;
       ctkHASH : Result:=ParseHashIdentifier;
       ctkHASH : Result:=ParseHashIdentifier;
       ctkCLASSNAME : Result:=ParseClassName;
       ctkCLASSNAME : Result:=ParseClassName;
       ctkLBRACKET: Result:=ParseAttributeSelector;
       ctkLBRACKET: Result:=ParseAttributeSelector;
-      ctkPSEUDO: Result:=ParsePseudo;
+      ctkPSEUDO: Result:=ParsePseudoClass;
       ctkPSEUDOFUNCTION: Result:=ParseCall('',true);
       ctkPSEUDOFUNCTION: Result:=ParseCall('',true);
+      ctkDOUBLECOLON: Result:=ParseUnaryPseudoElement;
     else
     else
       DoWarn(SErrUnexpectedToken ,[
       DoWarn(SErrUnexpectedToken ,[
                GetEnumName(TypeInfo(TCSSToken),Ord(CurrentToken)),
                GetEnumName(TypeInfo(TCSSToken),Ord(CurrentToken)),
@@ -1218,8 +1256,8 @@ function TCSSParser.ParseSelector: TCSSElement;
 
 
 var
 var
   ok, OldReturnWhiteSpace: Boolean;
   ok, OldReturnWhiteSpace: Boolean;
-  Bin: TCSSBinaryElement;
-  El: TCSSElement;
+  Bin, PseudoBin: TCSSBinaryElement;
+  El, Sub: TCSSElement;
   List: TCSSListElement;
   List: TCSSListElement;
 begin
 begin
   Result:=nil;
   Result:=nil;
@@ -1234,15 +1272,18 @@ begin
   Scanner.ReturnWhiteSpace:=true;
   Scanner.ReturnWhiteSpace:=true;
   try
   try
     repeat
     repeat
-      {$IFDEF VerbosecSSParser}
+      {$IFDEF VerboseCSSParser}
       writeln('TCSSParser.ParseSelector LIST START ',CurrentToken,' ',CurrentTokenString);
       writeln('TCSSParser.ParseSelector LIST START ',CurrentToken,' ',CurrentTokenString);
       {$ENDIF}
       {$ENDIF}
       // read list
       // read list
       List:=nil;
       List:=nil;
       El:=ParseSub;
       El:=ParseSub;
-      {$IFDEF VerbosecSSParser}
+      {$IFDEF VerboseCSSParser}
       writeln('TCSSParser.ParseSelector LIST NEXT ',CurrentToken,' ',CurrentTokenString,' El=',GetCSSObj(El));
       writeln('TCSSParser.ParseSelector LIST NEXT ',CurrentToken,' ',CurrentTokenString,' El=',GetCSSObj(El));
       {$ENDIF}
       {$ENDIF}
+      if El=nil then
+        exit;
+
       while CurrentToken in [ctkSTAR,ctkHASH,ctkIDENTIFIER,ctkCLASSNAME,ctkLBRACKET,ctkPSEUDO,ctkPSEUDOFUNCTION] do
       while CurrentToken in [ctkSTAR,ctkHASH,ctkIDENTIFIER,ctkCLASSNAME,ctkLBRACKET,ctkPSEUDO,ctkPSEUDOFUNCTION] do
         begin
         begin
         if List=nil then
         if List=nil then
@@ -1251,10 +1292,16 @@ begin
           List.AddChild(El);
           List.AddChild(El);
           El:=List;
           El:=List;
           end;
           end;
-        List.AddChild(ParseSub);
+        Sub:=ParseSub;
+        if Sub=nil then break;
+        List.AddChild(Sub);
         end;
         end;
       List:=nil;
       List:=nil;
 
 
+      // read postfix pseudo elements
+      while CurrentToken=ctkDOUBLECOLON do
+        if not ParseBinaryPseudoElement(El) then break;
+
       // use element
       // use element
       if Bin<>nil then
       if Bin<>nil then
         Bin.Right:=El
         Bin.Right:=El
@@ -1263,7 +1310,7 @@ begin
       El:=nil;
       El:=nil;
 
 
       SkipWhiteSpace;
       SkipWhiteSpace;
-      {$IFDEF VerbosecSSParser}
+      {$IFDEF VerboseCSSParser}
       writeln('TCSSParser.ParseSelector LIST END ',CurrentToken,' ',CurrentTokenString);
       writeln('TCSSParser.ParseSelector LIST END ',CurrentToken,' ',CurrentTokenString);
       {$ENDIF}
       {$ENDIF}
 
 
@@ -1282,7 +1329,7 @@ begin
         end;
         end;
       ctkSTAR,ctkHASH,ctkIDENTIFIER,ctkCLASSNAME,ctkLBRACKET,ctkPSEUDO,ctkPSEUDOFUNCTION:
       ctkSTAR,ctkHASH,ctkIDENTIFIER,ctkCLASSNAME,ctkLBRACKET,ctkPSEUDO,ctkPSEUDOFUNCTION:
         begin
         begin
-        // decendant combinator
+        // descendant combinator
         Bin:=TCSSBinaryElement(CreateElement(CSSBinaryElementClass));
         Bin:=TCSSBinaryElement(CreateElement(CSSBinaryElementClass));
         Bin.Left:=Result;
         Bin.Left:=Result;
         Result:=Bin;
         Result:=Bin;
@@ -1297,6 +1344,9 @@ begin
     Scanner.ReturnWhiteSpace:=OldReturnWhiteSpace;
     Scanner.ReturnWhiteSpace:=OldReturnWhiteSpace;
     if not ok then
     if not ok then
       begin
       begin
+      if Result=Bin then Bin:=nil;
+      if El=List then List:=nil;
+      if Result=El then El:=nil;
       Result.Free;
       Result.Free;
       El.Free;
       El.Free;
       List.Free;
       List.Free;
@@ -1470,7 +1520,6 @@ var
   l : Integer;
   l : Integer;
   aValue: TCSSElement;
   aValue: TCSSElement;
 begin
 begin
-  if IsSelector then ;
   aCall:=TCSSCallElement(CreateElement(CSSCallElementClass));
   aCall:=TCSSCallElement(CreateElement(CSSCallElementClass));
   try
   try
     if (aName='') then
     if (aName='') then

+ 154 - 62
packages/fcl-css/src/fpcssresolver.pas

@@ -140,6 +140,16 @@ type
     cssoUser,
     cssoUser,
     cssoAuthor
     cssoAuthor
     );
     );
+const
+  CSSOriginToSpecifity: array[TCSSOrigin] of TCSSNumericalID = (
+    CSSSpecificityUserAgent,
+    CSSSpecificityUser,
+    CSSSpecificityAuthor
+    );
+
+type
+
+  { ECSSResolver }
 
 
   ECSSResolver = class(ECSSException)
   ECSSResolver = class(ECSSException)
   end;
   end;
@@ -159,22 +169,28 @@ type
     function GetCSSID: TCSSString;
     function GetCSSID: TCSSString;
     function GetCSSTypeName: TCSSString;
     function GetCSSTypeName: TCSSString;
     function GetCSSTypeID: TCSSNumericalID;
     function GetCSSTypeID: TCSSNumericalID;
-    function HasCSSClass(const aClassName: TCSSString): boolean;
-    function GetCSSAttributeClass: TCSSString; // get the 'class' attribute
+    function GetCSSPseudoElementName: TCSSString;
+    function GetCSSPseudoElementID: TCSSNumericalID;
+    // parent
     function GetCSSParent: ICSSNode;
     function GetCSSParent: ICSSNode;
+    function GetCSSDepth: integer;
     function GetCSSIndex: integer; // node index in parent's children
     function GetCSSIndex: integer; // node index in parent's children
+    // siblings
     function GetCSSNextSibling: ICSSNode;
     function GetCSSNextSibling: ICSSNode;
     function GetCSSPreviousSibling: ICSSNode;
     function GetCSSPreviousSibling: ICSSNode;
-    function GetCSSChildCount: integer;
-    function GetCSSChild(const anIndex: integer): ICSSNode;
     function GetCSSNextOfType: ICSSNode;
     function GetCSSNextOfType: ICSSNode;
     function GetCSSPreviousOfType: ICSSNode;
     function GetCSSPreviousOfType: ICSSNode;
+    // children
+    function GetCSSEmpty: boolean;
+    function GetCSSChildCount: integer;
+    function GetCSSChild(const anIndex: integer): ICSSNode;
+    // attributes
+    function HasCSSClass(const aClassName: TCSSString): boolean;
+    function GetCSSAttributeClass: TCSSString; // get the 'class' attribute
     function GetCSSCustomAttribute(const AttrID: TCSSNumericalID): TCSSString;
     function GetCSSCustomAttribute(const AttrID: TCSSNumericalID): TCSSString;
     function HasCSSExplicitAttribute(const AttrID: TCSSNumericalID): boolean; // e.g. if the HTML has the attribute
     function HasCSSExplicitAttribute(const AttrID: TCSSNumericalID): boolean; // e.g. if the HTML has the attribute
     function GetCSSExplicitAttribute(const AttrID: TCSSNumericalID): TCSSString;
     function GetCSSExplicitAttribute(const AttrID: TCSSNumericalID): TCSSString;
     function HasCSSPseudoClass(const AttrID: TCSSNumericalID): boolean;
     function HasCSSPseudoClass(const AttrID: TCSSNumericalID): boolean;
-    function GetCSSEmpty: boolean;
-    function GetCSSDepth: integer;
   end;
   end;
 
 
 type
 type
@@ -386,9 +402,11 @@ type
     function SelectorIdentifierMatches(Identifier: TCSSResolvedIdentifierElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorIdentifierMatches(Identifier: TCSSResolvedIdentifierElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorHashIdentifierMatches(Identifier: TCSSHashIdentifierElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorHashIdentifierMatches(Identifier: TCSSHashIdentifierElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorClassNameMatches(aClassName: TCSSClassNameElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorClassNameMatches(aClassName: TCSSClassNameElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
-    function SelectorPseudoClassMatches(aPseudoClass: TCSSResolvedPseudoClassElement; var TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
+    function SelectorPseudoClassMatches(aPseudoClass: TCSSResolvedPseudoClassElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorListMatches(aList: TCSSListElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorListMatches(aList: TCSSListElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
+    function SelectorUnaryMatches(aUnary: TCSSUnaryElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorBinaryMatches(aBinary: TCSSBinaryElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorBinaryMatches(aBinary: TCSSBinaryElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
+    function SelectorPseudoElementMatches(aLeft, aRight: TCSSElement; const TestNode: ICSSNode): TCSSSpecificity; virtual;
     function SelectorArrayMatches(anArray: TCSSArrayElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorArrayMatches(anArray: TCSSArrayElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorArrayBinaryMatches(aBinary: TCSSBinaryElement; const TestNode: ICSSNode): TCSSSpecificity; virtual;
     function SelectorArrayBinaryMatches(aBinary: TCSSBinaryElement; const TestNode: ICSSNode): TCSSSpecificity; virtual;
     function SelectorCallMatches(aCall: TCSSResolvedCallElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
     function SelectorCallMatches(aCall: TCSSResolvedCallElement; const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity; virtual;
@@ -401,7 +419,7 @@ type
     function GetSiblingOfIndex(SiblingIDs: TIntegerDynArray; Index: integer): integer; virtual;
     function GetSiblingOfIndex(SiblingIDs: TIntegerDynArray; Index: integer): integer; virtual;
     function ComputeValue(El: TCSSElement): TCSSString; virtual;
     function ComputeValue(El: TCSSElement): TCSSString; virtual;
     function SameValueText(const A, B: TCSSString): boolean; virtual;
     function SameValueText(const A, B: TCSSString): boolean; virtual;
-    function SameValueText(A: PAnsiChar; ALen: integer; B: PAnsiChar; BLen: integer): boolean; virtual;
+    function SameValueText(A: PCSSChar; ALen: integer; B: PCSSChar; BLen: integer): boolean; virtual;
     function PosSubString(const SearchStr, Str: TCSSString): integer; virtual;
     function PosSubString(const SearchStr, Str: TCSSString): integer; virtual;
     function PosWord(const SearchWord, Words: TCSSString): integer; virtual;
     function PosWord(const SearchWord, Words: TCSSString): integer; virtual;
     function GetSiblingCount(aNode: ICSSNode): integer; virtual;
     function GetSiblingCount(aNode: ICSSNode): integer; virtual;
@@ -1160,15 +1178,6 @@ end;
 
 
 function TCSSResolver.SelectorMatches(aSelector: TCSSElement;
 function TCSSResolver.SelectorMatches(aSelector: TCSSElement;
   const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity;
   const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity;
-
-  procedure MatchPseudo;
-  var
-    aNode: ICSSNode;
-  begin
-    aNode:=TestNode;
-    Result:=SelectorPseudoClassMatches(TCSSResolvedPseudoClassElement(aSelector),aNode,OnlySpecificity);
-  end;
-
 var
 var
   C: TClass;
   C: TClass;
 begin
 begin
@@ -1182,7 +1191,9 @@ begin
   else if C=TCSSClassNameElement then
   else if C=TCSSClassNameElement then
     Result:=SelectorClassNameMatches(TCSSClassNameElement(aSelector),TestNode,OnlySpecificity)
     Result:=SelectorClassNameMatches(TCSSClassNameElement(aSelector),TestNode,OnlySpecificity)
   else if C=TCSSResolvedPseudoClassElement then
   else if C=TCSSResolvedPseudoClassElement then
-    MatchPseudo
+    Result:=SelectorPseudoClassMatches(TCSSResolvedPseudoClassElement(aSelector),TestNode,OnlySpecificity)
+  else if C=TCSSUnaryElement then
+    Result:=SelectorUnaryMatches(TCSSUnaryElement(aSelector),TestNode,OnlySpecificity)
   else if C=TCSSBinaryElement then
   else if C=TCSSBinaryElement then
     Result:=SelectorBinaryMatches(TCSSBinaryElement(aSelector),TestNode,OnlySpecificity)
     Result:=SelectorBinaryMatches(TCSSBinaryElement(aSelector),TestNode,OnlySpecificity)
   else if C=TCSSArrayElement then
   else if C=TCSSArrayElement then
@@ -1256,9 +1267,8 @@ begin
   //writeln('TCSSResolver.SelectorClassNameMatches ',aValue,' ',Result);
   //writeln('TCSSResolver.SelectorClassNameMatches ',aValue,' ',Result);
 end;
 end;
 
 
-function TCSSResolver.SelectorPseudoClassMatches(
-  aPseudoClass: TCSSResolvedPseudoClassElement; var TestNode: ICSSNode;
-  OnlySpecificity: boolean): TCSSSpecificity;
+function TCSSResolver.SelectorPseudoClassMatches(aPseudoClass: TCSSResolvedPseudoClassElement;
+  const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity;
 var
 var
   PseudoID: TCSSNumericalID;
   PseudoID: TCSSNumericalID;
 begin
 begin
@@ -1336,10 +1346,6 @@ begin
       Log(etWarning,20240625154031,'Type selector must be first',aList);
       Log(etWarning,20240625154031,'Type selector must be first',aList);
       {$ENDIF}
       {$ENDIF}
       exit(CSSSpecificityInvalid);
       exit(CSSSpecificityInvalid);
-    end
-    else if C=TCSSResolvedPseudoClassElement then
-    begin
-      Specificity:=SelectorPseudoClassMatches(TCSSResolvedPseudoClassElement(El),aNode,OnlySpecificity);
     end else
     end else
       Specificity:=SelectorMatches(El,aNode,OnlySpecificity);
       Specificity:=SelectorMatches(El,aNode,OnlySpecificity);
     if Specificity<0 then
     if Specificity<0 then
@@ -1348,11 +1354,35 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TCSSResolver.SelectorUnaryMatches(aUnary: TCSSUnaryElement; const TestNode: ICSSNode;
+  OnlySpecificity: boolean): TCSSSpecificity;
+begin
+  Result:=CSSSpecificityInvalid;
+  case aUnary.Operation of
+  uoDoubleColon:
+    begin
+      // ::PseudoElement
+      if OnlySpecificity then
+        // treat as Type::PseudoElement
+        Result:=CSSSpecificityType+FSourceSpecificity
+               +CSSSpecificityType+FSourceSpecificity
+      else
+        Result:=SelectorPseudoElementMatches(nil,aUnary.Right,TestNode);
+    end;
+  else
+    // already warned by parser
+    {$IFDEF VerboseCSSResolver}
+    Log(etWarning,20250225103026,'Invalid CSS unary selector '+UnaryOperators[aUnary.Operation],aUnary);
+    {$ENDIF}
+  end;
+end;
+
 function TCSSResolver.SelectorBinaryMatches(aBinary: TCSSBinaryElement;
 function TCSSResolver.SelectorBinaryMatches(aBinary: TCSSBinaryElement;
   const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity;
   const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity;
 var
 var
   aParent, Sibling: ICSSNode;
   aParent, Sibling: ICSSNode;
   aSpecificity: TCSSSpecificity;
   aSpecificity: TCSSSpecificity;
+  PseudoEl: TCSSElement;
 begin
 begin
   if OnlySpecificity then
   if OnlySpecificity then
   begin
   begin
@@ -1411,24 +1441,26 @@ begin
     end;
     end;
   boWhiteSpace:
   boWhiteSpace:
     begin
     begin
-    // descendant combinator
-    Result:=SelectorMatches(aBinary.Right,TestNode,false);
-    if Result<0 then exit;
-    aParent:=TestNode;
-    repeat
-      aParent:=aParent.GetCSSParent;
-      if aParent=nil then
-        exit(CSSSpecificityNoMatch);
-      aSpecificity:=SelectorMatches(aBinary.Left,aParent,false);
-      if aSpecificity>=0 then
-      begin
-        inc(Result,aSpecificity);
-        exit;
-      end
-      else if aSpecificity=CSSSpecificityInvalid then
-        exit(CSSSpecificityInvalid);
-    until false;
-    end
+      // descendant combinator
+      Result:=SelectorMatches(aBinary.Right,TestNode,false);
+      if Result<0 then exit;
+      aParent:=TestNode;
+      repeat
+        aParent:=aParent.GetCSSParent;
+        if aParent=nil then
+          exit(CSSSpecificityNoMatch);
+        aSpecificity:=SelectorMatches(aBinary.Left,aParent,false);
+        if aSpecificity>=0 then
+        begin
+          inc(Result,aSpecificity);
+          exit;
+        end
+        else if aSpecificity=CSSSpecificityInvalid then
+          exit(CSSSpecificityInvalid);
+      until false;
+    end;
+  boDoubleColon:
+    Result:=SelectorPseudoElementMatches(aBinary.Left,aBinary.Right,TestNode);
   else
   else
     // already warned by parser
     // already warned by parser
     {$IFDEF VerboseCSSResolver}
     {$IFDEF VerboseCSSResolver}
@@ -1437,6 +1469,65 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TCSSResolver.SelectorPseudoElementMatches(aLeft, aRight: TCSSElement;
+  const TestNode: ICSSNode): TCSSSpecificity;
+// pseudo element (function)
+var
+  ID: TCSSNumericalID;
+  aParent: ICSSNode;
+  aSpecificity: TCSSSpecificity;
+begin
+  Result:=CSSSpecificityInvalid;
+  if aRight is TCSSResolvedIdentifierElement then
+  begin
+    // pseudo element
+    ID:=TCSSResolvedIdentifierElement(aRight).NumericalID;
+    if ID<=0 then
+    begin
+      // already warned by parser
+      {$IFDEF VerboseCSSResolver}
+      Log(etWarning,20250224211914,'Invalid CSS pseudo element',aRight);
+      {$ENDIF}
+      exit;
+    end;
+    if ID<>TestNode.GetCSSPseudoElementID then
+      exit(CSSSpecificityNoMatch);
+    Result:=CSSSpecificityIdentifier;
+  end else if aRight is TCSSResolvedCallElement then begin
+    // pseudo element function
+    ID:=TCSSResolvedCallElement(aRight).NameNumericalID;
+    if ID<0 then
+    begin
+      // already warned by parser
+      {$IFDEF VerboseCSSResolver}
+      Log(etWarning,20250224212143,'Invalid CSS pseudo element function',aRight);
+      {$ENDIF}
+      exit;
+    end;
+    if ID<>TestNode.GetCSSPseudoElementID then
+      exit(CSSSpecificityNoMatch);
+    // todo: check parameters
+    Result:=CSSSpecificityIdentifier;
+  end else begin
+    // already warned by parser
+    {$IFDEF VerboseCSSResolver}
+    Log(etWarning,20250224212301,'Invalid CSS pseudo element',aRight);
+    {$ENDIF}
+  end;
+
+  if aLeft=nil then
+    exit; // unary ::Name
+
+  // test left side
+  aParent:=TestNode.GetCSSParent;
+  if aParent=nil then
+    exit(CSSSpecificityNoMatch);
+  aSpecificity:=SelectorMatches(aLeft,aParent,false);
+  if aSpecificity<0 then
+    exit(aSpecificity);
+  inc(Result,aSpecificity);
+end;
+
 function TCSSResolver.SelectorArrayMatches(anArray: TCSSArrayElement;
 function TCSSResolver.SelectorArrayMatches(anArray: TCSSArrayElement;
   const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity;
   const TestNode: ICSSNode; OnlySpecificity: boolean): TCSSSpecificity;
 var
 var
@@ -1976,10 +2067,10 @@ begin
     Result:=A=B;
     Result:=A=B;
 end;
 end;
 
 
-function TCSSResolver.SameValueText(A: PAnsiChar; ALen: integer; B: PAnsiChar;
-  BLen: integer): boolean;
+function TCSSResolver.SameValueText(A: PCSSChar; ALen: integer; B: PCSSChar; BLen: integer
+  ): boolean;
 var
 var
-  AC, BC: AnsiChar;
+  AC, BC: TCSSChar;
   i: Integer;
   i: Integer;
 begin
 begin
   if ALen<>BLen then exit(false);
   if ALen<>BLen then exit(false);
@@ -1990,8 +2081,13 @@ begin
     begin
     begin
       AC:=A^;
       AC:=A^;
       BC:=B^;
       BC:=B^;
-      if (AC<>BC) and (UpCase(AC)<>UpCase(BC)) then
-        exit(false);
+      if (AC<>BC) then
+      begin
+        if (AC in ['a'..'z']) then AC:=TCSSChar(ord(AC)-32);
+        if (BC in ['a'..'z']) then BC:=TCSSChar(ord(BC)-32);
+        if AC<>BC then
+          exit(false);
+      end;
       inc(A);
       inc(A);
       inc(B);
       inc(B);
     end;
     end;
@@ -2004,22 +2100,24 @@ function TCSSResolver.PosSubString(const SearchStr, Str: TCSSString): integer;
 var
 var
   SearchLen: SizeInt;
   SearchLen: SizeInt;
   i: Integer;
   i: Integer;
-  SearchP, StrP: PAnsiChar;
-  AC, BC: AnsiChar;
+  SearchP, StrP: PCSSChar;
+  AC, BC: TCSSChar;
 begin
 begin
   Result:=0;
   Result:=0;
   if SearchStr='' then exit;
   if SearchStr='' then exit;
   if Str='' then exit;
   if Str='' then exit;
   if StringComparison=crscCaseInsensitive then
   if StringComparison=crscCaseInsensitive then
   begin
   begin
-    SearchP:=PAnsiChar(SearchStr);
-    StrP:=PAnsiChar(Str);
+    SearchP:=PCSSChar(SearchStr);
+    StrP:=PCSSChar(Str);
     SearchLen:=length(SearchStr);
     SearchLen:=length(SearchStr);
     AC:=SearchP^;
     AC:=SearchP^;
+    if AC in ['a'..'z'] then AC:=TCSSChar(ord(AC)-32);
     for i:=0 to length(Str)-SearchLen do
     for i:=0 to length(Str)-SearchLen do
     begin
     begin
       BC:=StrP^;
       BC:=StrP^;
-      if (upcase(AC)=upcase(BC)) and SameValueText(SearchP,SearchLen,StrP,SearchLen) then
+      if BC in ['a'..'z'] then BC:=TCSSChar(ord(BC)-32);
+      if (AC=BC) and SameValueText(SearchP,SearchLen,StrP,SearchLen) then
         exit(i+1);
         exit(i+1);
       inc(StrP);
       inc(StrP);
     end;
     end;
@@ -2689,9 +2787,9 @@ begin
   begin
   begin
     // not yet resolved
     // not yet resolved
     aName:=El.Name;
     aName:=El.Name;
-    if Kind=nikPseudoClass then
+    if Kind in [nikPseudoClass,nikPseudoElement] then
     begin
     begin
-      // pseudo attributes are ASCII case insensitive
+      // pseudo attributes and elements are ASCII case insensitive
       System.Delete(aName,1,1);
       System.Delete(aName,1,1);
       aName:=lowercase(aName);
       aName:=lowercase(aName);
     end;
     end;
@@ -2903,13 +3001,7 @@ begin
   // find all matching rules in all stylesheets
   // find all matching rules in all stylesheets
   for aLayerIndex:=0 to length(FLayers)-1 do
   for aLayerIndex:=0 to length(FLayers)-1 do
     with FLayers[aLayerIndex] do begin
     with FLayers[aLayerIndex] do begin
-      case Origin of
-      cssoUserAgent: FSourceSpecificity:=CSSSpecificityUserAgent;
-      cssoUser: FSourceSpecificity:=CSSSpecificityUser;
-      else
-        FSourceSpecificity:=CSSSpecificityAuthor;
-      end;
-
+      FSourceSpecificity:=CSSOriginToSpecifity[Origin];
       for i:=0 to ElementCount-1 do
       for i:=0 to ElementCount-1 do
         ComputeElement(Elements[i].Element);
         ComputeElement(Elements[i].Element);
     end;
     end;

+ 237 - 25
packages/fcl-css/src/fpcssresparser.pas

@@ -119,6 +119,7 @@ type
   TCSSNumericalIDKind = (
   TCSSNumericalIDKind = (
     nikAttribute,
     nikAttribute,
     nikPseudoClass, // e.g. "hover" of ":hover"
     nikPseudoClass, // e.g. "hover" of ":hover"
+    nikPseudoElement, // e.g. "first-line" of "::first-line"
     nikPseudoFunction, // e.g. "is" of ":is()"
     nikPseudoFunction, // e.g. "is" of ":is()"
     nikType,
     nikType,
     nikKeyword,
     nikKeyword,
@@ -132,6 +133,7 @@ const
   CSSNumericalIDKindNames: array[TCSSNumericalIDKind] of TCSSString = (
   CSSNumericalIDKindNames: array[TCSSNumericalIDKind] of TCSSString = (
     'Type',
     'Type',
     'PseudoClass',
     'PseudoClass',
+    'PseudoElement',
     'PseudoFunction',
     'PseudoFunction',
     'Attribute',
     'Attribute',
     'Keyword',
     'Keyword',
@@ -309,22 +311,6 @@ type
     Index: TCSSNumericalID;
     Index: TCSSNumericalID;
   end;
   end;
 
 
-  { TCSSPseudoClassDesc }
-
-  TCSSPseudoClassDesc = class(TCSSRegistryNamedItem)
-  public
-  end;
-  TCSSPseudoClassDescClass = class of TCSSPseudoClassDesc;
-  TCSSPseudoClassDescArray = array of TCSSPseudoClassDesc;
-
-  { TCSSTypeDesc }
-
-  TCSSTypeDesc = class(TCSSRegistryNamedItem)
-  public
-  end;
-  TCSSTypeDescClass = class of TCSSTypeDesc;
-  TCSSTypeDescArray = array of TCSSTypeDesc;
-
   { TCSSAttributeKeyData }
   { TCSSAttributeKeyData }
 
 
   TCSSAttributeKeyData = class(TCSSElementOwnedData)
   TCSSAttributeKeyData = class(TCSSElementOwnedData)
@@ -355,11 +341,37 @@ type
       // used by the cascade algorithm to delete all overwritten properties
       // used by the cascade algorithm to delete all overwritten properties
     OnCheck: TCheckEvent; // called by the parser after reading a declaration and there is no var()
     OnCheck: TCheckEvent; // called by the parser after reading a declaration and there is no var()
       // return false if invalid, so the resolver skips this declaration
       // return false if invalid, so the resolver skips this declaration
-    OnSplitShorthand: TSplitShorthandEvent; // called by resolver after resolving var(), if any value is empty, the initialvalue is used
+    OnSplitShorthand: TSplitShorthandEvent; // called by resolver after resolving var(), if any value is empty, the InitialValue is used
   end;
   end;
   TCSSAttributeDescClass = class of TCSSAttributeDesc;
   TCSSAttributeDescClass = class of TCSSAttributeDesc;
   TCSSAttributeDescArray = array of TCSSAttributeDesc;
   TCSSAttributeDescArray = array of TCSSAttributeDesc;
 
 
+  { TCSSPseudoClassDesc }
+
+  TCSSPseudoClassDesc = class(TCSSRegistryNamedItem)
+  public
+  end;
+  TCSSPseudoClassDescClass = class of TCSSPseudoClassDesc;
+  TCSSPseudoClassDescArray = array of TCSSPseudoClassDesc;
+
+  { TCSSPseudoElementDesc }
+
+  TCSSPseudoElementDesc = class(TCSSRegistryNamedItem)
+  public
+    Attributes: TCSSAttributeDescArray; // allowed attributes
+    IsFunction: boolean;
+  end;
+  TCSSPseudoElementDescClass = class of TCSSPseudoElementDesc;
+  TCSSPseudoElementDescArray = array of TCSSPseudoElementDesc;
+
+  { TCSSTypeDesc }
+
+  TCSSTypeDesc = class(TCSSRegistryNamedItem)
+  public
+  end;
+  TCSSTypeDescClass = class of TCSSTypeDesc;
+  TCSSTypeDescArray = array of TCSSTypeDesc;
+
   { TCSSRegistry }
   { TCSSRegistry }
 
 
   TCSSRegistry = class
   TCSSRegistry = class
@@ -369,6 +381,7 @@ type
     FHashLists: array[TCSSNumericalIDKind] of TFPHashList; // name to TCSSRegistryNamedItem
     FHashLists: array[TCSSNumericalIDKind] of TFPHashList; // name to TCSSRegistryNamedItem
     FKeywordCount: TCSSNumericalID;
     FKeywordCount: TCSSNumericalID;
     FPseudoClassCount: TCSSNumericalID;
     FPseudoClassCount: TCSSNumericalID;
+    FPseudoElementCount: TCSSNumericalID;
     FPseudoFunctionCount: TCSSNumericalID;
     FPseudoFunctionCount: TCSSNumericalID;
     FStamp, FModifiedStamp: TCSSNumericalID;
     FStamp, FModifiedStamp: TCSSNumericalID;
     FTypeCount: TCSSNumericalID;
     FTypeCount: TCSSNumericalID;
@@ -401,7 +414,7 @@ type
       TopLeftID, TopRightID, BottomLeftID, BottomRightID: TCSSNumericalID; const Found: TCSSStringArray); overload;
       TopLeftID, TopRightID, BottomLeftID, BottomRightID: TCSSNumericalID; const Found: TCSSStringArray); overload;
     property AttributeCount: TCSSNumericalID read FAttributeCount;
     property AttributeCount: TCSSNumericalID read FAttributeCount;
   public
   public
-    // pseudo classes
+    // pseudo classes, e.g. :hover
     PseudoClasses: TCSSPseudoClassDescArray; // Note: PseudoClasses[0] is nil to spot bugs easily
     PseudoClasses: TCSSPseudoClassDescArray; // Note: PseudoClasses[0] is nil to spot bugs easily
     PseudoClass_ClassOf: TCSSPseudoClassDescClass;
     PseudoClass_ClassOf: TCSSPseudoClassDescClass;
     function AddPseudoClass(aPseudo: TCSSPseudoClassDesc): TCSSPseudoClassDesc; overload;
     function AddPseudoClass(aPseudo: TCSSPseudoClassDesc): TCSSPseudoClassDesc; overload;
@@ -410,13 +423,22 @@ type
     function IndexOfPseudoClassName(const aName: TCSSString): TCSSNumericalID; overload;
     function IndexOfPseudoClassName(const aName: TCSSString): TCSSNumericalID; overload;
     property PseudoClassCount: TCSSNumericalID read FPseudoClassCount;
     property PseudoClassCount: TCSSNumericalID read FPseudoClassCount;
   public
   public
-    // pseudo functions lowercase (they are parsed case insensitive)
-    PseudoFunctions: TCSSStringArray;
+    // pseudo element, e.g. ::first-line
+    PseudoElements: TCSSPseudoElementDescArray;
+    PseudoElement_ClassOf: TCSSPseudoElementDescClass;
+    function AddPseudoElement(aPseudo: TCSSPseudoElementDesc): TCSSPseudoElementDesc; overload;
+    function AddPseudoElement(const aName: TCSSString; aClass: TCSSPseudoElementDescClass = nil): TCSSPseudoElementDesc; overload;
+    function FindPseudoElement(const aName: TCSSString): TCSSPseudoElementDesc; overload;
+    function IndexOfPseudoElementName(const aName: TCSSString): TCSSNumericalID; overload;
+    property PseudoElementCount: TCSSNumericalID read FPseudoElementCount;
+  public
+    // pseudo functions lowercase (they are parsed case insensitive), e.g. :not()
+    PseudoFunctions: TCSSStringArray; // Note: PseudoFunctions[0] is nil to spot bugs easily
     function AddPseudoFunction(const aName: TCSSString): TCSSNumericalID; overload;
     function AddPseudoFunction(const aName: TCSSString): TCSSNumericalID; overload;
     function IndexOfPseudoFunction(const aName: TCSSString): TCSSNumericalID; overload;
     function IndexOfPseudoFunction(const aName: TCSSString): TCSSNumericalID; overload;
     property PseudoFunctionCount: TCSSNumericalID read FPseudoFunctionCount;
     property PseudoFunctionCount: TCSSNumericalID read FPseudoFunctionCount;
   public
   public
-    // types
+    // types, e.g. div
     Types: TCSSTypeDescArray; // Note: Types[0] is nil to spot bugs easily
     Types: TCSSTypeDescArray; // Note: Types[0] is nil to spot bugs easily
     Type_ClassOf: TCSSTypeDescClass;
     Type_ClassOf: TCSSTypeDescClass;
     function AddType(aType: TCSSTypeDesc): TCSSTypeDesc; overload;
     function AddType(aType: TCSSTypeDesc): TCSSTypeDesc; overload;
@@ -426,7 +448,7 @@ type
     property TypeCount: TCSSNumericalID read FTypeCount;
     property TypeCount: TCSSNumericalID read FTypeCount;
   public
   public
     // keywords
     // keywords
-    Keywords: TCSSStringArray;
+    Keywords: TCSSStringArray; // Note: Keywords[0] is nil to spot bugs easily
     kwFirstColor, kwLastColor, kwTransparent: TCSSNumericalID;
     kwFirstColor, kwLastColor, kwTransparent: TCSSNumericalID;
     function AddKeyword(const aName: TCSSString): TCSSNumericalID; overload;
     function AddKeyword(const aName: TCSSString): TCSSNumericalID; overload;
     procedure AddKeywords(const Names: TCSSStringArray; out First, Last: TCSSNumericalID); overload;
     procedure AddKeywords(const Names: TCSSStringArray; out First, Last: TCSSNumericalID); overload;
@@ -436,8 +458,8 @@ type
     function GetKeywordColor(KeywordID: TCSSNumericalID): TCSSAlphaColor; virtual; overload;
     function GetKeywordColor(KeywordID: TCSSNumericalID): TCSSAlphaColor; virtual; overload;
     property KeywordCount: TCSSNumericalID read FKeywordCount;
     property KeywordCount: TCSSNumericalID read FKeywordCount;
   public
   public
-    // attribute functions
-    AttrFunctions: TCSSStringArray;
+    // attribute functions, e.g. var()
+    AttrFunctions: TCSSStringArray; // Note: AttrFunctions[0] is nil to spot bugs easily
     const afVar = CSSAttrFuncVar;
     const afVar = CSSAttrFuncVar;
     function AddAttrFunction(const aName: TCSSString): TCSSNumericalID; overload;
     function AddAttrFunction(const aName: TCSSString): TCSSNumericalID; overload;
     function IndexOfAttrFunction(const aName: TCSSString): TCSSNumericalID; overload;
     function IndexOfAttrFunction(const aName: TCSSString): TCSSNumericalID; overload;
@@ -575,6 +597,8 @@ type
     function GetAttributeDesc(AttrID: TCSSNumericalID): TCSSAttributeDesc; virtual;
     function GetAttributeDesc(AttrID: TCSSNumericalID): TCSSAttributeDesc; virtual;
     function GetTypeID(const aName: TCSSString): TCSSNumericalID; virtual;
     function GetTypeID(const aName: TCSSString): TCSSNumericalID; virtual;
     function GetPseudoClassID(const aName: TCSSString): TCSSNumericalID; virtual;
     function GetPseudoClassID(const aName: TCSSString): TCSSNumericalID; virtual;
+    function GetPseudoElementID(const aName: TCSSString): TCSSNumericalID; virtual;
+    function GetPseudoElFuncID(const aName: TCSSString): TCSSNumericalID; virtual;
     function GetPseudoFunctionID(const aName: TCSSString): TCSSNumericalID; virtual;
     function GetPseudoFunctionID(const aName: TCSSString): TCSSNumericalID; virtual;
 
 
     property CSSRegistry: TCSSRegistry read FCSSRegistry write SetCSSRegistry;
     property CSSRegistry: TCSSRegistry read FCSSRegistry write SetCSSRegistry;
@@ -592,13 +616,17 @@ type
     function ResolveAttribute(El: TCSSResolvedIdentifierElement): TCSSNumericalID; virtual;
     function ResolveAttribute(El: TCSSResolvedIdentifierElement): TCSSNumericalID; virtual;
     function ResolveType(El: TCSSResolvedIdentifierElement): TCSSNumericalID; virtual;
     function ResolveType(El: TCSSResolvedIdentifierElement): TCSSNumericalID; virtual;
     function ResolvePseudoClass(El: TCSSResolvedPseudoClassElement): TCSSNumericalID; virtual;
     function ResolvePseudoClass(El: TCSSResolvedPseudoClassElement): TCSSNumericalID; virtual;
+    function ResolvePseudoElement(El: TCSSResolvedIdentifierElement): TCSSNumericalID; virtual;
+    function ResolvePseudoElementFunction(El: TCSSResolvedCallElement): TCSSNumericalID; virtual;
     function ResolvePseudoFunction(El: TCSSResolvedCallElement): TCSSNumericalID; virtual;
     function ResolvePseudoFunction(El: TCSSResolvedCallElement): TCSSNumericalID; virtual;
     function ParseCall(aName: TCSSString; IsSelector: boolean): TCSSCallElement; override;
     function ParseCall(aName: TCSSString; IsSelector: boolean): TCSSCallElement; override;
     function ParseDeclaration(aIsAt: Boolean): TCSSDeclarationElement; override;
     function ParseDeclaration(aIsAt: Boolean): TCSSDeclarationElement; override;
+    function ParsePseudoElement: TCSSElement; override;
     function ParseSelector: TCSSElement; override;
     function ParseSelector: TCSSElement; override;
     procedure CheckSelector(El: TCSSElement); virtual;
     procedure CheckSelector(El: TCSSElement); virtual;
     procedure CheckSelectorArray(anArray: TCSSArrayElement); virtual;
     procedure CheckSelectorArray(anArray: TCSSArrayElement); virtual;
     procedure CheckSelectorArrayBinary(aBinary: TCSSBinaryElement); virtual;
     procedure CheckSelectorArrayBinary(aBinary: TCSSBinaryElement); virtual;
+    procedure CheckSelectorUnary(aUnary: TCSSUnaryElement); virtual;
     procedure CheckSelectorBinary(aBinary: TCSSBinaryElement); virtual;
     procedure CheckSelectorBinary(aBinary: TCSSBinaryElement); virtual;
     procedure CheckSelectorList(aList: TCSSListElement); virtual;
     procedure CheckSelectorList(aList: TCSSListElement); virtual;
     procedure CheckNthChildParams(aCall: TCSSResolvedCallElement); virtual;
     procedure CheckNthChildParams(aCall: TCSSResolvedCallElement); virtual;
@@ -653,6 +681,8 @@ begin
     Attribute_ClassOf:=TCSSAttributeDesc;
     Attribute_ClassOf:=TCSSAttributeDesc;
   if PseudoClass_ClassOf=nil then
   if PseudoClass_ClassOf=nil then
     PseudoClass_ClassOf:=TCSSPseudoClassDesc;
     PseudoClass_ClassOf:=TCSSPseudoClassDesc;
+  if PseudoElement_ClassOf=nil then
+    PseudoElement_ClassOf:=TCSSPseudoElementDesc;
   if Type_ClassOf=nil then
   if Type_ClassOf=nil then
     Type_ClassOf:=TCSSTypeDesc;
     Type_ClassOf:=TCSSTypeDesc;
 
 
@@ -666,6 +696,11 @@ begin
   for i:=0 to length(PseudoClasses)-1 do PseudoClasses[i]:=nil;
   for i:=0 to length(PseudoClasses)-1 do PseudoClasses[i]:=nil;
   FPseudoClassCount:=1; // index 0 is CSSIDNone
   FPseudoClassCount:=1; // index 0 is CSSIDNone
 
 
+  // init pseudo elements
+  SetLength(PseudoElements,32);
+  for i:=0 to length(PseudoElements)-1 do PseudoElements[i]:=nil;
+  FPseudoElementCount:=1; // index 0 is CSSIDNone
+
   // init pseudo functions
   // init pseudo functions
   SetLength(PseudoFunctions,16);
   SetLength(PseudoFunctions,16);
   FPseudoFunctionCount:=1; // index 0 is CSSIDNone
   FPseudoFunctionCount:=1; // index 0 is CSSIDNone
@@ -712,6 +747,9 @@ begin
   if AddPseudoClass('only-of-type').Index<>CSSPseudoID_OnlyOfType then
   if AddPseudoClass('only-of-type').Index<>CSSPseudoID_OnlyOfType then
     raise Exception.Create('20240623170609');
     raise Exception.Create('20240623170609');
 
 
+  // init pseudo elements
+  // none by default
+
   // init pseudo functions
   // init pseudo functions
   if AddPseudoFunction('not')<>CSSCallID_Not then
   if AddPseudoFunction('not')<>CSSCallID_Not then
     raise Exception.Create('20240625183757');
     raise Exception.Create('20240625183757');
@@ -776,6 +814,12 @@ begin
   PseudoClasses:=nil;
   PseudoClasses:=nil;
   FPseudoClassCount:=0;
   FPseudoClassCount:=0;
 
 
+  // pseudo elements
+  for i:=1 to PseudoElementCount-1 do
+    FreeAndNil(PseudoElements[i]);
+  PseudoElements:=nil;
+  FPseudoElementCount:=0;
+
   // types
   // types
   for i:=1 to TypeCount-1 do
   for i:=1 to TypeCount-1 do
     FreeAndNil(Types[i]);
     FreeAndNil(Types[i]);
@@ -827,6 +871,7 @@ var
   TypeDesc: TCSSTypeDesc;
   TypeDesc: TCSSTypeDesc;
   i: Integer;
   i: Integer;
   aName: TCSSString;
   aName: TCSSString;
+  PseudoElementDesc: TCSSPseudoElementDesc;
 begin
 begin
   if AttributeCount>length(Attributes) then
   if AttributeCount>length(Attributes) then
     raise Exception.Create('20240629102438');
     raise Exception.Create('20240629102438');
@@ -885,6 +930,27 @@ begin
       raise Exception.Create('20240629101227 pseudo class ID='+IntToStr(ID)+' "'+aName+'" IndexOf failed: '+IntToStr(ID2));
       raise Exception.Create('20240629101227 pseudo class ID='+IntToStr(ID)+' "'+aName+'" IndexOf failed: '+IntToStr(ID2));
   end;
   end;
 
 
+  if PseudoElementCount>length(PseudoElements) then
+    raise Exception.Create('20250220140108');
+  for ID:=1 to PseudoElementCount-1 do
+  begin
+    PseudoElementDesc:=PseudoElements[ID];
+    if PseudoElementDesc=nil then
+      raise Exception.Create('20250220140126 pseudo element ID='+IntToStr(ID)+' Desc=nil');
+    aName:=PseudoElementDesc.Name;
+    if aName='' then
+      raise Exception.Create('20250220140201 pseudo element ID='+IntToStr(ID)+' missing name');
+    if length(aName)>255 then
+      raise Exception.Create('20250220140202 pseudo element ID='+IntToStr(ID)+' name too long "'+aName+'"');
+    if aName[1]=':' then
+      raise Exception.Create('20250220140204 pseudo element ID='+IntToStr(ID)+' invalid name "'+aName+'"');
+    if PseudoElementDesc.Index<>ID then
+      raise Exception.Create('20250220140205 pseudo element ID='+IntToStr(ID)+' Desc.Index='+IntToStr(PseudoElementDesc.Index)+' "'+aName+'"');
+    ID2:=IndexOfPseudoElementName(PseudoElementDesc.Name);
+    if ID2<>ID then
+      raise Exception.Create('20250220140207 pseudo element ID='+IntToStr(ID)+' "'+aName+'" IndexOf failed: '+IntToStr(ID2));
+  end;
+
   if PseudoFunctionCount>length(PseudoFunctions) then
   if PseudoFunctionCount>length(PseudoFunctions) then
     raise Exception.Create('20240629103430');
     raise Exception.Create('20240629103430');
   for ID:=1 to PseudoFunctionCount-1 do
   for ID:=1 to PseudoFunctionCount-1 do
@@ -1152,6 +1218,8 @@ function TCSSRegistry.AddPseudoClass(const aName: TCSSString;
 begin
 begin
   if aName='' then
   if aName='' then
     raise ECSSParser.Create('missing name');
     raise ECSSParser.Create('missing name');
+  if aName<>lowercase(aName) then
+    raise ECSSParser.Create('name not lowercase');
   if FindPseudoClass(aName)<>nil then
   if FindPseudoClass(aName)<>nil then
     raise ECSSParser.Create('duplicate pseudo class "'+aName+'"');
     raise ECSSParser.Create('duplicate pseudo class "'+aName+'"');
   if aClass=nil then
   if aClass=nil then
@@ -1180,6 +1248,62 @@ begin
     Result:=-1;
     Result:=-1;
 end;
 end;
 
 
+function TCSSRegistry.AddPseudoElement(aPseudo: TCSSPseudoElementDesc): TCSSPseudoElementDesc;
+begin
+  Result:=aPseudo;
+  if aPseudo.Name='' then
+    raise ECSSParser.Create('missing name');
+  if FindPseudoElement(aPseudo.Name)<>nil then
+    raise ECSSParser.Create('duplicate pseudo element "'+aPseudo.Name+'"');
+
+  if PseudoElementCount=length(PseudoElements) then
+  begin
+    if PseudoElementCount<32 then
+      SetLength(PseudoElements,32)
+    else
+      SetLength(PseudoElements,2*PseudoElementCount);
+    FillByte(PseudoElements[PseudoElementCount],SizeOf(Pointer)*(length(PseudoElements)-PseudoElementCount),0);
+  end;
+  PseudoElements[PseudoElementCount]:=aPseudo;
+  aPseudo.Index:=PseudoElementCount;
+  FHashLists[nikPseudoElement].Add(aPseudo.Name,aPseudo);
+  inc(FPseudoElementCount);
+  ChangeStamp;
+end;
+
+function TCSSRegistry.AddPseudoElement(const aName: TCSSString; aClass: TCSSPseudoElementDescClass
+  ): TCSSPseudoElementDesc;
+begin
+  if aName='' then
+    raise ECSSParser.Create('missing name');
+  if aName<>lowercase(aName) then
+    raise ECSSParser.Create('name not lowercase');
+  if FindPseudoElement(aName)<>nil then
+    raise ECSSParser.Create('duplicate pseudo element "'+aName+'"');
+  if aClass=nil then
+    aClass:=PseudoElement_ClassOf;
+
+  Result:=aClass.Create;
+  Result.Name:=aName;
+  AddPseudoElement(Result);
+end;
+
+function TCSSRegistry.FindPseudoElement(const aName: TCSSString): TCSSPseudoElementDesc;
+begin
+  Result:=TCSSPseudoElementDesc(FHashLists[nikPseudoElement].Find(aName));
+end;
+
+function TCSSRegistry.IndexOfPseudoElementName(const aName: TCSSString): TCSSNumericalID;
+var
+  aPseudo: TCSSPseudoElementDesc;
+begin
+  aPseudo:=TCSSPseudoElementDesc(FHashLists[nikPseudoElement].Find(aName));
+  if aPseudo<>nil then
+    Result:=aPseudo.Index
+  else
+    Result:=-1;
+end;
+
 function TCSSRegistry.AddPseudoFunction(const aName: TCSSString
 function TCSSRegistry.AddPseudoFunction(const aName: TCSSString
   ): TCSSNumericalID;
   ): TCSSNumericalID;
 begin
 begin
@@ -2121,6 +2245,20 @@ begin
   Result:=CSSRegistry.IndexOfPseudoClassName(aName);
   Result:=CSSRegistry.IndexOfPseudoClassName(aName);
 end;
 end;
 
 
+function TCSSBaseResolver.GetPseudoElementID(const aName: TCSSString): TCSSNumericalID;
+begin
+  Result:=CSSRegistry.IndexOfPseudoElementName(aName);
+  if (Result>=0) and CSSRegistry.PseudoElements[Result].IsFunction then
+    Result:=-1;
+end;
+
+function TCSSBaseResolver.GetPseudoElFuncID(const aName: TCSSString): TCSSNumericalID;
+begin
+  Result:=CSSRegistry.IndexOfPseudoElementName(aName);
+  if (Result>=0) and not CSSRegistry.PseudoElements[Result].IsFunction then
+    Result:=-1;
+end;
+
 function TCSSBaseResolver.GetPseudoFunctionID(const aName: TCSSString): TCSSNumericalID;
 function TCSSBaseResolver.GetPseudoFunctionID(const aName: TCSSString): TCSSNumericalID;
 begin
 begin
   Result:=CSSRegistry.IndexOfPseudoFunction(aName);
   Result:=CSSRegistry.IndexOfPseudoFunction(aName);
@@ -2186,6 +2324,50 @@ begin
     El.NumericalID:=Result;
     El.NumericalID:=Result;
 end;
 end;
 
 
+function TCSSResolverParser.ResolvePseudoElement(El: TCSSResolvedIdentifierElement
+  ): TCSSNumericalID;
+var
+  aName: TCSSString;
+begin
+  // pseudo elements are ASCII case insensitive
+  aName:=lowercase(El.Name);
+
+  if El.NumericalID<>CSSIDNone then
+    raise Exception.Create('20250224203646');
+
+  El.Kind:=nikPseudoElement;
+  Result:=Resolver.GetPseudoElementID(aName);
+  //writeln('TCSSResolverParser.ResolvePseudoElement ',aName,' ID=',Result);
+  if Result<=CSSIDNone then
+  begin
+    El.NumericalID:=-1;
+    Log(etWarning,20250224203703,'unknown pseudo element "'+aName+'"',El);
+  end else
+    El.NumericalID:=Result;
+end;
+
+function TCSSResolverParser.ResolvePseudoElementFunction(El: TCSSResolvedCallElement
+  ): TCSSNumericalID;
+var
+  aName: TCSSString;
+begin
+  // pseudo elements are ASCII case insensitive
+  aName:=lowercase(El.Name);
+
+  if El.NameNumericalID<>CSSIDNone then
+    raise Exception.Create('20250224210628');
+
+  El.Kind:=nikPseudoElement;
+  Result:=Resolver.GetPseudoElFuncID(aName);
+  //writeln('TCSSResolverParser.ResolvePseudoElement ',aName,' ID=',Result);
+  if Result<=CSSIDNone then
+  begin
+    El.NameNumericalID:=-1;
+    Log(etWarning,20250224203703,'unknown pseudo element function "'+aName+'"',El);
+  end else
+    El.NameNumericalID:=Result;
+end;
+
 function TCSSResolverParser.ResolvePseudoFunction(El: TCSSResolvedCallElement
 function TCSSResolverParser.ResolvePseudoFunction(El: TCSSResolvedCallElement
   ): TCSSNumericalID;
   ): TCSSNumericalID;
 var
 var
@@ -2300,6 +2482,17 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TCSSResolverParser.ParsePseudoElement: TCSSElement;
+begin
+  Result:=inherited ParsePseudoElement;
+  if Result is TCSSResolvedIdentifierElement then
+    ResolvePseudoElement(TCSSResolvedIdentifierElement(Result))
+  else if Result is TCSSResolvedCallElement then
+    ResolvePseudoElementFunction(TCSSResolvedCallElement(Result))
+  else
+    Log(etWarning,20250224210802,'Unknown CSS selector pseudo element',Result);
+end;
+
 function TCSSResolverParser.ParseSelector: TCSSElement;
 function TCSSResolverParser.ParseSelector: TCSSElement;
 begin
 begin
   Result:=inherited ParseSelector;
   Result:=inherited ParseSelector;
@@ -2321,6 +2514,8 @@ begin
   else if C=TCSSResolvedPseudoClassElement then
   else if C=TCSSResolvedPseudoClassElement then
     // e.g. :pseudoclass {}
     // e.g. :pseudoclass {}
     ResolvePseudoClass(TCSSResolvedPseudoClassElement(El))
     ResolvePseudoClass(TCSSResolvedPseudoClassElement(El))
+  else if C=TCSSUnaryElement then
+    CheckSelectorUnary(TCSSUnaryElement(El))
   else if C=TCSSBinaryElement then
   else if C=TCSSBinaryElement then
     CheckSelectorBinary(TCSSBinaryElement(El))
     CheckSelectorBinary(TCSSBinaryElement(El))
   else if C=TCSSArrayElement then
   else if C=TCSSArrayElement then
@@ -2430,13 +2625,30 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TCSSResolverParser.CheckSelectorUnary(aUnary: TCSSUnaryElement);
+begin
+  case aUnary.Operation of
+  uoDoubleColon:
+    ; // right side was done in ParsePseudoElement
+  else
+    Log(etWarning,20250225103443,'Invalid CSS unary selector '+UnaryOperators[aUnary.Operation],aUnary);
+  end;
+end;
+
 procedure TCSSResolverParser.CheckSelectorBinary(aBinary: TCSSBinaryElement);
 procedure TCSSResolverParser.CheckSelectorBinary(aBinary: TCSSBinaryElement);
 begin
 begin
   case aBinary.Operation of
   case aBinary.Operation of
   boGT,
   boGT,
   boPlus,
   boPlus,
   boTilde,
   boTilde,
-  boWhiteSpace: ;
+  boWhiteSpace:
+    ;
+  boDoubleColon:
+    begin
+    CheckSelector(aBinary.Left);
+    // right side was done in ParsePseudoElement
+    exit;
+    end
   else
   else
     Log(etWarning,20240625153307,'Invalid CSS binary selector '+BinaryOperators[aBinary.Operation],aBinary);
     Log(etWarning,20240625153307,'Invalid CSS binary selector '+BinaryOperators[aBinary.Operation],aBinary);
   end;
   end;

+ 1 - 6
packages/fcl-css/src/fpcssscanner.pp

@@ -952,12 +952,7 @@ begin
       if csoDisablePseudo in Options then
       if csoDisablePseudo in Options then
         CharToken(ctkCOLON)
         CharToken(ctkCOLON)
       else if (TokenStr[1]=':') then
       else if (TokenStr[1]=':') then
-        begin
-        if (TokenStr[2] in AlNumIden) then
-          Result:=DoIdentifierLike
-        else
-          Result:=ctkDoubleCOLON
-        end
+        TwoCharsToken(ctkDoubleCOLON)
       else if (TokenStr[1] in AlNumIden) then
       else if (TokenStr[1] in AlNumIden) then
         Result:=DoIdentifierLike
         Result:=DoIdentifierLike
       else
       else

+ 1 - 2
packages/fcl-css/tests/tccssparser.pp

@@ -581,14 +581,13 @@ var
   List : TCSSListElement;
   List : TCSSListElement;
 
 
 begin
 begin
-  R:=ParseRule('input:enabled:read-write:-webkit-any(:focus,:hover)::-webkit-clear-button {  }');
+  R:=ParseRule('input:enabled:read-write:-webkit-any(:focus,:hover) {  }');
   AssertEquals('No rule children',0,R.ChildCount);
   AssertEquals('No rule children',0,R.ChildCount);
   AssertEquals('selector count',1,R.SelectorCount);
   AssertEquals('selector count',1,R.SelectorCount);
   List:=TCSSListElement(CheckClass('List',TCSSListElement,R.Selectors[0]));
   List:=TCSSListElement(CheckClass('List',TCSSListElement,R.Selectors[0]));
   CheckList(List,0,'input');
   CheckList(List,0,'input');
   CheckList(List,1,':enabled');
   CheckList(List,1,':enabled');
   CheckList(List,2,':read-write');
   CheckList(List,2,':read-write');
-  CheckList(List,4,'::-webkit-clear-button');
 end;
 end;
 
 
 procedure TTestCSSParser.TestQueryPrefixedEmptyRule;
 procedure TTestCSSParser.TestQueryPrefixedEmptyRule;

+ 238 - 10
packages/fcl-css/tests/tccssresolver.pp

@@ -216,7 +216,7 @@ type
     // computed by resolver:
     // computed by resolver:
     Rules: TCSSSharedRuleList; // owned by resolver
     Rules: TCSSSharedRuleList; // owned by resolver
     Values: TCSSAttributeValues;
     Values: TCSSAttributeValues;
-
+    // explicit attributes: can be queried by CSS, e.g. div[foo=3px]
     ExplicitAttributes: array[TDemoNodeAttribute] of TCSSString;
     ExplicitAttributes: array[TDemoNodeAttribute] of TCSSString;
 
 
     constructor Create(AOwner: TComponent); override;
     constructor Create(AOwner: TComponent); override;
@@ -232,22 +232,24 @@ type
     function GetCSSID: TCSSString; virtual;
     function GetCSSID: TCSSString; virtual;
     function GetCSSTypeName: TCSSString;
     function GetCSSTypeName: TCSSString;
     function GetCSSTypeID: TCSSNumericalID;
     function GetCSSTypeID: TCSSNumericalID;
-    function HasCSSClass(const aClassName: TCSSString): boolean; virtual;
+    function GetCSSPseudoElementName: TCSSString; virtual;
+    function GetCSSPseudoElementID: TCSSNumericalID; virtual;
     function GetCSSParent: ICSSNode; virtual;
     function GetCSSParent: ICSSNode; virtual;
+    function GetCSSDepth: integer; virtual;
     function GetCSSIndex: integer; virtual;
     function GetCSSIndex: integer; virtual;
     function GetCSSNextSibling: ICSSNode; virtual;
     function GetCSSNextSibling: ICSSNode; virtual;
     function GetCSSPreviousSibling: ICSSNode; virtual;
     function GetCSSPreviousSibling: ICSSNode; virtual;
-    function GetCSSChildCount: integer; virtual;
-    function GetCSSChild(const anIndex: integer): ICSSNode; virtual;
     function GetCSSNextOfType: ICSSNode; virtual;
     function GetCSSNextOfType: ICSSNode; virtual;
     function GetCSSPreviousOfType: ICSSNode; virtual;
     function GetCSSPreviousOfType: ICSSNode; virtual;
+    function GetCSSEmpty: boolean; virtual;
+    function GetCSSChildCount: integer; virtual;
+    function GetCSSChild(const anIndex: integer): ICSSNode; virtual;
+    function HasCSSClass(const aClassName: TCSSString): boolean; virtual;
     function GetCSSAttributeClass: TCSSString; virtual;
     function GetCSSAttributeClass: TCSSString; virtual;
     function GetCSSCustomAttribute(const AttrID: TCSSNumericalID): TCSSString; virtual;
     function GetCSSCustomAttribute(const AttrID: TCSSNumericalID): TCSSString; virtual;
     function HasCSSExplicitAttribute(const AttrID: TCSSNumericalID): boolean; virtual;
     function HasCSSExplicitAttribute(const AttrID: TCSSNumericalID): boolean; virtual;
     function GetCSSExplicitAttribute(const AttrID: TCSSNumericalID): TCSSString; virtual;
     function GetCSSExplicitAttribute(const AttrID: TCSSNumericalID): TCSSString; virtual;
     function HasCSSPseudoClass(const {%H-}AttrID: TCSSNumericalID): boolean; virtual;
     function HasCSSPseudoClass(const {%H-}AttrID: TCSSNumericalID): boolean; virtual;
-    function GetCSSEmpty: boolean; virtual;
-    function GetCSSDepth: integer; virtual;
 
 
     property Parent: TDemoNode read FParent write SetParent;
     property Parent: TDemoNode read FParent write SetParent;
     property NodeCount: integer read GetNodeCount;
     property NodeCount: integer read GetNodeCount;
@@ -275,6 +277,35 @@ type
   end;
   end;
   TDemoNodeClass = class of TDemoNode;
   TDemoNodeClass = class of TDemoNode;
 
 
+  { TDemoPseudoElement }
+
+  TDemoPseudoElement = class(TDemoNode)
+  public
+    constructor Create(AOwner: TComponent); override;
+    function GetCSSTypeName: TCSSString;
+    function GetCSSTypeID: TCSSNumericalID;
+    function GetCSSParent: ICSSNode; override;
+    function GetCSSIndex: integer; override;
+    function GetCSSNextSibling: ICSSNode; override;
+    function GetCSSPreviousSibling: ICSSNode; override;
+    function GetCSSNextOfType: ICSSNode; override;
+    function GetCSSPreviousOfType: ICSSNode; override;
+    function GetCSSEmpty: boolean; override;
+    function GetCSSChildCount: integer; override;
+    function GetCSSChild(const anIndex: integer): ICSSNode; override;
+    function HasCSSClass(const aClassName: TCSSString): boolean; override;
+    function GetCSSAttributeClass: TCSSString; override;
+  end;
+
+  { TDemoFirstLine }
+
+  TDemoFirstLine = class(TDemoPseudoElement)
+  public
+    class var DemoFirstLineID: TCSSNumericalID;
+    function GetCSSPseudoElementName: TCSSString; override;
+    function GetCSSPseudoElementID: TCSSNumericalID; override;
+  end;
+
   { TDemoDiv }
   { TDemoDiv }
 
 
   TDemoDiv = class(TDemoNode)
   TDemoDiv = class(TDemoNode)
@@ -342,7 +373,7 @@ type
   { TCustomTestNewCSSResolver }
   { TCustomTestNewCSSResolver }
 
 
   TCustomTestNewCSSResolver = class(TTestCase)
   TCustomTestNewCSSResolver = class(TTestCase)
-  Private
+  private
     FDoc: TDemoDocument;
     FDoc: TDemoDocument;
   protected
   protected
     procedure SetUp; override;
     procedure SetUp; override;
@@ -429,7 +460,7 @@ type
     // var()
     // var()
     procedure Test_Var_NoDefault;
     procedure Test_Var_NoDefault;
     procedure Test_Var_Inline_NoDefault;
     procedure Test_Var_Inline_NoDefault;
-      procedure Test_Var_Defaults;
+    procedure Test_Var_Defaults;
 
 
     // skipping for forward compatibility
     // skipping for forward compatibility
     // ToDo: invalid token in selector makes selector invalid
     // ToDo: invalid token in selector makes selector invalid
@@ -439,7 +470,10 @@ type
     // test skip invalid value  color: 3 red;
     // test skip invalid value  color: 3 red;
     // test skip invalid attribute  color: 3;
     // test skip invalid attribute  color: 3;
 
 
-    // pseudo elements
+    // pseudo elements (works like child combinator)
+    procedure Test_PseudoElement;
+    procedure Test_PseudoElement_Unary;
+    procedure Test_PseudoElement_PostfixSelectNothing;
   end;
   end;
 
 
 function LinesToStr(const Args: array of const): TCSSString;
 function LinesToStr(const Args: array of const): TCSSString;
@@ -833,6 +867,10 @@ begin
   if FindPseudoClass(DemoPseudoClassNames[pcHover]).Index<>DemoPseudoClassIDBase+ord(pcHover) then
   if FindPseudoClass(DemoPseudoClassNames[pcHover]).Index<>DemoPseudoClassIDBase+ord(pcHover) then
     raise Exception.Create('20231008232201');
     raise Exception.Create('20231008232201');
 
 
+  // register demo pseudo elements
+  TDemoFirstLine.DemoFirstLineID:=AddPseudoElement('first-line').Index;
+  AddPseudoElement('selection');
+
   // register demo element types
   // register demo element types
   for aType in TDemoElementType do
   for aType in TDemoElementType do
     AddDemoType(aType);
     AddDemoType(aType);
@@ -859,7 +897,7 @@ begin
   kwLTR:=AddKeyword('ltr');
   kwLTR:=AddKeyword('ltr');
   kwRTL:=AddKeyword('rtl');
   kwRTL:=AddKeyword('rtl');
 
 
-  // check parameters - - - - - - - - - - - - - - - - - - - - - - - -
+  // check attribute values - - - - - - - - - - - - - - - - - - - - - - - -
 
 
   // border-color
   // border-color
   DemoAttrs[naBorderColor].OnCheck:=@OnCheck_BorderColor;
   DemoAttrs[naBorderColor].OnCheck:=@OnCheck_BorderColor;
@@ -1023,6 +1061,7 @@ begin
   Clear;
   Clear;
   FreeAndNil(FNodes);
   FreeAndNil(FNodes);
   FreeAndNil(FCSSClasses);
   FreeAndNil(FCSSClasses);
+  FParent:=nil;
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
@@ -1300,11 +1339,109 @@ begin
   Result:=GetClassCSSTypeID;
   Result:=GetClassCSSTypeID;
 end;
 end;
 
 
+function TDemoNode.GetCSSPseudoElementName: TCSSString;
+begin
+  Result:='';
+end;
+
+function TDemoNode.GetCSSPseudoElementID: TCSSNumericalID;
+begin
+  Result:=CSSIDNone;
+end;
+
 class function TDemoNode.GetCSSTypeStyle: TCSSString;
 class function TDemoNode.GetCSSTypeStyle: TCSSString;
 begin
 begin
   Result:='';
   Result:='';
 end;
 end;
 
 
+{ TDemoPseudoElement }
+
+constructor TDemoPseudoElement.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  if not (AOwner is TDemoNode) then
+    raise Exception.Create('20250224153414');
+end;
+
+function TDemoPseudoElement.GetCSSTypeName: TCSSString;
+begin
+  Result:='';
+end;
+
+function TDemoPseudoElement.GetCSSTypeID: TCSSNumericalID;
+begin
+  Result:=CSSIDNone;
+end;
+
+function TDemoPseudoElement.GetCSSParent: ICSSNode;
+begin
+  Result:=TDemoNode(Owner);
+end;
+
+function TDemoPseudoElement.GetCSSIndex: integer;
+begin
+  Result:=-1;
+end;
+
+function TDemoPseudoElement.GetCSSNextSibling: ICSSNode;
+begin
+  Result:=nil;
+end;
+
+function TDemoPseudoElement.GetCSSPreviousSibling: ICSSNode;
+begin
+  Result:=nil;
+end;
+
+function TDemoPseudoElement.GetCSSNextOfType: ICSSNode;
+begin
+  Result:=nil;
+end;
+
+function TDemoPseudoElement.GetCSSPreviousOfType: ICSSNode;
+begin
+  Result:=nil;
+end;
+
+function TDemoPseudoElement.GetCSSEmpty: boolean;
+begin
+  Result:=true;
+end;
+
+function TDemoPseudoElement.GetCSSChildCount: integer;
+begin
+  Result:=0;
+end;
+
+function TDemoPseudoElement.GetCSSChild(const anIndex: integer): ICSSNode;
+begin
+  Result:=nil;
+  if anIndex=0 then ;
+end;
+
+function TDemoPseudoElement.HasCSSClass(const aClassName: TCSSString): boolean;
+begin
+  Result:=false;
+  if aClassName='' then ;
+end;
+
+function TDemoPseudoElement.GetCSSAttributeClass: TCSSString;
+begin
+  Result:='';
+end;
+
+{ TDemoFirstLine }
+
+function TDemoFirstLine.GetCSSPseudoElementName: TCSSString;
+begin
+  Result:='first-line';
+end;
+
+function TDemoFirstLine.GetCSSPseudoElementID: TCSSNumericalID;
+begin
+  Result:=DemoFirstLineID;
+end;
+
 { TCustomTestNewCSSResolver }
 { TCustomTestNewCSSResolver }
 
 
 procedure TCustomTestNewCSSResolver.SetUp;
 procedure TCustomTestNewCSSResolver.SetUp;
@@ -2734,6 +2871,97 @@ begin
   AssertEquals('Div1.Color','',Div1.Color);
   AssertEquals('Div1.Color','',Div1.Color);
 end;
 end;
 
 
+procedure TTestNewCSSResolver.Test_PseudoElement;
+var
+  Div1: TDemoDiv;
+  FirstLine: TDemoFirstLine;
+begin
+  Doc.Root:=TDemoNode.Create(nil);
+
+  Div1:=TDemoDiv.Create(nil);
+  Div1.Name:='Div1';
+  Div1.Parent:=Doc.Root;
+
+  Doc.Style:=LinesToStr([
+  'div {',
+  '  border-color:red;',
+  '}',
+  '#Div1::first-line {',
+  '  color:red;',
+  '  border-color:white;',
+  '}',
+  'div {',
+  '  color: blue;',
+  '}']);
+  ApplyStyle;
+  FirstLine:=TDemoFirstLine.Create(Div1);
+  FirstLine.ApplyCSS(Doc.CSSResolver);
+
+  AssertEquals('Div1.BorderColor','red',Div1.BorderColor);
+  AssertEquals('Div1.Color','blue',Div1.Color);
+  AssertEquals('Div1::first-line.BorderColor','white',FirstLine.BorderColor);
+  AssertEquals('Div1::first-line.Color','red',FirstLine.Color);
+end;
+
+procedure TTestNewCSSResolver.Test_PseudoElement_Unary;
+var
+  Div1: TDemoDiv;
+  FirstLine: TDemoFirstLine;
+begin
+  Doc.Root:=TDemoNode.Create(nil);
+
+  Div1:=TDemoDiv.Create(nil);
+  Div1.Name:='Div1';
+  Div1.Parent:=Doc.Root;
+
+  Doc.Style:=LinesToStr([
+  '::first-line {',
+  '  color:red;',
+  '}',
+  'div {',
+  '  color: blue;',
+  '}']);
+  ApplyStyle;
+  FirstLine:=TDemoFirstLine.Create(Div1);
+  FirstLine.ApplyCSS(Doc.CSSResolver);
+
+  AssertEquals('Div1.Color','blue',Div1.Color);
+  AssertEquals('Div1::first-line.Color','red',FirstLine.Color);
+end;
+
+procedure TTestNewCSSResolver.Test_PseudoElement_PostfixSelectNothing;
+var
+  Div1: TDemoDiv;
+  FirstLine: TDemoFirstLine;
+begin
+  Doc.Root:=TDemoNode.Create(nil);
+
+  Div1:=TDemoDiv.Create(nil);
+  Div1.Name:='Div1';
+  Div1.Parent:=Doc.Root;
+  Div1.CSSClasses.Add('Big');
+
+  Doc.Style:=LinesToStr([
+  'div::first-line#Bird {',
+  '  color:red;',
+  '}',
+  'div::first-line.Big {',
+  '  border-color:red;',
+  '}',
+  'div {',
+  '  color: blue;',
+  '  border-color: blue;',
+  '}']);
+  ApplyStyle;
+  FirstLine:=TDemoFirstLine.Create(Div1);
+  FirstLine.ApplyCSS(Doc.CSSResolver);
+
+  AssertEquals('Div1.Color','blue',Div1.Color);
+  AssertEquals('Div1.BorderColor','blue',Div1.BorderColor);
+  AssertEquals('Div1::first-line.Color','',FirstLine.Color);
+  AssertEquals('Div1::first-line.BorderColor','',FirstLine.BorderColor);
+end;
+
 initialization
 initialization
   RegisterTests([TTestNewCSSResolver]);
   RegisterTests([TTestNewCSSResolver]);
 
 

+ 3 - 5
packages/fcl-css/tests/tccssscanner.pp

@@ -519,7 +519,7 @@ end;
 
 
 procedure TTestCSSScanner.TestPSEUDO2;
 procedure TTestCSSScanner.TestPSEUDO2;
 begin
 begin
-  CheckToken(ctkPSEUDO,'::name');
+  CheckTokens('::name',[ctkDOUBLECOLON,ctkIDENTIFIER]);
 end;
 end;
 
 
 procedure TTestCSSScanner.TestPSEUDOMinus;
 procedure TTestCSSScanner.TestPSEUDOMinus;
@@ -529,7 +529,7 @@ end;
 
 
 procedure TTestCSSScanner.TestPSEUDO2Minus;
 procedure TTestCSSScanner.TestPSEUDO2Minus;
 begin
 begin
-  CheckToken(ctkPSEUDO,'::-name');
+  CheckTokens('::-name',[ctkDOUBLECOLON,ctkIDENTIFIER]);
 end;
 end;
 
 
 procedure TTestCSSScanner.TestPSEUDODisabled;
 procedure TTestCSSScanner.TestPSEUDODisabled;
@@ -561,11 +561,9 @@ end;
 
 
 procedure TTestCSSScanner.TestPSEUDOFUNCTION2;
 procedure TTestCSSScanner.TestPSEUDOFUNCTION2;
 begin
 begin
-  CheckToken(ctkPSEUDOFUNCTION,'::name(');
+  CheckTokens('::name(',[ctkDOUBLECOLON,ctkFUNCTION]);
 end;
 end;
 
 
-
-
 procedure TTestCSSScanner.TestJUNK;
 procedure TTestCSSScanner.TestJUNK;
 var
 var
   HasUnknown: Boolean;
   HasUnknown: Boolean;

+ 1 - 1
packages/fcl-db/fpmake.pp

@@ -32,7 +32,7 @@ begin
     P.Email := '';
     P.Email := '';
     P.Description := 'Database library of Free Component Libraries(FCL), FPC''s OOP library.';
     P.Description := 'Database library of Free Component Libraries(FCL), FPC''s OOP library.';
     P.NeedLibC:= false;
     P.NeedLibC:= false;
-    P.OSes:=AllOSes-[embedded,msdos,win16,macosclassic,palmos,zxspectrum,msxdos,amstradcpc,sinclairql,human68k,ps1];
+    P.OSes:=AllOSes-[embedded,msdos,win16,macosclassic,palmos,zxspectrum,msxdos,amstradcpc,sinclairql,human68k,ps1,wasip2];
     if Defaults.CPU=jvm then
     if Defaults.CPU=jvm then
       P.OSes := P.OSes - [java,android];
       P.OSes := P.OSes - [java,android];
 
 

+ 47 - 7
packages/fcl-db/src/base/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -663,7 +663,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=dbconst db dbwhtml bufdataset_parser bufdataset dbcoll sqlscript xmldatapacketreader
 override TARGET_UNITS+=dbconst db dbwhtml bufdataset_parser bufdataset dbcoll sqlscript xmldatapacketreader
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=dbconst db dbwhtml bufdataset_parser bufdataset dbcoll sqlscript xmldatapacketreader
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=dbconst db dbwhtml bufdataset_parser bufdataset dbcoll sqlscript xmldatapacketreader
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=dbconst db dbwhtml bufdataset_parser bufdataset dbcoll sqlscript xmldatapacketreader
 override TARGET_UNITS+=dbconst db dbwhtml bufdataset_parser bufdataset dbcoll sqlscript xmldatapacketreader
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1002,7 +1008,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=dbconst dbcoll sqlscript xmldatapacketreader
 override TARGET_RSTS+=dbconst dbcoll sqlscript xmldatapacketreader
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=dbconst dbcoll sqlscript xmldatapacketreader
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=dbconst dbcoll sqlscript xmldatapacketreader
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=dbconst dbcoll sqlscript xmldatapacketreader
 override TARGET_RSTS+=dbconst dbcoll sqlscript xmldatapacketreader
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1342,7 +1354,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1681,7 +1699,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_UNITDIR+=../dbase
 override COMPILER_UNITDIR+=../dbase
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_UNITDIR+=../dbase
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_UNITDIR+=../dbase
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_UNITDIR+=../dbase
 override COMPILER_UNITDIR+=../dbase
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2256,7 +2280,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -3004,7 +3034,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1

+ 38 - 6
packages/fcl-db/src/codegen/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=fpddcodegen fpcgcreatedbf fpcgdbcoll fpcgsqlconst fpcgtiopf fpddpopcode
 override TARGET_UNITS+=fpddcodegen fpcgcreatedbf fpcgdbcoll fpcgsqlconst fpcgtiopf fpddpopcode
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=fpddcodegen fpcgcreatedbf fpcgdbcoll fpcgsqlconst fpcgtiopf fpddpopcode
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=fpddcodegen fpcgcreatedbf fpcgdbcoll fpcgsqlconst fpcgtiopf fpddpopcode
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=fpddcodegen fpcgcreatedbf fpcgdbcoll fpcgsqlconst fpcgtiopf fpddpopcode
 override TARGET_UNITS+=fpddcodegen fpcgcreatedbf fpcgdbcoll fpcgsqlconst fpcgtiopf fpddpopcode
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=fpddcodegen fpcgsqlconst fpddpopcode
 override TARGET_RSTS+=fpddcodegen fpcgsqlconst fpddpopcode
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=fpddcodegen fpcgsqlconst fpddpopcode
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=fpddcodegen fpcgsqlconst fpddpopcode
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=fpddcodegen fpcgsqlconst fpddpopcode
 override TARGET_RSTS+=fpddcodegen fpcgsqlconst fpddpopcode
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1341,7 +1353,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1916,7 +1934,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2566,7 +2590,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif

+ 40 - 6
packages/fcl-db/src/datadict/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=fpdatadict fpdddiff fpdddbf fpddsqldb
 override TARGET_UNITS+=fpdatadict fpdddiff fpdddbf fpddsqldb
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=fpdatadict fpdddiff fpdddbf fpddsqldb
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=fpdatadict fpdddiff fpdddbf fpddsqldb
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=fpdatadict fpdddiff fpdddbf fpddsqldb
 override TARGET_UNITS+=fpdatadict fpdddiff fpdddbf fpddsqldb
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=fpdatadict fpddfb fpddsqldb fpdddiff
 override TARGET_RSTS+=fpdatadict fpddfb fpddsqldb fpdddiff
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=fpdatadict fpddfb fpddsqldb fpdddiff
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=fpdatadict fpddfb fpddsqldb fpdddiff
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=fpdatadict fpddfb fpddsqldb fpdddiff
 override TARGET_RSTS+=fpdatadict fpddfb fpddsqldb fpdddiff
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1341,7 +1353,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1916,7 +1934,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2890,7 +2914,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1

+ 52 - 8
packages/fcl-db/src/dbase/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -670,7 +670,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=dbf
 override TARGET_UNITS+=dbf
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=dbf
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=dbf
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=dbf
 override TARGET_UNITS+=dbf
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1009,7 +1015,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_EXAMPLES+=testdbf
 override TARGET_EXAMPLES+=testdbf
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_EXAMPLES+=testdbf
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_EXAMPLES+=testdbf
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_EXAMPLES+=testdbf
 override TARGET_EXAMPLES+=testdbf
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1348,7 +1360,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override CLEAN_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
 override CLEAN_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override CLEAN_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override CLEAN_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override CLEAN_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
 override CLEAN_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1687,7 +1705,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override INSTALL_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
 override INSTALL_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override INSTALL_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override INSTALL_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override INSTALL_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
 override INSTALL_UNITS+=dbf_collate dbf_common dbf_cursor dbf_dbffile dbf_fields dbf_idxcur dbf_idxfile dbf_lang dbf_memo dbf_parser dbf_pgfile dbf_prscore dbf_prsdef dbf_prssupp dbf_str
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2027,7 +2051,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2 -Sh
 override COMPILER_OPTIONS+=-S2 -Sh
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2 -Sh
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2 -Sh
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2 -Sh
 override COMPILER_OPTIONS+=-S2 -Sh
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2602,7 +2632,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -3252,7 +3288,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif

+ 40 - 6
packages/fcl-db/src/export/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
 override TARGET_UNITS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
 override TARGET_UNITS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
 override TARGET_RSTS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
 override TARGET_RSTS+=fpdbexport fpcsvexport fpfixedexport fpsqlexport fpsimplexmlexport fpsimplejsonexport fpdbfexport fptexexport fprtfexport fpxmlxsdexport fpstdexports
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1341,7 +1353,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1916,7 +1934,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2664,7 +2688,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1

+ 26 - 4
packages/fcl-db/src/json/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=fpjsondataset extjsdataset
 override TARGET_UNITS+=fpjsondataset extjsdataset
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=fpjsondataset extjsdataset
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=fpjsondataset extjsdataset
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=fpjsondataset extjsdataset
 override TARGET_UNITS+=fpjsondataset extjsdataset
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1238,7 +1244,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -1986,7 +1998,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-JSON=1
 REQUIRE_PACKAGES_FCL-JSON=1

+ 38 - 6
packages/fcl-db/src/memds/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=memds
 override TARGET_UNITS+=memds
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=memds
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=memds
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=memds
 override TARGET_UNITS+=memds
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=memds
 override TARGET_RSTS+=memds
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=memds
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=memds
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=memds
 override TARGET_RSTS+=memds
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1340,7 +1352,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_EXAMPLES+=testpop testopen testld testcp
 override TARGET_EXAMPLES+=testpop testopen testld testcp
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_EXAMPLES+=testpop testopen testld testcp
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_EXAMPLES+=testpop testopen testld testcp
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_EXAMPLES+=testpop testopen testld testcp
 override TARGET_EXAMPLES+=testpop testopen testld testcp
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1916,7 +1934,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2566,7 +2590,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif

+ 33 - 5
packages/fcl-db/src/paradox/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=paradox
 override TARGET_UNITS+=paradox
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=paradox
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=paradox
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=paradox
 override TARGET_UNITS+=paradox
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=paradox
 override TARGET_RSTS+=paradox
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=paradox
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=paradox
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=paradox
 override TARGET_RSTS+=paradox
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1577,7 +1589,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2325,7 +2343,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_PXLIB=1
 REQUIRE_PACKAGES_PXLIB=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PXLIB=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_PXLIB=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_PXLIB=1
 REQUIRE_PACKAGES_PXLIB=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1

+ 31 - 5
packages/fcl-db/src/sdf/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=sdfdata
 override TARGET_UNITS+=sdfdata
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=sdfdata
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=sdfdata
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=sdfdata
 override TARGET_UNITS+=sdfdata
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_EXAMPLES+=testsdf testfix
 override TARGET_EXAMPLES+=testsdf testfix
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_EXAMPLES+=testsdf testfix
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_EXAMPLES+=testsdf testfix
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_EXAMPLES+=testsdf testfix
 override TARGET_EXAMPLES+=testsdf testfix
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1577,7 +1589,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2227,7 +2245,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif

+ 45 - 7
packages/fcl-db/src/sql/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=fpsqltree fpsqlscanner fpsqlparser
 override TARGET_UNITS+=fpsqltree fpsqlscanner fpsqlparser
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=fpsqltree fpsqlscanner fpsqlparser
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=fpsqltree fpsqlscanner fpsqlparser
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=fpsqltree fpsqlscanner fpsqlparser
 override TARGET_UNITS+=fpsqltree fpsqlscanner fpsqlparser
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=fpsqltree fpsqlscanner fpsqlparser
 override TARGET_RSTS+=fpsqltree fpsqlscanner fpsqlparser
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=fpsqltree fpsqlscanner fpsqlparser
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=fpsqltree fpsqlscanner fpsqlparser
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=fpsqltree fpsqlscanner fpsqlparser
 override TARGET_RSTS+=fpsqltree fpsqlscanner fpsqlparser
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1341,7 +1353,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2h
 override COMPILER_OPTIONS+=-S2h
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1680,7 +1698,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_UNITDIR+=../dbase
 override COMPILER_UNITDIR+=../dbase
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_UNITDIR+=../dbase
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_UNITDIR+=../dbase
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_UNITDIR+=../dbase
 override COMPILER_UNITDIR+=../dbase
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2255,7 +2279,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2905,7 +2935,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-BASE=1
 REQUIRE_PACKAGES_FCL-BASE=1
 endif
 endif

+ 38 - 6
packages/fcl-db/src/sqldb/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -797,7 +797,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=sqldb
 override TARGET_UNITS+=sqldb
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=sqldb
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=sqldb
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=sqldb
 override TARGET_UNITS+=sqldb
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1136,7 +1142,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=sqldb
 override TARGET_RSTS+=sqldb
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=sqldb
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=sqldb
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=sqldb
 override TARGET_RSTS+=sqldb
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1476,7 +1488,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -2051,7 +2069,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2965,7 +2989,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 endif
 endif

+ 33 - 5
packages/fcl-db/src/sqldb/interbase/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=ibconnection fbadmin  fbeventmonitor
 override TARGET_UNITS+=ibconnection fbadmin  fbeventmonitor
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=ibconnection fbadmin  fbeventmonitor
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=ibconnection fbadmin  fbeventmonitor
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=ibconnection fbadmin  fbeventmonitor
 override TARGET_UNITS+=ibconnection fbadmin  fbeventmonitor
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1002,7 +1008,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1577,7 +1589,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2325,7 +2343,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_IBASE=1
 REQUIRE_PACKAGES_IBASE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_IBASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_IBASE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_IBASE=1
 REQUIRE_PACKAGES_IBASE=1

+ 34 - 17
packages/fcl-db/src/sqldb/interbase/ibconnection.pp

@@ -195,11 +195,6 @@ uses
   StrUtils, FmtBCD;
   StrUtils, FmtBCD;
 {$ENDIF FPC_DOTTEDUNITS}
 {$ENDIF FPC_DOTTEDUNITS}
 
 
-const
-  SQL_BOOLEAN_INTERBASE = 590;
-  SQL_BOOLEAN_FIREBIRD = 32764;
-  SQL_NULL = 32767;
-  INVALID_DATA = -1;
 
 
 procedure TIBConnection.CheckError(const ProcName : string; Status : PISC_STATUS);
 procedure TIBConnection.CheckError(const ProcName : string; Status : PISC_STATUS);
 
 
@@ -804,6 +799,9 @@ begin
         TrType := ftFloat;
         TrType := ftFloat;
     SQL_BOOLEAN_INTERBASE, SQL_BOOLEAN_FIREBIRD :
     SQL_BOOLEAN_INTERBASE, SQL_BOOLEAN_FIREBIRD :
         TrType := ftBoolean;
         TrType := ftBoolean;
+    SQL_INT128,
+    SQL_DEC16, SQL_DEC34:
+        TrType := ftFmtBCD;
     else
     else
         TrType := ftUnknown;
         TrType := ftUnknown;
   end;
   end;
@@ -1083,7 +1081,7 @@ begin
       TranslateFldType(PSQLVar^.SQLType, PSQLVar^.sqlsubtype, PSQLVar^.SQLLen, PSQLVar^.SQLScale,
       TranslateFldType(PSQLVar^.SQLType, PSQLVar^.sqlsubtype, PSQLVar^.SQLLen, PSQLVar^.SQLScale,
         TransType, TransLen, TransPrec);
         TransType, TransLen, TransPrec);
 
 
-      // [var]AnsiChar or blob column character set NONE or OCTETS overrides connection charset
+      // [var]char or blob column character set NONE or OCTETS overrides connection charset
       if (((TransType in [ftString, ftFixedChar]) and (PSQLVar^.sqlsubtype and $FF in [CS_NONE,CS_BINARY])) and not UseConnectionCharSetIfNone)
       if (((TransType in [ftString, ftFixedChar]) and (PSQLVar^.sqlsubtype and $FF in [CS_NONE,CS_BINARY])) and not UseConnectionCharSetIfNone)
          or
          or
          ((TransType = ftMemo) and (PSQLVar^.relname_length>0) and (PSQLVar^.sqlname_length>0) and (GetBlobCharset(@PSQLVar^.relname,@PSQLVar^.sqlname) in [CS_NONE,CS_BINARY])) then
          ((TransType = ftMemo) and (PSQLVar^.relname_length>0) and (PSQLVar^.sqlname_length>0) and (GetBlobCharset(@PSQLVar^.relname,@PSQLVar^.sqlname) in [CS_NONE,CS_BINARY])) then
@@ -1200,6 +1198,7 @@ var
   li       : LargeInt;
   li       : LargeInt;
   CurrBuff : PAnsiChar;
   CurrBuff : PAnsiChar;
   w        : word;
   w        : word;
+  i128     : Int128Rec;
 
 
 begin
 begin
   {$push}
   {$push}
@@ -1283,6 +1282,15 @@ begin
           SetDateTime(VSQLVar^.SQLData, AParam.AsDateTime, VSQLVar^.SQLType);
           SetDateTime(VSQLVar^.SQLData, AParam.AsDateTime, VSQLVar^.SQLType);
         SQL_BOOLEAN_FIREBIRD:
         SQL_BOOLEAN_FIREBIRD:
           PByte(VSQLVar^.SQLData)^ := Byte(AParam.AsBoolean);
           PByte(VSQLVar^.SQLData)^ := Byte(AParam.AsBoolean);
+        SQL_INT128:
+          begin
+            i128 := BCDToInt128(AParam.AsFMTBCD);
+            Move(i128, VSQLVar^.SQLData^, VSQLVar^.SQLLen);
+          end;
+        SQL_DEC16:
+          begin
+          // ToDo
+          end;
       else
       else
         if (VSQLVar^.sqltype <> SQL_NULL) then
         if (VSQLVar^.sqltype <> SQL_NULL) then
           DatabaseErrorFmt(SUnsupportedParameter,[FieldTypeNames[AParam.DataType]],self);
           DatabaseErrorFmt(SUnsupportedParameter,[FieldTypeNames[AParam.DataType]],self);
@@ -1294,12 +1302,14 @@ end;
 
 
 function TIBConnection.LoadField(cursor : TSQLCursor; FieldDef : TFieldDef; buffer : pointer; out CreateBlob : boolean) : boolean;
 function TIBConnection.LoadField(cursor : TSQLCursor; FieldDef : TFieldDef; buffer : pointer; out CreateBlob : boolean) : boolean;
 
 
+type
+  PInt128Rec = ^Int128Rec;
 var
 var
   VSQLVar    : PXSQLVAR;
   VSQLVar    : PXSQLVAR;
   VarcharLen : word;
   VarcharLen : word;
-  CurrBuff     : PAnsiChar;
-  c            : currency;
-  AFmtBcd      : tBCD;
+  CurrBuff   : PAnsiChar;
+  c          : currency;
+  AFmtBcd    : tBCD;
 
 
   function BcdDivPower10(Dividend: largeint; e: integer): TBCD;
   function BcdDivPower10(Dividend: largeint; e: integer): TBCD;
   var d: double;
   var d: double;
@@ -1358,15 +1368,22 @@ begin
           end;
           end;
         ftFMTBcd :
         ftFMTBcd :
           begin
           begin
-            case VSQLVar^.SQLLen of
-              2 : AFmtBcd := BcdDivPower10(PSmallint(CurrBuff)^, -VSQLVar^.SQLScale);
-              4 : AFmtBcd := BcdDivPower10(PLongint(CurrBuff)^,  -VSQLVar^.SQLScale);
-              8 : if Dialect < 3 then
-                    AFmtBcd := PDouble(CurrBuff)^
-                  else
-                    AFmtBcd := BcdDivPower10(PLargeint(CurrBuff)^, -VSQLVar^.SQLScale);
+            case (VSQLVar^.sqltype and not 1) of
+              SQL_DEC16:
+                // ToDo
+                AFmtBcd := 0;
               else
               else
-                Result := False; // Just to be sure, in principle this will never happen
+                case VSQLVar^.SQLLen of
+                  2 : AFmtBcd := BcdDivPower10(PSmallint(CurrBuff)^, -VSQLVar^.SQLScale);
+                  4 : AFmtBcd := BcdDivPower10(PLongint(CurrBuff)^,  -VSQLVar^.SQLScale);
+                  8 : if Dialect < 3 then
+                        AFmtBcd := PDouble(CurrBuff)^
+                      else
+                        AFmtBcd := BcdDivPower10(PLargeint(CurrBuff)^, -VSQLVar^.SQLScale);
+                  16: AFmtBcd := Int128ToBcd(PInt128Rec(CurrBuff)^);
+                  else
+                    Result := False; // Just to be sure, in principle this will never happen
+                end; {case}
             end; {case}
             end; {case}
             Move(AFmtBcd, buffer^ , sizeof(AFmtBcd));
             Move(AFmtBcd, buffer^ , sizeof(AFmtBcd));
           end;
           end;

+ 31 - 5
packages/fcl-db/src/sqldb/mssql/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=mssqlconn
 override TARGET_UNITS+=mssqlconn
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=mssqlconn
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=mssqlconn
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=mssqlconn
 override TARGET_UNITS+=mssqlconn
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1002,7 +1008,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1577,7 +1589,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2227,7 +2245,15 @@ ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_DBLIB=1
 REQUIRE_PACKAGES_DBLIB=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_DBLIB=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_DBLIB=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_DBLIB=1
 REQUIRE_PACKAGES_DBLIB=1
 endif
 endif

+ 40 - 6
packages/fcl-db/src/sqldb/mysql/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1341,7 +1353,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1916,7 +1934,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2664,7 +2688,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_MYSQL=1
 REQUIRE_PACKAGES_MYSQL=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_MYSQL=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_MYSQL=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_MYSQL=1
 REQUIRE_PACKAGES_MYSQL=1

+ 33 - 5
packages/fcl-db/src/sqldb/odbc/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=odbcconn
 override TARGET_UNITS+=odbcconn
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=odbcconn
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=odbcconn
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=odbcconn
 override TARGET_UNITS+=odbcconn
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1002,7 +1008,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1577,7 +1589,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2325,7 +2343,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_ODBC=1
 REQUIRE_PACKAGES_ODBC=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_ODBC=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_ODBC=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_ODBC=1
 REQUIRE_PACKAGES_ODBC=1

+ 40 - 6
packages/fcl-db/src/sqldb/oracle/Makefile

@@ -2,7 +2,7 @@
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 # Don't edit, this file is generated by FPCMake Version 2.0.0
 #
 #
 default: all
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasi sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-netbsd m68k-amiga m68k-atari m68k-palmos m68k-macosclassic m68k-embedded m68k-sinclairql m68k-human68k powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macosclassic powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-haiku x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-android x86_64-aros x86_64-dragonfly arm-linux arm-netbsd arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android arm-aros arm-freertos arm-ios powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android mipsel-ps1 mips64-linux mips64el-linux jvm-java jvm-android i8086-embedded i8086-msdos i8086-win16 aarch64-linux aarch64-freebsd aarch64-darwin aarch64-win64 aarch64-embedded aarch64-iphonesim aarch64-android aarch64-ios wasm32-embedded wasm32-wasip1 wasm32-wasip1threads wasm32-wasip2 sparc64-linux riscv32-linux riscv32-embedded riscv32-freertos riscv64-linux riscv64-embedded xtensa-linux xtensa-embedded xtensa-freertos z80-embedded z80-zxspectrum z80-msxdos z80-amstradcpc loongarch64-linux
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
 LIMIT83fs = go32v2 os2 emx watcom msdos win16 atari human68k
@@ -662,7 +662,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_UNITS+=oracleconnection
 override TARGET_UNITS+=oracleconnection
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_UNITS+=oracleconnection
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_UNITS+=oracleconnection
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_UNITS+=oracleconnection
 override TARGET_UNITS+=oracleconnection
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1001,7 +1007,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override TARGET_RSTS+=oracleconnection
 override TARGET_RSTS+=oracleconnection
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override TARGET_RSTS+=oracleconnection
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override TARGET_RSTS+=oracleconnection
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override TARGET_RSTS+=oracleconnection
 override TARGET_RSTS+=oracleconnection
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1341,7 +1353,13 @@ endif
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 ifeq ($(CPU_OS_TARGET),wasm32-embedded)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+override COMPILER_OPTIONS+=-S2
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 override COMPILER_OPTIONS+=-S2
 override COMPILER_OPTIONS+=-S2
 endif
 endif
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
 ifeq ($(CPU_OS_TARGET),sparc64-linux)
@@ -1916,7 +1934,13 @@ endif
 ifeq ($(OS_TARGET),zxspectrum)
 ifeq ($(OS_TARGET),zxspectrum)
 OEXT=.rel
 OEXT=.rel
 endif
 endif
-ifeq ($(OS_TARGET),wasi)
+ifeq ($(OS_TARGET),wasip1)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip1threads)
+EXEEXT=.wasm
+endif
+ifeq ($(OS_TARGET),wasip2)
 EXEEXT=.wasm
 EXEEXT=.wasm
 endif
 endif
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(filter $(OS_SOURCE),$(LIMIT83fs)),)
@@ -2664,7 +2688,17 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_ORACLE=1
 REQUIRE_PACKAGES_ORACLE=1
 endif
 endif
-ifeq ($(CPU_OS_TARGET),wasm32-wasi)
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_ORACLE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip1threads)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_ORACLE=1
+endif
+ifeq ($(CPU_OS_TARGET),wasm32-wasip2)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_FCL-XML=1
 REQUIRE_PACKAGES_ORACLE=1
 REQUIRE_PACKAGES_ORACLE=1

Some files were not shown because too many files changed in this diff