Переглянути джерело

* synchronised with trunk up to r24912
o resolved conflict in updated morphos sysutils unit
o moved code that had been added to the now deleted sysunix.inc to the
unix-specific block of the fpwidestring unit's init code

git-svn-id: branches/cpstrrtl@24913 -

Jonas Maebe 12 роки тому
батько
коміт
ecd3cba02b
100 змінених файлів з 12906 додано та 3828 видалено
  1. 393 54
      .gitattributes
  2. 117 12
      Makefile
  3. 59 10
      Makefile.fpc
  4. 156 120
      compiler/Makefile
  5. 49 29
      compiler/Makefile.fpc
  6. 133 0
      compiler/aarch64/a64att.inc
  7. 133 0
      compiler/aarch64/a64atts.inc
  8. 262 0
      compiler/aarch64/a64ins.dat
  9. 2 0
      compiler/aarch64/a64nop.inc
  10. 133 0
      compiler/aarch64/a64op.inc
  11. 238 0
      compiler/aarch64/a64reg.dat
  12. 4 0
      compiler/aarch64/a64tab.inc
  13. 2178 0
      compiler/aarch64/aasmcpu.pas
  14. 66 0
      compiler/aarch64/aoptcpu.pas
  15. 134 0
      compiler/aarch64/aoptcpub.pas
  16. 41 0
      compiler/aarch64/aoptcpud.pas
  17. 458 0
      compiler/aarch64/cpubase.pas
  18. 102 0
      compiler/aarch64/cpuinfo.pas
  19. 709 0
      compiler/aarch64/cpupara.pas
  20. 93 0
      compiler/aarch64/itcpugas.pas
  21. 227 0
      compiler/aarch64/ra64con.inc
  22. 227 0
      compiler/aarch64/ra64dwa.inc
  23. 2 0
      compiler/aarch64/ra64nor.inc
  24. 227 0
      compiler/aarch64/ra64num.inc
  25. 227 0
      compiler/aarch64/ra64rni.inc
  26. 227 0
      compiler/aarch64/ra64sri.inc
  27. 227 0
      compiler/aarch64/ra64sta.inc
  28. 227 0
      compiler/aarch64/ra64std.inc
  29. 227 0
      compiler/aarch64/ra64sup.inc
  30. 10 8
      compiler/aasmbase.pas
  31. 8 2
      compiler/aasmdata.pas
  32. 209 32
      compiler/aasmtai.pas
  33. 141 17
      compiler/aggas.pas
  34. 1 0
      compiler/agjasmin.pas
  35. 15 29
      compiler/aoptobj.pas
  36. 294 74
      compiler/arm/aasmcpu.pas
  37. 54 13
      compiler/arm/agarmgas.pas
  38. 746 122
      compiler/arm/aoptcpu.pas
  39. 41 7
      compiler/arm/armatt.inc
  40. 34 0
      compiler/arm/armatts.inc
  41. 54 13
      compiler/arm/armins.dat
  42. 1 1
      compiler/arm/armnop.inc
  43. 41 7
      compiler/arm/armop.inc
  44. 38 1
      compiler/arm/armreg.dat
  45. 0 7
      compiler/arm/armtab.inc
  46. 393 162
      compiler/arm/cgcpu.pas
  47. 114 10
      compiler/arm/cpubase.pas
  48. 882 0
      compiler/arm/cpuelf.pas
  49. 408 859
      compiler/arm/cpuinfo.pas
  50. 85 34
      compiler/arm/cpupara.pas
  51. 113 43
      compiler/arm/cpupi.pas
  52. 5 0
      compiler/arm/cputarg.pas
  53. 2 2
      compiler/arm/itcpugas.pas
  54. 147 30
      compiler/arm/narmadd.pas
  55. 11 6
      compiler/arm/narmcal.pas
  56. 78 20
      compiler/arm/narmcnv.pas
  57. 2 3
      compiler/arm/narmcon.pas
  58. 34 14
      compiler/arm/narminl.pas
  59. 88 21
      compiler/arm/narmmat.pas
  60. 31 8
      compiler/arm/narmmem.pas
  61. 47 21
      compiler/arm/narmset.pas
  62. 116 12
      compiler/arm/raarmgas.pas
  63. 34 1
      compiler/arm/rarmcon.inc
  64. 33 0
      compiler/arm/rarmdwa.inc
  65. 1 1
      compiler/arm/rarmnor.inc
  66. 34 1
      compiler/arm/rarmnum.inc
  67. 34 1
      compiler/arm/rarmrni.inc
  68. 34 1
      compiler/arm/rarmsri.inc
  69. 33 0
      compiler/arm/rarmsta.inc
  70. 35 2
      compiler/arm/rarmstd.inc
  71. 34 1
      compiler/arm/rarmsup.inc
  72. 182 5
      compiler/arm/rgcpu.pas
  73. 2 2
      compiler/asmutils.pas
  74. 51 15
      compiler/assemble.pas
  75. 1 1
      compiler/avr/agavrgas.pas
  76. 166 99
      compiler/avr/cgcpu.pas
  77. 13 1
      compiler/avr/cpubase.pas
  78. 0 6
      compiler/avr/cpuinfo.pas
  79. 54 20
      compiler/avr/cpupara.pas
  80. 7 4
      compiler/avr/navradd.pas
  81. 1 1
      compiler/browcol.pas
  82. 270 0
      compiler/ccharset.pas
  83. 31 54
      compiler/cclasses.pas
  84. 11 1
      compiler/cfileutl.pas
  85. 155 68
      compiler/cg64f32.pas
  86. 36 9
      compiler/cgbase.pas
  87. 63 19
      compiler/cgobj.pas
  88. 9 5
      compiler/cgutils.pas
  89. 4 1
      compiler/comphook.pas
  90. 14 1
      compiler/compiler.pas
  91. 1 0
      compiler/compinnr.inc
  92. 0 9
      compiler/constexp.pas
  93. 0 282
      compiler/cp1251.pas
  94. 0 282
      compiler/cp437.pas
  95. 0 282
      compiler/cp850.pas
  96. 0 282
      compiler/cp866.pas
  97. 0 282
      compiler/cp8859_1.pas
  98. 0 282
      compiler/cp8859_5.pas
  99. 4 4
      compiler/cresstr.pas
  100. 38 0
      compiler/cutils.pas

Різницю між файлами не показано, бо вона завелика
+ 393 - 54
.gitattributes


+ 117 - 12
Makefile

@@ -1,11 +1,11 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2012/08/24]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2013/05/28]
 #
 default: help
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos 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-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx 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 m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos 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-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android i8086-msdos
 BSDs = freebsd netbsd openbsd darwin
 UNIXs = linux $(BSDs) solaris qnx haiku aix
-LIMIT83fs = go32v2 os2 emx watcom
+LIMIT83fs = go32v2 os2 emx watcom msdos
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 .PHONY: FORCE
@@ -265,12 +265,29 @@ endif
 ifndef BINUTILSPREFIX
 ifndef CROSSBINDIR
 ifdef CROSSCOMPILE
+ifneq ($(OS_TARGET),msdos)
 ifndef DARWIN2DARWIN
 ifneq ($(CPU_TARGET),jvm)
 BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+ifeq ($(OS_TARGET),android)
+ifeq ($(CPU_TARGET),arm)
+BINUTILSPREFIX=arm-linux-androideabi-
+else
+ifeq ($(CPU_TARGET),i386)
+BINUTILSPREFIX=i686-linux-android-
+else
+ifeq ($(CPU_TARGET),mips)
+BINUTILSPREFIX=mipsel-linux-android-
+endif
+endif
+endif
 endif
 endif
 endif
+else
+BINUTILSPREFIX=$(OS_TARGET)-
+endif
+endif
 endif
 endif
 UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
@@ -304,6 +321,8 @@ endif
 endif
 override PACKAGE_NAME=fpc
 override PACKAGE_VERSION=2.7.1
+REQUIREDVERSION=2.6.2
+REQUIREDVERSION2=2.6.0
 ifndef inOS2
 override FPCDIR:=$(BASEDIR)
 export FPCDIR
@@ -348,6 +367,9 @@ endif
 ifeq ($(CPU_TARGET),mipsel)
 PPSUF=mipsel
 endif
+ifeq ($(CPU_TARGET),i8086)
+PPSUF=8086
+endif
 ifdef CROSSCOMPILE
 ifneq ($(CPU_TARGET),jvm)
 PPPRE=ppcross
@@ -359,6 +381,13 @@ PPPRE=ppc
 endif
 PPNEW=$(BASEDIR)/compiler/$(PPPRE)$(PPSUF)$(SRCEXEEXT)
 endif
+ifndef FPCFPMAKENEW
+ifdef CROSSCOMPILE
+FPCFPMAKENEW=$(BASEDIR)/compiler/ppc$(SRCEXEEXT)
+else
+FPCFPMAKENEW=$(PPNEW)
+endif
+endif
 ifneq ($(wildcard install),)
 CVSINSTALL=install
 else
@@ -406,13 +435,15 @@ ifndef DIST_DESTDIR
 export DIST_DESTDIR:=$(BASEDIR)
 endif
 BASEPACKDIR=$(BASEDIR)/basepack
-ifeq ($(FULL_SOURCE),$(FULL_TARGET))
-FPCMAKENEW=$(BASEDIR)/utils/fpcm/fpcmake$(EXEEXT)
+ifndef FPCMAKENEW
+ifdef CROSSCOMPILE
+FPCMAKENEW=$(BASEDIR)/utils/fpcm/fpcmake$(SRCEXEEXT)
 else
-FPCMAKENEW=fpcmake
+FPCMAKENEW=$(BASEDIR)/utils/fpcm/bin/$(SOURCESUFFIX)/fpcmake$(SRCEXEEXT)
+endif
 endif
 CLEANOPTS=FPC=$(PPNEW)
-BUILDOPTS=FPC=$(PPNEW) RELEASE=1
+BUILDOPTS=FPC=$(PPNEW) FPCFPMAKE=$(FPCFPMAKENEW) RELEASE=1
 INSTALLOPTS=FPC=$(PPNEW) ZIPDESTDIR=$(BASEDIR) FPCMAKE=$(FPCMAKENEW)
 ifndef CROSSCOMPILE
 ifneq ($(wildcard ide),)
@@ -497,6 +528,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
+ifeq ($(FULL_TARGET),i386-android)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
@@ -608,6 +642,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
+ifeq ($(FULL_TARGET),arm-android)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
@@ -641,6 +678,9 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 override INSTALL_FPCPACKAGE=y
 ifdef REQUIRE_UNITSDIR
 override UNITSDIR+=$(REQUIRE_UNITSDIR)
@@ -870,6 +910,14 @@ SHAREDLIBEXT=.dll
 SHORTSUFFIX=wat
 IMPORTLIBPREFIX=
 endif
+ifneq ($(CPU_TARGET),jvm)
+ifeq ($(OS_TARGET),android)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+endif
 ifeq ($(OS_TARGET),linux)
 BATCHEXT=.sh
 EXEEXT=
@@ -1005,12 +1053,19 @@ ASMEXT=.j
 SHAREDLIBEXT=.jar
 SHORTSUFFIX=java
 endif
+ifeq ($(CPU_TARGET),jvm)
 ifeq ($(OS_TARGET),android)
 OEXT=.class
 ASMEXT=.j
 SHAREDLIBEXT=.jar
 SHORTSUFFIX=android
 endif
+endif
+ifeq ($(OS_TARGET),msdos)
+STATICLIBPREFIX=
+STATICLIBEXT=.lib
+SHORTSUFFIX=d16
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -1232,7 +1287,11 @@ AS=$(ASPROG)
 LD=$(LDPROG)
 RC=$(RCPROG)
 AR=$(ARPROG)
+ifdef inUnix
+PPAS=./ppas$(SRCBATCHEXT)
+else
 PPAS=ppas$(SRCBATCHEXT)
+endif
 ifdef inUnix
 LDCONFIG=ldconfig
 else
@@ -1923,6 +1982,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 endif
+ifeq ($(FULL_TARGET),i386-android)
+TARGET_DIRS_COMPILER=1
+TARGET_DIRS_RTL=1
+TARGET_DIRS_UTILS=1
+TARGET_DIRS_PACKAGES=1
+TARGET_DIRS_IDE=1
+TARGET_DIRS_INSTALLER=1
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
@@ -2219,6 +2286,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 endif
+ifeq ($(FULL_TARGET),arm-android)
+TARGET_DIRS_COMPILER=1
+TARGET_DIRS_RTL=1
+TARGET_DIRS_UTILS=1
+TARGET_DIRS_PACKAGES=1
+TARGET_DIRS_IDE=1
+TARGET_DIRS_INSTALLER=1
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
@@ -2307,6 +2382,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+TARGET_DIRS_COMPILER=1
+TARGET_DIRS_RTL=1
+TARGET_DIRS_UTILS=1
+TARGET_DIRS_PACKAGES=1
+TARGET_DIRS_IDE=1
+TARGET_DIRS_INSTALLER=1
+endif
 ifdef TARGET_DIRS_COMPILER
 compiler_all:
 	$(MAKE) -C compiler all
@@ -2614,13 +2697,29 @@ help:
 compiler_cycle:
 	$(MAKE) -C compiler cycle
 BUILDSTAMP=build-stamp.$(FULL_TARGET)
-.PHONY: all clean distclean build buildbase install installbase installother zipinstallbase zipinstallotherzipinstall singlezipinstall
+.PHONY: all clean distclean build buildbase install installbase
+.PHONY: installother zipinstallbase zipinstallotherzipinstall
+.PHONY: singlezipinstall versioncheckstartingcompiler
+versioncheckstartingcompiler: 
+ifndef CROSSCOMPILE
+ifneq ($(FPC_VERSION),$(REQUIREDVERSION))
+ifneq ($(FPC_VERSION),$(REQUIREDVERSION2))
+ifndef OVERRIDEVERSIONCHECK
+	$(error The only supported starting compiler version is $(REQUIREDVERSION). You are trying to build with $(FPC_VERSION). If you are absolutely sure that the current compiler is built from the exact same version/revision, you can try to use OVERRIDEVERSIONCHECK=1 to override )
+else
+	@$(ECHO) You have overriden the starting compiler versioncheck while using starting compiler version $(FPC_VERSION). This situation is not supported and strange things and errors may happen. Remove OVERRIDEVERSIONCHECK=1 to fix this. 
+endif
+endif
+endif
+endif
 ifeq ($(findstring $(CPU_TARGET),$(BuildOnlyBaseCPUs)),)
-all: build
+all: versioncheckstartingcompiler build
 install: installall
+zipinstall: zipinstallall
 else
-all: buildbase
+all: versioncheckstartingcompiler buildbase
 install: installbase
+zipinstall: zipinstallbase
 endif
 clean: $(addsuffix _distclean,$(TARGET_DIRS))
 	-$(DEL) build-stamp.*
@@ -2629,6 +2728,9 @@ distclean: clean
 build: $(BUILDSTAMP)
 $(BUILDSTAMP):
 	$(MAKE) compiler_cycle RELEASE=1
+ifdef CROSSCOMPILE
+	$(MAKE) -C utils/fpcm bootstrap $(BUILDOPTS)
+endif
 	$(MAKE) rtl_clean $(CLEANOPTS)
 	$(MAKE) packages_clean $(CLEANOPTS)
 ifdef UTILS
@@ -2652,6 +2754,9 @@ endif
 buildbase: base.$(BUILDSTAMP)
 base.$(BUILDSTAMP):
 	$(MAKE) compiler_cycle RELEASE=1
+ifdef CROSSCOMPILE
+	$(MAKE) -C utils/fpcm bootstrap $(BUILDOPTS)
+endif
 	$(MAKE) rtl_clean $(CLEANOPTS)
 	$(MAKE) rtl_$(ALLTARGET) $(BUILDOPTS)
 	$(ECHOREDIR) Build > base.$(BUILDSTAMP)
@@ -2683,8 +2788,8 @@ installall: $(BUILDSTAMP)
 ifeq ($(findstring $(CPU_TARGET), $(BuildOnlyBaseCPUs)),)
 	$(MAKE) installother $(INSTALLOPTS)
 endif
-singlezipinstall: zipinstall
-zipinstall: $(BUILDSTAMP)
+singlezipinstall: zipinstallall
+zipinstallall: $(BUILDSTAMP)
 	$(MAKE) fpc_zipinstall ZIPTARGET=install FULLZIPNAME=fpc-$(PACKAGE_VERSION).$(TARGETSUFFIX) $(INSTALLOPTS)
 .PHONY: crossall crossinstall crosszipinstall crosssinglezipinstall
 crossall:

+ 59 - 10
Makefile.fpc

@@ -20,6 +20,10 @@ fpcdir=.
 rule=help
 
 [prerules]
+REQUIREDVERSION=2.6.2
+REQUIREDVERSION2=2.6.0
+
+
 # make versions < 3.77 (OS2 version) are buggy
 ifndef inOS2
 override FPCDIR:=$(BASEDIR)
@@ -69,6 +73,9 @@ endif
 ifeq ($(CPU_TARGET),mipsel)
 PPSUF=mipsel
 endif
+ifeq ($(CPU_TARGET),i8086)
+PPSUF=8086
+endif
 
 # cross compilers uses full cpu_target, not just ppc-suffix
 # (except if the target cannot run a native compiler)
@@ -85,6 +92,18 @@ endif
 PPNEW=$(BASEDIR)/compiler/$(PPPRE)$(PPSUF)$(SRCEXEEXT)
 endif
 
+# Use FPCFPMAKENEW to explicitly specify FPCFPMAKE.
+# Otherwise fpmkunit build will use wrong (starting) compiler
+# if there has been no compiler binary available in the compiler
+# dir before running make.
+ifndef FPCFPMAKENEW
+ifdef CROSSCOMPILE
+FPCFPMAKENEW=$(BASEDIR)/compiler/ppc$(SRCEXEEXT)
+else
+FPCFPMAKENEW=$(PPNEW)
+endif
+endif
+
 # Check if install/ subdir is available
 ifneq ($(wildcard install),)
 CVSINSTALL=install
@@ -148,16 +167,20 @@ endif
 # Temporary path to pack a file
 BASEPACKDIR=$(BASEDIR)/basepack
 
-# Newly created fpcmake
-ifeq ($(FULL_SOURCE),$(FULL_TARGET))
-FPCMAKENEW=$(BASEDIR)/utils/fpcm/fpcmake$(EXEEXT)
+# Always use newly created fpcmake
+ifndef FPCMAKENEW
+ifdef CROSSCOMPILE
+# Use bootstrapped fpcmake when cross-compiling
+FPCMAKENEW=$(BASEDIR)/utils/fpcm/fpcmake$(SRCEXEEXT)
 else
-FPCMAKENEW=fpcmake
+# Use normal fpcmake
+FPCMAKENEW=$(BASEDIR)/utils/fpcm/bin/$(SOURCESUFFIX)/fpcmake$(SRCEXEEXT)
+endif
 endif
 
 # Build/install options
 CLEANOPTS=FPC=$(PPNEW)
-BUILDOPTS=FPC=$(PPNEW) RELEASE=1
+BUILDOPTS=FPC=$(PPNEW) FPCFPMAKE=$(FPCFPMAKENEW) RELEASE=1
 INSTALLOPTS=FPC=$(PPNEW) ZIPDESTDIR=$(BASEDIR) FPCMAKE=$(FPCMAKENEW)
 
 # Compile also IDE (check for ide and fv dir)
@@ -230,15 +253,31 @@ compiler_cycle:
 
 BUILDSTAMP=build-stamp.$(FULL_TARGET)
 
-.PHONY: all clean distclean build buildbase install installbase installother zipinstallbase zipinstallotherzipinstall singlezipinstall
+.PHONY: all clean distclean build buildbase install installbase
+.PHONY: installother zipinstallbase zipinstallotherzipinstall
+.PHONY: singlezipinstall versioncheckstartingcompiler
 
+versioncheckstartingcompiler: 
+ifndef CROSSCOMPILE
+ifneq ($(FPC_VERSION),$(REQUIREDVERSION))
+ifneq ($(FPC_VERSION),$(REQUIREDVERSION2))
+ifndef OVERRIDEVERSIONCHECK
+	$(error The only supported starting compiler version is $(REQUIREDVERSION). You are trying to build with $(FPC_VERSION). If you are absolutely sure that the current compiler is built from the exact same version/revision, you can try to use OVERRIDEVERSIONCHECK=1 to override )
+else
+	@$(ECHO) You have overriden the starting compiler versioncheck while using starting compiler version $(FPC_VERSION). This situation is not supported and strange things and errors may happen. Remove OVERRIDEVERSIONCHECK=1 to fix this. 
+endif
+endif
+endif
+endif
 
 ifeq ($(findstring $(CPU_TARGET),$(BuildOnlyBaseCPUs)),)
-all: build
+all: versioncheckstartingcompiler build
 install: installall
+zipinstall: zipinstallall
 else
-all: buildbase
+all: versioncheckstartingcompiler buildbase
 install: installbase
+zipinstall: zipinstallbase
 endif
 
 clean: $(addsuffix _distclean,$(TARGET_DIRS))
@@ -251,6 +290,11 @@ build: $(BUILDSTAMP)
 $(BUILDSTAMP):
 # create new compiler
         $(MAKE) compiler_cycle RELEASE=1
+ifdef CROSSCOMPILE
+# Buld a new native fpcmake when cross-compiling.
+# Fresh native compiler and RTL are ready at this stage.
+        $(MAKE) -C utils/fpcm bootstrap $(BUILDOPTS)
+endif
 # clean
         $(MAKE) rtl_clean $(CLEANOPTS)
         $(MAKE) packages_clean $(CLEANOPTS)
@@ -278,6 +322,11 @@ buildbase: base.$(BUILDSTAMP)
 base.$(BUILDSTAMP):
 # create new compiler
         $(MAKE) compiler_cycle RELEASE=1
+ifdef CROSSCOMPILE
+# Buld a new native fpcmake when cross-compiling.
+# Fresh native compiler and RTL are ready at this stage.
+        $(MAKE) -C utils/fpcm bootstrap $(BUILDOPTS)
+endif
 # clean
         $(MAKE) rtl_clean $(CLEANOPTS)
 # build everything
@@ -320,8 +369,8 @@ ifeq ($(findstring $(CPU_TARGET), $(BuildOnlyBaseCPUs)),)
         $(MAKE) installother $(INSTALLOPTS)
 endif
 
-singlezipinstall: zipinstall
-zipinstall: $(BUILDSTAMP)
+singlezipinstall: zipinstallall
+zipinstallall: $(BUILDSTAMP)
         $(MAKE) fpc_zipinstall ZIPTARGET=install FULLZIPNAME=fpc-$(PACKAGE_VERSION).$(TARGETSUFFIX) $(INSTALLOPTS)
 
 

+ 156 - 120
compiler/Makefile

@@ -1,11 +1,11 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2012/09/21]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2013-04-26 rev 24324]
 #
 default: all
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos 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-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx 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 m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos 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-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android i8086-msdos
 BSDs = freebsd netbsd openbsd darwin
 UNIXs = linux $(BSDs) solaris qnx haiku aix
-LIMIT83fs = go32v2 os2 emx watcom
+LIMIT83fs = go32v2 os2 emx watcom msdos
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 .PHONY: FORCE
@@ -265,14 +265,31 @@ endif
 ifndef BINUTILSPREFIX
 ifndef CROSSBINDIR
 ifdef CROSSCOMPILE
+ifneq ($(OS_TARGET),msdos)
 ifndef DARWIN2DARWIN
 ifneq ($(CPU_TARGET),jvm)
 BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+ifeq ($(OS_TARGET),android)
+ifeq ($(CPU_TARGET),arm)
+BINUTILSPREFIX=arm-linux-androideabi-
+else
+ifeq ($(CPU_TARGET),i386)
+BINUTILSPREFIX=i686-linux-android-
+else
+ifeq ($(CPU_TARGET),mips)
+BINUTILSPREFIX=mipsel-linux-android-
+endif
 endif
 endif
 endif
 endif
 endif
+else
+BINUTILSPREFIX=$(OS_TARGET)-
+endif
+endif
+endif
+endif
 UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
 ifeq ($(UNITSDIR),)
 UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
@@ -305,8 +322,8 @@ endif
 override PACKAGE_NAME=compiler
 override PACKAGE_VERSION=2.7.1
 unexport FPC_VERSION FPC_COMPILERINFO
-CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr
-ALLTARGETS=$(CYCLETARGETS) jvm
+CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086
+ALLTARGETS=$(CYCLETARGETS)
 ifdef ALPHA
 PPC_TARGET=alpha
 endif
@@ -346,6 +363,9 @@ endif
 ifdef JVM
 PPC_TARGET=jvm
 endif
+ifdef I8086
+PPC_TARGET=i8086
+endif
 ifndef PPC_TARGET
 PPC_TARGET=$(CPU_TARGET)
 endif
@@ -372,28 +392,28 @@ RTLOPT:=$(OPT)
 endif
 ifdef CYCLELEVEL
 ifeq ($(CYCLELEVEL),1)
-LOCALOOPT+=$(OPTLEVEL1)
-RTLOPT+=$(OPTLEVEL1)
-LOCALOPT+=$(LOCALOPTLEVEL1)
-RTLOPT+=$(RTLOPTLEVEL1)
+override LOCALOPT+=$(OPTLEVEL1)
+override RTLOPT+=$(OPTLEVEL1)
+override LOCALOPT+=$(LOCALOPTLEVEL1)
+override RTLOPT+=$(RTLOPTLEVEL1)
 endif
 ifeq ($(CYCLELEVEL),2)
-LOCALOOPT+=$(OPTLEVEL2)
-RTLOPT+=$(OPTLEVEL2)
-LOCALOPT+=$(LOCALOPTLEVEL2)
-RTLOPT+=$(RTLOPTLEVEL2)
+override LOCALOPT+=$(OPTLEVEL2)
+override RTLOPT+=$(OPTLEVEL2)
+override LOCALOPT+=$(LOCALOPTLEVEL2)
+override RTLOPT+=$(RTLOPTLEVEL2)
 endif
 ifeq ($(CYCLELEVEL),3)
-LOCALOOPT+=$(OPTLEVEL3)
-RTLOPT+=$(OPTLEVEL3)
-LOCALOPT+=$(LOCALOPTLEVEL3)
-RTLOPT+=$(RTLOPTLEVEL3)
+override LOCALOPT+=$(OPTLEVEL3)
+override RTLOPT+=$(OPTLEVEL3)
+override LOCALOPT+=$(LOCALOPTLEVEL3)
+override RTLOPT+=$(RTLOPTLEVEL3)
 endif
 ifeq ($(CYCLELEVEL),4)
-LOCALOOPT+=$(OPTLEVEL4)
-RTLOPT+=$(OPTLEVEL4)
-LOCALOPT+=$(LOCALOPTLEVEL4)
-RTLOPT+=$(RTLOPTLEVEL4)
+override LOCALOPT+=$(OPTLEVEL4)
+override RTLOPT+=$(OPTLEVEL4)
+override LOCALOPT+=$(LOCALOPTLEVEL4)
+override RTLOPT+=$(RTLOPTLEVEL4)
 endif
 endif
 override OPT=
@@ -434,6 +454,9 @@ endif
 ifeq ($(CPC_TARGET),jvm)
 CPUSUF=jvm
 endif
+ifeq ($(CPC_TARGET),i8086)
+CPUSUF=8086
+endif
 NOCPUDEF=1
 MSGFILE=msg/error$(FPCLANG).msg
 SVNVERSION:=$(firstword $(wildcard $(addsuffix /svnversion$(SRCEXEEXT),$(SEARCHPATH))))
@@ -485,6 +508,9 @@ endif
 ifeq ($(PPC_TARGET),jvm)
 override LOCALOPT+=-Fujvm -dNOOPT
 endif
+ifeq ($(PPC_TARGET),i8086)
+override LOCALOPT+=-Fux86
+endif
 OPTWPOCOLLECT=-OWdevirtcalls,optvmts -FW$(BASEDIR)/pp1.wpo
 OPTWPOPERFORM=-Owdevirtcalls,optvmts -Fw$(BASEDIR)/pp1.wpo
 ifneq ($(findstring $(OS_TARGET),darwin linux freebsd solaris),)
@@ -504,6 +530,9 @@ endif
 ifeq ($(OS_TARGET),gba)
 NoNativeBinaries=1
 endif
+ifeq ($(OS_TARGET),msdos)
+NoNativeBinaries=1
+endif
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_DIRS+=utils
 endif
@@ -570,6 +599,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 override TARGET_DIRS+=utils
 endif
+ifeq ($(FULL_TARGET),i386-android)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_DIRS+=utils
 endif
@@ -681,6 +713,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 override TARGET_DIRS+=utils
 endif
+ifeq ($(FULL_TARGET),arm-android)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 override TARGET_DIRS+=utils
 endif
@@ -714,6 +749,9 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 override TARGET_DIRS+=utils
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_PROGRAMS+=pp
 endif
@@ -780,6 +818,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 override TARGET_PROGRAMS+=pp
 endif
+ifeq ($(FULL_TARGET),i386-android)
+override TARGET_PROGRAMS+=pp
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_PROGRAMS+=pp
 endif
@@ -891,6 +932,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 override TARGET_PROGRAMS+=pp
 endif
+ifeq ($(FULL_TARGET),arm-android)
+override TARGET_PROGRAMS+=pp
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 override TARGET_PROGRAMS+=pp
 endif
@@ -924,6 +968,9 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 override TARGET_PROGRAMS+=pp
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+override TARGET_PROGRAMS+=pp
+endif
 override INSTALL_FPCPACKAGE=y
 ifeq ($(FULL_TARGET),i386-linux)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
@@ -991,6 +1038,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
+ifeq ($(FULL_TARGET),i386-android)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
@@ -1102,6 +1152,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
+ifeq ($(FULL_TARGET),arm-android)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
@@ -1135,6 +1188,9 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),i386-linux)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
@@ -1201,6 +1257,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
+ifeq ($(FULL_TARGET),i386-android)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
@@ -1312,6 +1371,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
+ifeq ($(FULL_TARGET),arm-android)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
@@ -1345,6 +1407,9 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),i386-linux)
 override COMPILER_TARGETDIR+=.
 endif
@@ -1411,6 +1476,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 override COMPILER_TARGETDIR+=.
 endif
+ifeq ($(FULL_TARGET),i386-android)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_TARGETDIR+=.
 endif
@@ -1522,6 +1590,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 override COMPILER_TARGETDIR+=.
 endif
+ifeq ($(FULL_TARGET),arm-android)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 override COMPILER_TARGETDIR+=.
 endif
@@ -1555,6 +1626,9 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 override COMPILER_TARGETDIR+=.
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),i386-linux)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
@@ -1621,6 +1695,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
+ifeq ($(FULL_TARGET),i386-android)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
@@ -1732,6 +1809,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
+ifeq ($(FULL_TARGET),arm-android)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
@@ -1765,6 +1845,9 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifdef REQUIRE_UNITSDIR
 override UNITSDIR+=$(REQUIRE_UNITSDIR)
 endif
@@ -1993,6 +2076,14 @@ SHAREDLIBEXT=.dll
 SHORTSUFFIX=wat
 IMPORTLIBPREFIX=
 endif
+ifneq ($(CPU_TARGET),jvm)
+ifeq ($(OS_TARGET),android)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+endif
 ifeq ($(OS_TARGET),linux)
 BATCHEXT=.sh
 EXEEXT=
@@ -2128,12 +2219,19 @@ ASMEXT=.j
 SHAREDLIBEXT=.jar
 SHORTSUFFIX=java
 endif
+ifeq ($(CPU_TARGET),jvm)
 ifeq ($(OS_TARGET),android)
 OEXT=.class
 ASMEXT=.j
 SHAREDLIBEXT=.jar
 SHORTSUFFIX=android
 endif
+endif
+ifeq ($(OS_TARGET),msdos)
+STATICLIBPREFIX=
+STATICLIBEXT=.lib
+SHORTSUFFIX=d16
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -2355,7 +2453,11 @@ AS=$(ASPROG)
 LD=$(LDPROG)
 RC=$(RCPROG)
 AR=$(ARPROG)
+ifdef inUnix
+PPAS=./ppas$(SRCBATCHEXT)
+else
 PPAS=ppas$(SRCBATCHEXT)
+endif
 ifdef inUnix
 LDCONFIG=ldconfig
 else
@@ -2442,6 +2544,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),i386-android)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -2553,6 +2658,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),arm-android)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -2586,6 +2694,9 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),i8086-msdos)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifdef REQUIRE_PACKAGES_RTL
 PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_RTL),)
@@ -3278,6 +3389,9 @@ endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
 TARGET_DIRS_UTILS=1
 endif
+ifeq ($(FULL_TARGET),i386-android)
+TARGET_DIRS_UTILS=1
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 TARGET_DIRS_UTILS=1
 endif
@@ -3389,6 +3503,9 @@ endif
 ifeq ($(FULL_TARGET),arm-symbian)
 TARGET_DIRS_UTILS=1
 endif
+ifeq ($(FULL_TARGET),arm-android)
+TARGET_DIRS_UTILS=1
+endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
 TARGET_DIRS_UTILS=1
 endif
@@ -3422,50 +3539,8 @@ endif
 ifeq ($(FULL_TARGET),jvm-android)
 TARGET_DIRS_UTILS=1
 endif
-ifdef TARGET_DIRS_TARGET_DIRS
-TARGET_DIRS_all:
-	$(MAKE) -C TARGET_DIRS all
-TARGET_DIRS_debug:
-	$(MAKE) -C TARGET_DIRS debug
-TARGET_DIRS_smart:
-	$(MAKE) -C TARGET_DIRS smart
-TARGET_DIRS_release:
-	$(MAKE) -C TARGET_DIRS release
-TARGET_DIRS_units:
-	$(MAKE) -C TARGET_DIRS units
-TARGET_DIRS_examples:
-	$(MAKE) -C TARGET_DIRS examples
-TARGET_DIRS_shared:
-	$(MAKE) -C TARGET_DIRS shared
-TARGET_DIRS_install:
-	$(MAKE) -C TARGET_DIRS install
-TARGET_DIRS_sourceinstall:
-	$(MAKE) -C TARGET_DIRS sourceinstall
-TARGET_DIRS_exampleinstall:
-	$(MAKE) -C TARGET_DIRS exampleinstall
-TARGET_DIRS_distinstall:
-	$(MAKE) -C TARGET_DIRS distinstall
-TARGET_DIRS_zipinstall:
-	$(MAKE) -C TARGET_DIRS zipinstall
-TARGET_DIRS_zipsourceinstall:
-	$(MAKE) -C TARGET_DIRS zipsourceinstall
-TARGET_DIRS_zipexampleinstall:
-	$(MAKE) -C TARGET_DIRS zipexampleinstall
-TARGET_DIRS_zipdistinstall:
-	$(MAKE) -C TARGET_DIRS zipdistinstall
-TARGET_DIRS_clean:
-	$(MAKE) -C TARGET_DIRS clean
-TARGET_DIRS_distclean:
-	$(MAKE) -C TARGET_DIRS distclean
-TARGET_DIRS_cleanall:
-	$(MAKE) -C TARGET_DIRS cleanall
-TARGET_DIRS_info:
-	$(MAKE) -C TARGET_DIRS info
-TARGET_DIRS_makefiles:
-	$(MAKE) -C TARGET_DIRS makefiles
-TARGET_DIRS:
-	$(MAKE) -C TARGET_DIRS all
-.PHONY: TARGET_DIRS_all TARGET_DIRS_debug TARGET_DIRS_smart TARGET_DIRS_release TARGET_DIRS_units TARGET_DIRS_examples TARGET_DIRS_shared TARGET_DIRS_install TARGET_DIRS_sourceinstall TARGET_DIRS_exampleinstall TARGET_DIRS_distinstall TARGET_DIRS_zipinstall TARGET_DIRS_zipsourceinstall TARGET_DIRS_zipexampleinstall TARGET_DIRS_zipdistinstall TARGET_DIRS_clean TARGET_DIRS_distclean TARGET_DIRS_cleanall TARGET_DIRS_info TARGET_DIRS_makefiles TARGET_DIRS
+ifeq ($(FULL_TARGET),i8086-msdos)
+TARGET_DIRS_UTILS=1
 endif
 ifdef TARGET_DIRS_UTILS
 utils_all:
@@ -3512,51 +3587,6 @@ utils:
 	$(MAKE) -C utils all
 .PHONY: utils_all utils_debug utils_smart utils_release utils_units utils_examples utils_shared utils_install utils_sourceinstall utils_exampleinstall utils_distinstall utils_zipinstall utils_zipsourceinstall utils_zipexampleinstall utils_zipdistinstall utils_clean utils_distclean utils_cleanall utils_info utils_makefiles utils
 endif
-ifdef TARGET_EXAMPLEDIRS_TARGET_EXAMPLEDIRS
-TARGET_EXAMPLEDIRS_all:
-	$(MAKE) -C TARGET_EXAMPLEDIRS all
-TARGET_EXAMPLEDIRS_debug:
-	$(MAKE) -C TARGET_EXAMPLEDIRS debug
-TARGET_EXAMPLEDIRS_smart:
-	$(MAKE) -C TARGET_EXAMPLEDIRS smart
-TARGET_EXAMPLEDIRS_release:
-	$(MAKE) -C TARGET_EXAMPLEDIRS release
-TARGET_EXAMPLEDIRS_units:
-	$(MAKE) -C TARGET_EXAMPLEDIRS units
-TARGET_EXAMPLEDIRS_examples:
-	$(MAKE) -C TARGET_EXAMPLEDIRS examples
-TARGET_EXAMPLEDIRS_shared:
-	$(MAKE) -C TARGET_EXAMPLEDIRS shared
-TARGET_EXAMPLEDIRS_install:
-	$(MAKE) -C TARGET_EXAMPLEDIRS install
-TARGET_EXAMPLEDIRS_sourceinstall:
-	$(MAKE) -C TARGET_EXAMPLEDIRS sourceinstall
-TARGET_EXAMPLEDIRS_exampleinstall:
-	$(MAKE) -C TARGET_EXAMPLEDIRS exampleinstall
-TARGET_EXAMPLEDIRS_distinstall:
-	$(MAKE) -C TARGET_EXAMPLEDIRS distinstall
-TARGET_EXAMPLEDIRS_zipinstall:
-	$(MAKE) -C TARGET_EXAMPLEDIRS zipinstall
-TARGET_EXAMPLEDIRS_zipsourceinstall:
-	$(MAKE) -C TARGET_EXAMPLEDIRS zipsourceinstall
-TARGET_EXAMPLEDIRS_zipexampleinstall:
-	$(MAKE) -C TARGET_EXAMPLEDIRS zipexampleinstall
-TARGET_EXAMPLEDIRS_zipdistinstall:
-	$(MAKE) -C TARGET_EXAMPLEDIRS zipdistinstall
-TARGET_EXAMPLEDIRS_clean:
-	$(MAKE) -C TARGET_EXAMPLEDIRS clean
-TARGET_EXAMPLEDIRS_distclean:
-	$(MAKE) -C TARGET_EXAMPLEDIRS distclean
-TARGET_EXAMPLEDIRS_cleanall:
-	$(MAKE) -C TARGET_EXAMPLEDIRS cleanall
-TARGET_EXAMPLEDIRS_info:
-	$(MAKE) -C TARGET_EXAMPLEDIRS info
-TARGET_EXAMPLEDIRS_makefiles:
-	$(MAKE) -C TARGET_EXAMPLEDIRS makefiles
-TARGET_EXAMPLEDIRS:
-	$(MAKE) -C TARGET_EXAMPLEDIRS all
-.PHONY: TARGET_EXAMPLEDIRS_all TARGET_EXAMPLEDIRS_debug TARGET_EXAMPLEDIRS_smart TARGET_EXAMPLEDIRS_release TARGET_EXAMPLEDIRS_units TARGET_EXAMPLEDIRS_examples TARGET_EXAMPLEDIRS_shared TARGET_EXAMPLEDIRS_install TARGET_EXAMPLEDIRS_sourceinstall TARGET_EXAMPLEDIRS_exampleinstall TARGET_EXAMPLEDIRS_distinstall TARGET_EXAMPLEDIRS_zipinstall TARGET_EXAMPLEDIRS_zipsourceinstall TARGET_EXAMPLEDIRS_zipexampleinstall TARGET_EXAMPLEDIRS_zipdistinstall TARGET_EXAMPLEDIRS_clean TARGET_EXAMPLEDIRS_distclean TARGET_EXAMPLEDIRS_cleanall TARGET_EXAMPLEDIRS_info TARGET_EXAMPLEDIRS_makefiles TARGET_EXAMPLEDIRS
-endif
 ifndef DIFF
 DIFF:=$(strip $(wildcard $(addsuffix /diff$(SRCEXEEXT),$(SEARCHPATH))))
 ifeq ($(DIFF),)
@@ -3640,7 +3670,7 @@ INSTALLEXEFILE=$(PPCROSSNAME)
 else
 INSTALLEXEFILE=$(EXENAME)
 endif
-PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 alpha vis ia64 mips mipsel avr jvm
+PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 alpha vis ia64 mips mipsel avr jvm i8086
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS)
 $(PPC_TARGETS):
@@ -3675,11 +3705,11 @@ ppuclean:
 tempclean:
 	-$(DEL) $(PPCROSSNAME) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC) pp1.wpo pp2.wpo
 execlean :
-	-$(DEL) ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2)
+	-$(DEL) ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2)
 $(addsuffix _clean,$(ALLTARGETS)):
 	-$(DELTREE) $(addprefix $(subst _clean,,$@),/units)
 	-$(DEL) $(addprefix $(subst _clean,,$@)/,*$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT))
-	-$(DEL) $(addprefix $(subst _clean,,$@)/,ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT)  $(EXENAME))
+	-$(DEL) $(addprefix $(subst _clean,,$@)/,ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) $(EXENAME))
 cycleclean: cleanall $(addsuffix _clean,$(CPC_TARGET))
 	-$(DEL) $(EXENAME)
 clean: tempclean execlean cleanall $(addsuffix _clean,$(CPC_TARGET)) $(addsuffix _clean,$(TARGET_DIRS))
@@ -3702,7 +3732,10 @@ insdatx86 : $(COMPILER_UNITTARGETDIR) x86/x86ins.dat
 insdatarm : arm/armins.dat
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkarmins.pp
 	cd arm && ..$(PATHSEP)utils$(PATHSEP)mkarmins$(SRCEXEEXT)
-insdat: insdatx86 insdatarm
+insdataarch64 : aarch64/a64ins.dat
+	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mka64ins.pp
+	cd aarch64 && ..$(PATHSEP)utils$(PATHSEP)mka64ins$(SRCEXEEXT)
+insdat: insdatx86 insdatarm insdataarch64
 regdatarm : arm/armreg.dat
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkarmreg.pp
 	cd arm && ..$(PATHSEP)utils$(PATHSEP)mkarmreg$(SRCEXEEXT)
@@ -3715,6 +3748,9 @@ regdatsp : sparc/spreg.dat
 regdatavr : avr/avrreg.dat
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkavrreg.pp
 	cd avr && ..$(PATHSEP)utils$(PATHSEP)mkavrreg$(SRCEXEEXT)
+regdataarch64 : aarch64/a64reg.dat
+	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mka64reg.pp
+	cd aarch64 && ..$(PATHSEP)utils$(PATHSEP)mka64reg$(SRCEXEEXT)
 revision.inc :
 ifneq ($(REVSTR),)
 ifdef USEZIPWRAPPER
@@ -3816,12 +3852,12 @@ cycle:
 	$(MAKE) echotime
 else
 cycle:
-	$(MAKE) OS_TARGET=$(OS_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl
+	$(MAKE) OS_TARGET=$(OS_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl CYCLELEVEL=1
 	$(MAKE) OS_TARGET=$(OS_SOURCE) EXENAME=$(TEMPNAME) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 cycleclean compiler CYCLELEVEL=1
-	$(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl
+	$(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl CYCLELEVEL=2
 	$(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) EXENAME=$(PPCROSSNAME) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 cycleclean compiler CYCLELEVEL=2
 ifndef CROSSINSTALL
-	$(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' rtlclean rtl
+	$(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' rtlclean rtl CYCLELEVEL=3
 ifneq ($(OS_TARGET),embedded)
 ifneq ($(OS_TARGET),gba)
 	$(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' cycleclean compiler CYCLELEVEL=3
@@ -3832,12 +3868,12 @@ endif
 else
 cycle: override FPC=
 cycle:
-	$(MAKE) OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl
+	$(MAKE) OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl CYCLELEVEL=1
 	$(MAKE) OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) EXENAME=$(TEMPNAME) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 cycleclean compiler CYCLELEVEL=1
-	$(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl
+	$(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl CYCLELEVEL=‚
 	$(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) PPC_TARGET=$(CPU_TARGET) EXENAME=$(PPCROSSNAME) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 cycleclean compiler CYCLELEVEL=2
 ifndef CROSSINSTALL
-	$(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' 'OPT=$(RTLOPT) $(CROSSOPT)' rtlclean rtl
+	$(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' 'OPT=$(RTLOPT) $(CROSSOPT)' rtlclean rtl CYCLELEVEL=3
 ifndef NoNativeBinaries
 	$(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' 'OPT=$(LOCALOPT) $(CROSSOPT)' cycleclean compiler CYCLELEVEL=3
 endif

+ 49 - 29
compiler/Makefile.fpc

@@ -32,10 +32,10 @@ fpcdir=..
 unexport FPC_VERSION FPC_COMPILERINFO
 
 # Which platforms are ready for inclusion in the cycle
-CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr
+CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086
 
 # All supported targets used for clean
-ALLTARGETS=$(CYCLETARGETS) jvm
+ALLTARGETS=$(CYCLETARGETS)
 
 # Allow ALPHA, POWERPC, POWERPC64, M68K, I386, jvm defines for target cpu
 ifdef ALPHA
@@ -77,6 +77,9 @@ endif
 ifdef JVM
 PPC_TARGET=jvm
 endif
+ifdef I8086
+PPC_TARGET=i8086
+endif
 
 # Default is to generate a compiler for the same
 # platform as CPU_TARGET (a native compiler)
@@ -125,28 +128,28 @@ endif
 
 ifdef CYCLELEVEL
 ifeq ($(CYCLELEVEL),1)
-LOCALOOPT+=$(OPTLEVEL1)
-RTLOPT+=$(OPTLEVEL1)
-LOCALOPT+=$(LOCALOPTLEVEL1)
-RTLOPT+=$(RTLOPTLEVEL1)
+override LOCALOPT+=$(OPTLEVEL1)
+override RTLOPT+=$(OPTLEVEL1)
+override LOCALOPT+=$(LOCALOPTLEVEL1)
+override RTLOPT+=$(RTLOPTLEVEL1)
 endif
 ifeq ($(CYCLELEVEL),2)
-LOCALOOPT+=$(OPTLEVEL2)
-RTLOPT+=$(OPTLEVEL2)
-LOCALOPT+=$(LOCALOPTLEVEL2)
-RTLOPT+=$(RTLOPTLEVEL2)
+override LOCALOPT+=$(OPTLEVEL2)
+override RTLOPT+=$(OPTLEVEL2)
+override LOCALOPT+=$(LOCALOPTLEVEL2)
+override RTLOPT+=$(RTLOPTLEVEL2)
 endif
 ifeq ($(CYCLELEVEL),3)
-LOCALOOPT+=$(OPTLEVEL3)
-RTLOPT+=$(OPTLEVEL3)
-LOCALOPT+=$(LOCALOPTLEVEL3)
-RTLOPT+=$(RTLOPTLEVEL3)
+override LOCALOPT+=$(OPTLEVEL3)
+override RTLOPT+=$(OPTLEVEL3)
+override LOCALOPT+=$(LOCALOPTLEVEL3)
+override RTLOPT+=$(RTLOPTLEVEL3)
 endif
 ifeq ($(CYCLELEVEL),4)
-LOCALOOPT+=$(OPTLEVEL4)
-RTLOPT+=$(OPTLEVEL4)
-LOCALOPT+=$(LOCALOPTLEVEL4)
-RTLOPT+=$(RTLOPTLEVEL4)
+override LOCALOPT+=$(OPTLEVEL4)
+override RTLOPT+=$(OPTLEVEL4)
+override LOCALOPT+=$(LOCALOPTLEVEL4)
+override RTLOPT+=$(RTLOPTLEVEL4)
 endif
 endif
 
@@ -193,6 +196,9 @@ endif
 ifeq ($(CPC_TARGET),jvm)
 CPUSUF=jvm
 endif
+ifeq ($(CPC_TARGET),i8086)
+CPUSUF=8086
+endif
 
 # Do not define the default -d$(CPU_TARGET) because that
 # will conflict with our -d$(CPC_TARGET)
@@ -279,6 +285,11 @@ ifeq ($(PPC_TARGET),jvm)
 override LOCALOPT+=-Fujvm -dNOOPT
 endif
 
+# i8086 specific
+ifeq ($(PPC_TARGET),i8086)
+override LOCALOPT+=-Fux86
+endif
+
 OPTWPOCOLLECT=-OWdevirtcalls,optvmts -FW$(BASEDIR)/pp1.wpo
 OPTWPOPERFORM=-Owdevirtcalls,optvmts -Fw$(BASEDIR)/pp1.wpo
 # symbol liveness WPO requires nm, smart linking and no stripping (the latter
@@ -303,6 +314,9 @@ endif
 ifeq ($(OS_TARGET),gba)
 NoNativeBinaries=1
 endif
+ifeq ($(OS_TARGET),msdos)
+NoNativeBinaries=1
+endif
 
 [rules]
 #####################################################################
@@ -377,7 +391,7 @@ endif
 # CPU targets
 #####################################################################
 
-PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 alpha vis ia64 mips mipsel avr jvm
+PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 alpha vis ia64 mips mipsel avr jvm i8086
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 
 .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS)
@@ -432,12 +446,12 @@ tempclean:
         -$(DEL) $(PPCROSSNAME) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC) pp1.wpo pp2.wpo
 
 execlean :
-        -$(DEL) ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2)
+        -$(DEL) ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2)
 
 $(addsuffix _clean,$(ALLTARGETS)):
         -$(DELTREE) $(addprefix $(subst _clean,,$@),/units)
         -$(DEL) $(addprefix $(subst _clean,,$@)/,*$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT))
-        -$(DEL) $(addprefix $(subst _clean,,$@)/,ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT)  $(EXENAME))
+        -$(DEL) $(addprefix $(subst _clean,,$@)/,ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) $(EXENAME))
 
 cycleclean: cleanall $(addsuffix _clean,$(CPC_TARGET))
         -$(DEL) $(EXENAME)
@@ -476,7 +490,11 @@ insdatarm : arm/armins.dat
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkarmins.pp
         cd arm && ..$(PATHSEP)utils$(PATHSEP)mkarmins$(SRCEXEEXT)
 
-insdat: insdatx86 insdatarm
+insdataarch64 : aarch64/a64ins.dat
+	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mka64ins.pp
+        cd aarch64 && ..$(PATHSEP)utils$(PATHSEP)mka64ins$(SRCEXEEXT)
+
+insdat: insdatx86 insdatarm insdataarch64
 
 regdatarm : arm/armreg.dat
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkarmreg.pp
@@ -494,7 +512,9 @@ regdatavr : avr/avrreg.dat
             $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkavrreg.pp
         cd avr && ..$(PATHSEP)utils$(PATHSEP)mkavrreg$(SRCEXEEXT)
 
-
+regdataarch64 : aarch64/a64reg.dat
+	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mka64reg.pp
+        cd aarch64 && ..$(PATHSEP)utils$(PATHSEP)mka64reg$(SRCEXEEXT)
 
 # revision.inc rule
 revision.inc :
@@ -645,14 +665,14 @@ else
 
 cycle:
 # ppc (source native)
-        $(MAKE) OS_TARGET=$(OS_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl
+        $(MAKE) OS_TARGET=$(OS_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl CYCLELEVEL=1
         $(MAKE) OS_TARGET=$(OS_SOURCE) EXENAME=$(TEMPNAME) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 cycleclean compiler CYCLELEVEL=1
 # ppcross<ARCH> (source native)
-        $(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl
+        $(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl CYCLELEVEL=2
         $(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) EXENAME=$(PPCROSSNAME) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 cycleclean compiler CYCLELEVEL=2
 # ppc<ARCH> (target native)
 ifndef CROSSINSTALL
-        $(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' rtlclean rtl
+        $(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' rtlclean rtl CYCLELEVEL=3
 # building a native compiler for embedded targets is not possible
 ifneq ($(OS_TARGET),embedded)
 # building a native compiler for the arm-gba target is not possible
@@ -678,14 +698,14 @@ cycle: override FPC=
 cycle:
 # ppc (source native)
 # Clear detected compiler binary, because it can be existing crosscompiler binary, but we need native compiler here
-        $(MAKE) OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl
+        $(MAKE) OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl CYCLELEVEL=1
         $(MAKE) OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) EXENAME=$(TEMPNAME) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 cycleclean compiler CYCLELEVEL=1
 # ppcross<ARCH> (source native)
-        $(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl
+        $(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 rtlclean rtl CYCLELEVEL=‚
         $(MAKE) 'FPC=$(BASEDIR)/$(TEMPNAME)' OS_TARGET=$(OS_SOURCE) CPU_TARGET=$(CPU_SOURCE) PPC_TARGET=$(CPU_TARGET) EXENAME=$(PPCROSSNAME) CROSSBINDIR= BINUTILSPREFIX= CROSSCYCLEBOOTSTRAP=1 cycleclean compiler CYCLELEVEL=2
 # ppc<ARCH> (target native)
 ifndef CROSSINSTALL
-        $(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' 'OPT=$(RTLOPT) $(CROSSOPT)' rtlclean rtl
+        $(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' 'OPT=$(RTLOPT) $(CROSSOPT)' rtlclean rtl CYCLELEVEL=3
 # building a native compiler for JVM and embedded targets is not possible
 ifndef NoNativeBinaries
         $(MAKE) 'FPC=$(BASEDIR)/$(PPCROSSNAME)' 'OPT=$(LOCALOPT) $(CROSSOPT)' cycleclean compiler CYCLELEVEL=3

+ 133 - 0
compiler/aarch64/a64att.inc

@@ -0,0 +1,133 @@
+{ don't edit, this file is generated from armins.dat }
+(
+'b',
+'cb',
+'tb',
+'bl',
+'blr',
+'br',
+'ret',
+'ldr',
+'str',
+'ldp',
+'stp',
+'ldnp',
+'stnp',
+'ldtr',
+'sttr',
+'ldxr',
+'stxr',
+'ldar',
+'stlr',
+'ldaxr',
+'stlxr',
+'prfm',
+'add',
+'adc',
+'sub',
+'sbc',
+'cmp',
+'cmn',
+'mov',
+'and',
+'bic',
+'eor',
+'eon',
+'orr',
+'orn',
+'tst',
+'mvn',
+'movk',
+'adrp',
+'adr',
+'bfm',
+'sbfm',
+'ubfm',
+'extr',
+'sxt',
+'uxt',
+'asrv',
+'llslv',
+'lsrv',
+'rorv',
+'cls',
+'clz',
+'rbit',
+'rev',
+'rev16',
+'rev32',
+'csel',
+'csinc',
+'csinv',
+'csneg',
+'ccmn',
+'ccmp',
+'madd',
+'msub',
+'smaddl',
+'smsubl',
+'smulh',
+'umaddl',
+'umsubl',
+'umulh',
+'sdiv',
+'udiv',
+'neg',
+'asr',
+'lsl',
+'lsr',
+'ror',
+'cset',
+'csetm',
+'cinc',
+'cinv',
+'cneg',
+'ngc',
+'mneg',
+'mul',
+'smnegl',
+'smull',
+'umnegl',
+'umull',
+'fmov',
+'fcvt',
+'fcvtas',
+'fcvtau',
+'fcvtms',
+'fcvtmu',
+'fcvtns',
+'fcvtnu',
+'fcvtps',
+'fcvtpu',
+'fcvtzs',
+'fcvtzu',
+'scvtf',
+'ucvtf',
+'fprinta',
+'fprinti',
+'fprintm',
+'fprintn',
+'fprintp',
+'fprintx',
+'fprintz',
+'fabs',
+'fneg',
+'fsqrt',
+'fadd',
+'fdiv',
+'fmul',
+'fnmul',
+'fsub',
+'fmax',
+'fmin',
+'fminnm',
+'fmadd',
+'fmsub',
+'fnmadd',
+'fnmsub',
+'fcmp',
+'fcmpe',
+'fccmp',
+'fcmmpe',
+'fcsel'
+);

+ 133 - 0
compiler/aarch64/a64atts.inc

@@ -0,0 +1,133 @@
+{ don't edit, this file is generated from armins.dat }
+(
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE
+);

+ 262 - 0
compiler/aarch64/a64ins.dat

@@ -0,0 +1,262 @@
+[B]
+
+[CB]
+
+[TB]
+
+[BL]
+
+[BLR]
+
+[BR]
+
+[RET]
+
+[LDR]
+
+[STR]
+
+[LDP]
+
+[STP]
+
+[LDNP]
+
+[STNP]
+
+[LDTR]
+
+[STTR]
+
+[LDXR]
+
+[STXR]
+
+[LDAR]
+
+[STLR]
+
+[LDAXR]
+
+[STLXR]
+
+[PRFM]
+
+[ADD]
+
+[ADC]
+
+[SUB]
+
+[SBC]
+
+[CMP]
+
+[CMN]
+
+[MOV]
+
+[AND]
+
+[BIC]
+
+[EOR]
+
+[EON]
+
+[ORR]
+
+[ORN]
+
+[TST]
+
+[MVN]
+
+[MOVK]
+
+[ADRP]
+
+[ADR]
+
+[BFM]
+
+[SBFM]
+
+[UBFM]
+
+[EXTR]
+
+[SXT]
+
+[UXT]
+
+[ASRV]
+
+[LLSLV]
+
+[LSRV]
+
+[RORV]
+
+[CLS]
+
+[CLZ]
+
+[RBIT]
+
+[REV]
+
+[REV16]
+
+[REV32]
+
+[CSEL]
+
+[CSINC]
+
+[CSINV]
+
+[CSNEG]
+
+[CCMN]
+
+[CCMP]
+
+[MADD]
+
+[MSUB]
+
+[SMADDL]
+
+[SMSUBL]
+
+[SMULH]
+
+[UMADDL]
+
+[UMSUBL]
+
+[UMULH]
+
+[SDIV]
+
+[UDIV]
+
+; Aliases
+; they are not generated by the compiler, they are only used for inline assembler
+[NEG]
+
+[ASR]
+
+[LSL]
+
+[LSR]
+
+[ROR]
+
+[CSET]
+
+[CSETM]
+
+[CINC]
+
+[CINV]
+
+[CNEG]
+
+[NGC]
+
+[MNEG]
+
+[MUL]
+
+[SMNEGL]
+
+[SMULL]
+
+[UMNEGL]
+
+[UMULL]
+
+[FMOV]
+
+[FCVT]
+
+[FCVTAS]
+
+[FCVTAU]
+
+[FCVTMS]
+
+[FCVTMU]
+
+[FCVTNS]
+
+[FCVTNU]
+
+[FCVTPS]
+
+[FCVTPU]
+
+[FCVTZS]
+
+[FCVTZU]
+
+[SCVTF]
+
+[UCVTF]
+
+[FPRINTA]
+
+[FPRINTI]
+
+[FPRINTM]
+
+[FPRINTN]
+
+[FPRINTP]
+
+[FPRINTX]
+
+[FPRINTZ]
+
+[FABS]
+
+[FNEG]
+
+[FSQRT]
+
+[FADD]
+
+[FDIV]
+
+[FMUL]
+
+[FNMUL]
+
+[FSUB]
+
+[FMAX]
+
+[FMIN]
+
+[FMINNM]
+
+[FMADD]
+
+[FMSUB]
+
+[FNMADD]
+
+[FNMSUB]
+
+[FCMP]
+
+[FCMPE]
+
+[FCCMP]
+
+[FCMMPE]
+
+[FCSEL]
+

+ 2 - 0
compiler/aarch64/a64nop.inc

@@ -0,0 +1,2 @@
+{ don't edit, this file is generated from a64ins.dat }
+0;

+ 133 - 0
compiler/aarch64/a64op.inc

@@ -0,0 +1,133 @@
+{ don't edit, this file is generated from armins.dat }
+(
+A_B,
+A_CB,
+A_TB,
+A_BL,
+A_BLR,
+A_BR,
+A_RET,
+A_LDR,
+A_STR,
+A_LDP,
+A_STP,
+A_LDNP,
+A_STNP,
+A_LDTR,
+A_STTR,
+A_LDXR,
+A_STXR,
+A_LDAR,
+A_STLR,
+A_LDAXR,
+A_STLXR,
+A_PRFM,
+A_ADD,
+A_ADC,
+A_SUB,
+A_SBC,
+A_CMP,
+A_CMN,
+A_MOV,
+A_AND,
+A_BIC,
+A_EOR,
+A_EON,
+A_ORR,
+A_ORN,
+A_TST,
+A_MVN,
+A_MOVK,
+A_ADRP,
+A_ADR,
+A_BFM,
+A_SBFM,
+A_UBFM,
+A_EXTR,
+A_SXT,
+A_UXT,
+A_ASRV,
+A_LLSLV,
+A_LSRV,
+A_RORV,
+A_CLS,
+A_CLZ,
+A_RBIT,
+A_REV,
+A_REV16,
+A_REV32,
+A_CSEL,
+A_CSINC,
+A_CSINV,
+A_CSNEG,
+A_CCMN,
+A_CCMP,
+A_MADD,
+A_MSUB,
+A_SMADDL,
+A_SMSUBL,
+A_SMULH,
+A_UMADDL,
+A_UMSUBL,
+A_UMULH,
+A_SDIV,
+A_UDIV,
+A_NEG,
+A_ASR,
+A_LSL,
+A_LSR,
+A_ROR,
+A_CSET,
+A_CSETM,
+A_CINC,
+A_CINV,
+A_CNEG,
+A_NGC,
+A_MNEG,
+A_MUL,
+A_SMNEGL,
+A_SMULL,
+A_UMNEGL,
+A_UMULL,
+A_FMOV,
+A_FCVT,
+A_FCVTAS,
+A_FCVTAU,
+A_FCVTMS,
+A_FCVTMU,
+A_FCVTNS,
+A_FCVTNU,
+A_FCVTPS,
+A_FCVTPU,
+A_FCVTZS,
+A_FCVTZU,
+A_SCVTF,
+A_UCVTF,
+A_FPRINTA,
+A_FPRINTI,
+A_FPRINTM,
+A_FPRINTN,
+A_FPRINTP,
+A_FPRINTX,
+A_FPRINTZ,
+A_FABS,
+A_FNEG,
+A_FSQRT,
+A_FADD,
+A_FDIV,
+A_FMUL,
+A_FNMUL,
+A_FSUB,
+A_FMAX,
+A_FMIN,
+A_FMINNM,
+A_FMADD,
+A_FMSUB,
+A_FNMADD,
+A_FNMSUB,
+A_FCMP,
+A_FCMPE,
+A_FCCMP,
+A_FCMMPE,
+A_FCSEL
+);

+ 238 - 0
compiler/aarch64/a64reg.dat

@@ -0,0 +1,238 @@
+;
+; AArch64 registers
+;
+; layout
+; <name>,<type>,<subtype>,<value>,<stdname>,<stab idx>,<dwarf idx>
+;
+NO,$00,$00,$00,INVALID,-1,-1
+; Integer registers
+W0,$01,$04,$00,w0,0,0
+X0,$01,$05,$00,x0,0,0
+W1,$01,$04,$01,w1,1,1
+X1,$01,$05,$01,x1,1,1
+W2,$01,$04,$02,w2,2,2
+X2,$01,$05,$02,x2,2,2
+W3,$01,$04,$03,w3,3,3
+X3,$01,$05,$03,x3,3,3
+W4,$01,$04,$04,w4,4,4
+X4,$01,$05,$04,x4,4,4
+W5,$01,$04,$05,w5,5,5
+X5,$01,$05,$05,x5,5,5
+W6,$01,$04,$06,w6,6,6
+X6,$01,$05,$06,x6,6,6
+W7,$01,$04,$07,w7,7,7
+X7,$01,$05,$07,x7,7,7
+W8,$01,$04,$08,w8,8,8
+X8,$01,$05,$08,x8,8,8
+W9,$01,$04,$09,w9,9,9
+X9,$01,$05,$09,x9,9,9
+W10,$01,$04,$0A,w10,10,10
+X10,$01,$05,$0A,x10,10,10
+W11,$01,$04,$0B,w11,11,11
+X11,$01,$05,$0B,x11,11,11
+W12,$01,$04,$0C,w12,12,12
+X12,$01,$05,$0C,x12,12,12
+W13,$01,$04,$0D,w13,13,13
+X13,$01,$05,$0D,x13,13,13
+W14,$01,$04,$0E,w14,14,14
+X14,$01,$05,$0E,x14,14,14
+W15,$01,$04,$0F,w15,15,15
+X15,$01,$05,$0F,x15,15,15
+W16,$01,$04,$10,w16,16,16
+X16,$01,$05,$10,x16,16,16
+W17,$01,$04,$11,w17,17,17
+X17,$01,$05,$11,x17,17,17
+W18,$01,$04,$12,w18,18,18
+X18,$01,$05,$12,x18,18,18
+W19,$01,$04,$13,w19,19,19
+X19,$01,$05,$13,x19,19,19
+W20,$01,$04,$14,w20,20,20
+X20,$01,$05,$14,x20,20,20
+W21,$01,$04,$15,w21,21,21
+X21,$01,$05,$15,x21,21,21
+W22,$01,$04,$16,w22,22,22
+X22,$01,$05,$16,x22,22,22
+W23,$01,$04,$17,w23,23,23
+X23,$01,$05,$17,x23,23,23
+W24,$01,$04,$18,w24,24,24
+X24,$01,$05,$18,x24,24,24
+W25,$01,$04,$19,w25,25,25
+X25,$01,$05,$19,x25,25,25
+W26,$01,$04,$1A,w26,26,26
+X26,$01,$05,$1A,x26,26,26
+W27,$01,$04,$1B,w27,27,27
+X27,$01,$05,$1B,x27,27,27
+W28,$01,$04,$1C,w28,28,28
+X28,$01,$05,$1C,x28,28,28
+W29,$01,$04,$1D,w29,29,29
+X29,$01,$05,$1D,x29,29,29
+W30,$01,$04,$1E,w30,30,30
+X30,$01,$05,$1E,x30,30,30
+WZR,$01,$04,$1F,wzr,31,31
+XZR,$01,$05,$1F,xzr,31,31
+
+
+; vfp registers
+B0,$04,$01,$00,b0,0,0
+H0,$04,$03,$00,h0,0,0
+S0,$04,$09,$00,s0,0,0
+D0,$04,$0a,$00,d0,0,0
+Q0,$04,$05,$00,q0,0,0
+B1,$04,$01,$01,b1,1,1
+H1,$04,$03,$01,h1,1,1
+S1,$04,$09,$01,s1,1,1
+D1,$04,$0a,$01,d1,1,1
+Q1,$04,$05,$01,q1,1,1
+B2,$04,$01,$02,b2,2,2
+H2,$04,$03,$02,h2,2,2
+S2,$04,$09,$02,s2,2,2
+D2,$04,$0a,$02,d2,2,2
+Q2,$04,$05,$02,q2,2,2
+B3,$04,$01,$03,b3,3,3
+H3,$04,$03,$03,h3,3,3
+S3,$04,$09,$03,s3,3,3
+D3,$04,$0a,$03,d3,3,3
+Q3,$04,$05,$03,q3,3,3
+B4,$04,$01,$04,b4,4,4
+H4,$04,$03,$04,h4,4,4
+S4,$04,$09,$04,s4,4,4
+D4,$04,$0a,$04,d4,4,4
+Q4,$04,$05,$04,q4,4,4
+B5,$04,$01,$05,b5,5,5
+H5,$04,$03,$05,h5,5,5
+S5,$04,$09,$05,s5,5,5
+D5,$04,$0a,$05,d5,5,5
+Q5,$04,$05,$05,q5,5,5
+B6,$04,$01,$06,b6,6,6
+H6,$04,$03,$06,h6,6,6
+S6,$04,$09,$06,s6,6,6
+D6,$04,$0a,$06,d6,6,6
+Q6,$04,$05,$06,q6,6,6
+B7,$04,$01,$07,b7,7,7
+H7,$04,$03,$07,h7,7,7
+S7,$04,$09,$07,s7,7,7
+D7,$04,$0a,$07,d7,7,7
+Q7,$04,$05,$07,q7,7,7
+B8,$04,$01,$08,b8,8,8
+H8,$04,$03,$08,h8,8,8
+S8,$04,$09,$08,s8,8,8
+D8,$04,$0a,$08,d8,8,8
+Q8,$04,$05,$08,q8,8,8
+B9,$04,$01,$09,b9,9,9
+H9,$04,$03,$09,h9,9,9
+S9,$04,$09,$09,s9,9,9
+D9,$04,$0a,$09,d9,9,9
+Q9,$04,$05,$09,q9,9,9
+B10,$04,$01,$0A,b10,10,10
+H10,$04,$03,$0A,h10,10,10
+S10,$04,$09,$0A,s10,10,10
+D10,$04,$0a,$0A,d10,10,10
+Q10,$04,$05,$0A,q10,10,10
+B11,$04,$01,$0B,b11,11,11
+H11,$04,$03,$0B,h11,11,11
+S11,$04,$09,$0B,s11,11,11
+D11,$04,$0a,$0B,d11,11,11
+Q11,$04,$05,$0B,q11,11,11
+B12,$04,$01,$0C,b12,12,12
+H12,$04,$03,$0C,h12,12,12
+S12,$04,$09,$0C,s12,12,12
+D12,$04,$0a,$0C,d12,12,12
+Q12,$04,$05,$0C,q12,12,12
+B13,$04,$01,$0D,b13,13,13
+H13,$04,$03,$0D,h13,13,13
+S13,$04,$09,$0D,s13,13,13
+D13,$04,$0a,$0D,d13,13,13
+Q13,$04,$05,$0D,q13,13,13
+B14,$04,$01,$0E,b14,14,14
+H14,$04,$03,$0E,h14,14,14
+S14,$04,$09,$0E,s14,14,14
+D14,$04,$0a,$0E,d14,14,14
+Q14,$04,$05,$0E,q14,14,14
+B15,$04,$01,$0F,b15,15,15
+H15,$04,$03,$0F,h15,15,15
+S15,$04,$09,$0F,s15,15,15
+D15,$04,$0a,$0F,d15,15,15
+Q15,$04,$05,$0F,q15,15,15
+B16,$04,$01,$10,b16,16,16
+H16,$04,$03,$10,h16,16,16
+S16,$04,$09,$10,s16,16,16
+D16,$04,$0a,$10,d16,16,16
+Q16,$04,$05,$10,q16,16,16
+B17,$04,$01,$11,b17,17,17
+H17,$04,$03,$11,h17,17,17
+S17,$04,$09,$11,s17,17,17
+D17,$04,$0a,$11,d17,17,17
+Q17,$04,$05,$11,q17,17,17
+B18,$04,$01,$12,b18,18,18
+H18,$04,$03,$12,h18,18,18
+S18,$04,$09,$12,s18,18,18
+D18,$04,$0a,$12,d18,18,18
+Q18,$04,$05,$12,q18,18,18
+B19,$04,$01,$13,b19,19,19
+H19,$04,$03,$13,h19,19,19
+S19,$04,$09,$13,s19,19,19
+D19,$04,$0a,$13,d19,19,19
+Q19,$04,$05,$13,q19,19,19
+B20,$04,$01,$14,b20,20,20
+H20,$04,$03,$14,h20,20,20
+S20,$04,$09,$14,s20,20,20
+D20,$04,$0a,$14,d20,20,20
+Q20,$04,$05,$14,q20,20,20
+B21,$04,$01,$15,b21,21,21
+H21,$04,$03,$15,h21,21,21
+S21,$04,$09,$15,s21,21,21
+D21,$04,$0a,$15,d21,21,21
+Q21,$04,$05,$15,q21,21,21
+B22,$04,$01,$16,b22,22,22
+H22,$04,$03,$16,h22,22,22
+S22,$04,$09,$16,s22,22,22
+D22,$04,$0a,$16,d22,22,22
+Q22,$04,$05,$16,q22,22,22
+B23,$04,$01,$17,b23,23,23
+H23,$04,$03,$17,h23,23,23
+S23,$04,$09,$17,s23,23,23
+D23,$04,$0a,$17,d23,23,23
+Q23,$04,$05,$17,q23,23,23
+B24,$04,$01,$18,b24,24,24
+H24,$04,$03,$18,h24,24,24
+S24,$04,$09,$18,s24,24,24
+D24,$04,$0a,$18,d24,24,24
+Q24,$04,$05,$18,q24,24,24
+B25,$04,$01,$19,b25,25,25
+H25,$04,$03,$19,h25,25,25
+S25,$04,$09,$19,s25,25,25
+D25,$04,$0a,$19,d25,25,25
+Q25,$04,$05,$19,q25,25,25
+B26,$04,$01,$1A,b26,26,26
+H26,$04,$03,$1A,h26,26,26
+S26,$04,$09,$1A,s26,26,26
+D26,$04,$0a,$1A,d26,26,26
+Q26,$04,$05,$1A,q26,26,26
+B27,$04,$01,$1B,b27,27,27
+H27,$04,$03,$1B,h27,27,27
+S27,$04,$09,$1B,s27,27,27
+D27,$04,$0a,$1B,d27,27,27
+Q27,$04,$05,$1B,q27,27,27
+B28,$04,$01,$1C,b28,28,28
+H28,$04,$03,$1C,h28,28,28
+S28,$04,$09,$1C,s28,28,28
+D28,$04,$0a,$1C,d28,28,28
+Q28,$04,$05,$1C,q28,28,28
+B29,$04,$01,$1D,b29,29,29
+H29,$04,$03,$1D,h29,29,29
+S29,$04,$09,$1D,s29,29,29
+D29,$04,$0a,$1D,d29,29,29
+Q29,$04,$05,$1D,q29,29,29
+B30,$04,$01,$1E,b30,30,30
+H30,$04,$03,$1E,h30,30,30
+S30,$04,$09,$1E,s30,30,30
+D30,$04,$0a,$1E,d30,30,30
+Q30,$04,$05,$1E,q30,30,30
+B31,$04,$01,$1F,b31,31,31
+H31,$04,$03,$1F,h31,31,31
+S31,$04,$09,$1F,s31,31,31
+D31,$04,$0a,$1F,d31,31,31
+Q31,$04,$05,$1F,q31,31,31
+
+NZCV,$05,$00,$00,nzcv,0,0
+

+ 4 - 0
compiler/aarch64/a64tab.inc

@@ -0,0 +1,4 @@
+{ don't edit, this file is generated from armins.dat }
+(
+
+);

+ 2178 - 0
compiler/aarch64/aasmcpu.pas

@@ -0,0 +1,2178 @@
+{
+    Copyright (c) 2003-2012 by Florian Klaempfl and others
+
+    Contains the assembler object for ARM64
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit aasmcpu;
+
+{$i fpcdefs.inc}
+
+interface
+
+uses
+  cclasses,globtype,globals,verbose,
+  aasmbase,aasmtai,aasmdata,aasmsym,
+  ogbase,
+  symtype,
+  cpubase,cpuinfo,cgbase,cgutils;
+
+    const
+      { "mov reg,reg" source operand number }
+      O_MOV_SOURCE = 1;
+      { "mov reg,reg" source operand number }
+      O_MOV_DEST = 0;
+
+      { Operand types }
+      OT_NONE      = $00000000;
+
+      OT_BITS8     = $00000001;  { size, and other attributes, of the operand  }
+      OT_BITS16    = $00000002;
+      OT_BITS32    = $00000004;
+      OT_BITS64    = $00000008;  { FPU only  }
+      OT_BITS80    = $00000010;
+      OT_FAR       = $00000020;  { this means 16:16 or 16:32, like in CALL/JMP }
+      OT_NEAR      = $00000040;
+      OT_SHORT     = $00000080;
+      OT_BITSTINY  = $00000100;  { fpu constant }
+      OT_BITSSHIFTER =
+                     $00000200;
+
+      OT_SIZE_MASK = $000003FF;  { all the size attributes  }
+      OT_NON_SIZE  = longint(not OT_SIZE_MASK);
+
+      OT_SIGNED    = $00000100;  { the operand need to be signed -128-127 }
+
+      OT_TO        = $00000200;  { operand is followed by a colon  }
+                                 { reverse effect in FADD, FSUB &c  }
+      OT_COLON     = $00000400;
+
+      OT_SHIFTEROP = $00000800;
+      OT_REGISTER  = $00001000;
+      OT_IMMEDIATE = $00002000;
+      OT_REGLIST   = $00008000;
+      OT_IMM8      = $00002001;
+      OT_IMM24     = $00002002;
+      OT_IMM32     = $00002004;
+      OT_IMM64     = $00002008;
+      OT_IMM80     = $00002010;
+      OT_IMMTINY   = $00002100;
+      OT_IMMSHIFTER= $00002200;
+      OT_IMMEDIATE24 = OT_IMM24;
+      OT_SHIFTIMM  = OT_SHIFTEROP or OT_IMMSHIFTER;
+      OT_SHIFTIMMEDIATE = OT_SHIFTIMM;
+      OT_IMMEDIATESHIFTER = OT_IMMSHIFTER;
+
+      OT_IMMEDIATEFPU = OT_IMMTINY;
+
+      OT_REGMEM    = $00200000;  { for r/m, ie EA, operands  }
+      OT_REGNORM   = $00201000;  { 'normal' reg, qualifies as EA  }
+      OT_REG8      = $00201001;
+      OT_REG16     = $00201002;
+      OT_REG32     = $00201004;
+      OT_REG64     = $00201008;
+      OT_VREG      = $00201010;  { vector register }
+      OT_REGF      = $00201020;  { coproc register }
+      OT_MEMORY    = $00204000;  { register number in 'basereg'  }
+      OT_MEM8      = $00204001;
+      OT_MEM16     = $00204002;
+      OT_MEM32     = $00204004;
+      OT_MEM64     = $00204008;
+      OT_MEM80     = $00204010;
+      { word/byte load/store }
+      OT_AM2       = $00010000;
+      { misc ld/st operations }
+      OT_AM3       = $00020000;
+      { multiple ld/st operations }
+      OT_AM4       = $00040000;
+      { co proc. ld/st operations }
+      OT_AM5       = $00080000;
+      OT_AMMASK    = $000f0000;
+      { IT instruction }
+      OT_CONDITION = $00100000;
+
+      OT_MEMORYAM2 = OT_MEMORY or OT_AM2;
+      OT_MEMORYAM3 = OT_MEMORY or OT_AM3;
+      OT_MEMORYAM4 = OT_MEMORY or OT_AM4;
+      OT_MEMORYAM5 = OT_MEMORY or OT_AM5;
+
+      OT_FPUREG    = $01000000;  { floating point stack registers  }
+      OT_REG_SMASK = $00070000;  { special register operands: these may be treated differently  }
+                                 { a mask for the following  }
+
+      OT_MEM_OFFS  = $00604000;  { special type of EA  }
+                                 { simple [address] offset  }
+      OT_ONENESS   = $00800000;  { special type of immediate operand  }
+                                 { so UNITY == IMMEDIATE | ONENESS  }
+      OT_UNITY     = $00802000;  { for shift/rotate instructions  }
+
+      instabentries = {$i a64nop.inc}
+
+      maxinfolen = 5;
+
+      IF_NONE   = $00000000;
+
+      IF_ARMMASK    = $000F0000;
+      IF_ARM7       = $00070000;
+      IF_FPMASK     = $00F00000;
+      IF_FPA        = $00100000;
+
+      { if the instruction can change in a second pass }
+      IF_PASS2  = longint($80000000);
+
+    type
+      TInsTabCache=array[TasmOp] of longint;
+      PInsTabCache=^TInsTabCache;
+
+      tinsentry = record
+        opcode  : tasmop;
+        ops     : byte;
+        optypes : array[0..3] of longint;
+        code    : array[0..maxinfolen] of char;
+        flags   : longint;
+      end;
+
+      pinsentry=^tinsentry;
+
+{    const
+      InsTab : array[0..instabentries-1] of TInsEntry={$i a64tab.inc} }
+
+    var
+      InsTabCache : PInsTabCache;
+
+    type
+      taicpu = class(tai_cpu_abstract_sym)
+         oppostfix : TOpPostfix;
+         procedure loadshifterop(opidx:longint;const so:tshifterop);
+         constructor op_none(op : tasmop);
+
+         constructor op_reg(op : tasmop;_op1 : tregister);
+         constructor op_ref(op : tasmop;const _op1 : treference);
+         constructor op_const(op : tasmop;_op1 : longint);
+
+         constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
+         constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
+         constructor op_reg_const(op:tasmop; _op1: tregister; _op2: aint);
+
+         constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
+         constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
+         constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
+         constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
+         constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
+         constructor op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop);
+         constructor op_reg_reg_reg_shifterop(op : tasmop;_op1,_op2,_op3 : tregister;_op4 : tshifterop);
+
+         { this is for Jmp instructions }
+         constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
+
+         constructor op_sym(op : tasmop;_op1 : tasmsymbol);
+         constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
+         constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
+         constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
+
+         function is_same_reg_move(regtype: Tregistertype):boolean; override;
+
+         function spilling_get_operation_type(opnr: longint): topertype;override;
+
+         { assembler }
+      public
+         { the next will reset all instructions that can change in pass 2 }
+         procedure ResetPass1;override;
+         procedure ResetPass2;override;
+         function  CheckIfValid:boolean;
+         function GetString:string;
+         function  Pass1(objdata:TObjData):longint;override;
+         procedure Pass2(objdata:TObjData);override;
+      protected
+         procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);override;
+         procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);override;
+         procedure ppubuildderefimploper(var o:toper);override;
+         procedure ppuderefoper(var o:toper);override;
+      private
+         { next fields are filled in pass1, so pass2 is faster }
+         inssize   : shortint;
+         insoffset : longint;
+         LastInsOffset : longint; { need to be public to be reset }
+         insentry  : PInsEntry;
+         function  InsEnd:longint;
+         procedure create_ot(objdata:TObjData);
+         function  Matches(p:PInsEntry):longint;
+         function  calcsize(p:PInsEntry):shortint;
+         procedure gencode(objdata:TObjData);
+         function  NeedAddrPrefix(opidx:byte):boolean;
+         procedure Swapoperands;
+         function  FindInsentry(objdata:TObjData):boolean;
+      end;
+
+      tai_align = class(tai_align_abstract)
+        { nothing to add }
+      end;
+
+    function spilling_create_load(const ref:treference;r:tregister):Taicpu;
+    function spilling_create_store(r:tregister; const ref:treference):Taicpu;
+
+    function setoppostfix(i : taicpu;pf : toppostfix) : taicpu;
+    function setcondition(i : taicpu;c : tasmcond) : taicpu;
+
+    { inserts pc relative symbols at places where they are reachable
+      and transforms special instructions to valid instruction encodings }
+    procedure finalizearmcode(list,listtoinsert : TAsmList);
+    { inserts .pdata section and dummy function prolog needed for arm-wince exception handling }
+    procedure InsertPData;
+
+    procedure InitAsm;
+    procedure DoneAsm;
+
+
+implementation
+
+  uses
+    cutils,rgobj,itcpugas,aoptcpu;
+
+
+    procedure taicpu.loadshifterop(opidx:longint;const so:tshifterop);
+      begin
+        allocate_oper(opidx+1);
+        with oper[opidx]^ do
+          begin
+            if typ<>top_shifterop then
+              begin
+                clearop(opidx);
+                new(shifterop);
+              end;
+            shifterop^:=so;
+            typ:=top_shifterop;
+          end;
+      end;
+
+
+{*****************************************************************************
+                                 taicpu Constructors
+*****************************************************************************}
+
+    constructor taicpu.op_none(op : tasmop);
+      begin
+         inherited create(op);
+      end;
+
+
+    { for pld }
+    constructor taicpu.op_ref(op : tasmop;const _op1 : treference);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadref(0,_op1);
+      end;
+
+
+    constructor taicpu.op_reg(op : tasmop;_op1 : tregister);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadreg(0,_op1);
+      end;
+
+
+    constructor taicpu.op_const(op : tasmop;_op1 : longint);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadconst(0,aint(_op1));
+      end;
+
+
+    constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
+      begin
+         inherited create(op);
+         ops:=2;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+      end;
+
+
+    constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: aint);
+      begin
+         inherited create(op);
+         ops:=2;
+         loadreg(0,_op1);
+         loadconst(1,aint(_op2));
+      end;
+
+
+    constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
+      begin
+         inherited create(op);
+         ops:=2;
+         loadreg(0,_op1);
+         loadref(1,_op2);
+      end;
+
+
+    constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
+      begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadreg(2,_op3);
+      end;
+
+
+    constructor taicpu.op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
+      begin
+         inherited create(op);
+         ops:=4;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadreg(2,_op3);
+         loadreg(3,_op4);
+      end;
+
+
+     constructor taicpu.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
+       begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadconst(2,aint(_op3));
+      end;
+
+
+     constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
+       begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadsymbol(0,_op3,_op3ofs);
+      end;
+
+
+     constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
+       begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadref(2,_op3);
+      end;
+
+
+     constructor taicpu.op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop);
+      begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadshifterop(2,_op3);
+      end;
+
+
+     constructor taicpu.op_reg_reg_reg_shifterop(op : tasmop;_op1,_op2,_op3 : tregister;_op4 : tshifterop);
+      begin
+         inherited create(op);
+         ops:=4;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadreg(2,_op3);
+         loadshifterop(3,_op4);
+      end;
+
+
+    constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
+      begin
+         inherited create(op);
+         condition:=cond;
+         ops:=1;
+         loadsymbol(0,_op1,0);
+      end;
+
+
+    constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadsymbol(0,_op1,0);
+      end;
+
+
+    constructor taicpu.op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadsymbol(0,_op1,_op1ofs);
+      end;
+
+
+     constructor taicpu.op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
+      begin
+         inherited create(op);
+         ops:=2;
+         loadreg(0,_op1);
+         loadsymbol(1,_op2,_op2ofs);
+      end;
+
+
+    constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
+      begin
+         inherited create(op);
+         ops:=2;
+         loadsymbol(0,_op1,_op1ofs);
+         loadref(1,_op2);
+      end;
+
+
+    function taicpu.is_same_reg_move(regtype: Tregistertype):boolean;
+      begin
+        { allow the register allocator to remove unnecessary moves }
+        result:=(
+                  ((opcode=A_MOV) and (regtype = R_INTREGISTER)) or
+                  ((opcode=A_FMOV) and (regtype = R_MMREGISTER))
+                ) and
+                (oppostfix in [PF_None]) and
+                (condition=C_None) and
+                (ops=2) and
+                (oper[0]^.typ=top_reg) and
+                (oper[1]^.typ=top_reg) and
+                (oper[0]^.reg=oper[1]^.reg);
+      end;
+
+
+    function spilling_create_load(const ref:treference;r:tregister):Taicpu;
+      var
+        op: tasmop;
+      begin
+        case getregtype(r) of
+          R_INTREGISTER :
+            result:=taicpu.op_reg_ref(A_LDR,r,ref);
+          R_MMREGISTER :
+            begin
+              case getsubreg(r) of
+                R_SUBFD:
+                  op:=A_LDR;
+                R_SUBFS:
+                  op:=A_LDR;
+                else
+                  internalerror(2009112905);
+              end;
+              result:=taicpu.op_reg_ref(op,r,ref);
+            end;
+          else
+            internalerror(200401041);
+        end;
+      end;
+
+
+    function spilling_create_store(r:tregister; const ref:treference):Taicpu;
+      var
+        op: tasmop;
+      begin
+        case getregtype(r) of
+          R_INTREGISTER :
+            result:=taicpu.op_reg_ref(A_STR,r,ref);
+          R_MMREGISTER :
+            begin
+              case getsubreg(r) of
+                R_SUBFD:
+                  op:=A_STR;
+                R_SUBFS:
+                  op:=A_STR;
+                else
+                  internalerror(2009112904);
+              end;
+              result:=taicpu.op_reg_ref(op,r,ref);
+            end;
+          else
+            internalerror(200401041);
+        end;
+      end;
+
+
+    function taicpu.spilling_get_operation_type(opnr: longint): topertype;
+      begin
+        case opcode of
+          A_ADC,A_ADD,A_AND,A_BIC,
+          A_EOR,A_CLZ,A_RBIT,
+          A_LDR,
+          A_MOV,A_MVN,A_MUL,
+          A_ORR,A_SBC,A_SUB,
+          A_UXT,A_SXT:
+            if opnr=0 then
+              result:=operand_write
+            else
+              result:=operand_read;
+          A_B,A_BL,
+          A_CMN,A_CMP,A_TST:
+            result:=operand_read;
+          A_STR:
+            { important is what happens with the involved registers }
+            if opnr=0 then
+              result := operand_read
+            else
+              { check for pre/post indexed }
+              result := operand_read;
+          else
+            internalerror(200403151);
+        end;
+      end;
+
+
+    procedure BuildInsTabCache;
+      var
+        i : longint;
+      begin
+(*        new(instabcache);
+        FillChar(instabcache^,sizeof(tinstabcache),$ff);
+        i:=0;
+        while (i<InsTabEntries) do
+          begin
+            if InsTabCache^[InsTab[i].Opcode]=-1 then
+              InsTabCache^[InsTab[i].Opcode]:=i;
+            inc(i);
+          end; *)
+      end;
+
+
+    procedure InitAsm;
+      begin
+        if not assigned(instabcache) then
+          BuildInsTabCache;
+      end;
+
+
+    procedure DoneAsm;
+      begin
+        if assigned(instabcache) then
+          begin
+            dispose(instabcache);
+            instabcache:=nil;
+          end;
+      end;
+
+
+    function setoppostfix(i : taicpu;pf : toppostfix) : taicpu;
+      begin
+        i.oppostfix:=pf;
+        result:=i;
+      end;
+
+
+    function setcondition(i : taicpu;c : tasmcond) : taicpu;
+      begin
+        i.condition:=c;
+        result:=i;
+      end;
+
+
+    Function SimpleGetNextInstruction(Current: tai; Var Next: tai): Boolean;
+      Begin
+        Current:=tai(Current.Next);
+        While Assigned(Current) And (Current.typ In SkipInstr) Do
+          Current:=tai(Current.Next);
+        Next:=Current;
+        If Assigned(Next) And Not(Next.typ In SkipInstr) Then
+           Result:=True
+          Else
+            Begin
+              Next:=Nil;
+              Result:=False;
+            End;
+      End;
+
+
+(*
+    function armconstequal(hp1,hp2: tai): boolean;
+      begin
+        result:=false;
+        if hp1.typ<>hp2.typ then
+          exit;
+        case hp1.typ of
+          tai_const:
+            result:=
+              (tai_const(hp2).sym=tai_const(hp).sym) and
+              (tai_const(hp2).value=tai_const(hp).value) and
+              (tai(hp2.previous).typ=ait_label);
+            tai_const:
+              result:=
+                (tai_const(hp2).sym=tai_const(hp).sym) and
+                (tai_const(hp2).value=tai_const(hp).value) and
+                (tai(hp2.previous).typ=ait_label);
+        end;
+      end;
+*)
+
+    procedure insertpcrelativedata(list,listtoinsert : TAsmList);
+      var
+        curinspos,
+        penalty,
+        lastinspos,
+        { increased for every data element > 4 bytes inserted }
+        currentsize,
+        extradataoffset,
+        limit: longint;
+        curop : longint;
+        curtai : tai;
+        curdatatai,hp,hp2 : tai;
+        curdata : TAsmList;
+        l : tasmlabel;
+        doinsert,
+        removeref : boolean;
+      begin
+(*
+        curdata:=TAsmList.create;
+        lastinspos:=-1;
+        curinspos:=0;
+        extradataoffset:=0;
+        limit:=1016;
+        curtai:=tai(list.first);
+        doinsert:=false;
+        while assigned(curtai) do
+          begin
+            { instruction? }
+            case curtai.typ of
+              ait_instruction:
+                begin
+                  { walk through all operand of the instruction }
+                  for curop:=0 to taicpu(curtai).ops-1 do
+                    begin
+                      { reference? }
+                      if (taicpu(curtai).oper[curop]^.typ=top_ref) then
+                        begin
+                          { pc relative symbol? }
+                          curdatatai:=tai(taicpu(curtai).oper[curop]^.ref^.symboldata);
+                          if assigned(curdatatai) and
+                            { move only if we're at the first reference of a label }
+                            not(tai_label(curdatatai).moved) then
+                            begin
+                              tai_label(curdatatai).moved:=true;
+                              { check if symbol already used. }
+                              { if yes, reuse the symbol }
+                              hp:=tai(curdatatai.next);
+                              removeref:=false;
+                              if assigned(hp) then
+                                begin
+                                  case hp.typ of
+                                    ait_const:
+                                      begin
+                                        if (tai_const(hp).consttype=aitconst_64bit) then
+                                          inc(extradataoffset);
+                                      end;
+                                    ait_comp_64bit,
+                                    ait_real_64bit:
+                                      begin
+                                        inc(extradataoffset);
+                                      end;
+                                    ait_real_80bit:
+                                      begin
+                                        inc(extradataoffset,2);
+                                      end;
+                                  end;
+                                  if (hp.typ=ait_const) then
+                                    begin
+                                      hp2:=tai(curdata.first);
+                                      while assigned(hp2) do
+                                        begin
+    {                                      if armconstequal(hp2,hp) then }
+                                          if (hp2.typ=ait_const) and (tai_const(hp2).sym=tai_const(hp).sym)
+                                            and (tai_const(hp2).value=tai_const(hp).value) and (tai(hp2.previous).typ=ait_label)
+                                          then
+                                            begin
+                                              with taicpu(curtai).oper[curop]^.ref^ do
+                                                begin
+                                                  symboldata:=hp2.previous;
+                                                  symbol:=tai_label(hp2.previous).labsym;
+                                                end;
+                                              removeref:=true;
+                                              break;
+                                            end;
+                                          hp2:=tai(hp2.next);
+                                        end;
+                                    end;
+                                end;
+                              { move or remove symbol reference }
+                              repeat
+                                hp:=tai(curdatatai.next);
+                                listtoinsert.remove(curdatatai);
+                                if removeref then
+                                  curdatatai.free
+                                else
+                                  curdata.concat(curdatatai);
+                                curdatatai:=hp;
+                              until (curdatatai=nil) or (curdatatai.typ=ait_label);
+                              if lastinspos=-1 then
+                                lastinspos:=curinspos;
+                            end;
+                        end;
+                    end;
+                  inc(curinspos);
+                end;
+              ait_align:
+                begin
+                  { code is always 4 byte aligned, so we don't have to take care of .align 2 which would
+                    requires also incrementing curinspos by 1 }
+                  inc(curinspos,(tai_align(curtai).aligntype div 4));
+                end;
+              ait_const:
+                begin
+                  inc(curinspos);
+                  if (tai_const(curtai).consttype=aitconst_64bit) then
+                    inc(curinspos);
+                end;
+              ait_real_32bit:
+                begin
+                  inc(curinspos);
+                end;
+              ait_comp_64bit,
+              ait_real_64bit:
+                begin
+                  inc(curinspos,2);
+                end;
+              ait_real_80bit:
+                begin
+                  inc(curinspos,3);
+                end;
+            end;
+            { special case for case jump tables }
+            if SimpleGetNextInstruction(curtai,hp) and
+              (tai(hp).typ=ait_instruction) and
+              (taicpu(hp).opcode=A_LDR) and
+              (taicpu(hp).oper[0]^.typ=top_reg) and
+              (taicpu(hp).oper[0]^.reg=NR_PC) then
+              begin
+                penalty:=1;
+                hp:=tai(hp.next);
+                { skip register allocations and comments inserted by the optimizer }
+                while assigned(hp) and (hp.typ in [ait_comment,ait_regalloc]) do
+                  hp:=tai(hp.next);
+                while assigned(hp) and (hp.typ=ait_const) do
+                  begin
+                    inc(penalty);
+                    hp:=tai(hp.next);
+                  end;
+              end
+            else
+              penalty:=0;
+
+            { FLD/FST VFP instructions have a limit of +/- 1024, not 4096 }
+            if SimpleGetNextInstruction(curtai,hp) and
+               (tai(hp).typ=ait_instruction) and
+               ((taicpu(hp).opcode=A_FLDS) or
+                (taicpu(hp).opcode=A_FLDD)) then
+              limit:=254;
+
+            { don't miss an insert }
+            doinsert:=doinsert or
+              (not(curdata.empty) and
+               (curinspos-lastinspos+penalty+extradataoffset>limit));
+
+            { split only at real instructions else the test below fails }
+            if doinsert and (curtai.typ=ait_instruction) and
+              (
+                { don't split loads of pc to lr and the following move }
+                not(
+                    (taicpu(curtai).opcode=A_MOV) and
+                    (taicpu(curtai).oper[0]^.typ=top_reg) and
+                    (taicpu(curtai).oper[0]^.reg=NR_R14) and
+                    (taicpu(curtai).oper[1]^.typ=top_reg) and
+                    (taicpu(curtai).oper[1]^.reg=NR_PC)
+                   )
+              ) then
+              begin
+                lastinspos:=-1;
+                extradataoffset:=0;
+                limit:=1016;
+                doinsert:=false;
+                hp:=tai(curtai.next);
+                current_asmdata.getjumplabel(l);
+                curdata.insert(taicpu.op_sym(A_B,l));
+                curdata.concat(tai_label.create(l));
+                list.insertlistafter(curtai,curdata);
+                curtai:=hp;
+              end
+            else
+              curtai:=tai(curtai.next);
+          end;
+        list.concatlist(curdata);
+        curdata.free;
+*)
+      end;
+
+
+    procedure finalizearmcode(list, listtoinsert: TAsmList);
+      begin
+        insertpcrelativedata(list, listtoinsert);
+      end;
+
+    procedure InsertPData;
+      var
+        prolog: TAsmList;
+      begin
+        prolog:=TAsmList.create;
+        new_section(prolog,sec_code,'FPC_EH_PROLOG',sizeof(pint),secorder_begin);
+        prolog.concat(Tai_const.Createname('_ARM_ExceptionHandler', 0));
+        prolog.concat(Tai_const.Create_32bit(0));
+        prolog.concat(Tai_symbol.Createname_global('FPC_EH_CODE_START',AT_DATA,0));
+        { dummy function }
+        prolog.concat(taicpu.op_reg(A_BR,NR_X29));
+        current_asmdata.asmlists[al_start].insertList(prolog);
+        prolog.Free;
+        new_section(current_asmdata.asmlists[al_end],sec_pdata,'',sizeof(pint));
+        current_asmdata.asmlists[al_end].concat(Tai_const.Createname('FPC_EH_CODE_START', 0));
+        current_asmdata.asmlists[al_end].concat(Tai_const.Create_32bit(longint($ffffff01)));
+      end;
+
+(*
+      Floating point instruction format information, taken from the linux kernel
+      ARM Floating Point Instruction Classes
+      | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+      |c o n d|1 1 0 P|U|u|W|L|   Rn  |v|  Fd |0|0|0|1|  o f f s e t  | CPDT
+      |c o n d|1 1 0 P|U|w|W|L|   Rn  |x|  Fd |0|0|1|0|  o f f s e t  | CPDT (copro 2)
+      | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+      |c o n d|1 1 1 0|a|b|c|d|e|  Fn |j|  Fd |0|0|0|1|f|g|h|0|i|  Fm | CPDO
+      |c o n d|1 1 1 0|a|b|c|L|e|  Fn |   Rd  |0|0|0|1|f|g|h|1|i|  Fm | CPRT
+      |c o n d|1 1 1 0|a|b|c|1|e|  Fn |1|1|1|1|0|0|0|1|f|g|h|1|i|  Fm | comparisons
+      | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+
+      CPDT            data transfer instructions
+                      LDF, STF, LFM (copro 2), SFM (copro 2)
+
+      CPDO            dyadic arithmetic instructions
+                      ADF, MUF, SUF, RSF, DVF, RDF,
+                      POW, RPW, RMF, FML, FDV, FRD, POL
+
+      CPDO            monadic arithmetic instructions
+                      MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
+                      SIN, COS, TAN, ASN, ACS, ATN, URD, NRM
+
+      CPRT            joint arithmetic/data transfer instructions
+                      FIX (arithmetic followed by load/store)
+                      FLT (load/store followed by arithmetic)
+                      CMF, CNF CMFE, CNFE (comparisons)
+                      WFS, RFS (write/read floating point status register)
+                      WFC, RFC (write/read floating point control register)
+
+      cond            condition codes
+      P               pre/post index bit: 0 = postindex, 1 = preindex
+      U               up/down bit: 0 = stack grows down, 1 = stack grows up
+      W               write back bit: 1 = update base register (Rn)
+      L               load/store bit: 0 = store, 1 = load
+      Rn              base register
+      Rd              destination/source register
+      Fd              floating point destination register
+      Fn              floating point source register
+      Fm              floating point source register or floating point constant
+
+      uv              transfer length (TABLE 1)
+      wx              register count (TABLE 2)
+      abcd            arithmetic opcode (TABLES 3 & 4)
+      ef              destination size (rounding precision) (TABLE 5)
+      gh              rounding mode (TABLE 6)
+      j               dyadic/monadic bit: 0 = dyadic, 1 = monadic
+      i               constant bit: 1 = constant (TABLE 6)
+      */
+
+      /*
+      TABLE 1
+      +-------------------------+---+---+---------+---------+
+      |  Precision              | u | v | FPSR.EP | length  |
+      +-------------------------+---+---+---------+---------+
+      | Single                  | 0 | 0 |    x    | 1 words |
+      | Double                  | 1 | 1 |    x    | 2 words |
+      | Extended                | 1 | 1 |    x    | 3 words |
+      | Packed decimal          | 1 | 1 |    0    | 3 words |
+      | Expanded packed decimal | 1 | 1 |    1    | 4 words |
+      +-------------------------+---+---+---------+---------+
+      Note: x = don't care
+      */
+
+      /*
+      TABLE 2
+      +---+---+---------------------------------+
+      | w | x | Number of registers to transfer |
+      +---+---+---------------------------------+
+      | 0 | 1 |  1                              |
+      | 1 | 0 |  2                              |
+      | 1 | 1 |  3                              |
+      | 0 | 0 |  4                              |
+      +---+---+---------------------------------+
+      */
+
+      /*
+      TABLE 3: Dyadic Floating Point Opcodes
+      +---+---+---+---+----------+-----------------------+-----------------------+
+      | a | b | c | d | Mnemonic | Description           | Operation             |
+      +---+---+---+---+----------+-----------------------+-----------------------+
+      | 0 | 0 | 0 | 0 | ADF      | Add                   | Fd := Fn + Fm         |
+      | 0 | 0 | 0 | 1 | MUF      | Multiply              | Fd := Fn * Fm         |
+      | 0 | 0 | 1 | 0 | SUF      | Subtract              | Fd := Fn - Fm         |
+      | 0 | 0 | 1 | 1 | RSF      | Reverse subtract      | Fd := Fm - Fn         |
+      | 0 | 1 | 0 | 0 | DVF      | Divide                | Fd := Fn / Fm         |
+      | 0 | 1 | 0 | 1 | RDF      | Reverse divide        | Fd := Fm / Fn         |
+      | 0 | 1 | 1 | 0 | POW      | Power                 | Fd := Fn ^ Fm         |
+      | 0 | 1 | 1 | 1 | RPW      | Reverse power         | Fd := Fm ^ Fn         |
+      | 1 | 0 | 0 | 0 | RMF      | Remainder             | Fd := IEEE rem(Fn/Fm) |
+      | 1 | 0 | 0 | 1 | FML      | Fast Multiply         | Fd := Fn * Fm         |
+      | 1 | 0 | 1 | 0 | FDV      | Fast Divide           | Fd := Fn / Fm         |
+      | 1 | 0 | 1 | 1 | FRD      | Fast reverse divide   | Fd := Fm / Fn         |
+      | 1 | 1 | 0 | 0 | POL      | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm)  |
+      | 1 | 1 | 0 | 1 |          | undefined instruction | trap                  |
+      | 1 | 1 | 1 | 0 |          | undefined instruction | trap                  |
+      | 1 | 1 | 1 | 1 |          | undefined instruction | trap                  |
+      +---+---+---+---+----------+-----------------------+-----------------------+
+      Note: POW, RPW, POL are deprecated, and are available for backwards
+            compatibility only.
+      */
+
+      /*
+      TABLE 4: Monadic Floating Point Opcodes
+      +---+---+---+---+----------+-----------------------+-----------------------+
+      | a | b | c | d | Mnemonic | Description           | Operation             |
+      +---+---+---+---+----------+-----------------------+-----------------------+
+      | 0 | 0 | 0 | 0 | MVF      | Move                  | Fd := Fm              |
+      | 0 | 0 | 0 | 1 | MNF      | Move negated          | Fd := - Fm            |
+      | 0 | 0 | 1 | 0 | ABS      | Absolute value        | Fd := abs(Fm)         |
+      | 0 | 0 | 1 | 1 | RND      | Round to integer      | Fd := int(Fm)         |
+      | 0 | 1 | 0 | 0 | SQT      | Square root           | Fd := sqrt(Fm)        |
+      | 0 | 1 | 0 | 1 | LOG      | Log base 10           | Fd := log10(Fm)       |
+      | 0 | 1 | 1 | 0 | LGN      | Log base e            | Fd := ln(Fm)          |
+      | 0 | 1 | 1 | 1 | EXP      | Exponent              | Fd := e ^ Fm          |
+      | 1 | 0 | 0 | 0 | SIN      | Sine                  | Fd := sin(Fm)         |
+      | 1 | 0 | 0 | 1 | COS      | Cosine                | Fd := cos(Fm)         |
+      | 1 | 0 | 1 | 0 | TAN      | Tangent               | Fd := tan(Fm)         |
+      | 1 | 0 | 1 | 1 | ASN      | Arc Sine              | Fd := arcsin(Fm)      |
+      | 1 | 1 | 0 | 0 | ACS      | Arc Cosine            | Fd := arccos(Fm)      |
+      | 1 | 1 | 0 | 1 | ATN      | Arc Tangent           | Fd := arctan(Fm)      |
+      | 1 | 1 | 1 | 0 | URD      | Unnormalized round    | Fd := int(Fm)         |
+      | 1 | 1 | 1 | 1 | NRM      | Normalize             | Fd := norm(Fm)        |
+      +---+---+---+---+----------+-----------------------+-----------------------+
+      Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are
+            available for backwards compatibility only.
+      */
+
+      /*
+      TABLE 5
+      +-------------------------+---+---+
+      |  Rounding Precision     | e | f |
+      +-------------------------+---+---+
+      | IEEE Single precision   | 0 | 0 |
+      | IEEE Double precision   | 0 | 1 |
+      | IEEE Extended precision | 1 | 0 |
+      | undefined (trap)        | 1 | 1 |
+      +-------------------------+---+---+
+      */
+
+      /*
+      TABLE 5
+      +---------------------------------+---+---+
+      |  Rounding Mode                  | g | h |
+      +---------------------------------+---+---+
+      | Round to nearest (default)      | 0 | 0 |
+      | Round toward plus infinity      | 0 | 1 |
+      | Round toward negative infinity  | 1 | 0 |
+      | Round toward zero               | 1 | 1 |
+      +---------------------------------+---+---+
+*)
+    function taicpu.GetString:string;
+      var
+        i : longint;
+        s : string;
+        addsize : boolean;
+      begin
+        s:='['+gas_op2str[opcode];
+        for i:=0 to ops-1 do
+         begin
+           with oper[i]^ do
+             begin
+               if i=0 then
+                s:=s+' '
+               else
+                s:=s+',';
+               { type }
+               addsize:=false;
+               if (ot and OT_VREG)=OT_VREG then
+                s:=s+'vreg'
+               else
+                 if (ot and OT_FPUREG)=OT_FPUREG then
+                  s:=s+'fpureg'
+               else
+                if (ot and OT_REGISTER)=OT_REGISTER then
+                 begin
+                   s:=s+'reg';
+                   addsize:=true;
+                 end
+               else
+                if (ot and OT_REGLIST)=OT_REGLIST then
+                 begin
+                   s:=s+'reglist';
+                   addsize:=false;
+                 end
+               else
+                if (ot and OT_IMMEDIATE)=OT_IMMEDIATE then
+                 begin
+                   s:=s+'imm';
+                   addsize:=true;
+                 end
+               else
+                if (ot and OT_MEMORY)=OT_MEMORY then
+                 begin
+                   s:=s+'mem';
+                   addsize:=true;
+                   if (ot and OT_AM2)<>0 then
+                     s:=s+' am2 ';
+                 end
+               else
+                 s:=s+'???';
+               { size }
+               if addsize then
+                begin
+                  if (ot and OT_BITS8)<>0 then
+                    s:=s+'8'
+                  else
+                   if (ot and OT_BITS16)<>0 then
+                    s:=s+'24'
+                  else
+                   if (ot and OT_BITS32)<>0 then
+                    s:=s+'32'
+                  else
+                   if (ot and OT_BITSSHIFTER)<>0 then
+                    s:=s+'shifter'
+                  else
+                    s:=s+'??';
+                  { signed }
+                  if (ot and OT_SIGNED)<>0 then
+                   s:=s+'s';
+                end;
+             end;
+         end;
+        GetString:=s+']';
+      end;
+
+
+    procedure taicpu.ResetPass1;
+      begin
+        { we need to reset everything here, because the choosen insentry
+          can be invalid for a new situation where the previously optimized
+          insentry is not correct }
+        InsEntry:=nil;
+        InsSize:=0;
+        LastInsOffset:=-1;
+      end;
+
+
+    procedure taicpu.ResetPass2;
+      begin
+        { we are here in a second pass, check if the instruction can be optimized }
+        if assigned(InsEntry) and
+           ((InsEntry^.flags and IF_PASS2)<>0) then
+         begin
+           InsEntry:=nil;
+           InsSize:=0;
+         end;
+        LastInsOffset:=-1;
+      end;
+
+
+    function taicpu.CheckIfValid:boolean;
+      begin
+        Result:=False; { unimplemented }
+      end;
+
+
+    function taicpu.Pass1(objdata:TObjData):longint;
+      begin
+        Pass1:=0;
+        LastInsOffset:=-1;
+      end;
+
+
+    procedure taicpu.Pass2(objdata:TObjData);
+      begin
+        { error in pass1 ? }
+        if insentry=nil then
+         exit;
+        current_filepos:=fileinfo;
+        { Generate the instruction }
+        GenCode(objdata);
+      end;
+
+
+    procedure taicpu.ppuloadoper(ppufile:tcompilerppufile;var o:toper);
+      begin
+      end;
+
+
+    procedure taicpu.ppuwriteoper(ppufile:tcompilerppufile;const o:toper);
+      begin
+      end;
+
+
+    procedure taicpu.ppubuildderefimploper(var o:toper);
+      begin
+      end;
+
+
+    procedure taicpu.ppuderefoper(var o:toper);
+      begin
+      end;
+
+
+    function  taicpu.InsEnd:longint;
+      begin
+        Result:=0; { unimplemented }
+      end;
+
+
+    procedure taicpu.create_ot(objdata:TObjData);
+      begin
+      end;
+
+
+    function taicpu.Matches(p:PInsEntry):longint;
+      begin
+      end;
+
+
+    function  taicpu.calcsize(p:PInsEntry):shortint;
+      begin
+        result:=4;
+      end;
+
+
+    function  taicpu.NeedAddrPrefix(opidx:byte):boolean;
+      begin
+        Result:=False; { unimplemented }
+      end;
+
+
+    procedure taicpu.Swapoperands;
+      begin
+      end;
+
+
+    function taicpu.FindInsentry(objdata:TObjData):boolean;
+      begin
+      end;
+
+
+    procedure taicpu.gencode(objdata:TObjData);
+      var
+        bytes : dword;
+        i_field : byte;
+
+      procedure setshifterop(op : byte);
+        begin
+          case oper[op]^.typ of
+            top_const:
+              begin
+                i_field:=1;
+                bytes:=bytes or dword(oper[op]^.val and $fff);
+              end;
+            top_reg:
+              begin
+                i_field:=0;
+                bytes:=bytes or (getsupreg(oper[op]^.reg) shl 16);
+
+                { does a real shifter op follow? }
+                if (op+1<=op) and (oper[op+1]^.typ=top_shifterop) then
+                  begin
+                  end;
+              end;
+          else
+            internalerror(2005091103);
+          end;
+        end;
+
+      begin
+        bytes:=$0;
+        { evaluate and set condition code }
+
+        { condition code allowed? }
+
+        { setup rest of the instruction }
+        case insentry^.code[0] of
+          #$08:
+            begin
+              { set instruction code }
+              bytes:=bytes or (ord(insentry^.code[1]) shl 26);
+              bytes:=bytes or (ord(insentry^.code[2]) shl 21);
+
+              { set destination }
+              bytes:=bytes or (getsupreg(oper[0]^.reg) shl 12);
+
+              { create shifter op }
+              setshifterop(1);
+
+              { set i field }
+              bytes:=bytes or (i_field shl 25);
+
+              { set s if necessary }
+              if oppostfix=PF_S then
+                bytes:=bytes or (1 shl 20);
+            end;
+          #$ff:
+            internalerror(2005091101);
+          else
+            internalerror(2005091102);
+        end;
+        { we're finished, write code }
+        objdata.writebytes(bytes,sizeof(bytes));
+      end;
+
+
+{$ifdef dummy}
+(*
+static void gencode (long segment, long offset, int bits,
+                     insn *ins, char *codes, long insn_end)
+{
+    int has_S_code;             /* S - setflag */
+    int has_B_code;             /* B - setflag */
+    int has_T_code;             /* T - setflag */
+    int has_W_code;             /* ! => W flag */
+    int has_F_code;             /* ^ => S flag */
+    int keep;
+    unsigned char c;
+    unsigned char bytes[4];
+    long          data, size;
+    static int cc_code[] =      /* bit pattern of cc */
+  {                             /* order as enum in  */
+    0x0E, 0x03, 0x02, 0x00,     /* nasm.h            */
+    0x0A, 0x0C, 0x08, 0x0D,
+    0x09, 0x0B, 0x04, 0x01,
+    0x05, 0x07, 0x06,
+  };
+
+
+#ifdef DEBUG
+static char *CC[] =
+  {                                    /* condition code names */
+    "AL", "CC", "CS", "EQ",
+    "GE", "GT", "HI", "LE",
+    "LS", "LT", "MI", "NE",
+    "PL", "VC", "VS", "",
+    "S"
+};
+
+
+    has_S_code = (ins->condition & C_SSETFLAG);
+    has_B_code = (ins->condition & C_BSETFLAG);
+    has_T_code = (ins->condition & C_TSETFLAG);
+    has_W_code = (ins->condition & C_EXSETFLAG);
+    has_F_code = (ins->condition & C_FSETFLAG);
+    ins->condition = (ins->condition & 0x0F);
+
+
+    if (rt_debug)
+      {
+    printf ("gencode: instruction: %s%s", insn_names[ins->opcode],
+            CC[ins->condition & 0x0F]);
+    if (has_S_code)
+      printf ("S");
+    if (has_B_code)
+      printf ("B");
+    if (has_T_code)
+      printf ("T");
+    if (has_W_code)
+      printf ("!");
+    if (has_F_code)
+      printf ("^");
+
+    printf ("\n");
+
+    c = *codes;
+
+    printf ("   (%d)  decode - '0x%02X'\n", ins->operands, c);
+
+
+    bytes[0] = 0xB;
+    bytes[1] = 0xE;
+    bytes[2] = 0xE;
+    bytes[3] = 0xF;
+      }
+
+    // First condition code in upper nibble
+    if (ins->condition < C_NONE)
+      {
+        c = cc_code[ins->condition] << 4;
+      }
+    else
+      {
+        c = cc_code[C_AL] << 4; // is often ALWAYS but not always
+      }
+
+
+    switch (keep = *codes)
+      {
+        case 1:
+          // B, BL
+          ++codes;
+          c |= *codes++;
+          bytes[0] = c;
+
+          if (ins->oprs[0].segment != segment)
+            {
+              // fais une relocation
+              c = 1;
+              data = 0; // Let the linker locate ??
+            }
+          else
+            {
+              c = 0;
+              data = ins->oprs[0].offset - (offset + 8);
+
+              if (data % 4)
+                {
+                  errfunc (ERR_NONFATAL, "offset not aligned on 4 bytes");
+                }
+            }
+
+          if (data >= 0x1000)
+            {
+              errfunc (ERR_NONFATAL, "too long offset");
+            }
+
+          data = data >> 2;
+          bytes[1] = (data >> 16) & 0xFF;
+          bytes[2] = (data >> 8)  & 0xFF;
+          bytes[3] = (data )      & 0xFF;
+
+          if (c == 1)
+            {
+//            out (offset, segment, &bytes[0], OUT_RAWDATA+1, NO_SEG, NO_SEG);
+              out (offset, segment, &bytes[0], OUT_REL3ADR+4, ins->oprs[0].segment, NO_SEG);
+            }
+          else
+            {
+              out (offset, segment, &bytes[0], OUT_RAWDATA+4, NO_SEG, NO_SEG);
+            }
+          return;
+
+        case 2:
+          // SWI
+          ++codes;
+          c |= *codes++;
+          bytes[0] = c;
+          data = ins->oprs[0].offset;
+          bytes[1] = (data >> 16) & 0xFF;
+          bytes[2] = (data >> 8) & 0xFF;
+          bytes[3] = (data) & 0xFF;
+          out (offset, segment, &bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+          return;
+        case 3:
+          // BX
+          ++codes;
+          c |= *codes++;
+          bytes[0] = c;
+          bytes[1] = *codes++;
+          bytes[2] = *codes++;
+          bytes[3] = *codes++;
+          c = regval (&ins->oprs[0],1);
+          if (c == 15)  // PC
+            {
+              errfunc (ERR_WARNING, "'BX' with R15 has undefined behaviour");
+            }
+          else if (c > 15)
+            {
+              errfunc (ERR_NONFATAL, "Illegal register specified for 'BX'");
+            }
+
+          bytes[3] |= (c & 0x0F);
+          out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+          return;
+
+        case 4:         // AND Rd,Rn,Rm
+        case 5:         // AND Rd,Rn,Rm,<shift>Rs
+        case 6:         // AND Rd,Rn,Rm,<shift>imm
+        case 7:         // AND Rd,Rn,<shift>imm
+          ++codes;
+#ifdef DEBUG
+          if (rt_debug)
+            {
+              printf ("         decode - '0x%02X'\n", keep);
+              printf ("           code - '0x%02X'\n", (unsigned char) ( *codes));
+            }
+#endif
+          bytes[0] = c | *codes;
+          ++codes;
+
+          bytes[1] = *codes;
+          if (has_S_code)
+            bytes[1] |= 0x10;
+          c = regval (&ins->oprs[1],1);
+          // Rn in low nibble
+          bytes[1] |= c;
+
+          // Rd in high nibble
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+
+          if (keep != 7)
+            {
+              // Rm in low nibble
+              bytes[3] = regval (&ins->oprs[2],1);
+            }
+
+          // Shifts if any
+          if (keep == 5 || keep == 6)
+            {
+              // Shift in bytes 2 and 3
+              if (keep == 5)
+                {
+                  // Rs
+                  c = regval (&ins->oprs[3],1);
+                  bytes[2] |= c;
+
+                  c = 0x10;             // Set bit 4 in byte[3]
+                }
+              if (keep == 6)
+                {
+                  c = (ins->oprs[3].offset) & 0x1F;
+
+                  // #imm
+                  bytes[2] |= c >> 1;
+                  if (c & 0x01)
+                    {
+                      bytes[3] |= 0x80;
+                    }
+                  c = 0;                // Clr bit 4 in byte[3]
+                }
+              // <shift>
+              c |= shiftval (&ins->oprs[3]) << 5;
+
+              bytes[3] |= c;
+            }
+
+          // reg,reg,imm
+          if (keep == 7)
+            {
+              int shimm;
+
+              shimm = imm_shift (ins->oprs[2].offset);
+
+              if (shimm == -1)
+                {
+                  errfunc (ERR_NONFATAL, "cannot create that constant");
+                }
+              bytes[3] = shimm & 0xFF;
+              bytes[2] |= (shimm & 0xF00) >> 8;
+            }
+
+          out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+          return;
+
+        case 8:         // MOV Rd,Rm
+        case 9:         // MOV Rd,Rm,<shift>Rs
+        case 0xA:       // MOV Rd,Rm,<shift>imm
+        case 0xB:       // MOV Rd,<shift>imm
+          ++codes;
+#ifdef DEBUG
+          if (rt_debug)
+            {
+              printf ("         decode - '0x%02X'\n", keep);
+              printf ("           code - '0x%02X'\n", (unsigned char) ( *codes));
+            }
+#endif
+          bytes[0] = c | *codes;
+          ++codes;
+
+          bytes[1] = *codes;
+          if (has_S_code)
+            bytes[1] |= 0x10;
+
+          // Rd in high nibble
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+
+          if (keep != 0x0B)
+            {
+              // Rm in low nibble
+              bytes[3] = regval (&ins->oprs[1],1);
+            }
+
+          // Shifts if any
+          if (keep == 0x09 || keep == 0x0A)
+            {
+              // Shift in bytes 2 and 3
+              if (keep == 0x09)
+                {
+                  // Rs
+                  c = regval (&ins->oprs[2],1);
+                  bytes[2] |= c;
+
+                  c = 0x10;             // Set bit 4 in byte[3]
+                }
+              if (keep == 0x0A)
+                {
+                  c = (ins->oprs[2].offset) & 0x1F;
+
+                  // #imm
+                  bytes[2] |= c >> 1;
+                  if (c & 0x01)
+                    {
+                      bytes[3] |= 0x80;
+                    }
+                  c = 0;                // Clr bit 4 in byte[3]
+                }
+              // <shift>
+              c |= shiftval (&ins->oprs[2]) << 5;
+
+              bytes[3] |= c;
+            }
+
+          // reg,imm
+          if (keep == 0x0B)
+            {
+              int shimm;
+
+              shimm = imm_shift (ins->oprs[1].offset);
+
+              if (shimm == -1)
+                {
+                  errfunc (ERR_NONFATAL, "cannot create that constant");
+                }
+              bytes[3] = shimm & 0xFF;
+              bytes[2] |= (shimm & 0xF00) >> 8;
+            }
+
+          out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+          return;
+
+
+        case 0xC:       // CMP Rn,Rm
+        case 0xD:       // CMP Rn,Rm,<shift>Rs
+        case 0xE:       // CMP Rn,Rm,<shift>imm
+        case 0xF:       // CMP Rn,<shift>imm
+          ++codes;
+
+          bytes[0] = c | *codes++;
+
+          bytes[1] = *codes;
+
+          // Implicit S code
+          bytes[1] |= 0x10;
+
+          c = regval (&ins->oprs[0],1);
+          // Rn in low nibble
+          bytes[1] |= c;
+
+          // No destination
+          bytes[2] = 0;
+
+          if (keep != 0x0B)
+            {
+              // Rm in low nibble
+              bytes[3] = regval (&ins->oprs[1],1);
+            }
+
+          // Shifts if any
+          if (keep == 0x0D || keep == 0x0E)
+            {
+              // Shift in bytes 2 and 3
+              if (keep == 0x0D)
+                {
+                  // Rs
+                  c = regval (&ins->oprs[2],1);
+                  bytes[2] |= c;
+
+                  c = 0x10;             // Set bit 4 in byte[3]
+                }
+              if (keep == 0x0E)
+                {
+                  c = (ins->oprs[2].offset) & 0x1F;
+
+                  // #imm
+                  bytes[2] |= c >> 1;
+                  if (c & 0x01)
+                    {
+                      bytes[3] |= 0x80;
+                    }
+                  c = 0;                // Clr bit 4 in byte[3]
+                }
+              // <shift>
+              c |= shiftval (&ins->oprs[2]) << 5;
+
+              bytes[3] |= c;
+            }
+
+          // reg,imm
+          if (keep == 0x0F)
+            {
+              int shimm;
+
+              shimm = imm_shift (ins->oprs[1].offset);
+
+              if (shimm == -1)
+                {
+                  errfunc (ERR_NONFATAL, "cannot create that constant");
+                }
+              bytes[3] = shimm & 0xFF;
+              bytes[2] |= (shimm & 0xF00) >> 8;
+            }
+
+          out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+          return;
+
+        case 0x10:      // MRS Rd,<psr>
+          ++codes;
+
+          bytes[0] = c | *codes++;
+
+          bytes[1] = *codes++;
+
+          // Rd
+          c = regval (&ins->oprs[0],1);
+
+          bytes[2] = c << 4;
+
+          bytes[3] = 0;
+
+          c = ins->oprs[1].basereg;
+
+          if (c == R_CPSR || c == R_SPSR)
+            {
+              if (c == R_SPSR)
+                {
+                  bytes[1] |= 0x40;
+                }
+            }
+          else
+            {
+              errfunc (ERR_NONFATAL, "CPSR or SPSR expected");
+            }
+
+          out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+
+          return;
+
+        case 0x11:      // MSR <psr>,Rm
+        case 0x12:      // MSR <psrf>,Rm
+        case 0x13:      // MSR <psrf>,#expression
+          ++codes;
+
+          bytes[0] = c | *codes++;
+
+          bytes[1] = *codes++;
+
+          bytes[2] = *codes;
+
+
+          if (keep == 0x11 || keep == 0x12)
+            {
+              // Rm
+              c = regval (&ins->oprs[1],1);
+
+              bytes[3] = c;
+            }
+          else
+            {
+              int shimm;
+
+              shimm = imm_shift (ins->oprs[1].offset);
+
+              if (shimm == -1)
+                {
+                  errfunc (ERR_NONFATAL, "cannot create that constant");
+                }
+              bytes[3] = shimm & 0xFF;
+              bytes[2] |= (shimm & 0xF00) >> 8;
+            }
+
+          c = ins->oprs[0].basereg;
+
+          if ( keep == 0x11)
+            {
+              if ( c == R_CPSR || c == R_SPSR)
+                {
+                if ( c== R_SPSR)
+                  {
+                    bytes[1] |= 0x40;
+                  }
+                }
+            else
+              {
+                errfunc (ERR_NONFATAL, "CPSR or SPSR expected");
+              }
+            }
+          else
+            {
+              if ( c == R_CPSR_FLG || c == R_SPSR_FLG)
+                {
+                  if ( c== R_SPSR_FLG)
+                    {
+                      bytes[1] |= 0x40;
+                    }
+                }
+              else
+                {
+                  errfunc (ERR_NONFATAL, "CPSR_flg or SPSR_flg expected");
+                }
+            }
+          break;
+
+        case 0x14:      // MUL  Rd,Rm,Rs
+        case 0x15:      // MULA Rd,Rm,Rs,Rn
+          ++codes;
+
+          bytes[0] = c | *codes++;
+
+          bytes[1] = *codes++;
+
+          bytes[3] = *codes;
+
+          // Rd
+          bytes[1] |= regval (&ins->oprs[0],1);
+          if (has_S_code)
+            bytes[1] |= 0x10;
+
+          // Rm
+          bytes[3] |= regval (&ins->oprs[1],1);
+
+          // Rs
+          bytes[2] = regval (&ins->oprs[2],1);
+
+          if (keep == 0x15)
+            {
+              bytes[2] |= regval (&ins->oprs[3],1) << 4;
+            }
+          break;
+
+        case 0x16:      // SMLAL RdHi,RdLo,Rm,Rs
+          ++codes;
+
+          bytes[0] = c | *codes++;
+
+          bytes[1] = *codes++;
+
+          bytes[3] = *codes;
+
+          // RdHi
+          bytes[1] |= regval (&ins->oprs[1],1);
+          if (has_S_code)
+            bytes[1] |= 0x10;
+
+          // RdLo
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+          // Rm
+          bytes[3] |= regval (&ins->oprs[2],1);
+
+          // Rs
+          bytes[2] |= regval (&ins->oprs[3],1);
+
+          break;
+
+        case 0x17:      // LDR Rd, expression
+          ++codes;
+
+          bytes[0] = c | *codes++;
+
+          bytes[1] = *codes++;
+
+          // Rd
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+          if (has_B_code)
+            bytes[1] |= 0x40;
+          if (has_T_code)
+            {
+              errfunc (ERR_NONFATAL, "'T' not allowed in pre-index mode");
+            }
+          if (has_W_code)
+            {
+              errfunc (ERR_NONFATAL, "'!' not allowed");
+            }
+
+          // Rn - implicit R15
+          bytes[1] |= 0xF;
+
+          if (ins->oprs[1].segment != segment)
+            {
+              errfunc (ERR_NONFATAL, "label not in same segment");
+            }
+
+          data = ins->oprs[1].offset - (offset + 8);
+
+          if (data < 0)
+            {
+              data = -data;
+            }
+          else
+            {
+              bytes[1] |= 0x80;
+            }
+
+          if (data >= 0x1000)
+            {
+              errfunc (ERR_NONFATAL, "too long offset");
+            }
+
+          bytes[2] |= ((data & 0xF00) >> 8);
+          bytes[3] = data & 0xFF;
+          break;
+
+        case 0x18:      // LDR Rd, [Rn]
+          ++codes;
+
+          bytes[0] = c | *codes++;
+
+          bytes[1] = *codes++;
+
+          // Rd
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+          if (has_B_code)
+            bytes[1] |= 0x40;
+          if (has_T_code)
+            {
+              bytes[1] |= 0x20;         // write-back
+            }
+          else
+            {
+              bytes[0] |= 0x01;         // implicit pre-index mode
+            }
+
+          if (has_W_code)
+            {
+              bytes[1] |= 0x20;         // write-back
+            }
+
+          // Rn
+          c = regval (&ins->oprs[1],1);
+          bytes[1] |= c;
+
+          if (c == 0x15)                // R15
+            data = -8;
+          else
+            data = 0;
+
+          if (data < 0)
+            {
+              data = -data;
+            }
+          else
+            {
+              bytes[1] |= 0x80;
+            }
+
+          bytes[2] |= ((data & 0xF00) >> 8);
+          bytes[3] = data & 0xFF;
+          break;
+
+        case 0x19:      // LDR Rd, [Rn,#expression]
+        case 0x20:      // LDR Rd, [Rn,Rm]
+        case 0x21:      // LDR Rd, [Rn,Rm,shift]
+          ++codes;
+
+          bytes[0] = c | *codes++;
+
+          bytes[1] = *codes++;
+
+          // Rd
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+          if (has_B_code)
+            bytes[1] |= 0x40;
+
+          // Rn
+          c = regval (&ins->oprs[1],1);
+          bytes[1] |= c;
+
+          if (ins->oprs[ins->operands-1].bracket)       // FIXME: Bracket on last operand -> pre-index  <--
+            {
+              bytes[0] |= 0x01;         // pre-index mode
+              if (has_W_code)
+                {
+                  bytes[1] |= 0x20;
+                }
+              if (has_T_code)
+                {
+                  errfunc (ERR_NONFATAL, "'T' not allowed in pre-index mode");
+                }
+            }
+          else
+            {
+              if (has_T_code)           // Forced write-back in post-index mode
+                {
+                  bytes[1] |= 0x20;
+                }
+              if (has_W_code)
+                {
+                  errfunc (ERR_NONFATAL, "'!' not allowed in post-index mode");
+                }
+            }
+
+          if (keep == 0x19)
+            {
+              data = ins->oprs[2].offset;
+
+              if (data < 0)
+                {
+                  data = -data;
+                }
+              else
+                {
+                  bytes[1] |= 0x80;
+                }
+
+              if (data >= 0x1000)
+                {
+                  errfunc (ERR_NONFATAL, "too long offset");
+                }
+
+              bytes[2] |= ((data & 0xF00) >> 8);
+              bytes[3] = data & 0xFF;
+            }
+          else
+            {
+              if (ins->oprs[2].minus == 0)
+                {
+                  bytes[1] |= 0x80;
+                }
+              c = regval (&ins->oprs[2],1);
+              bytes[3] = c;
+
+              if (keep == 0x21)
+                {
+                  c = ins->oprs[3].offset;
+                  if (c > 0x1F)
+                    {
+                      errfunc (ERR_NONFATAL, "too large shiftvalue");
+                      c = c & 0x1F;
+                    }
+
+                  bytes[2] |= c >> 1;
+                  if (c & 0x01)
+                    {
+                      bytes[3] |= 0x80;
+                    }
+                  bytes[3] |= shiftval (&ins->oprs[3]) << 5;
+                }
+            }
+
+          break;
+
+        case 0x22:      // LDRH Rd, expression
+          ++codes;
+
+          bytes[0] = c | 0x01;          // Implicit pre-index
+
+          bytes[1] = *codes++;
+
+          // Rd
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+
+          // Rn - implicit R15
+          bytes[1] |= 0xF;
+
+          if (ins->oprs[1].segment != segment)
+            {
+              errfunc (ERR_NONFATAL, "label not in same segment");
+            }
+
+          data = ins->oprs[1].offset - (offset + 8);
+
+          if (data < 0)
+            {
+              data = -data;
+            }
+          else
+            {
+              bytes[1] |= 0x80;
+            }
+
+          if (data >= 0x100)
+            {
+              errfunc (ERR_NONFATAL, "too long offset");
+            }
+          bytes[3] = *codes++;
+
+          bytes[2] |= ((data & 0xF0) >> 4);
+          bytes[3] |= data & 0xF;
+          break;
+
+        case 0x23:      // LDRH Rd, Rn
+          ++codes;
+
+          bytes[0] = c | 0x01;          // Implicit pre-index
+
+          bytes[1] = *codes++;
+
+          // Rd
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+
+          // Rn
+          c = regval (&ins->oprs[1],1);
+          bytes[1] |= c;
+
+          if (c == 0x15)                // R15
+            data = -8;
+          else
+            data = 0;
+
+          if (data < 0)
+            {
+              data = -data;
+            }
+          else
+            {
+              bytes[1] |= 0x80;
+            }
+
+          if (data >= 0x100)
+            {
+              errfunc (ERR_NONFATAL, "too long offset");
+            }
+          bytes[3] = *codes++;
+
+          bytes[2] |= ((data & 0xF0) >> 4);
+          bytes[3] |= data & 0xF;
+          break;
+
+        case 0x24:      // LDRH Rd, Rn, expression
+        case 0x25:      // LDRH Rd, Rn, Rm
+          ++codes;
+
+          bytes[0] = c;
+
+          bytes[1] = *codes++;
+
+          // Rd
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+
+          // Rn
+          c = regval (&ins->oprs[1],1);
+          bytes[1] |= c;
+
+          if (ins->oprs[ins->operands-1].bracket)       // FIXME: Bracket on last operand -> pre-index  <--
+            {
+              bytes[0] |= 0x01;         // pre-index mode
+              if (has_W_code)
+                {
+                  bytes[1] |= 0x20;
+                }
+            }
+          else
+            {
+              if (has_W_code)
+                {
+                  errfunc (ERR_NONFATAL, "'!' not allowed in post-index mode");
+                }
+            }
+
+          bytes[3] = *codes++;
+
+          if (keep == 0x24)
+            {
+              data = ins->oprs[2].offset;
+
+              if (data < 0)
+                {
+                  data = -data;
+                }
+              else
+                {
+                  bytes[1] |= 0x80;
+                }
+
+              if (data >= 0x100)
+                {
+                  errfunc (ERR_NONFATAL, "too long offset");
+                }
+
+              bytes[2] |= ((data & 0xF0) >> 4);
+              bytes[3] |= data & 0xF;
+            }
+          else
+            {
+              if (ins->oprs[2].minus == 0)
+                {
+                  bytes[1] |= 0x80;
+                }
+              c = regval (&ins->oprs[2],1);
+              bytes[3] |= c;
+
+            }
+          break;
+
+        case 0x26:      // LDM/STM Rn, {reg-list}
+          ++codes;
+
+          bytes[0] = c;
+
+          bytes[0] |= ( *codes >> 4) & 0xF;
+          bytes[1] = ( *codes << 4) & 0xF0;
+          ++codes;
+
+          if (has_W_code)
+            {
+              bytes[1] |= 0x20;
+            }
+          if (has_F_code)
+            {
+              bytes[1] |= 0x40;
+            }
+
+          // Rn
+          bytes[1] |= regval (&ins->oprs[0],1);
+
+          data = ins->oprs[1].basereg;
+
+          bytes[2] = ((data >> 8) & 0xFF);
+          bytes[3] = (data & 0xFF);
+
+          break;
+
+        case 0x27:      // SWP Rd, Rm, [Rn]
+          ++codes;
+
+          bytes[0] = c;
+
+          bytes[0] |= *codes++;
+
+          bytes[1] = regval (&ins->oprs[2],1);
+          if (has_B_code)
+            {
+              bytes[1] |= 0x40;
+            }
+          bytes[2] = regval (&ins->oprs[0],1) << 4;
+          bytes[3] = *codes++;
+          bytes[3] |= regval (&ins->oprs[1],1);
+          break;
+
+        default:
+          errfunc (ERR_FATAL, "unknown decoding of instruction");
+
+          bytes[0] = c;
+          // And a fix nibble
+          ++codes;
+          bytes[0] |= *codes++;
+
+         if ( *codes == 0x01)           // An I bit
+           {
+
+           }
+         if ( *codes == 0x02)           // An I bit
+           {
+
+           }
+         ++codes;
+      }
+    out (offset, segment, bytes, OUT_RAWDATA+4, NO_SEG, NO_SEG);
+}
+
+*)
+{$endif dummy}
+
+begin
+  cai_align:=tai_align;
+end.
+

+ 66 - 0
compiler/aarch64/aoptcpu.pas

@@ -0,0 +1,66 @@
+{
+    Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
+    Development Team
+
+    This unit implements the ARM64 optimizer object
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+
+
+Unit aoptcpu;
+
+{$i fpcdefs.inc}
+
+Interface
+
+uses cpubase, aasmtai, aopt, aoptcpub;
+
+Type
+  TCpuAsmOptimizer = class(TAsmOptimizer)
+    { uses the same constructor as TAopObj }
+    function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
+    procedure PeepHoleOptPass2;override;
+  End;
+
+Implementation
+
+  uses
+    aasmbase,aasmcpu,cgbase;
+
+  function CanBeCond(p : tai) : boolean;
+    begin
+      result:=(p.typ=ait_instruction) and (taicpu(p).condition=C_None);
+    end;
+
+
+  function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
+    var
+      next1: tai;
+    begin
+      result := false;
+    end;
+
+
+  procedure TCpuAsmOptimizer.PeepHoleOptPass2;
+    begin
+    end;
+
+begin
+  casmoptimizer:=TCpuAsmOptimizer;
+End.
+

+ 134 - 0
compiler/aarch64/aoptcpub.pas

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

+ 41 - 0
compiler/aarch64/aoptcpud.pas

@@ -0,0 +1,41 @@
+{
+    Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
+    Development Team
+
+    This unit contains the processor specific implementation of the
+    assembler optimizer data flow analyzer.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+Unit aoptcpud;
+
+{$i fpcdefs.inc}
+
+Interface
+
+uses
+  AOptDA;
+
+Type
+  TAOptDFACpu = class(TAOptDFA)
+  End;
+
+Implementation
+
+
+End.
+

+ 458 - 0
compiler/aarch64/cpubase.pas

@@ -0,0 +1,458 @@
+{
+    Copyright (c) 1998-2012 by Florian Klaempfl and Peter Vreman
+
+    Contains the base types for ARM64
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+{ Base unit for processor information. This unit contains
+  enumerations of registers, opcodes, sizes, and other
+  such things which are processor specific.
+}
+unit cpubase;
+
+{$define USEINLINE}
+
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+      cutils,cclasses,
+      globtype,globals,
+      cpuinfo,
+      aasmbase,
+      cgbase
+      ;
+
+
+{*****************************************************************************
+                                Assembler Opcodes
+*****************************************************************************}
+
+    type
+      TAsmOp= {$i a64op.inc}
+
+      { This should define the array of instructions as string }
+      op2strtable=array[tasmop] of string[11];
+
+    const
+      { First value of opcode enumeration }
+      firstop = low(tasmop);
+      { Last value of opcode enumeration  }
+      lastop  = high(tasmop);
+
+{*****************************************************************************
+                                  Registers
+*****************************************************************************}
+
+    type
+      { Number of registers used for indexing in tables }
+      tregisterindex=0..{$i ra64nor.inc}-1;
+
+    const
+      { Available Superregisters }
+      {$i ra64sup.inc}
+
+      R_SUBWHOLE = R_SUBQ;
+
+      { Available Registers }
+      {$i ra64con.inc}
+
+      { Integer Super registers first and last }
+      first_int_supreg = RS_X0;
+      first_int_imreg = $20;
+
+      { Integer Super registers first and last }
+      first_fpu_supreg = RS_S0;
+      first_fpu_imreg = $20;
+
+      { MM Super register first and last }
+      first_mm_supreg    = RS_S0;
+      first_mm_imreg     = $20;
+
+      { Required parameter alignment when calling a routine declared as
+        stdcall and cdecl. The alignment value should be the one defined
+        by GCC or the target ABI.
+
+        The value of this constant is equal to the constant
+        PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
+      }
+      std_param_align = 4;
+
+      { TODO: Calculate bsstart}
+      regnumber_count_bsstart = 128;
+
+      regnumber_table : array[tregisterindex] of tregister = (
+        {$i ra64num.inc}
+      );
+
+      regstabs_table : array[tregisterindex] of shortint = (
+        {$i ra64sta.inc}
+      );
+
+      regdwarf_table : array[tregisterindex] of shortint = (
+        {$i ra64dwa.inc}
+      );
+      { registers which may be destroyed by calls }
+      VOLATILE_INTREGISTERS = [RS_X0..RS_X18,RS_X29..RS_X30];
+      VOLATILE_MMREGISTERS =  [RS_D0..RS_D7,RS_D16..RS_D31];
+
+    type
+      totherregisterset = set of tregisterindex;
+
+{*****************************************************************************
+                          Instruction post fixes
+*****************************************************************************}
+    type
+      { ARM instructions load/store and arithmetic instructions
+        can have several instruction post fixes which are collected
+        in this enumeration
+      }
+      TOpPostfix = (PF_None,
+        { update condition flags }
+        PF_S,
+        { load/store }
+        PF_B,PF_SB,PF_H,PF_SH
+      );
+
+      TOpPostfixes = set of TOpPostfix;
+
+    const
+      oppostfix2str : array[TOpPostfix] of string[2] = ('',
+        's',
+        'b','sb','h','sh');
+
+{*****************************************************************************
+                                Conditions
+*****************************************************************************}
+
+    type
+      TAsmCond=(C_None,
+        C_EQ,C_NE,C_HS,C_LO,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
+        C_GE,C_LT,C_GT,C_LE,C_AL,C_NV
+      );
+
+      TAsmConds = set of TAsmCond;
+
+    const
+      cond2str : array[TAsmCond] of string[2]=('',
+        'eq','ne','hs','lo','mi','pl','vs','vc','hi','ls',
+        'ge','lt','gt','le','al','nv'
+      );
+
+      uppercond2str : array[TAsmCond] of string[2]=('',
+        'EQ','NE','hs','LO','MI','PL','VS','VC','HI','LS',
+        'GE','LT','GT','LE','AL','NV'
+      );
+
+{*****************************************************************************
+                                   Flags
+*****************************************************************************}
+
+    type
+      TResFlags = (F_EQ,F_NE,F_CS,F_CC,F_MI,F_PL,F_VS,F_VC,F_HI,F_LS,
+        F_GE,F_LT,F_GT,F_LE);
+
+{*****************************************************************************
+                                Operands
+*****************************************************************************}
+
+      taddressmode = (AM_OFFSET,AM_PREINDEXED,AM_POSTINDEXED);
+      tshiftmode = (SM_None,SM_LSL,SM_LSR,SM_ASR,SM_ROR);
+
+      tupdatereg = (UR_None,UR_Update);
+
+      pshifterop = ^tshifterop;
+
+      tshifterop = record
+        shiftmode : tshiftmode;
+        shiftimm : byte;
+      end;
+
+      tcpumodeflag = (mfA, mfI, mfF);
+      tcpumodeflags = set of tcpumodeflag;
+
+      tspecialregflag = (srC, srX, srS, srF);
+      tspecialregflags = set of tspecialregflag;
+
+{*****************************************************************************
+                                 Constants
+*****************************************************************************}
+
+    const
+      max_operands = 6;
+
+      maxintregs = 32;
+      maxfpuregs = 32;
+      maxaddrregs = 0;
+
+{*****************************************************************************
+                                Operand Sizes
+*****************************************************************************}
+
+    type
+      topsize = (S_NO,
+        S_B,S_W,S_L,S_BW,S_BL,S_WL,
+        S_IS,S_IL,S_IQ,
+        S_FS,S_FL,S_FX,S_D,S_Q,S_FV,S_FXX
+      );
+
+{*****************************************************************************
+                          Default generic sizes
+*****************************************************************************}
+
+   const
+      { Defines the default address size for a processor, }
+      OS_ADDR = OS_64;
+      { the natural int size for a processor,
+        has to match osuinttype/ossinttype as initialized in psystem }
+      OS_INT = OS_64;
+      OS_SINT = OS_S64;
+      { the maximum float size for a processor,           }
+      OS_FLOAT = OS_F64;
+      { the size of a vector register for a processor     }
+      OS_VECTOR = OS_M128;
+
+{*****************************************************************************
+                          Generic Register names
+*****************************************************************************}
+
+      NR_SP = NR_XZR;
+      RS_SP = RS_XZR;
+      NR_WSP = NR_WZR;
+      RS_WSP = RS_WZR;
+
+      { Stack pointer register }
+      NR_STACK_POINTER_REG = NR_SP;
+      RS_STACK_POINTER_REG = RS_SP;
+      { Frame pointer register (initialized in tarmprocinfo.init_framepointer) }
+      RS_FRAME_POINTER_REG: tsuperregister = RS_X29;
+      NR_FRAME_POINTER_REG: tregister = NR_X29;
+      { Register for addressing absolute data in a position independant way,
+        such as in PIC code. The exact meaning is ABI specific. For
+        further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
+      }
+      NR_PIC_OFFSET_REG = NR_X18;
+      { Results are returned in this register (32-bit values) }
+      NR_FUNCTION_RETURN_REG = NR_X0;
+      RS_FUNCTION_RETURN_REG = RS_X0;
+      { The value returned from a function is available in this register }
+      NR_FUNCTION_RESULT_REG = NR_FUNCTION_RETURN_REG;
+      RS_FUNCTION_RESULT_REG = RS_FUNCTION_RETURN_REG;
+
+      NR_FPU_RESULT_REG = NR_NO;
+
+      NR_MM_RESULT_REG  = NR_D0;
+
+      NR_RETURN_ADDRESS_REG = NR_FUNCTION_RETURN_REG;
+
+      { Offset where the parent framepointer is pushed }
+      PARENT_FRAMEPOINTER_OFFSET = 0;
+
+      NR_DEFAULTFLAGS = NR_NZCV;
+      RS_DEFAULTFLAGS = RS_NZCV;
+
+{*****************************************************************************
+                       GCC /ABI linking information
+*****************************************************************************}
+
+    const
+      { Registers which must be saved when calling a routine declared as
+        cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
+        saved should be the ones as defined in the target ABI and / or GCC.
+
+        This value can be deduced from the CALLED_USED_REGISTERS array in the
+        GCC source.
+      }
+      saved_standard_registers : array[0..9] of tsuperregister =
+        (RS_X19,RS_X20,RS_X21,RS_X22,RS_X23,RS_X24,RS_X25,RS_X26,RS_X27,RS_X28);
+
+      { this is only for the generic code which is not used for this architecture }
+      saved_mm_registers : array[0..7] of tsuperregister = (RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15);
+
+{*****************************************************************************
+                                  Helpers
+*****************************************************************************}
+
+    { Returns the tcgsize corresponding with the size of reg.}
+    function reg_cgsize(const reg: tregister) : tcgsize;
+    function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
+    function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
+    procedure inverse_flags(var f: TResFlags);
+    function flags_to_cond(const f: TResFlags) : TAsmCond;
+    function findreg_by_number(r:Tregister):tregisterindex;
+    function std_regnum_search(const s:string):Tregister;
+    function std_regname(r:Tregister):string;
+
+    function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
+    function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
+
+    procedure shifterop_reset(var so : tshifterop); {$ifdef USEINLINE}inline;{$endif USEINLINE}
+
+    function dwarf_reg(r:tregister):shortint;
+
+  implementation
+
+    uses
+      systems,rgBase,verbose;
+
+    const
+      std_regname_table : TRegNameTable = (
+        {$i ra64std.inc}
+      );
+
+      regnumber_index : array[tregisterindex] of tregisterindex = (
+        {$i ra64rni.inc}
+      );
+
+      std_regname_index : array[tregisterindex] of tregisterindex = (
+        {$i ra64sri.inc}
+      );
+
+
+    function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
+      begin
+        case regtype of
+          R_MMREGISTER:
+            begin
+              case s of
+                OS_F32:
+                  cgsize2subreg:=R_SUBFS;
+                OS_F64:
+                  cgsize2subreg:=R_SUBFD;
+                else
+                  internalerror(2009112701);
+              end;
+            end;
+          else
+            cgsize2subreg:=R_SUBWHOLE;
+        end;
+      end;
+
+
+    function reg_cgsize(const reg: tregister): tcgsize;
+      begin
+        case getregtype(reg) of
+          R_INTREGISTER :
+            reg_cgsize:=OS_32;
+          R_FPUREGISTER :
+            reg_cgsize:=OS_F80;
+          R_MMREGISTER :
+            begin
+              case getsubreg(reg) of
+                R_SUBFD,
+                R_SUBWHOLE:
+                  result:=OS_F64;
+                R_SUBFS:
+                  result:=OS_F32;
+                else
+                  internalerror(2009112903);
+              end;
+            end;
+          else
+            internalerror(200303181);
+          end;
+        end;
+
+
+    function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
+      begin
+        { This isn't 100% perfect because the arm allows jumps also by writing to PC=R15.
+          To overcome this problem we simply forbid that FPC generates jumps by loading R15 }
+        is_calljmp:= o in [A_B,A_BLR,A_RET];
+      end;
+
+
+    procedure inverse_flags(var f: TResFlags);
+      const
+        inv_flags: array[TResFlags] of TResFlags =
+          (F_NE,F_EQ,F_CC,F_CS,F_PL,F_MI,F_VC,F_VS,F_LS,F_HI,
+          F_LT,F_GE,F_LE,F_GT);
+      begin
+        f:=inv_flags[f];
+      end;
+
+
+    function flags_to_cond(const f: TResFlags) : TAsmCond;
+      const
+        flag_2_cond: array[F_EQ..F_LE] of TAsmCond =
+          (C_EQ,C_NE,C_HI,C_LO,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
+           C_GE,C_LT,C_GT,C_LE);
+      begin
+        if f>high(flag_2_cond) then
+          internalerror(200112301);
+        result:=flag_2_cond[f];
+      end;
+
+
+    function findreg_by_number(r:Tregister):tregisterindex;
+      begin
+        result:=rgBase.findreg_by_number_table(r,regnumber_index);
+      end;
+
+
+    function std_regnum_search(const s:string):Tregister;
+      begin
+        result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)];
+      end;
+
+
+    function std_regname(r:Tregister):string;
+      var
+        p : tregisterindex;
+      begin
+        p:=findreg_by_number_table(r,regnumber_index);
+        if p<>0 then
+          result:=std_regname_table[p]
+        else
+          result:=generic_regname(r);
+      end;
+
+
+    procedure shifterop_reset(var so : tshifterop);{$ifdef USEINLINE}inline;{$endif USEINLINE}
+      begin
+        FillChar(so,sizeof(so),0);
+      end;
+
+
+    function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
+      const
+        inverse: array[TAsmCond] of TAsmCond=(C_None,
+          C_NE,C_EQ,C_LO,C_HI,C_PL,C_MI,C_VC,C_VS,C_LS,C_HI,
+          C_LT,C_GE,C_LE,C_GT,C_None,C_None
+        );
+      begin
+        result := inverse[c];
+      end;
+
+
+    function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
+      begin
+        result := c1 = c2;
+      end;
+
+
+    function dwarf_reg(r:tregister):shortint;
+      begin
+        result:=regdwarf_table[findreg_by_number(r)];
+        if result=-1 then
+          internalerror(200603251);
+      end;
+
+
+end.

+ 102 - 0
compiler/aarch64/cpuinfo.pas

@@ -0,0 +1,102 @@
+{
+    Copyright (c) 1998-2002 by the Free Pascal development team
+
+    Basic Processor information for AArch64
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+Unit CPUInfo;
+
+Interface
+
+  uses
+    globtype;
+
+Type
+   bestreal = double;
+   ts32real = single;
+   ts64real = double;
+   ts80real = type extended;
+   ts128real = type extended;
+   ts64comp = comp;
+
+   pbestreal=^bestreal;
+
+   { possible supported processors for this target }
+   tcputype =
+      (cpu_none,
+       cpu_armv8
+      );
+
+Type
+   tfputype =
+     (fpu_none,
+      fpu_vfp
+     );
+
+   tcontrollertype =
+     (ct_none
+     );
+
+
+Const
+   {# Size of native extended floating point type }
+   extended_size = 8;
+   {# Size of a multimedia register               }
+   mmreg_size = 16;
+   { target cpu string (used by compiler options) }
+   target_cpu_string = 'aarch64';
+
+   { calling conventions supported by the code generator }
+   supported_calling_conventions : tproccalloptions = [
+     pocall_internproc,
+     pocall_safecall,
+     pocall_stdcall,
+     { same as stdcall only different name mangling }
+     pocall_cdecl,
+     { same as stdcall only different name mangling }
+     pocall_cppdecl,
+     { same as stdcall but floating point numbers are handled like equal sized integers }
+     pocall_softfloat,
+     { same as stdcall (requires that all const records are passed by
+       reference, but that's already done for stdcall) }
+     pocall_mwpascal,
+     { used for interrupt handling }
+     pocall_interrupt
+   ];
+
+   cputypestr : array[tcputype] of string[8] = ('',
+     'ARMV8'
+   );
+
+   fputypestr : array[tfputype] of string[9] = ('',
+     'VFP'
+   );
+
+
+   { Supported optimizations, only used for information }
+   supported_optimizerswitches = genericlevel1optimizerswitches+
+                                 genericlevel2optimizerswitches+
+                                 genericlevel3optimizerswitches-
+                                 { no need to write info about those }
+                                 [cs_opt_level1,cs_opt_level2,cs_opt_level3]+
+                                 [cs_opt_regvar,cs_opt_loopunroll,cs_opt_tailrecursion,
+				  cs_opt_stackframe,cs_opt_nodecse,cs_opt_reorder_fields,cs_opt_fastmath];
+
+   level1optimizerswitches = genericlevel1optimizerswitches;
+   level2optimizerswitches = genericlevel2optimizerswitches + level1optimizerswitches +
+     [cs_opt_regvar,cs_opt_stackframe,cs_opt_tailrecursion,cs_opt_nodecse];
+   level3optimizerswitches = genericlevel3optimizerswitches + level2optimizerswitches + [cs_opt_scheduler{,cs_opt_loopunroll}];
+   level4optimizerswitches = genericlevel4optimizerswitches + level3optimizerswitches + [];
+
+Implementation
+
+end.
+

+ 709 - 0
compiler/aarch64/cpupara.pas

@@ -0,0 +1,709 @@
+{
+    Copyright (c) 2003-2012 by Florian Klaempfl and others
+
+    AArch64 specific calling conventions
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ****************************************************************************
+}
+{ AArch64 specific calling conventions are handled by this unit
+}
+unit cpupara;
+
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+       globtype,globals,
+       aasmtai,aasmdata,
+       cpuinfo,cpubase,cgbase,cgutils,
+       symconst,symbase,symtype,symdef,parabase,paramgr;
+
+    type
+       taarch64paramanager = class(tparamanager)
+          function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
+          function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
+          function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
+          function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
+          function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
+          procedure getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
+          function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
+          function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
+          function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
+         private
+          procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister);
+          function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
+            var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister; isvariadic: boolean):longint;
+       end;
+
+  implementation
+
+    uses
+       verbose,systems,cutils,
+       rgobj,
+       defutil,symsym,symtable;
+
+
+    function taarch64paramanager.get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;
+      begin
+        result:=VOLATILE_INTREGISTERS
+      end;
+
+
+    function taarch64paramanager.get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;
+      begin
+        result:=[];
+      end;
+
+
+    function taarch64paramanager.get_volatile_registers_mm(calloption: tproccalloption): tcpuregisterset;
+      begin
+        result:=VOLATILE_MMREGISTERS;
+      end;
+
+
+    procedure taarch64paramanager.getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);
+      var
+        paraloc : pcgparalocation;
+        def : tdef;
+      begin
+        if nr<1 then
+          internalerror(2002070801);
+        def:=tparavarsym(pd.paras[nr-1]).vardef;
+        cgpara.reset;
+        cgpara.size:=def_cgsize(def);
+        cgpara.intsize:=tcgsize2size[cgpara.size];
+        cgpara.alignment:=std_param_align;
+        cgpara.def:=def;
+        paraloc:=cgpara.add_location;
+        with paraloc^ do
+          begin
+            size:=OS_INT;
+            { the four first parameters are passed into registers }
+            if nr<=8 then
+              begin
+                loc:=LOC_REGISTER;
+                register:=newreg(R_INTREGISTER,RS_X0+nr-1,R_SUBWHOLE);
+              end
+            else
+              begin
+                { the other parameters are passed on the stack }
+                loc:=LOC_REFERENCE;
+                reference.index:=NR_STACK_POINTER_REG;
+                reference.offset:=(nr-9)*8;
+              end;
+          end;
+      end;
+
+
+    function Is_HFA(p : tdef) : boolean;
+      begin
+        result:=false;
+      end;
+
+
+    function getparaloc(calloption : tproccalloption; p : tdef; isvariadic: boolean) : tcgloc;
+      begin
+         { Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER
+           if push_addr_param for the def is true
+         }
+         case p.typ of
+            orddef:
+              getparaloc:=LOC_REGISTER;
+            floatdef:
+              getparaloc:=LOC_MMREGISTER
+            enumdef:
+              getparaloc:=LOC_REGISTER;
+            pointerdef:
+              getparaloc:=LOC_REGISTER;
+            formaldef:
+              getparaloc:=LOC_REGISTER;
+            classrefdef:
+              getparaloc:=LOC_REGISTER;
+            recorddef:
+              getparaloc:=LOC_REGISTER;
+            objectdef:
+              getparaloc:=LOC_REGISTER;
+            stringdef:
+              if is_shortstring(p) or is_longstring(p) then
+                getparaloc:=LOC_REFERENCE
+              else
+                getparaloc:=LOC_REGISTER;
+            procvardef:
+              getparaloc:=LOC_REGISTER;
+            filedef:
+              getparaloc:=LOC_REGISTER;
+            arraydef:
+              getparaloc:=LOC_REFERENCE;
+            setdef:
+              if is_smallset(p) then
+                getparaloc:=LOC_REGISTER
+              else
+                getparaloc:=LOC_REFERENCE;
+            variantdef:
+              getparaloc:=LOC_REGISTER;
+            { avoid problems with errornous definitions }
+            errordef:
+              getparaloc:=LOC_REGISTER;
+            else
+              internalerror(2002071001);
+         end;
+      end;
+
+
+    function taarch64paramanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
+      begin
+        result:=false;
+        if varspez in [vs_var,vs_out,vs_constref] then
+          begin
+            result:=true;
+            exit;
+          end;
+        case def.typ of
+          objectdef:
+            result:=not(Is_HFA(def) and (is_object(def) and ((varspez=vs_const) or (def.size=0));
+          recorddef:
+            { note: should this ever be changed, make sure that const records
+                are always passed by reference for calloption=pocall_mwpascal }
+            result:=(varspez=vs_const) or (def.size=0);
+          variantdef,
+          formaldef:
+            result:=true;
+          arraydef:
+            result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
+                             is_open_array(def) or
+                             is_array_of_const(def) or
+                             is_array_constructor(def);
+          setdef :
+            result:=def.size>16;
+          stringdef :
+            result:=tstringdef(def).stringtype in [st_shortstring,st_longstring];
+        end;
+      end;
+
+
+    function taarch64paramanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
+      var
+        i: longint;
+        sym: tsym;
+        fpufield: boolean;
+      begin
+        if handle_common_ret_in_param(def,pd,result) then
+          exit;
+        case def.typ of
+          recorddef:
+            begin
+              result:=def.size>4;
+              if not result and
+                 (target_info.abi in [abi_default,abi_armeb]) then
+                begin
+                  { in case of the old ARM abi (APCS), a struct is returned in
+                    a register only if it is simple. And what is a (non-)simple
+                    struct:
+
+                    "A non-simple type is any non-floating-point type of size
+                     greater than one word (including structures containing only
+                     floating-point fields), and certain single-word structured
+                     types."
+                       (-- ARM APCS documentation)
+
+                    So only floating point types or more than one word ->
+                    definitely non-simple (more than one word is already
+                    checked above). This includes unions/variant records with
+                    overlaid floating point and integer fields.
+
+                    Smaller than one word struct types are simple if they are
+                    "integer-like", and:
+
+                    "A structure is termed integer-like if its size is less than
+                    or equal to one word, and the offset of each of its
+                    addressable subfields is zero."
+                      (-- ARM APCS documentation)
+
+                    An "addressable subfield" is a field of which you can take
+                    the address, which in practive means any non-bitfield.
+                    In Pascal, there is no way to express the difference that
+                    you can have in C between "char" and "int :8". In this
+                    context, we use the fake distinction that a type defined
+                    inside the record itself (such as "a: 0..255;") indicates
+                    a bitpacked field while a field using a different type
+                    (such as "a: byte;") is not.
+                  }
+                  for i:=0 to trecorddef(def).symtable.SymList.count-1 do
+                    begin
+                      sym:=tsym(trecorddef(def).symtable.SymList[i]);
+                      if sym.typ<>fieldvarsym then
+                        continue;
+                      { bitfield -> ignore }
+                      if (trecordsymtable(trecorddef(def).symtable).usefieldalignment=bit_alignment) and
+                         (tfieldvarsym(sym).vardef.typ in [orddef,enumdef]) and
+                         (tfieldvarsym(sym).vardef.owner.defowner=def) then
+                        continue;
+                      { all other fields must be at offset zero }
+                      if tfieldvarsym(sym).fieldoffset<>0 then
+                        begin
+                          result:=true;
+                          exit;
+                        end;
+                      { floating point field -> also by reference }
+                      if tfieldvarsym(sym).vardef.typ=floatdef then
+                        begin
+                          result:=true;
+                          exit;
+                        end;
+                    end;
+                end;
+            end;
+          procvardef:
+            if not tprocvardef(def).is_addressonly then
+              result:=true
+            else
+              result:=false
+          else
+            result:=inherited ret_in_param(def,pd);
+        end;
+      end;
+
+
+    procedure taarch64paramanager.init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister);
+      begin
+        curintreg:=RS_R0;
+        curfloatreg:=RS_F0;
+        curmmreg:=RS_D0;
+        cur_stack_offset:=0;
+        sparesinglereg := NR_NO;
+      end;
+
+
+    function taarch64paramanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
+        var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister; isvariadic: boolean):longint;
+
+      var
+        nextintreg,nextfloatreg,nextmmreg : tsuperregister;
+        paradef : tdef;
+        paraloc : pcgparalocation;
+        stack_offset : aword;
+        hp : tparavarsym;
+        loc : tcgloc;
+        paracgsize   : tcgsize;
+        paralen : longint;
+        i : integer;
+        firstparaloc: boolean;
+
+      procedure assignintreg;
+        begin
+          { In case of po_delphi_nested_cc, the parent frame pointer
+            is always passed on the stack. }
+           if (nextintreg<=RS_R3) and
+              (not(vo_is_parentfp in hp.varoptions) or
+               not(po_delphi_nested_cc in p.procoptions)) then
+             begin
+               paraloc^.loc:=LOC_REGISTER;
+               paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
+               inc(nextintreg);
+             end
+           else
+             begin
+               paraloc^.loc:=LOC_REFERENCE;
+               paraloc^.reference.index:=NR_STACK_POINTER_REG;
+               paraloc^.reference.offset:=stack_offset;
+               inc(stack_offset,4);
+            end;
+        end;
+
+
+      begin
+        result:=0;
+        nextintreg:=curintreg;
+        nextfloatreg:=curfloatreg;
+        nextmmreg:=curmmreg;
+        stack_offset:=cur_stack_offset;
+
+        for i:=0 to paras.count-1 do
+          begin
+            hp:=tparavarsym(paras[i]);
+            paradef:=hp.vardef;
+
+            hp.paraloc[side].reset;
+
+            { currently only support C-style array of const,
+              there should be no location assigned to the vararg array itself }
+            if (p.proccalloption in cstylearrayofconst) and
+               is_array_of_const(paradef) then
+              begin
+                paraloc:=hp.paraloc[side].add_location;
+                { hack: the paraloc must be valid, but is not actually used }
+                paraloc^.loc:=LOC_REGISTER;
+                paraloc^.register:=NR_R0;
+                paraloc^.size:=OS_ADDR;
+                break;
+              end;
+
+            if push_addr_param(hp.varspez,paradef,p.proccalloption) then
+              begin
+                paradef:=getpointerdef(paradef);
+                loc:=LOC_REGISTER;
+                paracgsize := OS_ADDR;
+                paralen := tcgsize2size[OS_ADDR];
+              end
+            else
+              begin
+                if not is_special_array(paradef) then
+                  paralen := paradef.size
+                else
+                  paralen := tcgsize2size[def_cgsize(paradef)];
+                loc := getparaloc(p.proccalloption,paradef,isvariadic);
+                if (paradef.typ in [objectdef,arraydef,recorddef]) and
+                  not is_special_array(paradef) and
+                  (hp.varspez in [vs_value,vs_const]) then
+                  paracgsize := int_cgsize(paralen)
+                else
+                  begin
+                    paracgsize:=def_cgsize(paradef);
+                    { for things like formaldef }
+                    if (paracgsize=OS_NO) then
+                      begin
+                        paracgsize:=OS_ADDR;
+                        paralen:=tcgsize2size[OS_ADDR];
+                        paradef:=voidpointertype;
+                      end;
+                  end
+              end;
+
+             hp.paraloc[side].size:=paracgsize;
+             hp.paraloc[side].Alignment:=std_param_align;
+             hp.paraloc[side].intsize:=paralen;
+             hp.paraloc[side].def:=paradef;
+             firstparaloc:=true;
+
+{$ifdef EXTDEBUG}
+             if paralen=0 then
+               internalerror(200410311);
+{$endif EXTDEBUG}
+             while paralen>0 do
+               begin
+                 paraloc:=hp.paraloc[side].add_location;
+
+                 if (loc=LOC_REGISTER) and (paracgsize in [OS_F32,OS_F64,OS_F80]) then
+                   case paracgsize of
+                     OS_F32:
+                       paraloc^.size:=OS_32;
+                     OS_F64:
+                       paraloc^.size:=OS_32;
+                     else
+                       internalerror(2005082901);
+                   end
+                 else if (paracgsize in [OS_NO,OS_64,OS_S64]) then
+                   paraloc^.size := OS_32
+                 else
+                   paraloc^.size:=paracgsize;
+                 case loc of
+                    LOC_REGISTER:
+                      begin
+                        { align registers for eabi }
+                        if (target_info.abi in [abi_eabi,abi_eabihf]) and
+                           firstparaloc and
+                           (paradef.alignment=8) then
+                          begin
+                            if (nextintreg in [RS_R1,RS_R3]) then
+                              inc(nextintreg)
+                            else if nextintreg>RS_R3 then
+                              stack_offset:=align(stack_offset,8);
+                          end;
+                        { this is not abi compliant
+                          why? (FK) }
+                        if nextintreg<=RS_R3 then
+                          begin
+                            paraloc^.loc:=LOC_REGISTER;
+                            paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
+                            inc(nextintreg);
+                          end
+                        else
+                          begin
+                            { LOC_REFERENCE always contains everything that's left }
+                            paraloc^.loc:=LOC_REFERENCE;
+                            paraloc^.size:=int_cgsize(paralen);
+                            if (side=callerside) then
+                              paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                            paraloc^.reference.offset:=stack_offset;
+                            inc(stack_offset,align(paralen,4));
+                            paralen:=0;
+                         end;
+                      end;
+                    LOC_FPUREGISTER:
+                      begin
+                        if nextfloatreg<=RS_F3 then
+                          begin
+                            paraloc^.loc:=LOC_FPUREGISTER;
+                            paraloc^.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE);
+                            inc(nextfloatreg);
+                          end
+                        else
+                          begin
+                            paraloc^.loc:=LOC_REFERENCE;
+                            paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                            paraloc^.reference.offset:=stack_offset;
+                            case paraloc^.size of
+                              OS_F32:
+                                inc(stack_offset,4);
+                              OS_F64:
+                                inc(stack_offset,8);
+                              OS_F80:
+                                inc(stack_offset,10);
+                              OS_F128:
+                                inc(stack_offset,16);
+                              else
+                                internalerror(200403201);
+                            end;
+                          end;
+                      end;
+                    LOC_MMREGISTER:
+                      begin
+                        if (nextmmreg<=RS_D7) or
+                           ((paraloc^.size = OS_F32) and
+                            (sparesinglereg<>NR_NO)) then
+                          begin
+                            paraloc^.loc:=LOC_MMREGISTER;
+                            case paraloc^.size of
+                              OS_F32:
+                                if sparesinglereg = NR_NO then 
+                                  begin     
+                                    paraloc^.register:=newreg(R_MMREGISTER,nextmmreg,R_SUBFS);
+                                    sparesinglereg:=newreg(R_MMREGISTER,nextmmreg-RS_S0+RS_S1,R_SUBFS);
+                                    inc(nextmmreg);
+                                  end
+                                else
+                                  begin
+                                    paraloc^.register:=sparesinglereg;
+                                    sparesinglereg := NR_NO;
+                                  end;
+                              OS_F64:
+                                begin
+                                  paraloc^.register:=newreg(R_MMREGISTER,nextmmreg,R_SUBFD);
+                                  inc(nextmmreg);
+                                end;
+                              else
+                                internalerror(2012031601);
+                            end;
+                          end
+                        else
+                          begin
+                            { once a floating point parameters has been placed
+                            on the stack we must not pass any more in vfp regs
+                            even if there is a single precision register still
+                            free}
+                            sparesinglereg := NR_NO;
+                            { LOC_REFERENCE always contains everything that's left }
+                            paraloc^.loc:=LOC_REFERENCE;
+                            paraloc^.size:=int_cgsize(paralen);
+                            if (side=callerside) then
+                              paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                            paraloc^.reference.offset:=stack_offset;
+                            inc(stack_offset,align(paralen,4));
+                            paralen:=0;
+                         end;
+                      end;
+                    LOC_REFERENCE:
+                      begin
+                        if push_addr_param(hp.varspez,paradef,p.proccalloption) then
+                          begin
+                            paraloc^.size:=OS_ADDR;
+                            assignintreg
+                          end
+                        else
+                          begin
+                            { align stack for eabi }
+                            if (target_info.abi in [abi_eabi,abi_eabihf]) and
+                               firstparaloc and
+                               (paradef.alignment=8) then
+                              stack_offset:=align(stack_offset,8);
+
+                             paraloc^.size:=paracgsize;
+                             paraloc^.loc:=LOC_REFERENCE;
+                             paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                             paraloc^.reference.offset:=stack_offset;
+                             inc(stack_offset,align(paralen,4));
+                             paralen:=0
+                          end;
+                      end;
+                    else
+                      internalerror(2002071002);
+                 end;
+                 if side=calleeside then
+                   begin
+                     if paraloc^.loc=LOC_REFERENCE then
+                       begin
+                         paraloc^.reference.index:=NR_FRAME_POINTER_REG;
+                         { on non-Darwin, the framepointer contains the value
+                           of the stack pointer on entry. On Darwin, the
+                           framepointer points to the previously saved
+                           framepointer (which is followed only by the saved
+                           return address -> framepointer + 4 = stack pointer
+                           on entry }
+                         if not(target_info.system in systems_darwin) then
+                           inc(paraloc^.reference.offset,4)
+                         else
+                           inc(paraloc^.reference.offset,8);
+                       end;
+                   end;
+                 dec(paralen,tcgsize2size[paraloc^.size]);
+                 firstparaloc:=false
+               end;
+          end;
+        curintreg:=nextintreg;
+        curfloatreg:=nextfloatreg;
+        curmmreg:=nextmmreg;
+        cur_stack_offset:=stack_offset;
+        result:=cur_stack_offset;
+      end;
+
+
+    function  taarch64paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
+      var
+        paraloc : pcgparalocation;
+        retcgsize  : tcgsize;
+      begin
+         if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
+           exit;
+
+        paraloc:=result.add_location;
+        { Return in FPU register? }
+        if result.def.typ=floatdef then
+          begin
+            if target_info.abi = abi_eabihf then 
+              begin
+                paraloc^.loc:=LOC_MMREGISTER;
+                case retcgsize of
+                  OS_64,
+                  OS_F64:
+                    begin
+                      paraloc^.register:=NR_MM_RESULT_REG;
+                    end;
+                  OS_32,
+                  OS_F32:
+                    begin
+                      paraloc^.register:=NR_S0;
+                    end;
+                  else
+                    internalerror(2012032501);
+                end;
+                paraloc^.size:=retcgsize;
+              end
+            else if (p.proccalloption in [pocall_softfloat]) or
+               (cs_fp_emulation in current_settings.moduleswitches) or
+               (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_fpv4_s16]) then
+              begin
+                case retcgsize of
+                  OS_64,
+                  OS_F64:
+                    begin
+                      paraloc^.loc:=LOC_REGISTER;
+                      if target_info.endian = endian_big then
+                        paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
+                      else
+                        paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG;
+                      paraloc^.size:=OS_32;
+                      paraloc:=result.add_location;
+                      paraloc^.loc:=LOC_REGISTER;
+                      if target_info.endian = endian_big then
+                        paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
+                      else
+                        paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG;
+                      paraloc^.size:=OS_32;
+                    end;
+                  OS_32,
+                  OS_F32:
+                    begin
+                      paraloc^.loc:=LOC_REGISTER;
+                      paraloc^.register:=NR_FUNCTION_RETURN_REG;
+                      paraloc^.size:=OS_32;
+                    end;
+                  else
+                    internalerror(2005082603);
+                end;
+              end
+            else
+              begin
+                paraloc^.loc:=LOC_FPUREGISTER;
+                paraloc^.register:=NR_FPU_RESULT_REG;
+                paraloc^.size:=retcgsize;
+              end;
+          end
+          { Return in register }
+        else
+          begin
+            if retcgsize in [OS_64,OS_S64] then
+              begin
+                paraloc^.loc:=LOC_REGISTER;
+                if target_info.endian = endian_big then
+                  paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG
+                else
+                  paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG;
+                paraloc^.size:=OS_32;
+                paraloc:=result.add_location;
+                paraloc^.loc:=LOC_REGISTER;
+                if target_info.endian = endian_big then
+                  paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG
+                else
+                  paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG;
+                paraloc^.size:=OS_32;
+              end
+            else
+              begin
+                paraloc^.loc:=LOC_REGISTER;
+                paraloc^.register:=NR_FUNCTION_RETURN_REG;
+                if (result.intsize<>3) then
+                  paraloc^.size:=retcgsize
+                else
+                  paraloc^.size:=OS_32;
+              end;
+          end;
+      end;
+
+
+    function taarch64paramanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
+      var
+        cur_stack_offset: aword;
+        curintreg, curfloatreg, curmmreg: tsuperregister;
+        sparesinglereg:tregister;
+      begin
+        init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg);
+
+        result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,false);
+
+        create_funcretloc_info(p,side);
+     end;
+
+
+    function taarch64paramanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;
+      var
+        cur_stack_offset: aword;
+        curintreg, curfloatreg, curmmreg: tsuperregister;
+        sparesinglereg:tregister;
+      begin
+        init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg);
+
+        result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true);
+        if (p.proccalloption in cstylearrayofconst) then
+          { just continue loading the parameters in the registers }
+          result:=create_paraloc_info_intern(p,callerside,varargspara,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true)
+        else
+          internalerror(200410231);
+      end;
+
+begin
+   paramanager:=taarch64paramanager.create;
+end.

+ 93 - 0
compiler/aarch64/itcpugas.pas

@@ -0,0 +1,93 @@
+{
+    Copyright (c) 1998-2012 by Florian Klaempfl and others
+
+    This unit contains the ARM64 GAS instruction tables
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit itcpugas;
+
+{$i fpcdefs.inc}
+
+interface
+
+  uses
+    cpubase,cgbase;
+
+
+  const
+    { Standard opcode string table (for each tasmop enumeration). The
+      opcode strings should conform to the names as defined by the
+      processor manufacturer.
+    }
+    gas_op2str : op2strtable = {$i a64att.inc}
+
+    function gas_regnum_search(const s:string):Tregister;
+    function gas_regname(r:Tregister):string;
+
+
+implementation
+
+    uses
+      cutils,verbose,rgbase;
+
+    const
+      gas_regname_table : TRegNameTable = (
+        {$i ra64std.inc}
+      );
+
+      gas_regname_index : array[tregisterindex] of tregisterindex = (
+        {$i ra64sri.inc}
+      );
+
+    function findreg_by_gasname(const s:string):tregisterindex;
+      var
+        i,p : tregisterindex;
+      begin
+        {Binary search.}
+        p:=0;
+        i:=regnumber_count_bsstart;
+        repeat
+          if (p+i<=high(tregisterindex)) and (gas_regname_table[gas_regname_index[p+i]]<=s) then
+            p:=p+i;
+          i:=i shr 1;
+        until i=0;
+        if gas_regname_table[gas_regname_index[p]]=s then
+          findreg_by_gasname:=gas_regname_index[p]
+        else
+          findreg_by_gasname:=0;
+      end;
+
+
+    function gas_regnum_search(const s:string):Tregister;
+      begin
+        result:=regnumber_table[findreg_by_gasname(s)];
+      end;
+
+
+    function gas_regname(r:Tregister):string;
+      var
+        p : tregisterindex;
+      begin
+        p:=findreg_by_number(r);
+        if p<>0 then
+          result:=gas_regname_table[p]
+        else
+          result:=generic_regname(r);
+      end;
+
+end.

+ 227 - 0
compiler/aarch64/ra64con.inc

@@ -0,0 +1,227 @@
+{ don't edit, this file is generated from a64reg.dat }
+NR_NO = tregister($00000000);
+NR_W0 = tregister($01040000);
+NR_X0 = tregister($01050000);
+NR_W1 = tregister($01040001);
+NR_X1 = tregister($01050001);
+NR_W2 = tregister($01040002);
+NR_X2 = tregister($01050002);
+NR_W3 = tregister($01040003);
+NR_X3 = tregister($01050003);
+NR_W4 = tregister($01040004);
+NR_X4 = tregister($01050004);
+NR_W5 = tregister($01040005);
+NR_X5 = tregister($01050005);
+NR_W6 = tregister($01040006);
+NR_X6 = tregister($01050006);
+NR_W7 = tregister($01040007);
+NR_X7 = tregister($01050007);
+NR_W8 = tregister($01040008);
+NR_X8 = tregister($01050008);
+NR_W9 = tregister($01040009);
+NR_X9 = tregister($01050009);
+NR_W10 = tregister($0104000A);
+NR_X10 = tregister($0105000A);
+NR_W11 = tregister($0104000B);
+NR_X11 = tregister($0105000B);
+NR_W12 = tregister($0104000C);
+NR_X12 = tregister($0105000C);
+NR_W13 = tregister($0104000D);
+NR_X13 = tregister($0105000D);
+NR_W14 = tregister($0104000E);
+NR_X14 = tregister($0105000E);
+NR_W15 = tregister($0104000F);
+NR_X15 = tregister($0105000F);
+NR_W16 = tregister($01040010);
+NR_X16 = tregister($01050010);
+NR_W17 = tregister($01040011);
+NR_X17 = tregister($01050011);
+NR_W18 = tregister($01040012);
+NR_X18 = tregister($01050012);
+NR_W19 = tregister($01040013);
+NR_X19 = tregister($01050013);
+NR_W20 = tregister($01040014);
+NR_X20 = tregister($01050014);
+NR_W21 = tregister($01040015);
+NR_X21 = tregister($01050015);
+NR_W22 = tregister($01040016);
+NR_X22 = tregister($01050016);
+NR_W23 = tregister($01040017);
+NR_X23 = tregister($01050017);
+NR_W24 = tregister($01040018);
+NR_X24 = tregister($01050018);
+NR_W25 = tregister($01040019);
+NR_X25 = tregister($01050019);
+NR_W26 = tregister($0104001A);
+NR_X26 = tregister($0105001A);
+NR_W27 = tregister($0104001B);
+NR_X27 = tregister($0105001B);
+NR_W28 = tregister($0104001C);
+NR_X28 = tregister($0105001C);
+NR_W29 = tregister($0104001D);
+NR_X29 = tregister($0105001D);
+NR_W30 = tregister($0104001E);
+NR_X30 = tregister($0105001E);
+NR_WZR = tregister($0104001F);
+NR_XZR = tregister($0105001F);
+NR_B0 = tregister($04010000);
+NR_H0 = tregister($04030000);
+NR_S0 = tregister($04090000);
+NR_D0 = tregister($040a0000);
+NR_Q0 = tregister($04050000);
+NR_B1 = tregister($04010001);
+NR_H1 = tregister($04030001);
+NR_S1 = tregister($04090001);
+NR_D1 = tregister($040a0001);
+NR_Q1 = tregister($04050001);
+NR_B2 = tregister($04010002);
+NR_H2 = tregister($04030002);
+NR_S2 = tregister($04090002);
+NR_D2 = tregister($040a0002);
+NR_Q2 = tregister($04050002);
+NR_B3 = tregister($04010003);
+NR_H3 = tregister($04030003);
+NR_S3 = tregister($04090003);
+NR_D3 = tregister($040a0003);
+NR_Q3 = tregister($04050003);
+NR_B4 = tregister($04010004);
+NR_H4 = tregister($04030004);
+NR_S4 = tregister($04090004);
+NR_D4 = tregister($040a0004);
+NR_Q4 = tregister($04050004);
+NR_B5 = tregister($04010005);
+NR_H5 = tregister($04030005);
+NR_S5 = tregister($04090005);
+NR_D5 = tregister($040a0005);
+NR_Q5 = tregister($04050005);
+NR_B6 = tregister($04010006);
+NR_H6 = tregister($04030006);
+NR_S6 = tregister($04090006);
+NR_D6 = tregister($040a0006);
+NR_Q6 = tregister($04050006);
+NR_B7 = tregister($04010007);
+NR_H7 = tregister($04030007);
+NR_S7 = tregister($04090007);
+NR_D7 = tregister($040a0007);
+NR_Q7 = tregister($04050007);
+NR_B8 = tregister($04010008);
+NR_H8 = tregister($04030008);
+NR_S8 = tregister($04090008);
+NR_D8 = tregister($040a0008);
+NR_Q8 = tregister($04050008);
+NR_B9 = tregister($04010009);
+NR_H9 = tregister($04030009);
+NR_S9 = tregister($04090009);
+NR_D9 = tregister($040a0009);
+NR_Q9 = tregister($04050009);
+NR_B10 = tregister($0401000A);
+NR_H10 = tregister($0403000A);
+NR_S10 = tregister($0409000A);
+NR_D10 = tregister($040a000A);
+NR_Q10 = tregister($0405000A);
+NR_B11 = tregister($0401000B);
+NR_H11 = tregister($0403000B);
+NR_S11 = tregister($0409000B);
+NR_D11 = tregister($040a000B);
+NR_Q11 = tregister($0405000B);
+NR_B12 = tregister($0401000C);
+NR_H12 = tregister($0403000C);
+NR_S12 = tregister($0409000C);
+NR_D12 = tregister($040a000C);
+NR_Q12 = tregister($0405000C);
+NR_B13 = tregister($0401000D);
+NR_H13 = tregister($0403000D);
+NR_S13 = tregister($0409000D);
+NR_D13 = tregister($040a000D);
+NR_Q13 = tregister($0405000D);
+NR_B14 = tregister($0401000E);
+NR_H14 = tregister($0403000E);
+NR_S14 = tregister($0409000E);
+NR_D14 = tregister($040a000E);
+NR_Q14 = tregister($0405000E);
+NR_B15 = tregister($0401000F);
+NR_H15 = tregister($0403000F);
+NR_S15 = tregister($0409000F);
+NR_D15 = tregister($040a000F);
+NR_Q15 = tregister($0405000F);
+NR_B16 = tregister($04010010);
+NR_H16 = tregister($04030010);
+NR_S16 = tregister($04090010);
+NR_D16 = tregister($040a0010);
+NR_Q16 = tregister($04050010);
+NR_B17 = tregister($04010011);
+NR_H17 = tregister($04030011);
+NR_S17 = tregister($04090011);
+NR_D17 = tregister($040a0011);
+NR_Q17 = tregister($04050011);
+NR_B18 = tregister($04010012);
+NR_H18 = tregister($04030012);
+NR_S18 = tregister($04090012);
+NR_D18 = tregister($040a0012);
+NR_Q18 = tregister($04050012);
+NR_B19 = tregister($04010013);
+NR_H19 = tregister($04030013);
+NR_S19 = tregister($04090013);
+NR_D19 = tregister($040a0013);
+NR_Q19 = tregister($04050013);
+NR_B20 = tregister($04010014);
+NR_H20 = tregister($04030014);
+NR_S20 = tregister($04090014);
+NR_D20 = tregister($040a0014);
+NR_Q20 = tregister($04050014);
+NR_B21 = tregister($04010015);
+NR_H21 = tregister($04030015);
+NR_S21 = tregister($04090015);
+NR_D21 = tregister($040a0015);
+NR_Q21 = tregister($04050015);
+NR_B22 = tregister($04010016);
+NR_H22 = tregister($04030016);
+NR_S22 = tregister($04090016);
+NR_D22 = tregister($040a0016);
+NR_Q22 = tregister($04050016);
+NR_B23 = tregister($04010017);
+NR_H23 = tregister($04030017);
+NR_S23 = tregister($04090017);
+NR_D23 = tregister($040a0017);
+NR_Q23 = tregister($04050017);
+NR_B24 = tregister($04010018);
+NR_H24 = tregister($04030018);
+NR_S24 = tregister($04090018);
+NR_D24 = tregister($040a0018);
+NR_Q24 = tregister($04050018);
+NR_B25 = tregister($04010019);
+NR_H25 = tregister($04030019);
+NR_S25 = tregister($04090019);
+NR_D25 = tregister($040a0019);
+NR_Q25 = tregister($04050019);
+NR_B26 = tregister($0401001A);
+NR_H26 = tregister($0403001A);
+NR_S26 = tregister($0409001A);
+NR_D26 = tregister($040a001A);
+NR_Q26 = tregister($0405001A);
+NR_B27 = tregister($0401001B);
+NR_H27 = tregister($0403001B);
+NR_S27 = tregister($0409001B);
+NR_D27 = tregister($040a001B);
+NR_Q27 = tregister($0405001B);
+NR_B28 = tregister($0401001C);
+NR_H28 = tregister($0403001C);
+NR_S28 = tregister($0409001C);
+NR_D28 = tregister($040a001C);
+NR_Q28 = tregister($0405001C);
+NR_B29 = tregister($0401001D);
+NR_H29 = tregister($0403001D);
+NR_S29 = tregister($0409001D);
+NR_D29 = tregister($040a001D);
+NR_Q29 = tregister($0405001D);
+NR_B30 = tregister($0401001E);
+NR_H30 = tregister($0403001E);
+NR_S30 = tregister($0409001E);
+NR_D30 = tregister($040a001E);
+NR_Q30 = tregister($0405001E);
+NR_B31 = tregister($0401001F);
+NR_H31 = tregister($0403001F);
+NR_S31 = tregister($0409001F);
+NR_D31 = tregister($040a001F);
+NR_Q31 = tregister($0405001F);
+NR_NZCV = tregister($05000000);

+ 227 - 0
compiler/aarch64/ra64dwa.inc

@@ -0,0 +1,227 @@
+{ don't edit, this file is generated from a64reg.dat }
+-1,
+0,
+0,
+1,
+1,
+2,
+2,
+3,
+3,
+4,
+4,
+5,
+5,
+6,
+6,
+7,
+7,
+8,
+8,
+9,
+9,
+10,
+10,
+11,
+11,
+12,
+12,
+13,
+13,
+14,
+14,
+15,
+15,
+16,
+16,
+17,
+17,
+18,
+18,
+19,
+19,
+20,
+20,
+21,
+21,
+22,
+22,
+23,
+23,
+24,
+24,
+25,
+25,
+26,
+26,
+27,
+27,
+28,
+28,
+29,
+29,
+30,
+30,
+31,
+31,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+1,
+1,
+2,
+2,
+2,
+2,
+2,
+3,
+3,
+3,
+3,
+3,
+4,
+4,
+4,
+4,
+4,
+5,
+5,
+5,
+5,
+5,
+6,
+6,
+6,
+6,
+6,
+7,
+7,
+7,
+7,
+7,
+8,
+8,
+8,
+8,
+8,
+9,
+9,
+9,
+9,
+9,
+10,
+10,
+10,
+10,
+10,
+11,
+11,
+11,
+11,
+11,
+12,
+12,
+12,
+12,
+12,
+13,
+13,
+13,
+13,
+13,
+14,
+14,
+14,
+14,
+14,
+15,
+15,
+15,
+15,
+15,
+16,
+16,
+16,
+16,
+16,
+17,
+17,
+17,
+17,
+17,
+18,
+18,
+18,
+18,
+18,
+19,
+19,
+19,
+19,
+19,
+20,
+20,
+20,
+20,
+20,
+21,
+21,
+21,
+21,
+21,
+22,
+22,
+22,
+22,
+22,
+23,
+23,
+23,
+23,
+23,
+24,
+24,
+24,
+24,
+24,
+25,
+25,
+25,
+25,
+25,
+26,
+26,
+26,
+26,
+26,
+27,
+27,
+27,
+27,
+27,
+28,
+28,
+28,
+28,
+28,
+29,
+29,
+29,
+29,
+29,
+30,
+30,
+30,
+30,
+30,
+31,
+31,
+31,
+31,
+31,
+0

+ 2 - 0
compiler/aarch64/ra64nor.inc

@@ -0,0 +1,2 @@
+{ don't edit, this file is generated from a64reg.dat }
+226

+ 227 - 0
compiler/aarch64/ra64num.inc

@@ -0,0 +1,227 @@
+{ don't edit, this file is generated from a64reg.dat }
+tregister($00000000),
+tregister($01040000),
+tregister($01050000),
+tregister($01040001),
+tregister($01050001),
+tregister($01040002),
+tregister($01050002),
+tregister($01040003),
+tregister($01050003),
+tregister($01040004),
+tregister($01050004),
+tregister($01040005),
+tregister($01050005),
+tregister($01040006),
+tregister($01050006),
+tregister($01040007),
+tregister($01050007),
+tregister($01040008),
+tregister($01050008),
+tregister($01040009),
+tregister($01050009),
+tregister($0104000A),
+tregister($0105000A),
+tregister($0104000B),
+tregister($0105000B),
+tregister($0104000C),
+tregister($0105000C),
+tregister($0104000D),
+tregister($0105000D),
+tregister($0104000E),
+tregister($0105000E),
+tregister($0104000F),
+tregister($0105000F),
+tregister($01040010),
+tregister($01050010),
+tregister($01040011),
+tregister($01050011),
+tregister($01040012),
+tregister($01050012),
+tregister($01040013),
+tregister($01050013),
+tregister($01040014),
+tregister($01050014),
+tregister($01040015),
+tregister($01050015),
+tregister($01040016),
+tregister($01050016),
+tregister($01040017),
+tregister($01050017),
+tregister($01040018),
+tregister($01050018),
+tregister($01040019),
+tregister($01050019),
+tregister($0104001A),
+tregister($0105001A),
+tregister($0104001B),
+tregister($0105001B),
+tregister($0104001C),
+tregister($0105001C),
+tregister($0104001D),
+tregister($0105001D),
+tregister($0104001E),
+tregister($0105001E),
+tregister($0104001F),
+tregister($0105001F),
+tregister($04010000),
+tregister($04030000),
+tregister($04090000),
+tregister($040a0000),
+tregister($04050000),
+tregister($04010001),
+tregister($04030001),
+tregister($04090001),
+tregister($040a0001),
+tregister($04050001),
+tregister($04010002),
+tregister($04030002),
+tregister($04090002),
+tregister($040a0002),
+tregister($04050002),
+tregister($04010003),
+tregister($04030003),
+tregister($04090003),
+tregister($040a0003),
+tregister($04050003),
+tregister($04010004),
+tregister($04030004),
+tregister($04090004),
+tregister($040a0004),
+tregister($04050004),
+tregister($04010005),
+tregister($04030005),
+tregister($04090005),
+tregister($040a0005),
+tregister($04050005),
+tregister($04010006),
+tregister($04030006),
+tregister($04090006),
+tregister($040a0006),
+tregister($04050006),
+tregister($04010007),
+tregister($04030007),
+tregister($04090007),
+tregister($040a0007),
+tregister($04050007),
+tregister($04010008),
+tregister($04030008),
+tregister($04090008),
+tregister($040a0008),
+tregister($04050008),
+tregister($04010009),
+tregister($04030009),
+tregister($04090009),
+tregister($040a0009),
+tregister($04050009),
+tregister($0401000A),
+tregister($0403000A),
+tregister($0409000A),
+tregister($040a000A),
+tregister($0405000A),
+tregister($0401000B),
+tregister($0403000B),
+tregister($0409000B),
+tregister($040a000B),
+tregister($0405000B),
+tregister($0401000C),
+tregister($0403000C),
+tregister($0409000C),
+tregister($040a000C),
+tregister($0405000C),
+tregister($0401000D),
+tregister($0403000D),
+tregister($0409000D),
+tregister($040a000D),
+tregister($0405000D),
+tregister($0401000E),
+tregister($0403000E),
+tregister($0409000E),
+tregister($040a000E),
+tregister($0405000E),
+tregister($0401000F),
+tregister($0403000F),
+tregister($0409000F),
+tregister($040a000F),
+tregister($0405000F),
+tregister($04010010),
+tregister($04030010),
+tregister($04090010),
+tregister($040a0010),
+tregister($04050010),
+tregister($04010011),
+tregister($04030011),
+tregister($04090011),
+tregister($040a0011),
+tregister($04050011),
+tregister($04010012),
+tregister($04030012),
+tregister($04090012),
+tregister($040a0012),
+tregister($04050012),
+tregister($04010013),
+tregister($04030013),
+tregister($04090013),
+tregister($040a0013),
+tregister($04050013),
+tregister($04010014),
+tregister($04030014),
+tregister($04090014),
+tregister($040a0014),
+tregister($04050014),
+tregister($04010015),
+tregister($04030015),
+tregister($04090015),
+tregister($040a0015),
+tregister($04050015),
+tregister($04010016),
+tregister($04030016),
+tregister($04090016),
+tregister($040a0016),
+tregister($04050016),
+tregister($04010017),
+tregister($04030017),
+tregister($04090017),
+tregister($040a0017),
+tregister($04050017),
+tregister($04010018),
+tregister($04030018),
+tregister($04090018),
+tregister($040a0018),
+tregister($04050018),
+tregister($04010019),
+tregister($04030019),
+tregister($04090019),
+tregister($040a0019),
+tregister($04050019),
+tregister($0401001A),
+tregister($0403001A),
+tregister($0409001A),
+tregister($040a001A),
+tregister($0405001A),
+tregister($0401001B),
+tregister($0403001B),
+tregister($0409001B),
+tregister($040a001B),
+tregister($0405001B),
+tregister($0401001C),
+tregister($0403001C),
+tregister($0409001C),
+tregister($040a001C),
+tregister($0405001C),
+tregister($0401001D),
+tregister($0403001D),
+tregister($0409001D),
+tregister($040a001D),
+tregister($0405001D),
+tregister($0401001E),
+tregister($0403001E),
+tregister($0409001E),
+tregister($040a001E),
+tregister($0405001E),
+tregister($0401001F),
+tregister($0403001F),
+tregister($0409001F),
+tregister($040a001F),
+tregister($0405001F),
+tregister($05000000)

+ 227 - 0
compiler/aarch64/ra64rni.inc

@@ -0,0 +1,227 @@
+{ don't edit, this file is generated from a64reg.dat }
+0,
+1,
+3,
+5,
+7,
+9,
+11,
+13,
+15,
+17,
+19,
+21,
+23,
+25,
+27,
+29,
+31,
+33,
+35,
+37,
+39,
+41,
+43,
+45,
+47,
+49,
+51,
+53,
+55,
+57,
+59,
+61,
+63,
+2,
+4,
+6,
+8,
+10,
+12,
+14,
+16,
+18,
+20,
+22,
+24,
+26,
+28,
+30,
+32,
+34,
+36,
+38,
+40,
+42,
+44,
+46,
+48,
+50,
+52,
+54,
+56,
+58,
+60,
+62,
+64,
+65,
+70,
+75,
+80,
+85,
+90,
+95,
+100,
+105,
+110,
+115,
+120,
+125,
+130,
+135,
+140,
+145,
+150,
+155,
+160,
+165,
+170,
+175,
+180,
+185,
+190,
+195,
+200,
+205,
+210,
+215,
+220,
+66,
+71,
+76,
+81,
+86,
+91,
+96,
+101,
+106,
+111,
+116,
+121,
+126,
+131,
+136,
+141,
+146,
+151,
+156,
+161,
+166,
+171,
+176,
+181,
+186,
+191,
+196,
+201,
+206,
+211,
+216,
+221,
+69,
+74,
+79,
+84,
+89,
+94,
+99,
+104,
+109,
+114,
+119,
+124,
+129,
+134,
+139,
+144,
+149,
+154,
+159,
+164,
+169,
+174,
+179,
+184,
+189,
+194,
+199,
+204,
+209,
+214,
+219,
+224,
+67,
+72,
+77,
+82,
+87,
+92,
+97,
+102,
+107,
+112,
+117,
+122,
+127,
+132,
+137,
+142,
+147,
+152,
+157,
+162,
+167,
+172,
+177,
+182,
+187,
+192,
+197,
+202,
+207,
+212,
+217,
+222,
+68,
+73,
+78,
+83,
+88,
+93,
+98,
+103,
+108,
+113,
+118,
+123,
+128,
+133,
+138,
+143,
+148,
+153,
+158,
+163,
+168,
+173,
+178,
+183,
+188,
+193,
+198,
+203,
+208,
+213,
+218,
+223,
+225

+ 227 - 0
compiler/aarch64/ra64sri.inc

@@ -0,0 +1,227 @@
+{ don't edit, this file is generated from a64reg.dat }
+0,
+65,
+70,
+115,
+120,
+125,
+130,
+135,
+140,
+145,
+150,
+155,
+160,
+75,
+165,
+170,
+175,
+180,
+185,
+190,
+195,
+200,
+205,
+210,
+80,
+215,
+220,
+85,
+90,
+95,
+100,
+105,
+110,
+68,
+73,
+118,
+123,
+128,
+133,
+138,
+143,
+148,
+153,
+158,
+163,
+78,
+168,
+173,
+178,
+183,
+188,
+193,
+198,
+203,
+208,
+213,
+83,
+218,
+223,
+88,
+93,
+98,
+103,
+108,
+113,
+66,
+71,
+116,
+121,
+126,
+131,
+136,
+141,
+146,
+151,
+156,
+161,
+76,
+166,
+171,
+176,
+181,
+186,
+191,
+196,
+201,
+206,
+211,
+81,
+216,
+221,
+86,
+91,
+96,
+101,
+106,
+111,
+225,
+69,
+74,
+119,
+124,
+129,
+134,
+139,
+144,
+149,
+154,
+159,
+164,
+79,
+169,
+174,
+179,
+184,
+189,
+194,
+199,
+204,
+209,
+214,
+84,
+219,
+224,
+89,
+94,
+99,
+104,
+109,
+114,
+67,
+72,
+117,
+122,
+127,
+132,
+137,
+142,
+147,
+152,
+157,
+162,
+77,
+167,
+172,
+177,
+182,
+187,
+192,
+197,
+202,
+207,
+212,
+82,
+217,
+222,
+87,
+92,
+97,
+102,
+107,
+112,
+1,
+3,
+21,
+23,
+25,
+27,
+29,
+31,
+33,
+35,
+37,
+39,
+5,
+41,
+43,
+45,
+47,
+49,
+51,
+53,
+55,
+57,
+59,
+7,
+61,
+9,
+11,
+13,
+15,
+17,
+19,
+63,
+2,
+4,
+22,
+24,
+26,
+28,
+30,
+32,
+34,
+36,
+38,
+40,
+6,
+42,
+44,
+46,
+48,
+50,
+52,
+54,
+56,
+58,
+60,
+8,
+62,
+10,
+12,
+14,
+16,
+18,
+20,
+64

+ 227 - 0
compiler/aarch64/ra64sta.inc

@@ -0,0 +1,227 @@
+{ don't edit, this file is generated from a64reg.dat }
+-1,
+0,
+0,
+1,
+1,
+2,
+2,
+3,
+3,
+4,
+4,
+5,
+5,
+6,
+6,
+7,
+7,
+8,
+8,
+9,
+9,
+10,
+10,
+11,
+11,
+12,
+12,
+13,
+13,
+14,
+14,
+15,
+15,
+16,
+16,
+17,
+17,
+18,
+18,
+19,
+19,
+20,
+20,
+21,
+21,
+22,
+22,
+23,
+23,
+24,
+24,
+25,
+25,
+26,
+26,
+27,
+27,
+28,
+28,
+29,
+29,
+30,
+30,
+31,
+31,
+0,
+0,
+0,
+0,
+0,
+1,
+1,
+1,
+1,
+1,
+2,
+2,
+2,
+2,
+2,
+3,
+3,
+3,
+3,
+3,
+4,
+4,
+4,
+4,
+4,
+5,
+5,
+5,
+5,
+5,
+6,
+6,
+6,
+6,
+6,
+7,
+7,
+7,
+7,
+7,
+8,
+8,
+8,
+8,
+8,
+9,
+9,
+9,
+9,
+9,
+10,
+10,
+10,
+10,
+10,
+11,
+11,
+11,
+11,
+11,
+12,
+12,
+12,
+12,
+12,
+13,
+13,
+13,
+13,
+13,
+14,
+14,
+14,
+14,
+14,
+15,
+15,
+15,
+15,
+15,
+16,
+16,
+16,
+16,
+16,
+17,
+17,
+17,
+17,
+17,
+18,
+18,
+18,
+18,
+18,
+19,
+19,
+19,
+19,
+19,
+20,
+20,
+20,
+20,
+20,
+21,
+21,
+21,
+21,
+21,
+22,
+22,
+22,
+22,
+22,
+23,
+23,
+23,
+23,
+23,
+24,
+24,
+24,
+24,
+24,
+25,
+25,
+25,
+25,
+25,
+26,
+26,
+26,
+26,
+26,
+27,
+27,
+27,
+27,
+27,
+28,
+28,
+28,
+28,
+28,
+29,
+29,
+29,
+29,
+29,
+30,
+30,
+30,
+30,
+30,
+31,
+31,
+31,
+31,
+31,
+0

+ 227 - 0
compiler/aarch64/ra64std.inc

@@ -0,0 +1,227 @@
+{ don't edit, this file is generated from a64reg.dat }
+'INVALID',
+'w0',
+'x0',
+'w1',
+'x1',
+'w2',
+'x2',
+'w3',
+'x3',
+'w4',
+'x4',
+'w5',
+'x5',
+'w6',
+'x6',
+'w7',
+'x7',
+'w8',
+'x8',
+'w9',
+'x9',
+'w10',
+'x10',
+'w11',
+'x11',
+'w12',
+'x12',
+'w13',
+'x13',
+'w14',
+'x14',
+'w15',
+'x15',
+'w16',
+'x16',
+'w17',
+'x17',
+'w18',
+'x18',
+'w19',
+'x19',
+'w20',
+'x20',
+'w21',
+'x21',
+'w22',
+'x22',
+'w23',
+'x23',
+'w24',
+'x24',
+'w25',
+'x25',
+'w26',
+'x26',
+'w27',
+'x27',
+'w28',
+'x28',
+'w29',
+'x29',
+'w30',
+'x30',
+'wzr',
+'xzr',
+'b0',
+'h0',
+'s0',
+'d0',
+'q0',
+'b1',
+'h1',
+'s1',
+'d1',
+'q1',
+'b2',
+'h2',
+'s2',
+'d2',
+'q2',
+'b3',
+'h3',
+'s3',
+'d3',
+'q3',
+'b4',
+'h4',
+'s4',
+'d4',
+'q4',
+'b5',
+'h5',
+'s5',
+'d5',
+'q5',
+'b6',
+'h6',
+'s6',
+'d6',
+'q6',
+'b7',
+'h7',
+'s7',
+'d7',
+'q7',
+'b8',
+'h8',
+'s8',
+'d8',
+'q8',
+'b9',
+'h9',
+'s9',
+'d9',
+'q9',
+'b10',
+'h10',
+'s10',
+'d10',
+'q10',
+'b11',
+'h11',
+'s11',
+'d11',
+'q11',
+'b12',
+'h12',
+'s12',
+'d12',
+'q12',
+'b13',
+'h13',
+'s13',
+'d13',
+'q13',
+'b14',
+'h14',
+'s14',
+'d14',
+'q14',
+'b15',
+'h15',
+'s15',
+'d15',
+'q15',
+'b16',
+'h16',
+'s16',
+'d16',
+'q16',
+'b17',
+'h17',
+'s17',
+'d17',
+'q17',
+'b18',
+'h18',
+'s18',
+'d18',
+'q18',
+'b19',
+'h19',
+'s19',
+'d19',
+'q19',
+'b20',
+'h20',
+'s20',
+'d20',
+'q20',
+'b21',
+'h21',
+'s21',
+'d21',
+'q21',
+'b22',
+'h22',
+'s22',
+'d22',
+'q22',
+'b23',
+'h23',
+'s23',
+'d23',
+'q23',
+'b24',
+'h24',
+'s24',
+'d24',
+'q24',
+'b25',
+'h25',
+'s25',
+'d25',
+'q25',
+'b26',
+'h26',
+'s26',
+'d26',
+'q26',
+'b27',
+'h27',
+'s27',
+'d27',
+'q27',
+'b28',
+'h28',
+'s28',
+'d28',
+'q28',
+'b29',
+'h29',
+'s29',
+'d29',
+'q29',
+'b30',
+'h30',
+'s30',
+'d30',
+'q30',
+'b31',
+'h31',
+'s31',
+'d31',
+'q31',
+'nzcv'

+ 227 - 0
compiler/aarch64/ra64sup.inc

@@ -0,0 +1,227 @@
+{ don't edit, this file is generated from a64reg.dat }
+RS_NO = $00;
+RS_W0 = $00;
+RS_X0 = $00;
+RS_W1 = $01;
+RS_X1 = $01;
+RS_W2 = $02;
+RS_X2 = $02;
+RS_W3 = $03;
+RS_X3 = $03;
+RS_W4 = $04;
+RS_X4 = $04;
+RS_W5 = $05;
+RS_X5 = $05;
+RS_W6 = $06;
+RS_X6 = $06;
+RS_W7 = $07;
+RS_X7 = $07;
+RS_W8 = $08;
+RS_X8 = $08;
+RS_W9 = $09;
+RS_X9 = $09;
+RS_W10 = $0A;
+RS_X10 = $0A;
+RS_W11 = $0B;
+RS_X11 = $0B;
+RS_W12 = $0C;
+RS_X12 = $0C;
+RS_W13 = $0D;
+RS_X13 = $0D;
+RS_W14 = $0E;
+RS_X14 = $0E;
+RS_W15 = $0F;
+RS_X15 = $0F;
+RS_W16 = $10;
+RS_X16 = $10;
+RS_W17 = $11;
+RS_X17 = $11;
+RS_W18 = $12;
+RS_X18 = $12;
+RS_W19 = $13;
+RS_X19 = $13;
+RS_W20 = $14;
+RS_X20 = $14;
+RS_W21 = $15;
+RS_X21 = $15;
+RS_W22 = $16;
+RS_X22 = $16;
+RS_W23 = $17;
+RS_X23 = $17;
+RS_W24 = $18;
+RS_X24 = $18;
+RS_W25 = $19;
+RS_X25 = $19;
+RS_W26 = $1A;
+RS_X26 = $1A;
+RS_W27 = $1B;
+RS_X27 = $1B;
+RS_W28 = $1C;
+RS_X28 = $1C;
+RS_W29 = $1D;
+RS_X29 = $1D;
+RS_W30 = $1E;
+RS_X30 = $1E;
+RS_WZR = $1F;
+RS_XZR = $1F;
+RS_B0 = $00;
+RS_H0 = $00;
+RS_S0 = $00;
+RS_D0 = $00;
+RS_Q0 = $00;
+RS_B1 = $01;
+RS_H1 = $01;
+RS_S1 = $01;
+RS_D1 = $01;
+RS_Q1 = $01;
+RS_B2 = $02;
+RS_H2 = $02;
+RS_S2 = $02;
+RS_D2 = $02;
+RS_Q2 = $02;
+RS_B3 = $03;
+RS_H3 = $03;
+RS_S3 = $03;
+RS_D3 = $03;
+RS_Q3 = $03;
+RS_B4 = $04;
+RS_H4 = $04;
+RS_S4 = $04;
+RS_D4 = $04;
+RS_Q4 = $04;
+RS_B5 = $05;
+RS_H5 = $05;
+RS_S5 = $05;
+RS_D5 = $05;
+RS_Q5 = $05;
+RS_B6 = $06;
+RS_H6 = $06;
+RS_S6 = $06;
+RS_D6 = $06;
+RS_Q6 = $06;
+RS_B7 = $07;
+RS_H7 = $07;
+RS_S7 = $07;
+RS_D7 = $07;
+RS_Q7 = $07;
+RS_B8 = $08;
+RS_H8 = $08;
+RS_S8 = $08;
+RS_D8 = $08;
+RS_Q8 = $08;
+RS_B9 = $09;
+RS_H9 = $09;
+RS_S9 = $09;
+RS_D9 = $09;
+RS_Q9 = $09;
+RS_B10 = $0A;
+RS_H10 = $0A;
+RS_S10 = $0A;
+RS_D10 = $0A;
+RS_Q10 = $0A;
+RS_B11 = $0B;
+RS_H11 = $0B;
+RS_S11 = $0B;
+RS_D11 = $0B;
+RS_Q11 = $0B;
+RS_B12 = $0C;
+RS_H12 = $0C;
+RS_S12 = $0C;
+RS_D12 = $0C;
+RS_Q12 = $0C;
+RS_B13 = $0D;
+RS_H13 = $0D;
+RS_S13 = $0D;
+RS_D13 = $0D;
+RS_Q13 = $0D;
+RS_B14 = $0E;
+RS_H14 = $0E;
+RS_S14 = $0E;
+RS_D14 = $0E;
+RS_Q14 = $0E;
+RS_B15 = $0F;
+RS_H15 = $0F;
+RS_S15 = $0F;
+RS_D15 = $0F;
+RS_Q15 = $0F;
+RS_B16 = $10;
+RS_H16 = $10;
+RS_S16 = $10;
+RS_D16 = $10;
+RS_Q16 = $10;
+RS_B17 = $11;
+RS_H17 = $11;
+RS_S17 = $11;
+RS_D17 = $11;
+RS_Q17 = $11;
+RS_B18 = $12;
+RS_H18 = $12;
+RS_S18 = $12;
+RS_D18 = $12;
+RS_Q18 = $12;
+RS_B19 = $13;
+RS_H19 = $13;
+RS_S19 = $13;
+RS_D19 = $13;
+RS_Q19 = $13;
+RS_B20 = $14;
+RS_H20 = $14;
+RS_S20 = $14;
+RS_D20 = $14;
+RS_Q20 = $14;
+RS_B21 = $15;
+RS_H21 = $15;
+RS_S21 = $15;
+RS_D21 = $15;
+RS_Q21 = $15;
+RS_B22 = $16;
+RS_H22 = $16;
+RS_S22 = $16;
+RS_D22 = $16;
+RS_Q22 = $16;
+RS_B23 = $17;
+RS_H23 = $17;
+RS_S23 = $17;
+RS_D23 = $17;
+RS_Q23 = $17;
+RS_B24 = $18;
+RS_H24 = $18;
+RS_S24 = $18;
+RS_D24 = $18;
+RS_Q24 = $18;
+RS_B25 = $19;
+RS_H25 = $19;
+RS_S25 = $19;
+RS_D25 = $19;
+RS_Q25 = $19;
+RS_B26 = $1A;
+RS_H26 = $1A;
+RS_S26 = $1A;
+RS_D26 = $1A;
+RS_Q26 = $1A;
+RS_B27 = $1B;
+RS_H27 = $1B;
+RS_S27 = $1B;
+RS_D27 = $1B;
+RS_Q27 = $1B;
+RS_B28 = $1C;
+RS_H28 = $1C;
+RS_S28 = $1C;
+RS_D28 = $1C;
+RS_Q28 = $1C;
+RS_B29 = $1D;
+RS_H29 = $1D;
+RS_S29 = $1D;
+RS_D29 = $1D;
+RS_Q29 = $1D;
+RS_B30 = $1E;
+RS_H30 = $1E;
+RS_S30 = $1E;
+RS_D30 = $1E;
+RS_Q30 = $1E;
+RS_B31 = $1F;
+RS_H31 = $1F;
+RS_S31 = $1F;
+RS_D31 = $1F;
+RS_Q31 = $1F;
+RS_NZCV = $00;

+ 10 - 8
compiler/aasmbase.pas

@@ -195,13 +195,15 @@ interface
 
     function ReplaceForbiddenAsmSymbolChars(const s: string): string;
 
-	{ dummy default noop callback }
-	procedure default_global_used; 
-  type
-	TGlobalUsedProcedure = procedure;
-	{ Procedure variable to allow for special handling of 
-	  the occurence of use of a global variable,
-	  used by PIC code generation to request GOT loading }
+    { dummy default noop callback }
+    procedure default_global_used;
+
+    type
+      { Procedure variable to allow for special handling of
+        the occurence of use of a global variable,
+        used by PIC code generation to request GOT loading }
+      TGlobalUsedProcedure = procedure;
+
   const
     global_used : TGlobalUsedProcedure = @default_global_used;
 
@@ -432,7 +434,7 @@ implementation
         is_set:=false;
         { write it always }
         increfs;
-		global_used;
+        global_used;
       end;
 
 

+ 8 - 2
compiler/aasmdata.pas

@@ -89,7 +89,8 @@ interface
          sp_objcvartypes,
          sp_objcprotocolrefs,
          sp_varsets,
-         sp_floats
+         sp_floats,
+         sp_guids
       );
       
     const
@@ -121,6 +122,7 @@ interface
     type
       TAsmList = class(tlinkedlist)
          constructor create;
+         constructor create_without_marker;
          function  empty : boolean;
          function  getlasttaifilepos : pfileposinfo;
       end;
@@ -287,6 +289,10 @@ implementation
         insert(tai_marker.create(mark_BlockStart));
       end;
 
+    constructor TAsmList.create_without_marker;
+      begin
+        inherited create;
+      end;
 
     function TAsmList.empty : boolean;
       begin
@@ -482,7 +488,7 @@ implementation
 
     procedure TAsmData.getlabel(out l : TAsmLabel;alt:TAsmLabeltype);
       begin
-        if (target_info.system in (systems_linux + systems_bsd)) and
+        if (target_info.system in (systems_linux + systems_bsd + systems_android)) and
            { the next condition was
              (cs_create_smart in current_settings.moduleswitches) and
              but if we create_smartlink_sections, this is useless }

+ 209 - 32
compiler/aasmtai.pas

@@ -85,7 +85,10 @@ interface
 {$endif m68k}
 {$ifdef arm}
           ait_thumb_func,
+          ait_thumb_set,
 {$endif arm}
+          ait_set,
+          ait_weak,
           { used to split into tiny assembler files }
           ait_cutobject,
           ait_regalloc,
@@ -94,11 +97,13 @@ interface
           ait_marker,
           { used to describe a new location of a variable }
           ait_varloc,
-          { SEH directives used in ARM,MIPS and x86_64 COFF targets }
-          ait_seh_directive,
+{$ifdef JVM}
           { JVM only }
           ait_jvar,    { debug information for a local variable }
-          ait_jcatch   { exception catch clause }
+          ait_jcatch,  { exception catch clause }
+{$endif JVM}
+          { SEH directives used in ARM,MIPS and x86_64 COFF targets }
+          ait_seh_directive
           );
 
         taiconst_type = (
@@ -129,21 +134,36 @@ interface
           aitconst_darwin_dwarf_delta64,
           aitconst_darwin_dwarf_delta32,
           { ARM Thumb-2 only }
-          aitconst_half16bit { used for table jumps. The actual value is the 16bit value shifted left once }
+          aitconst_half16bit, { used for table jumps. The actual value is the 16bit value shifted left once }
+          { for use by dwarf debugger information }
+          aitconst_16bit_unaligned,
+          aitconst_32bit_unaligned,
+          aitconst_64bit_unaligned,
+          { i8086 far pointer; emits: 'DW symbol, SEG symbol' }
+          aitconst_farptr
         );
 
     const
-{$ifdef cpu64bitaddr}
+{$if defined(cpu64bitaddr)}
        aitconst_ptr = aitconst_64bit;
-{$else cpu64bitaddr}
+       aitconst_ptr_unaligned = aitconst_64bit_unaligned;
+{$elseif defined(cpu32bitaddr)}
        aitconst_ptr = aitconst_32bit;
-{$endif cpu64bitaddr}
+       aitconst_ptr_unaligned = aitconst_32bit_unaligned;
+{$elseif defined(cpu16bitaddr)}
+       aitconst_ptr = aitconst_16bit;
+       aitconst_ptr_unaligned = aitconst_16bit_unaligned;
+{$endif}
 
-{$ifdef cpu64bitalu}
+{$if defined(cpu64bitalu)}
        aitconst_aint = aitconst_64bit;
-{$else cpu64bitaddr}
+{$elseif defined(cpu32bitalu)}
        aitconst_aint = aitconst_32bit;
-{$endif cpu64bitaddr}
+{$elseif defined(cpu16bitalu)}
+       aitconst_aint = aitconst_16bit;
+{$elseif defined(cpu8bitalu)}
+       aitconst_aint = aitconst_8bit;
+{$endif}
 
        taitypestr : array[taitype] of string[24] = (
           '<none>',
@@ -181,15 +201,20 @@ interface
 {$endif m68k}
 {$ifdef arm}
           'thumb_func',
+          'thumb_set',
 {$endif arm}
+          'set',
+          'weak',
           'cut',
           'regalloc',
           'tempalloc',
           'marker',
           'varloc',
-          'seh_directive',
+{$ifdef JVM}
           'jvar',
-          'jcatch'
+          'jcatch',
+{$endif JVM}
+          'seh_directive'
           );
 
     type
@@ -198,10 +223,13 @@ interface
 {$ifdef arm}
        { ARM only }
        ,top_regset
-       ,top_shifterop
        ,top_conditioncode
        ,top_modeflags
+       ,top_specialreg
 {$endif arm}
+{$if defined(arm) or defined(aarch64)}
+       ,top_shifterop
+{$endif defined(arm) or defined(aarch64)}
 {$ifdef m68k}
        { m68k only }
        ,top_regset
@@ -241,11 +269,14 @@ interface
           { local varsym that will be inserted in pass_generate_code }
           top_local  : (localoper:plocaloper);
       {$ifdef arm}
-          top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister);
-          top_shifterop : (shifterop : pshifterop);
+          top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister; usermode: boolean);
           top_conditioncode : (cc : TAsmCond);
           top_modeflags : (modeflags : tcpumodeflags);
+          top_specialreg : (specialreg:tregister; specialflags:tspecialregflags);
       {$endif arm}
+      {$if defined(arm) or defined(aarch64)}
+          top_shifterop : (shifterop : pshifterop);
+      {$endif defined(arm) or defined(aarch64)}
       {$ifdef m68k}
           top_regset : (regset:^tcpuregisterset);
       {$endif m68k}
@@ -265,10 +296,13 @@ interface
         a new ait type!                                                              }
       SkipInstr = [ait_comment, ait_symbol,ait_section
                    ,ait_stab, ait_function_name, ait_force_line
-                   ,ait_regalloc, ait_tempalloc, ait_symbol_end 
-				   ,ait_ent, ait_ent_end, ait_directive
-                   ,ait_varloc,ait_seh_directive
-                   ,ait_jvar, ait_jcatch];
+                   ,ait_regalloc, ait_tempalloc, ait_symbol_end
+                   ,ait_ent, ait_ent_end, ait_directive
+                   ,ait_varloc,
+{$ifdef JVM}
+                   ait_jvar, ait_jcatch,
+{$endif JVM}
+                   ait_seh_directive];
 
       { ait_* types which do not have line information (and hence which are of type
         tai, otherwise, they are of type tailineinfo }
@@ -277,14 +311,18 @@ interface
                      ait_stab,ait_function_name,
                      ait_cutobject,ait_marker,ait_varloc,ait_align,ait_section,ait_comment,
                      ait_const,ait_directive,
-					 ait_ent, ait_ent_end,
+                     ait_ent, ait_ent_end,
 {$ifdef arm}
                      ait_thumb_func,
+                     ait_thumb_set,
 {$endif arm}
+                     ait_set,ait_weak,
                      ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit,ait_real_128bit,
                      ait_symbol,
-                     ait_seh_directive,
-                     ait_jvar,ait_jcatch
+{$ifdef JVM}
+                     ait_jvar, ait_jcatch,
+{$endif JVM}
+                     ait_seh_directive
                     ];
 
 
@@ -452,6 +490,9 @@ interface
           { set to true when the label has been moved by insertpcrelativedata to the correct location
             so one label can be used multiple times }
           moved     : boolean;
+          { true, if a label has been already inserted, this is important for arm thumb where no negative
+            pc relative offsets are allowed }
+          inserted  : boolean;
 {$endif arm}
           constructor Create(_labsym : tasmlabel);
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
@@ -518,6 +559,9 @@ interface
           constructor Create_64bit(_value : int64);
           constructor Create_32bit(_value : longint);
           constructor Create_16bit(_value : word);
+          constructor Create_64bit_unaligned(_value : int64);
+          constructor Create_32bit_unaligned(_value : longint);
+          constructor Create_16bit_unaligned(_value : word);
           constructor Create_8bit(_value : byte);
           constructor Create_char(size: integer; _value: dword);
           constructor Create_sleb128bit(_value : int64);
@@ -738,6 +782,8 @@ interface
         tai_align_class = class of tai_align_abstract;
 
         tai_varloc = class(tai)
+           oldlocation,
+           oldlocationhi,
            newlocation,
            newlocationhi : tregister;
            varsym : tsym;
@@ -777,6 +823,7 @@ interface
         end;
         tai_seh_directive_class=class of tai_seh_directive;
 
+{$ifdef JVM}
         { JVM variable live range description }
         tai_jvar = class(tai)
           stackslot: longint;
@@ -801,6 +848,30 @@ interface
           procedure ppuwrite(ppufile:tcompilerppufile);override;
         end;
         tai_jcatch_class = class of tai_jcatch;
+{$endif JVM}
+
+        tai_set = class(tai)
+          sym,
+          value: pshortstring;
+          constructor create(const asym, avalue: string);
+          destructor destroy;override;
+          constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
+          procedure ppuwrite(ppufile:tcompilerppufile);override;
+        end;
+
+{$ifdef arm}
+        tai_thumb_set = class(tai_set)
+          constructor create(const asym, avalue: string);
+        end;
+{$endif arm}
+
+        tai_weak = class(tai)
+          sym: pshortstring;
+          constructor create(const asym: string);
+          destructor destroy;override;
+          constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
+          procedure ppuwrite(ppufile:tcompilerppufile);override;
+        end;
 
     var
       { array with all class types for tais }
@@ -914,6 +985,69 @@ implementation
       end;
 
 
+    constructor tai_weak.create(const asym: string);
+      begin
+        inherited create;
+        typ:=ait_weak;
+        sym:=stringdup(asym);
+      end;
+
+    destructor tai_weak.destroy;
+      begin
+        stringdispose(sym);
+        inherited destroy;
+      end;
+
+    constructor tai_weak.ppuload(t: taitype; ppufile: tcompilerppufile);
+      begin
+        inherited ppuload(t,ppufile);
+        sym:=stringdup(ppufile.getstring);
+      end;
+
+    procedure tai_weak.ppuwrite(ppufile: tcompilerppufile);
+      begin
+        inherited ppuwrite(ppufile);
+        ppufile.putstring(sym^);
+      end;
+
+{$ifdef arm}
+    constructor tai_thumb_set.create(const asym, avalue: string);
+      begin
+        inherited create(asym, avalue);
+        typ:=ait_thumb_set;
+      end;
+{$endif arm}
+
+    constructor tai_set.create(const asym, avalue: string);
+      begin
+        inherited create;
+        typ:=ait_set;
+        sym:=stringdup(asym);
+        value:=stringdup(avalue);
+      end;
+
+    destructor tai_set.destroy;
+      begin
+        stringdispose(sym);
+        stringdispose(value);
+        inherited destroy;
+      end;
+
+    constructor tai_set.ppuload(t: taitype; ppufile: tcompilerppufile);
+      begin
+        inherited ppuload(t,ppufile);
+        sym:=stringdup(ppufile.getstring);
+        value:=stringdup(ppufile.getstring);
+      end;
+
+    procedure tai_set.ppuwrite(ppufile: tcompilerppufile);
+      begin
+        inherited ppuwrite(ppufile);
+        ppufile.putstring(sym^);
+        ppufile.putstring(value^);
+      end;
+
+
     constructor tai_varloc.create(sym: tsym; loc: tregister);
       begin
         inherited Create;
@@ -921,6 +1055,7 @@ implementation
         newlocation:=loc;
         newlocationhi:=NR_NO;
         varsym:=sym;
+        oldlocationhi:=NR_NO;
       end;
 
 
@@ -1362,6 +1497,38 @@ implementation
          endsym:=nil;
       end;
 
+    constructor tai_const.Create_64bit_unaligned(_value : int64);
+      begin
+         inherited Create;
+         typ:=ait_const;
+         consttype:=aitconst_64bit_unaligned;
+         value:=_value;
+         sym:=nil;
+         endsym:=nil;
+      end;
+
+
+    constructor tai_const.Create_32bit_unaligned(_value : longint);
+      begin
+         inherited Create;
+         typ:=ait_const;
+         consttype:=aitconst_32bit_unaligned;
+         value:=_value;
+         sym:=nil;
+         endsym:=nil;
+      end;
+
+
+    constructor tai_const.Create_16bit_unaligned(_value : word);
+      begin
+         inherited Create;
+         typ:=ait_const;
+         consttype:=aitconst_16bit_unaligned;
+         value:=_value;
+         sym:=nil;
+         endsym:=nil;
+      end;
+
 
     constructor tai_const.Create_8bit(_value : byte);
       begin
@@ -1463,7 +1630,12 @@ implementation
       begin
          inherited Create;
          typ:=ait_const;
-         consttype:=aitconst_ptr;
+{$ifdef i8086}
+         if current_settings.x86memorymodel in x86_far_code_models then
+           consttype:=aitconst_farptr
+         else
+{$endif i8086}
+           consttype:=aitconst_ptr;
          { sym is allowed to be nil, this is used to write nil pointers }
          sym:=_sym;
          endsym:=nil;
@@ -1528,7 +1700,8 @@ implementation
       begin
         getcopy:=inherited getcopy;
         { we need to increase the reference number }
-        sym.increfs;
+        if assigned(sym) then
+          sym.increfs;
         if assigned(endsym) then
           endsym.increfs;
       end;
@@ -1539,11 +1712,13 @@ implementation
         case consttype of
           aitconst_8bit :
             result:=1;
-          aitconst_16bit :
+          aitconst_16bit,aitconst_16bit_unaligned :
             result:=2;
-          aitconst_32bit,aitconst_darwin_dwarf_delta32:
+          aitconst_32bit,aitconst_darwin_dwarf_delta32,
+	  aitconst_32bit_unaligned:
             result:=4;
-          aitconst_64bit,aitconst_darwin_dwarf_delta64:
+          aitconst_64bit,aitconst_darwin_dwarf_delta64,
+	  aitconst_64bit_unaligned:
             result:=8;
           aitconst_secrel32_symbol,
           aitconst_rva_symbol :
@@ -1727,7 +1902,8 @@ implementation
           typ:=ait_string;
           len:=length(_str);
           getmem(str,len+1);
-          strpcopy(str,_str);
+          move(_str[1],str^,len);
+          str[len]:=#0;
        end;
 
 
@@ -1780,7 +1956,7 @@ implementation
                                TAI_LABEL
  ****************************************************************************}
 
-    constructor tai_label.create(_labsym : tasmlabel);
+        constructor tai_label.Create(_labsym : tasmlabel);
       begin
         inherited Create;
         typ:=ait_label;
@@ -1811,7 +1987,6 @@ implementation
         labsym.is_set:=true;
       end;
 
-
 {****************************************************************************
           tai_comment  comment to be inserted in the assembler file
  ****************************************************************************}
@@ -2416,14 +2591,14 @@ implementation
         { When the generic RA is used this needs to be overridden, we don't use
           virtual;abstract; to prevent a lot of warnings of unimplemented abstract methods
           when tai_cpu is created (PFV) }
-        internalerror(200404091);
+        internalerror(2004040901);
         result:=false;
       end;
 
 
     function tai_cpu_abstract.spilling_get_operation_type(opnr: longint): topertype;
       begin
-        internalerror(200404091);
+        internalerror(2004040902);
         result:=operand_readwrite;
       end;
 
@@ -2775,6 +2950,7 @@ implementation
       begin
       end;
 
+{$ifdef JVM}
 
 {****************************************************************************
                               tai_jvar
@@ -2865,6 +3041,7 @@ implementation
         ppufile.putasmsymbol(handlerlab);
       end;
 
+{$endif JVM}
 
 begin
 {$push}{$warnings off}

+ 141 - 17
compiler/aggas.pas

@@ -53,6 +53,7 @@ interface
         procedure WriteWeakSymbolDef(s: tasmsymbol); virtual;
         procedure WriteAixStringConst(hp: tai_string);
         procedure WriteAixIntConst(hp: tai_const);
+        procedure WriteUnalignedIntConst(hp: tai_const);
         procedure WriteDirectiveName(dir: TAsmDirective); virtual;
        public
         function MakeCmdLine: TCmdStr; override;
@@ -104,9 +105,12 @@ implementation
       SysUtils,
       cutils,cfileutl,systems,
       fmodule,verbose,
-{$ifdef TEST_WIN64_SEH}
+{$ifndef DISABLE_WIN64_SEH}
       itcpugas,
-{$endif TEST_WIN64_SEH}
+{$endif DISABLE_WIN64_SEH}
+{$ifdef m68k}
+      cpuinfo,aasmcpu,
+{$endif m68k}
       cpubase;
 
     const
@@ -199,12 +203,38 @@ implementation
 
 
     const
-      ait_const2str : array[aitconst_128bit..aitconst_half16bit] of string[20]=(
+      ait_const2str : array[aitconst_128bit..aitconst_64bit_unaligned] of string[20]=(
         #9'.fixme128'#9,#9'.quad'#9,#9'.long'#9,#9'.short'#9,#9'.byte'#9,
         #9'.sleb128'#9,#9'.uleb128'#9,
-        #9'.rva'#9,#9'.secrel32'#9,#9'.quad'#9,#9'.long'#9,#9'.short'#9
+        #9'.rva'#9,#9'.secrel32'#9,#9'.quad'#9,#9'.long'#9,#9'.short'#9,
+        #9'.short'#9,#9'.long'#9,#9'.quad'#9
       );
 
+      ait_unaligned_consts = [aitconst_16bit_unaligned..aitconst_64bit_unaligned];
+
+      { Sparc type of unaligned pseudo-instructions }
+      use_ua_sparc_systems = [system_sparc_linux];
+      ait_ua_sparc_const2str : array[aitconst_16bit_unaligned..aitconst_64bit_unaligned]
+        of string[20]=(
+          #9'.uahalf'#9,#9'.uaword'#9,#9'.uaxword'#9
+        );
+
+      { Alpha type of unaligned pseudo-instructions }
+      use_ua_alpha_systems = [system_alpha_linux];
+      ait_ua_alpha_const2str : array[aitconst_16bit_unaligned..aitconst_64bit_unaligned]
+        of string[20]=(
+          #9'.uword'#9,#9'.ulong'#9,#9'.uquad'#9
+        );
+
+      { Generic unaligned pseudo-instructions, seems ELF specific }
+      use_ua_elf_systems = [system_mipsel_linux,system_mipseb_linux];
+      ait_ua_elf_const2str : array[aitconst_16bit_unaligned..aitconst_64bit_unaligned]
+        of string[20]=(
+          #9'.2byte'#9,#9'.4byte'#9,#9'.8byte'#9
+        );
+
+
+
 {****************************************************************************}
 {                          GNU Assembler writer                              }
 {****************************************************************************}
@@ -491,8 +521,7 @@ implementation
         case target_info.system of
          system_i386_OS2,
          system_i386_EMX,
-         system_m68k_amiga,  { amiga has old GNU AS (2.14), which blews up from .section (KB) }
-         system_m68k_linux: ;
+         system_m68k_amiga: ; { amiga has old GNU AS (2.14), which blews up from .section (KB) }
          system_powerpc_darwin,
          system_i386_darwin,
          system_i386_iphonesim,
@@ -610,15 +639,45 @@ implementation
         end;
 
 
-      procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint);
+      procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint;lasthp:tai);
         var
           i: longint;
+{$ifdef m68k}
+          instr : string;
+{$endif}
         begin
           last_align:=alignment;
           if alignment>1 then
             begin
               if not(target_info.system in (systems_darwin+systems_aix)) then
                 begin
+{$ifdef m68k}
+                  if assigned(lasthp) and
+                      (
+                        (lasthp.typ=ait_instruction) and
+                        (taicpu(lasthp).opcode<>A_JMP)
+                      ) or
+                      (
+                        (lasthp.typ=ait_label)
+                      ) then
+                    begin
+                      if ispowerof2(alignment,i) then
+                        begin
+                          { the Coldfire manual suggests the TBF instruction for
+                            alignments, but somehow QEMU does not interpret that
+                            correctly... }
+                          {if current_settings.cputype=cpu_coldfire then
+                            instr:='0x51fc'
+                          else}
+                            instr:='0x4e71';
+                          AsmWrite(#9'.balignw '+tostr(alignment)+','+instr);
+                        end
+                      else
+                        internalerror(2012102101);
+                    end
+                  else
+                    begin
+{$endif m68k}
                   AsmWrite(#9'.balign '+tostr(alignment));
                   if use_op then
                     AsmWrite(','+tostr(fillop))
@@ -627,6 +686,9 @@ implementation
                   else if LastSecType=sec_code then
                     AsmWrite(',0x90');
 {$endif x86}
+{$ifdef m68k}
+                    end;
+{$endif m68k}
                 end
               else
                 begin
@@ -642,6 +704,7 @@ implementation
 
     var
       ch       : char;
+      lasthp,
       hp       : tai;
       constdef : taiconst_type;
       s,t      : string;
@@ -669,6 +732,7 @@ implementation
       do_line:=(cs_asm_source in current_settings.globalswitches) or
                ((cs_lineinfo in current_settings.moduleswitches)
                  and (p=current_asmdata.asmlists[al_procedures]));
+      lasthp:=nil;
       hp:=tai(p.first);
       while assigned(hp) do
        begin
@@ -717,7 +781,7 @@ implementation
 
            ait_align :
              begin
-               doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align);
+               doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align,lasthp);
              end;
 
            ait_section :
@@ -783,9 +847,9 @@ implementation
                      begin
                        asmwrite(#9'.lcomm ');
                        asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
-                       asmwrite(',_data.bss_[RW],');
+                       asmwrite(',');
                        asmwrite(tostr(tai_datablock(hp).size)+',');
-                       asmwriteln(tostr(last_align));
+                       asmwrite('_data.bss_');
                      end;
                  end
                else
@@ -831,7 +895,7 @@ implementation
                            else
                              asmwriteln(Tai_datablock(hp).sym.name);
                          end;
-                       if (target_info.system <> system_arm_linux) then
+                       if ((target_info.system <> system_arm_linux) and (target_info.system <> system_arm_android)) then
                          sepChar := '@'
                        else
                          sepChar := '%';
@@ -905,7 +969,10 @@ implementation
                  aitconst_secrel32_symbol,
                  aitconst_darwin_dwarf_delta32,
                  aitconst_darwin_dwarf_delta64,
-                 aitconst_half16bit:
+                 aitconst_half16bit,
+                 aitconst_16bit_unaligned,
+                 aitconst_32bit_unaligned,
+                 aitconst_64bit_unaligned:
                    begin
                      { the AIX assembler (and for compatibility, the GNU
                        assembler when targeting AIX) automatically aligns
@@ -932,7 +999,16 @@ implementation
                        end
                      else
                        begin
-                         if not(target_info.system in systems_aix) or
+                         if (constdef in ait_unaligned_consts) and
+                            (target_info.system in use_ua_sparc_systems) then
+                           AsmWrite(ait_ua_sparc_const2str[constdef])
+                         else if (constdef in ait_unaligned_consts) and
+                            (target_info.system in use_ua_alpha_systems) then
+                           AsmWrite(ait_ua_alpha_const2str[constdef])
+                         else if (constdef in ait_unaligned_consts) and
+                                 (target_info.system in use_ua_elf_systems) then
+                           AsmWrite(ait_ua_elf_const2str[constdef])
+                          else if not(target_info.system in systems_aix) or
                             (constdef<>aitconst_64bit) then
                            AsmWrite(ait_const2str[constdef])
                          else
@@ -1220,7 +1296,7 @@ implementation
                  end
                else
                  begin
-                   if (target_info.system <> system_arm_linux) then
+                   if ((target_info.system <> system_arm_linux) and (target_info.system <> system_arm_android)) then
                      sepChar := '@'
                    else
                      sepChar := '#';
@@ -1248,7 +1324,19 @@ implementation
              begin
                AsmWriteLn(#9'.thumb_func');
              end;
+           ait_thumb_set:
+             begin
+               AsmWriteLn(#9'.thumb_set '+tai_thumb_set(hp).sym^+', '+tai_thumb_set(hp).value^);
+             end;
 {$endif arm}
+           ait_set:
+             begin
+               AsmWriteLn(#9'.set '+tai_set(hp).sym^+', '+tai_set(hp).value^);
+             end;
+           ait_weak:
+             begin
+               AsmWriteLn(#9'.weak '+tai_weak(hp).sym^);
+             end;
            ait_ent:
              begin
                AsmWrite(#9'.ent'#9);
@@ -1350,7 +1438,7 @@ implementation
 
            ait_seh_directive :
              begin
-{$ifdef TEST_WIN64_SEH}
+{$ifndef DISABLE_WIN64_SEH}
                AsmWrite(sehdirectivestr[tai_seh_directive(hp).kind]);
                case tai_seh_directive(hp).datatype of
                  sd_none:;
@@ -1371,7 +1459,7 @@ implementation
                      tostr(tai_seh_directive(hp).data.offset));
                end;
                AsmLn;
-{$endif TEST_WIN64_SEH}
+{$endif DISABLE_WIN64_SEH}
              end;
            ait_varloc:
              begin
@@ -1386,6 +1474,7 @@ implementation
            else
              internalerror(2006012201);
          end;
+         lasthp:=hp;
          hp:=tai(hp.next);
        end;
     end;
@@ -1519,6 +1608,41 @@ implementation
         end;
       end;
 
+    procedure TGNUAssembler.WriteUnalignedIntConst(hp: tai_const);
+      var
+        pos, size: longint;
+      begin
+        size:=tai_const(hp).size;
+        AsmWrite(#9'.byte'#9);
+        if target_info.endian=endian_big then
+          begin
+            pos:=size-1;
+            while pos>=0 do
+              begin
+                AsmWrite(tostr((tai_const(hp).value shr (pos*8)) and $ff));
+                dec(pos);
+                if pos>=0 then
+                  AsmWrite(', ')
+                else
+                  AsmLn;
+              end;
+          end
+        else
+          begin
+            pos:=0;
+            while pos<size do
+              begin
+                AsmWriteln(tostr((tai_const(hp).value shr (pos*8)) and $ff));
+                inc(pos);
+                if pos<=size then
+                  AsmWrite(', ')
+                else
+                  AsmLn;
+              end;
+          end;
+        AsmLn;
+      end;
+
 
     procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
     begin
@@ -1569,7 +1693,7 @@ implementation
         AsmWriteLn(#9'.subsections_via_symbols');
 
       { "no executable stack" marker for Linux }
-      if (target_info.system in systems_linux) and
+      if (target_info.system in (systems_linux + systems_android)) and
          not(cs_executable_stack in current_settings.moduleswitches) then
         begin
           AsmWriteLn('.section .note.GNU-stack,"",%progbits');

+ 1 - 0
compiler/agjasmin.pas

@@ -1228,6 +1228,7 @@ implementation
          flags : [];
          labelprefix : 'L';
          comment : ' ; ';
+         dollarsign : '$';
        );
 
 

+ 15 - 29
compiler/aoptobj.pas

@@ -1120,6 +1120,17 @@ Unit AoptObj;
       end;
 {$pop}
 
+    function IsJumpToLabel(hp: taicpu): boolean;
+      begin
+        result:=(hp.opcode=aopt_uncondjmp) and
+{$ifdef arm}
+          (hp.condition=c_None) and
+{$endif arm}
+          (hp.oper[0]^.typ = top_ref) and
+          (hp.oper[0]^.ref^.symbol is TAsmLabel);
+      end;
+
+
     function TAOptObj.GetFinalDestination(hp: taicpu; level: longint): boolean;
       {traces sucessive jumps to their final destination and sets it, e.g.
        je l1                je l3
@@ -1148,13 +1159,7 @@ Unit AoptObj;
                (taicpu(p1).is_jmp) then
               if { the next instruction after the label where the jump hp arrives}
                  { is unconditional or of the same type as hp, so continue       }
-                 (((taicpu(p1).opcode = aopt_uncondjmp) and
-{$ifdef arm}
-                   (taicpu(p1).condition = C_None) and
-{$endif arm}
-                   (taicpu(p1).oper[0]^.typ = top_ref) and
-                   (assigned(taicpu(p1).oper[0]^.ref^.symbol)) and
-                   (taicpu(p1).oper[0]^.ref^.symbol is TAsmLabel)) or
+                 (IsJumpToLabel(taicpu(p1)) or
                   conditions_equal(taicpu(p1).condition,hp.condition)) or
                  { the next instruction after the label where the jump hp arrives
                    is the opposite of hp (so this one is never taken), but after
@@ -1165,13 +1170,7 @@ Unit AoptObj;
                   SkipLabels(p1,p2) and
                   (p2.typ = ait_instruction) and
                   (taicpu(p2).is_jmp) and
-                  (((taicpu(p2).opcode = aopt_uncondjmp) and
-{$ifdef arm}
-                    (taicpu(p1).condition = C_None) and
-{$endif arm}
-                    (taicpu(p2).oper[0]^.typ = top_ref) and
-                    (assigned(taicpu(p2).oper[0]^.ref^.symbol)) and
-                    (taicpu(p2).oper[0]^.ref^.symbol is TAsmLabel)) or
+                   (IsJumpToLabel(taicpu(p2)) or
                    (conditions_equal(taicpu(p2).condition,hp.condition))) and
                   SkipLabels(p1,p1)) then
                 begin
@@ -1255,13 +1254,7 @@ Unit AoptObj;
                       { the following if-block removes all code between a jmp and the next label,
                         because it can never be executed
                       }
-                      if (taicpu(p).opcode = aopt_uncondjmp) and
-{$ifdef arm}
-                         (taicpu(p).condition = C_None) and
-{$endif arm}
-                         (taicpu(p).oper[0]^.typ = top_ref) and
-                         (assigned(taicpu(p).oper[0]^.ref^.symbol)) and
-                         (taicpu(p).oper[0]^.ref^.symbol is TAsmLabel) then
+                      if IsJumpToLabel(taicpu(p)) then
                         begin
                           hp2:=p;
                           while GetNextInstruction(hp2, hp1) and
@@ -1271,7 +1264,6 @@ Unit AoptObj;
                                 if (hp1.typ = ait_instruction) and
                                    taicpu(hp1).is_jmp and
                                    (taicpu(hp1).oper[0]^.typ = top_ref) and
-                                   assigned(taicpu(hp1).oper[0]^.ref^.symbol) and
                                    (taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) then
                                    TAsmLabel(taicpu(hp1).oper[0]^.ref^.symbol).decrefs;
                                 { don't kill start/end of assembler block,
@@ -1305,13 +1297,7 @@ Unit AoptObj;
                               if hp1.typ = ait_label then
                                 SkipLabels(hp1,hp1);
                               if (tai(hp1).typ=ait_instruction) and
-                                  (taicpu(hp1).opcode=aopt_uncondjmp) and
-{$ifdef arm}
-                                  (taicpu(hp1).condition=C_None) and
-{$endif arm}
-                                  (taicpu(hp1).oper[0]^.typ = top_ref) and
-                                  (assigned(taicpu(hp1).oper[0]^.ref^.symbol)) and
-                                  (taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) and
+                                  IsJumpToLabel(taicpu(hp1)) and
                                   GetNextInstruction(hp1, hp2) and
                                   FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol), hp2) then
                                 begin

+ 294 - 74
compiler/arm/aasmcpu.pas

@@ -26,7 +26,7 @@ unit aasmcpu;
 interface
 
 uses
-  cclasses,globtype,globals,verbose,
+  globtype,globals,verbose,
   aasmbase,aasmtai,aasmdata,aasmsym,
   ogbase,
   symtype,
@@ -161,9 +161,10 @@ uses
          wideformat : boolean;
          roundingmode : troundingmode;
          procedure loadshifterop(opidx:longint;const so:tshifterop);
-         procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset);
+         procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset; ausermode: boolean=false);
          procedure loadconditioncode(opidx:longint;const cond:tasmcond);
          procedure loadmodeflags(opidx:longint;const flags:tcpumodeflags);
+         procedure loadspecialreg(opidx:longint;const areg:tregister; const aflags:tspecialregflags);
          constructor op_none(op : tasmop);
 
          constructor op_reg(op : tasmop;_op1 : tregister);
@@ -174,10 +175,12 @@ uses
          constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
          constructor op_reg_const(op:tasmop; _op1: tregister; _op2: aint);
 
+         constructor op_regset(op:tasmop; regtype: tregistertype; subreg: tsubregister; _op1: tcpuregisterset);
          constructor op_ref_regset(op:tasmop; _op1: treference; regtype: tregistertype; subreg: tsubregister; _op2: tcpuregisterset);
 
          constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
          constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
+         constructor op_reg_const_const(op : tasmop;_op1 : tregister; _op2,_op3: aint);
          constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
          constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
          constructor op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop);
@@ -192,6 +195,9 @@ uses
          constructor op_modeflags(op: tasmop; flags: tcpumodeflags);
          constructor op_modeflags_const(op: tasmop; flags: tcpumodeflags; a: aint);
 
+         { MSR }
+         constructor op_specialreg_reg(op: tasmop; specialreg: tregister; specialregflags: tspecialregflags; _op2: tregister);
+
          { *M*LL }
          constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
 
@@ -265,7 +271,7 @@ uses
 implementation
 
   uses
-    cutils,rgobj,itcpugas;
+    itcpugas,aoptcpu;
 
 
     procedure taicpu.loadshifterop(opidx:longint;const so:tshifterop);
@@ -286,7 +292,7 @@ implementation
       end;
 
 
-    procedure taicpu.loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset);
+    procedure taicpu.loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset; ausermode: boolean);
       var
         i : byte;
       begin
@@ -301,6 +307,7 @@ implementation
            regset^:=s;
            regtyp:=regsetregtype;
            subreg:=regsetsubregtype;
+           usermode:=ausermode;
            typ:=top_regset;
            case regsetregtype of
              R_INTREGISTER:
@@ -345,6 +352,19 @@ implementation
          end;
       end;
 
+    procedure taicpu.loadspecialreg(opidx: longint; const areg: tregister; const aflags: tspecialregflags);
+      begin
+        allocate_oper(opidx+1);
+        with oper[opidx]^ do
+         begin
+           if typ<>top_specialreg then
+             clearop(opidx);
+           specialreg:=areg;
+           specialflags:=aflags;
+           typ:=top_specialreg;
+         end;
+      end;
+
 {*****************************************************************************
                                  taicpu Constructors
 *****************************************************************************}
@@ -397,6 +417,13 @@ implementation
          loadconst(1,aint(_op2));
       end;
 
+    constructor taicpu.op_regset(op: tasmop; regtype: tregistertype; subreg: tsubregister; _op1: tcpuregisterset);
+      begin
+        inherited create(op);
+        ops:=1;
+        loadregset(0,regtype,subreg,_op1);
+      end;
+
 
     constructor taicpu.op_ref_regset(op:tasmop; _op1: treference; regtype: tregistertype; subreg: tsubregister; _op2: tcpuregisterset);
       begin
@@ -447,6 +474,16 @@ implementation
       end;
 
 
+     constructor taicpu.op_reg_const_const(op : tasmop;_op1 : tregister; _op2,_op3: aint);
+       begin
+         inherited create(op);
+         ops:=3;
+         loadreg(0,_op1);
+         loadconst(1,aint(_op2));
+         loadconst(2,aint(_op3));
+       end;
+
+
     constructor taicpu.op_reg_const_ref(op : tasmop;_op1 : tregister;_op2 : aint;_op3 : treference);
       begin
          inherited create(op);
@@ -460,8 +497,8 @@ implementation
     constructor taicpu.op_cond(op: tasmop; cond: tasmcond);
       begin
         inherited create(op);
-        ops:=0;
-        condition := cond;
+        ops:=1;
+        loadconditioncode(0, cond);
       end;
 
     constructor taicpu.op_modeflags(op: tasmop; flags: tcpumodeflags);
@@ -479,6 +516,13 @@ implementation
         loadconst(1,a);
       end;
 
+    constructor taicpu.op_specialreg_reg(op: tasmop; specialreg: tregister; specialregflags: tspecialregflags; _op2: tregister);
+      begin
+        inherited create(op);
+        ops:=2;
+        loadspecialreg(0,specialreg,specialregflags);
+        loadreg(1,_op2);
+      end;
 
      constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
        begin
@@ -645,7 +689,7 @@ implementation
       begin
         case opcode of
           A_ADC,A_ADD,A_AND,A_BIC,
-          A_EOR,A_CLZ,
+          A_EOR,A_CLZ,A_RBIT,
           A_LDR,A_LDRB,A_LDRBT,A_LDRH,A_LDRSB,
           A_LDRSH,A_LDRT,
           A_MOV,A_MVN,A_MLA,A_MUL,
@@ -670,7 +714,8 @@ implementation
           A_FSITOS,A_FSITOD,A_FTOSIS,A_FTOSID,
           A_FTOUIS,A_FTOUID,A_FUITOS,A_FUITOD,
           A_SXTB16,A_UXTB16,
-          A_UXTB,A_UXTH,A_SXTB,A_SXTH:
+          A_UXTB,A_UXTH,A_SXTB,A_SXTH,
+          A_NEG:
             if opnr=0 then
               result:=operand_write
             else
@@ -702,11 +747,16 @@ implementation
               { check for pre/post indexed }
               result := operand_read;
           //Thumb2
-          A_LSL, A_LSR, A_ROR, A_ASR, A_SDIV, A_UDIV,A_MOVT:
+          A_LSL, A_LSR, A_ROR, A_ASR, A_SDIV, A_UDIV, A_MOVW, A_MOVT, A_MLS, A_BFI:
             if opnr in [0] then
               result:=operand_write
             else
               result:=operand_read;
+          A_BFC:
+            if opnr in [0] then
+              result:=operand_readwrite
+            else
+              result:=operand_read;
           A_LDREX:
             if opnr in [0] then
               result:=operand_write
@@ -823,17 +873,28 @@ implementation
         limit: longint;
         curop : longint;
         curtai : tai;
+        ai_label : tai_label;
         curdatatai,hp,hp2 : tai;
         curdata : TAsmList;
         l : tasmlabel;
         doinsert,
         removeref : boolean;
+        multiplier : byte;
       begin
         curdata:=TAsmList.create;
         lastinspos:=-1;
         curinspos:=0;
         extradataoffset:=0;
-        limit:=1016;
+        if current_settings.cputype in cpu_thumb then
+          begin
+            multiplier:=2;
+            limit:=504;
+          end
+        else
+          begin
+            limit:=1016;
+            multiplier:=1;
+          end;
         curtai:=tai(list.first);
         doinsert:=false;
         while assigned(curtai) do
@@ -850,96 +911,117 @@ implementation
                         begin
                           { pc relative symbol? }
                           curdatatai:=tai(taicpu(curtai).oper[curop]^.ref^.symboldata);
-                          if assigned(curdatatai) and
-                            { move only if we're at the first reference of a label }
-                            not(tai_label(curdatatai).moved) then
+                          if assigned(curdatatai) then
                             begin
-                              tai_label(curdatatai).moved:=true;
-                              { check if symbol already used. }
-                              { if yes, reuse the symbol }
-                              hp:=tai(curdatatai.next);
-                              removeref:=false;
-                              if assigned(hp) then
+                              { create a new copy of a data entry on arm thumb if the entry has been inserted already
+                                before because arm thumb does not allow pc relative negative offsets }
+                              if (current_settings.cputype in cpu_thumb) and
+                                tai_label(curdatatai).inserted then
                                 begin
-                                  case hp.typ of
-                                    ait_const:
-                                      begin
-                                        if (tai_const(hp).consttype=aitconst_64bit) then
-                                          inc(extradataoffset);
-                                      end;
-                                    ait_comp_64bit,
-                                    ait_real_64bit:
-                                      begin
-                                        inc(extradataoffset);
-                                      end;
-                                    ait_real_80bit:
-                                      begin
-                                        inc(extradataoffset,2);
-                                      end;
-                                  end;
-                                  if (hp.typ=ait_const) then
+                                  current_asmdata.getjumplabel(l);
+                                  hp:=tai_label.create(l);
+                                  listtoinsert.Concat(hp);
+                                  hp2:=tai(curdatatai.Next.GetCopy);
+                                  hp2.Next:=nil;
+                                  hp2.Previous:=nil;
+                                  listtoinsert.Concat(hp2);
+                                  taicpu(curtai).oper[curop]^.ref^.symboldata:=hp;
+                                  taicpu(curtai).oper[curop]^.ref^.symbol:=l;
+                                  curdatatai:=hp;
+                                end;
+
+                              { move only if we're at the first reference of a label }
+                              if not(tai_label(curdatatai).moved) then
+                                begin
+                                  tai_label(curdatatai).moved:=true;
+                                  { check if symbol already used. }
+
+                                  { if yes, reuse the symbol }
+                                  hp:=tai(curdatatai.next);
+                                  removeref:=false;
+                                  if assigned(hp) then
                                     begin
-                                      hp2:=tai(curdata.first);
-                                      while assigned(hp2) do
+                                      case hp.typ of
+                                        ait_const:
+                                          begin
+                                            if (tai_const(hp).consttype=aitconst_64bit) then
+                                              inc(extradataoffset,multiplier);
+                                          end;
+                                        ait_comp_64bit,
+                                        ait_real_64bit:
+                                          begin
+                                            inc(extradataoffset,multiplier);
+                                          end;
+                                        ait_real_80bit:
+                                          begin
+                                            inc(extradataoffset,2*multiplier);
+                                          end;
+                                      end;
+                                      { check if the same constant has been already inserted into the currently handled list,
+                                        if yes, reuse it }
+                                      if (hp.typ=ait_const) then
                                         begin
-    {                                      if armconstequal(hp2,hp) then }
-                                          if (hp2.typ=ait_const) and (tai_const(hp2).sym=tai_const(hp).sym)
-                                            and (tai_const(hp2).value=tai_const(hp).value) and (tai(hp2.previous).typ=ait_label)
-                                          then
+                                          hp2:=tai(curdata.first);
+                                          while assigned(hp2) do
                                             begin
-                                              with taicpu(curtai).oper[curop]^.ref^ do
+                                              if (hp2.typ=ait_const) and (tai_const(hp2).sym=tai_const(hp).sym)
+                                                and (tai_const(hp2).value=tai_const(hp).value) and (tai(hp2.previous).typ=ait_label)
+                                              then
                                                 begin
-                                                  symboldata:=hp2.previous;
-                                                  symbol:=tai_label(hp2.previous).labsym;
+                                                  with taicpu(curtai).oper[curop]^.ref^ do
+                                                    begin
+                                                      symboldata:=hp2.previous;
+                                                      symbol:=tai_label(hp2.previous).labsym;
+                                                    end;
+                                                  removeref:=true;
+                                                  break;
                                                 end;
-                                              removeref:=true;
-                                              break;
+                                              hp2:=tai(hp2.next);
                                             end;
-                                          hp2:=tai(hp2.next);
                                         end;
                                     end;
+                                  { move or remove symbol reference }
+                                  repeat
+                                    hp:=tai(curdatatai.next);
+                                    listtoinsert.remove(curdatatai);
+                                    if removeref then
+                                      curdatatai.free
+                                    else
+                                      curdata.concat(curdatatai);
+                                    curdatatai:=hp;
+                                  until (curdatatai=nil) or (curdatatai.typ=ait_label);
+                                  if lastinspos=-1 then
+                                    lastinspos:=curinspos;
                                 end;
-                              { move or remove symbol reference }
-                              repeat
-                                hp:=tai(curdatatai.next);
-                                listtoinsert.remove(curdatatai);
-                                if removeref then
-                                  curdatatai.free
-                                else
-                                  curdata.concat(curdatatai);
-                                curdatatai:=hp;
-                              until (curdatatai=nil) or (curdatatai.typ=ait_label);
-                              if lastinspos=-1 then
-                                lastinspos:=curinspos;
                             end;
                         end;
                     end;
-                  inc(curinspos);
+                  inc(curinspos,multiplier);
                 end;
               ait_align:
                 begin
                   { code is always 4 byte aligned, so we don't have to take care of .align 2 which would
                     requires also incrementing curinspos by 1 }
-                  inc(curinspos,(tai_align(curtai).aligntype div 4));
+                  inc(curinspos,(tai_align(curtai).aligntype div 4)*multiplier);
                 end;
               ait_const:
                 begin
-                  inc(curinspos);
+                  inc(curinspos,multiplier);
                   if (tai_const(curtai).consttype=aitconst_64bit) then
-                    inc(curinspos);
+                    inc(curinspos,multiplier);
                 end;
               ait_real_32bit:
                 begin
-                  inc(curinspos);
+                  inc(curinspos,multiplier);
                 end;
               ait_comp_64bit,
               ait_real_64bit:
                 begin
-                  inc(curinspos,2);
+                  inc(curinspos,2*multiplier);
                 end;
               ait_real_80bit:
                 begin
-                  inc(curinspos,3);
+                  inc(curinspos,3*multiplier);
                 end;
             end;
             { special case for case jump tables }
@@ -949,14 +1031,14 @@ implementation
               (taicpu(hp).oper[0]^.typ=top_reg) and
               (taicpu(hp).oper[0]^.reg=NR_PC) then
               begin
-                penalty:=1;
+                penalty:=1*multiplier;
                 hp:=tai(hp.next);
                 { skip register allocations and comments inserted by the optimizer }
                 while assigned(hp) and (hp.typ in [ait_comment,ait_regalloc]) do
                   hp:=tai(hp.next);
                 while assigned(hp) and (hp.typ=ait_const) do
                   begin
-                    inc(penalty);
+                    inc(penalty,multiplier);
                     hp:=tai(hp.next);
                   end;
               end
@@ -986,22 +1068,63 @@ implementation
                     (taicpu(curtai).oper[1]^.typ=top_reg) and
                     (taicpu(curtai).oper[1]^.reg=NR_PC)
                    )
+              ) and
+              (
+                { do not insert data after a B instruction due to their limited range }
+                not((current_settings.cputype in cpu_thumb) and
+                    (taicpu(curtai).opcode=A_B)
+                   )
               ) then
               begin
                 lastinspos:=-1;
                 extradataoffset:=0;
-                limit:=1016;
+
+                if current_settings.cputype in cpu_thumb then
+                  limit:=502
+                else
+                  limit:=1016;
+
+                { on arm thumb, insert the date always after all labels etc. following an instruction so it
+                  is prevent that a bxx yyy; bl xxx; yyyy: sequence gets separated ( we never insert on arm thumb after
+                  bxx) and the distance of bxx gets too long }
+                if current_settings.cputype in cpu_thumb then
+                  while assigned(tai(curtai.Next)) and (tai(curtai.Next).typ in SkipInstr+[ait_label]) do
+                    curtai:=tai(curtai.next);
+
                 doinsert:=false;
-                hp:=tai(curtai.next);
                 current_asmdata.getjumplabel(l);
+
+                { align thumb in thumb .text section to 4 bytes }
+                if not(curdata.empty) and (current_settings.cputype in cpu_thumb) then
+                  curdata.Insert(tai_align.Create(4));
                 curdata.insert(taicpu.op_sym(A_B,l));
                 curdata.concat(tai_label.create(l));
+
+                { mark all labels as inserted, arm thumb
+                  needs this, so data referencing an already inserted label can be
+                  duplicated because arm thumb does not allow negative pc relative offset }
+                hp2:=tai(curdata.first);
+                while assigned(hp2) do
+                  begin
+                    if hp2.typ=ait_label then
+                      tai_label(hp2).inserted:=true;
+                    hp2:=tai(hp2.next);
+                  end;
+
+                { continue with the last inserted label because we use later
+                  on SimpleGetNextInstruction, so if we used curtai.next (which
+                  is then equal curdata.last.previous) we could over see one
+                  instruction }
+                hp:=tai(curdata.Last);
                 list.insertlistafter(curtai,curdata);
                 curtai:=hp;
               end
             else
               curtai:=tai(curtai.next);
           end;
+        { align thumb in thumb .text section to 4 bytes }
+        if not(curdata.empty) and (current_settings.cputype in cpu_thumb+cpu_thumb2) then
+          curdata.Insert(tai_align.Create(4));
         list.concatlist(curdata);
         curdata.free;
       end;
@@ -1065,13 +1188,110 @@ implementation
           end;
       end;
 
-    procedure finalizearmcode(list, listtoinsert: TAsmList);
+
+    function getMergedInstruction(FirstOp,LastOp:TAsmOp;InvertLast:boolean) : TAsmOp;
+      const
+        opTable: array[A_IT..A_ITTTT] of string =
+          ('T','TE','TT','TEE','TTE','TET','TTT',
+           'TEEE','TTEE','TETE','TTTE',
+           'TEET','TTET','TETT','TTTT');
+        invertedOpTable: array[A_IT..A_ITTTT] of string =
+          ('E','ET','EE','ETT','EET','ETE','EEE',
+           'ETTT','EETT','ETET','EEET',
+           'ETTE','EETE','ETEE','EEEE');
+      var
+        resStr : string;
+        i : TAsmOp;
       begin
-        insertpcrelativedata(list, listtoinsert);
+        if InvertLast then
+          resStr := opTable[FirstOp]+invertedOpTable[LastOp]
+        else
+          resStr := opTable[FirstOp]+opTable[LastOp];
+        if length(resStr) > 4 then
+          internalerror(2012100805);
 
+        for i := low(opTable) to high(opTable) do
+          if opTable[i] = resStr then
+            exit(i);
+
+        internalerror(2012100806);
+      end;
+
+    procedure foldITInstructions(list: TAsmList);
+      var
+        curtai,hp1 : tai;
+        levels,i : LongInt;
+      begin
+        curtai:=tai(list.First);
+        while assigned(curtai) do
+          begin
+            case curtai.typ of
+              ait_instruction:
+                if IsIT(taicpu(curtai).opcode) then
+                  begin
+                    levels := GetITLevels(taicpu(curtai).opcode);
+                    if levels < 4 then
+                      begin
+                        i:=levels;
+                        hp1:=tai(curtai.Next);
+                        while assigned(hp1) and
+                          (i > 0) do
+                          begin
+                            if hp1.typ=ait_instruction then
+                              begin
+                                dec(i);
+                                if (i = 0) and
+                                  mustbelast(hp1) then
+                                  begin
+                                    hp1:=nil;
+                                    break;
+                                  end;
+                              end;
+                            hp1:=tai(hp1.Next);
+                          end;
+
+                        if assigned(hp1) then
+                          begin
+                            // We are pointing at the first instruction after the IT block
+                            while assigned(hp1) and
+                              (hp1.typ<>ait_instruction) do
+                                hp1:=tai(hp1.Next);
+
+                            if assigned(hp1) and
+                              (hp1.typ=ait_instruction) and
+                              IsIT(taicpu(hp1).opcode) then
+                              begin
+                                if (levels+GetITLevels(taicpu(hp1).opcode) <= 4) and
+                                  ((taicpu(curtai).oper[0]^.cc=taicpu(hp1).oper[0]^.cc) or
+                                   (taicpu(curtai).oper[0]^.cc=inverse_cond(taicpu(hp1).oper[0]^.cc))) then
+                                  begin
+                                    taicpu(curtai).opcode:=getMergedInstruction(taicpu(curtai).opcode,
+                                                                                taicpu(hp1).opcode,
+                                                                                taicpu(curtai).oper[0]^.cc=inverse_cond(taicpu(hp1).oper[0]^.cc));
+
+                                    list.Remove(hp1);
+                                    hp1.Free;
+                                  end;
+                              end;
+                          end;
+                      end;
+                  end;
+            end;
+
+            curtai:=tai(curtai.Next);
+          end;
+      end;
+
+    procedure finalizearmcode(list, listtoinsert: TAsmList);
+      begin
         { Do Thumb-2 16bit -> 32bit transformations }
         if current_settings.cputype in cpu_thumb2 then
-          ensurethumb2encodings(list);
+          begin
+            ensurethumb2encodings(list);
+            foldITInstructions(list);
+          end;
+
+        insertpcrelativedata(list, listtoinsert);
       end;
 
     procedure InsertPData;

+ 54 - 13
compiler/arm/agarmgas.pas

@@ -30,9 +30,9 @@ unit agarmgas;
 
     uses
        globtype,
-       aasmtai,aasmdata,
+       aasmtai,
        aggas,
-       cpubase;
+       cpubase,cpuinfo;
 
     type
       TARMGNUAssembler=class(TGNUassembler)
@@ -54,13 +54,34 @@ unit agarmgas;
       gas_shiftmode2str : array[tshiftmode] of string[3] = (
         '','lsl','lsr','asr','ror','rrx');
 
+    const 
+      cputype_to_gas_march : array[tcputype] of string = (
+        '', // cpu_none
+        'armv3',
+        'armv4',
+        'armv4t',
+        'armv5',
+        'armv5t',
+        'armv5te',
+        'armv5tej',
+        'armv6',
+        'armv6k',
+        'armv6t2',
+        'armv6z',
+        'armv6-m',
+        'armv7',
+        'armv7-a',
+        'armv7-r',
+        'armv7-m',
+        'armv7e-m');
+
   implementation
 
     uses
        cutils,globals,verbose,
        systems,
        assemble,
-       cpuinfo,aasmcpu,
+       aasmcpu,
        itcpugas,
        cgbase,cgutils;
 
@@ -86,13 +107,16 @@ unit agarmgas;
           result:='-mfpu=vfpv3 '+result;
         if (current_settings.fputype = fpu_vfpv3_d16) then
           result:='-mfpu=vfpv3-d16 '+result;
+        if (current_settings.fputype = fpu_fpv4_s16) then
+          result:='-mfpu=fpv4-sp-d16 '+result;
 
-        if current_settings.cputype=cpu_armv7m then
-          result:='-march=armv7m -mthumb -mthumb-interwork '+result
-        else if current_settings.cputype=cpu_armv6 then
-          result:='-march=armv6 '+result
-        else if current_settings.cputype=cpu_armv7 then
-          result:='-march=armv7-a '+result;
+        if current_settings.cputype in cpu_thumb2 then
+          result:='-march='+cputype_to_gas_march[current_settings.cputype]+' -mthumb -mthumb-interwork '+result
+        else if current_settings.cputype in cpu_thumb then
+          result:='-march='+cputype_to_gas_march[current_settings.cputype]+' -mthumb -mthumb-interwork '+result
+        // EDSP instructions in RTL require armv5te at least to not generate error
+        else if current_settings.cputype >= cpu_armv5te then
+          result:='-march='+cputype_to_gas_march[current_settings.cputype]+' '+result;
 
         if target_info.abi = abi_eabihf then
           { options based on what gcc uses on debian armhf }
@@ -215,6 +239,8 @@ unit agarmgas;
                     first:=false;
                   end;
               getopstr:=getopstr+'}';
+              if o.usermode then
+                getopstr:=getopstr+'^';
             end;
           top_conditioncode:
             getopstr:=cond2str[o.cc];
@@ -238,6 +264,18 @@ unit agarmgas;
               end
             else
               getopstr:=getreferencestring(o.ref^);
+          top_specialreg:
+            begin
+              getopstr:=gas_regname(o.specialreg);
+              if o.specialflags<>[] then
+                begin
+                  getopstr:=getopstr+'_';
+                  if srC in o.specialflags then getopstr:=getopstr+'c';
+                  if srX in o.specialflags then getopstr:=getopstr+'x';
+                  if srF in o.specialflags then getopstr:=getopstr+'f';
+                  if srS in o.specialflags then getopstr:=getopstr+'s';
+                end;
+            end
           else
             internalerror(2002070604);
         end;
@@ -259,8 +297,10 @@ unit agarmgas;
 
           if taicpu(hp).ops = 0 then
             s:=#9+gas_op2str[op]+' '+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix]
+          else if (taicpu(hp).opcode>=A_VABS) and (taicpu(hp).opcode<=A_VSUB) then
+            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix]
           else
-            s:=#9+gas_op2str[op]+oppostfix2str[taicpu(hp).oppostfix]+postfix+cond2str[taicpu(hp).condition]; // Conditional infixes are deprecated in unified syntax
+            s:=#9+gas_op2str[op]+oppostfix2str[taicpu(hp).oppostfix]+cond2str[taicpu(hp).condition]+postfix; // Conditional infixes are deprecated in unified syntax
         end
       else
         s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix];
@@ -317,8 +357,9 @@ unit agarmgas;
             idtxt  : 'AS';
             asmbin : 'as';
             asmcmd : '-o $OBJ $ASM';
-            supported_targets : [system_arm_linux,system_arm_wince,system_arm_gba,system_arm_palmos,system_arm_nds,system_arm_embedded,system_arm_symbian];
-            flags : [af_allowdirect,af_needar,af_smartlink_sections];
+            supported_targets : [system_arm_linux,system_arm_wince,system_arm_gba,system_arm_palmos,system_arm_nds,
+                                 system_arm_embedded,system_arm_symbian,system_arm_android];
+            flags : [af_needar,af_smartlink_sections];
             labelprefix : '.L';
             comment : '# ';
             dollarsign: '$';
@@ -331,7 +372,7 @@ unit agarmgas;
             asmbin : 'as';
             asmcmd : '-o $OBJ $ASM -arch $ARCH';
             supported_targets : [system_arm_darwin];
-            flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf,af_stabs_use_function_absolute_addresses];
+            flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_stabs_use_function_absolute_addresses];
             labelprefix : 'L';
             comment : '# ';
             dollarsign: '$';

Різницю між файлами не показано, бо вона завелика
+ 746 - 122
compiler/arm/aoptcpu.pas


+ 41 - 7
compiler/arm/armatt.inc

@@ -50,6 +50,7 @@
 'mcr',
 'mla',
 'mov',
+'mrc',
 'mrs',
 'msr',
 'mnf',
@@ -206,6 +207,10 @@
 'sel',
 'setend',
 'sev',
+'asr',
+'lsr',
+'lsl',
+'ror',
 'shadd16',
 'shadd8',
 'shasx',
@@ -236,6 +241,8 @@
 'sxtah',
 'sxtb',
 'sxtb16',
+'uxtb',
+'uxth',
 'sxth',
 'uadd16',
 'uadd8',
@@ -264,18 +271,12 @@
 'uxtab',
 'uxtab16',
 'uxtah',
-'uxtb',
 'uxtb16',
-'uxth',
 'wfe',
 'wfi',
 'yield',
-'asr',
-'lsr',
-'lsl',
 'pop',
 'push',
-'ror',
 'sdiv',
 'udiv',
 'movt',
@@ -295,5 +296,38 @@
 'itett',
 'itttt',
 'tbb',
-'tbh'
+'tbh',
+'movw',
+'cbz',
+'cbnz',
+'vabs',
+'vadd',
+'vcmp',
+'vcmpe',
+'vcvt',
+'vdiv',
+'vldm',
+'vldr',
+'vmov',
+'vmrs',
+'vmsr',
+'vmul',
+'vmla',
+'vmls',
+'vnmla',
+'vnmls',
+'vfma',
+'vfms',
+'vfnma',
+'vfnms',
+'vneg',
+'vnmul',
+'vpop',
+'vpush',
+'vsqrt',
+'vstm',
+'vstr',
+'vsub',
+'neg',
+'svc'
 );

+ 34 - 0
compiler/arm/armatts.inc

@@ -295,5 +295,39 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufNONE
 );

+ 54 - 13
compiler/arm/armins.dat

@@ -235,7 +235,7 @@ reg32,imm8,fpureg        \xF0\x02\x01                   FPA
 [LOGcc]
 
 [MCR]
-reg32,mem32         \320\301\1\x13\110            ARM7
+; reg32,mem32         \320\301\1\x13\110            ARM7
 
 [MLAcc]
 reg32,reg32,reg32,reg32  \x15\x00\x20\x90               ARM7
@@ -247,7 +247,7 @@ reg32,reg32,reg32,reg32  \x15\x00\x20\x90               ARM7
 ; reg32,reg32,imm          \xA\x1\xA0                     ARM7
 ; reg32,imm                \xB\x3\xA0                     ARM7
 
-; [MRC]
+[MRC]
 ; reg32,reg32         \321\301\1\x13\110                  ARM7
 
 [MRScc]
@@ -618,6 +618,14 @@ reg32,reg32,reg32,reg32  \x16\x00\x80\x90		 ARM7
 
 [SEVcc]
 
+[ASRcc]
+
+[LSRcc]
+
+[LSLcc]
+
+[RORcc]
+
 [SHADD16cc]
 [SHADD8cc]
 [SHASXcc]
@@ -654,6 +662,10 @@ reg32,reg32,reg32,reg32  \x16\x00\x80\x90		 ARM7
 [SXTAHcc]
 [SXTBcc]
 [SXTB16cc]
+
+[UXTBcc]
+[UXTHcc]
+
 [SXTHcc]
 
 [UADD16cc]
@@ -691,10 +703,7 @@ reg32,reg32,reg32,reg32  \x16\x00\x80\x90		 ARM7
 [UXTABcc]
 [UXTAB16cc]
 [UXTAHcc]
-
-[UXTBcc]
 [UXTB16cc]
-[UXTHcc]
 
 [WFEcc]
 [WFIcc]
@@ -702,18 +711,10 @@ reg32,reg32,reg32,reg32  \x16\x00\x80\x90		 ARM7
 
 ; Thumb-2
 
-[ASRcc]
-
-[LSRcc]
-
-[LSLcc]
-
 [POP]
 
 [PUSH]
 
-[RORcc]
-
 [SDIVcc]
 
 [UDIVcc]
@@ -752,3 +753,43 @@ reg32,reg32,reg32,reg32  \x16\x00\x80\x90		 ARM7
 
 [TBB]
 [TBH]
+
+[MOVW]
+
+[CBZ]
+[CBNZ]
+
+; FPv4-s16 - ARMv7M floating point
+[VABS]
+[VADD]
+[VCMP]
+[VCMPE]
+[VCVT]
+[VDIV]
+[VLDM]
+[VLDR]
+[VMOV]
+[VMRS]
+[VMSR]
+[VMUL]
+[VMLA]
+[VMLS]
+[VNMLA]
+[VNMLS]
+[VFMA]
+[VFMS]
+[VFNMA]
+[VFNMS]
+[VNEG]
+[VNMUL]
+[VPOP]
+[VPUSH]
+[VSQRT]
+[VSTM]
+[VSTR]
+[VSUB]
+
+; Thumb armv6-m (gcc)
+[NEG]
+[SVC]
+

+ 1 - 1
compiler/arm/armnop.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from armins.dat }
-106;
+105;

+ 41 - 7
compiler/arm/armop.inc

@@ -50,6 +50,7 @@ A_LOG,
 A_MCR,
 A_MLA,
 A_MOV,
+A_MRC,
 A_MRS,
 A_MSR,
 A_MNF,
@@ -206,6 +207,10 @@ A_SBFX,
 A_SEL,
 A_SETEND,
 A_SEV,
+A_ASR,
+A_LSR,
+A_LSL,
+A_ROR,
 A_SHADD16,
 A_SHADD8,
 A_SHASX,
@@ -236,6 +241,8 @@ A_SXTAB16,
 A_SXTAH,
 A_SXTB,
 A_SXTB16,
+A_UXTB,
+A_UXTH,
 A_SXTH,
 A_UADD16,
 A_UADD8,
@@ -264,18 +271,12 @@ A_USUB8,
 A_UXTAB,
 A_UXTAB16,
 A_UXTAH,
-A_UXTB,
 A_UXTB16,
-A_UXTH,
 A_WFE,
 A_WFI,
 A_YIELD,
-A_ASR,
-A_LSR,
-A_LSL,
 A_POP,
 A_PUSH,
-A_ROR,
 A_SDIV,
 A_UDIV,
 A_MOVT,
@@ -295,5 +296,38 @@ A_ITTET,
 A_ITETT,
 A_ITTTT,
 A_TBB,
-A_TBH
+A_TBH,
+A_MOVW,
+A_CBZ,
+A_CBNZ,
+A_VABS,
+A_VADD,
+A_VCMP,
+A_VCMPE,
+A_VCVT,
+A_VDIV,
+A_VLDM,
+A_VLDR,
+A_VMOV,
+A_VMRS,
+A_VMSR,
+A_VMUL,
+A_VMLA,
+A_VMLS,
+A_VNMLA,
+A_VNMLS,
+A_VFMA,
+A_VFMS,
+A_VFNMA,
+A_VFNMS,
+A_VNEG,
+A_VNMUL,
+A_VPOP,
+A_VPUSH,
+A_VSQRT,
+A_VSTM,
+A_VSTR,
+A_VSUB,
+A_NEG,
+A_SVC
 );

+ 38 - 1
compiler/arm/armreg.dat

@@ -107,5 +107,42 @@ D30,$04,$07,$1E,d30,0,0
 D31,$04,$07,$1F,d31,0,0
 
 ; special registers
-CPSR_C,$05,$00,$00,cpsr_c,0,0
+CPSR,$05,$00,$00,cpsr,0,0
 FPSCR,$05,$00,$01,fpscr,0,0
+SPSR,$05,$00,$02,spsr,0,0
+APSR_nzcv,$05,$00,$03,apsr_nzcv,0,0
+; coprocessor registers
+CR0,$05,$00,$04,cr0,0,0
+CR1,$05,$00,$05,cr1,0,0
+CR2,$05,$00,$06,cr2,0,0
+CR3,$05,$00,$07,cr3,0,0
+CR4,$05,$00,$08,cr4,0,0
+CR5,$05,$00,$09,cr5,0,0
+CR6,$05,$00,$0A,cr6,0,0
+CR7,$05,$00,$0B,cr7,0,0
+CR8,$05,$00,$0C,cr8,0,0
+CR9,$05,$00,$0D,cr9,0,0
+CR10,$05,$00,$0E,cr10,0,0
+CR11,$05,$00,$0F,cr11,0,0
+CR12,$05,$00,$10,cr12,0,0
+CR13,$05,$00,$11,cr13,0,0
+CR14,$05,$00,$12,cr14,0,0
+CR15,$05,$00,$13,cr15,0,0
+; coprocessors
+p15,$05,$00,$14,p15,0,0
+; Cortex-M3 special registers
+APSR,$05,$00,$15,apsr,0,0
+IPSR,$05,$00,$16,ipsr,0,0
+EPSR,$05,$00,$17,epsr,0,0
+IEPSR,$05,$00,$18,iepsr,0,0
+IAPSR,$05,$00,$19,iapsr,0,0
+EAPSR,$05,$00,$1A,eapsr,0,0
+PSR,$05,$00,$1B,psr,0,0
+MSP,$05,$00,$1C,msp,0,0
+PSP,$05,$00,$1D,psp,0,0
+PRIMASK,$05,$00,$1E,primask,0,0
+BASEPRI,$05,$00,$1F,basepri,0,0
+BASEPRI_MAX,$05,$00,$20,basepri_max,0,0
+FAULTMASK,$05,$00,$21,faultmask,0,0
+CONTROL,$05,$00,$22,control,0,0
+

+ 0 - 7
compiler/arm/armtab.inc

@@ -385,13 +385,6 @@
     code    : #240#2#1;
     flags   : if_fpa
   ),
-  (
-    opcode  : A_MCR;
-    ops     : 2;
-    optypes : (ot_reg32,ot_memory or ot_bits32,ot_none,ot_none);
-    code    : #208#193#1#19#72;
-    flags   : if_arm7
-  ),
   (
     opcode  : A_MLA;
     ops     : 4;

Різницю між файлами не показано, бо вона завелика
+ 393 - 162
compiler/arm/cgcpu.pas


+ 114 - 10
compiler/arm/cpubase.pas

@@ -32,10 +32,8 @@ unit cpubase;
   interface
 
     uses
-      cutils,cclasses,
       globtype,globals,
       cpuinfo,
-      aasmbase,
       cgbase
       ;
 
@@ -48,7 +46,7 @@ unit cpubase;
       TAsmOp= {$i armop.inc}
       {This is a bit of a hack, because there are more than 256 ARM Assembly Ops
        But FPC currently can't handle more than 256 elements in a set.}
-      TCommonAsmOps = Set of A_None .. A_UQSADA8;
+      TCommonAsmOps = Set of A_None .. A_UADD16;
 
       { This should define the array of instructions as string }
       op2strtable=array[tasmop] of string[11];
@@ -139,7 +137,11 @@ unit cpubase;
         { multiple load/store vfp address modes }
         PF_IAD,PF_DBD,PF_FDD,PF_EAD,
         PF_IAS,PF_DBS,PF_FDS,PF_EAS,
-        PF_IAX,PF_DBX,PF_FDX,PF_EAX
+        PF_IAX,PF_DBX,PF_FDX,PF_EAX,
+        { FPv4 postfixes }
+        PF_32,PF_64,PF_F32,PF_F64,
+        PF_F32S32,PF_F32U32,
+        PF_S32F32,PF_U32F32
       );
 
       TOpPostfixes = set of TOpPostfix;
@@ -152,14 +154,17 @@ unit cpubase;
         PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,
         PF_S,PF_D,PF_E,PF_None,PF_None);
 
-      oppostfix2str : array[TOpPostfix] of string[3] = ('',
+      oppostfix2str : array[TOpPostfix] of string[8] = ('',
         's',
         'd','e','p','ep',
         'b','sb','bt','h','sh','t',
         'ia','ib','da','db','fd','fa','ed','ea',
         'iad','dbd','fdd','ead',
         'ias','dbs','fds','eas',
-        'iax','dbx','fdx','eax');
+        'iax','dbx','fdx','eax',
+        '.32','.64','.f32','.f64',
+        '.f32.s32','.f32.u32',
+        '.s32.f32','.u32.f32');
 
       roundingmode2str : array[TRoundingMode] of string[1] = ('',
         'p','m','z');
@@ -215,12 +220,15 @@ unit cpubase;
       tcpumodeflag = (mfA, mfI, mfF);
       tcpumodeflags = set of tcpumodeflag;
 
+      tspecialregflag = (srC, srX, srS, srF);
+      tspecialregflags = set of tspecialregflag;
+
 {*****************************************************************************
                                  Constants
 *****************************************************************************}
 
     const
-      max_operands = 4;
+      max_operands = 6;
 
       maxintregs = 15;
       maxfpuregs = 8;
@@ -296,8 +304,8 @@ unit cpubase;
       { Offset where the parent framepointer is pushed }
       PARENT_FRAMEPOINTER_OFFSET = 0;
 
-      NR_DEFAULTFLAGS = NR_CPSR_C;
-      RS_DEFAULTFLAGS = RS_CPSR_C;
+      NR_DEFAULTFLAGS = NR_CPSR;
+      RS_DEFAULTFLAGS = RS_CPSR;
 
       { Low part of 64bit return value }
       function NR_FUNCTION_RESULT64_LOW_REG: tregister;{$ifdef USEINLINE}inline;{$endif USEINLINE}
@@ -355,9 +363,17 @@ unit cpubase;
     function is_pc(const r : tregister) : boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
     function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
+    function is_thumb_imm(d: aint): boolean;
+    { Returns true if d is a valid constant for thumb 32 bit,
+      doesn't handle ROR_C detection }
+    function is_thumb32_imm(d : aint) : boolean;
     function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword):boolean;
+    function is_continuous_mask(d : aint;var lsb, width: byte) : boolean;
     function dwarf_reg(r:tregister):shortint;
 
+    function IsIT(op: TAsmOp) : boolean;
+    function GetITLevels(op: TAsmOp) : longint;
+
   implementation
 
     uses
@@ -365,7 +381,7 @@ unit cpubase;
 
 
     const
-      std_regname_table : array[tregisterindex] of string[7] = (
+      std_regname_table : TRegNameTable = (
         {$i rarmstd.inc}
       );
 
@@ -537,6 +553,63 @@ unit cpubase;
         result:=false;
       end;
 
+
+    function is_thumb_imm(d: aint): boolean;
+      begin
+        result:=(d and $FF) = d;
+      end;
+
+
+    function is_thumb32_imm(d: aint): boolean;
+      var
+        t : aint;
+        i : longint;
+        imm : byte;
+      begin
+        result:=false;
+        if (d and $FF) = d then
+          begin
+            result:=true;
+            exit;
+          end;
+        if ((d and $FF00FF00) = 0) and
+           ((d shr 16)=(d and $FFFF)) then
+          begin
+            result:=true;
+            exit;
+          end;
+        if ((d and $00FF00FF) = 0) and
+           ((d shr 16)=(d and $FFFF)) then
+          begin
+            result:=true;
+            exit;
+          end;
+        if ((d shr 16)=(d and $FFFF)) and
+           ((d shr 8)=(d and $FF)) then
+          begin
+            result:=true;
+            exit;
+          end;
+        if is_shifter_const(d,imm) then
+          begin
+            result:=true;
+            exit;
+          end;
+      end;
+    
+    function is_continuous_mask(d : aint;var lsb, width: byte) : boolean;
+      var
+        msb : byte;
+      begin
+        lsb:=BsfDword(d);
+        msb:=BsrDword(d);
+        
+        width:=msb-lsb+1;
+        
+        result:=(lsb<>255) and (msb<>255) and ((((1 shl (msb-lsb+1))-1) shl lsb) = d);
+      end;
+
+
     function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword) : boolean;
       var
         d, i, i2: Dword;
@@ -603,4 +676,35 @@ unit cpubase;
         result:=RS_R0;
     end;
 
+    function IsIT(op: TAsmOp) : boolean;
+      begin
+        case op of
+          A_IT,
+          A_ITE, A_ITT,
+          A_ITEE, A_ITTE, A_ITET, A_ITTT,
+          A_ITEEE, A_ITTEE, A_ITETE, A_ITTTE,
+          A_ITEET, A_ITTET, A_ITETT, A_ITTTT:
+            result:=true;
+        else
+          result:=false;
+        end;
+      end;
+
+    function GetITLevels(op: TAsmOp) : longint;
+      begin
+        case op of
+          A_IT:
+            result:=1;
+          A_ITE, A_ITT:
+            result:=2;
+          A_ITEE, A_ITTE, A_ITET, A_ITTT:
+            result:=3;
+          A_ITEEE, A_ITTEE, A_ITETE, A_ITTTE,
+          A_ITEET, A_ITTET, A_ITETT, A_ITTTT:
+            result:=4;
+        else
+          result:=0;
+        end;
+      end;
+
 end.

+ 882 - 0
compiler/arm/cpuelf.pas

@@ -0,0 +1,882 @@
+{
+    Copyright (c) 2012 by Sergei Gorelkin
+
+    Includes ELF-related code specific to ARM
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit cpuelf;
+
+interface
+
+{$i fpcdefs.inc}
+
+implementation
+
+  uses
+    globtype,cutils,cclasses,
+    verbose, elfbase,
+    systems,aasmbase,ogbase,ogelf,assemble;
+
+  type
+    TElfExeOutputARM=class(TElfExeOutput)
+    private
+      procedure MaybeWriteGOTEntry(reltyp:byte;relocval:aint;objsym:TObjSymbol);
+    protected
+      procedure WriteFirstPLTEntry;override;
+      procedure WritePLTEntry(exesym:TExeSymbol);override;
+      procedure WriteIndirectPLTEntry(exesym:TExeSymbol);override;
+      procedure GOTRelocPass1(objsec:TObjSection;var idx:longint);override;
+      procedure DoRelocationFixup(objsec:TObjSection);override;
+    end;
+
+  const
+    { Relocation types }
+    R_ARM_NONE  = 0;
+    R_ARM_PC24  = 1;       // deprecated
+    R_ARM_ABS32 = 2;
+    R_ARM_REL32 = 3;
+    R_ARM_LDR_PC_G0 = 4;
+    R_ARM_ABS16 = 5;
+    R_ARM_ABS12 = 6;
+    R_ARM_THM_ABS5 = 7;
+    R_ARM_ABS8  = 8;
+    R_ARM_SBREL32 = 9;
+    R_ARM_THM_CALL = 10;
+    R_ARM_THM_PC8 = 11;
+    R_ARM_BREL_ADJ = 12;
+    R_ARM_TLS_DESC = 13;
+    { 14,15,16 are obsolete }
+    R_ARM_TLS_DTPMOD32 = 17;
+    R_ARM_TLS_DTPOFF32 = 18;
+    R_ARM_TLS_TPOFF32 = 19;
+    R_ARM_COPY = 20;
+    R_ARM_GLOB_DAT = 21;
+    R_ARM_JUMP_SLOT = 22;
+    R_ARM_RELATIVE = 23;
+    R_ARM_GOTOFF32 = 24;
+    R_ARM_BASE_PREL = 25;
+    R_ARM_GOT_BREL = 26;
+    R_ARM_PLT32 = 27;      // deprecated
+    R_ARM_CALL = 28;
+    R_ARM_JUMP24 = 29;
+    R_ARM_THM_JUMP24 = 30;
+    R_ARM_BASE_ABS = 31;
+    { 32,33,34 are obsolete }
+    R_ARM_LDR_SBREL_11_0 = 35;    // deprecated
+    R_ARM_ALU_SBREL_19_12 = 36;   // deprecated
+    R_ARM_ALU_SBREL_27_20 = 37;   // deprecated
+    R_ARM_TARGET1 = 38;
+    R_ARM_SBREL31 = 39;           // deprecated
+    R_ARM_V4BX = 40;
+    R_ARM_TARGET2 = 41;
+    R_ARM_PREL31 = 42;
+    R_ARM_MOVW_ABS_NC = 43;
+    R_ARM_MOVT_ABS = 44;
+    R_ARM_MOVW_PREL_NC = 45;
+    R_ARM_MOVT_PREL = 46;
+    R_ARM_THM_MOVW_ABS_NC = 47;
+    R_ARM_THM_MOVT_ABS    = 48;
+    R_ARM_THM_MOVW_PREL_NC = 49;
+    R_ARM_THM_MOVT_PREL = 50;
+    R_ARM_THM_JUMP19 = 51;
+    R_ARM_THM_JUMP6 = 52;
+    R_ARM_THM_ALU_PREL_11_0 = 53;
+    R_ARM_THM_PC12     = 54;
+    R_ARM_ABS32_NOI    = 55;
+    R_ARM_REL32_NOI    = 56;
+    R_ARM_ALU_PC_G0_NC = 57;
+    R_ARM_ALU_PC_G0    = 58;
+    R_ARM_ALU_PC_G1_NC = 59;
+    R_ARM_ALU_PC_G1    = 60;
+    R_ARM_ALU_PC_G2    = 61;
+    R_ARM_LDR_PC_G1    = 62;
+    R_ARM_LDR_PC_G2    = 63;
+    R_ARM_LDRS_PC_G0   = 64;
+    R_ARM_LDRS_PC_G1   = 65;
+    R_ARM_LDRS_PC_G2   = 66;
+    R_ARM_LDC_PC_G0    = 67;
+    R_ARM_LDC_PC_G1    = 68;
+    R_ARM_LDC_PC_G2    = 69;
+    R_ARM_ALU_SB_G0_NC = 70;
+    R_ARM_ALU_SB_G0    = 71;
+    R_ARM_ALU_SB_G1_NC = 72;
+    R_ARM_ALU_SB_G1    = 73;
+    R_ARM_ALU_SB_G2    = 74;
+    R_ARM_LDR_SB_G0    = 75;
+    R_ARM_LDR_SB_G1    = 76;
+    R_ARM_LDR_SB_G2    = 77;
+    R_ARM_LDRS_SB_G0   = 78;
+    R_ARM_LDRS_SB_G1   = 79;
+    R_ARM_LDRS_SB_G2   = 80;
+    R_ARM_LDC_SB_G0    = 81;
+    R_ARM_LDC_SB_G1    = 82;
+    R_ARM_LDC_SB_G2    = 83;
+    R_ARM_MOVW_BREL_NC = 84;
+    R_ARM_MOVT_BREL    = 85;
+    R_ARM_MOVW_BREL    = 86;
+    R_ARM_THM_MOVW_BREL_NC = 87;
+    R_ARM_THM_MOVT_BREL = 88;
+    R_ARM_THM_MOVW_BREL = 89;
+    R_ARM_TLS_GOTDESC   = 90;
+    R_ARM_TLS_CALL      = 91;
+    R_ARM_TLS_DESCSEQ   = 92;
+    R_ARM_THM_TLS_CALL  = 93;
+    R_ARM_PLT32_ABS     = 94;
+    R_ARM_GOT_ABS = 95;
+    R_ARM_GOT_PREL = 96;
+    R_ARM_GOT_BREL12 = 97;
+    R_ARM_GOTOFF12 = 98;
+    R_ARM_GOTRELAX = 99;
+    R_ARM_GNU_VTENTRY = 100;   // deprecated - old C++ abi
+    R_ARM_GNU_VTINHERIT = 101; // deprecated - old C++ abi
+    R_ARM_THM_JUMP11 = 102;
+    R_ARM_THM_JUMP8  = 103;
+    R_ARM_TLS_GD32   = 104;
+    R_ARM_TLS_LDM32  = 105;
+    R_ARM_TLS_LDO32  = 106;
+    R_ARM_TLS_IE32   = 107;
+    R_ARM_TLS_LE32   = 108;
+    R_ARM_TLS_LDO12  = 109;
+    R_ARM_TLS_LE12   = 110;
+    R_ARM_TLS_IE12GP = 111;
+    { 112-127 are for private experiments }
+    { 128 is obsolete }
+    R_ARM_THM_TLS_DESCSEQ = 129;
+    R_ARM_IRELATIVE = 160;
+
+    { Section types }
+    SHT_ARM_EXIDX          = $70000001;
+    SHT_ARM_PREEMPTMAP     = $70000002;
+    SHT_ARM_ATTRIBUTES     = $70000003;
+    SHT_ARM_DEBUGOVERLAY   = $70000004;
+    SHT_ARM_OVERLAYSECTION = $70000005;
+
+    TCB_SIZE = 8;
+
+  { Using short identifiers to save typing. This ARM thing has more relocations
+    than it has instructions... }
+  const
+    g0=1;
+    g1=2;
+    g2=3;
+    gpmask=3;
+    pc=4;
+    nc=8;
+    thm=16;
+
+  type
+    TArmRelocProp=record
+      name: PChar;
+      flags: byte;      // bits 0,1: group, bit 2: PC-relative, bit 3: unchecked,
+                        // bit 4: THUMB
+    end;
+
+  const
+    relocprops: array[0..111] of TArmRelocProp = (
+      (name: 'R_ARM_NONE';     flags: 0),                //
+      (name: 'R_ARM_PC24';     flags: pc),               //
+      (name: 'R_ARM_ABS32';    flags: 0),                //
+      (name: 'R_ARM_REL32';    flags: pc),               //
+      (name: 'R_ARM_LDR_PC_G0'; flags: g0+pc),           //
+      (name: 'R_ARM_ABS16';    flags: 0),
+      (name: 'R_ARM_ABS12';    flags: 0),
+      (name: 'R_ARM_THM_ABS5'; flags: thm),
+      (name: 'R_ARM_ABS8';     flags: 0),
+      (name: 'R_ARM_SBREL32';  flags: 0),
+      (name: 'R_ARM_THM_CALL'; flags: thm),
+      (name: 'R_ARM_THM_PC8';  flags: pc+thm),
+      (name: 'R_ARM_BREL_ADJ'; flags: 0),
+      (name: 'R_ARM_TLS_DESC'; flags: 0),
+      (name: 'obsolete(14)';   flags: 0),
+      (name: 'obsolete(15)';   flags: 0),
+      (name: 'obsolete(16)';   flags: 0),
+      (name: 'R_ARM_TLS_DTPMOD32'; flags: 0),
+      (name: 'R_ARM_TLS_DTPOFF32'; flags: 0),
+      (name: 'R_ARM_TLS_TPOFF32';  flags: 0),
+      (name: 'R_ARM_COPY';     flags: 0),
+      (name: 'R_ARM_GLOB_DAT'; flags: 0),
+      (name: 'R_ARM_JUMP_SLOT'; flags: 0),
+      (name: 'R_ARM_RELATIVE'; flags: 0),
+      (name: 'R_ARM_GOTOFF32'; flags: 0),
+      (name: 'R_ARM_BASE_PREL'; flags: pc),              //
+      (name: 'R_ARM_GOT_BREL'; flags: 0),                //
+      (name: 'R_ARM_PLT32';    flags: pc),               //
+      (name: 'R_ARM_CALL';     flags: pc),               //
+      (name: 'R_ARM_JUMP24';   flags: pc),               //
+      (name: 'R_ARM_THM_JUMP24'; flags: thm),
+      (name: 'R_ARM_BASE_ABS'; flags: 0),
+      (name: 'obsolete(32)';   flags: 0),
+      (name: 'obsolete(33)';   flags: 0),
+      (name: 'obsolete(34)';   flags: 0),
+      (name: 'R_ARM_LDR_SBREL_11_0'; flags: g0),
+      (name: 'R_ARM_ALU_SBREL_19_12'; flags: g1),
+      (name: 'R_ARM_ALU_SBREL_27_20'; flags: g2),
+      (name: 'R_ARM_TARGET1';  flags: 0),
+      (name: 'R_ARM_SBREL31';  flags: 0),
+      (name: 'R_ARM_V4BX';     flags: 0),
+      (name: 'R_ARM_TARGET2';  flags: 0),
+      (name: 'R_ARM_PREL31';   flags: 0),
+      (name: 'R_ARM_MOVW_ABS_NC'; flags: nc),
+      (name: 'R_ARM_MOVT_ABS'; flags: 0),
+      (name: 'R_ARM_MOVW_PREL_NC'; flags: nc),
+      (name: 'R_ARM_MOVT_PREL'; flags: 0),
+      (name: 'R_ARM_THM_MOVW_ABS_NC';  flags: nc+thm),
+      (name: 'R_ARM_THM_MOVT_ABS';     flags: thm),
+      (name: 'R_ARM_THM_MOVW_PREL_NC'; flags: nc+thm),
+      (name: 'R_ARM_THM_MOVT_PREL';    flags: thm),
+      (name: 'R_ARM_THM_JUMP19';       flags: thm),
+      (name: 'R_ARM_THM_JUMP6';        flags: thm),
+      (name: 'R_ARM_THM_ALU_PREL_11_0'; flags: thm+pc),
+      (name: 'R_ARM_THM_PC12';         flags: thm+pc),
+      (name: 'R_ARM_ABS32_NOI';    flags: 0),
+      (name: 'R_ARM_REL32_NOI';    flags: pc),
+      (name: 'R_ARM_ALU_PC_G0_NC'; flags: pc+g0+nc),     //
+      (name: 'R_ARM_ALU_PC_G0';    flags: pc+g0),        //
+      (name: 'R_ARM_ALU_PC_G1_NC'; flags: pc+g1+nc),     //
+      (name: 'R_ARM_ALU_PC_G1';    flags: pc+g1),        //
+      (name: 'R_ARM_ALU_PC_G2';    flags: pc+g2),        //
+      (name: 'R_ARM_LDR_PC_G1';    flags: pc+g1),        //
+      (name: 'R_ARM_LDR_PC_G2';    flags: pc+g2),        //
+      (name: 'R_ARM_LDRS_PC_G0';   flags: pc+g0),        //
+      (name: 'R_ARM_LDRS_PC_G1';   flags: pc+g1),        //
+      (name: 'R_ARM_LDRS_PC_G2';   flags: pc+g2),        //
+      (name: 'R_ARM_LDC_PC_G0';    flags: pc+g0),        //
+      (name: 'R_ARM_LDC_PC_G1';    flags: pc+g1),        //
+      (name: 'R_ARM_LDC_PC_G2';    flags: pc+g2),        //
+      (name: 'R_ARM_ALU_SB_G0_NC'; flags: g0+nc),        //
+      (name: 'R_ARM_ALU_SB_G0';    flags: g0),           //
+      (name: 'R_ARM_ALU_SB_G1_NC'; flags: g1+nc),        //
+      (name: 'R_ARM_ALU_SB_G1';    flags: g1),           //
+      (name: 'R_ARM_ALU_SB_G2';    flags: g2),           //
+      (name: 'R_ARM_LDR_SB_G0';    flags: g0),           //
+      (name: 'R_ARM_LDR_SB_G1';    flags: g1),           //
+      (name: 'R_ARM_LDR_SB_G2';    flags: g2),           //
+      (name: 'R_ARM_LDRS_SB_G0';   flags: g0),           //
+      (name: 'R_ARM_LDRS_SB_G1';   flags: g1),           //
+      (name: 'R_ARM_LDRS_SB_G2';   flags: g2),           //
+      (name: 'R_ARM_LDC_SB_G0';    flags: g0),           //
+      (name: 'R_ARM_LDC_SB_G1';    flags: g1),           //
+      (name: 'R_ARM_LDC_SB_G2';    flags: g2),           //
+      (name: 'R_ARM_MOVW_BREL_NC'; flags: nc),
+      (name: 'R_ARM_MOVT_BREL';    flags: 0),
+      (name: 'R_ARM_MOVW_BREL';    flags: 0),
+      (name: 'R_ARM_THM_MOVW_BREL_NC'; flags: nc+thm),
+      (name: 'R_ARM_THM_MOVT_BREL'; flags: thm),
+      (name: 'R_ARM_THM_MOVW_BREL'; flags: thm),
+      (name: 'R_ARM_TLS_GOTDESC';   flags: 0),
+      (name: 'R_ARM_TLS_CALL';      flags: 0),
+      (name: 'R_ARM_TLS_DESCSEQ';   flags: 0),
+      (name: 'R_ARM_THM_TLS_CALL';  flags: 0),
+      (name: 'R_ARM_PLT32_ABS';     flags: 0),
+      (name: 'R_ARM_GOT_ABS';       flags: 0),
+      (name: 'R_ARM_GOT_PREL';      flags: pc),          //
+      (name: 'R_ARM_GOT_BREL12';    flags: 0),
+      (name: 'R_ARM_GOTOFF12';      flags: 0),
+      (name: 'R_ARM_GOTRELAX';      flags: 0),
+      (name: 'R_ARM_GNU_VTENTRY';   flags: 0),
+      (name: 'R_ARM_GNU_VTINHERIT'; flags: 0),
+      (name: 'R_ARM_THM_JUMP11';    flags: thm),
+      (name: 'R_ARM_THM_JUMP8';     flags: thm),
+      (name: 'R_ARM_TLS_GD32';      flags: 0),
+      (name: 'R_ARM_TLS_LDM32';     flags: 0),
+      (name: 'R_ARM_TLS_LDO32';     flags: 0),
+      (name: 'R_ARM_TLS_IE32';      flags: 0),
+      (name: 'R_ARM_TLS_LE32';      flags: 0),
+      (name: 'R_ARM_TLS_LDO12';     flags: 0),
+      (name: 'R_ARM_TLS_LE12';      flags: 0),
+      (name: 'R_ARM_TLS_IE12GP';    flags: 0)
+    );
+
+{****************************************************************************
+                              ELF Target methods
+****************************************************************************}
+
+  function elf_arm_encodereloc(objrel:TObjRelocation):byte;
+    begin
+      case objrel.typ of
+        RELOC_NONE:
+          result:=R_ARM_NONE;
+        RELOC_ABSOLUTE:
+          result:=R_ARM_ABS32;
+        RELOC_RELATIVE:
+          result:=R_ARM_REL32;
+      else
+        result:=0;
+        InternalError(2012110602);
+      end;
+    end;
+
+  function elf_arm_relocname(reltyp:byte):string;
+    begin
+      if reltyp<=high(relocprops) then
+        result:=relocprops[reltyp].name
+      else
+        case reltyp of
+          112..127:
+            result:='R_ARM_PRIVATE_'+tostr(reltyp-112);
+          R_ARM_THM_TLS_DESCSEQ:
+            result:='R_ARM_THM_TLS_DESCSEQ';
+          R_ARM_IRELATIVE:
+            result:='R_ARM_IRELATIVE';
+        else
+          result:='unknown ('+tostr(reltyp)+')';
+        end;
+    end;
+
+  procedure elf_arm_loadreloc(objrel:TObjRelocation);
+    begin
+      if (objrel.ftype=R_ARM_V4BX) then
+        objrel.flags:=objrel.flags or rf_nosymbol;
+    end;
+
+  function elf_arm_loadsection(objinput:TElfObjInput;objdata:TObjData;const shdr:TElfsechdr;shindex:longint):boolean;
+    var
+      secname:string;
+    begin
+      case shdr.sh_type of
+        SHT_ARM_EXIDX,
+        SHT_ARM_PREEMPTMAP,
+        SHT_ARM_ATTRIBUTES:
+          begin
+            objinput.CreateSection(shdr,shindex,objdata,secname);
+            result:=true;
+          end;
+      else
+        writeln(hexstr(shdr.sh_type,8));
+        result:=false;
+      end;
+    end;
+
+{****************************************************************************
+                              TELFExeOutputARM
+****************************************************************************}
+
+  function group_reloc_mask(value:longword;n:longint;out final_residual:longword):longword;
+    var
+      i:longint;
+      g_n:longword;
+      shift:longint;
+    begin
+      result:=0;
+      for i:=0 to n do
+        begin
+          if (value=0) then
+            shift:=0
+          else
+            { MSB in the residual, aligned to a 2-bit boundary }
+            shift:=max(0,(bsrdword(value) and (not 1))-6);
+
+          { Calculate plain g_n and encode it into constant+rotation form }
+          g_n:=value and ($ff shl shift);
+          result:=(g_n shr shift);
+          if (g_n>$FF) then
+            result:=result or ((32-shift) div 2) shl 8;
+
+          { Mask away the processed part of residual }
+          value:=value and (not g_n);
+        end;
+      final_residual:=value;
+    end;
+
+
+  procedure TElfExeOutputARM.MaybeWriteGOTEntry(reltyp:byte;relocval:aint;objsym:TObjSymbol);
+    var
+      gotoff,tmp:aword;
+    begin
+      gotoff:=objsym.exesymbol.gotoffset;
+      if gotoff=0 then
+        InternalError(2012060902);
+
+      { the GOT slot itself, and a dynamic relocation for it }
+      { TODO: only data symbols must get here }
+      if gotoff=gotobjsec.Data.size+sizeof(pint) then
+        begin
+          gotobjsec.write(relocval,sizeof(pint));
+
+          tmp:=gotobjsec.mempos+gotoff-sizeof(pint);
+          if (objsym.exesymbol.dynindex>0) then
+            begin
+              WriteDynRelocEntry(tmp,R_ARM_GLOB_DAT,objsym.exesymbol.dynindex,0)
+            end
+          else if IsSharedLibrary then
+            WriteDynRelocEntry(tmp,R_ARM_RELATIVE,0,relocval);
+        end;
+    end;
+
+
+  procedure TElfExeOutputARM.WriteFirstPLTEntry;
+    begin
+      pltobjsec.WriteBytes(
+        #$04#$E0#$2D#$E5+       // str   lr, [sp, #-4]!
+        #$04#$E0#$9F#$E5+       // ldr   lr, [pc, #4]
+        #$0E#$E0#$8F#$E0+       // add   lr, pc, lr
+        #$08#$F0#$BE#$E5);      // ldr   pc, [lr, #8]!
+                                // .long _GLOBAL_OFFSET_TABLE-.
+      pltobjsec.writeReloc_internal(gotpltobjsec,0,4,RELOC_RELATIVE);
+    end;
+
+
+  procedure TElfExeOutputARM.WritePLTEntry(exesym: TExeSymbol);
+    var
+      tmp: longword;
+      sym:TObjSymbol;
+    begin
+      { TODO: it may be beneficial to postpone processing until after mempos pass,
+        and calculate instructions directly, instead of messing with complex relocations. }
+      { Group relocation to "section+offset" with REL-style is impossible, because the
+        offset has be encoded into instructions, and it is only possible for offsets
+        representable as shifter constants. Therefore we need to define a symbol
+        (and risk a name conflict, to some degree) }
+      internalobjdata.setsection(gotpltobjsec);
+      sym:=internalobjdata.SymbolDefine(exesym.name+'_ptr',AB_LOCAL,AT_DATA);
+      pltobjsec.WriteBytes(
+        #$08#$C0#$4F#$E2+      // add ip,pc,#:pc_g0_nc:sym-8
+        #$04#$C0#$4C#$E2+      // add ip,ip,#:pc_g1_nc:sym-4
+        #$00#$F0#$BC#$E5);     // ldr pc,[ip,#:pc_g2:sym]!
+
+      pltobjsec.addrawReloc(pltobjsec.size-12,sym,R_ARM_ALU_PC_G0_NC);
+      pltobjsec.addrawReloc(pltobjsec.size-8,sym,R_ARM_ALU_PC_G1_NC);
+      pltobjsec.addrawReloc(pltobjsec.size-4,sym,R_ARM_LDR_PC_G2);
+
+      { .got.plt slot initially points to the first PLT entry }
+      gotpltobjsec.writeReloc_internal(pltobjsec,0,sizeof(pint),RELOC_ABSOLUTE);
+      { write a .rel.plt entry (Elf32_rel record) }
+      pltrelocsec.writeReloc_internal(gotpltobjsec,gotpltobjsec.size-sizeof(pint),sizeof(pint),RELOC_ABSOLUTE);
+      tmp:=(exesym.dynindex shl 8) or R_ARM_JUMP_SLOT;
+      pltrelocsec.write(tmp,sizeof(tmp));
+      if ElfTarget.relocs_use_addend then
+        pltrelocsec.writezeros(sizeof(pint));
+    end;
+
+
+  procedure TElfExeOutputARM.WriteIndirectPLTEntry(exesym: TExeSymbol);
+    begin
+      inherited WriteIndirectPLTEntry(exesym);
+    end;
+
+
+  procedure TElfExeOutputARM.GOTRelocPass1(objsec:TObjSection;var idx:longint);
+    var
+      objreloc:TObjRelocation;
+      exesym:TExeSymbol;
+      objsym:TObjSymbol;
+      reltyp:byte;
+    begin
+      objreloc:=TObjRelocation(objsec.ObjRelocations[idx]);
+      if (ObjReloc.flags and rf_raw)=0 then
+        reltyp:=ElfTarget.encodereloc(ObjReloc)
+      else
+        reltyp:=ObjReloc.ftype;
+
+      case reltyp of
+        // Any call or jump can go through PLT, no x86-like segregation here.
+        R_ARM_PC24,
+        R_ARM_CALL,
+        R_ARM_JUMP24,
+        R_ARM_PREL31,
+        R_ARM_THM_CALL,
+        R_ARM_THM_JUMP24,
+        R_ARM_THM_JUMP19,
+        R_ARM_PLT32:
+          begin
+            if (objreloc.symbol=nil) or (objreloc.symbol.exesymbol=nil) then
+              exit;
+            exesym:=objreloc.symbol.exesymbol;
+            exesym.objsymbol.refs:=exesym.objsymbol.refs or symref_plt;
+          end;
+
+        R_ARM_ABS32:
+          if Assigned(ObjReloc.symbol.exesymbol) then
+            begin
+              objsym:=ObjReloc.symbol.exesymbol.ObjSymbol;
+              if (oso_executable in objsec.SecOptions) or
+                not (oso_write in objsec.SecOptions) then
+                  objsym.refs:=objsym.refs or symref_from_text;
+            end;
+      end;
+
+      case reltyp of
+        R_ARM_ABS32:
+          begin
+            if not IsSharedLibrary then
+              exit;
+            if (oso_executable in objsec.SecOptions) or
+               not (oso_write in objsec.SecOptions) then
+              hastextrelocs:=True;
+            dynrelocsec.alloc(dynrelocsec.shentsize);
+            objreloc.flags:=objreloc.flags or rf_dynamic;
+          end;
+
+        //R_ARM_GOT_ABS,
+        //R_ARM_GOT_PREL,
+        //R_ARM_GOT_BREL12,
+        R_ARM_GOT_BREL:
+          begin
+            AllocGOTSlot(objreloc.symbol);
+          end;
+
+        R_ARM_TLS_IE32:
+          AllocGOTSlot(objreloc.symbol);
+
+      end;
+    end;
+
+
+  procedure TElfExeOutputARM.DoRelocationFixup(objsec:TObjSection);
+  var
+    i,zero:longint;
+    objreloc: TObjRelocation;
+    tmp,
+    address,
+    relocval : aint;
+    relocsec : TObjSection;
+    data: TDynamicArray;
+    reltyp: byte;
+    group:longint;
+    rotation:longint;
+    residual,g_n:longword;
+    curloc: aword;
+  begin
+    data:=objsec.data;
+    for i:=0 to objsec.ObjRelocations.Count-1 do
+      begin
+        objreloc:=TObjRelocation(objsec.ObjRelocations[i]);
+        case objreloc.typ of
+          RELOC_NONE:
+            continue;
+          RELOC_ZERO:
+            begin
+              data.Seek(objreloc.dataoffset);
+              zero:=0;
+              data.Write(zero,4);
+              continue;
+            end;
+        end;
+
+        if (objreloc.flags and rf_raw)=0 then
+          reltyp:=ElfTarget.encodereloc(objreloc)
+        else
+          reltyp:=objreloc.ftype;
+
+        { TODO: TARGET1 and TARGET2 are intended to be configured via commandline }
+        if (reltyp=R_ARM_TARGET1) then
+          reltyp:=R_ARM_ABS32;             { may be ABS32 or REL32 }
+        if (reltyp=R_ARM_TARGET2) then
+          reltyp:=R_ARM_ABS32;             { may be ABS32,REL32 or GOT_PREL }
+
+        if ElfTarget.relocs_use_addend then
+          address:=objreloc.orgsize
+        else
+          begin
+            data.Seek(objreloc.dataoffset);
+            data.Read(address,4);
+          end;
+        if assigned(objreloc.symbol) then
+          begin
+            relocsec:=objreloc.symbol.objsection;
+            relocval:=objreloc.symbol.address;
+          end
+        else if assigned(objreloc.objsection) then
+          begin
+            relocsec:=objreloc.objsection;
+            relocval:=objreloc.objsection.mempos
+          end
+        else if (reltyp=R_ARM_V4BX) then
+          continue        // ignore for now
+        else
+          internalerror(2012060702);
+
+        { Only debug sections are allowed to have relocs pointing to unused sections }
+        if assigned(relocsec) and not (relocsec.used and assigned(relocsec.exesection)) and
+           not (oso_debug in objsec.secoptions) then
+          begin
+            writeln(objsec.fullname,' references ',relocsec.fullname);
+            internalerror(2012060703);
+          end;
+
+        curloc:=objsec.mempos+objreloc.dataoffset;
+        if (relocsec=nil) or (relocsec.used) then
+          case reltyp of
+
+            R_ARM_ABS32:
+              begin
+                if (objreloc.flags and rf_dynamic)<>0 then
+                  begin
+                    if (objreloc.symbol=nil) or
+                       (objreloc.symbol.exesymbol=nil) or
+                       (objreloc.symbol.exesymbol.dynindex=0) then
+                      begin
+                        address:=address+relocval;
+                        WriteDynRelocEntry(objreloc.dataoffset+objsec.mempos,R_ARM_RELATIVE,0,address);
+                      end
+                    else
+                      { Don't modify address in this case, as it serves as addend for RTLD }
+                      WriteDynRelocEntry(objreloc.dataoffset+objsec.mempos,R_ARM_ABS32,objreloc.symbol.exesymbol.dynindex,0);
+                  end
+                else
+                  address:=address+relocval;
+              end;
+
+            R_ARM_REL32:
+              begin
+                address:=address+relocval-curloc;
+              end;
+
+            R_ARM_PC24,
+            R_ARM_PLT32,
+            R_ARM_JUMP24,
+            R_ARM_CALL:
+              begin
+                { R_ARM_PC24 is deprecated in favour of R_ARM_JUMP24 and R_ARM_CALL,
+                  which allow to distinguish opcodes without examining them.
+                  Difference is:
+                  1) when target is Thumb, BL can be changed to BLX, while B has
+                  to go via thunking code.
+                  2) when target is unresolved weak symbol, CALL must be changed to NOP,
+                  while JUMP24 behavior is unspecified. }
+                tmp:=sarlongint((address and $00FFFFFF) shl 8,6);
+                tmp:=tmp+relocval-curloc;
+                // TODO: check overflow
+                address:=(address and $FF000000) or ((tmp and $3FFFFFE) shr 2);
+              end;
+
+            R_ARM_BASE_PREL:    { GOTPC }
+              address:=address+gotsymbol.address-curloc;
+
+            R_ARM_GOT_BREL:     { GOT32 }
+              begin
+                MaybeWriteGOTEntry(reltyp,relocval,objreloc.symbol);
+                address:=address+gotobjsec.mempos+objreloc.symbol.exesymbol.gotoffset-sizeof(pint)-gotsymbol.address;
+              end;
+
+            R_ARM_GOTOFF32:
+              address:=address+relocval-gotsymbol.address;
+
+            R_ARM_ALU_PC_G0_NC,
+            R_ARM_ALU_PC_G1_NC,
+            R_ARM_ALU_PC_G0,
+            R_ARM_ALU_PC_G1,
+            R_ARM_ALU_PC_G2,
+            R_ARM_ALU_SB_G0_NC,
+            R_ARM_ALU_SB_G1_NC,
+            R_ARM_ALU_SB_G0,
+            R_ARM_ALU_SB_G1,
+            R_ARM_ALU_SB_G2:
+              begin
+                group:=(relocprops[reltyp].flags and gpmask)-1;
+                if group<0 then
+                  InternalError(2012112601);
+
+                if (not ElfTarget.relocs_use_addend) then
+                  begin
+                    { initial addend must be determined by parsing the instruction }
+                    tmp:=address and $FF;
+                    rotation:=(address and $F00) shr 7;  { is in multpile of 2 bits }
+                    if rotation<>0 then
+                      tmp:=RorDword(tmp,rotation);
+                    case (address and $1E00000) of
+                      1 shl 23: ;           { ADD instruction }
+                      1 shl 22: tmp:=-tmp;  { SUB instruction }
+                    else
+                      Comment(v_error,'Group ALU relocations are permitted only for ADD or SUB instructions');
+                      continue;
+                    end;
+                  end
+                else  { TODO: must read the instruction anyway!! }
+                  tmp:=address;
+
+                if (relocprops[reltyp].flags and pc)<>0 then
+                  tmp:=tmp+relocval-curloc
+                else
+                  tmp:=tmp+relocval{-SB};  { assuming zero segment base }
+
+                g_n:=group_reloc_mask(abs(tmp),group,residual);
+                {TODO: check for overflow}
+
+                address:=address and $FF1FF000 or g_n;
+                { set opcode depending on the sign of resulting value }
+                if tmp<0 then
+                  address:=address or (1 shl 22)
+                else
+                  address:=address or (1 shl 23);
+              end;
+
+            R_ARM_LDR_PC_G0,
+            R_ARM_LDR_PC_G1,
+            R_ARM_LDR_PC_G2,
+            R_ARM_LDR_SB_G0,
+            R_ARM_LDR_SB_G1,
+            R_ARM_LDR_SB_G2:
+              begin
+                group:=(relocprops[reltyp].flags and gpmask)-1;
+                if group<0 then
+                  InternalError(2012112602);
+
+                if (not ElfTarget.relocs_use_addend) then
+                  begin
+                    tmp:=(address and $FFF);
+                    if (address and (1 shl 23))=0 then
+                      tmp:=-tmp;
+                  end
+                else   { TODO: must read the instruction anyway }
+                  tmp:=address;
+
+                if (relocprops[reltyp].flags and pc)<>0 then
+                  tmp:=tmp+relocval-curloc
+                else
+                  tmp:=tmp+relocval{-SB};  { assuming zero segment base }
+
+                group_reloc_mask(abs(tmp),group-1,residual);
+                if residual>$FFF then
+                  InternalError(2012112603);  { TODO: meaningful overflow error message }
+
+                address:=address and $FF7FF000 or residual;
+                if tmp>=0 then
+                  address:=address or (1 shl 23);
+              end;
+
+            R_ARM_LDRS_PC_G0,
+            R_ARM_LDRS_PC_G1,
+            R_ARM_LDRS_PC_G2,
+            R_ARM_LDRS_SB_G0,
+            R_ARM_LDRS_SB_G1,
+            R_ARM_LDRS_SB_G2:
+              begin
+                group:=(relocprops[reltyp].flags and gpmask)-1;
+                if group<0 then
+                  InternalError(2012112606);
+
+                if (not ElfTarget.relocs_use_addend) then
+                  begin
+                    tmp:=((address and $F00) shr 4) or (address and $F);
+                    if (address and (1 shl 23))=0 then
+                      tmp:=-tmp;
+                  end
+                else { TODO: must read the instruction anyway }
+                  tmp:=address;
+
+                if (relocprops[reltyp].flags and pc)<>0 then
+                  tmp:=tmp+relocval-curloc
+                else
+                  tmp:=tmp+relocval{-SB};  { assuming zero segment base }
+
+                group_reloc_mask(abs(tmp),group-1,residual);
+                if (residual>$FF) then
+                  InternalError(2012112607); { TODO: meaningful overflow error message }
+
+                address:=address and $FF7FF0F0 or ((residual and $F0) shl 4) or (residual and $F);
+                if tmp>=0 then
+                  address:=address or (1 shl 23);
+              end;
+
+            R_ARM_LDC_PC_G0,
+            R_ARM_LDC_PC_G1,
+            R_ARM_LDC_PC_G2,
+            R_ARM_LDC_SB_G0,
+            R_ARM_LDC_SB_G1,
+            R_ARM_LDC_SB_G2:
+              begin
+                group:=(relocprops[reltyp].flags and gpmask)-1;
+                if group<0 then
+                  InternalError(2012112604);
+
+                if (not ElfTarget.relocs_use_addend) then
+                  begin
+                    tmp:=(address and $FF) shl 2;
+                    if (address and (1 shl 23))=0 then
+                      tmp:=-tmp;
+                  end
+                else { TODO: must read the instruction anyway }
+                  tmp:=address;
+
+                if (relocprops[reltyp].flags and pc)<>0 then
+                  tmp:=tmp+relocval-curloc
+                else
+                  tmp:=tmp+relocval{-SB};  { assuming zero segment base }
+
+                group_reloc_mask(abs(tmp),group-1,residual);
+                { residual must be divisible by 4 and fit into 8 bits after having been divided }
+                if ((residual and 3)<>0) or (residual>$3FF) then
+                  InternalError(2012112605);  { TODO: meaningful overflow error message }
+
+                address:=address and $FF7FFF00 or (residual shr 2);
+                if tmp>=0 then
+                  address:=address or (1 shl 23);
+              end;
+
+            R_ARM_TLS_IE32:
+              begin
+                relocval:=relocval-tlsseg.mempos+align_aword(TCB_SIZE,tlsseg.align);
+                MaybeWriteGOTEntry(reltyp,relocval,objreloc.symbol);
+                { resolves to PC-relative offset to GOT slot }
+                relocval:=gotobjsec.mempos+objreloc.symbol.exesymbol.gotoffset-sizeof(pint);
+                address:=address+relocval-curloc;
+              end;
+
+            R_ARM_TLS_LE32:
+              if IsSharedLibrary then
+                { TODO: error message saying "recompile with -Cg" isn't correct. Or is it? }
+                ReportNonDSOReloc(reltyp,objsec,objreloc)
+              else
+                address:=relocval-tlsseg.mempos+align_aword(TCB_SIZE,tlsseg.align);
+
+          else
+            begin
+              writeln(objreloc.ftype);
+              internalerror(200604014);
+            end;
+          end
+        else           { not relocsec.Used }
+          address:=0;  { Relocation in debug section points to unused section, which is eliminated by linker }
+
+        data.Seek(objreloc.dataoffset);
+        data.Write(address,4);
+      end;
+    end;
+
+
+{*****************************************************************************
+                                    Initialize
+*****************************************************************************}
+
+  const
+    elf_target_arm: TElfTarget =
+      (
+        max_page_size:     $8000;
+        exe_image_base:    $8000;
+        machine_code:      EM_ARM;
+        relocs_use_addend: false;
+        dyn_reloc_codes: (
+          R_ARM_RELATIVE,
+          R_ARM_GLOB_DAT,
+          R_ARM_JUMP_SLOT,
+          R_ARM_COPY,
+          R_ARM_IRELATIVE
+        );
+        relocname:         @elf_arm_relocName;
+        encodereloc:       @elf_arm_encodeReloc;
+        loadreloc:         @elf_arm_loadReloc;
+        loadsection:       @elf_arm_loadSection;
+      );
+
+initialization
+  ElfTarget:=elf_target_arm;
+  ElfExeOutputClass:=TElfExeOutputARM;
+
+end.
+

Різницю між файлами не показано, бо вона завелика
+ 408 - 859
compiler/arm/cpuinfo.pas


+ 85 - 34
compiler/arm/cpupara.pas

@@ -28,9 +28,8 @@ unit cpupara;
 
     uses
        globtype,globals,
-       aasmtai,aasmdata,
        cpuinfo,cpubase,cgbase,cgutils,
-       symconst,symbase,symtype,symdef,parabase,paramgr;
+       symconst,symtype,symdef,parabase,paramgr;
 
     type
        tarmparamanager = class(tparamanager)
@@ -38,13 +37,15 @@ unit cpupara;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
           function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
-          function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
-          procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
+          function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
+          procedure getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
          private
-          procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister);
+          procedure init_values(p: tabstractprocdef; side: tcallercallee; var curintreg,
+           curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword;
+ var sparesinglereg: tregister);
           function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
             var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister; isvariadic: boolean):longint;
        end;
@@ -53,7 +54,6 @@ unit cpupara;
 
     uses
        verbose,systems,cutils,
-       rgobj,
        defutil,symsym,symtable;
 
 
@@ -78,21 +78,28 @@ unit cpupara;
       end;
 
 
-    procedure tarmparamanager.getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);
+    procedure tarmparamanager.getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);
       var
         paraloc : pcgparalocation;
+        psym : tparavarsym;
+        pdef : tdef;
       begin
         if nr<1 then
           internalerror(2002070801);
+        psym:=tparavarsym(pd.paras[nr-1]);
+        pdef:=psym.vardef;
+        if push_addr_param(psym.varspez,pdef,pd.proccalloption) then
+          pdef:=getpointerdef(pdef);
         cgpara.reset;
-        cgpara.size:=def_cgsize(def);
+        cgpara.size:=def_cgsize(pdef);
         cgpara.intsize:=tcgsize2size[cgpara.size];
         cgpara.alignment:=std_param_align;
-        cgpara.def:=def;
+        cgpara.def:=pdef;
         paraloc:=cgpara.add_location;
         with paraloc^ do
           begin
-            size:=OS_INT;
+            def:=pdef;
+            size:=def_cgsize(pdef);
             { the four first parameters are passed into registers }
             if nr<=4 then
               begin
@@ -124,7 +131,7 @@ unit cpupara;
                 getparaloc:=LOC_MMREGISTER
               else if (calloption in [pocall_cdecl,pocall_cppdecl,pocall_softfloat]) or
                  (cs_fp_emulation in current_settings.moduleswitches) or
-                 (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16]) then
+                 (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_fpv4_s16]) then
                 { the ARM eabi also allows passing VFP values via VFP registers,
                   but Mac OS X doesn't seem to do that and linux only does it if
                   built with the "-mfloat-abi=hard" option }
@@ -201,12 +208,14 @@ unit cpupara;
       end;
 
 
-    function tarmparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
+    function tarmparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
       var
         i: longint;
         sym: tsym;
         fpufield: boolean;
       begin
+        if handle_common_ret_in_param(def,pd,result) then
+          exit;
         case def.typ of
           recorddef:
             begin
@@ -277,17 +286,22 @@ unit cpupara;
             else
               result:=false
           else
-            result:=inherited ret_in_param(def,calloption);
+            result:=inherited ret_in_param(def,pd);
         end;
       end;
 
 
-    procedure tarmparamanager.init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister);
+    procedure tarmparamanager.init_values(p : tabstractprocdef; side: tcallercallee;
+      var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister);
       begin
         curintreg:=RS_R0;
         curfloatreg:=RS_F0;
         curmmreg:=RS_D0;
-        cur_stack_offset:=0;
+
+        if (current_settings.cputype in cpu_thumb) and (side=calleeside) then
+          cur_stack_offset:=(p as tprocdef).total_stackframe_size
+        else
+          cur_stack_offset:=0;
         sparesinglereg := NR_NO;
       end;
 
@@ -353,6 +367,7 @@ unit cpupara;
                 paraloc^.loc:=LOC_REGISTER;
                 paraloc^.register:=NR_R0;
                 paraloc^.size:=OS_ADDR;
+                paraloc^.def:=voidpointertype;
                 break;
               end;
 
@@ -404,16 +419,28 @@ unit cpupara;
                  if (loc=LOC_REGISTER) and (paracgsize in [OS_F32,OS_F64,OS_F80]) then
                    case paracgsize of
                      OS_F32:
-                       paraloc^.size:=OS_32;
+                       begin
+                         paraloc^.size:=OS_32;
+                         paraloc^.def:=u32inttype;
+                       end;
                      OS_F64:
-                       paraloc^.size:=OS_32;
+                       begin
+                         paraloc^.size:=OS_32;
+                         paraloc^.def:=u32inttype;
+                       end;
                      else
                        internalerror(2005082901);
                    end
                  else if (paracgsize in [OS_NO,OS_64,OS_S64]) then
-                   paraloc^.size := OS_32
+                   begin
+                     paraloc^.size:=OS_32;
+                     paraloc^.def:=u32inttype;
+                   end
                  else
-                   paraloc^.size:=paracgsize;
+                   begin
+                     paraloc^.size:=paracgsize;
+                     paraloc^.def:=get_paraloc_def(paradef,paralen,firstparaloc);
+                   end;
                  case loc of
                     LOC_REGISTER:
                       begin
@@ -440,6 +467,7 @@ unit cpupara;
                             { LOC_REFERENCE always contains everything that's left }
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.size:=int_cgsize(paralen);
+                            paraloc^.def:=getarraydef(u8inttype,paralen);
                             if (side=callerside) then
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                             paraloc^.reference.offset:=stack_offset;
@@ -513,6 +541,7 @@ unit cpupara;
                             { LOC_REFERENCE always contains everything that's left }
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.size:=int_cgsize(paralen);
+                            paraloc^.def:=getarraydef(u8inttype,paralen);
                             if (side=callerside) then
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                             paraloc^.reference.offset:=stack_offset;
@@ -525,6 +554,7 @@ unit cpupara;
                         if push_addr_param(hp.varspez,paradef,p.proccalloption) then
                           begin
                             paraloc^.size:=OS_ADDR;
+                            paraloc^.def:=getpointerdef(paradef);
                             assignintreg
                           end
                         else
@@ -536,6 +566,7 @@ unit cpupara;
                               stack_offset:=align(stack_offset,8);
 
                              paraloc^.size:=paracgsize;
+                             paraloc^.def:=paradef;
                              paraloc^.loc:=LOC_REFERENCE;
                              paraloc^.reference.index:=NR_STACK_POINTER_REG;
                              paraloc^.reference.offset:=stack_offset;
@@ -550,17 +581,24 @@ unit cpupara;
                    begin
                      if paraloc^.loc=LOC_REFERENCE then
                        begin
-                         paraloc^.reference.index:=NR_FRAME_POINTER_REG;
-                         { on non-Darwin, the framepointer contains the value
-                           of the stack pointer on entry. On Darwin, the
-                           framepointer points to the previously saved
-                           framepointer (which is followed only by the saved
-                           return address -> framepointer + 4 = stack pointer
-                           on entry }
-                         if not(target_info.system in systems_darwin) then
-                           inc(paraloc^.reference.offset,4)
+                         if current_settings.cputype in cpu_thumb then
+                           begin
+                             paraloc^.reference.index:=NR_STACK_POINTER_REG;
+                           end
                          else
-                           inc(paraloc^.reference.offset,8);
+                           begin
+                             paraloc^.reference.index:=NR_FRAME_POINTER_REG;
+                             { on non-Darwin, the framepointer contains the value
+                               of the stack pointer on entry. On Darwin, the
+                               framepointer points to the previously saved
+                               framepointer (which is followed only by the saved
+                               return address -> framepointer + 4 = stack pointer
+                               on entry }
+                             if not(target_info.system in systems_darwin) then
+                               inc(paraloc^.reference.offset,4)
+                             else
+                               inc(paraloc^.reference.offset,8);
+                           end;
                        end;
                    end;
                  dec(paralen,tcgsize2size[paraloc^.size]);
@@ -605,10 +643,11 @@ unit cpupara;
                     internalerror(2012032501);
                 end;
                 paraloc^.size:=retcgsize;
+                paraloc^.def:=result.def;
               end
             else if (p.proccalloption in [pocall_softfloat]) or
                (cs_fp_emulation in current_settings.moduleswitches) or
-               (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16]) then
+               (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_fpv4_s16]) then
               begin
                 case retcgsize of
                   OS_64,
@@ -620,6 +659,7 @@ unit cpupara;
                       else
                         paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG;
                       paraloc^.size:=OS_32;
+                      paraloc^.def:=u32inttype;
                       paraloc:=result.add_location;
                       paraloc^.loc:=LOC_REGISTER;
                       if target_info.endian = endian_big then
@@ -627,6 +667,7 @@ unit cpupara;
                       else
                         paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG;
                       paraloc^.size:=OS_32;
+                      paraloc^.def:=u32inttype;
                     end;
                   OS_32,
                   OS_F32:
@@ -634,6 +675,7 @@ unit cpupara;
                       paraloc^.loc:=LOC_REGISTER;
                       paraloc^.register:=NR_FUNCTION_RETURN_REG;
                       paraloc^.size:=OS_32;
+                      paraloc^.def:=u32inttype;
                     end;
                   else
                     internalerror(2005082603);
@@ -644,6 +686,7 @@ unit cpupara;
                 paraloc^.loc:=LOC_FPUREGISTER;
                 paraloc^.register:=NR_FPU_RESULT_REG;
                 paraloc^.size:=retcgsize;
+                paraloc^.def:=result.def;
               end;
           end
           { Return in register }
@@ -657,6 +700,7 @@ unit cpupara;
                 else
                   paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG;
                 paraloc^.size:=OS_32;
+                paraloc^.def:=u32inttype;
                 paraloc:=result.add_location;
                 paraloc^.loc:=LOC_REGISTER;
                 if target_info.endian = endian_big then
@@ -664,15 +708,22 @@ unit cpupara;
                 else
                   paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG;
                 paraloc^.size:=OS_32;
+                paraloc^.def:=u32inttype;
               end
             else
               begin
                 paraloc^.loc:=LOC_REGISTER;
                 paraloc^.register:=NR_FUNCTION_RETURN_REG;
                 if (result.intsize<>3) then
-                  paraloc^.size:=retcgsize
+                  begin
+                    paraloc^.size:=retcgsize;
+                    paraloc^.def:=result.def;
+                  end
                 else
-                  paraloc^.size:=OS_32;
+                  begin
+                    paraloc^.size:=OS_32;
+                    paraloc^.def:=u32inttype;
+                  end;
               end;
           end;
       end;
@@ -684,7 +735,7 @@ unit cpupara;
         curintreg, curfloatreg, curmmreg: tsuperregister;
         sparesinglereg:tregister;
       begin
-        init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg);
+        init_values(p,side,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg);
 
         result:=create_paraloc_info_intern(p,side,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,false);
 
@@ -698,7 +749,7 @@ unit cpupara;
         curintreg, curfloatreg, curmmreg: tsuperregister;
         sparesinglereg:tregister;
       begin
-        init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg);
+        init_values(p,callerside,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg);
 
         result:=create_paraloc_info_intern(p,callerside,p.paras,curintreg,curfloatreg,curmmreg,cur_stack_offset,sparesinglereg,true);
         if (p.proccalloption in cstylearrayofconst) then

+ 113 - 43
compiler/arm/cpupi.pas

@@ -33,12 +33,18 @@ unit cpupi;
 
     type
        tarmprocinfo = class(tcgprocinfo)
+          { for arm thumb, we need to know the stackframe size before
+            starting procedure compilation, so this contains the stack frame size, the compiler
+            should assume
+            if this size is too little the procedure must be compiled again with a larger value }
+          stackframesize,
           floatregstart : aint;
           // procedure handle_body_start;override;
           // procedure after_pass1;override;
           procedure set_first_temp_offset;override;
           function calc_stackframe_size:longint;override;
           procedure init_framepointer; override;
+          procedure generate_parameter_info;override;
        end;
 
 
@@ -47,13 +53,16 @@ unit cpupi;
     uses
        globals,systems,
        cpubase,
-       aasmtai,aasmdata,
        tgobj,
-       symconst,symsym,paramgr,
+       symconst,symtype,symsym,paramgr,
        cgbase,cgutils,
-       cgobj;
+       cgobj,
+       defutil;
 
     procedure tarmprocinfo.set_first_temp_offset;
+      var
+        localsize : aint;
+        i : longint;
       begin
         { We allocate enough space to save all registers because we can't determine
           the necessary space because the used registers aren't known before
@@ -63,6 +72,13 @@ unit cpupi;
           is especially a problem when taking the address of a local. For now,
           this extra memory should hurt less than generating all local contants with offsets
           >256 as non shifter constants }
+        if (po_nostackframe in procdef.procoptions) then
+          begin
+             { maxpushedparasize sghould be zero,
+               if not we will get an error later. }
+             tg.setfirsttemp(maxpushedparasize);
+             exit;
+          end;
         if tg.direction = -1 then
           begin
             if (target_info.system<>system_arm_darwin) then
@@ -78,6 +94,40 @@ unit cpupi;
           end
         else
           tg.setfirsttemp(maxpushedparasize);
+
+        { estimate stack frame size }
+        if current_settings.cputype in cpu_thumb then
+          begin
+            stackframesize:=maxpushedparasize+32;
+            localsize:=0;
+            for i:=0 to procdef.localst.SymList.Count-1 do
+              if tsym(procdef.localst.SymList[i]).typ=localvarsym then
+                inc(localsize,tabstractnormalvarsym(procdef.localst.SymList[i]).getsize);
+            inc(stackframesize,localsize);
+
+            localsize:=0;
+            for i:=0 to procdef.parast.SymList.Count-1 do
+              if tsym(procdef.parast.SymList[i]).typ=paravarsym then
+                if is_open_string(tabstractnormalvarsym(procdef.parast.SymList[i]).vardef) then
+                  inc(localsize,256)
+                else
+                  inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize);
+
+            inc(stackframesize,localsize);
+
+            if pi_needs_implicit_finally in flags then
+              inc(stackframesize,40);
+
+            if pi_uses_exceptions in flags then
+              inc(stackframesize,40);
+
+            if procdef.proctypeoption in [potype_constructor] then
+              inc(stackframesize,40*2);
+
+            inc(stackframesize,estimatedtempsize);
+
+            stackframesize:=Align(stackframesize,8);
+          end;
       end;
 
 
@@ -88,60 +138,80 @@ unit cpupi;
          floatsavesize : aword;
          regs: tcpuregisterset;
       begin
-        maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
-        floatsavesize:=0;
-        case current_settings.fputype of
-          fpu_fpa,
-          fpu_fpa10,
-          fpu_fpa11:
-            begin
-              { save floating point registers? }
-              firstfloatreg:=RS_NO;
-              regs:=cg.rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall);
-              for r:=RS_F0 to RS_F7 do
-                if r in regs then
-                  begin
-                    if firstfloatreg=RS_NO then
-                      firstfloatreg:=r;
-                    lastfloatreg:=r;
-                  end;
-              if firstfloatreg<>RS_NO then
-                floatsavesize:=(lastfloatreg-firstfloatreg+1)*12;
-            end;
-          fpu_vfpv2,
-          fpu_vfpv3,
-          fpu_vfpv3_d16:
-            begin
-              floatsavesize:=0;
-              regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);
-              for r:=RS_D0 to RS_D31 do
-                if r in regs then
-                  inc(floatsavesize,8);
+        if current_settings.cputype in cpu_thumb then
+          result:=stackframesize
+        else
+          begin
+            maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
+            floatsavesize:=0;
+            case current_settings.fputype of
+              fpu_fpa,
+              fpu_fpa10,
+              fpu_fpa11:
+                begin
+                  { save floating point registers? }
+                  firstfloatreg:=RS_NO;
+                  regs:=cg.rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall);
+                  for r:=RS_F0 to RS_F7 do
+                    if r in regs then
+                      begin
+                        if firstfloatreg=RS_NO then
+                          firstfloatreg:=r;
+                        lastfloatreg:=r;
+                      end;
+                  if firstfloatreg<>RS_NO then
+                    floatsavesize:=(lastfloatreg-firstfloatreg+1)*12;
+                end;
+              fpu_vfpv2,
+              fpu_vfpv3,
+              fpu_vfpv3_d16:
+                begin
+                  floatsavesize:=0;
+                  regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);
+                  for r:=RS_D0 to RS_D31 do
+                    if r in regs then
+                      inc(floatsavesize,8);
+                end;
+              fpu_fpv4_s16:
+                begin
+                  floatsavesize:=0;
+                  regs:=cg.rg[R_MMREGISTER].used_in_proc-paramanager.get_volatile_registers_mm(pocall_stdcall);
+                  for r:=RS_D0 to RS_D15 do
+                    if r in regs then
+                      inc(floatsavesize,8);
+                end;
             end;
-        end;
-        floatsavesize:=align(floatsavesize,max(current_settings.alignment.localalignmin,4));
-        result:=Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+maxpushedparasize+aint(floatsavesize);
-        floatregstart:=tg.direction*result+maxpushedparasize;
-        if tg.direction=1 then
-          dec(floatregstart,floatsavesize);
+            floatsavesize:=align(floatsavesize,max(current_settings.alignment.localalignmin,4));
+            result:=Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+maxpushedparasize+aint(floatsavesize);
+            floatregstart:=tg.direction*result+maxpushedparasize;
+            if tg.direction=1 then
+              dec(floatregstart,floatsavesize);
+          end;
       end;
 
 
     procedure tarmprocinfo.init_framepointer;
       begin
-        if not(target_info.system in systems_darwin) then
+        if (target_info.system in systems_darwin) or (current_settings.cputype in cpu_thumb) then
           begin
-            RS_FRAME_POINTER_REG:=RS_R11;
-            NR_FRAME_POINTER_REG:=NR_R11;
+            RS_FRAME_POINTER_REG:=RS_R7;
+            NR_FRAME_POINTER_REG:=NR_R7;
           end
         else
           begin
-            RS_FRAME_POINTER_REG:=RS_R7;
-            NR_FRAME_POINTER_REG:=NR_R7;
+            RS_FRAME_POINTER_REG:=RS_R11;
+            NR_FRAME_POINTER_REG:=NR_R11;
           end;
       end;
 
 
+    procedure tarmprocinfo.generate_parameter_info;
+      begin
+       procdef.total_stackframe_size:=stackframesize;
+       inherited generate_parameter_info;
+      end;
+
+
 begin
    cprocinfo:=tarmprocinfo;
 end.

+ 5 - 0
compiler/arm/cputarg.pas

@@ -35,6 +35,9 @@ implementation
              Targets
 **************************************}
 
+    {$ifndef NOTARGETANDROID}
+      ,t_android
+    {$endif}
     {$ifndef NOTARGETLINUX}
       ,t_linux
     {$endif}
@@ -69,6 +72,8 @@ implementation
     {$endif}
 
       ,ogcoff
+      ,ogelf
+      ,cpuelf
 
 {**************************************
         Assembler Readers

+ 2 - 2
compiler/arm/itcpugas.pas

@@ -43,10 +43,10 @@ interface
 implementation
 
     uses
-      cutils,verbose;
+      rgbase;
 
     const
-      gas_regname_table : array[tregisterindex] of string[7] = (
+      gas_regname_table : TRegNameTable = (
         {$i rarmstd.inc}
       );
 

+ 147 - 30
compiler/arm/narmadd.pas

@@ -35,6 +35,7 @@ interface
        public
           function pass_1 : tnode;override;
        protected
+          function first_addfloat: tnode; override;
           procedure second_addfloat;override;
           procedure second_cmpfloat;override;
           procedure second_cmpordinal;override;
@@ -45,16 +46,13 @@ interface
   implementation
 
     uses
-      globtype,systems,
-      cutils,verbose,globals,
-      constexp,
-      symconst,symdef,paramgr,
-      aasmbase,aasmtai,aasmdata,aasmcpu,defutil,htypechk,
-      cgbase,cgutils,cgcpu,
-      cpuinfo,pass_1,pass_2,regvars,procinfo,
-      cpupara,
-      ncon,nset,nadd,
-      ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32,
+      globtype,verbose,globals,
+      constexp,symdef,symtable,symtype,
+      aasmbase,aasmdata,aasmcpu,defutil,htypechk,
+      cgbase,cgutils,
+      cpuinfo,pass_1,procinfo,
+      ncon,nadd,ncnv,ncal,nmat,
+      ncgutil,cgobj,
       hlcgobj
       ;
 
@@ -141,13 +139,10 @@ interface
               { force fpureg as location, left right doesn't matter
                 as both will be in a fpureg }
               location_force_fpureg(current_asmdata.CurrAsmList,left.location,true);
-              location_force_fpureg(current_asmdata.CurrAsmList,right.location,(left.location.loc<>LOC_CFPUREGISTER));
+              location_force_fpureg(current_asmdata.CurrAsmList,right.location,true);
 
               location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
-              if left.location.loc<>LOC_CFPUREGISTER then
-                location.register:=left.location.register
-              else
-                location.register:=right.location.register;
+              location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
 
               case nodetype of
                 addn :
@@ -172,16 +167,11 @@ interface
             begin
               { force mmreg as location, left right doesn't matter
                 as both will be in a fpureg }
-              location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,true);
-              location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,true);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
 
               location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
-              if left.location.loc<>LOC_CMMREGISTER then
-                location.register:=left.location.register
-              else if right.location.loc<>LOC_CMMREGISTER then
-                location.register:=right.location.register
-              else
-                location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
+              location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
 
               singleprec:=tfloatdef(left.resultdef).floattype=s32real;
               case nodetype of
@@ -212,6 +202,31 @@ interface
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,
                  location.register,left.location.register,right.location.register));
             end;
+          fpu_fpv4_s16:
+            begin
+              { force mmreg as location, left right doesn't matter
+                as both will be in a fpureg }
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
+
+              location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
+              location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
+
+              case nodetype of
+                addn :
+                  op:=A_VADD;
+                muln :
+                  op:=A_VMUL;
+                subn :
+                  op:=A_VSUB;
+                slashn :
+                  op:=A_VDIV;
+                else
+                  internalerror(2009111401);
+              end;
+
+              current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op, location.register,left.location.register,right.location.register), PF_F32));
+            end;
           fpu_soft:
             { this case should be handled already by pass1 }
             internalerror(200308252);
@@ -256,8 +271,8 @@ interface
           fpu_vfpv3,
           fpu_vfpv3_d16:
             begin
-              location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,true);
-              location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,true);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
 
               if (tfloatdef(left.resultdef).floattype=s32real) then
                 if nodetype in [equaln,unequaln] then
@@ -273,6 +288,21 @@ interface
               cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
               current_asmdata.CurrAsmList.concat(taicpu.op_none(A_FMSTAT));
             end;
+          fpu_fpv4_s16:
+            begin
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
+
+              if nodetype in [equaln,unequaln] then
+                op:=A_VCMP
+              else
+                op:=A_VCMPE;
+
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,
+                left.location.register,right.location.register));
+              cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
+              current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_VMRS, NR_APSR_nzcv, NR_FPSCR));
+            end;
           fpu_soft:
             { this case should be handled already by pass1 }
             internalerror(2009112404);
@@ -300,7 +330,8 @@ interface
 
         (* Try to keep right as a constant *)
         if (right.location.loc <> LOC_CONSTANT) or
-          not(is_shifter_const(right.location.value, b)) then
+          not(is_shifter_const(right.location.value, b)) or
+          ((current_settings.cputype in cpu_thumb) and not(is_thumb_imm(right.location.value))) then
           hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
         hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
 
@@ -363,7 +394,11 @@ interface
               hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
             dummyreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
             cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
-            current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,right.location.register64.reglo,right.location.register64.reghi),PF_S));
+
+            if current_settings.cputype in cpu_thumb then
+              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,right.location.register64.reglo,right.location.register64.reghi,dummyreg)
+            else
+              current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,right.location.register64.reglo,right.location.register64.reghi),PF_S));
           end
         else if (nodetype in [equaln,unequaln]) and
           (right.nodetype=ordconstn) and (tordconstnode(right).value=0) then
@@ -374,7 +409,11 @@ interface
               hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
             dummyreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
             cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
-            current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
+
+            if current_settings.cputype in cpu_thumb then
+              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reglo,left.location.register64.reghi,dummyreg)
+            else
+              current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
           end
         else
           begin
@@ -388,7 +427,7 @@ interface
                 location.resflags:=getresflags(unsigned);
                 cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
                 current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register64.reghi,right.location.register64.reghi));
-                if current_settings.cputype in cpu_thumb2 then
+                if current_settings.cputype in (cpu_thumb+cpu_thumb2) then
                   begin
                     current_asmdata.getjumplabel(l);
                     cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,l);
@@ -464,6 +503,83 @@ interface
           end;
       end;
 
+    function tarmaddnode.first_addfloat: tnode;
+      var
+        procname: string[31];
+        { do we need to reverse the result ? }
+        notnode : boolean;
+        fdef : tdef;
+      begin
+        result := nil;
+        notnode := false;
+
+        if current_settings.fputype = fpu_fpv4_s16 then
+          begin
+            case tfloatdef(left.resultdef).floattype of
+              s32real:
+                begin
+                  result:=nil;
+                  notnode:=false;
+                end;
+              s64real:
+                begin
+                  fdef:=search_system_type('FLOAT64').typedef;
+                  procname:='float64';
+
+                  case nodetype of
+                    addn:
+                      procname:=procname+'_add';
+                    muln:
+                      procname:=procname+'_mul';
+                    subn:
+                      procname:=procname+'_sub';
+                    slashn:
+                      procname:=procname+'_div';
+                    ltn:
+                      procname:=procname+'_lt';
+                    lten:
+                      procname:=procname+'_le';
+                    gtn:
+                      begin
+                        procname:=procname+'_le';
+                        notnode:=true;
+                      end;
+                    gten:
+                      begin
+                        procname:=procname+'_lt';
+                        notnode:=true;
+                      end;
+                    equaln:
+                      procname:=procname+'_eq';
+                    unequaln:
+                      begin
+                        procname:=procname+'_eq';
+                        notnode:=true;
+                      end;
+                    else
+                      CGMessage3(type_e_operator_not_supported_for_types,node2opstr(nodetype),left.resultdef.typename,right.resultdef.typename);
+                  end;
+
+                  if nodetype in [ltn,lten,gtn,gten,equaln,unequaln] then
+                    resultdef:=pasbool8type;
+                  result:=ctypeconvnode.create_internal(ccallnode.createintern(procname,ccallparanode.create(
+                      ctypeconvnode.create_internal(right,fdef),
+                      ccallparanode.create(
+                        ctypeconvnode.create_internal(left,fdef),nil))),resultdef);
+
+                  left:=nil;
+                  right:=nil;
+
+                  { do we need to reverse the result }
+                  if notnode then
+                    result:=cnotnode.create(result);
+                end;
+            end;
+          end
+        else
+          result:=inherited first_addfloat;
+      end;
+
 
     procedure tarmaddnode.second_cmpordinal;
       var
@@ -479,7 +595,8 @@ interface
         cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
         if right.location.loc = LOC_CONSTANT then
           begin
-             if is_shifter_const(right.location.value,b) then
+             if (not(current_settings.cputype in cpu_thumb) and is_shifter_const(right.location.value,b)) or
+                ((current_settings.cputype in cpu_thumb) and is_thumb_imm(right.location.value)) then
                current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP,left.location.register,right.location.value))
              else
                begin

+ 11 - 6
compiler/arm/narmcal.pas

@@ -26,7 +26,7 @@ unit narmcal;
 interface
 
     uses
-      symdef,node,ncal,ncgcal;
+      symdef,ncal,ncgcal;
 
     type
        tarmcallnode = class(tcgcallnode)
@@ -38,10 +38,8 @@ implementation
   uses
     verbose,globtype,globals,aasmdata,
     symconst,
-    cgbase,
-    cpubase,cpuinfo,
-    ncgutil,
-    paramgr,
+    cgbase,cgutils,cpuinfo,
+    ncgutil,tgobj,
     systems;
 
   procedure tarmcallnode.set_result_location(realresdef: tstoreddef);
@@ -49,7 +47,7 @@ implementation
       if (realresdef.typ=floatdef) and 
          (target_info.abi <> abi_eabihf) and
          ((cs_fp_emulation in current_settings.moduleswitches) or
-          (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16])) then
+          (current_settings.fputype in [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_fpv4_s16])) then
         begin
           { keep the fpu values in integer registers for now, the code
             generator will move them to memory or an mmregister when necessary
@@ -66,6 +64,13 @@ implementation
               internalerror(2010053008);
           end
         end
+      else if (resultdef.typ=floatdef) and
+         (location.loc=LOC_REGISTER) and
+         (current_settings.fputype in [fpu_fpa,fpu_fpa10,fpu_fpa11]) then
+        begin
+          location_reset_ref(location,LOC_REFERENCE,location.size,resultdef.alignment);
+          tg.gethltemp(current_asmdata.CurrAsmList,resultdef,resultdef.size,tt_normal,location.reference);
+        end
       else
         inherited;
     end;

+ 78 - 20
compiler/arm/narmcnv.pas

@@ -26,12 +26,13 @@ unit narmcnv;
 interface
 
     uses
-      node,ncnv,ncgcnv,defcmp;
+      node,ncnv,ncgcnv;
 
     type
        tarmtypeconvnode = class(tcgtypeconvnode)
          protected
            function first_int_to_real: tnode;override;
+           function first_real_to_real: tnode; override;
          { procedure second_int_to_int;override; }
          { procedure second_string_to_string;override; }
          { procedure second_cstring_to_pchar;override; }
@@ -57,15 +58,12 @@ interface
 implementation
 
    uses
-      verbose,globtype,globals,systems,
-      symconst,symdef,aasmbase,aasmtai,aasmdata,
+      verbose,globtype,globals,symdef,aasmbase,aasmtai,aasmdata,symtable,
       defutil,
       cgbase,cgutils,
-      pass_1,pass_2,procinfo,
-      ncon,ncal,
+      pass_1,pass_2,procinfo,ncal,
       ncgutil,
-      cpubase,cpuinfo,aasmcpu,
-      rgobj,tgobj,cgobj,hlcgobj,cgcpu;
+      cpubase,cpuinfo,aasmcpu,cgobj,hlcgobj,cgcpu;
 
 
 {*****************************************************************************
@@ -76,7 +74,8 @@ implementation
       var
         fname: string[19];
       begin
-        if cs_fp_emulation in current_settings.moduleswitches then
+        if (cs_fp_emulation in current_settings.moduleswitches) or
+          (current_settings.fputype=fpu_fpv4_s16) then
           result:=inherited first_int_to_real
         else
           begin
@@ -117,7 +116,8 @@ implementation
                 expectloc:=LOC_FPUREGISTER;
               fpu_vfpv2,
               fpu_vfpv3,
-              fpu_vfpv3_d16:
+              fpu_vfpv3_d16,
+              fpu_fpv4_s16:
                 expectloc:=LOC_MMREGISTER;
               else
                 internalerror(2009112702);
@@ -125,6 +125,48 @@ implementation
           end;
       end;
 
+    function tarmtypeconvnode.first_real_to_real: tnode;
+      begin
+        if (current_settings.fputype=fpu_fpv4_s16) then
+          begin
+            case tfloatdef(left.resultdef).floattype of
+              s32real:
+                case tfloatdef(resultdef).floattype of
+                  s64real:
+                    result:=ctypeconvnode.create_explicit(ccallnode.createintern('float32_to_float64',ccallparanode.create(
+                      ctypeconvnode.create_internal(left,search_system_type('FLOAT32REC').typedef),nil)),resultdef);
+                  s32real:
+                    begin
+                      result:=left;
+                      left:=nil;
+                    end;
+                  else
+                    internalerror(200610151);
+                end;
+              s64real:
+                case tfloatdef(resultdef).floattype of
+                  s32real:
+                    result:=ctypeconvnode.create_explicit(ccallnode.createintern('float64_to_float32',ccallparanode.create(
+                      ctypeconvnode.create_internal(left,search_system_type('FLOAT64').typedef),nil)),resultdef);
+                  s64real:
+                    begin
+                      result:=left;
+                      left:=nil;
+                    end;
+                  else
+                    internalerror(200610152);
+                end;
+              else
+                internalerror(200610153);
+            end;
+            left:=nil;
+            firstpass(result);
+            exit;
+          end
+        else
+          Result := inherited first_real_to_real;
+      end;
+
 
     procedure tarmtypeconvnode.second_int_to_real;
       const
@@ -204,7 +246,7 @@ implementation
             begin
               location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
               signed:=left.location.size=OS_S32;
-              location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,false);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,false);
               if (left.location.size<>OS_F32) then
                 internalerror(2009112703);
               if left.location.size<>location.size then
@@ -214,6 +256,22 @@ implementation
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(
                 signedprec2vfpop[signed,location.size],location.register,left.location.register));
             end;
+          fpu_fpv4_s16:
+            begin
+              location_reset(location,LOC_MMREGISTER,def_cgsize(resultdef));
+              signed:=left.location.size=OS_S32;
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,false);
+              if (left.location.size<>OS_F32) then
+                internalerror(2009112703);
+              if left.location.size<>location.size then
+                location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size)
+              else
+                location.register:=left.location.register;
+              if signed then
+                current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VCVT,location.register,left.location.register), PF_F32S32))
+              else
+                current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VCVT,location.register,left.location.register), PF_F32U32));
+            end;
         end;
       end;
 
@@ -265,16 +323,16 @@ implementation
                    cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hregister);
                    href:=left.location.reference;
                    inc(href.offset,4);
-                   tcgarm(cg).cgsetflags:=true;
+                   tbasecgarm(cg).cgsetflags:=true;
                    cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hregister);
-                   tcgarm(cg).cgsetflags:=false;
+                   tbasecgarm(cg).cgsetflags:=false;
                  end
                 else
                  begin
                    hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
-                   tcgarm(cg).cgsetflags:=true;
+                   tbasecgarm(cg).cgsetflags:=true;
                    cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
-                   tcgarm(cg).cgsetflags:=false;
+                   tbasecgarm(cg).cgsetflags:=false;
                  end;
               end;
             LOC_FLAGS :
@@ -287,15 +345,15 @@ implementation
                  begin
                    hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.register64.reglo,hregister);
-                   tcgarm(cg).cgsetflags:=true;
+                   tbasecgarm(cg).cgsetflags:=true;
                    cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,hregister);
-                   tcgarm(cg).cgsetflags:=false;
+                   tbasecgarm(cg).cgsetflags:=false;
                  end
                 else
                  begin
-                   tcgarm(cg).cgsetflags:=true;
+                   tbasecgarm(cg).cgsetflags:=true;
                    cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
-                   tcgarm(cg).cgsetflags:=false;
+                   tbasecgarm(cg).cgsetflags:=false;
                  end;
               end;
             LOC_JUMP :
@@ -308,9 +366,9 @@ implementation
                 cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
                 cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hregister);
                 cg.a_label(current_asmdata.CurrAsmList,hlabel);
-                tcgarm(cg).cgsetflags:=true;
+                tbasecgarm(cg).cgsetflags:=true;
                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,hregister,hregister);
-                tcgarm(cg).cgsetflags:=false;
+                tbasecgarm(cg).cgsetflags:=false;
               end;
             else
               internalerror(200311301);

+ 2 - 3
compiler/arm/narmcon.pas

@@ -26,7 +26,7 @@ unit narmcon;
 interface
 
     uses
-      node,ncgcon,cpubase;
+      ncgcon,cpubase;
 
     type
       tarmrealconstnode = class(tcgrealconstnode)
@@ -39,8 +39,7 @@ interface
       verbose,
       globtype,globals,
       cpuinfo,
-      aasmbase,aasmtai,aasmdata,
-      symconst,symdef,
+      aasmbase,aasmtai,aasmdata,symdef,
       defutil,
       cgbase,cgutils,
       procinfo,

+ 34 - 14
compiler/arm/narminl.pas

@@ -58,16 +58,10 @@ interface
 implementation
 
     uses
-      globtype,systems,
-      cutils,verbose,globals,fmodule,
-      cpuinfo, defutil,
-      symconst,symdef,
-      aasmbase,aasmtai,aasmdata,aasmcpu,
-      cgbase,cgutils,
-      pass_1,pass_2,
-      cpubase,paramgr,
-      nbas,ncon,ncal,ncnv,nld,
-      tgobj,ncgutil,cgobj,cg64f32,rgobj,rgcpu,cgcpu, hlcgobj;
+      globtype,verbose,globals,
+      cpuinfo, defutil,symdef,aasmdata,aasmcpu,
+      cgbase,cgutils,pass_2,
+      cpubase,ncgutil,cgobj,cgcpu, hlcgobj;
 
 {*****************************************************************************
                               tarminlinenode
@@ -91,9 +85,10 @@ implementation
             end;
           fpu_vfpv2,
           fpu_vfpv3,
-          fpu_vfpv3_d16:
+          fpu_vfpv3_d16,
+          fpu_fpv4_s16:
             begin
-              location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,true);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
               location_copy(location,left.location);
               if left.location.loc=LOC_CMMREGISTER then
                 begin
@@ -123,6 +118,13 @@ implementation
               fpu_vfpv3,
               fpu_vfpv3_d16:
                 expectloc:=LOC_MMREGISTER;
+              fpu_fpv4_s16:
+                begin
+                  if tfloatdef(left.resultdef).floattype=s32real then
+                    expectloc:=LOC_MMREGISTER
+                  else
+                    exit(inherited first_abs_real);
+                end;
               else
                 internalerror(2009112401);
             end;
@@ -146,6 +148,13 @@ implementation
               fpu_vfpv3,
               fpu_vfpv3_d16:
                 expectloc:=LOC_MMREGISTER;
+              fpu_fpv4_s16:
+                begin
+                  if tfloatdef(left.resultdef).floattype=s32real then
+                    expectloc:=LOC_MMREGISTER
+                  else
+                    exit(inherited first_sqr_real);
+                end;
               else
                 internalerror(2009112402);
             end;
@@ -169,6 +178,13 @@ implementation
               fpu_vfpv3,
               fpu_vfpv3_d16:
                 expectloc:=LOC_MMREGISTER;
+              fpu_fpv4_s16:
+                begin
+                  if tfloatdef(left.resultdef).floattype=s32real then
+                    expectloc:=LOC_MMREGISTER
+                  else
+                    exit(inherited first_sqrt_real);
+                end;
               else
                 internalerror(2009112403);
             end;
@@ -227,6 +243,8 @@ implementation
                 op:=A_FABSD;
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,location.register,left.location.register));
             end;
+          fpu_fpv4_s16:
+            current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register), PF_F32));
         else
           internalerror(2009111402);
         end;
@@ -254,6 +272,8 @@ implementation
                 op:=A_FMULD;
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,left.location.register));
             end;
+          fpu_fpv4_s16:
+            current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg_reg(A_VMUL,location.register,left.location.register,left.location.register), PF_F32));
         else
           internalerror(2009111403);
         end;
@@ -281,6 +301,8 @@ implementation
                 op:=A_FSQRTD;
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,location.register,left.location.register));
             end;
+          fpu_fpv4_s16:
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VSQRT,location.register,left.location.register));
         else
           internalerror(2009111402);
         end;
@@ -341,14 +363,12 @@ implementation
 
     procedure tarminlinenode.second_abs_long;
       var
-        hregister : tregister;
         opsize : tcgsize;
         hp : taicpu;
       begin
         secondpass(left);
         opsize:=def_cgsize(left.resultdef);
         hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
-        hregister:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
         location:=left.location;
         location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
         cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);

+ 88 - 21
compiler/arm/narmmat.pas

@@ -39,6 +39,7 @@ interface
       end;
 
       tarmunaryminusnode = class(tcgunaryminusnode)
+        function pass_1: tnode; override;
         procedure second_float;override;
       end;
 
@@ -50,15 +51,16 @@ interface
 implementation
 
     uses
-      globtype,systems,
+      globtype,
       cutils,verbose,globals,constexp,
       aasmbase,aasmcpu,aasmtai,aasmdata,
       defutil,
+      symtype,symconst,symtable,
       cgbase,cgobj,hlcgobj,cgutils,
       pass_2,procinfo,
-      ncon,
+      ncon,ncnv,ncal,ninl,
       cpubase,cpuinfo,
-      ncgutil,cgcpu,
+      ncgutil,
       nadd,pass_1,symdef;
 
 {*****************************************************************************
@@ -77,11 +79,11 @@ implementation
           ) and
           not(is_64bitint(resultdef)) then
           result:=nil
-        else if (current_settings.cputype in [cpu_armv7m]) and
+        else if (current_settings.cputype in [cpu_armv7m,cpu_armv7em]) and
           (nodetype=divn) and
           not(is_64bitint(resultdef)) then
           result:=nil
-        else if (current_settings.cputype in [cpu_armv7m]) and
+        else if (current_settings.cputype in [cpu_armv7m,cpu_armv7em]) and
           (nodetype=modn) and
           not(is_64bitint(resultdef)) then
           begin
@@ -97,6 +99,17 @@ implementation
               end;
             left:=nil;
           end
+        else if (nodetype=modn) and
+          (is_signed(left.resultdef)) and
+          (right.nodetype=ordconstn) and
+          (tordconstnode(right).value=2) then
+          begin
+            // result:=(0-(left and 1)) and (1+(sarlongint(left,31) shl 1))
+            result:=caddnode.create(andn,caddnode.create(subn,cordconstnode.create(0,sinttype,false),caddnode.create(andn,left,cordconstnode.create(1,sinttype,false))),
+                                         caddnode.create(addn,cordconstnode.create(1,sinttype,false),
+                                                              cshlshrnode.create(shln,cinlinenode.create(in_sar_x_y,false,ccallparanode.create(cordconstnode.create(31,sinttype,false),ccallparanode.Create(left.getcopy,nil))),cordconstnode.create(1,sinttype,false))));
+            left:=nil;
+          end
         else
           result:=inherited first_moddivint;
       end;
@@ -133,18 +146,23 @@ implementation
                  begin
                     helper1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                     helper2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_ASR;
-                    so.shiftimm:=31;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_MOV,helper1,numerator,so));
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_LSR;
-                    so.shiftimm:=32-power;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,helper2,numerator,helper1,so));
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_ASR;
-                    so.shiftimm:=power;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_MOV,resultreg,helper2,so));
+                    if power = 1 then
+                      cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,numerator,helper1)
+                    else
+                      cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
+                    if current_settings.cputype in cpu_thumb then
+                      begin
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,32-power,helper1);
+                        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ADD,helper2,numerator,helper1));
+                      end
+                    else
+                      begin
+                        shifterop_reset(so);
+                        so.shiftmode:=SM_LSR;
+                        so.shiftimm:=32-power;
+                        current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,helper2,numerator,helper1,so));
+                      end;
+                    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,power,helper2,resultreg);
                   end
                else
                  cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,power,numerator,resultreg)
@@ -196,7 +214,7 @@ implementation
         secondpass(left);
         secondpass(right);
 
-        if (current_settings.cputype in [cpu_armv7m]) and
+        if (current_settings.cputype in [cpu_armv7m,cpu_armv7em]) and
            (nodetype=divn) and
            not(is_64bitint(resultdef)) then
           begin
@@ -326,6 +344,46 @@ implementation
                                TARMUNARYMINUSNODE
 *****************************************************************************}
 
+    function tarmunaryminusnode.pass_1: tnode;
+      var
+        procname: string[31];
+        fdef : tdef;
+      begin
+        if (current_settings.fputype<>fpu_fpv4_s16) or
+          (tfloatdef(resultdef).floattype=s32real) then
+          exit(inherited pass_1);
+
+        result:=nil;
+        firstpass(left);
+        if codegenerror then
+          exit;
+
+        if (left.resultdef.typ=floatdef) then
+          begin
+            case tfloatdef(resultdef).floattype of
+              s64real:
+                begin
+                  procname:='float64_sub';
+                  fdef:=search_system_type('FLOAT64').typedef;
+                end;
+              else
+                internalerror(2005082801);
+            end;
+            result:=ctypeconvnode.create_internal(ccallnode.createintern(procname,ccallparanode.create(
+              ctypeconvnode.create_internal(left,fDef),
+              ccallparanode.create(ctypeconvnode.create_internal(crealconstnode.create(0,resultdef),fdef),nil))),resultdef);
+
+            left:=nil;
+          end
+        else
+          begin
+            if (left.resultdef.typ=floatdef) then
+              expectloc:=LOC_FPUREGISTER
+             else if (left.resultdef.typ=orddef) then
+               expectloc:=LOC_REGISTER;
+          end;
+      end;
+
     procedure tarmunaryminusnode.second_float;
       var
         op: tasmop;
@@ -346,7 +404,7 @@ implementation
           fpu_vfpv3,
           fpu_vfpv3_d16:
             begin
-              location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,true);
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
               location:=left.location;
               if (left.location.loc=LOC_CMMREGISTER) then
                 location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
@@ -357,6 +415,15 @@ implementation
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,
                 location.register,left.location.register));
             end;
+          fpu_fpv4_s16:
+            begin
+              hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+              location:=left.location;
+              if (left.location.loc=LOC_CMMREGISTER) then
+                location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
+              current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VNEG,
+                location.register,left.location.register), PF_F32));
+            end
           else
             internalerror(2009112602);
         end;
@@ -364,7 +431,7 @@ implementation
 
     function tarmshlshrnode.first_shlshr64bitint: tnode;
       begin
-        if (current_settings.cputype in cpu_thumb2) then
+        if (current_settings.cputype in cpu_thumb+cpu_thumb2) then
           result:=inherited
         else
           result := nil;
@@ -439,7 +506,7 @@ implementation
         end;
 
       begin
-        if (current_settings.cputype in cpu_thumb2) then
+        if (current_settings.cputype in cpu_thumb+cpu_thumb2) then
         begin
           inherited;
           exit;

+ 31 - 8
compiler/arm/narmmem.pas

@@ -27,10 +27,14 @@ interface
 
     uses
       globtype,
-      cgbase,cpuinfo,cpubase,
-      node,nmem,ncgmem;
+      cgbase,cpubase,nmem,ncgmem;
 
     type
+      tarmloadparentfpnode = class(tcgloadparentfpnode)
+        procedure pass_generate_code; override;
+      end;
+
+
       tarmvecnode = class(tcgvecnode)
         procedure update_reference_reg_mul(maybe_const_reg: tregister; l: aint);override;
       end;
@@ -38,12 +42,29 @@ interface
 implementation
 
     uses
-      systems,
-      cutils,verbose,
-      symdef,paramgr,
-      aasmtai,aasmdata,aasmcpu,
-      nld,ncon,nadd,
-      cgutils,cgobj;
+      cutils,verbose,globals,aasmdata,aasmcpu,cgobj,
+      cpuinfo,
+      cgutils,
+      procinfo;
+
+{*****************************************************************************
+                        TARMLOADPARENTFPNODE
+*****************************************************************************}
+
+    procedure tarmloadparentfpnode.pass_generate_code;
+      begin
+        { normally, we cannot use the stack pointer as normal register on arm thumb }
+        if (current_settings.cputype in cpu_thumb) and
+          (getsupreg(current_procinfo.framepointer) in [RS_R8..RS_R15]) and
+          (current_procinfo.procdef.parast.symtablelevel=parentpd.parast.symtablelevel) then
+          begin
+            location_reset(location,LOC_REGISTER,OS_ADDR);
+            location.register:=cg.getaddressregister(current_asmdata.CurrAsmList);
+            cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,current_procinfo.framepointer,location.register);
+          end
+        else
+          inherited pass_generate_code;
+      end;
 
 {*****************************************************************************
                              TARMVECNODE
@@ -55,6 +76,7 @@ implementation
          hl : longint;
        begin
          if ((location.reference.base=NR_NO) and (location.reference.index=NR_NO)) or
+            (current_settings.cputype in cpu_thumb) or
             { simple constant? }
             (l=1) or ispowerof2(l,hl) or ispowerof2(l+1,hl) or ispowerof2(l-1,hl) then
            inherited update_reference_reg_mul(maybe_const_reg,l)
@@ -88,4 +110,5 @@ implementation
 
 begin
   cvecnode:=tarmvecnode;
+  cloadparentfpnode:=tarmloadparentfpnode;
 end.

+ 47 - 21
compiler/arm/narmset.pas

@@ -27,7 +27,7 @@ interface
 
     uses
       globtype,
-      symtype,symdef,
+      symtype,
       cgbase,
       node,nset,pass_1,ncgset;
 
@@ -51,13 +51,9 @@ interface
 implementation
 
     uses
-      systems,
-      verbose,globals,constexp,
-      symconst,defutil,
+      globals,constexp,defutil,
       aasmbase,aasmtai,aasmdata,aasmcpu,
-      pass_2,
-      ncon,
-      cpubase,cpuinfo,procinfo,
+      cpubase,cpuinfo,
       cgutils,cgobj,ncgutil,
       cgcpu,hlcgobj;
 
@@ -88,7 +84,7 @@ implementation
       begin
         location_reset(location,LOC_FLAGS,OS_NO);
         location.resflags:=F_NE;
-        if left.location.loc=LOC_CONSTANT then
+        if (left.location.loc=LOC_CONSTANT) and not(current_settings.cputype in cpu_thumb) then
           begin
             hlcg.location_force_reg(current_asmdata.CurrAsmList, right.location,
               right.resultdef, right.resultdef, true);
@@ -108,11 +104,20 @@ implementation
             hregister:=cg.getintregister(current_asmdata.CurrAsmList, uopsize);
             current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_MOV,hregister,1));
 
-            shifterop_reset(so);
-            so.rs:=left.location.register;
-            so.shiftmode:=SM_LSL;
-            cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
-            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_TST,right.location.register,hregister,so));
+            if current_settings.cputype in cpu_thumb then
+              begin
+                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_LSL,hregister,left.location.register));
+                cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
+                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_TST,right.location.register,hregister));
+              end
+            else
+              begin
+                shifterop_reset(so);
+                so.rs:=left.location.register;
+                so.shiftmode:=SM_LSL;
+                cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
+                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_TST,right.location.register,hregister,so));
+              end;
           end;
       end;
 
@@ -136,6 +141,7 @@ implementation
     procedure tarmcasenode.genjumptable(hp : pcaselabel;min_,max_ : aint);
       var
         last : TConstExprInt;
+        basereg,
         indexreg : tregister;
         href : treference;
         tablelabel: TAsmLabel;
@@ -203,6 +209,26 @@ implementation
             last:=min_;
             genitem_thumb2(current_asmdata.CurrAsmList,hp);
           end
+        else if current_settings.cputype in cpu_thumb then
+          begin
+            cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_ADDR,min_+1,indexreg,indexreg);
+            current_asmdata.getaddrlabel(tablelabel);
+
+            cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHL,OS_ADDR,2,indexreg);
+
+            basereg:=cg.getintregister(current_asmdata.CurrAsmList, OS_ADDR);
+            reference_reset_symbol(href,tablelabel,0,4);
+            cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList, href, basereg);
+
+            cg.a_op_reg_reg(current_asmdata.CurrAsmList, OP_ADD, OS_ADDr, indexreg, basereg);
+
+            current_asmdata.CurrAsmList.Concat(taicpu.op_reg(A_BX, basereg));
+
+            cg.a_label(current_asmdata.CurrAsmList,tablelabel);
+            { generate jump table }
+            last:=min_;
+            genitem(current_asmdata.CurrAsmList,hp);
+          end
         else
           begin
             { adjust index }
@@ -244,11 +270,11 @@ implementation
                     cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, opcgsize, OC_EQ,0,hregister,blocklabel(t^.blockid))
                   else
                     begin
-                      tcgarm(cg).cgsetflags:=true;
+                      tbasecgarm(cg).cgsetflags:=true;
                       { use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
                         then genlinearlist wouldn't be used }
                       cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low-last)), hregister);
-                      tcgarm(cg).cgsetflags:=false;
+                      tbasecgarm(cg).cgsetflags:=false;
                       cg.a_jmp_flags(current_asmdata.CurrAsmList,F_EQ,blocklabel(t^.blockid));
                     end;
                   last:=t^._low;
@@ -264,11 +290,11 @@ implementation
                        { have we to ajust the first value ? }
                        if (t^._low>get_min_value(left.resultdef)) or (get_min_value(left.resultdef)<>0) then
                          begin
-                           tcgarm(cg).cgsetflags:=true;
+                           tbasecgarm(cg).cgsetflags:=true;
                            { use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
                              then genlinearlist wouldn't be use }
                            cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low)), hregister);
-                           tcgarm(cg).cgsetflags:=false;
+                           tbasecgarm(cg).cgsetflags:=false;
                          end;
                     end
                   else
@@ -277,22 +303,22 @@ implementation
                       { present label then the lower limit can be checked    }
                       { immediately. else check the range in between:       }
 
-                      tcgarm(cg).cgsetflags:=true;
+                      tbasecgarm(cg).cgsetflags:=true;
                       { use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
                         then genlinearlist wouldn't be use }
                       cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low-last)), hregister);
-                      tcgarm(cg).cgsetflags:=false;
+                      tbasecgarm(cg).cgsetflags:=false;
                       { no jump necessary here if the new range starts at }
                       { at the value following the previous one           }
                       if ((t^._low-last) <> 1) or
                          (not lastrange) then
                         cg.a_jmp_flags(current_asmdata.CurrAsmList,cond_lt,elselabel);
                     end;
-                  tcgarm(cg).cgsetflags:=true;
+                  tbasecgarm(cg).cgsetflags:=true;
                   { use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
                     then genlinearlist wouldn't be use }
                   cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,OS_32,aint(int64(t^._high-t^._low)),hregister);
-                  tcgarm(cg).cgsetflags:=false;
+                  tbasecgarm(cg).cgsetflags:=false;
                   cg.a_jmp_flags(current_asmdata.CurrAsmList,cond_le,blocklabel(t^.blockid));
 
                   last:=t^._high;

+ 116 - 12
compiler/arm/raarmgas.pas

@@ -35,13 +35,16 @@ Unit raarmgas;
         actwideformat : boolean;
         function is_asmopcode(const s: string):boolean;override;
         function is_register(const s:string):boolean;override;
+        function is_targetdirective(const s: string): boolean; override;
         procedure handleopcode;override;
         procedure BuildReference(oper : tarmoperand);
         procedure BuildOperand(oper : tarmoperand);
+        procedure BuildSpecialreg(oper : tarmoperand);
         function TryBuildShifterOp(oper : tarmoperand) : boolean;
         procedure BuildOpCode(instr : tarminstruction);
         procedure ReadSym(oper : tarmoperand);
         procedure ConvertCalljmp(instr : tarminstruction);
+        procedure HandleTargetDirective; override;
       end;
 
 
@@ -51,19 +54,13 @@ Unit raarmgas;
       { helpers }
       cutils,
       { global }
-      globtype,globals,verbose,
-      systems,
-      { aasm }
-      cpuinfo,aasmbase,aasmtai,aasmdata,aasmcpu,
+      globtype,verbose,
+      systems,aasmbase,aasmtai,aasmdata,aasmcpu,
       { symtable }
-      symconst,symbase,symtype,symsym,symtable,
-      { parser }
-      scanner,
+      symconst,symsym,
       procinfo,
-      itcpugas,
       rabase,rautils,
-      cgbase,cgutils,cgobj
-      ;
+      cgbase,cgutils;
 
 
     function tarmattreader.is_register(const s:string):boolean;
@@ -118,6 +115,16 @@ Unit raarmgas;
           end;
       end;
 
+    function tarmattreader.is_targetdirective(const s: string): boolean;
+      begin
+        if s = '.thumb_func' then
+          result:=true
+        else if s='.thumb_set' then
+          result:=true
+        else
+          Result:=inherited is_targetdirective(s);
+      end;
+
 
     procedure tarmattreader.ReadSym(oper : tarmoperand);
       var
@@ -925,6 +932,13 @@ Unit raarmgas;
               oper.opr.regtype:=regtype;
               oper.opr.subreg:=subreg;
               oper.opr.regset:=registerset;
+              if actasmtoken=AS_XOR then
+                begin
+                  consume(AS_XOR);
+                  oper.opr.usermode:=true;
+                end
+              else
+                oper.opr.usermode:=false;
               if (registerset=[]) then
                 Message(asmr_e_empty_regset);
             end;
@@ -939,6 +953,68 @@ Unit raarmgas;
         end; { end case }
       end;
 
+    procedure tarmattreader.BuildSpecialreg(oper: tarmoperand);
+      var
+        hs, reg : String;
+        ch : char;
+        i, t : longint;
+        hreg : tregister;
+        flags : tspecialregflags;
+      begin
+        case actasmtoken of
+          AS_REGISTER:
+            begin
+              oper.opr.typ:=OPR_REGISTER;
+              oper.opr.reg:=actasmregister;
+              Consume(AS_REGISTER);
+            end;
+          AS_ID:
+            begin
+              t := pos('_', actasmpattern);
+              if t > 0 then
+                begin
+                  hs:=lower(actasmpattern);
+                  reg:=copy(hs, 1, t-1);
+                  delete(hs, 1, t);
+
+                  if length(hs) < 1 then
+                    Message(asmr_e_invalid_operand_type);
+
+                  if reg = 'cpsr' then
+                    hreg:=NR_CPSR
+                  else if reg='spsr' then
+                    hreg:=NR_SPSR
+                  else
+                    Message(asmr_e_invalid_register);
+
+                  flags:=[];
+                  for i := 1 to length(hs) do
+                    begin
+                      ch:=hs[i];
+                      if ch='c' then
+                        include(flags, srC)
+                      else if ch='x' then
+                        include(flags, srX)
+                      else if ch='f' then
+                        include(flags, srF)
+                      else if ch='s' then
+                        include(flags, srS)
+                      else
+                        message(asmr_e_invalid_operand_type);
+                    end;
+
+                  oper.opr.typ:=OPR_SPECIALREG;
+                  oper.opr.specialreg:=hreg;
+                  oper.opr.specialregflags:=flags;
+
+                  consume(AS_ID);
+                end
+              else
+                Message(asmr_e_invalid_operand_type); // Otherwise it would have been seen as a AS_REGISTER
+            end;
+        end;
+      end;
+
 
 {*****************************************************************************
                                 tarmattreader
@@ -979,7 +1055,7 @@ Unit raarmgas;
             AS_COMMA: { Operand delimiter }
               Begin
                 if ((instr.opcode in [A_MOV, A_MVN, A_CMP, A_CMN, A_TST, A_TEQ]) and (operandnum=2)) or
-                  ((operandnum=3) and not(instr.opcode in [A_UMLAL,A_UMULL,A_SMLAL,A_SMULL,A_MLA])) then
+                  ((operandnum=3) and not(instr.opcode in [A_UMLAL,A_UMULL,A_SMLAL,A_SMULL,A_MLA,A_MRC,A_MCR,A_MCRR,A_MRRC])) then
                   begin
                     Consume(AS_COMMA);
                     if not(TryBuildShifterOp(instr.Operands[operandnum+1] as tarmoperand)) then
@@ -1001,7 +1077,10 @@ Unit raarmgas;
                 break;
               end;
           else
-            BuildOperand(instr.Operands[operandnum] as tarmoperand);
+            if (instr.opcode = A_MSR) and (operandnum = 1) then
+              BuildSpecialreg(instr.Operands[operandnum] as tarmoperand)
+            else
+              BuildOperand(instr.Operands[operandnum] as tarmoperand);
           end; { end case }
         until false;
         instr.Ops:=operandnum;
@@ -1132,6 +1211,31 @@ Unit raarmgas;
           end;
       end;
 
+    procedure tarmattreader.HandleTargetDirective;
+      var
+        symname,
+        symval  : String;
+        val     : aint;
+        symtyp  : TAsmsymtype;
+      begin
+        if actasmpattern='.thumb_set' then
+          begin
+            consume(AS_TARGET_DIRECTIVE);
+            BuildConstSymbolExpression(true,false,false, val,symname,symtyp);
+            Consume(AS_COMMA);
+            BuildConstSymbolExpression(true,false,false, val,symval,symtyp);
+
+            curList.concat(tai_thumb_set.create(symname,symval));
+          end
+        else if actasmpattern='.thumb_func' then
+          begin
+            consume(AS_TARGET_DIRECTIVE);
+            curList.concat(tai_thumb_func.create);
+          end
+        else
+          inherited HandleTargetDirective;
+      end;
+
 
     procedure tarmattreader.handleopcode;
       var

+ 34 - 1
compiler/arm/rarmcon.inc

@@ -88,5 +88,38 @@ NR_D28 = tregister($0407001C);
 NR_D29 = tregister($0407001D);
 NR_D30 = tregister($0407001E);
 NR_D31 = tregister($0407001F);
-NR_CPSR_C = tregister($05000000);
+NR_CPSR = tregister($05000000);
 NR_FPSCR = tregister($05000001);
+NR_SPSR = tregister($05000002);
+NR_APSR_nzcv = tregister($05000003);
+NR_CR0 = tregister($05000004);
+NR_CR1 = tregister($05000005);
+NR_CR2 = tregister($05000006);
+NR_CR3 = tregister($05000007);
+NR_CR4 = tregister($05000008);
+NR_CR5 = tregister($05000009);
+NR_CR6 = tregister($0500000A);
+NR_CR7 = tregister($0500000B);
+NR_CR8 = tregister($0500000C);
+NR_CR9 = tregister($0500000D);
+NR_CR10 = tregister($0500000E);
+NR_CR11 = tregister($0500000F);
+NR_CR12 = tregister($05000010);
+NR_CR13 = tregister($05000011);
+NR_CR14 = tregister($05000012);
+NR_CR15 = tregister($05000013);
+NR_p15 = tregister($05000014);
+NR_APSR = tregister($05000015);
+NR_IPSR = tregister($05000016);
+NR_EPSR = tregister($05000017);
+NR_IEPSR = tregister($05000018);
+NR_IAPSR = tregister($05000019);
+NR_EAPSR = tregister($0500001A);
+NR_PSR = tregister($0500001B);
+NR_MSP = tregister($0500001C);
+NR_PSP = tregister($0500001D);
+NR_PRIMASK = tregister($0500001E);
+NR_BASEPRI = tregister($0500001F);
+NR_BASEPRI_MAX = tregister($05000020);
+NR_FAULTMASK = tregister($05000021);
+NR_CONTROL = tregister($05000022);

+ 33 - 0
compiler/arm/rarmdwa.inc

@@ -89,4 +89,37 @@
 0,
 0,
 0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
 0

+ 1 - 1
compiler/arm/rarmnor.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from armreg.dat }
-91
+124

+ 34 - 1
compiler/arm/rarmnum.inc

@@ -89,4 +89,37 @@ tregister($0407001D),
 tregister($0407001E),
 tregister($0407001F),
 tregister($05000000),
-tregister($05000001)
+tregister($05000001),
+tregister($05000002),
+tregister($05000003),
+tregister($05000004),
+tregister($05000005),
+tregister($05000006),
+tregister($05000007),
+tregister($05000008),
+tregister($05000009),
+tregister($0500000A),
+tregister($0500000B),
+tregister($0500000C),
+tregister($0500000D),
+tregister($0500000E),
+tregister($0500000F),
+tregister($05000010),
+tregister($05000011),
+tregister($05000012),
+tregister($05000013),
+tregister($05000014),
+tregister($05000015),
+tregister($05000016),
+tregister($05000017),
+tregister($05000018),
+tregister($05000019),
+tregister($0500001A),
+tregister($0500001B),
+tregister($0500001C),
+tregister($0500001D),
+tregister($0500001E),
+tregister($0500001F),
+tregister($05000020),
+tregister($05000021),
+tregister($05000022)

+ 34 - 1
compiler/arm/rarmrni.inc

@@ -89,4 +89,37 @@
 87,
 88,
 89,
-90
+90,
+91,
+92,
+93,
+94,
+95,
+96,
+97,
+98,
+99,
+100,
+101,
+102,
+103,
+104,
+105,
+106,
+107,
+108,
+109,
+110,
+111,
+112,
+113,
+114,
+115,
+116,
+117,
+118,
+119,
+120,
+121,
+122,
+123

+ 34 - 1
compiler/arm/rarmsri.inc

@@ -1,6 +1,27 @@
 { don't edit, this file is generated from armreg.dat }
 0,
+110,
+92,
+120,
+121,
+123,
 89,
+93,
+94,
+103,
+104,
+105,
+106,
+107,
+108,
+95,
+96,
+97,
+98,
+99,
+100,
+101,
+102,
 27,
 30,
 57,
@@ -33,6 +54,8 @@
 48,
 51,
 54,
+115,
+112,
 17,
 18,
 19,
@@ -41,7 +64,16 @@
 22,
 23,
 24,
+122,
 90,
+114,
+113,
+111,
+117,
+109,
+119,
+118,
+116,
 1,
 2,
 11,
@@ -89,4 +121,5 @@
 34,
 35,
 37,
-38
+38,
+91

+ 33 - 0
compiler/arm/rarmsta.inc

@@ -89,4 +89,37 @@
 0,
 0,
 0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
+0,
 0

+ 35 - 2
compiler/arm/rarmstd.inc

@@ -88,5 +88,38 @@
 'd29',
 'd30',
 'd31',
-'cpsr_c',
-'fpscr'
+'cpsr',
+'fpscr',
+'spsr',
+'apsr_nzcv',
+'cr0',
+'cr1',
+'cr2',
+'cr3',
+'cr4',
+'cr5',
+'cr6',
+'cr7',
+'cr8',
+'cr9',
+'cr10',
+'cr11',
+'cr12',
+'cr13',
+'cr14',
+'cr15',
+'p15',
+'apsr',
+'ipsr',
+'epsr',
+'iepsr',
+'iapsr',
+'eapsr',
+'psr',
+'msp',
+'psp',
+'primask',
+'basepri',
+'basepri_max',
+'faultmask',
+'control'

+ 34 - 1
compiler/arm/rarmsup.inc

@@ -88,5 +88,38 @@ RS_D28 = $1C;
 RS_D29 = $1D;
 RS_D30 = $1E;
 RS_D31 = $1F;
-RS_CPSR_C = $00;
+RS_CPSR = $00;
 RS_FPSCR = $01;
+RS_SPSR = $02;
+RS_APSR_nzcv = $03;
+RS_CR0 = $04;
+RS_CR1 = $05;
+RS_CR2 = $06;
+RS_CR3 = $07;
+RS_CR4 = $08;
+RS_CR5 = $09;
+RS_CR6 = $0A;
+RS_CR7 = $0B;
+RS_CR8 = $0C;
+RS_CR9 = $0D;
+RS_CR10 = $0E;
+RS_CR11 = $0F;
+RS_CR12 = $10;
+RS_CR13 = $11;
+RS_CR14 = $12;
+RS_CR15 = $13;
+RS_p15 = $14;
+RS_APSR = $15;
+RS_IPSR = $16;
+RS_EPSR = $17;
+RS_IEPSR = $18;
+RS_IAPSR = $19;
+RS_EAPSR = $1A;
+RS_PSR = $1B;
+RS_MSP = $1C;
+RS_PSP = $1D;
+RS_PRIMASK = $1E;
+RS_BASEPRI = $1F;
+RS_BASEPRI_MAX = $20;
+RS_FAULTMASK = $21;
+RS_CONTROL = $22;

+ 182 - 5
compiler/arm/rgcpu.pas

@@ -31,6 +31,9 @@ unit rgcpu;
        aasmbase,aasmtai,aasmdata,aasmcpu,
        cgbase,cgutils,
        cpubase,
+       {$ifdef DEBUG_SPILLING}
+       cutils,
+       {$endif}
        rgobj;
 
      type
@@ -45,6 +48,9 @@ unit rgcpu;
        end;
 
        trgcputhumb2 = class(trgobj)
+       private
+         procedure SplitITBlock(list:TAsmList;pos:tai);
+       public
          procedure do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override;
          procedure do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);override;
        end;
@@ -57,20 +63,35 @@ unit rgcpu;
          procedure add_cpu_interferences(p : tai);override;
        end;
 
+       trgcputhumb = class(trgcpu)
+       end;
+
+       trgintcputhumb = class(trgcputhumb)
+         procedure add_cpu_interferences(p: tai);override;
+       end;
+
+
   implementation
 
     uses
-      verbose, cutils,globtype,globals,cpuinfo,
+      verbose,globtype,globals,cpuinfo,
       cgobj,
       procinfo;
 
     procedure trgintcputhumb2.add_cpu_interferences(p: tai);
       var
         r : tregister;
+        hr : longint;
       begin
         if p.typ=ait_instruction then
           begin
             case taicpu(p).opcode of
+              A_CBNZ,
+              A_CBZ:
+                begin
+                  for hr := RS_R8 to RS_R15 do
+                    add_edge(getsupreg(taicpu(p).oper[0]^.reg), hr);
+                end;
               A_ADD:
                 begin
                   if taicpu(p).ops = 3 then
@@ -144,7 +165,16 @@ unit rgcpu;
 
       { Lets remove the bits we can fold in later and check if the result can be easily with an add or sub }
       a:=abs(spilltemp.offset);
-      if is_shifter_const(a and not($FFF), immshift) then
+      if current_settings.cputype in cpu_thumb then
+        begin
+          {$ifdef DEBUG_SPILLING}
+          helplist.concat(tai_comment.create(strpnew('Spilling: Use a_load_const_reg to fix spill offset')));
+          {$endif}
+          cg.a_load_const_reg(helplist,OS_ADDR,spilltemp.offset,hreg);
+          cg.a_op_reg_reg(helplist,OP_ADD,OS_ADDR,current_procinfo.framepointer,hreg);
+          reference_reset_base(tmpref,hreg,0,sizeof(aint));
+        end
+      else if is_shifter_const(a and not($FFF), immshift) then
         if spilltemp.offset > 0 then
           begin
             {$ifdef DEBUG_SPILLING}
@@ -188,6 +218,14 @@ unit rgcpu;
       helplist.free;
     end;
 
+
+   function fix_spilling_offset(offset : ASizeInt) : boolean;
+     begin
+       result:=(abs(offset)>4095) or
+          ((current_settings.cputype in cpu_thumb) and ((offset<0) or (offset>1020)));
+     end;
+
+
     procedure trgcpu.do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
       begin
         { don't load spilled register between
@@ -204,7 +242,7 @@ unit rgcpu;
           (taicpu(pos).oper[1]^.reg=NR_PC) then
           pos:=tai(pos.previous);
 
-        if abs(spilltemp.offset)>4095 then
+        if fix_spilling_offset(spilltemp.offset) then
           spilling_create_load_store(list, pos, spilltemp, tempreg, false)
         else
           inherited do_spill_read(list,pos,spilltemp,tempreg);
@@ -213,7 +251,7 @@ unit rgcpu;
 
     procedure trgcpu.do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
       begin
-        if abs(spilltemp.offset)>4095 then
+        if fix_spilling_offset(spilltemp.offset) then
           spilling_create_load_store(list, pos, spilltemp, tempreg, true)
         else
           inherited do_spill_written(list,pos,spilltemp,tempreg);
@@ -245,6 +283,69 @@ unit rgcpu;
           result:=getsubreg(r);
       end;
 
+    function GetITRemainderOp(originalOp:TAsmOp;remLevels:longint;var newOp: TAsmOp;var NeedsCondSwap:boolean) : TAsmOp;
+      const
+        remOps : array[1..3] of array[A_ITE..A_ITTTT] of TAsmOp = (
+          (A_IT,A_IT,       A_IT,A_IT,A_IT,A_IT,            A_IT,A_IT,A_IT,A_IT,A_IT,A_IT,A_IT,A_IT),
+          (A_NONE,A_NONE,   A_ITT,A_ITE,A_ITE,A_ITT,        A_ITT,A_ITT,A_ITE,A_ITE,A_ITE,A_ITE,A_ITT,A_ITT),
+          (A_NONE,A_NONE,   A_NONE,A_NONE,A_NONE,A_NONE,    A_ITTT,A_ITEE,A_ITET,A_ITTE,A_ITTE,A_ITET,A_ITEE,A_ITTT));
+        newOps : array[1..3] of array[A_ITE..A_ITTTT] of TAsmOp = (
+          (A_IT,A_IT,       A_ITE,A_ITT,A_ITE,A_ITT,        A_ITEE,A_ITTE,A_ITET,A_ITTT,A_ITEE,A_ITTE,A_ITET,A_ITTT),
+          (A_NONE,A_NONE,   A_IT,A_IT,A_IT,A_IT,            A_ITE,A_ITT,A_ITE,A_ITT,A_ITE,A_ITT,A_ITE,A_ITT),
+          (A_NONE,A_NONE,   A_NONE,A_NONE,A_NONE,A_NONE,    A_IT,A_IT,A_IT,A_IT,A_IT,A_IT,A_IT,A_IT));
+        needsSwap: array[1..3] of array[A_ITE..A_ITTTT] of Boolean = (
+          (true ,false,     true ,true ,false,false,        true ,true ,true ,true ,false,false,false,false),
+          (false,false,     true ,false,true ,false,        true ,true ,false,false,true ,true ,false,false),
+          (false,false,     false,false,false,false,        true ,false,true ,false,true ,false,true ,false));
+      begin
+        result:=remOps[remLevels][originalOp];
+        newOp:=newOps[remLevels][originalOp];
+        NeedsCondSwap:=needsSwap[remLevels][originalOp];
+      end;
+
+    procedure trgcputhumb2.SplitITBlock(list: TAsmList; pos: tai);
+      var
+        hp : tai;
+        level,itLevel : LongInt;
+        remOp,newOp : TAsmOp;
+        needsSwap : boolean;
+      begin
+        hp:=pos;
+        level := 0;
+        while assigned(hp) do
+          begin
+            if IsIT(taicpu(hp).opcode) then
+              break
+            else if hp.typ=ait_instruction then
+              inc(level);
+
+            hp:=tai(hp.Previous);
+          end;
+
+        if not assigned(hp) then
+          internalerror(2012100801); // We are supposed to have found the ITxxx instruction here
+
+        if (hp.typ<>ait_instruction) or
+          (not IsIT(taicpu(hp).opcode)) then
+          internalerror(2012100802); // Sanity check
+
+        itLevel := GetITLevels(taicpu(hp).opcode);
+        if level=itLevel then
+          exit; // pos was the last instruction in the IT block anyway
+
+        remOp:=GetITRemainderOp(taicpu(hp).opcode,itLevel-level,newOp,needsSwap);
+
+        if (remOp=A_NONE) or
+          (newOp=A_NONE) then
+          Internalerror(2012100803);
+
+        taicpu(hp).opcode:=newOp;
+
+        if needsSwap then
+          list.InsertAfter(taicpu.op_cond(remOp,inverse_cond(taicpu(hp).oper[0]^.cc)), pos)
+        else
+          list.InsertAfter(taicpu.op_cond(remOp,taicpu(hp).oper[0]^.cc), pos);
+      end;
 
     procedure trgcputhumb2.do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
       var
@@ -256,7 +357,7 @@ unit rgcpu;
         { don't load spilled register between
           mov lr,pc
           mov pc,r4
-          but befure the mov lr,pc
+          but before the mov lr,pc
         }
         if assigned(pos.previous) and
           (pos.typ=ait_instruction) and
@@ -267,6 +368,18 @@ unit rgcpu;
           (taicpu(pos).oper[1]^.reg=NR_PC) then
           pos:=tai(pos.previous);
 
+        if (pos.typ=ait_instruction) and
+          (taicpu(pos).condition<>C_None) and
+          (taicpu(pos).opcode<>A_B) then
+          SplitITBlock(list, pos)
+        else if (pos.typ=ait_instruction) and
+          IsIT(taicpu(pos).opcode) then
+          begin
+            if not assigned(pos.Previous) then
+              list.InsertBefore(tai_comment.Create('Dummy'), pos);
+            pos:=tai(pos.Previous);
+          end;
+
         if (spilltemp.offset>4095) or (spilltemp.offset<-255) then
           begin
             helplist:=TAsmList.create;
@@ -313,6 +426,18 @@ unit rgcpu;
         l : tasmlabel;
         hreg : tregister;
       begin
+        if (pos.typ=ait_instruction) and
+          (taicpu(pos).condition<>C_None) and
+          (taicpu(pos).opcode<>A_B) then
+          SplitITBlock(list, pos)
+        else if (pos.typ=ait_instruction) and
+          IsIT(taicpu(pos).opcode) then
+          begin
+            if not assigned(pos.Previous) then
+              list.InsertBefore(tai_comment.Create('Dummy'), pos);
+            pos:=tai(pos.Previous);
+          end;
+
         if (spilltemp.offset>4095) or (spilltemp.offset<-255) then
           begin
             helplist:=TAsmList.create;
@@ -394,4 +519,56 @@ unit rgcpu;
       end;
 
 
+    procedure trgintcputhumb.add_cpu_interferences(p: tai);
+      var
+        r : tregister;
+        i,
+        hr : longint;
+      begin
+        if p.typ=ait_instruction then
+          begin
+            { prevent that the register allocator merges registers with frame/stack pointer
+              if an instruction writes to the register }
+            if (taicpu(p).ops>=1) and (taicpu(p).oper[0]^.typ=top_reg) and
+              (taicpu(p).spilling_get_operation_type(0) in [operand_write,operand_readwrite]) then
+              begin
+                { FIXME: temp variable r is needed here to avoid Internal error 20060521 }
+                {        while compiling the compiler. }
+                r:=NR_STACK_POINTER_REG;
+                add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(r));
+                add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(current_procinfo.framepointer));
+              end;
+            if (taicpu(p).ops>=2) and (taicpu(p).oper[1]^.typ=top_reg) and
+              (taicpu(p).spilling_get_operation_type(1) in [operand_write,operand_readwrite]) then
+              begin
+                { FIXME: temp variable r is needed here to avoid Internal error 20060521 }
+                {        while compiling the compiler. }
+                r:=NR_STACK_POINTER_REG;
+                add_edge(getsupreg(taicpu(p).oper[1]^.reg),getsupreg(r));
+                add_edge(getsupreg(taicpu(p).oper[1]^.reg),getsupreg(current_procinfo.framepointer));
+              end;
+            case taicpu(p).opcode of
+              A_LDRB,
+              A_STRB,
+              A_STR,
+              A_LDR,
+              A_LDRH,
+              A_STRH,
+              A_LDRSB,
+              A_LDRSH,
+              A_LDRD,
+              A_STRD:
+                 begin
+                   { add_edge handles precoloured registers already }
+                   for i:=RS_R8 to RS_R15 do
+                     begin
+                       add_edge(getsupreg(taicpu(p).oper[1]^.ref^.base),i);
+                       add_edge(getsupreg(taicpu(p).oper[1]^.ref^.index),i);
+                       add_edge(getsupreg(taicpu(p).oper[0]^.reg),i);
+                     end;
+                 end;
+            end;
+          end;
+      end;
+
 end.

+ 2 - 2
compiler/asmutils.pas

@@ -62,7 +62,7 @@ uses
         if NewSection then
           begin
             maybe_new_object_file(list);
-            new_section(list,sec_rodata,result.lab.name,const_align(sizeof(pint)));
+            new_section(list,sec_rodata_norel,result.lab.name,const_align(sizeof(pint)));
           end;
         { put label before header on Darwin, because there the linker considers
           a global symbol to be the start of a new subsection }
@@ -105,7 +105,7 @@ uses
         current_asmdata.getdatalabel(result.lab);
         result.ofs:=0;
         maybe_new_object_file(list);
-        new_section(list,sec_rodata,result.lab.name,const_align(sizeof(pint)));
+        new_section(list,sec_rodata_norel,result.lab.name,const_align(sizeof(pint)));
         strlength := getlengthwidestring(pcompilerwidestring(data));
         if Winlike then
           begin

+ 51 - 15
compiler/assemble.pas

@@ -66,7 +66,7 @@ interface
       }
       TExternalAssembler=class(TAssembler)
       private
-        procedure CreateSmartLinkPath(const s:string);
+        procedure CreateSmartLinkPath(const s:TPathStr);
       protected
       {outfile}
         AsmSize,
@@ -291,7 +291,7 @@ Implementation
       end;
 
 
-    procedure TExternalAssembler.CreateSmartLinkPath(const s:string);
+    procedure TExternalAssembler.CreateSmartLinkPath(const s:TPathStr);
 
         procedure DeleteFilesWithExt(const AExt:string);
         var
@@ -307,7 +307,7 @@ Implementation
         end;
 
       var
-        hs  : string;
+        hs  : TPathStr;
       begin
         if PathExists(s,false) then
          begin
@@ -580,10 +580,29 @@ Implementation
       begin
         result:=target_asm.asmcmd;
 {$ifdef m68k}
-        if current_settings.cputype = cpu_MC68020 then
-          result:='-m68020 '+result
+        { TODO: use a better approach for this }
+        if (target_info.system=system_m68k_amiga) then
+          begin
+            { m68k-amiga has old binutils, which doesn't support -march=* }
+            case current_settings.cputype of
+              cpu_MC68000:
+                result:='-m68000 '+result;
+              cpu_MC68020:
+                result:='-m68020 '+result;
+              { additionally, AmigaOS doesn't work on Coldfire }
+            end;
+          end
         else
-          result:='-m68000 '+result;
+          begin
+            case current_settings.cputype of
+              cpu_MC68000:
+                result:='-march=68000 '+result;
+              cpu_MC68020:
+                result:='-march=68020 '+result;
+              cpu_Coldfire:
+                result:='-march=cfv4e '+result;
+            end;
+          end;
 {$endif}
 {$ifdef arm}
         if (target_info.system=system_arm_darwin) then
@@ -605,13 +624,13 @@ Implementation
            Replace(result,'$OBJ',maybequoted(ObjFileName));
          end;
          if (cs_create_pic in current_settings.moduleswitches) then
-		   Replace(result,'$PIC','-KPIC')
+           Replace(result,'$PIC','-KPIC')
          else
-		   Replace(result,'$PIC','');
+           Replace(result,'$PIC','');
          if (cs_asm_source in current_settings.globalswitches) then
-		   Replace(result,'$NOWARN','')
-		 else
-		   Replace(result,'$NOWARN','-W');
+           Replace(result,'$NOWARN','')
+         else
+           Replace(result,'$NOWARN','-W');
       end;
 
 
@@ -685,11 +704,24 @@ Implementation
       end;
 
     procedure TExternalAssembler.WriteSourceLine(hp: tailineinfo);
+      var
+        module : tmodule;
       begin
         { load infile }
-        if lastfileinfo.fileindex<>hp.fileinfo.fileindex then
+        if (lastfileinfo.moduleindex<>hp.fileinfo.moduleindex) or
+            (lastfileinfo.fileindex<>hp.fileinfo.fileindex) then
           begin
-            infile:=current_module.sourcefiles.get_file(hp.fileinfo.fileindex);
+            { in case of a generic the module can be different }
+            if current_module.unit_index=hp.fileinfo.moduleindex then
+              module:=current_module
+            else
+              module:=get_module(hp.fileinfo.moduleindex);
+            { during the compilation of the system unit there are cases when
+              the fileinfo contains just zeros => invalid }
+            if assigned(module) then
+              infile:=module.sourcefiles.get_file(hp.fileinfo.fileindex)
+            else
+              infile:=nil;
             if assigned(infile) then
               begin
                 { open only if needed !! }
@@ -698,6 +730,7 @@ Implementation
               end;
             { avoid unnecessary reopens of the same file !! }
             lastfileinfo.fileindex:=hp.fileinfo.fileindex;
+            lastfileinfo.moduleindex:=hp.fileinfo.moduleindex;
             { be sure to change line !! }
             lastfileinfo.line:=-1;
           end;
@@ -1427,6 +1460,9 @@ Implementation
                    aitconst_64bit,
                    aitconst_32bit,
                    aitconst_16bit,
+                   aitconst_64bit_unaligned,
+                   aitconst_32bit_unaligned,
+                   aitconst_16bit_unaligned,
                    aitconst_8bit :
                      begin
                        if assigned(tai_const(hp).sym) and
@@ -1483,10 +1519,10 @@ Implementation
              ait_cutobject :
                if SmartAsm then
                 break;
-{$ifdef TEST_WIN64_SEH}
+{$ifndef DISABLE_WIN64_SEH}
              ait_seh_directive :
                tai_seh_directive(hp).generate_code(objdata);
-{$endif TEST_WIN64_SEH}
+{$endif DISABLE_WIN64_SEH}
            end;
            hp:=Tai(hp.next);
          end;

+ 1 - 1
compiler/avr/agavrgas.pas

@@ -205,7 +205,7 @@ unit agavrgas;
             asmbin : 'as';
             asmcmd : '-o $OBJ $ASM';
             supported_targets : [system_avr_embedded];
-            flags : [af_allowdirect,af_needar,af_smartlink_sections];
+            flags : [af_needar,af_smartlink_sections];
             labelprefix : '.L';
             comment : '# ';
             dollarsign: 's';

+ 166 - 99
compiler/avr/cgcpu.pas

@@ -56,7 +56,7 @@ unit cgcpu;
         procedure a_call_ref(list : TAsmList;ref: treference);override;
 
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
-        procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override;
+        procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst : TRegister); override;
 
         { move instructions }
         procedure a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);override;
@@ -107,6 +107,9 @@ unit cgcpu;
         function GetStore(const ref: treference): tasmop;
 
         procedure a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; size: TCGSize; src, dst: TRegister); override;
+      protected
+        procedure a_op_reg_reg_internal(list: TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
+        procedure a_op_const_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg, reghi: TRegister);
       end;
 
       tcg64favr = class(tcg64f32)
@@ -125,7 +128,7 @@ unit cgcpu;
     uses
        globals,verbose,systems,cutils,
        fmodule,
-       symconst,symsym,
+       symconst,symsym,symtable,
        tgobj,rgobj,
        procinfo,cpupi,
        paramgr;
@@ -332,60 +335,22 @@ unit cgcpu;
 
 
      procedure tcgavr.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister);
-       var
-         mask : qword;
-         shift : byte;
-         i : byte;
-         tmpreg : tregister;
        begin
-         mask:=$ff;
-         shift:=0;
-         case op of
-           OP_OR:
-             begin
-               for i:=1 to tcgsize2size[size] do
-                 begin
-                   list.concat(taicpu.op_reg_const(A_ORI,reg,(a and mask) shr shift));
-                   reg:=GetNextReg(reg);
-                   mask:=mask shl 8;
-                   inc(shift,8);
-                 end;
-             end;
-           OP_AND:
-             begin
-               for i:=1 to tcgsize2size[size] do
-                 begin
-                   list.concat(taicpu.op_reg_const(A_ANDI,reg,(a and mask) shr shift));
-                   reg:=GetNextReg(reg);
-                   mask:=mask shl 8;
-                   inc(shift,8);
-                 end;
-             end;
-           OP_SUB:
-             begin
-               list.concat(taicpu.op_reg_const(A_SUBI,reg,a));
-               if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
-                 begin
-                   for i:=2 to tcgsize2size[size] do
-                     begin
-                       reg:=GetNextReg(reg);
-                       mask:=mask shl 8;
-                       inc(shift,8);
-                       list.concat(taicpu.op_reg_const(A_SBCI,reg,(a and mask) shr shift));
-                     end;
-                 end;
-             end;
-         else
-           begin
-             tmpreg:=getintregister(list,size);
-             a_load_const_reg(list,size,a,tmpreg);
-             a_op_reg_reg(list,op,size,tmpreg,reg);
-           end;
-         end;
+         if not(size in [OS_S8,OS_8,OS_S16,OS_16,OS_S32,OS_32]) then
+           internalerror(2012102403);
+         a_op_const_reg_internal(list,Op,size,a,reg,NR_NO);
+       end;
+
+
+     procedure tcgavr.a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst : TRegister);
+       begin
+         if not(size in [OS_S8,OS_8,OS_S16,OS_16,OS_S32,OS_32]) then
+           internalerror(2012102401);
+         a_op_reg_reg_internal(list,Op,size,src,NR_NO,dst,NR_NO);
        end;
 
 
-     procedure tcgavr.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
+     procedure tcgavr.a_op_reg_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
        var
          countreg,
          tmpreg: tregister;
@@ -393,6 +358,31 @@ unit cgcpu;
          instr : taicpu;
          paraloc1,paraloc2,paraloc3 : TCGPara;
          l1,l2 : tasmlabel;
+         pd : tprocdef;
+
+       procedure NextSrcDst;
+         begin
+           if i=5 then
+             begin
+               dst:=dsthi;
+               src:=srchi;
+             end
+           else
+             begin
+               dst:=GetNextReg(dst);
+               src:=GetNextReg(src);
+             end;
+         end;
+
+       { iterates TmpReg through all registers of dst }
+       procedure NextTmp;
+         begin
+           if i=5 then
+             tmpreg:=dsthi
+           else
+             tmpreg:=GetNextReg(tmpreg);
+         end;
+
       begin
          case op of
            OP_ADD:
@@ -402,12 +392,10 @@ unit cgcpu;
                  begin
                    for i:=2 to tcgsize2size[size] do
                      begin
-                       dst:=GetNextReg(dst);
-                       src:=GetNextReg(src);
+                       NextSrcDst;
                        list.concat(taicpu.op_reg_reg(A_ADC,dst,src));
-                   end;
-                 end
-               else
+                     end;
+                 end;
              end;
 
            OP_SUB:
@@ -417,8 +405,7 @@ unit cgcpu;
                  begin
                    for i:=2 to tcgsize2size[size] do
                      begin
-                       dst:=GetNextReg(dst);
-                       src:=GetNextReg(src);
+                       NextSrcDst;
                        list.concat(taicpu.op_reg_reg(A_SBC,dst,src));
                      end;
                  end;
@@ -435,18 +422,16 @@ unit cgcpu;
                    for i:=2 to tcgsize2size[size] do
                      begin
                        list.concat(taicpu.op_reg(A_COM,tmpreg));
-                       tmpreg:=GetNextReg(tmpreg);
+                       NextTmp;
                      end;
                    list.concat(taicpu.op_reg(A_NEG,dst));
                    tmpreg:=GetNextReg(dst);
                    for i:=2 to tcgsize2size[size] do
                      begin
                        list.concat(taicpu.op_reg_const(A_SBCI,dst,-1));
-                       tmpreg:=GetNextReg(tmpreg);
+                       NextTmp;
                    end;
-                 end
-               else
-                 list.concat(taicpu.op_reg(A_NEG,dst));
+                 end;
              end;
 
            OP_NOT:
@@ -456,8 +441,7 @@ unit cgcpu;
                    if src<>dst then
                      a_load_reg_reg(list,OS_8,OS_8,src,dst);
                    list.concat(taicpu.op_reg(A_COM,dst));
-                   src:=GetNextReg(src);
-                   dst:=GetNextReg(dst);
+                   NextSrcDst;
                  end;
              end;
 
@@ -467,12 +451,13 @@ unit cgcpu;
                  list.concat(taicpu.op_reg_reg(topcg2asmop[op],dst,src))
                else if size=OS_16 then
                  begin
+                   pd:=search_system_proc('fpc_mul_word');
                    paraloc1.init;
                    paraloc2.init;
                    paraloc3.init;
-                   paramanager.getintparaloc(pocall_default,1,u16inttype,paraloc1);
-                   paramanager.getintparaloc(pocall_default,2,u16inttype,paraloc2);
-                   paramanager.getintparaloc(pocall_default,3,pasbool8type,paraloc3);
+                   paramanager.getintparaloc(pd,1,paraloc1);
+                   paramanager.getintparaloc(pd,2,paraloc2);
+                   paramanager.getintparaloc(pd,3,paraloc3);
                    a_load_const_cgpara(list,OS_8,0,paraloc3);
                    a_load_reg_cgpara(list,OS_16,src,paraloc2);
                    a_load_reg_cgpara(list,OS_16,dst,paraloc1);
@@ -508,11 +493,11 @@ unit cgcpu;
                cg.a_label(list,l1);
                case op of
                  OP_SHR:
-                   list.concat(taicpu.op_reg(A_LSR,GetOffsetReg(dst,tcgsize2size[size]-1)));
+                   list.concat(taicpu.op_reg(A_LSR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
                  OP_SHL:
                    list.concat(taicpu.op_reg(A_LSL,dst));
                  OP_SAR:
-                   list.concat(taicpu.op_reg(A_ASR,GetOffsetReg(dst,tcgsize2size[size]-1)));
+                   list.concat(taicpu.op_reg(A_ASR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
                  OP_ROR:
                    begin
                      { load carry? }
@@ -522,7 +507,7 @@ unit cgcpu;
                          list.concat(taicpu.op_reg_const(A_SBRC,src,0));
                          list.concat(taicpu.op_none(A_SEC));
                        end;
-                     list.concat(taicpu.op_reg(A_ROR,GetOffsetReg(dst,tcgsize2size[size]-1)));
+                     list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1)));
                    end;
                  OP_ROL:
                    begin
@@ -530,7 +515,7 @@ unit cgcpu;
                      if not(size in [OS_8,OS_S8]) then
                        begin
                          list.concat(taicpu.op_none(A_CLC));
-                         list.concat(taicpu.op_reg_const(A_SBRC,GetOffsetReg(dst,tcgsize2size[size]-1),7));
+                         list.concat(taicpu.op_reg_const(A_SBRC,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1),7));
                          list.concat(taicpu.op_none(A_SEC));
                        end;
                      list.concat(taicpu.op_reg(A_ROL,dst))
@@ -545,12 +530,12 @@ unit cgcpu;
                        case op of
                          OP_ROR,
                          OP_SHR:
-                           list.concat(taicpu.op_reg(A_ROR,GetOffsetReg(dst,tcgsize2size[size]-i)));
+                           list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i)));
                          OP_ROL,
                          OP_SHL:
-                           list.concat(taicpu.op_reg(A_ROL,GetOffsetReg(dst,i-1)));
+                           list.concat(taicpu.op_reg(A_ROL,GetOffsetReg64(dst,dsthi,i-1)));
                          OP_SAR:
-                           list.concat(taicpu.op_reg(A_ROR,GetOffsetReg(dst,tcgsize2size[size]-i)));
+                           list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i)));
                          else
                            internalerror(2011030902);
                        end;
@@ -569,8 +554,7 @@ unit cgcpu;
                 for i:=1 to tcgsize2size[size] do
                   begin
                     list.concat(taicpu.op_reg_reg(topcg2asmop[op],dst,src));
-                    dst:=GetNextReg(dst);
-                    src:=GetNextReg(src);
+                    NextSrcDst;
                   end;
              end;
            else
@@ -578,6 +562,81 @@ unit cgcpu;
          end;
        end;
 
+     procedure tcgavr.a_op_const_reg_internal(list: TAsmList; Op: TOpCG;
+      size: TCGSize; a: tcgint; reg, reghi: TRegister);
+
+       var
+         mask : qword;
+         shift : byte;
+         i : byte;
+         tmpreg : tregister;
+         tmpreg64 : tregister64;
+
+      procedure NextReg;
+        begin
+          if i=5 then
+            reg:=reghi
+          else
+            reg:=GetNextReg(reg);
+        end;
+
+       begin
+         mask:=$ff;
+         shift:=0;
+         case op of
+           OP_OR:
+             begin
+               for i:=1 to tcgsize2size[size] do
+                 begin
+                   list.concat(taicpu.op_reg_const(A_ORI,reg,(a and mask) shr shift));
+                   NextReg;
+                   mask:=mask shl 8;
+                   inc(shift,8);
+                 end;
+             end;
+           OP_AND:
+             begin
+               for i:=1 to tcgsize2size[size] do
+                 begin
+                   list.concat(taicpu.op_reg_const(A_ANDI,reg,(a and mask) shr shift));
+                   NextReg;
+                   mask:=mask shl 8;
+                   inc(shift,8);
+                 end;
+             end;
+           OP_SUB:
+             begin
+               list.concat(taicpu.op_reg_const(A_SUBI,reg,a));
+               if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
+                 begin
+                   for i:=2 to tcgsize2size[size] do
+                     begin
+                       NextReg;
+                       mask:=mask shl 8;
+                       inc(shift,8);
+                       list.concat(taicpu.op_reg_const(A_SBCI,reg,(a and mask) shr shift));
+                     end;
+                 end;
+             end;
+         else
+           begin
+             if size in [OS_64,OS_S64] then
+               begin
+                 tmpreg64.reglo:=getintregister(list,OS_32);
+                 tmpreg64.reghi:=getintregister(list,OS_32);
+                 cg64.a_load64_const_reg(list,a,tmpreg64);
+                 cg64.a_op64_reg_reg(list,op,size,tmpreg64,joinreg64(reg,reghi));
+               end
+             else
+               begin
+                 tmpreg:=getintregister(list,size);
+                 a_load_const_reg(list,size,a,tmpreg);
+                 a_op_reg_reg(list,op,size,tmpreg,reg);
+               end;
+           end;
+       end;
+     end;
+
 
      procedure tcgavr.a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);
        var
@@ -1020,18 +1079,20 @@ unit cgcpu;
                  end;
                OS_S8:
                  begin
-                   { dest is always at least 16 bit at this point }
                    emit_mov(list,reg2,reg1);
 
-                   reg2:=GetNextReg(reg2);
-                   list.concat(taicpu.op_reg(A_CLR,reg2));
-                   list.concat(taicpu.op_reg_const(A_SBRC,reg1,7));
-                   list.concat(taicpu.op_reg(A_COM,reg2));
-                   tmpreg:=reg2;
-                   for i:=3 to tcgsize2size[tosize] do
+                   if tcgsize2size[tosize]>1 then
                      begin
                        reg2:=GetNextReg(reg2);
-                       emit_mov(list,reg2,tmpreg);
+                       list.concat(taicpu.op_reg(A_CLR,reg2));
+                       list.concat(taicpu.op_reg_const(A_SBRC,reg1,7));
+                       list.concat(taicpu.op_reg(A_COM,reg2));
+                       tmpreg:=reg2;
+                       for i:=3 to tcgsize2size[tosize] do
+                         begin
+                           reg2:=GetNextReg(reg2);
+                           emit_mov(list,reg2,tmpreg);
+                         end;
                      end;
                  end;
                OS_16:
@@ -1050,22 +1111,24 @@ unit cgcpu;
                  end;
                OS_S16:
                  begin
-                   { dest is always at least 32 bit at this point }
                    emit_mov(list,reg2,reg1);
 
                    reg1:=GetNextReg(reg1);
                    reg2:=GetNextReg(reg2);
                    emit_mov(list,reg2,reg1);
 
-                   reg2:=GetNextReg(reg2);
-                   list.concat(taicpu.op_reg(A_CLR,reg2));
-                   list.concat(taicpu.op_reg_const(A_SBRC,reg1,7));
-                   list.concat(taicpu.op_reg(A_COM,reg2));
-                   tmpreg:=reg2;
-                   for i:=4 to tcgsize2size[tosize] do
+                   if tcgsize2size[tosize]>2 then
                      begin
                        reg2:=GetNextReg(reg2);
-                       emit_mov(list,reg2,tmpreg);
+                       list.concat(taicpu.op_reg(A_CLR,reg2));
+                       list.concat(taicpu.op_reg_const(A_SBRC,reg1,7));
+                       list.concat(taicpu.op_reg(A_COM,reg2));
+                       tmpreg:=reg2;
+                       for i:=4 to tcgsize2size[tosize] do
+                         begin
+                           reg2:=GetNextReg(reg2);
+                           emit_mov(list,reg2,tmpreg);
+                         end;
                      end;
                  end;
                else
@@ -1447,13 +1510,15 @@ unit cgcpu;
     procedure tcgavr.g_concatcopy_move(list : TAsmList;const source,dest : treference;len : tcgint);
       var
         paraloc1,paraloc2,paraloc3 : TCGPara;
+        pd : tprocdef;
       begin
+        pd:=search_system_proc('MOVE');
         paraloc1.init;
         paraloc2.init;
         paraloc3.init;
-        paramanager.getintparaloc(pocall_default,1,voidpointertype,paraloc1);
-        paramanager.getintparaloc(pocall_default,2,voidpointertype,paraloc2);
-        paramanager.getintparaloc(pocall_default,3,ptrsinttype,paraloc3);
+        paramanager.getintparaloc(pd,1,paraloc1);
+        paramanager.getintparaloc(pd,2,paraloc2);
+        paramanager.getintparaloc(pd,3,paraloc3);
         a_load_const_cgpara(list,OS_SINT,len,paraloc3);
         a_loadaddr_ref_cgpara(list,dest,paraloc2);
         a_loadaddr_ref_cgpara(list,source,paraloc1);
@@ -1733,13 +1798,15 @@ unit cgcpu;
 
     procedure tcg64favr.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
       begin
-        { TODO : a_op64_reg_reg }
+         if not(size in [OS_S64,OS_64]) then
+           internalerror(2012102402);
+         tcgavr(cg).a_op_reg_reg_internal(list,Op,size,regsrc.reglo,regsrc.reghi,regdst.reglo,regdst.reghi);
       end;
 
 
     procedure tcg64favr.a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);
       begin
-        { TODO : a_op64_const_reg }
+        tcgavr(cg).a_op_const_reg_internal(list,Op,size,value,reg.reglo,reg.reghi);
       end;
 
 

+ 13 - 1
compiler/avr/cpubase.pas

@@ -317,7 +317,10 @@ unit cpubase;
     { returns the last virtual register }
     function GetLastReg(const r : TRegister) : TRegister;
 
+    { returns the register with the offset of ofs of a continuous set of register starting with r }
     function GetOffsetReg(const r : TRegister;ofs : shortint) : TRegister;
+    { returns the register with the offset of ofs of a continuous set of register starting with r and being continued with rhi }
+    function GetOffsetReg64(const r,rhi: TRegister;ofs : shortint): TRegister;
 
   implementation
 
@@ -326,7 +329,7 @@ unit cpubase;
 
 
     const
-      std_regname_table : array[tregisterindex] of string[7] = (
+      std_regname_table : TRegNameTable = (
         {$i ravrstd.inc}
       );
 
@@ -463,4 +466,13 @@ unit cpubase;
       end;
 
 
+    function GetOffsetReg64(const r,rhi: TRegister;ofs : shortint): TRegister;
+      begin
+        if ofs>3 then
+          result:=TRegister(longint(rhi)+ofs-4)
+        else
+          result:=TRegister(longint(r)+ofs);
+      end;
+
+
 end.

+ 0 - 6
compiler/avr/cpuinfo.pas

@@ -104,7 +104,6 @@ Const
    ((
    	controllertypestr:'';
         controllerunitstr:'';
-        interruptvectors:0;
         flashbase:0;
         flashsize:0;
         srambase:0;
@@ -115,7 +114,6 @@ Const
         (
    	controllertypestr:'ATMEGA16';
         controllerunitstr:'ATMEGA16';
-        interruptvectors:0;
         flashbase:0;
         flashsize:$4000;
         srambase:0;
@@ -126,7 +124,6 @@ Const
         (
    	controllertypestr:'ATMEGA32';
         controllerunitstr:'ATMEGA32';
-        interruptvectors:0;
         flashbase:0;
         flashsize:$8000;
         srambase:0;
@@ -137,7 +134,6 @@ Const
    	(
         controllertypestr:'ATMEGA48';
         controllerunitstr:'ATMEGA48';
-        interruptvectors:0;
         flashbase:0;
         flashsize:$1000;
         srambase:0;
@@ -148,7 +144,6 @@ Const
    	(
         controllertypestr:'ATMEGA64';
         controllerunitstr:'ATMEGA64';
-        interruptvectors:0;
         flashbase:0;
         flashsize:$10000;
         srambase:0;
@@ -159,7 +154,6 @@ Const
    	(
         controllertypestr:'ATMEGA128';
         controllerunitstr:'ATMEGA128';
-        interruptvectors:0;
         flashbase:0;
         flashsize:$20000;
         srambase:0;

+ 54 - 20
compiler/avr/cpupara.pas

@@ -37,8 +37,8 @@ unit cpupara;
           function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
           function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
           function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
-          function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
-          procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override;
+          function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
+          procedure getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
           function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
           function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
           function  get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
@@ -68,21 +68,28 @@ unit cpupara;
       end;
 
 
-    procedure tavrparamanager.getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);
+    procedure tavrparamanager.getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);
       var
         paraloc : pcgparalocation;
+        psym: tparavarsym;
+        pdef: tdef;
       begin
         if nr<1 then
           internalerror(2002070801);
+        psym:=tparavarsym(pd.paras[nr-1]);
+        pdef:=psym.vardef;
+        if push_addr_param(psym.varspez,pdef,pd.proccalloption) then
+          pdef:=getpointerdef(pdef);
         cgpara.reset;
-        cgpara.size:=def_cgsize(def);
+        cgpara.size:=def_cgsize(pdef);
         cgpara.intsize:=tcgsize2size[cgpara.size];
         cgpara.alignment:=std_param_align;
-        cgpara.def:=def;
+        cgpara.def:=pdef;
         paraloc:=cgpara.add_location;
         with paraloc^ do
           begin
-            size:=OS_INT;
+            size:=def_cgsize(pdef);
+            def:=pdef;
             { the four first parameters are passed into registers }
             if nr<=9 then
               begin
@@ -178,22 +185,24 @@ unit cpupara;
       end;
 
 
-    function tavrparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
+    function tavrparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
       begin
+        if handle_common_ret_in_param(def,pd,result) then
+          exit;
         case def.typ of
           recorddef:
             { this is how gcc 4.0.4 on linux seems to do it, it doesn't look like being
               ARM ABI standard compliant
             }
             result:=not((trecorddef(def).symtable.SymList.count=1) and
-              not(ret_in_param(tabstractvarsym(trecorddef(def).symtable.SymList[0]).vardef,calloption)));
+              not(ret_in_param(tabstractvarsym(trecorddef(def).symtable.SymList[0]).vardef,pd)));
           {
           objectdef
           arraydef:
             result:=not(def.size in [1,2,4]);
           }
           else
-            result:=inherited ret_in_param(def,calloption);
+            result:=inherited ret_in_param(def,pd);
         end;
       end;
 
@@ -221,6 +230,7 @@ unit cpupara;
         paracgsize   : tcgsize;
         paralen : longint;
         i : integer;
+        firstparaloc: boolean;
 
       procedure assignintreg;
         begin
@@ -268,6 +278,7 @@ unit cpupara;
                 paraloc^.loc:=LOC_REGISTER;
                 paraloc^.register:=NR_R25;
                 paraloc^.size:=OS_ADDR;
+                paraloc^.def:=voidpointertype;
                 break;
               end;
 
@@ -311,6 +322,7 @@ unit cpupara;
              if paralen=0 then
                internalerror(200410311);
 {$endif EXTDEBUG}
+             firstparaloc:=true;
              while paralen>0 do
                begin
                  paraloc:=hp.paraloc[side].add_location;
@@ -318,21 +330,31 @@ unit cpupara;
                  if (loc=LOC_REGISTER) and (paracgsize in [OS_F32,OS_F64,OS_F80]) then
                    case paracgsize of
                      OS_F32:
-                       paraloc^.size:=OS_32;
+                       begin
+                         paraloc^.size:=OS_32;
+                         paraloc^.def:=u32inttype;
+                       end;
                      OS_F64:
-                       paraloc^.size:=OS_32;
+                       begin
+                         paraloc^.size:=OS_32;
+                         paraloc^.def:=u32inttype;
+                       end;
                      else
                        internalerror(2005082901);
                    end
-                 else if (paracgsize in [OS_NO,OS_64,OS_S64]) then
-                   paraloc^.size := OS_32
+                 else if paracgsize<>OS_S8 then
+                   begin
+                     paraloc^.size:=OS_8;
+                     paraloc^.def:=u8inttype
+                   end
                  else
-                   paraloc^.size:=paracgsize;
+                   begin
+                     paraloc^.size:=paracgsize;
+                     paraloc^.def:=paradef;
+                   end;
                  case loc of
                     LOC_REGISTER:
                       begin
-                        { this is not abi compliant
-                          why? (FK) }
                         if nextintreg>=RS_R8 then
                           begin
                             paraloc^.loc:=LOC_REGISTER;
@@ -344,6 +366,8 @@ unit cpupara;
                             { LOC_REFERENCE covers always the overleft }
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.size:=int_cgsize(paralen);
+                            paraloc^.def:=get_paraloc_def(paradef,paralen,firstparaloc);
+
                             if (side=callerside) then
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                             paraloc^.reference.offset:=stack_offset;
@@ -354,12 +378,14 @@ unit cpupara;
                     LOC_REFERENCE:
                       begin
                         paraloc^.size:=OS_ADDR;
-                        if push_addr_param(hp.varspez,paradef,p.proccalloption) or
-                          is_open_array(paradef) or
-                          is_array_of_const(paradef) then
-                          assignintreg
+                        if push_addr_param(hp.varspez,paradef,p.proccalloption) then
+                          begin
+                            paraloc^.def:=getpointerdef(paradef);
+                            assignintreg
+                          end
                         else
                           begin
+                             paraloc^.def:=hp.vardef;
                              paraloc^.loc:=LOC_REFERENCE;
                              paraloc^.reference.index:=NR_STACK_POINTER_REG;
                              paraloc^.reference.offset:=stack_offset;
@@ -378,6 +404,7 @@ unit cpupara;
                        end;
                    end;
                  dec(paralen,tcgsize2size[paraloc^.size]);
+                 firstparaloc:=false;
                end;
           end;
         curintreg:=nextintreg;
@@ -424,10 +451,12 @@ unit cpupara;
                       paraloc^.loc:=LOC_REGISTER;
                       paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG;
                       paraloc^.size:=OS_32;
+                      paraloc^.def:=u32inttype;
                       paraloc:=result.add_location;
                       paraloc^.loc:=LOC_REGISTER;
                       paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG;
                       paraloc^.size:=OS_32;
+                      paraloc^.def:=u32inttype;
                     end;
                   OS_32,
                   OS_F32:
@@ -435,6 +464,7 @@ unit cpupara;
                       paraloc^.loc:=LOC_REGISTER;
                       paraloc^.register:=NR_FUNCTION_RETURN_REG;
                       paraloc^.size:=OS_32;
+                      paraloc^.def:=u32inttype;
                     end;
                   else
                     internalerror(2005082603);
@@ -445,6 +475,7 @@ unit cpupara;
                 paraloc^.loc:=LOC_FPUREGISTER;
                 paraloc^.register:=NR_FPU_RESULT_REG;
                 paraloc^.size:=retcgsize;
+                paraloc^.def:=result.def;
               end;
           end
           { Return in register }
@@ -455,16 +486,19 @@ unit cpupara;
                 paraloc^.loc:=LOC_REGISTER;
                 paraloc^.register:=NR_FUNCTION_RESULT64_LOW_REG;
                 paraloc^.size:=OS_32;
+                paraloc^.def:=u32inttype;
                 paraloc:=result.add_location;
                 paraloc^.loc:=LOC_REGISTER;
                 paraloc^.register:=NR_FUNCTION_RESULT64_HIGH_REG;
                 paraloc^.size:=OS_32;
+                paraloc^.def:=u32inttype;
               end
             else
               begin
                 paraloc^.loc:=LOC_REGISTER;
                 paraloc^.register:=NR_FUNCTION_RETURN_REG;
                 paraloc^.size:=OS_32;
+                paraloc^.def:=u32inttype;
               end;
           end;
       end;

+ 7 - 4
compiler/avr/navradd.pas

@@ -29,7 +29,7 @@ interface
        node,ncgadd,cpubase;
 
     type
-       tavraddnode = class(tcgaddnode)
+       TAVRAddNode = class(tcgaddnode)
        private
          function  GetResFlags(unsigned:Boolean):TResFlags;
        protected
@@ -54,7 +54,7 @@ interface
       ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32;
 
 {*****************************************************************************
-                               TSparcAddNode
+                               TAVRAddNode
 *****************************************************************************}
 
     function tavraddnode.GetResFlags(unsigned:Boolean):TResFlags;
@@ -193,12 +193,15 @@ interface
 
         for i:=2 to tcgsize2size[left.location.size] do
           begin
-            tmpreg1:=GetNextReg(tmpreg1);
-            tmpreg2:=GetNextReg(tmpreg2);
             if i=5 then
               begin
                 tmpreg1:=left.location.registerhi;
                 tmpreg2:=right.location.registerhi;
+              end
+            else
+              begin
+                tmpreg1:=GetNextReg(tmpreg1);
+                tmpreg2:=GetNextReg(tmpreg2);
               end;
             current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
           end;

+ 1 - 1
compiler/browcol.pas

@@ -48,7 +48,7 @@ const
     sfObject        = $00000002;
     sfClass         = $00000004;
     sfPointer       = $00000008;
-    sfHasMemInfo    = $80000000;
+    sfHasMemInfo    = $40000000;
 
 type
     TStoreCollection = object(TStringCollection)

+ 270 - 0
compiler/ccharset.pas

@@ -275,11 +275,281 @@ unit ccharset;
              end;
       end;
 
+   const
+     map : array[0..255] of tunicodecharmapping = (
+       (unicode : 0; flag : umf_noinfo; reserved: 0),
+       (unicode : 1; flag : umf_noinfo; reserved: 0),
+       (unicode : 2; flag : umf_noinfo; reserved: 0),
+       (unicode : 3; flag : umf_noinfo; reserved: 0),
+       (unicode : 4; flag : umf_noinfo; reserved: 0),
+       (unicode : 5; flag : umf_noinfo; reserved: 0),
+       (unicode : 6; flag : umf_noinfo; reserved: 0),
+       (unicode : 7; flag : umf_noinfo; reserved: 0),
+       (unicode : 8; flag : umf_noinfo; reserved: 0),
+       (unicode : 9; flag : umf_noinfo; reserved: 0),
+       (unicode : 10; flag : umf_noinfo; reserved: 0),
+       (unicode : 11; flag : umf_noinfo; reserved: 0),
+       (unicode : 12; flag : umf_noinfo; reserved: 0),
+       (unicode : 13; flag : umf_noinfo; reserved: 0),
+       (unicode : 14; flag : umf_noinfo; reserved: 0),
+       (unicode : 15; flag : umf_noinfo; reserved: 0),
+       (unicode : 16; flag : umf_noinfo; reserved: 0),
+       (unicode : 17; flag : umf_noinfo; reserved: 0),
+       (unicode : 18; flag : umf_noinfo; reserved: 0),
+       (unicode : 19; flag : umf_noinfo; reserved: 0),
+       (unicode : 20; flag : umf_noinfo; reserved: 0),
+       (unicode : 21; flag : umf_noinfo; reserved: 0),
+       (unicode : 22; flag : umf_noinfo; reserved: 0),
+       (unicode : 23; flag : umf_noinfo; reserved: 0),
+       (unicode : 24; flag : umf_noinfo; reserved: 0),
+       (unicode : 25; flag : umf_noinfo; reserved: 0),
+       (unicode : 26; flag : umf_noinfo; reserved: 0),
+       (unicode : 27; flag : umf_noinfo; reserved: 0),
+       (unicode : 28; flag : umf_noinfo; reserved: 0),
+       (unicode : 29; flag : umf_noinfo; reserved: 0),
+       (unicode : 30; flag : umf_noinfo; reserved: 0),
+       (unicode : 31; flag : umf_noinfo; reserved: 0),
+       (unicode : 32; flag : umf_noinfo; reserved: 0),
+       (unicode : 33; flag : umf_noinfo; reserved: 0),
+       (unicode : 34; flag : umf_noinfo; reserved: 0),
+       (unicode : 35; flag : umf_noinfo; reserved: 0),
+       (unicode : 36; flag : umf_noinfo; reserved: 0),
+       (unicode : 37; flag : umf_noinfo; reserved: 0),
+       (unicode : 38; flag : umf_noinfo; reserved: 0),
+       (unicode : 39; flag : umf_noinfo; reserved: 0),
+       (unicode : 40; flag : umf_noinfo; reserved: 0),
+       (unicode : 41; flag : umf_noinfo; reserved: 0),
+       (unicode : 42; flag : umf_noinfo; reserved: 0),
+       (unicode : 43; flag : umf_noinfo; reserved: 0),
+       (unicode : 44; flag : umf_noinfo; reserved: 0),
+       (unicode : 45; flag : umf_noinfo; reserved: 0),
+       (unicode : 46; flag : umf_noinfo; reserved: 0),
+       (unicode : 47; flag : umf_noinfo; reserved: 0),
+       (unicode : 48; flag : umf_noinfo; reserved: 0),
+       (unicode : 49; flag : umf_noinfo; reserved: 0),
+       (unicode : 50; flag : umf_noinfo; reserved: 0),
+       (unicode : 51; flag : umf_noinfo; reserved: 0),
+       (unicode : 52; flag : umf_noinfo; reserved: 0),
+       (unicode : 53; flag : umf_noinfo; reserved: 0),
+       (unicode : 54; flag : umf_noinfo; reserved: 0),
+       (unicode : 55; flag : umf_noinfo; reserved: 0),
+       (unicode : 56; flag : umf_noinfo; reserved: 0),
+       (unicode : 57; flag : umf_noinfo; reserved: 0),
+       (unicode : 58; flag : umf_noinfo; reserved: 0),
+       (unicode : 59; flag : umf_noinfo; reserved: 0),
+       (unicode : 60; flag : umf_noinfo; reserved: 0),
+       (unicode : 61; flag : umf_noinfo; reserved: 0),
+       (unicode : 62; flag : umf_noinfo; reserved: 0),
+       (unicode : 63; flag : umf_noinfo; reserved: 0),
+       (unicode : 64; flag : umf_noinfo; reserved: 0),
+       (unicode : 65; flag : umf_noinfo; reserved: 0),
+       (unicode : 66; flag : umf_noinfo; reserved: 0),
+       (unicode : 67; flag : umf_noinfo; reserved: 0),
+       (unicode : 68; flag : umf_noinfo; reserved: 0),
+       (unicode : 69; flag : umf_noinfo; reserved: 0),
+       (unicode : 70; flag : umf_noinfo; reserved: 0),
+       (unicode : 71; flag : umf_noinfo; reserved: 0),
+       (unicode : 72; flag : umf_noinfo; reserved: 0),
+       (unicode : 73; flag : umf_noinfo; reserved: 0),
+       (unicode : 74; flag : umf_noinfo; reserved: 0),
+       (unicode : 75; flag : umf_noinfo; reserved: 0),
+       (unicode : 76; flag : umf_noinfo; reserved: 0),
+       (unicode : 77; flag : umf_noinfo; reserved: 0),
+       (unicode : 78; flag : umf_noinfo; reserved: 0),
+       (unicode : 79; flag : umf_noinfo; reserved: 0),
+       (unicode : 80; flag : umf_noinfo; reserved: 0),
+       (unicode : 81; flag : umf_noinfo; reserved: 0),
+       (unicode : 82; flag : umf_noinfo; reserved: 0),
+       (unicode : 83; flag : umf_noinfo; reserved: 0),
+       (unicode : 84; flag : umf_noinfo; reserved: 0),
+       (unicode : 85; flag : umf_noinfo; reserved: 0),
+       (unicode : 86; flag : umf_noinfo; reserved: 0),
+       (unicode : 87; flag : umf_noinfo; reserved: 0),
+       (unicode : 88; flag : umf_noinfo; reserved: 0),
+       (unicode : 89; flag : umf_noinfo; reserved: 0),
+       (unicode : 90; flag : umf_noinfo; reserved: 0),
+       (unicode : 91; flag : umf_noinfo; reserved: 0),
+       (unicode : 92; flag : umf_noinfo; reserved: 0),
+       (unicode : 93; flag : umf_noinfo; reserved: 0),
+       (unicode : 94; flag : umf_noinfo; reserved: 0),
+       (unicode : 95; flag : umf_noinfo; reserved: 0),
+       (unicode : 96; flag : umf_noinfo; reserved: 0),
+       (unicode : 97; flag : umf_noinfo; reserved: 0),
+       (unicode : 98; flag : umf_noinfo; reserved: 0),
+       (unicode : 99; flag : umf_noinfo; reserved: 0),
+       (unicode : 100; flag : umf_noinfo; reserved: 0),
+       (unicode : 101; flag : umf_noinfo; reserved: 0),
+       (unicode : 102; flag : umf_noinfo; reserved: 0),
+       (unicode : 103; flag : umf_noinfo; reserved: 0),
+       (unicode : 104; flag : umf_noinfo; reserved: 0),
+       (unicode : 105; flag : umf_noinfo; reserved: 0),
+       (unicode : 106; flag : umf_noinfo; reserved: 0),
+       (unicode : 107; flag : umf_noinfo; reserved: 0),
+       (unicode : 108; flag : umf_noinfo; reserved: 0),
+       (unicode : 109; flag : umf_noinfo; reserved: 0),
+       (unicode : 110; flag : umf_noinfo; reserved: 0),
+       (unicode : 111; flag : umf_noinfo; reserved: 0),
+       (unicode : 112; flag : umf_noinfo; reserved: 0),
+       (unicode : 113; flag : umf_noinfo; reserved: 0),
+       (unicode : 114; flag : umf_noinfo; reserved: 0),
+       (unicode : 115; flag : umf_noinfo; reserved: 0),
+       (unicode : 116; flag : umf_noinfo; reserved: 0),
+       (unicode : 117; flag : umf_noinfo; reserved: 0),
+       (unicode : 118; flag : umf_noinfo; reserved: 0),
+       (unicode : 119; flag : umf_noinfo; reserved: 0),
+       (unicode : 120; flag : umf_noinfo; reserved: 0),
+       (unicode : 121; flag : umf_noinfo; reserved: 0),
+       (unicode : 122; flag : umf_noinfo; reserved: 0),
+       (unicode : 123; flag : umf_noinfo; reserved: 0),
+       (unicode : 124; flag : umf_noinfo; reserved: 0),
+       (unicode : 125; flag : umf_noinfo; reserved: 0),
+       (unicode : 126; flag : umf_noinfo; reserved: 0),
+       (unicode : 127; flag : umf_noinfo; reserved: 0),
+       (unicode : 128; flag : umf_noinfo; reserved: 0),
+       (unicode : 129; flag : umf_noinfo; reserved: 0),
+       (unicode : 130; flag : umf_noinfo; reserved: 0),
+       (unicode : 131; flag : umf_noinfo; reserved: 0),
+       (unicode : 132; flag : umf_noinfo; reserved: 0),
+       (unicode : 133; flag : umf_noinfo; reserved: 0),
+       (unicode : 134; flag : umf_noinfo; reserved: 0),
+       (unicode : 135; flag : umf_noinfo; reserved: 0),
+       (unicode : 136; flag : umf_noinfo; reserved: 0),
+       (unicode : 137; flag : umf_noinfo; reserved: 0),
+       (unicode : 138; flag : umf_noinfo; reserved: 0),
+       (unicode : 139; flag : umf_noinfo; reserved: 0),
+       (unicode : 140; flag : umf_noinfo; reserved: 0),
+       (unicode : 141; flag : umf_noinfo; reserved: 0),
+       (unicode : 142; flag : umf_noinfo; reserved: 0),
+       (unicode : 143; flag : umf_noinfo; reserved: 0),
+       (unicode : 144; flag : umf_noinfo; reserved: 0),
+       (unicode : 145; flag : umf_noinfo; reserved: 0),
+       (unicode : 146; flag : umf_noinfo; reserved: 0),
+       (unicode : 147; flag : umf_noinfo; reserved: 0),
+       (unicode : 148; flag : umf_noinfo; reserved: 0),
+       (unicode : 149; flag : umf_noinfo; reserved: 0),
+       (unicode : 150; flag : umf_noinfo; reserved: 0),
+       (unicode : 151; flag : umf_noinfo; reserved: 0),
+       (unicode : 152; flag : umf_noinfo; reserved: 0),
+       (unicode : 153; flag : umf_noinfo; reserved: 0),
+       (unicode : 154; flag : umf_noinfo; reserved: 0),
+       (unicode : 155; flag : umf_noinfo; reserved: 0),
+       (unicode : 156; flag : umf_noinfo; reserved: 0),
+       (unicode : 157; flag : umf_noinfo; reserved: 0),
+       (unicode : 158; flag : umf_noinfo; reserved: 0),
+       (unicode : 159; flag : umf_noinfo; reserved: 0),
+       (unicode : 160; flag : umf_noinfo; reserved: 0),
+       (unicode : 161; flag : umf_noinfo; reserved: 0),
+       (unicode : 162; flag : umf_noinfo; reserved: 0),
+       (unicode : 163; flag : umf_noinfo; reserved: 0),
+       (unicode : 164; flag : umf_noinfo; reserved: 0),
+       (unicode : 165; flag : umf_noinfo; reserved: 0),
+       (unicode : 166; flag : umf_noinfo; reserved: 0),
+       (unicode : 167; flag : umf_noinfo; reserved: 0),
+       (unicode : 168; flag : umf_noinfo; reserved: 0),
+       (unicode : 169; flag : umf_noinfo; reserved: 0),
+       (unicode : 170; flag : umf_noinfo; reserved: 0),
+       (unicode : 171; flag : umf_noinfo; reserved: 0),
+       (unicode : 172; flag : umf_noinfo; reserved: 0),
+       (unicode : 173; flag : umf_noinfo; reserved: 0),
+       (unicode : 174; flag : umf_noinfo; reserved: 0),
+       (unicode : 175; flag : umf_noinfo; reserved: 0),
+       (unicode : 176; flag : umf_noinfo; reserved: 0),
+       (unicode : 177; flag : umf_noinfo; reserved: 0),
+       (unicode : 178; flag : umf_noinfo; reserved: 0),
+       (unicode : 179; flag : umf_noinfo; reserved: 0),
+       (unicode : 180; flag : umf_noinfo; reserved: 0),
+       (unicode : 181; flag : umf_noinfo; reserved: 0),
+       (unicode : 182; flag : umf_noinfo; reserved: 0),
+       (unicode : 183; flag : umf_noinfo; reserved: 0),
+       (unicode : 184; flag : umf_noinfo; reserved: 0),
+       (unicode : 185; flag : umf_noinfo; reserved: 0),
+       (unicode : 186; flag : umf_noinfo; reserved: 0),
+       (unicode : 187; flag : umf_noinfo; reserved: 0),
+       (unicode : 188; flag : umf_noinfo; reserved: 0),
+       (unicode : 189; flag : umf_noinfo; reserved: 0),
+       (unicode : 190; flag : umf_noinfo; reserved: 0),
+       (unicode : 191; flag : umf_noinfo; reserved: 0),
+       (unicode : 192; flag : umf_noinfo; reserved: 0),
+       (unicode : 193; flag : umf_noinfo; reserved: 0),
+       (unicode : 194; flag : umf_noinfo; reserved: 0),
+       (unicode : 195; flag : umf_noinfo; reserved: 0),
+       (unicode : 196; flag : umf_noinfo; reserved: 0),
+       (unicode : 197; flag : umf_noinfo; reserved: 0),
+       (unicode : 198; flag : umf_noinfo; reserved: 0),
+       (unicode : 199; flag : umf_noinfo; reserved: 0),
+       (unicode : 200; flag : umf_noinfo; reserved: 0),
+       (unicode : 201; flag : umf_noinfo; reserved: 0),
+       (unicode : 202; flag : umf_noinfo; reserved: 0),
+       (unicode : 203; flag : umf_noinfo; reserved: 0),
+       (unicode : 204; flag : umf_noinfo; reserved: 0),
+       (unicode : 205; flag : umf_noinfo; reserved: 0),
+       (unicode : 206; flag : umf_noinfo; reserved: 0),
+       (unicode : 207; flag : umf_noinfo; reserved: 0),
+       (unicode : 208; flag : umf_noinfo; reserved: 0),
+       (unicode : 209; flag : umf_noinfo; reserved: 0),
+       (unicode : 210; flag : umf_noinfo; reserved: 0),
+       (unicode : 211; flag : umf_noinfo; reserved: 0),
+       (unicode : 212; flag : umf_noinfo; reserved: 0),
+       (unicode : 213; flag : umf_noinfo; reserved: 0),
+       (unicode : 214; flag : umf_noinfo; reserved: 0),
+       (unicode : 215; flag : umf_noinfo; reserved: 0),
+       (unicode : 216; flag : umf_noinfo; reserved: 0),
+       (unicode : 217; flag : umf_noinfo; reserved: 0),
+       (unicode : 218; flag : umf_noinfo; reserved: 0),
+       (unicode : 219; flag : umf_noinfo; reserved: 0),
+       (unicode : 220; flag : umf_noinfo; reserved: 0),
+       (unicode : 221; flag : umf_noinfo; reserved: 0),
+       (unicode : 222; flag : umf_noinfo; reserved: 0),
+       (unicode : 223; flag : umf_noinfo; reserved: 0),
+       (unicode : 224; flag : umf_noinfo; reserved: 0),
+       (unicode : 225; flag : umf_noinfo; reserved: 0),
+       (unicode : 226; flag : umf_noinfo; reserved: 0),
+       (unicode : 227; flag : umf_noinfo; reserved: 0),
+       (unicode : 228; flag : umf_noinfo; reserved: 0),
+       (unicode : 229; flag : umf_noinfo; reserved: 0),
+       (unicode : 230; flag : umf_noinfo; reserved: 0),
+       (unicode : 231; flag : umf_noinfo; reserved: 0),
+       (unicode : 232; flag : umf_noinfo; reserved: 0),
+       (unicode : 233; flag : umf_noinfo; reserved: 0),
+       (unicode : 234; flag : umf_noinfo; reserved: 0),
+       (unicode : 235; flag : umf_noinfo; reserved: 0),
+       (unicode : 236; flag : umf_noinfo; reserved: 0),
+       (unicode : 237; flag : umf_noinfo; reserved: 0),
+       (unicode : 238; flag : umf_noinfo; reserved: 0),
+       (unicode : 239; flag : umf_noinfo; reserved: 0),
+       (unicode : 240; flag : umf_noinfo; reserved: 0),
+       (unicode : 241; flag : umf_noinfo; reserved: 0),
+       (unicode : 242; flag : umf_noinfo; reserved: 0),
+       (unicode : 243; flag : umf_noinfo; reserved: 0),
+       (unicode : 244; flag : umf_noinfo; reserved: 0),
+       (unicode : 245; flag : umf_noinfo; reserved: 0),
+       (unicode : 246; flag : umf_noinfo; reserved: 0),
+       (unicode : 247; flag : umf_noinfo; reserved: 0),
+       (unicode : 248; flag : umf_noinfo; reserved: 0),
+       (unicode : 249; flag : umf_noinfo; reserved: 0),
+       (unicode : 250; flag : umf_noinfo; reserved: 0),
+       (unicode : 251; flag : umf_noinfo; reserved: 0),
+       (unicode : 252; flag : umf_noinfo; reserved: 0),
+       (unicode : 253; flag : umf_noinfo; reserved: 0),
+       (unicode : 254; flag : umf_noinfo; reserved: 0),
+       (unicode : 255; flag : umf_noinfo; reserved: 0)
+     );
+
+     unicodemap : tunicodemap = (
+       cpname : '8859-1';
+       cp : 28591;
+       map : @map;
+       lastchar : 255;
+       next : nil;
+       internalmap : true
+     );
+
   var
      hp : punicodemap;
 
 initialization
   mappings:=nil;
+  registermapping(@unicodemap)
 finalization
   while assigned(mappings) do
     begin

+ 31 - 54
compiler/cclasses.pas

@@ -579,10 +579,10 @@ type
       end;
 
 
-    function FPHash(const s:shortstring):LongWord;
-    function FPHash(P: PChar; Len: Integer): LongWord;
     function FPHash(P: PChar; Len: Integer; Tag: LongWord): LongWord;
-    function FPHash(const a:ansistring):LongWord;
+    function FPHash(P: PChar; Len: Integer): LongWord; inline;
+    function FPHash(const s:shortstring):LongWord; inline;
+    function FPHash(const a:ansistring):LongWord; inline;
 
 
 implementation
@@ -742,7 +742,7 @@ end;
 
 class procedure TFPList.Error(const Msg: string; Data: PtrInt);
 begin
-  Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame);
+  Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame), get_caller_frame(get_frame);
 end;
 
 procedure TFPList.Exchange(Index1, Index2: Integer);
@@ -1137,59 +1137,38 @@ end;
                             TFPHashList
 *****************************************************************************}
 
-    function FPHash(const s:shortstring):LongWord;
-      Var
-        p,pmax : pchar;
-      begin
-{$push}
-{$q-,r-}
-        result:=0;
-        p:=@s[1];
-        pmax:=@s[length(s)+1];
-        while (p<pmax) do
-          begin
-            result:=LongWord(LongInt(result shl 5) - LongInt(result)) xor LongWord(P^);
-            inc(p);
-          end;
-{$pop}
-      end;
-
-    function FPHash(P: PChar; Len: Integer): LongWord;
-      Var
-        pmax : pchar;
-      begin
-{$push}
-{$q-,r-}
-        result:=0;
-        pmax:=p+len;
-        while (p<pmax) do
-          begin
-            result:=LongWord(LongInt(result shl 5) - LongInt(result)) xor LongWord(P^);
-            inc(p);
-          end;
-{$pop}
-      end;
 
     function FPHash(P: PChar; Len: Integer; Tag: LongWord): LongWord;
-      Var
-        pmax : pchar;
-      begin
+    Var
+      pmax : pchar;
+    begin
 {$push}
 {$q-,r-}
-        result:=Tag;
-        pmax:=p+len;
-        while (p<pmax) do
-          begin
-            result:=LongWord(LongInt(result shl 5) - LongInt(result)) xor LongWord(P^);
-            inc(p);
-          end;
+      result:=Tag;
+      pmax:=p+len;
+      while (p<pmax) do
+        begin
+          {DJBHash: result:=result*33 + next_char}
+          result:=LongWord(LongInt(result shl 5) + LongInt(result)) + LongWord(P^);
+          inc(p);
+        end;
 {$pop}
-      end;
+    end;
 
-    function FPHash(const a: ansistring): LongWord;
-      begin
-         result:=fphash(pchar(a),length(a));
-      end;
+    function FPHash(P: PChar; Len: Integer): LongWord; inline;
+    begin
+      result:=fphash(P,Len, 5381);
+    end;
+
+    function FPHash(const s: shortstring): LongWord; inline;
+    begin
+      result:=fphash(pchar(@s[1]),length(s));
+    end;
+
+    function FPHash(const a: ansistring): LongWord; inline;
+    begin
+      result:=fphash(pchar(a),length(a));
+    end;
 
 
 procedure TFPHashList.RaiseIndexError(Index : Integer);
@@ -1461,7 +1440,7 @@ end;
 
 class procedure TFPHashList.Error(const Msg: string; Data: PtrInt);
 begin
-  Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame);
+  Raise EListError.CreateFmt(Msg,[Data])  at get_caller_addr(get_frame), get_caller_frame(get_frame);
 end;
 
 function TFPHashList.Expand: TFPHashList;
@@ -1506,8 +1485,6 @@ begin
 end;
 
 function TFPHashList.InternalFind(AHash:LongWord;const AName:TSymStr;out PrevIndex:Integer):Integer;
-var
-  HashIndex : Integer;
 begin
   prefetch(AName[1]);
   Result:=FHashTable^[AHash and FCapacityMask];

+ 11 - 1
compiler/cfileutl.pas

@@ -142,7 +142,7 @@ interface
 
 {$IF DEFINED(MORPHOS) OR DEFINED(AMIGA)}
 { * PATHCONV is implemented in the Amiga/MorphOS system unit * }
-{$WARNING TODO Amiga: implement PathConv() in System unit, which works with AnsiString}
+{$NOTE TODO Amiga: implement PathConv() in System unit, which works with AnsiString}
 function Unix2AmigaPath(path: ShortString): ShortString; external name 'PATHCONV';
 {$ELSE}
 function Unix2AmigaPath(path: String): String;{$IFDEF USEINLINE}inline;{$ENDIF}
@@ -708,6 +708,8 @@ end;
         P: PChar;
       begin
         Result := s;
+        { make result unique since we're going to change it via a pchar }
+        uniquestring(result);
         L := Length(Result);
         if L=0 then
           exit;
@@ -1201,6 +1203,14 @@ end;
        StartPos, EndPos, L: LongInt;
      begin
        Result:=False;
+
+       if (path_absolute(f)) then
+         begin
+           Result:=FileExistsNonCase('',f, allowcache, foundfile);
+           if Result then
+             Exit;
+         end;
+
        StartPos := 1;
        L := Length(Path);
        repeat

+ 155 - 68
compiler/cg64f32.pas

@@ -122,8 +122,8 @@ unit cg64f32;
 
     procedure splitparaloc64(const cgpara:tcgpara;var cgparalo,cgparahi:tcgpara);
       var
-        paraloclo,
-        paralochi : pcgparalocation;
+        paraloclo,paraloclo2,
+        paralochi,paralochi2 : pcgparalocation;
       begin
         if not(cgpara.size in [OS_64,OS_S64]) then
           internalerror(200408231);
@@ -143,51 +143,110 @@ unit cg64f32;
         cgparalo.intsize:=4;
         cgparalo.alignment:=cgpara.alignment;
         paraloclo:=cgparalo.add_location;
-        { 2 parameter fields? }
-        if assigned(cgpara.location^.next) then
-          begin
-            { Order for multiple locations is always
-                paraloc^ -> high
-                paraloc^.next -> low }
-            if (target_info.endian=ENDIAN_BIG) then
-              begin
-                { paraloc^ -> high
+        case cgpara.locations_count of
+          4:
+            begin
+              { 4 parameter fields? }
+              { Order for multiple locations is always
+                  paraloc^ -> high
                   paraloc^.next -> low }
-                move(cgpara.location^,paralochi^,sizeof(paralochi^));
-                move(cgpara.location^.next^,paraloclo^,sizeof(paraloclo^));
-              end
-            else
-              begin
-                { paraloc^ -> low
-                  paraloc^.next -> high }
-                move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
-                move(cgpara.location^.next^,paralochi^,sizeof(paralochi^));
-              end;
-          end
-        else
-          begin
-            { single parameter, this can only be in memory }
-            if cgpara.location^.loc<>LOC_REFERENCE then
-              internalerror(200408282);
-            move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
-            move(cgpara.location^,paralochi^,sizeof(paralochi^));
-            { for big endian low is at +4, for little endian high }
-            if target_info.endian = endian_big then
-              begin
-                inc(cgparalo.location^.reference.offset,4);
-                cgparalo.alignment:=newalignment(cgparalo.alignment,4);
-              end
-            else
-              begin
-                inc(cgparahi.location^.reference.offset,4);
-                cgparahi.alignment:=newalignment(cgparahi.alignment,4);
-              end;
-          end;
-        { fix size }
-        paraloclo^.size:=cgparalo.size;
-        paraloclo^.next:=nil;
-        paralochi^.size:=cgparahi.size;
-        paralochi^.next:=nil;
+              if (target_info.endian=ENDIAN_BIG) then
+                begin
+                  { paraloc^ -> high }
+                  move(cgpara.location^,paralochi^,sizeof(paralochi^));
+                  paralochi^.next:=nil;
+                  paralochi2:=cgparahi.add_location;
+                  move(cgpara.location^.next,paralochi2^,sizeof(paralochi2^));
+
+                  { paraloc^.next^.next^ -> low }
+                  move(cgpara.location^.next^.next^,paraloclo^,sizeof(paraloclo^));
+                  paraloclo^.next:=nil;
+                  paraloclo2:=cgparalo.add_location;
+                  move(cgpara.location^.next^.next^.next^,paraloclo2^,sizeof(paraloclo2^));
+                end
+              else
+                begin
+                  { paraloc^ -> low }
+                  move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
+                  paraloclo^.next:=nil;
+                  paraloclo2:=cgparalo.add_location;
+                  move(cgpara.location^.next^,paraloclo2^,sizeof(paraloclo2^));
+
+                  { paraloc^.next^.next -> high }
+                  move(cgpara.location^.next^.next^,paralochi^,sizeof(paralochi^));
+                  paralochi^.next:=nil;
+                  paralochi2:=cgparahi.add_location;
+                  move(cgpara.location^.next^.next^.next^,paralochi2^,sizeof(paralochi2^));
+                end;
+
+              { fix size }
+              paraloclo^.size:=OS_16;
+              paraloclo2^.size:=OS_16;
+              paraloclo2^.next:=nil;
+              paralochi^.size:=OS_16;
+              paralochi2^.size:=OS_16;
+              paralochi2^.next:=nil;
+              if cgpara.size=OS_S64 then
+                if target_info.endian=ENDIAN_BIG then
+                  paralochi^.size:=OS_S16
+                else
+                  paraloclo2^.size:=OS_S16;
+            end;
+          2:
+            begin
+              { 2 parameter fields? }
+              { Order for multiple locations is always
+                  paraloc^ -> high
+                  paraloc^.next -> low }
+              if (target_info.endian=ENDIAN_BIG) then
+                begin
+                  { paraloc^ -> high
+                    paraloc^.next -> low }
+                  move(cgpara.location^,paralochi^,sizeof(paralochi^));
+                  move(cgpara.location^.next^,paraloclo^,sizeof(paraloclo^));
+                end
+              else
+                begin
+                  { paraloc^ -> low
+                    paraloc^.next -> high }
+                  move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
+                  move(cgpara.location^.next^,paralochi^,sizeof(paralochi^));
+                end;
+
+              { fix size }
+              paraloclo^.size:=cgparalo.size;
+              paraloclo^.next:=nil;
+              paralochi^.size:=cgparahi.size;
+              paralochi^.next:=nil;
+            end;
+          1:
+            begin
+              { single parameter, this can only be in memory }
+              if cgpara.location^.loc<>LOC_REFERENCE then
+                internalerror(200408282);
+              move(cgpara.location^,paraloclo^,sizeof(paraloclo^));
+              move(cgpara.location^,paralochi^,sizeof(paralochi^));
+              { for big endian low is at +4, for little endian high }
+              if target_info.endian = endian_big then
+                begin
+                  inc(cgparalo.location^.reference.offset,4);
+                  cgparalo.alignment:=newalignment(cgparalo.alignment,4);
+                end
+              else
+                begin
+                  inc(cgparahi.location^.reference.offset,4);
+                  cgparahi.alignment:=newalignment(cgparahi.alignment,4);
+                end;
+
+              { fix size }
+              paraloclo^.size:=cgparalo.size;
+              paraloclo^.next:=nil;
+              paralochi^.size:=cgparahi.size;
+              paralochi^.next:=nil;
+            end;
+          else
+            internalerror(2013051901);
+        end;
       end;
 
 
@@ -219,10 +278,10 @@ unit cg64f32;
       begin
         if target_info.endian = endian_big then
           swap64(value);
-        cg.a_load_const_ref(list,OS_32,aint(lo(value)),ref);
+        cg.a_load_const_ref(list,OS_32,longint(lo(value)),ref);
         tmpref := ref;
         inc(tmpref.offset,4);
-        cg.a_load_const_ref(list,OS_32,aint(hi(value)),tmpref);
+        cg.a_load_const_ref(list,OS_32,longint(hi(value)),tmpref);
       end;
 
 
@@ -271,8 +330,8 @@ unit cg64f32;
     procedure tcg64f32.a_load64_const_reg(list : TAsmList;value : int64;reg : tregister64);
 
       begin
-        cg.a_load_const_reg(list,OS_32,aint(lo(value)),reg.reglo);
-        cg.a_load_const_reg(list,OS_32,aint(hi(value)),reg.reghi);
+        cg.a_load_const_reg(list,OS_32,longint(lo(value)),reg.reglo);
+        cg.a_load_const_reg(list,OS_32,longint(hi(value)),reg.reghi);
       end;
 
 
@@ -359,9 +418,9 @@ unit cg64f32;
           swap64(a);
         tmpsref := sref;
         tmpsref.bitlen := 32;
-        hlcg.a_load_const_subsetref(list,u32inttype,aint(lo(a)),tmpsref);
+        hlcg.a_load_const_subsetref(list,u32inttype,longint(lo(a)),tmpsref);
         inc(tmpsref.ref.offset,4);
-        hlcg.a_load_const_subsetref(list,u32inttype,aint(hi(a)),tmpsref);
+        hlcg.a_load_const_subsetref(list,u32inttype,longint(hi(a)),tmpsref);
       end;
 
 
@@ -537,7 +596,7 @@ unit cg64f32;
           LOC_CREGISTER :
             cg.a_load_reg_reg(list,OS_32,OS_32,l.register64.reglo,reg);
           LOC_CONSTANT :
-            cg.a_load_const_reg(list,OS_32,aint(lo(l.value64)),reg);
+            cg.a_load_const_reg(list,OS_32,longint(lo(l.value64)),reg);
           else
             internalerror(200203244);
         end;
@@ -554,7 +613,7 @@ unit cg64f32;
           LOC_CREGISTER :
             cg.a_load_reg_reg(list,OS_32,OS_32,l.register64.reghi,reg);
           LOC_CONSTANT :
-            cg.a_load_const_reg(list,OS_32,aint(hi(l.value64)),reg);
+            cg.a_load_const_reg(list,OS_32,longint(hi(l.value64)),reg);
           else
             internalerror(200203244);
         end;
@@ -645,10 +704,20 @@ unit cg64f32;
         tmploclo.init;
         tmplochi.init;
         splitparaloc64(paraloc,tmploclo,tmplochi);
-        { Keep this order of first hi before lo to have
-          the correct push order for i386 }
-        cg.a_load_reg_cgpara(list,OS_32,reg.reghi,tmplochi);
-        cg.a_load_reg_cgpara(list,OS_32,reg.reglo,tmploclo);
+        if target_info.endian=endian_big then
+          begin
+            { Keep this order of first lo before hi to have
+              the correct push order for m68k }
+            cg.a_load_reg_cgpara(list,OS_32,reg.reglo,tmploclo);
+            cg.a_load_reg_cgpara(list,OS_32,reg.reghi,tmplochi);
+          end
+        else
+          begin
+            { Keep this order of first hi before lo to have
+              the correct push order for i386 }
+            cg.a_load_reg_cgpara(list,OS_32,reg.reghi,tmplochi);
+            cg.a_load_reg_cgpara(list,OS_32,reg.reglo,tmploclo);
+          end;
         tmploclo.done;
         tmplochi.done;
       end;
@@ -661,10 +730,20 @@ unit cg64f32;
         tmploclo.init;
         tmplochi.init;
         splitparaloc64(paraloc,tmploclo,tmplochi);
-        { Keep this order of first hi before lo to have
-          the correct push order for i386 }
-        cg.a_load_const_cgpara(list,OS_32,aint(hi(value)),tmplochi);
-        cg.a_load_const_cgpara(list,OS_32,aint(lo(value)),tmploclo);
+        if target_info.endian=endian_big then
+          begin
+            { Keep this order of first lo before hi to have
+              the correct push order for m68k }
+            cg.a_load_const_cgpara(list,OS_32,longint(lo(value)),tmploclo);
+            cg.a_load_const_cgpara(list,OS_32,longint(hi(value)),tmplochi);
+          end
+        else
+          begin
+            { Keep this order of first hi before lo to have
+              the correct push order for i386 }
+            cg.a_load_const_cgpara(list,OS_32,longint(hi(value)),tmplochi);
+            cg.a_load_const_cgpara(list,OS_32,longint(lo(value)),tmploclo);
+          end;
         tmploclo.done;
         tmplochi.done;
       end;
@@ -681,13 +760,21 @@ unit cg64f32;
         tmprefhi:=r;
         tmpreflo:=r;
         if target_info.endian=endian_big then
-          inc(tmpreflo.offset,4)
+          begin
+            { Keep this order of first lo before hi to have
+              the correct push order for m68k }
+            inc(tmpreflo.offset,4);
+            cg.a_load_ref_cgpara(list,OS_32,tmpreflo,tmploclo);
+            cg.a_load_ref_cgpara(list,OS_32,tmprefhi,tmplochi);
+          end
         else
-          inc(tmprefhi.offset,4);
-        { Keep this order of first hi before lo to have
-          the correct push order for i386 }
-        cg.a_load_ref_cgpara(list,OS_32,tmprefhi,tmplochi);
-        cg.a_load_ref_cgpara(list,OS_32,tmpreflo,tmploclo);
+          begin
+            { Keep this order of first hi before lo to have
+              the correct push order for i386 }
+            inc(tmprefhi.offset,4);
+            cg.a_load_ref_cgpara(list,OS_32,tmprefhi,tmplochi);
+            cg.a_load_ref_cgpara(list,OS_32,tmpreflo,tmploclo);
+          end;
         tmploclo.done;
         tmplochi.done;
       end;

+ 36 - 9
compiler/cgbase.pas

@@ -84,11 +84,25 @@ interface
          addr_highera,     // bits 32-47, adjusted
          addr_highesta     // bits 48-63, adjusted
          {$ENDIF}
+         {$ENDIF POWERPC or POWERPC64 or SPARC or MIPS}
+         {$IFDEF MIPS}
+         ,
+         addr_pic_call16,  // like addr_pic, but generates call16 reloc instead of got16
+         addr_low_pic,     // for large GOT model, generate got_hi16 and got_lo16 relocs
+         addr_high_pic,
+         addr_low_call,    // counterpart of two above, generate call_hi16 and call_lo16 relocs
+         addr_high_call
          {$ENDIF}
          {$IFDEF AVR}
          ,addr_lo8
          ,addr_hi8
          {$ENDIF}
+         {$IFDEF i8086}
+         ,addr_dgroup      // the data segment group
+         ,addr_far         // used for emitting 'call/jmp far label' instructions
+         ,addr_far_ref     // used for emitting 'call far [reference]' instructions
+         ,addr_seg         // used for getting the segment of an object, e.g. 'mov ax, SEG symbol'
+         {$ENDIF}
          );
 
 
@@ -145,8 +159,8 @@ interface
                   OS_F32,OS_F64,OS_F80,OS_C64,OS_F128,
                  { multi-media sizes: split in byte, word, dword, ... }
                  { entities, then the signed counterparts             }
-                  OS_M8,OS_M16,OS_M32,OS_M64,OS_M128,
-                  OS_MS8,OS_MS16,OS_MS32,OS_MS64,OS_MS128);
+                  OS_M8,OS_M16,OS_M32,OS_M64,OS_M128,OS_M256,  
+                  OS_MS8,OS_MS16,OS_MS32,OS_MS64,OS_MS128,OS_MS256 );  
 
       { Register types }
       TRegisterType = (
@@ -174,7 +188,10 @@ interface
         R_SUBFQ,   { = 8; Float that allocates 4 FPU registers }
         R_SUBMMS,  { = 9; single scalar in multi media register }
         R_SUBMMD,  { = 10; double scalar in multi media register }
-        R_SUBMMWHOLE  { = 11; complete MM register, size depends on CPU }
+        R_SUBMMWHOLE,  { = 11; complete MM register, size depends on CPU }
+        { For Intel X86 AVX-Register }
+        R_SUBMMX,     { = 12; 128 BITS }
+        R_SUBMMY      { = 13; 256 BITS }
       );
       TSubRegisterSet = set of TSubRegister;
 
@@ -272,7 +289,7 @@ interface
          { floating point values }
          4,8,10,8,16,
          { multimedia values }
-         1,2,4,8,16,1,2,4,8,16);
+         1,2,4,8,16,32,1,2,4,8,16,32); 
 
        tfloat2tcgsize: array[tfloattype] of tcgsize =
          (OS_F32,OS_F64,OS_F80,OS_F80,OS_C64,OS_C64,OS_F128);
@@ -283,25 +300,35 @@ interface
        tvarregable2tcgloc : array[tvarregable] of tcgloc = (LOC_VOID,
           LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMREGISTER,LOC_CREGISTER);
 
-{$ifdef cpu64bitalu}
+{$if defined(cpu64bitalu)}
        { operand size describing an unsigned value in a pair of int registers }
        OS_PAIR = OS_128;
        { operand size describing an signed value in a pair of int registers }
        OS_SPAIR = OS_S128;
-{$else cpu64bitalu}
+{$elseif defined(cpu32bitalu)}
        { operand size describing an unsigned value in a pair of int registers }
        OS_PAIR = OS_64;
        { operand size describing an signed value in a pair of int registers }
        OS_SPAIR = OS_S64;
-{$endif cpu64bitalu}
+{$elseif defined(cpu16bitalu)}
+       { operand size describing an unsigned value in a pair of int registers }
+       OS_PAIR = OS_32;
+       { operand size describing an signed value in a pair of int registers }
+       OS_SPAIR = OS_S32;
+{$elseif defined(cpu8bitalu)}
+       { operand size describing an unsigned value in a pair of int registers }
+       OS_PAIR = OS_16;
+       { operand size describing an signed value in a pair of int registers }
+       OS_SPAIR = OS_S16;
+{$endif}
 
        { Table to convert tcgsize variables to the correspondending
          unsigned types }
        tcgsize2unsigned : array[tcgsize] of tcgsize = (OS_NO,
           OS_8,OS_16,OS_32,OS_64,OS_128,OS_8,OS_16,OS_32,OS_64,OS_128,
           OS_F32,OS_F64,OS_F80,OS_C64,OS_F128,
-          OS_M8,OS_M16,OS_M32,OS_M64,OS_M128,OS_M8,OS_M16,OS_M32,
-          OS_M64,OS_M128);
+          OS_M8,OS_M16,OS_M32,OS_M64,OS_M128,OS_M256,OS_M8,OS_M16,OS_M32,
+          OS_M64,OS_M128,OS_M256);
 
        tcgloc2str : array[TCGLoc] of string[12] = (
             'LOC_INVALID',

+ 63 - 19
compiler/cgobj.pas

@@ -52,8 +52,10 @@ unit cgobj;
           by Free Pascal. For 32-bit processors, the base class
           should be @link(tcg64f32) and not @var(tcg).
        }
+
+       { tcg }
+
        tcg = class
-       public
           { how many times is this current code executed }
           executionweight : longint;
           alignment : talignment;
@@ -271,6 +273,9 @@ unit cgobj;
           procedure a_opmm_ref_reg(list: TAsmList; Op: TOpCG; size : tcgsize;const ref: treference; reg: tregister;shuffle : pmmshuffle); virtual;
           procedure a_opmm_loc_reg(list: TAsmList; Op: TOpCG; size : tcgsize;const loc: tlocation; reg: tregister;shuffle : pmmshuffle); virtual;
           procedure a_opmm_reg_ref(list: TAsmList; Op: TOpCG; size : tcgsize;reg: tregister;const ref: treference; shuffle : pmmshuffle); virtual;
+          procedure a_opmm_loc_reg_reg(list: TAsmList;Op : TOpCG;size : tcgsize;const loc : tlocation;src,dst : tregister;shuffle : pmmshuffle); virtual;
+          procedure a_opmm_reg_reg_reg(list: TAsmList; Op: TOpCG; size : tcgsize;src1,src2,dst: tregister;shuffle : pmmshuffle); virtual;
+          procedure a_opmm_ref_reg_reg(list: TAsmList; Op: TOpCG; size : tcgsize;const ref: treference; src,dst: tregister;shuffle : pmmshuffle); virtual;
 
           procedure a_loadmm_intreg_reg(list: TAsmList; fromsize, tosize : tcgsize; intreg, mmreg: tregister; shuffle: pmmshuffle); virtual;
           procedure a_loadmm_reg_intreg(list: TAsmList; fromsize, tosize : tcgsize; mmreg, intreg: tregister; shuffle : pmmshuffle); virtual;
@@ -574,7 +579,7 @@ implementation
 
     uses
        globals,systems,
-       verbose,paramgr,symsym,
+       verbose,paramgr,symtable,symsym,
        tgobj,cutils,procinfo;
 
 {*****************************************************************************
@@ -697,14 +702,14 @@ implementation
     procedure tcg.allocallcpuregisters(list:TAsmList);
       begin
         alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-{$if not(defined(i386)) and not(defined(avr))}
+{$if not(defined(i386)) and not(defined(i8086)) and not(defined(avr))}
         if uses_registers(R_FPUREGISTER) then
           alloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
 {$ifdef cpumm}
         if uses_registers(R_MMREGISTER) then
           alloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_mm(pocall_default));
 {$endif cpumm}
-{$endif not(defined(i386)) and not(defined(avr))}
+{$endif not(defined(i386)) and not(defined(i8086)) and not(defined(avr))}
       end;
 
 
@@ -720,14 +725,14 @@ implementation
     procedure tcg.deallocallcpuregisters(list:TAsmList);
       begin
         dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-{$if not(defined(i386)) and not(defined(avr))}
+{$if not(defined(i386)) and not(defined(i8086)) and not(defined(avr))}
         if uses_registers(R_FPUREGISTER) then
           dealloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default));
 {$ifdef cpumm}
         if uses_registers(R_MMREGISTER) then
           dealloccpuregisters(list,R_MMREGISTER,paramanager.get_volatile_registers_mm(pocall_default));
 {$endif cpumm}
-{$endif not(defined(i386)) and not(defined(avr))}
+{$endif not(defined(i386)) and not(defined(i8086)) and not(defined(avr))}
       end;
 
 
@@ -1146,6 +1151,7 @@ implementation
                if paraloc.shiftval<0 then
                  a_op_const_reg_reg(list,OP_SHR,OS_INT,-paraloc.shiftval,paraloc.register,paraloc.register);
                case getregtype(reg) of
+                 R_ADDRESSREGISTER,
                  R_INTREGISTER:
                    a_load_reg_reg(list,paraloc.size,regsize,paraloc.register,reg);
                  R_MMREGISTER:
@@ -1157,6 +1163,7 @@ implementation
            LOC_MMREGISTER :
              begin
                case getregtype(reg) of
+                 R_ADDRESSREGISTER,
                  R_INTREGISTER:
                    a_loadmm_reg_intreg(list,paraloc.size,regsize,paraloc.register,reg,mms_movescalar);
                  R_MMREGISTER:
@@ -1183,6 +1190,7 @@ implementation
              begin
                reference_reset_base(href,paraloc.reference.index,paraloc.reference.offset,align);
                case getregtype(reg) of
+                 R_ADDRESSREGISTER,
                  R_INTREGISTER :
                    a_load_ref_reg(list,paraloc.size,regsize,href,reg);
                  R_FPUREGISTER :
@@ -1699,7 +1707,6 @@ implementation
 
     procedure Tcg.a_op_const_reg_reg(list:TAsmList;op:Topcg;size:Tcgsize;
                                      a:tcgint;src,dst:Tregister);
-
     begin
       a_load_reg_reg(list,size,size,src,dst);
       a_op_const_reg(list,op,size,a,dst);
@@ -1845,8 +1852,6 @@ implementation
 
 
     procedure tcg.a_loadmm_loc_reg(list: TAsmList; size: tcgsize; const loc: tlocation; const reg: tregister;shuffle : pmmshuffle);
-      var
-        tmpreg: tregister;
       begin
         case loc.loc of
           LOC_MMREGISTER,LOC_CMMREGISTER:
@@ -2061,6 +2066,33 @@ implementation
       end;
 
 
+    procedure tcg.a_opmm_loc_reg_reg(list: TAsmList; Op: TOpCG; size : tcgsize;const loc: tlocation; src,dst: tregister;shuffle : pmmshuffle);
+      begin
+        case loc.loc of
+          LOC_CMMREGISTER,LOC_MMREGISTER:
+            a_opmm_reg_reg_reg(list,op,size,loc.register,src,dst,shuffle);
+          LOC_CREFERENCE,LOC_REFERENCE:
+            a_opmm_ref_reg_reg(list,op,size,loc.reference,src,dst,shuffle);
+          else
+            internalerror(200312232);
+        end;
+      end;
+
+
+    procedure tcg.a_opmm_reg_reg_reg(list : TAsmList;Op : TOpCG;size : tcgsize;
+      src1,src2,dst : tregister;shuffle : pmmshuffle);
+      begin
+        internalerror(2013061102);
+      end;
+
+
+    procedure tcg.a_opmm_ref_reg_reg(list : TAsmList;Op : TOpCG;size : tcgsize;
+      const ref : treference;src,dst : tregister;shuffle : pmmshuffle);
+      begin
+        internalerror(2013061101);
+      end;
+
+
     procedure tcg.g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : tcgint);
       begin
         g_concatcopy(list,source,dest,len);
@@ -2090,29 +2122,41 @@ implementation
       var
         hrefvmt : treference;
         cgpara1,cgpara2 : TCGPara;
+        pd: tprocdef;
       begin
         cgpara1.init;
         cgpara2.init;
-        paramanager.getintparaloc(pocall_default,1,voidpointertype,cgpara1);
         if (cs_check_object in current_settings.localswitches) then
          begin
-           paramanager.getintparaloc(pocall_default,2,voidpointertype,cgpara2);
+           pd:=search_system_proc('fpc_check_object_ext');
+           paramanager.getintparaloc(pd,1,cgpara1);
+           paramanager.getintparaloc(pd,2,cgpara2);
            reference_reset_symbol(hrefvmt,current_asmdata.RefAsmSymbol(objdef.vmt_mangledname),0,sizeof(pint));
-           a_loadaddr_ref_cgpara(list,hrefvmt,cgpara2);
-           a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
+           if pd.is_pushleftright then
+             begin
+               a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
+               a_loadaddr_ref_cgpara(list,hrefvmt,cgpara2);
+             end
+           else
+             begin
+               a_loadaddr_ref_cgpara(list,hrefvmt,cgpara2);
+               a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
+             end;
            paramanager.freecgpara(list,cgpara1);
            paramanager.freecgpara(list,cgpara2);
            allocallcpuregisters(list);
-           a_call_name(list,'FPC_CHECK_OBJECT_EXT',false);
+           a_call_name(list,'fpc_check_object_ext',false);
            deallocallcpuregisters(list);
          end
         else
          if (cs_check_range in current_settings.localswitches) then
           begin
+            pd:=search_system_proc('fpc_check_object');
+            paramanager.getintparaloc(pd,1,cgpara1);
             a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
             paramanager.freecgpara(list,cgpara1);
             allocallcpuregisters(list);
-            a_call_name(list,'FPC_CHECK_OBJECT',false);
+            a_call_name(list,'fpc_check_object',false);
             deallocallcpuregisters(list);
           end;
         cgpara1.done;
@@ -2182,7 +2226,7 @@ implementation
                       begin
                         if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
                           begin
-                            a_loadmm_reg_ref(list,OS_VECTOR,OS_VECTOR,newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBNONE),href,nil);
+                            a_loadmm_reg_ref(list,OS_VECTOR,OS_VECTOR,newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBMMWHOLE),href,nil);
                             inc(href.offset,tcgsize2size[OS_VECTOR]);
                           end;
                         include(rg[R_MMREGISTER].preserved_by_proc,saved_mm_registers[r]);
@@ -2222,7 +2266,7 @@ implementation
               begin
                 if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
                   begin
-                    hreg:=newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBNONE);
+                    hreg:=newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBMMWHOLE);
                     { Allocate register so the optimizer does not remove the load }
                     a_reg_alloc(list,hreg);
                     a_loadmm_ref_reg(list,OS_VECTOR,OS_VECTOR,href,hreg,nil);
@@ -2708,8 +2752,8 @@ implementation
     procedure tcg128.a_load128_const_reg(list: TAsmList; valuelo,
      valuehi: int64; reg: tregister128);
      begin
-       cg.a_load_const_reg(list,OS_32,aint(valuelo),reg.reglo);
-       cg.a_load_const_reg(list,OS_32,aint(valuehi),reg.reghi);
+       cg.a_load_const_reg(list,OS_64,aint(valuelo),reg.reglo);
+       cg.a_load_const_reg(list,OS_64,aint(valuehi),reg.reghi);
      end;
 
 

+ 9 - 5
compiler/cgutils.pas

@@ -105,11 +105,15 @@ unit cgutils;
 {$endif cpuflags}
             LOC_CONSTANT : (
               case longint of
-{$ifdef FPC_BIG_ENDIAN}
-                1 : (_valuedummy,value : aint);
-{$else FPC_BIG_ENDIAN}
-                1 : (value : aint);
-{$endif FPC_BIG_ENDIAN}
+{$ifdef cpu64bitalu}
+                1 : (value : Int64);
+{$else cpu64bitalu}
+    {$ifdef FPC_BIG_ENDIAN}
+                1 : (_valuedummy,value : longint);
+    {$else FPC_BIG_ENDIAN}
+                1 : (value : longint);
+    {$endif FPC_BIG_ENDIAN}
+{$endif cpu64bitalu}
                 2 : (value64 : Int64);
               );
             LOC_CREFERENCE,

+ 4 - 1
compiler/comphook.pas

@@ -79,7 +79,10 @@ type
     currentmodulestate : string[20];
   { Total Status }
     compiledlines : longint;  { the number of lines which are compiled }
-    errorcount,
+    errorcount,               { this field should never be increased directly,
+                                use Verbose.GenerateError procedure to do this,
+                                this allows easier error catching using GDB by
+                                adding a single breakpoint at this procedure }
     countWarnings,
     countNotes,
     countHints    : longint;  { number of found errors/warnings/notes/hints }

+ 14 - 1
compiler/compiler.pas

@@ -31,8 +31,12 @@ uses
   emu387,
 {$endif GO32V2}
 {$ifdef WATCOM}
-    emu387,
+  emu387,
 {$endif WATCOM}
+{$if defined(unix) and (FPC_FULLVERSION>20700)}
+  { system code page stuff for unix }
+  unixcp,
+{$endif}
 {$IFNDEF USE_FAKE_SYSUTILS}
   sysutils,math,
 {$ELSE}
@@ -58,6 +62,9 @@ uses
 {$ifdef amiga}
   ,i_amiga
 {$endif amiga}
+{$ifdef android}
+  ,i_android
+{$endif android}
 {$ifdef atari}
   ,i_atari
 {$endif atari}
@@ -170,6 +177,10 @@ procedure InitCompiler(const cmd:TCmdStr);
 begin
   if CompilerInited then
    DoneCompiler;
+{$if defined(unix) and (FPC_FULLVERSION>20700)}
+  { Set default code page for ansistrings on unix-like systems }
+  DefaultSystemCodePage:=GetSystemCodePage;
+{$endif}
 { inits which need to be done before the arguments are parsed }
   InitSystems;
   { fileutils depends on source_info so it must be after systems }
@@ -260,6 +271,8 @@ begin
           totaltime:=getrealtime-starttime;
           if totaltime<0 then
             totaltime:=totaltime+3600.0*24.0;
+          if round(frac(totaltime)*10) >= 10 then
+            totaltime:=trunc(totaltime) + 1;
           timestr:=tostr(trunc(totaltime))+'.'+tostr(round(frac(totaltime)*10));
           if status.codesize<>aword(-1) then
             linkstr:=', '+tostr(status.codesize)+' ' +strpas(MessagePChar(general_text_bytes_code))+', '+tostr(status.datasize)+' '+strpas(MessagePChar(general_text_bytes_data))

+ 1 - 0
compiler/compinnr.inc

@@ -87,6 +87,7 @@ const
    in_box_x             = 77; { managed platforms: wrap in class instance }
    in_unbox_x_y         = 78; { manage platforms: extract from class instance }
    in_popcnt_x          = 79;
+   in_aligned_x         = 80;
 
 { Internal constant functions }
    in_const_sqr        = 100;

+ 0 - 9
compiler/constexp.pas

@@ -26,13 +26,6 @@ unit constexp;
 
 interface
 
-{ bootstrapping with 2.0.x }
-{$ifdef VER2_0}
-  {$Q-}
-  {$R-}
-{$endif}
-
-
 type  Tconstexprint=record
         overflow:boolean;
         case signed:boolean of
@@ -42,8 +35,6 @@ type  Tconstexprint=record
             (svalue:int64);
       end;
 
-      Tconststring = type pchar;
-
       errorproc=procedure (i:longint);
 
 {"Uses verbose" gives a dependency on cpuinfo through globals. This leads

+ 0 - 282
compiler/cp1251.pas

@@ -1,282 +0,0 @@
-{ This is an automatically created file, so don't edit it }
-unit cp1251;
-
-  interface
-
-  implementation
-
-  uses
-     {$if FPC_FULLVERSION<20700}ccharset{$else}charset{$endif};
-
-  const
-     map : array[0..255] of tunicodecharmapping = (
-       (unicode : 0; flag : umf_noinfo; reserved : 0),
-       (unicode : 1; flag : umf_noinfo; reserved : 0),
-       (unicode : 2; flag : umf_noinfo; reserved : 0),
-       (unicode : 3; flag : umf_noinfo; reserved : 0),
-       (unicode : 4; flag : umf_noinfo; reserved : 0),
-       (unicode : 5; flag : umf_noinfo; reserved : 0),
-       (unicode : 6; flag : umf_noinfo; reserved : 0),
-       (unicode : 7; flag : umf_noinfo; reserved : 0),
-       (unicode : 8; flag : umf_noinfo; reserved : 0),
-       (unicode : 9; flag : umf_noinfo; reserved : 0),
-       (unicode : 10; flag : umf_noinfo; reserved : 0),
-       (unicode : 11; flag : umf_noinfo; reserved : 0),
-       (unicode : 12; flag : umf_noinfo; reserved : 0),
-       (unicode : 13; flag : umf_noinfo; reserved : 0),
-       (unicode : 14; flag : umf_noinfo; reserved : 0),
-       (unicode : 15; flag : umf_noinfo; reserved : 0),
-       (unicode : 16; flag : umf_noinfo; reserved : 0),
-       (unicode : 17; flag : umf_noinfo; reserved : 0),
-       (unicode : 18; flag : umf_noinfo; reserved : 0),
-       (unicode : 19; flag : umf_noinfo; reserved : 0),
-       (unicode : 20; flag : umf_noinfo; reserved : 0),
-       (unicode : 21; flag : umf_noinfo; reserved : 0),
-       (unicode : 22; flag : umf_noinfo; reserved : 0),
-       (unicode : 23; flag : umf_noinfo; reserved : 0),
-       (unicode : 24; flag : umf_noinfo; reserved : 0),
-       (unicode : 25; flag : umf_noinfo; reserved : 0),
-       (unicode : 26; flag : umf_noinfo; reserved : 0),
-       (unicode : 27; flag : umf_noinfo; reserved : 0),
-       (unicode : 28; flag : umf_noinfo; reserved : 0),
-       (unicode : 29; flag : umf_noinfo; reserved : 0),
-       (unicode : 30; flag : umf_noinfo; reserved : 0),
-       (unicode : 31; flag : umf_noinfo; reserved : 0),
-       (unicode : 32; flag : umf_noinfo; reserved : 0),
-       (unicode : 33; flag : umf_noinfo; reserved : 0),
-       (unicode : 34; flag : umf_noinfo; reserved : 0),
-       (unicode : 35; flag : umf_noinfo; reserved : 0),
-       (unicode : 36; flag : umf_noinfo; reserved : 0),
-       (unicode : 37; flag : umf_noinfo; reserved : 0),
-       (unicode : 38; flag : umf_noinfo; reserved : 0),
-       (unicode : 39; flag : umf_noinfo; reserved : 0),
-       (unicode : 40; flag : umf_noinfo; reserved : 0),
-       (unicode : 41; flag : umf_noinfo; reserved : 0),
-       (unicode : 42; flag : umf_noinfo; reserved : 0),
-       (unicode : 43; flag : umf_noinfo; reserved : 0),
-       (unicode : 44; flag : umf_noinfo; reserved : 0),
-       (unicode : 45; flag : umf_noinfo; reserved : 0),
-       (unicode : 46; flag : umf_noinfo; reserved : 0),
-       (unicode : 47; flag : umf_noinfo; reserved : 0),
-       (unicode : 48; flag : umf_noinfo; reserved : 0),
-       (unicode : 49; flag : umf_noinfo; reserved : 0),
-       (unicode : 50; flag : umf_noinfo; reserved : 0),
-       (unicode : 51; flag : umf_noinfo; reserved : 0),
-       (unicode : 52; flag : umf_noinfo; reserved : 0),
-       (unicode : 53; flag : umf_noinfo; reserved : 0),
-       (unicode : 54; flag : umf_noinfo; reserved : 0),
-       (unicode : 55; flag : umf_noinfo; reserved : 0),
-       (unicode : 56; flag : umf_noinfo; reserved : 0),
-       (unicode : 57; flag : umf_noinfo; reserved : 0),
-       (unicode : 58; flag : umf_noinfo; reserved : 0),
-       (unicode : 59; flag : umf_noinfo; reserved : 0),
-       (unicode : 60; flag : umf_noinfo; reserved : 0),
-       (unicode : 61; flag : umf_noinfo; reserved : 0),
-       (unicode : 62; flag : umf_noinfo; reserved : 0),
-       (unicode : 63; flag : umf_noinfo; reserved : 0),
-       (unicode : 64; flag : umf_noinfo; reserved : 0),
-       (unicode : 65; flag : umf_noinfo; reserved : 0),
-       (unicode : 66; flag : umf_noinfo; reserved : 0),
-       (unicode : 67; flag : umf_noinfo; reserved : 0),
-       (unicode : 68; flag : umf_noinfo; reserved : 0),
-       (unicode : 69; flag : umf_noinfo; reserved : 0),
-       (unicode : 70; flag : umf_noinfo; reserved : 0),
-       (unicode : 71; flag : umf_noinfo; reserved : 0),
-       (unicode : 72; flag : umf_noinfo; reserved : 0),
-       (unicode : 73; flag : umf_noinfo; reserved : 0),
-       (unicode : 74; flag : umf_noinfo; reserved : 0),
-       (unicode : 75; flag : umf_noinfo; reserved : 0),
-       (unicode : 76; flag : umf_noinfo; reserved : 0),
-       (unicode : 77; flag : umf_noinfo; reserved : 0),
-       (unicode : 78; flag : umf_noinfo; reserved : 0),
-       (unicode : 79; flag : umf_noinfo; reserved : 0),
-       (unicode : 80; flag : umf_noinfo; reserved : 0),
-       (unicode : 81; flag : umf_noinfo; reserved : 0),
-       (unicode : 82; flag : umf_noinfo; reserved : 0),
-       (unicode : 83; flag : umf_noinfo; reserved : 0),
-       (unicode : 84; flag : umf_noinfo; reserved : 0),
-       (unicode : 85; flag : umf_noinfo; reserved : 0),
-       (unicode : 86; flag : umf_noinfo; reserved : 0),
-       (unicode : 87; flag : umf_noinfo; reserved : 0),
-       (unicode : 88; flag : umf_noinfo; reserved : 0),
-       (unicode : 89; flag : umf_noinfo; reserved : 0),
-       (unicode : 90; flag : umf_noinfo; reserved : 0),
-       (unicode : 91; flag : umf_noinfo; reserved : 0),
-       (unicode : 92; flag : umf_noinfo; reserved : 0),
-       (unicode : 93; flag : umf_noinfo; reserved : 0),
-       (unicode : 94; flag : umf_noinfo; reserved : 0),
-       (unicode : 95; flag : umf_noinfo; reserved : 0),
-       (unicode : 96; flag : umf_noinfo; reserved : 0),
-       (unicode : 97; flag : umf_noinfo; reserved : 0),
-       (unicode : 98; flag : umf_noinfo; reserved : 0),
-       (unicode : 99; flag : umf_noinfo; reserved : 0),
-       (unicode : 100; flag : umf_noinfo; reserved : 0),
-       (unicode : 101; flag : umf_noinfo; reserved : 0),
-       (unicode : 102; flag : umf_noinfo; reserved : 0),
-       (unicode : 103; flag : umf_noinfo; reserved : 0),
-       (unicode : 104; flag : umf_noinfo; reserved : 0),
-       (unicode : 105; flag : umf_noinfo; reserved : 0),
-       (unicode : 106; flag : umf_noinfo; reserved : 0),
-       (unicode : 107; flag : umf_noinfo; reserved : 0),
-       (unicode : 108; flag : umf_noinfo; reserved : 0),
-       (unicode : 109; flag : umf_noinfo; reserved : 0),
-       (unicode : 110; flag : umf_noinfo; reserved : 0),
-       (unicode : 111; flag : umf_noinfo; reserved : 0),
-       (unicode : 112; flag : umf_noinfo; reserved : 0),
-       (unicode : 113; flag : umf_noinfo; reserved : 0),
-       (unicode : 114; flag : umf_noinfo; reserved : 0),
-       (unicode : 115; flag : umf_noinfo; reserved : 0),
-       (unicode : 116; flag : umf_noinfo; reserved : 0),
-       (unicode : 117; flag : umf_noinfo; reserved : 0),
-       (unicode : 118; flag : umf_noinfo; reserved : 0),
-       (unicode : 119; flag : umf_noinfo; reserved : 0),
-       (unicode : 120; flag : umf_noinfo; reserved : 0),
-       (unicode : 121; flag : umf_noinfo; reserved : 0),
-       (unicode : 122; flag : umf_noinfo; reserved : 0),
-       (unicode : 123; flag : umf_noinfo; reserved : 0),
-       (unicode : 124; flag : umf_noinfo; reserved : 0),
-       (unicode : 125; flag : umf_noinfo; reserved : 0),
-       (unicode : 126; flag : umf_noinfo; reserved : 0),
-       (unicode : 127; flag : umf_noinfo; reserved : 0),
-       (unicode : 1026; flag : umf_noinfo; reserved : 0),
-       (unicode : 1027; flag : umf_noinfo; reserved : 0),
-       (unicode : 8218; flag : umf_noinfo; reserved : 0),
-       (unicode : 1107; flag : umf_noinfo; reserved : 0),
-       (unicode : 8222; flag : umf_noinfo; reserved : 0),
-       (unicode : 8230; flag : umf_noinfo; reserved : 0),
-       (unicode : 8224; flag : umf_noinfo; reserved : 0),
-       (unicode : 8225; flag : umf_noinfo; reserved : 0),
-       (unicode : 8364; flag : umf_noinfo; reserved : 0),
-       (unicode : 8240; flag : umf_noinfo; reserved : 0),
-       (unicode : 1033; flag : umf_noinfo; reserved : 0),
-       (unicode : 8249; flag : umf_noinfo; reserved : 0),
-       (unicode : 1034; flag : umf_noinfo; reserved : 0),
-       (unicode : 1036; flag : umf_noinfo; reserved : 0),
-       (unicode : 1035; flag : umf_noinfo; reserved : 0),
-       (unicode : 1039; flag : umf_noinfo; reserved : 0),
-       (unicode : 1106; flag : umf_noinfo; reserved : 0),
-       (unicode : 8216; flag : umf_noinfo; reserved : 0),
-       (unicode : 8217; flag : umf_noinfo; reserved : 0),
-       (unicode : 8220; flag : umf_noinfo; reserved : 0),
-       (unicode : 8221; flag : umf_noinfo; reserved : 0),
-       (unicode : 8226; flag : umf_noinfo; reserved : 0),
-       (unicode : 8211; flag : umf_noinfo; reserved : 0),
-       (unicode : 8212; flag : umf_noinfo; reserved : 0),
-       (unicode : 65535; flag : umf_unused; reserved : 0),
-       (unicode : 8482; flag : umf_noinfo; reserved : 0),
-       (unicode : 1113; flag : umf_noinfo; reserved : 0),
-       (unicode : 8250; flag : umf_noinfo; reserved : 0),
-       (unicode : 1114; flag : umf_noinfo; reserved : 0),
-       (unicode : 1116; flag : umf_noinfo; reserved : 0),
-       (unicode : 1115; flag : umf_noinfo; reserved : 0),
-       (unicode : 1119; flag : umf_noinfo; reserved : 0),
-       (unicode : 160; flag : umf_noinfo; reserved : 0),
-       (unicode : 1038; flag : umf_noinfo; reserved : 0),
-       (unicode : 1118; flag : umf_noinfo; reserved : 0),
-       (unicode : 1032; flag : umf_noinfo; reserved : 0),
-       (unicode : 164; flag : umf_noinfo; reserved : 0),
-       (unicode : 1168; flag : umf_noinfo; reserved : 0),
-       (unicode : 166; flag : umf_noinfo; reserved : 0),
-       (unicode : 167; flag : umf_noinfo; reserved : 0),
-       (unicode : 1025; flag : umf_noinfo; reserved : 0),
-       (unicode : 169; flag : umf_noinfo; reserved : 0),
-       (unicode : 1028; flag : umf_noinfo; reserved : 0),
-       (unicode : 171; flag : umf_noinfo; reserved : 0),
-       (unicode : 172; flag : umf_noinfo; reserved : 0),
-       (unicode : 173; flag : umf_noinfo; reserved : 0),
-       (unicode : 174; flag : umf_noinfo; reserved : 0),
-       (unicode : 1031; flag : umf_noinfo; reserved : 0),
-       (unicode : 176; flag : umf_noinfo; reserved : 0),
-       (unicode : 177; flag : umf_noinfo; reserved : 0),
-       (unicode : 1030; flag : umf_noinfo; reserved : 0),
-       (unicode : 1110; flag : umf_noinfo; reserved : 0),
-       (unicode : 1169; flag : umf_noinfo; reserved : 0),
-       (unicode : 181; flag : umf_noinfo; reserved : 0),
-       (unicode : 182; flag : umf_noinfo; reserved : 0),
-       (unicode : 183; flag : umf_noinfo; reserved : 0),
-       (unicode : 1105; flag : umf_noinfo; reserved : 0),
-       (unicode : 8470; flag : umf_noinfo; reserved : 0),
-       (unicode : 1108; flag : umf_noinfo; reserved : 0),
-       (unicode : 187; flag : umf_noinfo; reserved : 0),
-       (unicode : 1112; flag : umf_noinfo; reserved : 0),
-       (unicode : 1029; flag : umf_noinfo; reserved : 0),
-       (unicode : 1109; flag : umf_noinfo; reserved : 0),
-       (unicode : 1111; flag : umf_noinfo; reserved : 0),
-       (unicode : 1040; flag : umf_noinfo; reserved : 0),
-       (unicode : 1041; flag : umf_noinfo; reserved : 0),
-       (unicode : 1042; flag : umf_noinfo; reserved : 0),
-       (unicode : 1043; flag : umf_noinfo; reserved : 0),
-       (unicode : 1044; flag : umf_noinfo; reserved : 0),
-       (unicode : 1045; flag : umf_noinfo; reserved : 0),
-       (unicode : 1046; flag : umf_noinfo; reserved : 0),
-       (unicode : 1047; flag : umf_noinfo; reserved : 0),
-       (unicode : 1048; flag : umf_noinfo; reserved : 0),
-       (unicode : 1049; flag : umf_noinfo; reserved : 0),
-       (unicode : 1050; flag : umf_noinfo; reserved : 0),
-       (unicode : 1051; flag : umf_noinfo; reserved : 0),
-       (unicode : 1052; flag : umf_noinfo; reserved : 0),
-       (unicode : 1053; flag : umf_noinfo; reserved : 0),
-       (unicode : 1054; flag : umf_noinfo; reserved : 0),
-       (unicode : 1055; flag : umf_noinfo; reserved : 0),
-       (unicode : 1056; flag : umf_noinfo; reserved : 0),
-       (unicode : 1057; flag : umf_noinfo; reserved : 0),
-       (unicode : 1058; flag : umf_noinfo; reserved : 0),
-       (unicode : 1059; flag : umf_noinfo; reserved : 0),
-       (unicode : 1060; flag : umf_noinfo; reserved : 0),
-       (unicode : 1061; flag : umf_noinfo; reserved : 0),
-       (unicode : 1062; flag : umf_noinfo; reserved : 0),
-       (unicode : 1063; flag : umf_noinfo; reserved : 0),
-       (unicode : 1064; flag : umf_noinfo; reserved : 0),
-       (unicode : 1065; flag : umf_noinfo; reserved : 0),
-       (unicode : 1066; flag : umf_noinfo; reserved : 0),
-       (unicode : 1067; flag : umf_noinfo; reserved : 0),
-       (unicode : 1068; flag : umf_noinfo; reserved : 0),
-       (unicode : 1069; flag : umf_noinfo; reserved : 0),
-       (unicode : 1070; flag : umf_noinfo; reserved : 0),
-       (unicode : 1071; flag : umf_noinfo; reserved : 0),
-       (unicode : 1072; flag : umf_noinfo; reserved : 0),
-       (unicode : 1073; flag : umf_noinfo; reserved : 0),
-       (unicode : 1074; flag : umf_noinfo; reserved : 0),
-       (unicode : 1075; flag : umf_noinfo; reserved : 0),
-       (unicode : 1076; flag : umf_noinfo; reserved : 0),
-       (unicode : 1077; flag : umf_noinfo; reserved : 0),
-       (unicode : 1078; flag : umf_noinfo; reserved : 0),
-       (unicode : 1079; flag : umf_noinfo; reserved : 0),
-       (unicode : 1080; flag : umf_noinfo; reserved : 0),
-       (unicode : 1081; flag : umf_noinfo; reserved : 0),
-       (unicode : 1082; flag : umf_noinfo; reserved : 0),
-       (unicode : 1083; flag : umf_noinfo; reserved : 0),
-       (unicode : 1084; flag : umf_noinfo; reserved : 0),
-       (unicode : 1085; flag : umf_noinfo; reserved : 0),
-       (unicode : 1086; flag : umf_noinfo; reserved : 0),
-       (unicode : 1087; flag : umf_noinfo; reserved : 0),
-       (unicode : 1088; flag : umf_noinfo; reserved : 0),
-       (unicode : 1089; flag : umf_noinfo; reserved : 0),
-       (unicode : 1090; flag : umf_noinfo; reserved : 0),
-       (unicode : 1091; flag : umf_noinfo; reserved : 0),
-       (unicode : 1092; flag : umf_noinfo; reserved : 0),
-       (unicode : 1093; flag : umf_noinfo; reserved : 0),
-       (unicode : 1094; flag : umf_noinfo; reserved : 0),
-       (unicode : 1095; flag : umf_noinfo; reserved : 0),
-       (unicode : 1096; flag : umf_noinfo; reserved : 0),
-       (unicode : 1097; flag : umf_noinfo; reserved : 0),
-       (unicode : 1098; flag : umf_noinfo; reserved : 0),
-       (unicode : 1099; flag : umf_noinfo; reserved : 0),
-       (unicode : 1100; flag : umf_noinfo; reserved : 0),
-       (unicode : 1101; flag : umf_noinfo; reserved : 0),
-       (unicode : 1102; flag : umf_noinfo; reserved : 0),
-       (unicode : 1103; flag : umf_noinfo; reserved : 0)
-     );
-
-     unicodemap : tunicodemap = (
-       cpname : 'cp1251';
-       cp : 1251;
-       map : @map;
-       lastchar : 255;
-       next : nil;
-       internalmap : true
-     );
-
-  begin
-     registermapping(@unicodemap)
-  end.

+ 0 - 282
compiler/cp437.pas

@@ -1,282 +0,0 @@
-{ This is an automatically created file, so don't edit it }
-unit cp437;
-
-  interface
-
-  implementation
-
-  uses
-     {$if FPC_FULLVERSION<20700}ccharset{$else}charset{$endif};
-
-  const
-     map : array[0..255] of tunicodecharmapping = (
-       (unicode : 0; flag : umf_noinfo; reserved : 0),
-       (unicode : 1; flag : umf_noinfo; reserved : 0),
-       (unicode : 2; flag : umf_noinfo; reserved : 0),
-       (unicode : 3; flag : umf_noinfo; reserved : 0),
-       (unicode : 4; flag : umf_noinfo; reserved : 0),
-       (unicode : 5; flag : umf_noinfo; reserved : 0),
-       (unicode : 6; flag : umf_noinfo; reserved : 0),
-       (unicode : 7; flag : umf_noinfo; reserved : 0),
-       (unicode : 8; flag : umf_noinfo; reserved : 0),
-       (unicode : 9; flag : umf_noinfo; reserved : 0),
-       (unicode : 10; flag : umf_noinfo; reserved : 0),
-       (unicode : 11; flag : umf_noinfo; reserved : 0),
-       (unicode : 12; flag : umf_noinfo; reserved : 0),
-       (unicode : 13; flag : umf_noinfo; reserved : 0),
-       (unicode : 14; flag : umf_noinfo; reserved : 0),
-       (unicode : 15; flag : umf_noinfo; reserved : 0),
-       (unicode : 16; flag : umf_noinfo; reserved : 0),
-       (unicode : 17; flag : umf_noinfo; reserved : 0),
-       (unicode : 18; flag : umf_noinfo; reserved : 0),
-       (unicode : 19; flag : umf_noinfo; reserved : 0),
-       (unicode : 20; flag : umf_noinfo; reserved : 0),
-       (unicode : 21; flag : umf_noinfo; reserved : 0),
-       (unicode : 22; flag : umf_noinfo; reserved : 0),
-       (unicode : 23; flag : umf_noinfo; reserved : 0),
-       (unicode : 24; flag : umf_noinfo; reserved : 0),
-       (unicode : 25; flag : umf_noinfo; reserved : 0),
-       (unicode : 26; flag : umf_noinfo; reserved : 0),
-       (unicode : 27; flag : umf_noinfo; reserved : 0),
-       (unicode : 28; flag : umf_noinfo; reserved : 0),
-       (unicode : 29; flag : umf_noinfo; reserved : 0),
-       (unicode : 30; flag : umf_noinfo; reserved : 0),
-       (unicode : 31; flag : umf_noinfo; reserved : 0),
-       (unicode : 32; flag : umf_noinfo; reserved : 0),
-       (unicode : 33; flag : umf_noinfo; reserved : 0),
-       (unicode : 34; flag : umf_noinfo; reserved : 0),
-       (unicode : 35; flag : umf_noinfo; reserved : 0),
-       (unicode : 36; flag : umf_noinfo; reserved : 0),
-       (unicode : 37; flag : umf_noinfo; reserved : 0),
-       (unicode : 38; flag : umf_noinfo; reserved : 0),
-       (unicode : 39; flag : umf_noinfo; reserved : 0),
-       (unicode : 40; flag : umf_noinfo; reserved : 0),
-       (unicode : 41; flag : umf_noinfo; reserved : 0),
-       (unicode : 42; flag : umf_noinfo; reserved : 0),
-       (unicode : 43; flag : umf_noinfo; reserved : 0),
-       (unicode : 44; flag : umf_noinfo; reserved : 0),
-       (unicode : 45; flag : umf_noinfo; reserved : 0),
-       (unicode : 46; flag : umf_noinfo; reserved : 0),
-       (unicode : 47; flag : umf_noinfo; reserved : 0),
-       (unicode : 48; flag : umf_noinfo; reserved : 0),
-       (unicode : 49; flag : umf_noinfo; reserved : 0),
-       (unicode : 50; flag : umf_noinfo; reserved : 0),
-       (unicode : 51; flag : umf_noinfo; reserved : 0),
-       (unicode : 52; flag : umf_noinfo; reserved : 0),
-       (unicode : 53; flag : umf_noinfo; reserved : 0),
-       (unicode : 54; flag : umf_noinfo; reserved : 0),
-       (unicode : 55; flag : umf_noinfo; reserved : 0),
-       (unicode : 56; flag : umf_noinfo; reserved : 0),
-       (unicode : 57; flag : umf_noinfo; reserved : 0),
-       (unicode : 58; flag : umf_noinfo; reserved : 0),
-       (unicode : 59; flag : umf_noinfo; reserved : 0),
-       (unicode : 60; flag : umf_noinfo; reserved : 0),
-       (unicode : 61; flag : umf_noinfo; reserved : 0),
-       (unicode : 62; flag : umf_noinfo; reserved : 0),
-       (unicode : 63; flag : umf_noinfo; reserved : 0),
-       (unicode : 64; flag : umf_noinfo; reserved : 0),
-       (unicode : 65; flag : umf_noinfo; reserved : 0),
-       (unicode : 66; flag : umf_noinfo; reserved : 0),
-       (unicode : 67; flag : umf_noinfo; reserved : 0),
-       (unicode : 68; flag : umf_noinfo; reserved : 0),
-       (unicode : 69; flag : umf_noinfo; reserved : 0),
-       (unicode : 70; flag : umf_noinfo; reserved : 0),
-       (unicode : 71; flag : umf_noinfo; reserved : 0),
-       (unicode : 72; flag : umf_noinfo; reserved : 0),
-       (unicode : 73; flag : umf_noinfo; reserved : 0),
-       (unicode : 74; flag : umf_noinfo; reserved : 0),
-       (unicode : 75; flag : umf_noinfo; reserved : 0),
-       (unicode : 76; flag : umf_noinfo; reserved : 0),
-       (unicode : 77; flag : umf_noinfo; reserved : 0),
-       (unicode : 78; flag : umf_noinfo; reserved : 0),
-       (unicode : 79; flag : umf_noinfo; reserved : 0),
-       (unicode : 80; flag : umf_noinfo; reserved : 0),
-       (unicode : 81; flag : umf_noinfo; reserved : 0),
-       (unicode : 82; flag : umf_noinfo; reserved : 0),
-       (unicode : 83; flag : umf_noinfo; reserved : 0),
-       (unicode : 84; flag : umf_noinfo; reserved : 0),
-       (unicode : 85; flag : umf_noinfo; reserved : 0),
-       (unicode : 86; flag : umf_noinfo; reserved : 0),
-       (unicode : 87; flag : umf_noinfo; reserved : 0),
-       (unicode : 88; flag : umf_noinfo; reserved : 0),
-       (unicode : 89; flag : umf_noinfo; reserved : 0),
-       (unicode : 90; flag : umf_noinfo; reserved : 0),
-       (unicode : 91; flag : umf_noinfo; reserved : 0),
-       (unicode : 92; flag : umf_noinfo; reserved : 0),
-       (unicode : 93; flag : umf_noinfo; reserved : 0),
-       (unicode : 94; flag : umf_noinfo; reserved : 0),
-       (unicode : 95; flag : umf_noinfo; reserved : 0),
-       (unicode : 96; flag : umf_noinfo; reserved : 0),
-       (unicode : 97; flag : umf_noinfo; reserved : 0),
-       (unicode : 98; flag : umf_noinfo; reserved : 0),
-       (unicode : 99; flag : umf_noinfo; reserved : 0),
-       (unicode : 100; flag : umf_noinfo; reserved : 0),
-       (unicode : 101; flag : umf_noinfo; reserved : 0),
-       (unicode : 102; flag : umf_noinfo; reserved : 0),
-       (unicode : 103; flag : umf_noinfo; reserved : 0),
-       (unicode : 104; flag : umf_noinfo; reserved : 0),
-       (unicode : 105; flag : umf_noinfo; reserved : 0),
-       (unicode : 106; flag : umf_noinfo; reserved : 0),
-       (unicode : 107; flag : umf_noinfo; reserved : 0),
-       (unicode : 108; flag : umf_noinfo; reserved : 0),
-       (unicode : 109; flag : umf_noinfo; reserved : 0),
-       (unicode : 110; flag : umf_noinfo; reserved : 0),
-       (unicode : 111; flag : umf_noinfo; reserved : 0),
-       (unicode : 112; flag : umf_noinfo; reserved : 0),
-       (unicode : 113; flag : umf_noinfo; reserved : 0),
-       (unicode : 114; flag : umf_noinfo; reserved : 0),
-       (unicode : 115; flag : umf_noinfo; reserved : 0),
-       (unicode : 116; flag : umf_noinfo; reserved : 0),
-       (unicode : 117; flag : umf_noinfo; reserved : 0),
-       (unicode : 118; flag : umf_noinfo; reserved : 0),
-       (unicode : 119; flag : umf_noinfo; reserved : 0),
-       (unicode : 120; flag : umf_noinfo; reserved : 0),
-       (unicode : 121; flag : umf_noinfo; reserved : 0),
-       (unicode : 122; flag : umf_noinfo; reserved : 0),
-       (unicode : 123; flag : umf_noinfo; reserved : 0),
-       (unicode : 124; flag : umf_noinfo; reserved : 0),
-       (unicode : 125; flag : umf_noinfo; reserved : 0),
-       (unicode : 126; flag : umf_noinfo; reserved : 0),
-       (unicode : 127; flag : umf_noinfo; reserved : 0),
-       (unicode : 199; flag : umf_noinfo; reserved : 0),
-       (unicode : 252; flag : umf_noinfo; reserved : 0),
-       (unicode : 233; flag : umf_noinfo; reserved : 0),
-       (unicode : 226; flag : umf_noinfo; reserved : 0),
-       (unicode : 228; flag : umf_noinfo; reserved : 0),
-       (unicode : 224; flag : umf_noinfo; reserved : 0),
-       (unicode : 229; flag : umf_noinfo; reserved : 0),
-       (unicode : 231; flag : umf_noinfo; reserved : 0),
-       (unicode : 234; flag : umf_noinfo; reserved : 0),
-       (unicode : 235; flag : umf_noinfo; reserved : 0),
-       (unicode : 232; flag : umf_noinfo; reserved : 0),
-       (unicode : 239; flag : umf_noinfo; reserved : 0),
-       (unicode : 238; flag : umf_noinfo; reserved : 0),
-       (unicode : 236; flag : umf_noinfo; reserved : 0),
-       (unicode : 196; flag : umf_noinfo; reserved : 0),
-       (unicode : 197; flag : umf_noinfo; reserved : 0),
-       (unicode : 201; flag : umf_noinfo; reserved : 0),
-       (unicode : 230; flag : umf_noinfo; reserved : 0),
-       (unicode : 198; flag : umf_noinfo; reserved : 0),
-       (unicode : 244; flag : umf_noinfo; reserved : 0),
-       (unicode : 246; flag : umf_noinfo; reserved : 0),
-       (unicode : 242; flag : umf_noinfo; reserved : 0),
-       (unicode : 251; flag : umf_noinfo; reserved : 0),
-       (unicode : 249; flag : umf_noinfo; reserved : 0),
-       (unicode : 255; flag : umf_noinfo; reserved : 0),
-       (unicode : 214; flag : umf_noinfo; reserved : 0),
-       (unicode : 220; flag : umf_noinfo; reserved : 0),
-       (unicode : 162; flag : umf_noinfo; reserved : 0),
-       (unicode : 163; flag : umf_noinfo; reserved : 0),
-       (unicode : 165; flag : umf_noinfo; reserved : 0),
-       (unicode : 8359; flag : umf_noinfo; reserved : 0),
-       (unicode : 402; flag : umf_noinfo; reserved : 0),
-       (unicode : 225; flag : umf_noinfo; reserved : 0),
-       (unicode : 237; flag : umf_noinfo; reserved : 0),
-       (unicode : 243; flag : umf_noinfo; reserved : 0),
-       (unicode : 250; flag : umf_noinfo; reserved : 0),
-       (unicode : 241; flag : umf_noinfo; reserved : 0),
-       (unicode : 209; flag : umf_noinfo; reserved : 0),
-       (unicode : 170; flag : umf_noinfo; reserved : 0),
-       (unicode : 186; flag : umf_noinfo; reserved : 0),
-       (unicode : 191; flag : umf_noinfo; reserved : 0),
-       (unicode : 8976; flag : umf_noinfo; reserved : 0),
-       (unicode : 172; flag : umf_noinfo; reserved : 0),
-       (unicode : 189; flag : umf_noinfo; reserved : 0),
-       (unicode : 188; flag : umf_noinfo; reserved : 0),
-       (unicode : 161; flag : umf_noinfo; reserved : 0),
-       (unicode : 171; flag : umf_noinfo; reserved : 0),
-       (unicode : 187; flag : umf_noinfo; reserved : 0),
-       (unicode : 9617; flag : umf_noinfo; reserved : 0),
-       (unicode : 9618; flag : umf_noinfo; reserved : 0),
-       (unicode : 9619; flag : umf_noinfo; reserved : 0),
-       (unicode : 9474; flag : umf_noinfo; reserved : 0),
-       (unicode : 9508; flag : umf_noinfo; reserved : 0),
-       (unicode : 9569; flag : umf_noinfo; reserved : 0),
-       (unicode : 9570; flag : umf_noinfo; reserved : 0),
-       (unicode : 9558; flag : umf_noinfo; reserved : 0),
-       (unicode : 9557; flag : umf_noinfo; reserved : 0),
-       (unicode : 9571; flag : umf_noinfo; reserved : 0),
-       (unicode : 9553; flag : umf_noinfo; reserved : 0),
-       (unicode : 9559; flag : umf_noinfo; reserved : 0),
-       (unicode : 9565; flag : umf_noinfo; reserved : 0),
-       (unicode : 9564; flag : umf_noinfo; reserved : 0),
-       (unicode : 9563; flag : umf_noinfo; reserved : 0),
-       (unicode : 9488; flag : umf_noinfo; reserved : 0),
-       (unicode : 9492; flag : umf_noinfo; reserved : 0),
-       (unicode : 9524; flag : umf_noinfo; reserved : 0),
-       (unicode : 9516; flag : umf_noinfo; reserved : 0),
-       (unicode : 9500; flag : umf_noinfo; reserved : 0),
-       (unicode : 9472; flag : umf_noinfo; reserved : 0),
-       (unicode : 9532; flag : umf_noinfo; reserved : 0),
-       (unicode : 9566; flag : umf_noinfo; reserved : 0),
-       (unicode : 9567; flag : umf_noinfo; reserved : 0),
-       (unicode : 9562; flag : umf_noinfo; reserved : 0),
-       (unicode : 9556; flag : umf_noinfo; reserved : 0),
-       (unicode : 9577; flag : umf_noinfo; reserved : 0),
-       (unicode : 9574; flag : umf_noinfo; reserved : 0),
-       (unicode : 9568; flag : umf_noinfo; reserved : 0),
-       (unicode : 9552; flag : umf_noinfo; reserved : 0),
-       (unicode : 9580; flag : umf_noinfo; reserved : 0),
-       (unicode : 9575; flag : umf_noinfo; reserved : 0),
-       (unicode : 9576; flag : umf_noinfo; reserved : 0),
-       (unicode : 9572; flag : umf_noinfo; reserved : 0),
-       (unicode : 9573; flag : umf_noinfo; reserved : 0),
-       (unicode : 9561; flag : umf_noinfo; reserved : 0),
-       (unicode : 9560; flag : umf_noinfo; reserved : 0),
-       (unicode : 9554; flag : umf_noinfo; reserved : 0),
-       (unicode : 9555; flag : umf_noinfo; reserved : 0),
-       (unicode : 9579; flag : umf_noinfo; reserved : 0),
-       (unicode : 9578; flag : umf_noinfo; reserved : 0),
-       (unicode : 9496; flag : umf_noinfo; reserved : 0),
-       (unicode : 9484; flag : umf_noinfo; reserved : 0),
-       (unicode : 9608; flag : umf_noinfo; reserved : 0),
-       (unicode : 9604; flag : umf_noinfo; reserved : 0),
-       (unicode : 9612; flag : umf_noinfo; reserved : 0),
-       (unicode : 9616; flag : umf_noinfo; reserved : 0),
-       (unicode : 9600; flag : umf_noinfo; reserved : 0),
-       (unicode : 945; flag : umf_noinfo; reserved : 0),
-       (unicode : 223; flag : umf_noinfo; reserved : 0),
-       (unicode : 915; flag : umf_noinfo; reserved : 0),
-       (unicode : 960; flag : umf_noinfo; reserved : 0),
-       (unicode : 931; flag : umf_noinfo; reserved : 0),
-       (unicode : 963; flag : umf_noinfo; reserved : 0),
-       (unicode : 181; flag : umf_noinfo; reserved : 0),
-       (unicode : 964; flag : umf_noinfo; reserved : 0),
-       (unicode : 934; flag : umf_noinfo; reserved : 0),
-       (unicode : 920; flag : umf_noinfo; reserved : 0),
-       (unicode : 937; flag : umf_noinfo; reserved : 0),
-       (unicode : 948; flag : umf_noinfo; reserved : 0),
-       (unicode : 8734; flag : umf_noinfo; reserved : 0),
-       (unicode : 966; flag : umf_noinfo; reserved : 0),
-       (unicode : 949; flag : umf_noinfo; reserved : 0),
-       (unicode : 8745; flag : umf_noinfo; reserved : 0),
-       (unicode : 8801; flag : umf_noinfo; reserved : 0),
-       (unicode : 177; flag : umf_noinfo; reserved : 0),
-       (unicode : 8805; flag : umf_noinfo; reserved : 0),
-       (unicode : 8804; flag : umf_noinfo; reserved : 0),
-       (unicode : 8992; flag : umf_noinfo; reserved : 0),
-       (unicode : 8993; flag : umf_noinfo; reserved : 0),
-       (unicode : 247; flag : umf_noinfo; reserved : 0),
-       (unicode : 8776; flag : umf_noinfo; reserved : 0),
-       (unicode : 176; flag : umf_noinfo; reserved : 0),
-       (unicode : 8729; flag : umf_noinfo; reserved : 0),
-       (unicode : 183; flag : umf_noinfo; reserved : 0),
-       (unicode : 8730; flag : umf_noinfo; reserved : 0),
-       (unicode : 8319; flag : umf_noinfo; reserved : 0),
-       (unicode : 178; flag : umf_noinfo; reserved : 0),
-       (unicode : 9632; flag : umf_noinfo; reserved : 0),
-       (unicode : 160; flag : umf_noinfo; reserved : 0)
-     );
-
-     unicodemap : tunicodemap = (
-       cpname : 'cp437';
-       cp : 437;
-       map : @map[0];
-       lastchar : 255;
-       next : nil;
-       internalmap : true
-     );
-
-  begin
-     registermapping(@unicodemap)
-  end.

+ 0 - 282
compiler/cp850.pas

@@ -1,282 +0,0 @@
-{ This is an automatically created file, so don't edit it }
-unit cp850;
-
-  interface
-
-  implementation
-
-  uses
-     {$if FPC_FULLVERSION<20700}ccharset{$else}charset{$endif};
-
-  const
-     map : array[0..255] of tunicodecharmapping = (
-       (unicode : 0; flag : umf_noinfo; reserved : 0),
-       (unicode : 1; flag : umf_noinfo; reserved : 0),
-       (unicode : 2; flag : umf_noinfo; reserved : 0),
-       (unicode : 3; flag : umf_noinfo; reserved : 0),
-       (unicode : 4; flag : umf_noinfo; reserved : 0),
-       (unicode : 5; flag : umf_noinfo; reserved : 0),
-       (unicode : 6; flag : umf_noinfo; reserved : 0),
-       (unicode : 7; flag : umf_noinfo; reserved : 0),
-       (unicode : 8; flag : umf_noinfo; reserved : 0),
-       (unicode : 9; flag : umf_noinfo; reserved : 0),
-       (unicode : 10; flag : umf_noinfo; reserved : 0),
-       (unicode : 11; flag : umf_noinfo; reserved : 0),
-       (unicode : 12; flag : umf_noinfo; reserved : 0),
-       (unicode : 13; flag : umf_noinfo; reserved : 0),
-       (unicode : 14; flag : umf_noinfo; reserved : 0),
-       (unicode : 15; flag : umf_noinfo; reserved : 0),
-       (unicode : 16; flag : umf_noinfo; reserved : 0),
-       (unicode : 17; flag : umf_noinfo; reserved : 0),
-       (unicode : 18; flag : umf_noinfo; reserved : 0),
-       (unicode : 19; flag : umf_noinfo; reserved : 0),
-       (unicode : 20; flag : umf_noinfo; reserved : 0),
-       (unicode : 21; flag : umf_noinfo; reserved : 0),
-       (unicode : 22; flag : umf_noinfo; reserved : 0),
-       (unicode : 23; flag : umf_noinfo; reserved : 0),
-       (unicode : 24; flag : umf_noinfo; reserved : 0),
-       (unicode : 25; flag : umf_noinfo; reserved : 0),
-       (unicode : 26; flag : umf_noinfo; reserved : 0),
-       (unicode : 27; flag : umf_noinfo; reserved : 0),
-       (unicode : 28; flag : umf_noinfo; reserved : 0),
-       (unicode : 29; flag : umf_noinfo; reserved : 0),
-       (unicode : 30; flag : umf_noinfo; reserved : 0),
-       (unicode : 31; flag : umf_noinfo; reserved : 0),
-       (unicode : 32; flag : umf_noinfo; reserved : 0),
-       (unicode : 33; flag : umf_noinfo; reserved : 0),
-       (unicode : 34; flag : umf_noinfo; reserved : 0),
-       (unicode : 35; flag : umf_noinfo; reserved : 0),
-       (unicode : 36; flag : umf_noinfo; reserved : 0),
-       (unicode : 37; flag : umf_noinfo; reserved : 0),
-       (unicode : 38; flag : umf_noinfo; reserved : 0),
-       (unicode : 39; flag : umf_noinfo; reserved : 0),
-       (unicode : 40; flag : umf_noinfo; reserved : 0),
-       (unicode : 41; flag : umf_noinfo; reserved : 0),
-       (unicode : 42; flag : umf_noinfo; reserved : 0),
-       (unicode : 43; flag : umf_noinfo; reserved : 0),
-       (unicode : 44; flag : umf_noinfo; reserved : 0),
-       (unicode : 45; flag : umf_noinfo; reserved : 0),
-       (unicode : 46; flag : umf_noinfo; reserved : 0),
-       (unicode : 47; flag : umf_noinfo; reserved : 0),
-       (unicode : 48; flag : umf_noinfo; reserved : 0),
-       (unicode : 49; flag : umf_noinfo; reserved : 0),
-       (unicode : 50; flag : umf_noinfo; reserved : 0),
-       (unicode : 51; flag : umf_noinfo; reserved : 0),
-       (unicode : 52; flag : umf_noinfo; reserved : 0),
-       (unicode : 53; flag : umf_noinfo; reserved : 0),
-       (unicode : 54; flag : umf_noinfo; reserved : 0),
-       (unicode : 55; flag : umf_noinfo; reserved : 0),
-       (unicode : 56; flag : umf_noinfo; reserved : 0),
-       (unicode : 57; flag : umf_noinfo; reserved : 0),
-       (unicode : 58; flag : umf_noinfo; reserved : 0),
-       (unicode : 59; flag : umf_noinfo; reserved : 0),
-       (unicode : 60; flag : umf_noinfo; reserved : 0),
-       (unicode : 61; flag : umf_noinfo; reserved : 0),
-       (unicode : 62; flag : umf_noinfo; reserved : 0),
-       (unicode : 63; flag : umf_noinfo; reserved : 0),
-       (unicode : 64; flag : umf_noinfo; reserved : 0),
-       (unicode : 65; flag : umf_noinfo; reserved : 0),
-       (unicode : 66; flag : umf_noinfo; reserved : 0),
-       (unicode : 67; flag : umf_noinfo; reserved : 0),
-       (unicode : 68; flag : umf_noinfo; reserved : 0),
-       (unicode : 69; flag : umf_noinfo; reserved : 0),
-       (unicode : 70; flag : umf_noinfo; reserved : 0),
-       (unicode : 71; flag : umf_noinfo; reserved : 0),
-       (unicode : 72; flag : umf_noinfo; reserved : 0),
-       (unicode : 73; flag : umf_noinfo; reserved : 0),
-       (unicode : 74; flag : umf_noinfo; reserved : 0),
-       (unicode : 75; flag : umf_noinfo; reserved : 0),
-       (unicode : 76; flag : umf_noinfo; reserved : 0),
-       (unicode : 77; flag : umf_noinfo; reserved : 0),
-       (unicode : 78; flag : umf_noinfo; reserved : 0),
-       (unicode : 79; flag : umf_noinfo; reserved : 0),
-       (unicode : 80; flag : umf_noinfo; reserved : 0),
-       (unicode : 81; flag : umf_noinfo; reserved : 0),
-       (unicode : 82; flag : umf_noinfo; reserved : 0),
-       (unicode : 83; flag : umf_noinfo; reserved : 0),
-       (unicode : 84; flag : umf_noinfo; reserved : 0),
-       (unicode : 85; flag : umf_noinfo; reserved : 0),
-       (unicode : 86; flag : umf_noinfo; reserved : 0),
-       (unicode : 87; flag : umf_noinfo; reserved : 0),
-       (unicode : 88; flag : umf_noinfo; reserved : 0),
-       (unicode : 89; flag : umf_noinfo; reserved : 0),
-       (unicode : 90; flag : umf_noinfo; reserved : 0),
-       (unicode : 91; flag : umf_noinfo; reserved : 0),
-       (unicode : 92; flag : umf_noinfo; reserved : 0),
-       (unicode : 93; flag : umf_noinfo; reserved : 0),
-       (unicode : 94; flag : umf_noinfo; reserved : 0),
-       (unicode : 95; flag : umf_noinfo; reserved : 0),
-       (unicode : 96; flag : umf_noinfo; reserved : 0),
-       (unicode : 97; flag : umf_noinfo; reserved : 0),
-       (unicode : 98; flag : umf_noinfo; reserved : 0),
-       (unicode : 99; flag : umf_noinfo; reserved : 0),
-       (unicode : 100; flag : umf_noinfo; reserved : 0),
-       (unicode : 101; flag : umf_noinfo; reserved : 0),
-       (unicode : 102; flag : umf_noinfo; reserved : 0),
-       (unicode : 103; flag : umf_noinfo; reserved : 0),
-       (unicode : 104; flag : umf_noinfo; reserved : 0),
-       (unicode : 105; flag : umf_noinfo; reserved : 0),
-       (unicode : 106; flag : umf_noinfo; reserved : 0),
-       (unicode : 107; flag : umf_noinfo; reserved : 0),
-       (unicode : 108; flag : umf_noinfo; reserved : 0),
-       (unicode : 109; flag : umf_noinfo; reserved : 0),
-       (unicode : 110; flag : umf_noinfo; reserved : 0),
-       (unicode : 111; flag : umf_noinfo; reserved : 0),
-       (unicode : 112; flag : umf_noinfo; reserved : 0),
-       (unicode : 113; flag : umf_noinfo; reserved : 0),
-       (unicode : 114; flag : umf_noinfo; reserved : 0),
-       (unicode : 115; flag : umf_noinfo; reserved : 0),
-       (unicode : 116; flag : umf_noinfo; reserved : 0),
-       (unicode : 117; flag : umf_noinfo; reserved : 0),
-       (unicode : 118; flag : umf_noinfo; reserved : 0),
-       (unicode : 119; flag : umf_noinfo; reserved : 0),
-       (unicode : 120; flag : umf_noinfo; reserved : 0),
-       (unicode : 121; flag : umf_noinfo; reserved : 0),
-       (unicode : 122; flag : umf_noinfo; reserved : 0),
-       (unicode : 123; flag : umf_noinfo; reserved : 0),
-       (unicode : 124; flag : umf_noinfo; reserved : 0),
-       (unicode : 125; flag : umf_noinfo; reserved : 0),
-       (unicode : 126; flag : umf_noinfo; reserved : 0),
-       (unicode : 127; flag : umf_noinfo; reserved : 0),
-       (unicode : 199; flag : umf_noinfo; reserved : 0),
-       (unicode : 252; flag : umf_noinfo; reserved : 0),
-       (unicode : 233; flag : umf_noinfo; reserved : 0),
-       (unicode : 226; flag : umf_noinfo; reserved : 0),
-       (unicode : 228; flag : umf_noinfo; reserved : 0),
-       (unicode : 224; flag : umf_noinfo; reserved : 0),
-       (unicode : 229; flag : umf_noinfo; reserved : 0),
-       (unicode : 231; flag : umf_noinfo; reserved : 0),
-       (unicode : 234; flag : umf_noinfo; reserved : 0),
-       (unicode : 235; flag : umf_noinfo; reserved : 0),
-       (unicode : 232; flag : umf_noinfo; reserved : 0),
-       (unicode : 239; flag : umf_noinfo; reserved : 0),
-       (unicode : 238; flag : umf_noinfo; reserved : 0),
-       (unicode : 236; flag : umf_noinfo; reserved : 0),
-       (unicode : 196; flag : umf_noinfo; reserved : 0),
-       (unicode : 197; flag : umf_noinfo; reserved : 0),
-       (unicode : 201; flag : umf_noinfo; reserved : 0),
-       (unicode : 230; flag : umf_noinfo; reserved : 0),
-       (unicode : 198; flag : umf_noinfo; reserved : 0),
-       (unicode : 244; flag : umf_noinfo; reserved : 0),
-       (unicode : 246; flag : umf_noinfo; reserved : 0),
-       (unicode : 242; flag : umf_noinfo; reserved : 0),
-       (unicode : 251; flag : umf_noinfo; reserved : 0),
-       (unicode : 249; flag : umf_noinfo; reserved : 0),
-       (unicode : 255; flag : umf_noinfo; reserved : 0),
-       (unicode : 214; flag : umf_noinfo; reserved : 0),
-       (unicode : 220; flag : umf_noinfo; reserved : 0),
-       (unicode : 248; flag : umf_noinfo; reserved : 0),
-       (unicode : 163; flag : umf_noinfo; reserved : 0),
-       (unicode : 216; flag : umf_noinfo; reserved : 0),
-       (unicode : 215; flag : umf_noinfo; reserved : 0),
-       (unicode : 402; flag : umf_noinfo; reserved : 0),
-       (unicode : 225; flag : umf_noinfo; reserved : 0),
-       (unicode : 237; flag : umf_noinfo; reserved : 0),
-       (unicode : 243; flag : umf_noinfo; reserved : 0),
-       (unicode : 250; flag : umf_noinfo; reserved : 0),
-       (unicode : 241; flag : umf_noinfo; reserved : 0),
-       (unicode : 209; flag : umf_noinfo; reserved : 0),
-       (unicode : 170; flag : umf_noinfo; reserved : 0),
-       (unicode : 186; flag : umf_noinfo; reserved : 0),
-       (unicode : 191; flag : umf_noinfo; reserved : 0),
-       (unicode : 174; flag : umf_noinfo; reserved : 0),
-       (unicode : 172; flag : umf_noinfo; reserved : 0),
-       (unicode : 189; flag : umf_noinfo; reserved : 0),
-       (unicode : 188; flag : umf_noinfo; reserved : 0),
-       (unicode : 161; flag : umf_noinfo; reserved : 0),
-       (unicode : 171; flag : umf_noinfo; reserved : 0),
-       (unicode : 187; flag : umf_noinfo; reserved : 0),
-       (unicode : 9617; flag : umf_noinfo; reserved : 0),
-       (unicode : 9618; flag : umf_noinfo; reserved : 0),
-       (unicode : 9619; flag : umf_noinfo; reserved : 0),
-       (unicode : 9474; flag : umf_noinfo; reserved : 0),
-       (unicode : 9508; flag : umf_noinfo; reserved : 0),
-       (unicode : 193; flag : umf_noinfo; reserved : 0),
-       (unicode : 194; flag : umf_noinfo; reserved : 0),
-       (unicode : 192; flag : umf_noinfo; reserved : 0),
-       (unicode : 169; flag : umf_noinfo; reserved : 0),
-       (unicode : 9571; flag : umf_noinfo; reserved : 0),
-       (unicode : 9553; flag : umf_noinfo; reserved : 0),
-       (unicode : 9559; flag : umf_noinfo; reserved : 0),
-       (unicode : 9565; flag : umf_noinfo; reserved : 0),
-       (unicode : 162; flag : umf_noinfo; reserved : 0),
-       (unicode : 165; flag : umf_noinfo; reserved : 0),
-       (unicode : 9488; flag : umf_noinfo; reserved : 0),
-       (unicode : 9492; flag : umf_noinfo; reserved : 0),
-       (unicode : 9524; flag : umf_noinfo; reserved : 0),
-       (unicode : 9516; flag : umf_noinfo; reserved : 0),
-       (unicode : 9500; flag : umf_noinfo; reserved : 0),
-       (unicode : 9472; flag : umf_noinfo; reserved : 0),
-       (unicode : 9532; flag : umf_noinfo; reserved : 0),
-       (unicode : 227; flag : umf_noinfo; reserved : 0),
-       (unicode : 195; flag : umf_noinfo; reserved : 0),
-       (unicode : 9562; flag : umf_noinfo; reserved : 0),
-       (unicode : 9556; flag : umf_noinfo; reserved : 0),
-       (unicode : 9577; flag : umf_noinfo; reserved : 0),
-       (unicode : 9574; flag : umf_noinfo; reserved : 0),
-       (unicode : 9568; flag : umf_noinfo; reserved : 0),
-       (unicode : 9552; flag : umf_noinfo; reserved : 0),
-       (unicode : 9580; flag : umf_noinfo; reserved : 0),
-       (unicode : 164; flag : umf_noinfo; reserved : 0),
-       (unicode : 240; flag : umf_noinfo; reserved : 0),
-       (unicode : 208; flag : umf_noinfo; reserved : 0),
-       (unicode : 202; flag : umf_noinfo; reserved : 0),
-       (unicode : 203; flag : umf_noinfo; reserved : 0),
-       (unicode : 200; flag : umf_noinfo; reserved : 0),
-       (unicode : 305; flag : umf_noinfo; reserved : 0),
-       (unicode : 205; flag : umf_noinfo; reserved : 0),
-       (unicode : 206; flag : umf_noinfo; reserved : 0),
-       (unicode : 207; flag : umf_noinfo; reserved : 0),
-       (unicode : 9496; flag : umf_noinfo; reserved : 0),
-       (unicode : 9484; flag : umf_noinfo; reserved : 0),
-       (unicode : 9608; flag : umf_noinfo; reserved : 0),
-       (unicode : 9604; flag : umf_noinfo; reserved : 0),
-       (unicode : 166; flag : umf_noinfo; reserved : 0),
-       (unicode : 204; flag : umf_noinfo; reserved : 0),
-       (unicode : 9600; flag : umf_noinfo; reserved : 0),
-       (unicode : 211; flag : umf_noinfo; reserved : 0),
-       (unicode : 223; flag : umf_noinfo; reserved : 0),
-       (unicode : 212; flag : umf_noinfo; reserved : 0),
-       (unicode : 210; flag : umf_noinfo; reserved : 0),
-       (unicode : 245; flag : umf_noinfo; reserved : 0),
-       (unicode : 213; flag : umf_noinfo; reserved : 0),
-       (unicode : 181; flag : umf_noinfo; reserved : 0),
-       (unicode : 254; flag : umf_noinfo; reserved : 0),
-       (unicode : 222; flag : umf_noinfo; reserved : 0),
-       (unicode : 218; flag : umf_noinfo; reserved : 0),
-       (unicode : 219; flag : umf_noinfo; reserved : 0),
-       (unicode : 217; flag : umf_noinfo; reserved : 0),
-       (unicode : 253; flag : umf_noinfo; reserved : 0),
-       (unicode : 221; flag : umf_noinfo; reserved : 0),
-       (unicode : 175; flag : umf_noinfo; reserved : 0),
-       (unicode : 180; flag : umf_noinfo; reserved : 0),
-       (unicode : 173; flag : umf_noinfo; reserved : 0),
-       (unicode : 177; flag : umf_noinfo; reserved : 0),
-       (unicode : 8215; flag : umf_noinfo; reserved : 0),
-       (unicode : 190; flag : umf_noinfo; reserved : 0),
-       (unicode : 182; flag : umf_noinfo; reserved : 0),
-       (unicode : 167; flag : umf_noinfo; reserved : 0),
-       (unicode : 247; flag : umf_noinfo; reserved : 0),
-       (unicode : 184; flag : umf_noinfo; reserved : 0),
-       (unicode : 176; flag : umf_noinfo; reserved : 0),
-       (unicode : 168; flag : umf_noinfo; reserved : 0),
-       (unicode : 183; flag : umf_noinfo; reserved : 0),
-       (unicode : 185; flag : umf_noinfo; reserved : 0),
-       (unicode : 179; flag : umf_noinfo; reserved : 0),
-       (unicode : 178; flag : umf_noinfo; reserved : 0),
-       (unicode : 9632; flag : umf_noinfo; reserved : 0),
-       (unicode : 160; flag : umf_noinfo; reserved : 0)
-     );
-
-     unicodemap : tunicodemap = (
-       cpname : 'cp850';
-       cp : 850;
-       map : @map[0];
-       lastchar : 255;
-       next : nil;
-       internalmap : true
-     );
-
-  begin
-     registermapping(@unicodemap)
-  end.

+ 0 - 282
compiler/cp866.pas

@@ -1,282 +0,0 @@
-{ This is an automatically created file, so don't edit it }
-unit cp866;
-
-  interface
-
-  implementation
-
-  uses
-     {$if FPC_FULLVERSION<20700}ccharset{$else}charset{$endif};
-
-  const
-     map : array[0..255] of tunicodecharmapping = (
-       (unicode : 0; flag : umf_noinfo; reserved : 0),
-       (unicode : 1; flag : umf_noinfo; reserved : 0),
-       (unicode : 2; flag : umf_noinfo; reserved : 0),
-       (unicode : 3; flag : umf_noinfo; reserved : 0),
-       (unicode : 4; flag : umf_noinfo; reserved : 0),
-       (unicode : 5; flag : umf_noinfo; reserved : 0),
-       (unicode : 6; flag : umf_noinfo; reserved : 0),
-       (unicode : 7; flag : umf_noinfo; reserved : 0),
-       (unicode : 8; flag : umf_noinfo; reserved : 0),
-       (unicode : 9; flag : umf_noinfo; reserved : 0),
-       (unicode : 10; flag : umf_noinfo; reserved : 0),
-       (unicode : 11; flag : umf_noinfo; reserved : 0),
-       (unicode : 12; flag : umf_noinfo; reserved : 0),
-       (unicode : 13; flag : umf_noinfo; reserved : 0),
-       (unicode : 14; flag : umf_noinfo; reserved : 0),
-       (unicode : 15; flag : umf_noinfo; reserved : 0),
-       (unicode : 16; flag : umf_noinfo; reserved : 0),
-       (unicode : 17; flag : umf_noinfo; reserved : 0),
-       (unicode : 18; flag : umf_noinfo; reserved : 0),
-       (unicode : 19; flag : umf_noinfo; reserved : 0),
-       (unicode : 20; flag : umf_noinfo; reserved : 0),
-       (unicode : 21; flag : umf_noinfo; reserved : 0),
-       (unicode : 22; flag : umf_noinfo; reserved : 0),
-       (unicode : 23; flag : umf_noinfo; reserved : 0),
-       (unicode : 24; flag : umf_noinfo; reserved : 0),
-       (unicode : 25; flag : umf_noinfo; reserved : 0),
-       (unicode : 26; flag : umf_noinfo; reserved : 0),
-       (unicode : 27; flag : umf_noinfo; reserved : 0),
-       (unicode : 28; flag : umf_noinfo; reserved : 0),
-       (unicode : 29; flag : umf_noinfo; reserved : 0),
-       (unicode : 30; flag : umf_noinfo; reserved : 0),
-       (unicode : 31; flag : umf_noinfo; reserved : 0),
-       (unicode : 32; flag : umf_noinfo; reserved : 0),
-       (unicode : 33; flag : umf_noinfo; reserved : 0),
-       (unicode : 34; flag : umf_noinfo; reserved : 0),
-       (unicode : 35; flag : umf_noinfo; reserved : 0),
-       (unicode : 36; flag : umf_noinfo; reserved : 0),
-       (unicode : 37; flag : umf_noinfo; reserved : 0),
-       (unicode : 38; flag : umf_noinfo; reserved : 0),
-       (unicode : 39; flag : umf_noinfo; reserved : 0),
-       (unicode : 40; flag : umf_noinfo; reserved : 0),
-       (unicode : 41; flag : umf_noinfo; reserved : 0),
-       (unicode : 42; flag : umf_noinfo; reserved : 0),
-       (unicode : 43; flag : umf_noinfo; reserved : 0),
-       (unicode : 44; flag : umf_noinfo; reserved : 0),
-       (unicode : 45; flag : umf_noinfo; reserved : 0),
-       (unicode : 46; flag : umf_noinfo; reserved : 0),
-       (unicode : 47; flag : umf_noinfo; reserved : 0),
-       (unicode : 48; flag : umf_noinfo; reserved : 0),
-       (unicode : 49; flag : umf_noinfo; reserved : 0),
-       (unicode : 50; flag : umf_noinfo; reserved : 0),
-       (unicode : 51; flag : umf_noinfo; reserved : 0),
-       (unicode : 52; flag : umf_noinfo; reserved : 0),
-       (unicode : 53; flag : umf_noinfo; reserved : 0),
-       (unicode : 54; flag : umf_noinfo; reserved : 0),
-       (unicode : 55; flag : umf_noinfo; reserved : 0),
-       (unicode : 56; flag : umf_noinfo; reserved : 0),
-       (unicode : 57; flag : umf_noinfo; reserved : 0),
-       (unicode : 58; flag : umf_noinfo; reserved : 0),
-       (unicode : 59; flag : umf_noinfo; reserved : 0),
-       (unicode : 60; flag : umf_noinfo; reserved : 0),
-       (unicode : 61; flag : umf_noinfo; reserved : 0),
-       (unicode : 62; flag : umf_noinfo; reserved : 0),
-       (unicode : 63; flag : umf_noinfo; reserved : 0),
-       (unicode : 64; flag : umf_noinfo; reserved : 0),
-       (unicode : 65; flag : umf_noinfo; reserved : 0),
-       (unicode : 66; flag : umf_noinfo; reserved : 0),
-       (unicode : 67; flag : umf_noinfo; reserved : 0),
-       (unicode : 68; flag : umf_noinfo; reserved : 0),
-       (unicode : 69; flag : umf_noinfo; reserved : 0),
-       (unicode : 70; flag : umf_noinfo; reserved : 0),
-       (unicode : 71; flag : umf_noinfo; reserved : 0),
-       (unicode : 72; flag : umf_noinfo; reserved : 0),
-       (unicode : 73; flag : umf_noinfo; reserved : 0),
-       (unicode : 74; flag : umf_noinfo; reserved : 0),
-       (unicode : 75; flag : umf_noinfo; reserved : 0),
-       (unicode : 76; flag : umf_noinfo; reserved : 0),
-       (unicode : 77; flag : umf_noinfo; reserved : 0),
-       (unicode : 78; flag : umf_noinfo; reserved : 0),
-       (unicode : 79; flag : umf_noinfo; reserved : 0),
-       (unicode : 80; flag : umf_noinfo; reserved : 0),
-       (unicode : 81; flag : umf_noinfo; reserved : 0),
-       (unicode : 82; flag : umf_noinfo; reserved : 0),
-       (unicode : 83; flag : umf_noinfo; reserved : 0),
-       (unicode : 84; flag : umf_noinfo; reserved : 0),
-       (unicode : 85; flag : umf_noinfo; reserved : 0),
-       (unicode : 86; flag : umf_noinfo; reserved : 0),
-       (unicode : 87; flag : umf_noinfo; reserved : 0),
-       (unicode : 88; flag : umf_noinfo; reserved : 0),
-       (unicode : 89; flag : umf_noinfo; reserved : 0),
-       (unicode : 90; flag : umf_noinfo; reserved : 0),
-       (unicode : 91; flag : umf_noinfo; reserved : 0),
-       (unicode : 92; flag : umf_noinfo; reserved : 0),
-       (unicode : 93; flag : umf_noinfo; reserved : 0),
-       (unicode : 94; flag : umf_noinfo; reserved : 0),
-       (unicode : 95; flag : umf_noinfo; reserved : 0),
-       (unicode : 96; flag : umf_noinfo; reserved : 0),
-       (unicode : 97; flag : umf_noinfo; reserved : 0),
-       (unicode : 98; flag : umf_noinfo; reserved : 0),
-       (unicode : 99; flag : umf_noinfo; reserved : 0),
-       (unicode : 100; flag : umf_noinfo; reserved : 0),
-       (unicode : 101; flag : umf_noinfo; reserved : 0),
-       (unicode : 102; flag : umf_noinfo; reserved : 0),
-       (unicode : 103; flag : umf_noinfo; reserved : 0),
-       (unicode : 104; flag : umf_noinfo; reserved : 0),
-       (unicode : 105; flag : umf_noinfo; reserved : 0),
-       (unicode : 106; flag : umf_noinfo; reserved : 0),
-       (unicode : 107; flag : umf_noinfo; reserved : 0),
-       (unicode : 108; flag : umf_noinfo; reserved : 0),
-       (unicode : 109; flag : umf_noinfo; reserved : 0),
-       (unicode : 110; flag : umf_noinfo; reserved : 0),
-       (unicode : 111; flag : umf_noinfo; reserved : 0),
-       (unicode : 112; flag : umf_noinfo; reserved : 0),
-       (unicode : 113; flag : umf_noinfo; reserved : 0),
-       (unicode : 114; flag : umf_noinfo; reserved : 0),
-       (unicode : 115; flag : umf_noinfo; reserved : 0),
-       (unicode : 116; flag : umf_noinfo; reserved : 0),
-       (unicode : 117; flag : umf_noinfo; reserved : 0),
-       (unicode : 118; flag : umf_noinfo; reserved : 0),
-       (unicode : 119; flag : umf_noinfo; reserved : 0),
-       (unicode : 120; flag : umf_noinfo; reserved : 0),
-       (unicode : 121; flag : umf_noinfo; reserved : 0),
-       (unicode : 122; flag : umf_noinfo; reserved : 0),
-       (unicode : 123; flag : umf_noinfo; reserved : 0),
-       (unicode : 124; flag : umf_noinfo; reserved : 0),
-       (unicode : 125; flag : umf_noinfo; reserved : 0),
-       (unicode : 126; flag : umf_noinfo; reserved : 0),
-       (unicode : 127; flag : umf_noinfo; reserved : 0),
-       (unicode : 1040; flag : umf_noinfo; reserved : 0),
-       (unicode : 1041; flag : umf_noinfo; reserved : 0),
-       (unicode : 1042; flag : umf_noinfo; reserved : 0),
-       (unicode : 1043; flag : umf_noinfo; reserved : 0),
-       (unicode : 1044; flag : umf_noinfo; reserved : 0),
-       (unicode : 1045; flag : umf_noinfo; reserved : 0),
-       (unicode : 1046; flag : umf_noinfo; reserved : 0),
-       (unicode : 1047; flag : umf_noinfo; reserved : 0),
-       (unicode : 1048; flag : umf_noinfo; reserved : 0),
-       (unicode : 1049; flag : umf_noinfo; reserved : 0),
-       (unicode : 1050; flag : umf_noinfo; reserved : 0),
-       (unicode : 1051; flag : umf_noinfo; reserved : 0),
-       (unicode : 1052; flag : umf_noinfo; reserved : 0),
-       (unicode : 1053; flag : umf_noinfo; reserved : 0),
-       (unicode : 1054; flag : umf_noinfo; reserved : 0),
-       (unicode : 1055; flag : umf_noinfo; reserved : 0),
-       (unicode : 1056; flag : umf_noinfo; reserved : 0),
-       (unicode : 1057; flag : umf_noinfo; reserved : 0),
-       (unicode : 1058; flag : umf_noinfo; reserved : 0),
-       (unicode : 1059; flag : umf_noinfo; reserved : 0),
-       (unicode : 1060; flag : umf_noinfo; reserved : 0),
-       (unicode : 1061; flag : umf_noinfo; reserved : 0),
-       (unicode : 1062; flag : umf_noinfo; reserved : 0),
-       (unicode : 1063; flag : umf_noinfo; reserved : 0),
-       (unicode : 1064; flag : umf_noinfo; reserved : 0),
-       (unicode : 1065; flag : umf_noinfo; reserved : 0),
-       (unicode : 1066; flag : umf_noinfo; reserved : 0),
-       (unicode : 1067; flag : umf_noinfo; reserved : 0),
-       (unicode : 1068; flag : umf_noinfo; reserved : 0),
-       (unicode : 1069; flag : umf_noinfo; reserved : 0),
-       (unicode : 1070; flag : umf_noinfo; reserved : 0),
-       (unicode : 1071; flag : umf_noinfo; reserved : 0),
-       (unicode : 1072; flag : umf_noinfo; reserved : 0),
-       (unicode : 1073; flag : umf_noinfo; reserved : 0),
-       (unicode : 1074; flag : umf_noinfo; reserved : 0),
-       (unicode : 1075; flag : umf_noinfo; reserved : 0),
-       (unicode : 1076; flag : umf_noinfo; reserved : 0),
-       (unicode : 1077; flag : umf_noinfo; reserved : 0),
-       (unicode : 1078; flag : umf_noinfo; reserved : 0),
-       (unicode : 1079; flag : umf_noinfo; reserved : 0),
-       (unicode : 1080; flag : umf_noinfo; reserved : 0),
-       (unicode : 1081; flag : umf_noinfo; reserved : 0),
-       (unicode : 1082; flag : umf_noinfo; reserved : 0),
-       (unicode : 1083; flag : umf_noinfo; reserved : 0),
-       (unicode : 1084; flag : umf_noinfo; reserved : 0),
-       (unicode : 1085; flag : umf_noinfo; reserved : 0),
-       (unicode : 1086; flag : umf_noinfo; reserved : 0),
-       (unicode : 1087; flag : umf_noinfo; reserved : 0),
-       (unicode : 9617; flag : umf_noinfo; reserved : 0),
-       (unicode : 9618; flag : umf_noinfo; reserved : 0),
-       (unicode : 9619; flag : umf_noinfo; reserved : 0),
-       (unicode : 9474; flag : umf_noinfo; reserved : 0),
-       (unicode : 9508; flag : umf_noinfo; reserved : 0),
-       (unicode : 9569; flag : umf_noinfo; reserved : 0),
-       (unicode : 9570; flag : umf_noinfo; reserved : 0),
-       (unicode : 9558; flag : umf_noinfo; reserved : 0),
-       (unicode : 9557; flag : umf_noinfo; reserved : 0),
-       (unicode : 9571; flag : umf_noinfo; reserved : 0),
-       (unicode : 9553; flag : umf_noinfo; reserved : 0),
-       (unicode : 9559; flag : umf_noinfo; reserved : 0),
-       (unicode : 9565; flag : umf_noinfo; reserved : 0),
-       (unicode : 9564; flag : umf_noinfo; reserved : 0),
-       (unicode : 9563; flag : umf_noinfo; reserved : 0),
-       (unicode : 9488; flag : umf_noinfo; reserved : 0),
-       (unicode : 9492; flag : umf_noinfo; reserved : 0),
-       (unicode : 9524; flag : umf_noinfo; reserved : 0),
-       (unicode : 9516; flag : umf_noinfo; reserved : 0),
-       (unicode : 9500; flag : umf_noinfo; reserved : 0),
-       (unicode : 9472; flag : umf_noinfo; reserved : 0),
-       (unicode : 9532; flag : umf_noinfo; reserved : 0),
-       (unicode : 9566; flag : umf_noinfo; reserved : 0),
-       (unicode : 9567; flag : umf_noinfo; reserved : 0),
-       (unicode : 9562; flag : umf_noinfo; reserved : 0),
-       (unicode : 9556; flag : umf_noinfo; reserved : 0),
-       (unicode : 9577; flag : umf_noinfo; reserved : 0),
-       (unicode : 9574; flag : umf_noinfo; reserved : 0),
-       (unicode : 9568; flag : umf_noinfo; reserved : 0),
-       (unicode : 9552; flag : umf_noinfo; reserved : 0),
-       (unicode : 9580; flag : umf_noinfo; reserved : 0),
-       (unicode : 9575; flag : umf_noinfo; reserved : 0),
-       (unicode : 9576; flag : umf_noinfo; reserved : 0),
-       (unicode : 9572; flag : umf_noinfo; reserved : 0),
-       (unicode : 9573; flag : umf_noinfo; reserved : 0),
-       (unicode : 9561; flag : umf_noinfo; reserved : 0),
-       (unicode : 9560; flag : umf_noinfo; reserved : 0),
-       (unicode : 9554; flag : umf_noinfo; reserved : 0),
-       (unicode : 9555; flag : umf_noinfo; reserved : 0),
-       (unicode : 9579; flag : umf_noinfo; reserved : 0),
-       (unicode : 9578; flag : umf_noinfo; reserved : 0),
-       (unicode : 9496; flag : umf_noinfo; reserved : 0),
-       (unicode : 9484; flag : umf_noinfo; reserved : 0),
-       (unicode : 9608; flag : umf_noinfo; reserved : 0),
-       (unicode : 9604; flag : umf_noinfo; reserved : 0),
-       (unicode : 9612; flag : umf_noinfo; reserved : 0),
-       (unicode : 9616; flag : umf_noinfo; reserved : 0),
-       (unicode : 9600; flag : umf_noinfo; reserved : 0),
-       (unicode : 1088; flag : umf_noinfo; reserved : 0),
-       (unicode : 1089; flag : umf_noinfo; reserved : 0),
-       (unicode : 1090; flag : umf_noinfo; reserved : 0),
-       (unicode : 1091; flag : umf_noinfo; reserved : 0),
-       (unicode : 1092; flag : umf_noinfo; reserved : 0),
-       (unicode : 1093; flag : umf_noinfo; reserved : 0),
-       (unicode : 1094; flag : umf_noinfo; reserved : 0),
-       (unicode : 1095; flag : umf_noinfo; reserved : 0),
-       (unicode : 1096; flag : umf_noinfo; reserved : 0),
-       (unicode : 1097; flag : umf_noinfo; reserved : 0),
-       (unicode : 1098; flag : umf_noinfo; reserved : 0),
-       (unicode : 1099; flag : umf_noinfo; reserved : 0),
-       (unicode : 1100; flag : umf_noinfo; reserved : 0),
-       (unicode : 1101; flag : umf_noinfo; reserved : 0),
-       (unicode : 1102; flag : umf_noinfo; reserved : 0),
-       (unicode : 1103; flag : umf_noinfo; reserved : 0),
-       (unicode : 1025; flag : umf_noinfo; reserved : 0),
-       (unicode : 1105; flag : umf_noinfo; reserved : 0),
-       (unicode : 1028; flag : umf_noinfo; reserved : 0),
-       (unicode : 1108; flag : umf_noinfo; reserved : 0),
-       (unicode : 1031; flag : umf_noinfo; reserved : 0),
-       (unicode : 1111; flag : umf_noinfo; reserved : 0),
-       (unicode : 1038; flag : umf_noinfo; reserved : 0),
-       (unicode : 1118; flag : umf_noinfo; reserved : 0),
-       (unicode : 176; flag : umf_noinfo; reserved : 0),
-       (unicode : 8729; flag : umf_noinfo; reserved : 0),
-       (unicode : 183; flag : umf_noinfo; reserved : 0),
-       (unicode : 8730; flag : umf_noinfo; reserved : 0),
-       (unicode : 8470; flag : umf_noinfo; reserved : 0),
-       (unicode : 164; flag : umf_noinfo; reserved : 0),
-       (unicode : 9632; flag : umf_noinfo; reserved : 0),
-       (unicode : 160; flag : umf_noinfo; reserved : 0)
-     );
-
-     unicodemap : tunicodemap = (
-       cpname : 'cp866';
-       cp : 866;
-       map : @map;
-       lastchar : 255;
-       next : nil;
-       internalmap : true
-     );
-
-  begin
-     registermapping(@unicodemap)
-  end.

+ 0 - 282
compiler/cp8859_1.pas

@@ -1,282 +0,0 @@
-{ This is an automatically created file, so don't edit it }
-unit cp8859_1;
-
-  interface
-
-  implementation
-
-  uses
-    {$if FPC_FULLVERSION<20700}ccharset{$else}charset{$endif};
-
-  const
-     map : array[0..255] of tunicodecharmapping = (
-       (unicode : 0; flag : umf_noinfo; reserved : 0),
-       (unicode : 1; flag : umf_noinfo; reserved : 0),
-       (unicode : 2; flag : umf_noinfo; reserved : 0),
-       (unicode : 3; flag : umf_noinfo; reserved : 0),
-       (unicode : 4; flag : umf_noinfo; reserved : 0),
-       (unicode : 5; flag : umf_noinfo; reserved : 0),
-       (unicode : 6; flag : umf_noinfo; reserved : 0),
-       (unicode : 7; flag : umf_noinfo; reserved : 0),
-       (unicode : 8; flag : umf_noinfo; reserved : 0),
-       (unicode : 9; flag : umf_noinfo; reserved : 0),
-       (unicode : 10; flag : umf_noinfo; reserved : 0),
-       (unicode : 11; flag : umf_noinfo; reserved : 0),
-       (unicode : 12; flag : umf_noinfo; reserved : 0),
-       (unicode : 13; flag : umf_noinfo; reserved : 0),
-       (unicode : 14; flag : umf_noinfo; reserved : 0),
-       (unicode : 15; flag : umf_noinfo; reserved : 0),
-       (unicode : 16; flag : umf_noinfo; reserved : 0),
-       (unicode : 17; flag : umf_noinfo; reserved : 0),
-       (unicode : 18; flag : umf_noinfo; reserved : 0),
-       (unicode : 19; flag : umf_noinfo; reserved : 0),
-       (unicode : 20; flag : umf_noinfo; reserved : 0),
-       (unicode : 21; flag : umf_noinfo; reserved : 0),
-       (unicode : 22; flag : umf_noinfo; reserved : 0),
-       (unicode : 23; flag : umf_noinfo; reserved : 0),
-       (unicode : 24; flag : umf_noinfo; reserved : 0),
-       (unicode : 25; flag : umf_noinfo; reserved : 0),
-       (unicode : 26; flag : umf_noinfo; reserved : 0),
-       (unicode : 27; flag : umf_noinfo; reserved : 0),
-       (unicode : 28; flag : umf_noinfo; reserved : 0),
-       (unicode : 29; flag : umf_noinfo; reserved : 0),
-       (unicode : 30; flag : umf_noinfo; reserved : 0),
-       (unicode : 31; flag : umf_noinfo; reserved : 0),
-       (unicode : 32; flag : umf_noinfo; reserved : 0),
-       (unicode : 33; flag : umf_noinfo; reserved : 0),
-       (unicode : 34; flag : umf_noinfo; reserved : 0),
-       (unicode : 35; flag : umf_noinfo; reserved : 0),
-       (unicode : 36; flag : umf_noinfo; reserved : 0),
-       (unicode : 37; flag : umf_noinfo; reserved : 0),
-       (unicode : 38; flag : umf_noinfo; reserved : 0),
-       (unicode : 39; flag : umf_noinfo; reserved : 0),
-       (unicode : 40; flag : umf_noinfo; reserved : 0),
-       (unicode : 41; flag : umf_noinfo; reserved : 0),
-       (unicode : 42; flag : umf_noinfo; reserved : 0),
-       (unicode : 43; flag : umf_noinfo; reserved : 0),
-       (unicode : 44; flag : umf_noinfo; reserved : 0),
-       (unicode : 45; flag : umf_noinfo; reserved : 0),
-       (unicode : 46; flag : umf_noinfo; reserved : 0),
-       (unicode : 47; flag : umf_noinfo; reserved : 0),
-       (unicode : 48; flag : umf_noinfo; reserved : 0),
-       (unicode : 49; flag : umf_noinfo; reserved : 0),
-       (unicode : 50; flag : umf_noinfo; reserved : 0),
-       (unicode : 51; flag : umf_noinfo; reserved : 0),
-       (unicode : 52; flag : umf_noinfo; reserved : 0),
-       (unicode : 53; flag : umf_noinfo; reserved : 0),
-       (unicode : 54; flag : umf_noinfo; reserved : 0),
-       (unicode : 55; flag : umf_noinfo; reserved : 0),
-       (unicode : 56; flag : umf_noinfo; reserved : 0),
-       (unicode : 57; flag : umf_noinfo; reserved : 0),
-       (unicode : 58; flag : umf_noinfo; reserved : 0),
-       (unicode : 59; flag : umf_noinfo; reserved : 0),
-       (unicode : 60; flag : umf_noinfo; reserved : 0),
-       (unicode : 61; flag : umf_noinfo; reserved : 0),
-       (unicode : 62; flag : umf_noinfo; reserved : 0),
-       (unicode : 63; flag : umf_noinfo; reserved : 0),
-       (unicode : 64; flag : umf_noinfo; reserved : 0),
-       (unicode : 65; flag : umf_noinfo; reserved : 0),
-       (unicode : 66; flag : umf_noinfo; reserved : 0),
-       (unicode : 67; flag : umf_noinfo; reserved : 0),
-       (unicode : 68; flag : umf_noinfo; reserved : 0),
-       (unicode : 69; flag : umf_noinfo; reserved : 0),
-       (unicode : 70; flag : umf_noinfo; reserved : 0),
-       (unicode : 71; flag : umf_noinfo; reserved : 0),
-       (unicode : 72; flag : umf_noinfo; reserved : 0),
-       (unicode : 73; flag : umf_noinfo; reserved : 0),
-       (unicode : 74; flag : umf_noinfo; reserved : 0),
-       (unicode : 75; flag : umf_noinfo; reserved : 0),
-       (unicode : 76; flag : umf_noinfo; reserved : 0),
-       (unicode : 77; flag : umf_noinfo; reserved : 0),
-       (unicode : 78; flag : umf_noinfo; reserved : 0),
-       (unicode : 79; flag : umf_noinfo; reserved : 0),
-       (unicode : 80; flag : umf_noinfo; reserved : 0),
-       (unicode : 81; flag : umf_noinfo; reserved : 0),
-       (unicode : 82; flag : umf_noinfo; reserved : 0),
-       (unicode : 83; flag : umf_noinfo; reserved : 0),
-       (unicode : 84; flag : umf_noinfo; reserved : 0),
-       (unicode : 85; flag : umf_noinfo; reserved : 0),
-       (unicode : 86; flag : umf_noinfo; reserved : 0),
-       (unicode : 87; flag : umf_noinfo; reserved : 0),
-       (unicode : 88; flag : umf_noinfo; reserved : 0),
-       (unicode : 89; flag : umf_noinfo; reserved : 0),
-       (unicode : 90; flag : umf_noinfo; reserved : 0),
-       (unicode : 91; flag : umf_noinfo; reserved : 0),
-       (unicode : 92; flag : umf_noinfo; reserved : 0),
-       (unicode : 93; flag : umf_noinfo; reserved : 0),
-       (unicode : 94; flag : umf_noinfo; reserved : 0),
-       (unicode : 95; flag : umf_noinfo; reserved : 0),
-       (unicode : 96; flag : umf_noinfo; reserved : 0),
-       (unicode : 97; flag : umf_noinfo; reserved : 0),
-       (unicode : 98; flag : umf_noinfo; reserved : 0),
-       (unicode : 99; flag : umf_noinfo; reserved : 0),
-       (unicode : 100; flag : umf_noinfo; reserved : 0),
-       (unicode : 101; flag : umf_noinfo; reserved : 0),
-       (unicode : 102; flag : umf_noinfo; reserved : 0),
-       (unicode : 103; flag : umf_noinfo; reserved : 0),
-       (unicode : 104; flag : umf_noinfo; reserved : 0),
-       (unicode : 105; flag : umf_noinfo; reserved : 0),
-       (unicode : 106; flag : umf_noinfo; reserved : 0),
-       (unicode : 107; flag : umf_noinfo; reserved : 0),
-       (unicode : 108; flag : umf_noinfo; reserved : 0),
-       (unicode : 109; flag : umf_noinfo; reserved : 0),
-       (unicode : 110; flag : umf_noinfo; reserved : 0),
-       (unicode : 111; flag : umf_noinfo; reserved : 0),
-       (unicode : 112; flag : umf_noinfo; reserved : 0),
-       (unicode : 113; flag : umf_noinfo; reserved : 0),
-       (unicode : 114; flag : umf_noinfo; reserved : 0),
-       (unicode : 115; flag : umf_noinfo; reserved : 0),
-       (unicode : 116; flag : umf_noinfo; reserved : 0),
-       (unicode : 117; flag : umf_noinfo; reserved : 0),
-       (unicode : 118; flag : umf_noinfo; reserved : 0),
-       (unicode : 119; flag : umf_noinfo; reserved : 0),
-       (unicode : 120; flag : umf_noinfo; reserved : 0),
-       (unicode : 121; flag : umf_noinfo; reserved : 0),
-       (unicode : 122; flag : umf_noinfo; reserved : 0),
-       (unicode : 123; flag : umf_noinfo; reserved : 0),
-       (unicode : 124; flag : umf_noinfo; reserved : 0),
-       (unicode : 125; flag : umf_noinfo; reserved : 0),
-       (unicode : 126; flag : umf_noinfo; reserved : 0),
-       (unicode : 127; flag : umf_noinfo; reserved : 0),
-       (unicode : 128; flag : umf_noinfo; reserved : 0),
-       (unicode : 129; flag : umf_noinfo; reserved : 0),
-       (unicode : 130; flag : umf_noinfo; reserved : 0),
-       (unicode : 131; flag : umf_noinfo; reserved : 0),
-       (unicode : 132; flag : umf_noinfo; reserved : 0),
-       (unicode : 133; flag : umf_noinfo; reserved : 0),
-       (unicode : 134; flag : umf_noinfo; reserved : 0),
-       (unicode : 135; flag : umf_noinfo; reserved : 0),
-       (unicode : 136; flag : umf_noinfo; reserved : 0),
-       (unicode : 137; flag : umf_noinfo; reserved : 0),
-       (unicode : 138; flag : umf_noinfo; reserved : 0),
-       (unicode : 139; flag : umf_noinfo; reserved : 0),
-       (unicode : 140; flag : umf_noinfo; reserved : 0),
-       (unicode : 141; flag : umf_noinfo; reserved : 0),
-       (unicode : 142; flag : umf_noinfo; reserved : 0),
-       (unicode : 143; flag : umf_noinfo; reserved : 0),
-       (unicode : 144; flag : umf_noinfo; reserved : 0),
-       (unicode : 145; flag : umf_noinfo; reserved : 0),
-       (unicode : 146; flag : umf_noinfo; reserved : 0),
-       (unicode : 147; flag : umf_noinfo; reserved : 0),
-       (unicode : 148; flag : umf_noinfo; reserved : 0),
-       (unicode : 149; flag : umf_noinfo; reserved : 0),
-       (unicode : 150; flag : umf_noinfo; reserved : 0),
-       (unicode : 151; flag : umf_noinfo; reserved : 0),
-       (unicode : 152; flag : umf_noinfo; reserved : 0),
-       (unicode : 153; flag : umf_noinfo; reserved : 0),
-       (unicode : 154; flag : umf_noinfo; reserved : 0),
-       (unicode : 155; flag : umf_noinfo; reserved : 0),
-       (unicode : 156; flag : umf_noinfo; reserved : 0),
-       (unicode : 157; flag : umf_noinfo; reserved : 0),
-       (unicode : 158; flag : umf_noinfo; reserved : 0),
-       (unicode : 159; flag : umf_noinfo; reserved : 0),
-       (unicode : 160; flag : umf_noinfo; reserved : 0),
-       (unicode : 161; flag : umf_noinfo; reserved : 0),
-       (unicode : 162; flag : umf_noinfo; reserved : 0),
-       (unicode : 163; flag : umf_noinfo; reserved : 0),
-       (unicode : 164; flag : umf_noinfo; reserved : 0),
-       (unicode : 165; flag : umf_noinfo; reserved : 0),
-       (unicode : 166; flag : umf_noinfo; reserved : 0),
-       (unicode : 167; flag : umf_noinfo; reserved : 0),
-       (unicode : 168; flag : umf_noinfo; reserved : 0),
-       (unicode : 169; flag : umf_noinfo; reserved : 0),
-       (unicode : 170; flag : umf_noinfo; reserved : 0),
-       (unicode : 171; flag : umf_noinfo; reserved : 0),
-       (unicode : 172; flag : umf_noinfo; reserved : 0),
-       (unicode : 173; flag : umf_noinfo; reserved : 0),
-       (unicode : 174; flag : umf_noinfo; reserved : 0),
-       (unicode : 175; flag : umf_noinfo; reserved : 0),
-       (unicode : 176; flag : umf_noinfo; reserved : 0),
-       (unicode : 177; flag : umf_noinfo; reserved : 0),
-       (unicode : 178; flag : umf_noinfo; reserved : 0),
-       (unicode : 179; flag : umf_noinfo; reserved : 0),
-       (unicode : 180; flag : umf_noinfo; reserved : 0),
-       (unicode : 181; flag : umf_noinfo; reserved : 0),
-       (unicode : 182; flag : umf_noinfo; reserved : 0),
-       (unicode : 183; flag : umf_noinfo; reserved : 0),
-       (unicode : 184; flag : umf_noinfo; reserved : 0),
-       (unicode : 185; flag : umf_noinfo; reserved : 0),
-       (unicode : 186; flag : umf_noinfo; reserved : 0),
-       (unicode : 187; flag : umf_noinfo; reserved : 0),
-       (unicode : 188; flag : umf_noinfo; reserved : 0),
-       (unicode : 189; flag : umf_noinfo; reserved : 0),
-       (unicode : 190; flag : umf_noinfo; reserved : 0),
-       (unicode : 191; flag : umf_noinfo; reserved : 0),
-       (unicode : 192; flag : umf_noinfo; reserved : 0),
-       (unicode : 193; flag : umf_noinfo; reserved : 0),
-       (unicode : 194; flag : umf_noinfo; reserved : 0),
-       (unicode : 195; flag : umf_noinfo; reserved : 0),
-       (unicode : 196; flag : umf_noinfo; reserved : 0),
-       (unicode : 197; flag : umf_noinfo; reserved : 0),
-       (unicode : 198; flag : umf_noinfo; reserved : 0),
-       (unicode : 199; flag : umf_noinfo; reserved : 0),
-       (unicode : 200; flag : umf_noinfo; reserved : 0),
-       (unicode : 201; flag : umf_noinfo; reserved : 0),
-       (unicode : 202; flag : umf_noinfo; reserved : 0),
-       (unicode : 203; flag : umf_noinfo; reserved : 0),
-       (unicode : 204; flag : umf_noinfo; reserved : 0),
-       (unicode : 205; flag : umf_noinfo; reserved : 0),
-       (unicode : 206; flag : umf_noinfo; reserved : 0),
-       (unicode : 207; flag : umf_noinfo; reserved : 0),
-       (unicode : 208; flag : umf_noinfo; reserved : 0),
-       (unicode : 209; flag : umf_noinfo; reserved : 0),
-       (unicode : 210; flag : umf_noinfo; reserved : 0),
-       (unicode : 211; flag : umf_noinfo; reserved : 0),
-       (unicode : 212; flag : umf_noinfo; reserved : 0),
-       (unicode : 213; flag : umf_noinfo; reserved : 0),
-       (unicode : 214; flag : umf_noinfo; reserved : 0),
-       (unicode : 215; flag : umf_noinfo; reserved : 0),
-       (unicode : 216; flag : umf_noinfo; reserved : 0),
-       (unicode : 217; flag : umf_noinfo; reserved : 0),
-       (unicode : 218; flag : umf_noinfo; reserved : 0),
-       (unicode : 219; flag : umf_noinfo; reserved : 0),
-       (unicode : 220; flag : umf_noinfo; reserved : 0),
-       (unicode : 221; flag : umf_noinfo; reserved : 0),
-       (unicode : 222; flag : umf_noinfo; reserved : 0),
-       (unicode : 223; flag : umf_noinfo; reserved : 0),
-       (unicode : 224; flag : umf_noinfo; reserved : 0),
-       (unicode : 225; flag : umf_noinfo; reserved : 0),
-       (unicode : 226; flag : umf_noinfo; reserved : 0),
-       (unicode : 227; flag : umf_noinfo; reserved : 0),
-       (unicode : 228; flag : umf_noinfo; reserved : 0),
-       (unicode : 229; flag : umf_noinfo; reserved : 0),
-       (unicode : 230; flag : umf_noinfo; reserved : 0),
-       (unicode : 231; flag : umf_noinfo; reserved : 0),
-       (unicode : 232; flag : umf_noinfo; reserved : 0),
-       (unicode : 233; flag : umf_noinfo; reserved : 0),
-       (unicode : 234; flag : umf_noinfo; reserved : 0),
-       (unicode : 235; flag : umf_noinfo; reserved : 0),
-       (unicode : 236; flag : umf_noinfo; reserved : 0),
-       (unicode : 237; flag : umf_noinfo; reserved : 0),
-       (unicode : 238; flag : umf_noinfo; reserved : 0),
-       (unicode : 239; flag : umf_noinfo; reserved : 0),
-       (unicode : 240; flag : umf_noinfo; reserved : 0),
-       (unicode : 241; flag : umf_noinfo; reserved : 0),
-       (unicode : 242; flag : umf_noinfo; reserved : 0),
-       (unicode : 243; flag : umf_noinfo; reserved : 0),
-       (unicode : 244; flag : umf_noinfo; reserved : 0),
-       (unicode : 245; flag : umf_noinfo; reserved : 0),
-       (unicode : 246; flag : umf_noinfo; reserved : 0),
-       (unicode : 247; flag : umf_noinfo; reserved : 0),
-       (unicode : 248; flag : umf_noinfo; reserved : 0),
-       (unicode : 249; flag : umf_noinfo; reserved : 0),
-       (unicode : 250; flag : umf_noinfo; reserved : 0),
-       (unicode : 251; flag : umf_noinfo; reserved : 0),
-       (unicode : 252; flag : umf_noinfo; reserved : 0),
-       (unicode : 253; flag : umf_noinfo; reserved : 0),
-       (unicode : 254; flag : umf_noinfo; reserved : 0),
-       (unicode : 255; flag : umf_noinfo; reserved : 0)
-     );
-
-     unicodemap : tunicodemap = (
-       cpname : '8859-1';
-       cp : 28591;
-       map : @map[0];
-       lastchar : 255;
-       next : nil;
-       internalmap : true
-     );
-
-  begin
-     registermapping(@unicodemap)
-  end.

+ 0 - 282
compiler/cp8859_5.pas

@@ -1,282 +0,0 @@
-{ This is an automatically created file, so don't edit it }
-unit cp8859_5;
-
-  interface
-
-  implementation
-
-  uses
-     {$if FPC_FULLVERSION<20700}ccharset{$else}charset{$endif};
-
-  const
-     map : array[0..255] of tunicodecharmapping = (
-       (unicode : 0; flag : umf_noinfo; reserved : 0),
-       (unicode : 1; flag : umf_noinfo; reserved : 0),
-       (unicode : 2; flag : umf_noinfo; reserved : 0),
-       (unicode : 3; flag : umf_noinfo; reserved : 0),
-       (unicode : 4; flag : umf_noinfo; reserved : 0),
-       (unicode : 5; flag : umf_noinfo; reserved : 0),
-       (unicode : 6; flag : umf_noinfo; reserved : 0),
-       (unicode : 7; flag : umf_noinfo; reserved : 0),
-       (unicode : 8; flag : umf_noinfo; reserved : 0),
-       (unicode : 9; flag : umf_noinfo; reserved : 0),
-       (unicode : 10; flag : umf_noinfo; reserved : 0),
-       (unicode : 11; flag : umf_noinfo; reserved : 0),
-       (unicode : 12; flag : umf_noinfo; reserved : 0),
-       (unicode : 13; flag : umf_noinfo; reserved : 0),
-       (unicode : 14; flag : umf_noinfo; reserved : 0),
-       (unicode : 15; flag : umf_noinfo; reserved : 0),
-       (unicode : 16; flag : umf_noinfo; reserved : 0),
-       (unicode : 17; flag : umf_noinfo; reserved : 0),
-       (unicode : 18; flag : umf_noinfo; reserved : 0),
-       (unicode : 19; flag : umf_noinfo; reserved : 0),
-       (unicode : 20; flag : umf_noinfo; reserved : 0),
-       (unicode : 21; flag : umf_noinfo; reserved : 0),
-       (unicode : 22; flag : umf_noinfo; reserved : 0),
-       (unicode : 23; flag : umf_noinfo; reserved : 0),
-       (unicode : 24; flag : umf_noinfo; reserved : 0),
-       (unicode : 25; flag : umf_noinfo; reserved : 0),
-       (unicode : 26; flag : umf_noinfo; reserved : 0),
-       (unicode : 27; flag : umf_noinfo; reserved : 0),
-       (unicode : 28; flag : umf_noinfo; reserved : 0),
-       (unicode : 29; flag : umf_noinfo; reserved : 0),
-       (unicode : 30; flag : umf_noinfo; reserved : 0),
-       (unicode : 31; flag : umf_noinfo; reserved : 0),
-       (unicode : 32; flag : umf_noinfo; reserved : 0),
-       (unicode : 33; flag : umf_noinfo; reserved : 0),
-       (unicode : 34; flag : umf_noinfo; reserved : 0),
-       (unicode : 35; flag : umf_noinfo; reserved : 0),
-       (unicode : 36; flag : umf_noinfo; reserved : 0),
-       (unicode : 37; flag : umf_noinfo; reserved : 0),
-       (unicode : 38; flag : umf_noinfo; reserved : 0),
-       (unicode : 39; flag : umf_noinfo; reserved : 0),
-       (unicode : 40; flag : umf_noinfo; reserved : 0),
-       (unicode : 41; flag : umf_noinfo; reserved : 0),
-       (unicode : 42; flag : umf_noinfo; reserved : 0),
-       (unicode : 43; flag : umf_noinfo; reserved : 0),
-       (unicode : 44; flag : umf_noinfo; reserved : 0),
-       (unicode : 45; flag : umf_noinfo; reserved : 0),
-       (unicode : 46; flag : umf_noinfo; reserved : 0),
-       (unicode : 47; flag : umf_noinfo; reserved : 0),
-       (unicode : 48; flag : umf_noinfo; reserved : 0),
-       (unicode : 49; flag : umf_noinfo; reserved : 0),
-       (unicode : 50; flag : umf_noinfo; reserved : 0),
-       (unicode : 51; flag : umf_noinfo; reserved : 0),
-       (unicode : 52; flag : umf_noinfo; reserved : 0),
-       (unicode : 53; flag : umf_noinfo; reserved : 0),
-       (unicode : 54; flag : umf_noinfo; reserved : 0),
-       (unicode : 55; flag : umf_noinfo; reserved : 0),
-       (unicode : 56; flag : umf_noinfo; reserved : 0),
-       (unicode : 57; flag : umf_noinfo; reserved : 0),
-       (unicode : 58; flag : umf_noinfo; reserved : 0),
-       (unicode : 59; flag : umf_noinfo; reserved : 0),
-       (unicode : 60; flag : umf_noinfo; reserved : 0),
-       (unicode : 61; flag : umf_noinfo; reserved : 0),
-       (unicode : 62; flag : umf_noinfo; reserved : 0),
-       (unicode : 63; flag : umf_noinfo; reserved : 0),
-       (unicode : 64; flag : umf_noinfo; reserved : 0),
-       (unicode : 65; flag : umf_noinfo; reserved : 0),
-       (unicode : 66; flag : umf_noinfo; reserved : 0),
-       (unicode : 67; flag : umf_noinfo; reserved : 0),
-       (unicode : 68; flag : umf_noinfo; reserved : 0),
-       (unicode : 69; flag : umf_noinfo; reserved : 0),
-       (unicode : 70; flag : umf_noinfo; reserved : 0),
-       (unicode : 71; flag : umf_noinfo; reserved : 0),
-       (unicode : 72; flag : umf_noinfo; reserved : 0),
-       (unicode : 73; flag : umf_noinfo; reserved : 0),
-       (unicode : 74; flag : umf_noinfo; reserved : 0),
-       (unicode : 75; flag : umf_noinfo; reserved : 0),
-       (unicode : 76; flag : umf_noinfo; reserved : 0),
-       (unicode : 77; flag : umf_noinfo; reserved : 0),
-       (unicode : 78; flag : umf_noinfo; reserved : 0),
-       (unicode : 79; flag : umf_noinfo; reserved : 0),
-       (unicode : 80; flag : umf_noinfo; reserved : 0),
-       (unicode : 81; flag : umf_noinfo; reserved : 0),
-       (unicode : 82; flag : umf_noinfo; reserved : 0),
-       (unicode : 83; flag : umf_noinfo; reserved : 0),
-       (unicode : 84; flag : umf_noinfo; reserved : 0),
-       (unicode : 85; flag : umf_noinfo; reserved : 0),
-       (unicode : 86; flag : umf_noinfo; reserved : 0),
-       (unicode : 87; flag : umf_noinfo; reserved : 0),
-       (unicode : 88; flag : umf_noinfo; reserved : 0),
-       (unicode : 89; flag : umf_noinfo; reserved : 0),
-       (unicode : 90; flag : umf_noinfo; reserved : 0),
-       (unicode : 91; flag : umf_noinfo; reserved : 0),
-       (unicode : 92; flag : umf_noinfo; reserved : 0),
-       (unicode : 93; flag : umf_noinfo; reserved : 0),
-       (unicode : 94; flag : umf_noinfo; reserved : 0),
-       (unicode : 95; flag : umf_noinfo; reserved : 0),
-       (unicode : 96; flag : umf_noinfo; reserved : 0),
-       (unicode : 97; flag : umf_noinfo; reserved : 0),
-       (unicode : 98; flag : umf_noinfo; reserved : 0),
-       (unicode : 99; flag : umf_noinfo; reserved : 0),
-       (unicode : 100; flag : umf_noinfo; reserved : 0),
-       (unicode : 101; flag : umf_noinfo; reserved : 0),
-       (unicode : 102; flag : umf_noinfo; reserved : 0),
-       (unicode : 103; flag : umf_noinfo; reserved : 0),
-       (unicode : 104; flag : umf_noinfo; reserved : 0),
-       (unicode : 105; flag : umf_noinfo; reserved : 0),
-       (unicode : 106; flag : umf_noinfo; reserved : 0),
-       (unicode : 107; flag : umf_noinfo; reserved : 0),
-       (unicode : 108; flag : umf_noinfo; reserved : 0),
-       (unicode : 109; flag : umf_noinfo; reserved : 0),
-       (unicode : 110; flag : umf_noinfo; reserved : 0),
-       (unicode : 111; flag : umf_noinfo; reserved : 0),
-       (unicode : 112; flag : umf_noinfo; reserved : 0),
-       (unicode : 113; flag : umf_noinfo; reserved : 0),
-       (unicode : 114; flag : umf_noinfo; reserved : 0),
-       (unicode : 115; flag : umf_noinfo; reserved : 0),
-       (unicode : 116; flag : umf_noinfo; reserved : 0),
-       (unicode : 117; flag : umf_noinfo; reserved : 0),
-       (unicode : 118; flag : umf_noinfo; reserved : 0),
-       (unicode : 119; flag : umf_noinfo; reserved : 0),
-       (unicode : 120; flag : umf_noinfo; reserved : 0),
-       (unicode : 121; flag : umf_noinfo; reserved : 0),
-       (unicode : 122; flag : umf_noinfo; reserved : 0),
-       (unicode : 123; flag : umf_noinfo; reserved : 0),
-       (unicode : 124; flag : umf_noinfo; reserved : 0),
-       (unicode : 125; flag : umf_noinfo; reserved : 0),
-       (unicode : 126; flag : umf_noinfo; reserved : 0),
-       (unicode : 127; flag : umf_noinfo; reserved : 0),
-       (unicode : 128; flag : umf_noinfo; reserved : 0),
-       (unicode : 129; flag : umf_noinfo; reserved : 0),
-       (unicode : 130; flag : umf_noinfo; reserved : 0),
-       (unicode : 131; flag : umf_noinfo; reserved : 0),
-       (unicode : 132; flag : umf_noinfo; reserved : 0),
-       (unicode : 133; flag : umf_noinfo; reserved : 0),
-       (unicode : 134; flag : umf_noinfo; reserved : 0),
-       (unicode : 135; flag : umf_noinfo; reserved : 0),
-       (unicode : 136; flag : umf_noinfo; reserved : 0),
-       (unicode : 137; flag : umf_noinfo; reserved : 0),
-       (unicode : 138; flag : umf_noinfo; reserved : 0),
-       (unicode : 139; flag : umf_noinfo; reserved : 0),
-       (unicode : 140; flag : umf_noinfo; reserved : 0),
-       (unicode : 141; flag : umf_noinfo; reserved : 0),
-       (unicode : 142; flag : umf_noinfo; reserved : 0),
-       (unicode : 143; flag : umf_noinfo; reserved : 0),
-       (unicode : 144; flag : umf_noinfo; reserved : 0),
-       (unicode : 145; flag : umf_noinfo; reserved : 0),
-       (unicode : 146; flag : umf_noinfo; reserved : 0),
-       (unicode : 147; flag : umf_noinfo; reserved : 0),
-       (unicode : 148; flag : umf_noinfo; reserved : 0),
-       (unicode : 149; flag : umf_noinfo; reserved : 0),
-       (unicode : 150; flag : umf_noinfo; reserved : 0),
-       (unicode : 151; flag : umf_noinfo; reserved : 0),
-       (unicode : 152; flag : umf_noinfo; reserved : 0),
-       (unicode : 153; flag : umf_noinfo; reserved : 0),
-       (unicode : 154; flag : umf_noinfo; reserved : 0),
-       (unicode : 155; flag : umf_noinfo; reserved : 0),
-       (unicode : 156; flag : umf_noinfo; reserved : 0),
-       (unicode : 157; flag : umf_noinfo; reserved : 0),
-       (unicode : 158; flag : umf_noinfo; reserved : 0),
-       (unicode : 159; flag : umf_noinfo; reserved : 0),
-       (unicode : 160; flag : umf_noinfo; reserved : 0),
-       (unicode : 1025; flag : umf_noinfo; reserved : 0),
-       (unicode : 1026; flag : umf_noinfo; reserved : 0),
-       (unicode : 1027; flag : umf_noinfo; reserved : 0),
-       (unicode : 1028; flag : umf_noinfo; reserved : 0),
-       (unicode : 1029; flag : umf_noinfo; reserved : 0),
-       (unicode : 1030; flag : umf_noinfo; reserved : 0),
-       (unicode : 1031; flag : umf_noinfo; reserved : 0),
-       (unicode : 1032; flag : umf_noinfo; reserved : 0),
-       (unicode : 1033; flag : umf_noinfo; reserved : 0),
-       (unicode : 1034; flag : umf_noinfo; reserved : 0),
-       (unicode : 1035; flag : umf_noinfo; reserved : 0),
-       (unicode : 1036; flag : umf_noinfo; reserved : 0),
-       (unicode : 173; flag : umf_noinfo; reserved : 0),
-       (unicode : 1038; flag : umf_noinfo; reserved : 0),
-       (unicode : 1039; flag : umf_noinfo; reserved : 0),
-       (unicode : 1040; flag : umf_noinfo; reserved : 0),
-       (unicode : 1041; flag : umf_noinfo; reserved : 0),
-       (unicode : 1042; flag : umf_noinfo; reserved : 0),
-       (unicode : 1043; flag : umf_noinfo; reserved : 0),
-       (unicode : 1044; flag : umf_noinfo; reserved : 0),
-       (unicode : 1045; flag : umf_noinfo; reserved : 0),
-       (unicode : 1046; flag : umf_noinfo; reserved : 0),
-       (unicode : 1047; flag : umf_noinfo; reserved : 0),
-       (unicode : 1048; flag : umf_noinfo; reserved : 0),
-       (unicode : 1049; flag : umf_noinfo; reserved : 0),
-       (unicode : 1050; flag : umf_noinfo; reserved : 0),
-       (unicode : 1051; flag : umf_noinfo; reserved : 0),
-       (unicode : 1052; flag : umf_noinfo; reserved : 0),
-       (unicode : 1053; flag : umf_noinfo; reserved : 0),
-       (unicode : 1054; flag : umf_noinfo; reserved : 0),
-       (unicode : 1055; flag : umf_noinfo; reserved : 0),
-       (unicode : 1056; flag : umf_noinfo; reserved : 0),
-       (unicode : 1057; flag : umf_noinfo; reserved : 0),
-       (unicode : 1058; flag : umf_noinfo; reserved : 0),
-       (unicode : 1059; flag : umf_noinfo; reserved : 0),
-       (unicode : 1060; flag : umf_noinfo; reserved : 0),
-       (unicode : 1061; flag : umf_noinfo; reserved : 0),
-       (unicode : 1062; flag : umf_noinfo; reserved : 0),
-       (unicode : 1063; flag : umf_noinfo; reserved : 0),
-       (unicode : 1064; flag : umf_noinfo; reserved : 0),
-       (unicode : 1065; flag : umf_noinfo; reserved : 0),
-       (unicode : 1066; flag : umf_noinfo; reserved : 0),
-       (unicode : 1067; flag : umf_noinfo; reserved : 0),
-       (unicode : 1068; flag : umf_noinfo; reserved : 0),
-       (unicode : 1069; flag : umf_noinfo; reserved : 0),
-       (unicode : 1070; flag : umf_noinfo; reserved : 0),
-       (unicode : 1071; flag : umf_noinfo; reserved : 0),
-       (unicode : 1072; flag : umf_noinfo; reserved : 0),
-       (unicode : 1073; flag : umf_noinfo; reserved : 0),
-       (unicode : 1074; flag : umf_noinfo; reserved : 0),
-       (unicode : 1075; flag : umf_noinfo; reserved : 0),
-       (unicode : 1076; flag : umf_noinfo; reserved : 0),
-       (unicode : 1077; flag : umf_noinfo; reserved : 0),
-       (unicode : 1078; flag : umf_noinfo; reserved : 0),
-       (unicode : 1079; flag : umf_noinfo; reserved : 0),
-       (unicode : 1080; flag : umf_noinfo; reserved : 0),
-       (unicode : 1081; flag : umf_noinfo; reserved : 0),
-       (unicode : 1082; flag : umf_noinfo; reserved : 0),
-       (unicode : 1083; flag : umf_noinfo; reserved : 0),
-       (unicode : 1084; flag : umf_noinfo; reserved : 0),
-       (unicode : 1085; flag : umf_noinfo; reserved : 0),
-       (unicode : 1086; flag : umf_noinfo; reserved : 0),
-       (unicode : 1087; flag : umf_noinfo; reserved : 0),
-       (unicode : 1088; flag : umf_noinfo; reserved : 0),
-       (unicode : 1089; flag : umf_noinfo; reserved : 0),
-       (unicode : 1090; flag : umf_noinfo; reserved : 0),
-       (unicode : 1091; flag : umf_noinfo; reserved : 0),
-       (unicode : 1092; flag : umf_noinfo; reserved : 0),
-       (unicode : 1093; flag : umf_noinfo; reserved : 0),
-       (unicode : 1094; flag : umf_noinfo; reserved : 0),
-       (unicode : 1095; flag : umf_noinfo; reserved : 0),
-       (unicode : 1096; flag : umf_noinfo; reserved : 0),
-       (unicode : 1097; flag : umf_noinfo; reserved : 0),
-       (unicode : 1098; flag : umf_noinfo; reserved : 0),
-       (unicode : 1099; flag : umf_noinfo; reserved : 0),
-       (unicode : 1100; flag : umf_noinfo; reserved : 0),
-       (unicode : 1101; flag : umf_noinfo; reserved : 0),
-       (unicode : 1102; flag : umf_noinfo; reserved : 0),
-       (unicode : 1103; flag : umf_noinfo; reserved : 0),
-       (unicode : 8470; flag : umf_noinfo; reserved : 0),
-       (unicode : 1105; flag : umf_noinfo; reserved : 0),
-       (unicode : 1106; flag : umf_noinfo; reserved : 0),
-       (unicode : 1107; flag : umf_noinfo; reserved : 0),
-       (unicode : 1108; flag : umf_noinfo; reserved : 0),
-       (unicode : 1109; flag : umf_noinfo; reserved : 0),
-       (unicode : 1110; flag : umf_noinfo; reserved : 0),
-       (unicode : 1111; flag : umf_noinfo; reserved : 0),
-       (unicode : 1112; flag : umf_noinfo; reserved : 0),
-       (unicode : 1113; flag : umf_noinfo; reserved : 0),
-       (unicode : 1114; flag : umf_noinfo; reserved : 0),
-       (unicode : 1115; flag : umf_noinfo; reserved : 0),
-       (unicode : 1116; flag : umf_noinfo; reserved : 0),
-       (unicode : 167; flag : umf_noinfo; reserved : 0),
-       (unicode : 1118; flag : umf_noinfo; reserved : 0),
-       (unicode : 1119; flag : umf_noinfo; reserved : 0)
-     );
-
-     unicodemap : tunicodemap = (
-       cpname : '8859-5';
-       cp : 28595;
-       map : @map;
-       lastchar : 255;
-       next : nil;
-       internalmap : true
-     );
-
-  begin
-     registermapping(@unicodemap)
-  end.

+ 4 - 4
compiler/cresstr.pas

@@ -139,10 +139,10 @@ uses
         R : TResourceStringItem;
       begin
         { Put resourcestrings in a new objectfile. Putting it in multiple files
-	  makes the linking too dependent on the linker script requiring a SORT(*) for
-	  the data sections }
+          makes the linking too dependent on the linker script requiring a SORT(*) for
+          the data sections }
         maybe_new_object_file(current_asmdata.asmlists[al_const]);
-        new_section(current_asmdata.asmlists[al_const],sec_data,make_mangledname('RESSTRTABLE',current_module.localsymtable,''),sizeof(pint));
+        new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTRTABLE',current_module.localsymtable,''),sizeof(pint));
 
         maybe_new_object_file(current_asmdata.asmlists[al_resourcestrings]);
         new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'1_START'),sizeof(pint));
@@ -163,7 +163,7 @@ uses
         R:=TResourceStringItem(List.First);
         while assigned(R) do
           begin
-            new_section(current_asmdata.asmlists[al_const],sec_rodata,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint));
+            new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint));
             { Write default value }
             if assigned(R.value) and (R.len<>0) then
               valuelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,getansistringcodepage,False)

+ 38 - 0
compiler/cutils.pas

@@ -29,6 +29,9 @@ unit cutils;
 
 interface
 
+  uses
+    constexp;
+
   type
     Tcharset=set of char;
 
@@ -42,6 +45,17 @@ interface
     {# Returns the maximum value between @var(a) and @var(b) }
     function max(a,b : longint) : longint;{$ifdef USEINLINE}inline;{$endif}
     function max(a,b : int64) : int64;{$ifdef USEINLINE}inline;{$endif}
+
+    { These functions are intenionally put here and not in the constexp unit.
+      Since Tconstexprint may be automatically converted to int, which causes
+      loss of data and since there are already min and max functions for ints in
+      this unit, we put min and max for Tconstexprint as well. This way we avoid
+      potential bugs, caused by code unintentionally calling the int versions of
+      min/max on Tconstexprint, because of only including cutils and forgetting
+      the constexp unit in the uses clause. }
+    function min(const a,b : Tconstexprint) : Tconstexprint;{$ifdef USEINLINE}inline;{$endif}
+    function max(const a,b : Tconstexprint) : Tconstexprint;{$ifdef USEINLINE}inline;{$endif}
+
     {# Return value @var(i) aligned on @var(a) boundary }
     function align(i,a:longint):longint;{$ifdef USEINLINE}inline;{$endif}
     { if you have an address aligned using "oldalignment" and add an
@@ -190,6 +204,18 @@ implementation
       end;
 
 
+    function min(const a,b : Tconstexprint) : Tconstexprint;{$ifdef USEINLINE}inline;{$endif}
+    {
+      return the minimal of a and b
+    }
+      begin
+         if a<=b then
+           min:=a
+         else
+           min:=b;
+      end;
+
+
     function max(a,b : longint) : longint;{$ifdef USEINLINE}inline;{$endif}
     {
       return the maximum of a and b
@@ -214,6 +240,18 @@ implementation
       end;
 
 
+    function max(const a,b : Tconstexprint) : Tconstexprint;{$ifdef USEINLINE}inline;{$endif}
+    {
+      return the maximum of a and b
+    }
+      begin
+         if a>=b then
+           max:=a
+         else
+           max:=b;
+      end;
+
+
     function newalignment(oldalignment: longint; offset: int64): longint;
       var
         localoffset: longint;

Деякі файли не було показано, через те що забагато файлів було змінено