Kaynağa Gözat

* synchronised with trunk r29513

git-svn-id: branches/blocks@29514 -
Jonas Maebe 10 yıl önce
ebeveyn
işleme
a76bbf363d
100 değiştirilmiş dosya ile 2635 ekleme ve 1151 silme
  1. 2 0
      .gitattributes
  2. 65 6
      compiler/Makefile
  3. 2 2
      compiler/Makefile.fpc
  4. 1 0
      compiler/aarch64/a64att.inc
  5. 1 0
      compiler/aarch64/a64atts.inc
  6. 2 0
      compiler/aarch64/a64ins.dat
  7. 1 0
      compiler/aarch64/a64op.inc
  8. 15 0
      compiler/aarch64/cpuinfo.pas
  9. 1 1
      compiler/aarch64/cpupara.pas
  10. 4 2
      compiler/aasmbase.pas
  11. 15 16
      compiler/aasmdata.pas
  12. 21 4
      compiler/aasmtai.pas
  13. 14 3
      compiler/aggas.pas
  14. 4 0
      compiler/agjasmin.pas
  15. 23 0
      compiler/alpha/cpuinfo.pas
  16. 3 0
      compiler/aoptobj.pas
  17. 15 5
      compiler/arm/aasmcpu.pas
  18. 81 21
      compiler/arm/aoptcpu.pas
  19. 8 5
      compiler/arm/aoptcpub.pas
  20. 78 15
      compiler/arm/cgcpu.pas
  21. 43 1
      compiler/arm/cpuelf.pas
  22. 6 1
      compiler/arm/cpuinfo.pas
  23. 36 10
      compiler/arm/narmadd.pas
  24. 11 4
      compiler/arm/narmset.pas
  25. 1 0
      compiler/arm/raarmgas.pas
  26. 14 0
      compiler/arm/rgcpu.pas
  27. 2 1
      compiler/assemble.pas
  28. 5 5
      compiler/avr/aasmcpu.pas
  29. 4 6
      compiler/avr/agavrgas.pas
  30. 6 0
      compiler/avr/cpuinfo.pas
  31. 4 4
      compiler/avr/cpupara.pas
  32. 10 2
      compiler/avr/navradd.pas
  33. 2 2
      compiler/avr/navrmat.pas
  34. 1 1
      compiler/avr/raavrgas.pas
  35. 4 4
      compiler/cclasses.pas
  36. 7 4
      compiler/cfileutl.pas
  37. 10 2
      compiler/cgobj.pas
  38. 3 0
      compiler/compiler.pas
  39. 1 0
      compiler/compinnr.inc
  40. 1 1
      compiler/comprsrc.pas
  41. 77 43
      compiler/dbgdwarf.pas
  42. 6 10
      compiler/dbgstabs.pas
  43. 0 39
      compiler/defutil.pas
  44. 1 1
      compiler/expunix.pas
  45. 4 4
      compiler/fmodule.pas
  46. 7 1
      compiler/fppu.pas
  47. 24 0
      compiler/generic/cpuinfo.pas
  48. 49 35
      compiler/globals.pas
  49. 10 2
      compiler/globtype.pas
  50. 1 0
      compiler/hlcg2ll.pas
  51. 63 22
      compiler/htypechk.pas
  52. 7 0
      compiler/i386/cgcpu.pas
  53. 1 1
      compiler/i386/cpuelf.pas
  54. 20 0
      compiler/i386/cpuinfo.pas
  55. 18 0
      compiler/i386/cpupara.pas
  56. 3 0
      compiler/i386/cputarg.pas
  57. 84 64
      compiler/i386/n386add.pas
  58. 36 2
      compiler/i386/n386cal.pas
  59. 10 5
      compiler/i386/n386flw.pas
  60. 58 1
      compiler/i386/symcpu.pas
  61. 20 0
      compiler/i8086/cpuinfo.pas
  62. 4 1
      compiler/i8086/n8086add.pas
  63. 43 3
      compiler/i8086/n8086inl.pas
  64. 1 0
      compiler/i8086/n8086mat.pas
  65. 46 4
      compiler/i8086/n8086mem.pas
  66. 1 1
      compiler/i8086/n8086tcon.pas
  67. 92 1
      compiler/i8086/symcpu.pas
  68. 22 1
      compiler/ia64/cpuinfo.pas
  69. 1 1
      compiler/impdef.pas
  70. 20 0
      compiler/jvm/cpuinfo.pas
  71. 38 6
      compiler/jvm/dbgjasm.pas
  72. 6 0
      compiler/jvm/njvmflw.pas
  73. 4 2
      compiler/jvm/njvminl.pas
  74. 2 0
      compiler/jvm/njvmmem.pas
  75. 3 0
      compiler/jvm/njvmutil.pas
  76. 4 4
      compiler/jvm/tgcpu.pas
  77. 20 8
      compiler/m68k/aasmcpu.pas
  78. 173 59
      compiler/m68k/cgcpu.pas
  79. 6 3
      compiler/m68k/cpubase.pas
  80. 29 6
      compiler/m68k/cpuinfo.pas
  81. 1 1
      compiler/m68k/itcpugas.pas
  82. 268 494
      compiler/m68k/n68kadd.pas
  83. 7 1
      compiler/m68k/n68kcnv.pas
  84. 3 6
      compiler/m68k/n68kmat.pas
  85. 1 0
      compiler/m68k/ra68k.pas
  86. 4 0
      compiler/m68k/ra68kmot.pas
  87. 138 2
      compiler/m68k/rgcpu.pas
  88. 10 4
      compiler/m68k/symcpu.pas
  89. 15 6
      compiler/mips/aasmcpu.pas
  90. 271 45
      compiler/mips/aoptcpu.pas
  91. 90 41
      compiler/mips/cgcpu.pas
  92. 7 5
      compiler/mips/cpuelf.pas
  93. 1 1
      compiler/mips/cpugas.pas
  94. 41 12
      compiler/mips/cpuinfo.pas
  95. 96 24
      compiler/mips/ncpuadd.pas
  96. 2 3
      compiler/mips/ncpucnv.pas
  97. 35 7
      compiler/mips/rgcpu.pas
  98. 2 2
      compiler/msg/errorct.msg
  99. 100 37
      compiler/msg/errord.msg
  100. 2 2
      compiler/msg/errorda.msg

+ 2 - 0
.gitattributes

@@ -674,6 +674,7 @@ compiler/systems.pas svneol=native#text/plain
 compiler/systems/i_aix.pas svneol=native#text/plain
 compiler/systems/i_amiga.pas svneol=native#text/plain
 compiler/systems/i_android.pas svneol=native#text/plain
+compiler/systems/i_aros.pas svneol=native#text/plain
 compiler/systems/i_atari.pas svneol=native#text/plain
 compiler/systems/i_beos.pas svneol=native#text/plain
 compiler/systems/i_bsd.pas svneol=native#text/plain
@@ -703,6 +704,7 @@ compiler/systems/mac_crea.txt svneol=native#text/plain
 compiler/systems/t_aix.pas svneol=native#text/plain
 compiler/systems/t_amiga.pas svneol=native#text/plain
 compiler/systems/t_android.pas svneol=native#text/plain
+compiler/systems/t_aros.pas svneol=native#text/plain
 compiler/systems/t_atari.pas svneol=native#text/plain
 compiler/systems/t_beos.pas svneol=native#text/plain
 compiler/systems/t_bsd.pas svneol=native#text/plain

+ 65 - 6
compiler/Makefile

@@ -1,9 +1,9 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2014-04-01 rev 27428]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2014-12-07 rev 29213]
 #
 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 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 mipsel-embedded mipsel-android jvm-java jvm-android i8086-msdos
-BSDs = freebsd netbsd openbsd darwin
+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 i386-aros 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 x86_64-dragonfly 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 mipsel-embedded mipsel-android jvm-java jvm-android i8086-msdos
+BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos
 OSNeedsComspecToRunBatch = go32v2 watcom
@@ -326,7 +326,7 @@ FPCFPMAKE=$(FPC)
 endif
 endif
 override PACKAGE_NAME=compiler
-override PACKAGE_VERSION=2.7.1
+override PACKAGE_VERSION=3.1.1
 unexport FPC_VERSION FPC_COMPILERINFO
 CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086
 ALLTARGETS=$(CYCLETARGETS)
@@ -525,7 +525,7 @@ 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),)
+ifneq ($(findstring $(OS_TARGET),darwin linux dragonfly freebsd solaris),)
 ifdef LINKSMART
 ifdef CREATESMART
 OPTWPOCOLLECT+=-OWsymbolliveness -Xs-
@@ -614,6 +614,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 override TARGET_DIRS+=utils
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_DIRS+=utils
 endif
@@ -701,6 +704,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override TARGET_DIRS+=utils
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 override TARGET_DIRS+=utils
 endif
@@ -839,6 +845,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 override TARGET_PROGRAMS+=pp
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+override TARGET_PROGRAMS+=pp
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_PROGRAMS+=pp
 endif
@@ -926,6 +935,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override TARGET_PROGRAMS+=pp
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+override TARGET_PROGRAMS+=pp
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 override TARGET_PROGRAMS+=pp
 endif
@@ -1065,6 +1077,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
@@ -1152,6 +1167,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
@@ -1290,6 +1308,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
@@ -1377,6 +1398,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
@@ -1515,6 +1539,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 override COMPILER_TARGETDIR+=.
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_TARGETDIR+=.
 endif
@@ -1602,6 +1629,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override COMPILER_TARGETDIR+=.
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 override COMPILER_TARGETDIR+=.
 endif
@@ -1740,6 +1770,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
@@ -1827,6 +1860,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
@@ -2138,6 +2174,12 @@ EXEEXT=
 HASSHAREDLIB=1
 SHORTSUFFIX=lnx
 endif
+ifeq ($(OS_TARGET),dragonfly)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=df
+endif
 ifeq ($(OS_TARGET),freebsd)
 BATCHEXT=.sh
 EXEEXT=
@@ -2183,6 +2225,11 @@ EXEEXT=
 SHAREDLIBEXT=.library
 SHORTSUFFIX=amg
 endif
+ifeq ($(OS_TARGET),aros)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=aros
+endif
 ifeq ($(OS_TARGET),morphos)
 EXEEXT=
 SHAREDLIBEXT=.library
@@ -2604,6 +2651,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -2691,6 +2741,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -2911,7 +2964,7 @@ endif
 ifdef CREATESHARED
 override FPCOPT+=-Cg
 endif
-ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris),)
+ifneq ($(findstring $(OS_TARGET),dragonfly freebsd openbsd netbsd linux solaris),)
 ifeq ($(CPU_TARGET),x86_64)
 override FPCOPT+=-Cg
 endif
@@ -3461,6 +3514,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 TARGET_DIRS_UTILS=1
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+TARGET_DIRS_UTILS=1
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 TARGET_DIRS_UTILS=1
 endif
@@ -3548,6 +3604,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 TARGET_DIRS_UTILS=1
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+TARGET_DIRS_UTILS=1
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 TARGET_DIRS_UTILS=1
 endif

+ 2 - 2
compiler/Makefile.fpc

@@ -4,7 +4,7 @@
 
 [package]
 name=compiler
-version=2.7.1
+version=3.1.1
 
 [target]
 programs=pp
@@ -300,7 +300,7 @@ 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
 # is forced by the Makefile when necessary)
-ifneq ($(findstring $(OS_TARGET),darwin linux freebsd solaris),)
+ifneq ($(findstring $(OS_TARGET),darwin linux dragonfly freebsd solaris),)
 ifdef LINKSMART
 ifdef CREATESMART
 OPTWPOCOLLECT+=-OWsymbolliveness -Xs-

+ 1 - 0
compiler/aarch64/a64att.inc

@@ -1,5 +1,6 @@
 { don't edit, this file is generated from armins.dat }
 (
+'nop',
 'b',
 'cb',
 'tb',

+ 1 - 0
compiler/aarch64/a64atts.inc

@@ -129,5 +129,6 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
 attsufNONE
 );

+ 2 - 0
compiler/aarch64/a64ins.dat

@@ -1,3 +1,5 @@
+[NOP]
+
 [B]
 
 [CB]

+ 1 - 0
compiler/aarch64/a64op.inc

@@ -1,5 +1,6 @@
 { don't edit, this file is generated from armins.dat }
 (
+A_NOP,
 A_B,
 A_CB,
 A_TB,

+ 15 - 0
compiler/aarch64/cpuinfo.pas

@@ -21,6 +21,9 @@ Interface
 
 Type
    bestreal = double;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = type extended;
@@ -47,6 +50,9 @@ Type
 
 
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false; (* Not yet at least ;-) *)
    {# Size of native extended floating point type }
    extended_size = 8;
    {# Size of a multimedia register               }
@@ -54,6 +60,15 @@ Const
    { target cpu string (used by compiler options) }
    target_cpu_string = 'aarch64';
 
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+
    { calling conventions supported by the code generator }
    supported_calling_conventions : tproccalloptions = [
      pocall_internproc,

+ 1 - 1
compiler/aarch64/cpupara.pas

@@ -124,7 +124,7 @@ unit cpupara;
             orddef:
               getparaloc:=LOC_REGISTER;
             floatdef:
-              getparaloc:=LOC_MMREGISTER
+              getparaloc:=LOC_MMREGISTER;
             enumdef:
               getparaloc:=LOC_REGISTER;
             pointerdef:

+ 4 - 2
compiler/aasmbase.pas

@@ -62,6 +62,8 @@ interface
 
     const
        asmlabeltypeprefix : array[TAsmLabeltype] of char = ('j','a','d','l','f','t','c');
+       asmsymbindname : array[TAsmsymbind] of string = ('none', 'external','common',
+       'local','global','weak external','private external','lazy','import');
 
     type
        TAsmSectiontype=(sec_none,
@@ -197,7 +199,7 @@ interface
     function EncodeUleb128(a: qword;out buf) : byte;
     function EncodeSleb128(a: int64;out buf) : byte;
 
-    function ReplaceForbiddenAsmSymbolChars(const s: string): string;
+    function ReplaceForbiddenAsmSymbolChars(const s: ansistring): ansistring;
 
     { dummy default noop callback }
     procedure default_global_used;
@@ -348,7 +350,7 @@ implementation
       end;
 
 
-    function ReplaceForbiddenAsmSymbolChars(const s: string): string;
+    function ReplaceForbiddenAsmSymbolChars(const s: ansistring): ansistring;
       var
         i : longint;
         rchar: char;

+ 15 - 16
compiler/aasmdata.pas

@@ -122,8 +122,6 @@ interface
     type
       TAsmList = class(tlinkedlist)
          constructor create;
-         constructor create_without_marker;
-         function  empty : boolean;
          function  getlasttaifilepos : pfileposinfo;
       end;
 
@@ -284,20 +282,6 @@ implementation
     constructor TAsmList.create;
       begin
         inherited create;
-        { make sure the optimizer won't remove the first tai of this list}
-        insert(tai_marker.create(mark_BlockStart));
-      end;
-
-    constructor TAsmList.create_without_marker;
-      begin
-        inherited create;
-      end;
-
-    function TAsmList.empty : boolean;
-      begin
-        { there is always a mark_BlockStart available,
-          see TAsmList.create }
-        result:=(count<=1);
       end;
 
 
@@ -422,6 +406,21 @@ implementation
                  internalerror(200603261);
              end;
            hp.typ:=_typ;
+           { Changing bind from AB_GLOBAL to AB_LOCAL is wrong
+             if bind is already AB_GLOBAL or AB_EXTERNAL,
+             GOT might have been used, so change might be harmful. }
+           if (_bind<>hp.bind) and (hp.getrefs>0) then
+             begin
+{$ifdef extdebug}
+               { the changes that matter must become internalerrors, the rest
+                 should be ignored; a used cannot change anything about this,
+                 so printing a warning/hint is not useful }
+               if (_bind=AB_LOCAL) then
+                 Message3(asmw_w_changing_bind_type,s,asmsymbindname[hp.bind],asmsymbindname[_bind])
+               else
+                 Message3(asmw_h_changing_bind_type,s,asmsymbindname[hp.bind],asmsymbindname[_bind]);
+{$endif extdebug}
+             end;
            hp.bind:=_bind;
          end
         else

+ 21 - 4
compiler/aasmtai.pas

@@ -579,6 +579,8 @@ interface
           constructor Create_type_name(_typ:taiconst_type;const name:string;_symtyp:Tasmsymtype;ofs:aint);
           constructor Create_nil_codeptr;
           constructor Create_nil_dataptr;
+          constructor Create_int_codeptr(_value: int64);
+          constructor Create_int_dataptr(_value: int64);
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure derefimpl;override;
@@ -1747,6 +1749,18 @@ implementation
 
 
     constructor tai_const.Create_nil_codeptr;
+      begin
+        self.Create_int_codeptr(0);
+      end;
+
+
+    constructor tai_const.Create_nil_dataptr;
+      begin
+        self.Create_int_dataptr(0);
+      end;
+
+
+    constructor tai_const.Create_int_codeptr(_value: int64);
       begin
         inherited Create;
         typ:=ait_const;
@@ -1759,11 +1773,11 @@ implementation
         sym:=nil;
         endsym:=nil;
         symofs:=0;
-        value:=0;
+        value:=_value;
       end;
 
 
-    constructor tai_const.Create_nil_dataptr;
+    constructor tai_const.Create_int_dataptr(_value: int64);
       begin
         inherited Create;
         typ:=ait_const;
@@ -1776,7 +1790,7 @@ implementation
         sym:=nil;
         endsym:=nil;
         symofs:=0;
-        value:=0;
+        value:=_value;
       end;
 
 
@@ -2173,7 +2187,10 @@ implementation
          typ:=ait_stab;
          stabtype:=_stabtype;
          getmem(str,length(s)+1);
-         move(s[1],str^,length(s)+1);
+         if length(s)>0 then
+           move(s[1],str^,length(s)+1)
+         else
+           str^:=#0;
       end;
 
     destructor tai_stab.destroy;

+ 14 - 3
compiler/aggas.pas

@@ -843,7 +843,8 @@ implementation
                        asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
                        asmwrite(',');
                        asmwrite(tostr(tai_datablock(hp).size)+',');
-                       asmwrite('_data.bss_');
+                       asmwrite('_data.bss_,');
+                       asmwriteln(tostr(last_align));
                      end;
                  end
                else
@@ -1243,6 +1244,11 @@ implementation
                     end;
                   if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
                    begin
+{$ifdef arm}
+                     { do no change arm mode accidently, .globl seems to reset the mode }
+                     if GenerateThumbCode or GenerateThumb2Code then
+                       AsmWriteln(#9'.thumb_func'#9);
+{$endif arm}
                      AsmWrite('.globl'#9);
                      if replaceforbidden then
                        AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
@@ -1446,7 +1452,12 @@ implementation
              begin
                WriteDirectiveName(tai_directive(hp).directive);
                if tai_directive(hp).name <>'' then
-                 AsmWrite(tai_directive(hp).name);
+                 begin
+                   if replaceforbidden then
+                     AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_directive(hp).name))
+                   else
+                     AsmWrite(tai_directive(hp).name);
+                 end;
                AsmLn;
              end;
 
@@ -1712,7 +1723,7 @@ implementation
 
       { "no executable stack" marker }
       { TODO: used by OpenBSD/NetBSD as well? }
-      if (target_info.system in (systems_linux + systems_android + systems_freebsd)) and
+      if (target_info.system in (systems_linux + systems_android + systems_freebsd + systems_dragonfly)) and
          not(cs_executable_stack in current_settings.moduleswitches) then
         begin
           AsmWriteLn('.section .note.GNU-stack,"",%progbits');

+ 4 - 0
compiler/agjasmin.pas

@@ -526,6 +526,8 @@ implementation
         i: longint;
         toplevelowner: tsymtable;
       begin
+        superclass:=nil;
+
         { JVM 1.5+ }
         AsmWriteLn('.bytecode 49.0');
         // include files are not support by Java, and the directory of the main
@@ -763,6 +765,8 @@ implementation
               2:result:=tostr(smallint(csym.value.valueord.svalue));
               4:result:=tostr(longint(csym.value.valueord.svalue));
               8:result:=tostr(csym.value.valueord.svalue);
+              else
+                internalerror(2014082050);
             end;
           conststring:
             result:=constastr(pchar(csym.value.valueptr),csym.value.len);

+ 23 - 0
compiler/alpha/cpuinfo.pas

@@ -21,6 +21,9 @@ Unit CPUInfo;
 
 Interface
 
+uses
+ globtype;
+
 Type
    { Natural integer register type and size for the target machine }
 {$ifdef FPC}
@@ -38,6 +41,9 @@ Type
    TConstPtrUInt = qword;
 
    bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TExtended80Rec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = extended;
@@ -52,7 +58,15 @@ Type
        ClassEV8
       );
 
+   tcontrollertype =
+     (ct_none
+     );
+
+
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false;
    { Size of native extended type }
    extended_size = 16;
    {# Size of a pointer                           }
@@ -60,6 +74,15 @@ Const
    {# Size of a multimedia register               }
    mmreg_size = 8;
 
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+
    { target cpu string (used by compiler options) }
    target_cpu_string = 'alpha';
 

+ 3 - 0
compiler/aoptobj.pas

@@ -1041,6 +1041,9 @@ Unit AoptObj;
         Repeat
           While Assigned(StartPai) And
                 ((StartPai.typ in (SkipInstr - [ait_regAlloc])) Or
+{$if defined(MIPS) or defined(SPARC)}
+                ((startpai.typ=ait_instruction) and (taicpu(startpai).opcode=A_NOP)) or
+{$endif MIPS or SPARC}
                  ((StartPai.typ = ait_label) and
                   Not(Tai_Label(StartPai).labsym.Is_Used))) Do
             StartPai := Tai(StartPai.Next);

+ 15 - 5
compiler/arm/aasmcpu.pas

@@ -212,7 +212,7 @@ uses
          function is_same_reg_move(regtype: Tregistertype):boolean; override;
 
          function spilling_get_operation_type(opnr: longint): topertype;override;
-
+         function spilling_get_operation_type_ref(opnr: longint; reg: tregister): topertype;override;
          { assembler }
       public
          { the next will reset all instructions that can change in pass 2 }
@@ -777,6 +777,15 @@ implementation
       end;
 
 
+    function taicpu.spilling_get_operation_type_ref(opnr: longint; reg: tregister): topertype;
+      begin
+        result := operand_read;
+        if (oper[opnr]^.ref^.base = reg) and
+          (oper[opnr]^.ref^.addressmode in [AM_PREINDEXED,AM_POSTINDEXED]) then
+           result := operand_readwrite;
+      end;
+
+
     procedure BuildInsTabCache;
       var
         i : longint;
@@ -1055,15 +1064,16 @@ implementation
               (tai(hp).typ=ait_instruction) then
               begin
                 case taicpu(hp).opcode of
-                  A_BX,
+                  A_MOV,
                   A_LDR,
                   A_ADD:
                     { approximation if we hit a case jump table }
                     if ((taicpu(hp).opcode in [A_ADD,A_LDR]) and not(GenerateThumbCode or GenerateThumb2Code) and
                        (taicpu(hp).oper[0]^.typ=top_reg) and
                       (taicpu(hp).oper[0]^.reg=NR_PC)) or
-                      ((taicpu(hp).opcode=A_BX) and (GenerateThumbCode) and
-                       (taicpu(hp).oper[0]^.typ=top_reg))
+                      ((taicpu(hp).opcode=A_MOV) and (GenerateThumbCode) and
+                       (taicpu(hp).oper[0]^.typ=top_reg) and
+                       (taicpu(hp).oper[0]^.reg=NR_PC))
                        then
                       begin
                         penalty:=multiplier;
@@ -1858,7 +1868,7 @@ implementation
                   ot:=OT_SHIFTEROP;
                 end;
               else
-                internalerror(200402261);
+                internalerror(2004022623);
             end;
           end;
       end;

+ 81 - 21
compiler/arm/aoptcpu.pas

@@ -30,7 +30,7 @@ Unit aoptcpu;
 
 Interface
 
-uses cgbase, cpubase, aasmtai, aasmcpu,aopt, aoptobj;
+uses cgbase, cgutils, cpubase, aasmtai, aasmcpu,aopt, aoptobj;
 
 Type
   TCpuAsmOptimizer = class(TAsmOptimizer)
@@ -49,7 +49,8 @@ Type
       change in program flow.
       If there is none, it returns false and
       sets p1 to nil                                                     }
-    Function GetNextInstructionUsingReg(Current: tai; Var Next: tai;reg : TRegister): Boolean;
+    Function GetNextInstructionUsingReg(Current: tai; Out Next: tai; reg: TRegister): Boolean;
+    Function GetNextInstructionUsingRef(Current: tai; Out Next: tai; const ref: TReference; StopOnStore: Boolean = true): Boolean;
 
     { outputs a debug message into the assembler file }
     procedure DebugMsg(const s: string; p: tai);
@@ -79,7 +80,7 @@ Implementation
     cutils,verbose,globtype,globals,
     systems,
     cpuinfo,
-    cgobj,cgutils,procinfo,
+    cgobj,procinfo,
     aasmbase,aasmdata;
 
   function CanBeCond(p : tai) : boolean;
@@ -317,15 +318,46 @@ Implementation
          RegLoadedWithNewValue(reg,p);
     end;
 
-
   function TCpuAsmOptimizer.GetNextInstructionUsingReg(Current: tai;
-    var Next: tai; reg: TRegister): Boolean;
+    Out Next: tai; reg: TRegister): Boolean;
     begin
       Next:=Current;
       repeat
         Result:=GetNextInstruction(Next,Next);
-      until not(cs_opt_level3 in current_settings.optimizerswitches) or not(Result) or (Next.typ<>ait_instruction) or (RegInInstruction(reg,Next)) or
-        (is_calljmp(taicpu(Next).opcode)) or (RegInInstruction(NR_PC,Next));
+      until not (Result) or
+            not(cs_opt_level3 in current_settings.optimizerswitches) or
+            (Next.typ<>ait_instruction) or
+            RegInInstruction(reg,Next) or
+            is_calljmp(taicpu(Next).opcode) or
+            RegModifiedByInstruction(NR_PC,Next);
+    end;
+
+  function TCpuAsmOptimizer.GetNextInstructionUsingRef(Current: tai;
+    Out Next: tai; const ref: TReference; StopOnStore: Boolean = true): Boolean;
+    begin
+      Next:=Current;
+      repeat
+        Result:=GetNextInstruction(Next,Next);
+        if Result and
+           (Next.typ=ait_instruction) and
+           (taicpu(Next).opcode in [A_LDR, A_STR]) and
+           (
+            ((taicpu(Next).ops = 2) and
+             (taicpu(Next).oper[1]^.typ = top_ref) and
+             RefsEqual(taicpu(Next).oper[1]^.ref^,ref)) or
+            ((taicpu(Next).ops = 3) and { LDRD/STRD }
+             (taicpu(Next).oper[2]^.typ = top_ref) and
+             RefsEqual(taicpu(Next).oper[2]^.ref^,ref))
+           ) then
+            {We've found an instruction LDR or STR with the same reference}
+            exit;
+      until not(Result) or
+            (Next.typ<>ait_instruction) or
+            not(cs_opt_level3 in current_settings.optimizerswitches) or
+            is_calljmp(taicpu(Next).opcode) or
+            (StopOnStore and (taicpu(Next).opcode in [A_STR, A_STM])) or
+            RegModifiedByInstruction(NR_PC,Next);
+      Result:=false;
     end;
 
 {$ifdef DEBUG_AOPTCPU}
@@ -482,7 +514,8 @@ Implementation
       hp1 : tai;
     begin
       Result:=false;
-      if (p.oper[1]^.ref^.addressmode=AM_OFFSET) and
+      if (p.oper[1]^.typ = top_ref) and
+        (p.oper[1]^.ref^.addressmode=AM_OFFSET) and
         (p.oper[1]^.ref^.index=NR_NO) and
         (p.oper[1]^.ref^.offset=0) and
         GetNextInstructionUsingReg(p, hp1, p.oper[1]^.ref^.base) and
@@ -538,6 +571,7 @@ Implementation
       TmpUsedRegs: TAllUsedRegs;
       tempop: tasmop;
       oldreg: tregister;
+      dealloc: tai_regalloc;
 
     function IsPowerOf2(const value: DWord): boolean; inline;
       begin
@@ -607,12 +641,17 @@ Implementation
                       str reg1,ref
                       mov reg2,reg1
                     }
-                    if (taicpu(p).oper[1]^.ref^.addressmode=AM_OFFSET) and
+                    if (taicpu(p).oper[1]^.typ = top_ref) and
+                       (taicpu(p).oper[1]^.ref^.addressmode=AM_OFFSET) and
                        (taicpu(p).oppostfix=PF_None) and
-                       GetNextInstruction(p,hp1) and
-                       MatchInstruction(hp1, A_LDR, [taicpu(p).condition, C_None], [PF_None]) and
-                       RefsEqual(taicpu(p).oper[1]^.ref^,taicpu(hp1).oper[1]^.ref^) and
-                       (taicpu(hp1).oper[1]^.ref^.addressmode=AM_OFFSET) then
+                       (taicpu(p).condition=C_None) and
+                       GetNextInstructionUsingRef(p,hp1,taicpu(p).oper[1]^.ref^) and
+                       MatchInstruction(hp1, A_LDR, [taicpu(p).condition], [PF_None]) and
+                       (taicpu(hp1).oper[1]^.typ=top_ref) and
+                       (taicpu(hp1).oper[1]^.ref^.addressmode=AM_OFFSET) and
+                       not(RegModifiedBetween(taicpu(p).oper[0]^.reg, p, hp1)) and
+                       ((taicpu(hp1).oper[1]^.ref^.index=NR_NO) or not (RegModifiedBetween(taicpu(hp1).oper[1]^.ref^.index, p, hp1))) and
+                       ((taicpu(hp1).oper[1]^.ref^.base=NR_NO) or not (RegModifiedBetween(taicpu(hp1).oper[1]^.ref^.base, p, hp1))) then
                       begin
                         if taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg then
                           begin
@@ -633,7 +672,7 @@ Implementation
                       str reg1,ref
                       str reg2,ref
                       into
-                      strd reg1,ref
+                      strd reg1,reg2,ref
                     }
                     else if (GenerateARMCode or GenerateThumb2Code) and
                        (CPUARM_HAS_EDSP in cpu_capabilities[current_settings.cputype]) and
@@ -654,6 +693,9 @@ Implementation
                       begin
                         DebugMsg('Peephole StrStr2Strd done', p);
                         taicpu(p).oppostfix:=PF_D;
+                        taicpu(p).loadref(2,taicpu(p).oper[1]^.ref^);
+                        taicpu(p).loadreg(1, taicpu(hp1).oper[0]^.reg);
+                        taicpu(p).ops:=3;
                         asml.remove(hp1);
                         hp1.free;
                         result:=true;
@@ -667,7 +709,8 @@ Implementation
                       ldr reg2,ref
                       into ...
                     }
-                    if (taicpu(p).oper[1]^.ref^.addressmode=AM_OFFSET) and
+                    if (taicpu(p).oper[1]^.typ = top_ref) and
+                       (taicpu(p).oper[1]^.ref^.addressmode=AM_OFFSET) and
                        GetNextInstruction(p,hp1) and
                        { ldrd is not allowed here }
                        MatchInstruction(hp1, A_LDR, [taicpu(p).condition, C_None], [taicpu(p).oppostfix,PF_None]-[PF_D]) then
@@ -700,7 +743,7 @@ Implementation
                           end
                         {
                            ...
-                           ldrd reg1,ref
+                           ldrd reg1,reg1+1,ref
                         }
                         else if (GenerateARMCode or GenerateThumb2Code) and
                           (CPUARM_HAS_EDSP in cpu_capabilities[current_settings.cputype]) and
@@ -718,6 +761,9 @@ Implementation
                           AlignedToQWord(taicpu(p).oper[1]^.ref^) then
                           begin
                             DebugMsg('Peephole LdrLdr2Ldrd done', p);
+                            taicpu(p).loadref(2,taicpu(p).oper[1]^.ref^);
+                            taicpu(p).loadreg(1, taicpu(hp1).oper[0]^.reg);
+                            taicpu(p).ops:=3;
                             taicpu(p).oppostfix:=PF_D;
                             asml.remove(hp1);
                             hp1.free;
@@ -1200,6 +1246,7 @@ Implementation
                        (taicpu(p).oppostfix = PF_NONE) and
                        GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
                        MatchInstruction(hp1, [A_LDR, A_STR], [taicpu(p).condition], []) and
+                       (taicpu(hp1).oper[1]^.typ = top_ref) and
                        { We can change the base register only when the instruction uses AM_OFFSET }
                        ((taicpu(hp1).oper[1]^.ref^.index = taicpu(p).oper[0]^.reg) or
                          ((taicpu(hp1).oper[1]^.ref^.addressmode = AM_OFFSET) and
@@ -1222,6 +1269,13 @@ Implementation
                         if taicpu(hp1).oper[1]^.ref^.index = taicpu(p).oper[0]^.reg then
                           taicpu(hp1).oper[1]^.ref^.index := taicpu(p).oper[1]^.reg;
 
+                        dealloc:=FindRegDeAlloc(taicpu(p).oper[1]^.reg, taicpu(p.Next));
+                        if Assigned(dealloc) then
+                          begin
+                            asml.remove(dealloc);
+                            asml.InsertAfter(dealloc,hp1);
+                          end;
+
                         GetNextInstruction(p, hp1);
                         asml.remove(p);
                         p.free;
@@ -1583,13 +1637,14 @@ Implementation
                               and reg1,reg0,2^n-1
                               mov reg2,reg1, lsl imm1
                               =>
-                              mov reg2,reg1, lsl imm1
+                              mov reg2,reg0, lsl imm1
                               if imm1>i
                             }
-                            else if i>32-taicpu(hp1).oper[2]^.shifterop^.shiftimm then
+                            else if (i>32-taicpu(hp1).oper[2]^.shifterop^.shiftimm) and
+                                    not(RegModifiedBetween(taicpu(p).oper[1]^.reg, p, hp1)) then
                               begin
                                 DebugMsg('Peephole AndLsl2Lsl done', p);
-                                taicpu(hp1).oper[1]^.reg:=taicpu(p).oper[0]^.reg;
+                                taicpu(hp1).oper[1]^.reg:=taicpu(p).oper[1]^.reg;
                                 GetNextInstruction(p, hp1);
                                 asml.Remove(p);
                                 p.free;
@@ -1616,6 +1671,7 @@ Implementation
                         while GetNextInstructionUsingReg(hp1, hp1, taicpu(p).oper[0]^.reg) and
                           { we cannot check NR_DEFAULTFLAGS for modification yet so don't allow a condition }
                           MatchInstruction(hp1, [A_LDR, A_STR], [C_None], []) and
+                          (taicpu(hp1).oper[1]^.typ = top_ref) and
                           (taicpu(hp1).oper[1]^.ref^.base=taicpu(p).oper[0]^.reg) and
                           { don't optimize if the register is stored/overwritten }
                           (taicpu(hp1).oper[0]^.reg<>taicpu(p).oper[1]^.reg) and
@@ -2389,7 +2445,7 @@ Implementation
     begin
       result:=true;
 
-      list:=TAsmList.create_without_marker;
+      list:=TAsmList.create;
       p:=BlockStart;
       while p<>BlockEnd Do
         begin
@@ -2410,6 +2466,7 @@ Implementation
                ) or
                { try to prove that the memory accesses don't overlapp }
                ((taicpu(p).opcode in [A_STRB,A_STRH,A_STR]) and
+                (taicpu(p).oper[1]^.typ = top_ref) and
                 (taicpu(p).oper[1]^.ref^.base=taicpu(hp1).oper[1]^.ref^.base) and
                 (taicpu(p).oppostfix=PF_None) and
                 (taicpu(hp1).oppostfix=PF_None) and
@@ -2435,7 +2492,10 @@ Implementation
             { first instruction might not change the register used as index }
             ((taicpu(hp1).oper[1]^.ref^.index=NR_NO) or
              not(RegModifiedByInstruction(taicpu(hp1).oper[1]^.ref^.index,p))
-            ) then
+            ) and
+            { if we modify the basereg AND the first instruction used that reg, we can not schedule }
+            ((taicpu(hp1).oper[1]^.ref^.addressmode = AM_OFFSET) or
+             not(instructionLoadsFromReg(taicpu(hp1).oper[1]^.ref^.base,p))) then
             begin
               hp3:=tai(p.Previous);
               hp5:=tai(p.next);

+ 8 - 5
compiler/arm/aoptcpub.pas

@@ -124,11 +124,14 @@ Implementation
     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;
+        case taicpu(p1).oper[i]^.typ of
+          top_reg:
+            if (taicpu(p1).oper[i]^.reg=Reg) and (taicpu(p1).spilling_get_operation_type(i) in [operand_write,operand_readwrite]) then
+              exit(true);
+          top_ref:
+            if (taicpu(p1).spilling_get_operation_type_ref(i,Reg)<>operand_read) then
+              exit(true);
+        end;
     end;
 
 End.

+ 78 - 15
compiler/arm/cgcpu.pas

@@ -71,6 +71,8 @@ unit cgcpu;
 
         procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister); override;
 
+        procedure g_profilecode(list : TAsmList); override;
+
         procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
         procedure g_proc_exit(list : TAsmList;parasize : longint;nostackframe:boolean); override;
         procedure g_maybe_got_init(list : TAsmList); override;
@@ -182,6 +184,8 @@ unit cgcpu;
         procedure g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: tcgint); override;
 
         function handle_load_store(list: TAsmList; op: tasmop; oppostfix: toppostfix; reg: tregister; ref: treference): treference; override;
+
+        procedure g_external_wrapper(list : TAsmList; procdef : tprocdef; const externalname : string); override;
       end;
 
       tthumbcg64farm = class(tbasecg64farm)
@@ -1794,6 +1798,16 @@ unit cgcpu;
         list.concat(setcondition(taicpu.op_reg_const(A_MOV,reg,0),inverse_cond(flags_to_cond(f))));
       end;
 
+    procedure tbasecgarm.g_profilecode(list : TAsmList);
+      begin
+        if target_info.system = system_arm_linux then
+          begin
+            list.concat(taicpu.op_regset(A_PUSH,R_INTREGISTER,R_SUBWHOLE,[RS_R14]));
+            a_call_name(list,'__gnu_mcount_nc',false);
+          end
+        else
+          internalerror(2014091201);
+      end;
 
     procedure tbasecgarm.g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);
       var
@@ -3201,6 +3215,7 @@ unit cgcpu;
               if (href.offset in [0..124]) and ((href.offset mod 4)=0) then
                 begin
                   list.concat(taicpu.op_regset(A_PUSH,R_INTREGISTER,R_SUBWHOLE,[RS_R0]));
+                  list.concat(taicpu.op_reg_reg(A_MOV,NR_R0,NR_R12));
                   cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_R0);
                   list.concat(taicpu.op_reg_reg(A_MOV,NR_R12,NR_R0));
                   list.concat(taicpu.op_regset(A_POP,R_INTREGISTER,R_SUBWHOLE,[RS_R0]));
@@ -3218,20 +3233,21 @@ unit cgcpu;
                   tmpref.symbol:=l;
                   tmpref.base:=NR_PC;
                   list.concat(taicpu.op_reg_ref(A_LDR,NR_R1,tmpref));
+                  list.concat(taicpu.op_reg_reg(A_MOV,NR_R0,NR_R12));
                   href.offset:=0;
+                  href.base:=NR_R0;
                   href.index:=NR_R1;
                   cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_R0);
                   list.concat(taicpu.op_reg_reg(A_MOV,NR_R12,NR_R0));
                   list.concat(taicpu.op_regset(A_POP,R_INTREGISTER,R_SUBWHOLE,[RS_R0,RS_R1]));
                 end;
-              list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R12));
             end
           else
             begin
               reference_reset_base(href,NR_R12,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber),sizeof(pint));
               cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_R12);
-              list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R12));
             end;
+          list.concat(taicpu.op_reg(A_BX,NR_R12));
         end;
 
       var
@@ -3248,6 +3264,9 @@ unit cgcpu;
         if procdef.owner.symtabletype<>ObjectSymtable then
           Internalerror(200109191);
 
+          if GenerateThumbCode or GenerateThumb2Code then
+            list.concat(tai_thumb_func.create);
+
         make_global:=false;
         if (not current_module.is_unit) or
            create_smartlink or
@@ -3293,7 +3312,7 @@ unit cgcpu;
             cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,tmpref,NR_R0);
             list.concat(taicpu.op_reg_reg(A_MOV,NR_R12,NR_R0));
             list.concat(taicpu.op_regset(A_POP,R_INTREGISTER,R_SUBWHOLE,[RS_R0]));
-            list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R12));
+            list.concat(taicpu.op_reg(A_BX,NR_R12));
           end
         else
           list.concat(taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol(procdef.mangledname)));
@@ -4050,18 +4069,36 @@ unit cgcpu;
         tmpreg : TRegister;
       begin
         href:=ref;
-        if (op in [A_STR,A_STRB,A_STRH]) and
-           (abs(ref.offset)>124) then
-          begin
-            tmpreg:=getintregister(list,OS_ADDR);
-            a_loadaddr_ref_reg(list,ref,tmpreg);
-
-            reference_reset_base(href,tmpreg,0,ref.alignment);
-          end
-        else if (op=A_LDR) and
-           (oppostfix in [PF_None]) and
-           (ref.base<>NR_STACK_POINTER_REG)  and
-           (abs(ref.offset)>124) then
+        if { LDR/STR limitations }
+           (
+            (((op=A_LDR) and (oppostfix=PF_None)) or
+             ((op=A_STR) and (oppostfix=PF_None))) and
+            (ref.base<>NR_STACK_POINTER_REG) and
+            (abs(ref.offset)>124)
+           ) or
+           { LDRB/STRB limitations }
+           (
+           (((op=A_LDR) and (oppostfix=PF_B)) or
+            ((op=A_LDRB) and (oppostfix=PF_None)) or
+            ((op=A_STR) and (oppostfix=PF_B)) or
+            ((op=A_STRB) and (oppostfix=PF_None))) and
+            ((ref.base=NR_STACK_POINTER_REG) or
+             (ref.index=NR_STACK_POINTER_REG) or
+             (abs(ref.offset)>31)
+            )
+           ) or
+           { LDRH/STRH limitations }
+           (
+            (((op=A_LDR) and (oppostfix=PF_H)) or
+             ((op=A_LDRH) and (oppostfix=PF_None)) or
+             ((op=A_STR) and (oppostfix=PF_H)) or
+             ((op=A_STRH) and (oppostfix=PF_None))) and
+            ((ref.base=NR_STACK_POINTER_REG) or
+             (ref.index=NR_STACK_POINTER_REG) or
+             (abs(ref.offset)>62) or
+             ((abs(ref.offset) mod 2)<>0)
+            )
+           ) then
           begin
             tmpreg:=getintregister(list,OS_ADDR);
             a_loadaddr_ref_reg(list,ref,tmpreg);
@@ -4274,6 +4311,32 @@ unit cgcpu;
       end;
 
 
+    procedure tthumbcgarm.g_external_wrapper(list: TAsmList; procdef: tprocdef; const externalname: string);
+      var
+        tmpref : treference;
+        l : tasmlabel;
+      begin
+        { there is no branch instruction on thumb which allows big distances and which leaves LR as it is
+          and which allows to switch the instruction set }
+
+        { create const entry }
+        reference_reset(tmpref,4);
+        current_asmdata.getjumplabel(l);
+        tmpref.symbol:=l;
+        tmpref.base:=NR_PC;
+        list.concat(taicpu.op_regset(A_PUSH,R_INTREGISTER,R_SUBWHOLE,[RS_R0]));
+        list.concat(taicpu.op_reg_ref(A_LDR,NR_R0,tmpref));
+        list.concat(taicpu.op_reg_reg(A_MOV,NR_R12,NR_R0));
+        list.concat(taicpu.op_regset(A_POP,R_INTREGISTER,R_SUBWHOLE,[RS_R0]));
+        list.concat(taicpu.op_reg(A_BX,NR_R12));
+
+        { append const entry }
+        list.Concat(tai_align.Create(4));
+        list.Concat(tai_label.create(l));
+        list.concat(tai_const.Create_sym(current_asmdata.RefAsmSymbol(externalname)));
+      end;
+
+
     procedure tthumb2cgarm.init_register_allocators;
       begin
         inherited init_register_allocators;

+ 43 - 1
compiler/arm/cpuelf.pas

@@ -561,6 +561,7 @@ implementation
     rotation:longint;
     residual,g_n:longword;
     curloc: aword;
+    bit_S,bit_I1,bit_I2: aint;
   begin
     data:=objsec.data;
     for i:=0 to objsec.ObjRelocations.Count-1 do
@@ -660,7 +661,16 @@ implementation
                   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;
+                tmp:=tmp+relocval;
+                if odd(tmp) then    { dest is Thumb? }
+                  begin
+                    if (reltyp=R_ARM_CALL) then
+                      { change BL to BLX, dest bit 1 goes to instruction bit 24 }
+                      address:=(address and $FE000000) or (((tmp-curloc) and 2) shl 23) or $10000000
+                    else
+                      InternalError(2014092001);
+                  end;
+                tmp:=tmp-curloc;
                 // TODO: check overflow
                 address:=(address and $FF000000) or ((tmp and $3FFFFFE) shr 2);
               end;
@@ -829,6 +839,38 @@ implementation
                   address:=address or (1 shl 23);
               end;
 
+            R_ARM_THM_CALL:
+              begin
+                if (not ElfTarget.relocs_use_addend) then
+                  begin
+                    address:=((address and $ffff) shl 16) or word(address shr 16);
+                    bit_S:=(address shr 26) and 1;
+                    bit_I1:=(bit_S xor ((address shr 13) and 1)) xor 1;
+                    bit_I2:=(bit_S xor ((address shr 11) and 1)) xor 1;
+                    tmp:=((-bit_S) shl 24) or (bit_I1 shl 23) or (bit_I2 shl 22) or (((address shr 16) and $3ff) shl 12) or ((address and $7ff) shl 1);
+                  end
+                else  { TODO: must read the instruction anyway }
+                  tmp:=address;
+                tmp:=tmp+relocval;       { dest address }
+                if odd(tmp) then         { if it's Thumb code, change possible BLX to BL }
+                  address:=address or $1800;
+                tmp:=tmp-curloc;         { now take PC-relative }
+                { TODO: overflow check, different limit for Thumb and Thumb-2 }
+
+                { now encode this mess back }
+                if (address and $5000)=$4000 then
+                  tmp:=(tmp+2) and (not 3);
+
+                bit_S:=(tmp shr 31) and 1;
+                address:=(address and $F800D000) or
+                  (bit_S shl 26) or
+                  (((tmp shr 12) and $3ff) shl 16) or
+                  ((tmp shr 1) and $7FF) or
+                  ((((tmp shr 23) and 1) xor 1 xor bit_S) shl 13) or
+                  ((((tmp shr 22) and 1) xor 1 xor bit_S) shl 11);
+                address:=((address and $ffff) shl 16) or word(address shr 16);
+              end;
+
             R_ARM_TLS_IE32:
               begin
                 relocval:=relocval-tlsseg.mempos+align_aword(TCB_SIZE,tlsseg.align);

+ 6 - 1
compiler/arm/cpuinfo.pas

@@ -21,6 +21,9 @@ Interface
 
 Type
    bestreal = double;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = type extended;
@@ -338,8 +341,10 @@ Type
       ct_thumb2bare
      );
 
-
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = true;
    {# Size of native extended floating point type }
    extended_size = 12;
    {# Size of a multimedia register               }

+ 36 - 10
compiler/arm/narmadd.pas

@@ -85,6 +85,8 @@ interface
                       GetResFlags:=F_LT;
                     gten:
                       GetResFlags:=F_LE;
+                    else
+                      internalerror(201408203);
                   end
                 else
                   case NodeType of
@@ -96,6 +98,8 @@ interface
                       GetResFlags:=F_GT;
                     gten:
                       GetResFlags:=F_GE;
+                    else
+                      internalerror(201408204);
                   end;
               end
             else
@@ -110,6 +114,8 @@ interface
                       GetResFlags:=F_CC;
                     gten:
                       GetResFlags:=F_LS;
+                    else
+                      internalerror(201408205);
                   end
                 else
                   case NodeType of
@@ -121,6 +127,8 @@ interface
                       GetResFlags:=F_HI;
                     gten:
                       GetResFlags:=F_CS;
+                    else
+                      internalerror(201408206);
                   end;
               end;
         end;
@@ -144,6 +152,8 @@ interface
             result:=F_GT;
           gten:
             result:=F_GE;
+          else
+            internalerror(201408207);
         end;
       end;
 
@@ -379,13 +389,13 @@ interface
               tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
               if right.location.loc = LOC_CONSTANT then
                 begin
-                  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_AND,tmpreg,left.location.register,right.location.value));
+                  cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_AND,OS_32,right.location.value,left.location.register,tmpreg);
                   cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
                   current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP,tmpreg,right.location.value));
                 end
               else
                 begin
-                  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_AND,tmpreg,left.location.register,right.location.register));
+                  cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,OS_32,left.location.register,right.location.register,tmpreg);
                   cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
                   current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,tmpreg,right.location.register));
                 end;
@@ -403,6 +413,8 @@ interface
         oldnodetype : tnodetype;
         dummyreg : tregister;
         l: tasmlabel;
+      const
+        lt_zero_swapped: array[boolean] of tnodetype = (ltn, gtn);
       begin
         unsigned:=not(is_signed(left.resultdef)) or
                   not(is_signed(right.resultdef));
@@ -411,20 +423,34 @@ interface
 
         { pass_left_right moves possible consts to the right, the only
           remaining case with left consts (currency) can take this path too (KB) }
-        if (nodetype in [equaln,unequaln]) and
-          (right.nodetype=ordconstn) and (tordconstnode(right).value=0) then
+        if (right.nodetype=ordconstn) and
+           (tordconstnode(right).value=0) and
+           ((nodetype in [equaln,unequaln]) or
+            (not(GenerateThumbCode) and is_signed(left.resultdef) and (nodetype = lt_zero_swapped[nf_swapped in Flags]))
+           ) then
           begin
             location_reset(location,LOC_FLAGS,OS_NO);
-            location.resflags:=getresflags(unsigned);
             if not(left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
               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);
 
-            if GenerateThumbCode then
-              cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reglo,left.location.register64.reghi,dummyreg)
+            cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
+            { Optimize for the common case of int64 < 0 }
+            if nodetype in [ltn, gtn] then
+              begin
+                {Just check for the MSB in reghi to be set or not, this is independed from nf_swapped}
+                location.resflags:=F_NE;
+                current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_TST,left.location.register64.reghi, aint($80000000)));
+              end
             else
-              current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
+              begin
+                location.resflags:=getresflags(unsigned);
+                dummyreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
+
+                if GenerateThumbCode 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;
           end
         else
           begin

+ 11 - 4
compiler/arm/narmset.pas

@@ -141,6 +141,7 @@ implementation
     procedure tarmcasenode.genjumptable(hp : pcaselabel;min_,max_ : aint);
       var
         last : TConstExprInt;
+        tmpreg,
         basereg,
         indexreg : tregister;
         href : treference;
@@ -222,7 +223,7 @@ implementation
           begin
             if cs_create_pic in current_settings.moduleswitches then
               internalerror(2013082102);
-            cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_ADDR,min_+1,indexreg,indexreg);
+            cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_ADDR,min_,indexreg,indexreg);
             current_asmdata.getaddrlabel(tablelabel);
 
             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHL,OS_ADDR,2,indexreg);
@@ -231,9 +232,15 @@ implementation
             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));
+            reference_reset(href,0);
+            href.base:=basereg;
+            href.index:=indexreg;
+            
+            tmpreg:=cg.getintregister(current_asmdata.CurrAsmList, OS_ADDR);
+            cg.a_load_ref_reg(current_asmdata.CurrAsmList, OS_ADDR, OS_ADDR, href, tmpreg);
+            
+            { do not use BX here to avoid switching into arm mode }
+            current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_MOV, NR_PC, tmpreg));
 
             cg.a_label(current_asmdata.CurrAsmList,tablelabel);
             { generate jump table }

+ 1 - 0
compiler/arm/raarmgas.pas

@@ -1043,6 +1043,7 @@ Unit raarmgas;
         hreg : tregister;
         flags : tspecialregflags;
       begin
+        hreg:=NR_NO;
         case actasmtoken of
           AS_REGISTER:
             begin

+ 14 - 0
compiler/arm/rgcpu.pas

@@ -290,6 +290,10 @@ unit rgcpu;
         if abs(spilltemp.offset)>4095 then
           exit;
 
+        { ldr can't set the flags }
+        if instr.oppostfix=PF_S then
+          exit;
+
         if GenerateThumbCode and
           (abs(spilltemp.offset)>1020) then
           exit;
@@ -304,6 +308,11 @@ unit rgcpu;
                    (get_alias(getsupreg(oper[0]^.reg))=orgreg) and
                    (get_alias(getsupreg(oper[1]^.reg))<>orgreg) then
                   begin
+                    { do not replace if we're on Thumb, ldr/str cannot be used with rX>r7 }
+                    if GenerateThumbCode and
+                       (getsupreg(oper[1]^.reg)>RS_R7) then
+                       exit;
+
                     { str expects the register in oper[0] }
                     instr.loadreg(0,oper[1]^.reg);
                     instr.loadref(1,spilltemp);
@@ -314,6 +323,11 @@ unit rgcpu;
                    (get_alias(getsupreg(oper[1]^.reg))=orgreg) and
                    (get_alias(getsupreg(oper[0]^.reg))<>orgreg) then
                   begin
+                    { do not replace if we're on Thumb, ldr/str cannot be used with rX>r7 }
+                    if GenerateThumbCode and
+                       (getsupreg(oper[0]^.reg)>RS_R7) then
+                       exit;
+
                     instr.loadref(1,spilltemp);
                     opcode:=A_LDR;
                     result:=true;

+ 2 - 1
compiler/assemble.pas

@@ -1736,7 +1736,8 @@ Implementation
         if not(tf_section_threadvars in target_info.flags) then
           exclude(to_do,al_threadvars);
         for i:=low(TasmlistType) to high(TasmlistType) do
-          if (i in to_do) and (current_asmdata.asmlists[i]<>nil) then
+          if (i in to_do) and (current_asmdata.asmlists[i]<>nil) and
+             (not current_asmdata.asmlists[i].empty) then
             addlist(current_asmdata.asmlists[i]);
 
         if SmartAsm then

+ 5 - 5
compiler/avr/aasmcpu.pas

@@ -246,11 +246,11 @@ implementation
       begin
         result:=operand_read;
         case opcode of
-          A_CLR,
-          A_MOV, A_MOVW:
-           if opnr=0 then
-             result:=operand_write;
-          A_CP,A_CPC,A_CPI,A_PUSH :
+          A_CLR,A_LDD,A_LD,A_LDI,A_LDS,
+          A_MOV,A_MOVW:
+            if opnr=0 then
+              result:=operand_write;
+          A_CP,A_CPC,A_CPI,A_PUSH,A_ST,A_STD,A_STS:
             ;
           else
             begin

+ 4 - 6
compiler/avr/agavrgas.pas

@@ -81,6 +81,7 @@ unit agavrgas;
         var
           s : string;
         begin
+           s:='';
            with ref do
             begin
   {$ifdef extdebug}
@@ -95,9 +96,8 @@ unit agavrgas;
               else if base<>NR_NO then
                 begin
                   if addressmode=AM_PREDRECEMENT then
-                    s:='-'
-                  else
-                    s:='';
+                    s:='-';
+
                   case base of
                     NR_R26:
                       s:=s+'X';
@@ -119,9 +119,7 @@ unit agavrgas;
               else if assigned(symbol) or (offset<>0) then
                 begin
                   if assigned(symbol) then
-                    s:=ReplaceForbiddenAsmSymbolChars(symbol.name)
-                  else
-                     s:='';
+                    s:=ReplaceForbiddenAsmSymbolChars(symbol.name);
 
                   if offset<0 then
                     s:=s+tostr(offset)

+ 6 - 0
compiler/avr/cpuinfo.pas

@@ -21,6 +21,9 @@ Interface
 
 Type
    bestreal = double;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = type extended;
@@ -61,6 +64,9 @@ Type
      );
 
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = true;
    {# Size of native extended floating point type }
    extended_size = 12;
    {# Size of a multimedia register               }

+ 4 - 4
compiler/avr/cpupara.pas

@@ -201,13 +201,13 @@ unit cpupara;
         begin
           { In case of po_delphi_nested_cc, the parent frame pointer
             is always passed on the stack. }
-           if (nextintreg>RS_R8) and
+           if (nextintreg>RS_R7) 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);
+               dec(nextintreg);
              end
            else
              begin
@@ -251,8 +251,8 @@ unit cpupara;
               begin
                 paradef:=getpointerdef(paradef);
                 loc:=LOC_REGISTER;
-                paracgsize := OS_ADDR;
-                paralen := tcgsize2size[OS_ADDR];
+                paracgsize:=OS_ADDR;
+                paralen:=tcgsize2size[OS_ADDR];
               end
             else
               begin

+ 10 - 2
compiler/avr/navradd.pas

@@ -77,6 +77,8 @@ interface
                       GetResFlags:=F_LT;
                     gten:
                       GetResFlags:=F_NotPossible;
+                    else
+                      internalerror(2014082020);
                   end
                 else
                   case NodeType of
@@ -88,6 +90,8 @@ interface
                       GetResFlags:=F_NotPossible;
                     gten:
                       GetResFlags:=F_GE;
+                    else
+                      internalerror(2014082021);
                   end;
               end
             else
@@ -102,6 +106,8 @@ interface
                       GetResFlags:=F_CC;
                     gten:
                       GetResFlags:=F_NotPossible;
+                    else
+                      internalerror(2014082022);
                   end
                 else
                   case NodeType of
@@ -113,6 +119,8 @@ interface
                       GetResFlags:=F_NotPossible;
                     gten:
                       GetResFlags:=F_CS;
+                    else
+                      internalerror(2014082023);
                   end;
               end;
         end;
@@ -220,7 +228,7 @@ interface
     function tavraddnode.pass_1 : tnode;
       begin
         result:=inherited pass_1;
-{
+{$ifdef dummy}
         if not(assigned(result)) then
           begin
             unsigned:=not(is_signed(left.resultdef)) or
@@ -240,7 +248,7 @@ interface
              is_dynamic_array(left.resultdef)
            ) then
           expectloc:=LOC_FLAGS;
-}
+{$endif dummy}
       end;
 
 

+ 2 - 2
compiler/avr/navrmat.pas

@@ -165,7 +165,7 @@ implementation
         secondpass(right);
         location_copy(location,left.location);
 
-{
+{$ifdef dummy}
         { put numerator in register }
         size:=def_cgsize(left.resultdef);
         hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,
@@ -201,7 +201,7 @@ implementation
         {  simple comparison with 0)                                             }
         if is_signed(right.resultdef) then
           cg.g_overflowcheck(current_asmdata.CurrAsmList,location,resultdef);
-}
+{$endif dummy}
       end;
 
 {*****************************************************************************

+ 1 - 1
compiler/avr/raavrgas.pas

@@ -617,7 +617,7 @@ Unit raavrgas;
         actopcode:=A_NONE;
         for j:=maxlen downto 1 do
           begin
-            actopcode:=tasmop(PtrInt(iasmops.Find(copy(hs,1,j))));
+            actopcode:=tasmop(PtrUInt(iasmops.Find(copy(hs,1,j))));
             if actopcode<>A_NONE then
               begin
                 actasmtoken:=AS_OPCODE;

+ 4 - 4
compiler/cclasses.pas

@@ -508,14 +508,14 @@ type
          destructor Destroy; override;
          procedure Clear;
          { finds an entry by key }
-         function Find(Key: Pointer; KeyLen: Integer): PHashSetItem;
+         function Find(Key: Pointer; KeyLen: Integer): PHashSetItem;virtual;
          { finds an entry, creates one if not exists }
          function FindOrAdd(Key: Pointer; KeyLen: Integer;
-           var Found: Boolean): PHashSetItem;
+           var Found: Boolean): PHashSetItem;virtual;
          { finds an entry, creates one if not exists }
-         function FindOrAdd(Key: Pointer; KeyLen: Integer): PHashSetItem;
+         function FindOrAdd(Key: Pointer; KeyLen: Integer): PHashSetItem;virtual;
          { returns Data by given Key }
-         function Get(Key: Pointer; KeyLen: Integer): TObject;
+         function Get(Key: Pointer; KeyLen: Integer): TObject;virtual;
          { removes an entry, returns False if entry wasn't there }
          function Remove(Entry: PHashSetItem): Boolean;
          property Count: LongWord read FCount;

+ 7 - 4
compiler/cfileutl.pas

@@ -23,7 +23,9 @@ unit cfileutl;
 
 {$i fpcdefs.inc}
 
+{$ifndef DragonFly}
 {$define usedircache}
+{$endif DragonFly}
 
 interface
 
@@ -124,6 +126,7 @@ interface
     function  GetShortName(const n:TCmdStr):TCmdStr;
     function maybequoted(const s:string):string;
     function maybequoted(const s:ansistring):ansistring;
+    function maybequoted_for_script(const s:ansistring; quote_script: tscripttype):ansistring;
 
     procedure InitFileUtils;
     procedure DoneFileUtils;
@@ -140,7 +143,7 @@ interface
 { * Since native Amiga commands can't handle Unix-style relative paths used by the compiler,
     and some GNU tools, Unix2AmigaPath is needed to handle such situations (KB) * }
 
-{$IF DEFINED(MORPHOS) OR DEFINED(AMIGA)}
+{$IFDEF HASAMIGA}
 { * PATHCONV is implemented in the Amiga/MorphOS system unit * }
 {$NOTE TODO Amiga: implement PathConv() in System unit, which works with AnsiString}
 function Unix2AmigaPath(path: ShortString): ShortString; external name 'PATHCONV';
@@ -187,7 +190,7 @@ implementation
       DirCache : TDirectoryCache;
 
 
-{$IF NOT (DEFINED(MORPHOS) OR DEFINED(AMIGA))}
+{$IFNDEF HASAMIGA}
 { Stub function for Unix2Amiga Path conversion functionality, only available in
   Amiga/MorphOS RTL. I'm open for better solutions. (KB) }
 function Unix2AmigaPath(path: String): String;{$IFDEF USEINLINE}inline;{$ENDIF}
@@ -537,7 +540,7 @@ end;
 {$if defined(unix)}
         if (length(s)>0) and (s[1] in AllowDirectorySeparators) then
           result:=true;
-{$elseif defined(amiga) or defined(morphos)}
+{$elseif defined(hasamiga)}
         (* An Amiga path is absolute, if it has a volume/device name in it (contains ":"),
            otherwise it's always a relative path, no matter if it starts with a directory
            separator or not. (KB) *)
@@ -1077,7 +1080,7 @@ end;
             currPath:=FixPath(ExpandFileName(currpath),false);
             if (CurrentDir<>'') and (Copy(currPath,1,length(CurrentDir))=CurrentDir) then
              begin
-{$if defined(amiga) and defined(morphos)}
+{$ifdef hasamiga}
                currPath:= CurrentDir+Copy(currPath,length(CurrentDir)+1,length(currPath));
 {$else}
                currPath:= CurDirRelPath(source_info)+Copy(currPath,length(CurrentDir)+1,length(currPath));

+ 10 - 2
compiler/cgobj.pas

@@ -815,8 +815,15 @@ implementation
 
 
     procedure tcg.translate_register(var reg : tregister);
+      var
+        rt: tregistertype;
       begin
-        rg[getregtype(reg)].translate_register(reg);
+        { Getting here without assigned rg is possible for an "assembler nostackframe"
+          function returning x87 float, compiler tries to translate NR_ST which is used for
+          result.  }
+        rt:=getregtype(reg);
+        if assigned(rg[rt]) then
+          rg[rt].translate_register(reg);
       end;
 
 
@@ -828,7 +835,8 @@ implementation
 
     procedure tcg.a_reg_dealloc(list : TAsmList;r : tregister);
       begin
-         list.concat(tai_regalloc.dealloc(r,nil));
+        if (r<>NR_NO) then
+          list.concat(tai_regalloc.dealloc(r,nil));
       end;
 
 

+ 3 - 0
compiler/compiler.pas

@@ -65,6 +65,9 @@ uses
 {$ifdef android}
   ,i_android
 {$endif android}
+{$ifdef aros}
+  ,i_aros
+{$endif}
 {$ifdef atari}
   ,i_atari
 {$endif atari}

+ 1 - 0
compiler/compinnr.inc

@@ -88,6 +88,7 @@ const
    in_unbox_x_y         = 78; { manage platforms: extract from class instance }
    in_popcnt_x          = 79;
    in_aligned_x         = 80;
+   in_setstring_x_y_z   = 81;
 
 { Internal constant functions }
    in_const_sqr        = 100;

+ 1 - 1
compiler/comprsrc.pas

@@ -377,7 +377,7 @@ procedure TWinLikeResourceFile.Collect(const fn: ansistring);
 begin
   if fResScript=nil then
     fResScript:=TScript.Create(fScriptName);
-  fResScript.Add(MaybeQuoted(fn));
+  fResScript.Add(maybequoted_for_script(fn,script_fpcres));
   inc(fCollectCount);
 end;
 

+ 77 - 43
compiler/dbgdwarf.pas

@@ -375,7 +375,7 @@ interface
         procedure appendsym_property(list:TAsmList;sym:tpropertysym);override;
 
         function symdebugname(sym:tsym): String; virtual;
-        function symname(sym:tsym): String; virtual;
+        function symname(sym: tsym; manglename: boolean): String; virtual;
         procedure append_visibility(vis: tvisibility);
 
         procedure enum_membersyms_callback(p:TObject;arg:pointer);
@@ -931,10 +931,10 @@ implementation
                   begin
                     if not assigned(def.typesym) then
                       internalerror(200610011);
-                    def.dwarf_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym)),AT_DATA);
-                    def.dwarf_ref_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym)),AT_DATA);
+                    def.dwarf_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AT_DATA);
+                    def.dwarf_ref_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AT_DATA);
                     if is_class_or_interface_or_dispinterface(def) or is_objectpascal_helper(def) then
-                      tobjectdef(def).dwarf_struct_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym)),AT_DATA);
+                      tobjectdef(def).dwarf_struct_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AT_DATA);
                     def.dbg_state:=dbg_state_written;
                   end
                 else
@@ -945,10 +945,10 @@ implementation
                        (def.owner.symtabletype=globalsymtable) and
                        (def.owner.iscurrentunit) then
                       begin
-                        def.dwarf_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym)),AB_GLOBAL,AT_DATA);
-                        def.dwarf_ref_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym)),AB_GLOBAL,AT_DATA);
+                        def.dwarf_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
+                        def.dwarf_ref_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
                         if is_class_or_interface_or_dispinterface(def) or is_objectpascal_helper(def) then
-                          tobjectdef(def).dwarf_struct_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym)),AB_GLOBAL,AT_DATA);
+                          tobjectdef(def).dwarf_struct_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
                         include(def.defstates,ds_dwarf_dbg_info_written);
                       end
                     else
@@ -1371,7 +1371,7 @@ implementation
                 { base type such as byte/shortint/word/... }
                 if assigned(def.typesym) then
                   append_entry(DW_TAG_base_type,false,[
-                    DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+                    DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
                     DW_AT_encoding,DW_FORM_data1,sign,
                     DW_AT_byte_size,DW_FORM_data1,fullbytesize])
                 else
@@ -1385,7 +1385,7 @@ implementation
                   {       to be always clipped to s32bit for some reason }
                   if assigned(def.typesym) then
                     append_entry(DW_TAG_subrange_type,false,[
-                      DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+                      DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
                       DW_AT_lower_bound,signform,int64(def.low),
                       DW_AT_upper_bound,signform,int64(def.high)
                       ])
@@ -1544,7 +1544,7 @@ implementation
             if assigned(def.typesym) then
               begin
                 append_entry(DW_TAG_base_type,false,[
-                  DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+                  DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
                   DW_AT_encoding,DW_FORM_data1,DW_ATE_float,
                   DW_AT_byte_size,DW_FORM_data1,def.size
                   ]);
@@ -1569,7 +1569,7 @@ implementation
             { we should use DW_ATE_signed_fixed, however it isn't supported yet by GDB (FK) }
             if assigned(def.typesym) then
               append_entry(DW_TAG_base_type,false,[
-                DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+                DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
                 DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
                 DW_AT_byte_size,DW_FORM_data1,8
                 ])
@@ -1581,7 +1581,7 @@ implementation
           s64comp:
             if assigned(def.typesym) then
               append_entry(DW_TAG_base_type,false,[
-                DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+                DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
                 DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
                 DW_AT_byte_size,DW_FORM_data1,8
                 ])
@@ -1604,7 +1604,7 @@ implementation
       begin
         if assigned(def.typesym) then
           append_entry(DW_TAG_enumeration_type,true,[
-            DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+            DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
             DW_AT_byte_size,DW_FORM_data1,def.size
             ])
         else
@@ -1625,7 +1625,7 @@ implementation
             if hp.value>def.maxval then
               break;
             append_entry(DW_TAG_enumerator,false,[
-              DW_AT_name,DW_FORM_string,symname(hp)+#0,
+              DW_AT_name,DW_FORM_string,symname(hp, false)+#0,
               DW_AT_const_value,DW_FORM_data4,hp.value
             ]);
             finish_entry;
@@ -1668,7 +1668,7 @@ implementation
             { no known size, no known upper bound }
             if assigned(def.typesym) then
               append_entry(DW_TAG_array_type,true,[
-                DW_AT_name,DW_FORM_string,symname(def.typesym)+#0
+                DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0
                 ])
             else
               append_entry(DW_TAG_array_type,true,[]);
@@ -1685,7 +1685,7 @@ implementation
             size:=def.size;
             if assigned(def.typesym) then
               append_entry(DW_TAG_array_type,true,[
-                DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+                DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
                 DW_AT_byte_size,DW_FORM_udata,size
                 ])
             else
@@ -1867,7 +1867,7 @@ implementation
         begin
           if assigned(def.typesym) then
             append_entry(DW_TAG_subroutine_type,true,[
-              DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+              DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
               DW_AT_prototyped,DW_FORM_flag,true
             ])
           else
@@ -1882,7 +1882,7 @@ implementation
           for i:=0 to def.paras.count-1 do
             begin
               append_entry(DW_TAG_formal_parameter,false,[
-                DW_AT_name,DW_FORM_string,symname(tsym(def.paras[i]))+#0
+                DW_AT_name,DW_FORM_string,symname(tsym(def.paras[i]), false)+#0
               ]);
               append_labelentry_ref(DW_AT_type,def_dwarf_lab(tparavarsym(def.paras[i]).vardef));
               finish_entry;
@@ -2017,7 +2017,7 @@ implementation
           begin
             current_asmdata.getaddrlabel(TAsmLabel(pointer(labsym)));
             append_entry(DW_TAG_typedef,false,[
-              DW_AT_name,DW_FORM_string,symname(def.typesym)+#0
+              DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0
             ]);
             append_labelentry_ref(DW_AT_type,labsym);
             finish_entry;
@@ -2114,7 +2114,7 @@ implementation
         current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Procdef '+def.fullprocname(true))));
         if not is_objc_class_or_protocol(def.struct) then
           append_entry(DW_TAG_subprogram,true,
-            [DW_AT_name,DW_FORM_string,symname(def.procsym)+#0
+            [DW_AT_name,DW_FORM_string,symname(def.procsym, false)+#0
             { data continues below }
             { problem: base reg isn't known here
               DW_AT_frame_base,DW_FORM_block1,1
@@ -2318,7 +2318,7 @@ implementation
 
     procedure TDebugInfoDwarf.appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
       begin
-        appendsym_var_with_name_type_offset(list,sym,symname(sym),sym.vardef,0,[]);
+        appendsym_var_with_name_type_offset(list,sym,symname(sym, false),sym.vardef,0,[]);
       end;
 
 
@@ -2404,7 +2404,12 @@ implementation
                     if (vo_is_thread_var in sym.varoptions) then
                       begin
 { TODO: !!! FIXME: dwarf for thread vars !!!}
-                        blocksize:=0;
+{ This is only a minimal change to at least be able to get a value
+  in only one thread is present PM 2014-11-21, like for stabs format }
+                        templist.concat(tai_const.create_8bit(ord(DW_OP_addr)));
+                        templist.concat(tai_const.Create_type_name(aitconst_ptr,sym.mangledname,
+                          offset+sizeof(pint)));
+                        blocksize:=1+sizeof(puint);
                       end
                     else
                       begin
@@ -2554,7 +2559,7 @@ implementation
 
     procedure TDebugInfoDwarf.appendsym_fieldvar(list:TAsmList;sym: tfieldvarsym);
       begin
-        appendsym_fieldvar_with_name_offset(list,sym,symname(sym),sym.vardef,0);
+        appendsym_fieldvar_with_name_offset(list,sym,symname(sym, false),sym.vardef,0);
       end;
 
 
@@ -2601,7 +2606,7 @@ implementation
             if (target_info.endian=endian_little) then
               bitoffset:=(fieldnatsize*8)-bitoffset-sym.vardef.packedbitsize;
             append_entry(DW_TAG_member,false,[
-              DW_AT_name,DW_FORM_string,symname(sym)+#0,
+              DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
               { gcc also generates both a bit and byte size attribute }
               { we don't support ordinals >= 256 bits }
               DW_AT_byte_size,DW_FORM_data1,fieldnatsize,
@@ -2642,7 +2647,7 @@ implementation
 
         if ismember then
           append_entry(DW_TAG_member,false,[
-            DW_AT_name,DW_FORM_string,symname(sym)+#0,
+            DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
           { The DW_AT_declaration tag is invalid according to the DWARF specifications.
             But gcc adds this to static const members and gdb checks
             for this flag. So we have to set it also.
@@ -2652,7 +2657,7 @@ implementation
             ])
         else
           append_entry(DW_TAG_variable,false,[
-            DW_AT_name,DW_FORM_string,symname(sym)+#0
+            DW_AT_name,DW_FORM_string,symname(sym, false)+#0
             ]);
         { for string constants, constdef isn't set because they have no real type }
         case sym.consttyp of
@@ -2821,10 +2826,10 @@ implementation
           begin
             if (tosym.typ=fieldvarsym) then
               internalerror(2009031404);
-            appendsym_var_with_name_type_offset(list,tabstractnormalvarsym(tosym),symname(sym),sym.propdef,offset,[])
+            appendsym_var_with_name_type_offset(list,tabstractnormalvarsym(tosym),symname(sym, false),sym.propdef,offset,[])
           end
         else
-          appendsym_fieldvar_with_name_offset(list,tfieldvarsym(tosym),symname(sym),sym.propdef,offset)
+          appendsym_fieldvar_with_name_offset(list,tfieldvarsym(tosym),symname(sym, false),sym.propdef,offset)
       end;
 
 
@@ -2883,7 +2888,7 @@ implementation
                   flags:=[];
                   if (sym.owner.symtabletype=localsymtable) then
                     include(flags,dvf_force_local_var);
-                  appendsym_var_with_name_type_offset(list,tabstractnormalvarsym(tosym),symname(sym),tabstractvarsym(sym).vardef,offset,flags);
+                  appendsym_var_with_name_type_offset(list,tabstractnormalvarsym(tosym),symname(sym, false),tabstractvarsym(sym).vardef,offset,flags);
                 end;
               templist.free;
               exit;
@@ -2893,7 +2898,7 @@ implementation
         end;
 
         append_entry(DW_TAG_variable,false,[
-          DW_AT_name,DW_FORM_string,symname(sym)+#0,
+          DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
           {
           DW_AT_decl_file,DW_FORM_data1,0,
           DW_AT_decl_line,DW_FORM_data1,
@@ -2914,7 +2919,7 @@ implementation
 
     procedure TDebugInfoDwarf.beforeappendsym(list:TAsmList;sym:tsym);
       begin
-        current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Symbol '+symname(sym))));
+        current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Symbol '+symname(sym, true))));
       end;
 
 
@@ -3270,7 +3275,7 @@ implementation
       end;
 
 
-    function TDebugInfoDwarf.symname(sym: tsym): String;
+    function TDebugInfoDwarf.symname(sym: tsym; manglename: boolean): String;
       begin
         if (sym.typ=paravarsym) and
            (vo_is_self in tparavarsym(sym).varoptions) then
@@ -3290,9 +3295,20 @@ implementation
         else if (ds_dwarf_method_class_prefix in current_settings.debugswitches) and
                 (sym.typ=procsym) and
                 (tprocsym(sym).owner.symtabletype in [objectsymtable,recordsymtable]) then
-          result:=tprocsym(sym).owner.name^+'__'+symdebugname(sym)
+          begin
+            result:=tprocsym(sym).owner.name^+'__';
+            if manglename then
+              result := result + sym.name
+            else
+              result := result + symdebugname(sym);
+          end
         else
-          result:=symdebugname(sym);
+          begin
+            if manglename then
+              result := sym.name
+            else
+              result := symdebugname(sym);
+          end;
       end;
 
 
@@ -3316,6 +3332,7 @@ implementation
         currfileinfo,
         lastfileinfo : tfileposinfo;
         currfuncname : pshortstring;
+        currstatement: boolean;
         currsectype  : TAsmSectiontype;
         hp, hpend : tai;
         infile : tinputfile;
@@ -3334,6 +3351,7 @@ implementation
         currfuncname:=nil;
         currsectype:=sec_code;
         hp:=Tai(list.first);
+        currstatement:=true;
         prevcolumn := 0;
         prevline := 1;
         prevfileidx := 1;
@@ -3365,8 +3383,7 @@ implementation
             end;
 
             if (currsectype=sec_code) and
-               (hp.typ=ait_instruction) and
-               (nolineinfolevel=0) then
+               (hp.typ=ait_instruction) then
               begin
                 currfileinfo:=tailineinfo(hp).fileinfo;
                 { file changed ? (must be before line info) }
@@ -3397,8 +3414,12 @@ implementation
                       end;
                   end;
 
+                { Set the line-nr to 0 if the code does not corresponds to a particular line  }
+                if nolineinfolevel>0 then
+                  currfileinfo.line := 0;
+
                 { line changed ? }
-                if (lastfileinfo.line<>currfileinfo.line) and (currfileinfo.line<>0) then
+                if (lastfileinfo.line<>currfileinfo.line) and ((currfileinfo.line<>0) or (nolineinfolevel>0)) then
                   begin
                     { set address }
                     current_asmdata.getlabel(currlabel, alt_dbgline);
@@ -3431,6 +3452,19 @@ implementation
                         prevcolumn := currfileinfo.column;
                       end;
 
+                    { set statement }
+                    if (currfileinfo.line=0) and currstatement then
+                      begin
+                        currstatement := false;
+                        asmline.concat(tai_const.create_8bit(DW_LNS_negate_stmt));
+                      end;
+
+                    if not currstatement and (currfileinfo.line>0) then
+                      begin
+                        currstatement := true;
+                        asmline.concat(tai_const.create_8bit(DW_LNS_negate_stmt));
+                      end;
+
                     { set line }
                     diffline := currfileinfo.line - prevline;
                     if (diffline >= LINE_BASE) and (OPCODE_BASE + diffline - LINE_BASE <= 255) then
@@ -3517,7 +3551,7 @@ implementation
           file recs. are less than 1k so using data2 is enough }
         if assigned(def.typesym) then
           append_entry(DW_TAG_structure_type,false,[
-           DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+           DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
            DW_AT_byte_size,DW_FORM_udata,def.size
           ])
         else
@@ -3660,7 +3694,7 @@ implementation
 
             if assigned(def.typesym) then
               append_entry(DW_TAG_set_type,false,[
-                DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+                DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
                 DW_AT_byte_size,DW_FORM_data2,def.size
                 ])
             else
@@ -3696,7 +3730,7 @@ implementation
             { info of modules that contain set tags                          }
             if assigned(def.typesym) then
               append_entry(DW_TAG_base_type,false,[
-                DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+                DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
                 DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
                 DW_AT_byte_size,DW_FORM_data2,def.size
                 ])
@@ -3764,7 +3798,7 @@ implementation
 
         if assigned(def.typesym) then
           append_entry(DW_TAG_array_type,true,[
-            DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+            DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
             DW_AT_data_location,DW_FORM_block1,2
             ])
         else
@@ -3935,7 +3969,7 @@ implementation
       begin
         if assigned(def.typesym) then
           append_entry(DW_TAG_file_type,false,[
-            DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
+            DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,
             DW_AT_byte_size,DW_FORM_data2,def.size
             ])
         else
@@ -4073,7 +4107,7 @@ implementation
         { ??? can a undefined def have a typename ? }
         if assigned(def.typesym) then
           append_entry(DW_TAG_unspecified_type,false,[
-            DW_AT_name,DW_FORM_string,symname(def.typesym)+#0
+            DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0
             ])
         else
           append_entry(DW_TAG_unspecified_type,false,[

+ 6 - 10
compiler/dbgstabs.pas

@@ -1408,20 +1408,16 @@ implementation
             if target_info.system in systems_dotted_function_names then
               mangledname:='.'+mangledname;
             // LBRAC
-            ss:=tostr(STABS_N_LBRAC)+',0,0,'+mangledname;
-            if not(af_stabs_use_function_absolute_addresses in target_asm.flags) then
-              begin
-                ss:=ss+'-';
-                ss:=ss+mangledname;
-              end;
+            if af_stabs_use_function_absolute_addresses in target_asm.flags then
+              ss:=tostr(STABS_N_LBRAC)+',0,0,'+mangledname
+            else
+              ss:=tostr(STABS_N_LBRAC)+',0,0,0';
             result.concat(Tai_stab.Create_ansistr(stab_stabn,ss));
+
             // RBRAC
             ss:=tostr(STABS_N_RBRAC)+',0,0,'+stabsendlabel.name;
             if not(af_stabs_use_function_absolute_addresses in target_asm.flags) then
-              begin
-                ss:=ss+'-';
-                ss:=ss+mangledname;
-              end;
+              ss:=ss+'-'+mangledname;
             result.concat(Tai_stab.Create_ansistr(stab_stabn,ss));
 
             { the stabsendlabel must come after all other stabs for this }

+ 0 - 39
compiler/defutil.pas

@@ -334,21 +334,6 @@ interface
     { returns true if def is a C "block" }
     function is_block(def: tdef): boolean;
 
-    {# returns the appropriate int type for pointer arithmetic with the given pointer type.
-       When adding or subtracting a number to/from a pointer, this function returns the
-       int type to which that number has to be converted, before the operation can be performed.
-       Normally, this is sinttype, except on i8086, where it takes into account the
-       special i8086 pointer types (near, far, huge). }
-    function get_int_type_for_pointer_arithmetic(p : tdef) : tdef;
-
-{$ifdef i8086}
-    {# Returns true if p is a far pointer def }
-    function is_farpointer(p : tdef) : boolean;
-
-    {# Returns true if p is a huge pointer def }
-    function is_hugepointer(p : tdef) : boolean;
-{$endif i8086}
-
 implementation
 
     uses
@@ -1450,28 +1435,4 @@ implementation
       end;
 
 
-    function get_int_type_for_pointer_arithmetic(p : tdef) : tdef;
-      begin
-{$ifdef i8086}
-        if is_hugepointer(p) then
-          result:=s32inttype
-        else
-{$endif i8086}
-          result:=sinttype;
-      end;
-
-{$ifdef i8086}
-    { true if p is a far pointer def }
-    function is_farpointer(p : tdef) : boolean;
-      begin
-        result:=(p.typ=pointerdef) and (tcpupointerdef(p).x86pointertyp=x86pt_far);
-      end;
-
-    { true if p is a huge pointer def }
-    function is_hugepointer(p : tdef) : boolean;
-      begin
-        result:=(p.typ=pointerdef) and (tcpupointerdef(p).x86pointertyp=x86pt_huge);
-      end;
-{$endif i8086}
-
 end.

+ 1 - 1
compiler/expunix.pas

@@ -154,7 +154,7 @@ begin
            current_asmdata.asmlists[al_procedures].concat(Tai_symbol.Createname_global(hp2.name^,AT_FUNCTION,0));
            if (cs_create_pic in current_settings.moduleswitches) and
              { other targets need to be checked how it works }
-             (target_info.system in [system_i386_freebsd,system_x86_64_freebsd,system_x86_64_linux,system_i386_linux,system_x86_64_solaris,system_i386_solaris,system_i386_android]) then
+             (target_info.system in [system_i386_freebsd,system_x86_64_freebsd,system_x86_64_linux,system_i386_linux,system_x86_64_solaris,system_i386_solaris,system_i386_android,system_x86_64_dragonfly]) then
              begin
 {$ifdef x86}
                sym:=current_asmdata.RefAsmSymbol(pd.mangledname);

+ 4 - 4
compiler/fmodule.pas

@@ -44,7 +44,7 @@ interface
     uses
        cutils,cclasses,cfileutl,
        globtype,finput,ogbase,
-       symbase,symsym,
+       symbase,symconst,symsym,symcpu,
        wpobase,
        aasmbase,aasmtai,aasmdata;
 
@@ -142,7 +142,7 @@ interface
         checkforwarddefs,
         deflist,
         symlist       : TFPObjectList;
-        ptrdefs       : THashSet; { list of pointerdefs created in this module so we can reuse them (not saved/restored) }
+        ptrdefs       : tPtrDefHashSet; { list of pointerdefs created in this module so we can reuse them (not saved/restored) }
         arraydefs     : THashSet; { list of single-element-arraydefs created in this module so we can reuse them (not saved/restored) }
         ansistrdef    : tobject; { an ansistring def redefined for the current module }
         wpoinfo       : tunitwpoinfobase; { whole program optimization-related information that is generated during the current run for this unit }
@@ -567,7 +567,7 @@ implementation
         derefdataintflen:=0;
         deflist:=TFPObjectList.Create(false);
         symlist:=TFPObjectList.Create(false);
-        ptrdefs:=THashSet.Create(64,true,false);
+        ptrdefs:=cPtrDefHashSet.Create;
         arraydefs:=THashSet.Create(64,true,false);
         ansistrdef:=nil;
         wpoinfo:=nil;
@@ -744,7 +744,7 @@ implementation
         symlist.free;
         symlist:=TFPObjectList.Create(false);
         ptrdefs.free;
-        ptrdefs:=THashSet.Create(64,true,false);
+        ptrdefs:=cPtrDefHashSet.Create;
         arraydefs.free;
         arraydefs:=THashSet.Create(64,true,false);
         wpoinfo.free;

+ 7 - 1
compiler/fppu.pas

@@ -836,7 +836,13 @@ var
                 end;
              end
            else
-             temp:=' not available';
+             begin
+               { still register the source module for proper error messages
+                 since source_avail for the module is still false, this should not hurt }
+               sourcefiles.register_file(tdosinputfile.create(hs));
+
+               temp:=' not available';
+             end;
            if is_main then
              begin
                mainsource:=hs;

+ 24 - 0
compiler/generic/cpuinfo.pas

@@ -22,6 +22,13 @@ Interface
 
 Type
    bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+{$ifdef FPC_HAS_TYPE_EXTENDED}
+   bestrealrec = TExtended80Rec;
+{$else}
+   bestrealrec = TDoubleRec;
+{$endif}
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = type extended;
@@ -42,7 +49,24 @@ Type
       fpu_soft
      );
 
+   tcontrollertype =
+     (ct_none
+     );
+
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false;
+
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+
    cputypestr : array[tcputype] of string[8] = ('none');
    fputypestr : array[tfputype] of string[6] = ('none','soft');
 

+ 49 - 35
compiler/globals.pas

@@ -41,7 +41,6 @@ interface
 {$ELSE}
       fksysutl,
 {$ENDIF}
-
       { comphook pulls in sysutils anyways }
       cutils,cclasses,cfileutl,
       cpuinfo,
@@ -52,7 +51,7 @@ interface
          [m_delphi,m_class,m_objpas,m_result,m_string_pchar,
           m_pointer_2_procedure,m_autoderef,m_tp_procvar,m_initfinal,m_default_ansistring,
           m_out,m_default_para,m_duplicate_names,m_hintdirective,
-          m_property,m_default_inline,m_except,m_advanced_records];
+          m_property,m_default_inline,m_except,m_advanced_records,m_type_helpers];
        delphiunicodemodeswitches = delphimodeswitches + [m_systemcodepage,m_default_unicodestring];
        fpcmodeswitches =
          [m_fpc,m_string_pchar,m_nested_comment,m_repeat_forward,
@@ -84,23 +83,23 @@ interface
        treelogfilename = 'tree.log';
 
 {$if defined(CPUARM) and defined(FPUFPA)}
-       MathQNaN : tdoublerec = (bytes : (0,0,252,255,0,0,0,0));
-       MathInf : tdoublerec = (bytes : (0,0,240,127,0,0,0,0));
-       MathNegInf : tdoublerec = (bytes : (0,0,240,255,0,0,0,0));
-       MathPi : tdoublerec =  (bytes : (251,33,9,64,24,45,68,84));
+       MathQNaN : tcompdoublerec = (bytes : (0,0,252,255,0,0,0,0));
+       MathInf : tcompdoublerec = (bytes : (0,0,240,127,0,0,0,0));
+       MathNegInf : tcompdoublerec = (bytes : (0,0,240,255,0,0,0,0));
+       MathPi : tcompdoublerec =  (bytes : (251,33,9,64,24,45,68,84));
 {$else}
 {$ifdef FPC_LITTLE_ENDIAN}
-       MathQNaN : tdoublerec = (bytes : (0,0,0,0,0,0,252,255));
-       MathInf : tdoublerec = (bytes : (0,0,0,0,0,0,240,127));
-       MathNegInf : tdoublerec = (bytes : (0,0,0,0,0,0,240,255));
-       MathPi : tdoublerec = (bytes : (24,45,68,84,251,33,9,64));
-       MathPiExtended : textendedrec = (bytes : (53,194,104,33,162,218,15,201,0,64));
+       MathQNaN : tcompdoublerec = (bytes : (0,0,0,0,0,0,252,255));
+       MathInf : tcompdoublerec = (bytes : (0,0,0,0,0,0,240,127));
+       MathNegInf : tcompdoublerec = (bytes : (0,0,0,0,0,0,240,255));
+       MathPi : tcompdoublerec = (bytes : (24,45,68,84,251,33,9,64));
+       MathPiExtended : tcompextendedrec = (bytes : (53,194,104,33,162,218,15,201,0,64));
 {$else FPC_LITTLE_ENDIAN}
-       MathQNaN : tdoublerec = (bytes : (255,252,0,0,0,0,0,0));
-       MathInf : tdoublerec = (bytes : (127,240,0,0,0,0,0,0));
-       MathNegInf : tdoublerec = (bytes : (255,240,0,0,0,0,0,0));
-       MathPi : tdoublerec =  (bytes : (64,9,33,251,84,68,45,24));
-       MathPiExtended : textendedrec = (bytes : (64,0,201,15,218,162,33,104,194,53));
+       MathQNaN : tcompdoublerec = (bytes : (255,252,0,0,0,0,0,0));
+       MathInf : tcompdoublerec = (bytes : (127,240,0,0,0,0,0,0));
+       MathNegInf : tcompdoublerec = (bytes : (255,240,0,0,0,0,0,0));
+       MathPi : tcompdoublerec =  (bytes : (64,9,33,251,84,68,45,24));
+       MathPiExtended : tcompextendedrec = (bytes : (64,0,201,15,218,162,33,104,194,53));
 {$endif FPC_LITTLE_ENDIAN}
 {$endif}
 
@@ -163,9 +162,8 @@ interface
 {$endif defined(ARM)}
 
         { CPU targets with microcontroller support can add a controller specific unit }
-{$if defined(ARM) or defined(AVR) or defined(MIPSEL)}
          controllertype   : tcontrollertype;
-{$endif defined(ARM) or defined(AVR) or defined(MIPSEL)}
+
          { WARNING: this pointer cannot be written as such in record token }
          pmessage : pmessagestaterecord;
        end;
@@ -238,7 +236,9 @@ interface
        paralinkoptions   : TCmdStr;
        paradynamiclinker : string;
        paraprintnodetree : byte;
+{$ifdef PREPROCWRITE}
        parapreprocess    : boolean;
+{$endif PREPROCWRITE}
        printnodefile     : text;
 
        {  typical cross compiling params}
@@ -411,7 +411,7 @@ interface
 {$endif i8086}
         maxfpuregisters : 0;
 
-{ Note: GENERIC_CPU is sued together with generic subdirectory to
+{ Note: GENERIC_CPU is used together with generic subdirectory to
   be able to compile some of the units without any real CPU.
   This is used to generate a CPU independant PPUDUMP utility. PM }
 {$ifdef GENERIC_CPU}
@@ -502,9 +502,7 @@ interface
 {$if defined(ARM)}
         instructionset : is_arm;
 {$endif defined(ARM)}
-{$if defined(ARM) or defined(AVR) or defined(MIPSEL)}
         controllertype : ct_none;
-{$endif defined(ARM) or defined(AVR) or defined(MIPSEL)}
         pmessage : nil;
       );
 
@@ -536,9 +534,7 @@ interface
     function Setoptimizecputype(const s:string;var a:tcputype):boolean;
     function Setcputype(const s:string;var a:tsettings):boolean;
     function SetFpuType(const s:string;var a:tfputype):boolean;
-{$if defined(arm) or defined(avr) or defined(mipsel)}
     function SetControllerType(const s:string;var a:tcontrollertype):boolean;
-{$endif defined(arm) or defined(avr) or defined(mipsel)}
     function IncludeFeature(const s : string) : boolean;
     function SetMinFPConstPrec(const s: string; var a: tfloattype) : boolean;
 
@@ -838,6 +834,13 @@ implementation
            Replace(s,'$FPCTARGET',target_os_string)
          else
            Replace(s,'$FPCTARGET',target_full_string);
+         Replace(s,'$FPCSUBARCH',lower(cputypestr[init_settings.cputype]));
+         Replace(s,'$FPCABI',lower(abiinfo[target_info.abi].name));
+{$ifdef i8086}
+         Replace(s,'$FPCMEMORYMODEL',lower(x86memorymodelstr[init_settings.x86memorymodel]));
+{$else i8086}
+         Replace(s,'$FPCMEMORYMODEL','flat');
+{$endif i8086}
 {$ifdef mswindows}
          ReplaceSpecialFolder('$LOCAL_APPDATA',CSIDL_LOCAL_APPDATA);
          ReplaceSpecialFolder('$APPDATA',CSIDL_APPDATA);
@@ -968,7 +971,7 @@ implementation
           result := -1;
       end;
 
-    function convertdoublerec(d : tdoublerec) : tdoublerec;{$ifdef USEINLINE}inline;{$endif}
+    function convertdoublerec(d : tcompdoublerec) : tcompdoublerec;{$ifdef USEINLINE}inline;{$endif}
 {$ifdef CPUARM}
       var
         i : longint;
@@ -1177,23 +1180,34 @@ implementation
       end;
 
 
-{$if defined(arm) or defined(avr) or defined(mipsel)}
     function SetControllerType(const s:string;var a:tcontrollertype):boolean;
       var
         t  : tcontrollertype;
         hs : string;
       begin
-        result:=false;
-        hs:=Upper(s);
-        for t:=low(tcontrollertype) to high(tcontrollertype) do
-          if embedded_controllers[t].controllertypestr=hs then
-            begin
-              a:=t;
-              result:=true;
-              break;
-            end;
+{ The following check allows to reduce amount of code for platforms  }
+{ not supporting microcontrollers due to evaluation at compile time. }
+{$PUSH}
+ {$WARN 6018 OFF} (* Unreachable code due to compile time evaluation *)
+        if ControllerSupport then
+         begin
+          result:=false;
+          hs:=Upper(s);
+          for t:=low(tcontrollertype) to high(tcontrollertype) do
+            if embedded_controllers[t].controllertypestr=hs then
+              begin
+                a:=t;
+                result:=true;
+                break;
+              end;
+         end
+        else
+         begin
+          a := ct_none;
+          Result := true;
+         end;
+{$POP}
       end;
-{$endif defined(arm) or defined(avr) or defined(mipsel)}
 
 
     function IncludeFeature(const s : string) : boolean;

+ 10 - 2
compiler/globtype.pas

@@ -110,12 +110,12 @@ interface
 {$endif i8086}
 
        { Use a variant record to be sure that the array if aligned correctly }
-       tdoublerec=record
+       tcompdoublerec=record
          case byte of
            0 : (bytes:array[0..7] of byte);
            1 : (value:double);
        end;
-       textendedrec=record
+       tcompextendedrec=record
          case byte of
            0 : (bytes:array[0..9] of byte);
            1 : (value:extended);
@@ -707,6 +707,14 @@ interface
 
     type
       tx86memorymodel = (mm_tiny,mm_small,mm_medium,mm_compact,mm_large,mm_huge);
+    const
+      x86memorymodelstr : array[tx86memorymodel] of string[7]=(
+        'TINY',
+        'SMALL',
+        'MEDIUM',
+        'COMPACT',
+        'LARGE',
+        'HUGE');
 
   { hide Sysutils.ExecuteProcess in units using this one after SysUtils}
   const

+ 1 - 0
compiler/hlcg2ll.pas

@@ -656,6 +656,7 @@ implementation
         internalerror(2012071226);
       tocgsize:=getintmmcgsize(reg,def_cgmmsize(tosize));
       case loc.loc of
+        LOC_CONSTANT,
         LOC_SUBSETREG,LOC_CSUBSETREG,
         LOC_SUBSETREF,LOC_CSUBSETREF:
           begin

+ 63 - 22
compiler/htypechk.pas

@@ -26,7 +26,7 @@ unit htypechk;
 interface
 
     uses
-      cclasses,tokens,cpuinfo,
+      cclasses,cmsgs,tokens,cpuinfo,
       node,globtype,
       symconst,symtype,symdef,symsym,symbase;
 
@@ -178,6 +178,8 @@ interface
       arrays, records and objects are checked recursively }
     function is_valid_for_default(def:tdef):boolean;
 
+    procedure UninitializedVariableMessage(pos : tfileposinfo;warning,local,managed : boolean;name : TMsgStr);
+
 implementation
 
     uses
@@ -1092,6 +1094,23 @@ implementation
       end;
 
 
+    procedure UninitializedVariableMessage(pos : tfileposinfo;warning,local,managed : boolean;name : TMsgStr);
+      const
+        msg : array[false..true,false..true,false..true] of dword = (
+            (
+              (sym_h_uninitialized_variable,sym_h_uninitialized_managed_variable),
+              (sym_h_uninitialized_local_variable,sym_h_uninitialized_managed_local_variable)
+            ),
+            (
+              (sym_w_uninitialized_variable,sym_w_uninitialized_managed_variable),
+              (sym_w_uninitialized_local_variable,sym_w_uninitialized_managed_local_variable)
+            )
+          );
+      begin
+        CGMessagePos1(pos,msg[warning,local,managed],name);
+      end;
+
+
     procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
       const
         vstrans: array[tvarstate,tvarstate] of tvarstate = (
@@ -1197,32 +1216,29 @@ implementation
                                  if (vo_is_funcret in hsym.varoptions) then
                                    begin
                                      if (vsf_use_hints in varstateflags) then
-                                       CGMessagePos(p.fileinfo,sym_h_function_result_uninitialized)
-                                     else
-                                       CGMessagePos(p.fileinfo,sym_w_function_result_uninitialized)
-                                   end
-                                 else
-                                   begin
-                                     if tloadnode(p).symtable.symtabletype=localsymtable then
                                        begin
-                                         { on the JVM, an uninitialized var-parameter
-                                           is just as fatal as a nil pointer dereference }
-                                         if (vsf_use_hints in varstateflags) and
-                                            not(target_info.system in systems_jvm) then
-                                           CGMessagePos1(p.fileinfo,sym_h_uninitialized_local_variable,hsym.realname)
+                                         if is_managed_type(hsym.vardef) then
+                                           CGMessagePos(p.fileinfo,sym_h_managed_function_result_uninitialized)
                                          else
-                                           CGMessagePos1(p.fileinfo,sym_w_uninitialized_local_variable,hsym.realname);
+                                           CGMessagePos(p.fileinfo,sym_h_function_result_uninitialized);
                                        end
                                      else
                                        begin
-                                         { on the JVM, an uninitialized var-parameter
-                                           is just as fatal as a nil pointer dereference }
-                                         if (vsf_use_hints in varstateflags) and
-                                            not(target_info.system in systems_jvm) then
-                                           CGMessagePos1(p.fileinfo,sym_h_uninitialized_variable,hsym.realname)
+                                         if is_managed_type(hsym.vardef) then
+                                           CGMessagePos(p.fileinfo,sym_w_managed_function_result_uninitialized)
                                          else
-                                           CGMessagePos1(p.fileinfo,sym_w_uninitialized_variable,hsym.realname);
+                                          CGMessagePos(p.fileinfo,sym_w_function_result_uninitialized);
                                        end;
+                                   end
+                                 else
+                                   begin
+                                     UninitializedVariableMessage(p.fileinfo,
+                                       { on the JVM, an uninitialized var-parameter
+                                         is just as fatal as a nil pointer dereference }
+                                       not((vsf_use_hints in varstateflags) and not(target_info.system in systems_jvm)),
+                                       tloadnode(p).symtable.symtabletype=localsymtable,
+                                       is_managed_type(tloadnode(p).resultdef),
+                                       hsym.realname);
                                    end;
                                end;
                            end
@@ -2227,7 +2243,7 @@ implementation
                  break;
              end;
            if is_objectpascal_helper(structdef) and
-              (tobjectdef(structdef).typ in [recorddef,objectdef]) then
+              (tobjectdef(structdef).extendeddef.typ in [recorddef,objectdef]) then
              begin
                { search methods in the extended type as well }
                srsym:=tprocsym(tabstractrecorddef(tobjectdef(structdef).extendeddef).symtable.FindWithHash(hashedid));
@@ -2583,7 +2599,8 @@ implementation
         def_to   : tdef;
         currpt,
         pt       : tcallparanode;
-        eq       : tequaltype;
+        eq,
+        mineq    : tequaltype;
         convtype : tconverttype;
         pdtemp,
         pdoper   : tprocdef;
@@ -2763,6 +2780,30 @@ implementation
                    eq:=compare_defs_ext(n.resultdef,def_to,n.nodetype,convtype,pdoper,cdoptions);
                    n.free;
                  end
+              else if is_open_array(def_to) and
+                      is_class_or_interface_or_dispinterface_or_objc_or_java(tarraydef(def_to).elementdef) and
+                      is_array_constructor(currpt.left.resultdef) and
+                      assigned(tarrayconstructornode(currpt.left).left) then
+                begin
+                  { ensure that [nil] can be converted to "array of tobject",
+                    because if we just try to convert "array of pointer" to
+                    "array of tobject", we get type conversion errors in
+                    non-Delphi modes }
+                  n:=currpt.left;
+                  mineq:=te_exact;
+                  repeat
+                    if tarrayconstructornode(n).left.nodetype=arrayconstructorrangen then
+                      eq:=te_incompatible
+                    else
+                      eq:=compare_defs_ext(tarrayconstructornode(n).left.resultdef,tarraydef(def_to).elementdef,tarrayconstructornode(n).left.nodetype,convtype,pdoper,cdoptions);
+                    if eq<mineq then
+                      mineq:=eq;
+                    if eq=te_incompatible then
+                      break;
+                    n:=tarrayconstructornode(n).right;
+                  until not assigned(n);
+                  eq:=mineq;
+                end
               else
               { generic type comparision }
                begin

+ 7 - 0
compiler/i386/cgcpu.pas

@@ -314,6 +314,13 @@ unit cgcpu;
         end;
 
       begin
+        { Release PIC register }
+        if (cs_create_pic in current_settings.moduleswitches) and
+           (tf_pic_uses_got in target_info.flags) and
+           (pi_needs_got in current_procinfo.flags) and
+           not(target_info.system in systems_darwin) then
+          list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil));
+
         { MMX needs to call EMMS }
         if assigned(rg[R_MMXREGISTER]) and
            (rg[R_MMXREGISTER].uses_registers) then

+ 1 - 1
compiler/i386/cpuelf.pas

@@ -509,7 +509,7 @@ implementation
                               system_i386_openbsd,system_i386_netbsd,
                               system_i386_Netware,system_i386_netwlibc,
                               system_i386_solaris,system_i386_embedded,
-                              system_i386_android];
+                              system_i386_android,system_i386_aros];
          flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf];
          labelprefix : '.L';
          comment : '';

+ 20 - 0
compiler/i386/cpuinfo.pas

@@ -30,6 +30,9 @@ Interface
 
 Type
    bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TExtended80Rec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = extended;
@@ -66,8 +69,25 @@ Type
       fpu_avx2
      );
 
+   tcontrollertype =
+     (ct_none
+     );
+
 
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false;
+
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+
    { calling conventions supported by the code generator }
    supported_calling_conventions : tproccalloptions = [
      pocall_internproc,

+ 18 - 0
compiler/i386/cpupara.pas

@@ -114,6 +114,23 @@ unit cpupara;
                   end;
               end;
             end;
+          system_i386_os2,
+          system_i386_emx:
+            begin
+              case def.typ of
+                recorddef :
+                  begin
+                    { EMX port of GCC returns small records in the FUNCTION_RETURN_REG up to 4 bytes in registers. }
+                    if ((pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
+                        (def.size>0) and
+                        (def.size<=4)) then
+                     begin
+                       result:=false;
+                       exit;
+                     end;
+                  end;
+              end;
+            end;
           system_i386_freebsd,
           system_i386_openbsd,
           system_i386_darwin,
@@ -243,6 +260,7 @@ unit cpupara;
           pocall_safecall,
           pocall_stdcall,
           pocall_cdecl,
+          pocall_syscall,
           pocall_cppdecl,
           pocall_mwpascal :
             result:=[RS_EAX,RS_EDX,RS_ECX];

+ 3 - 0
compiler/i386/cputarg.pas

@@ -86,6 +86,9 @@ implementation
     {$ifndef NOTARGETEMBEDDED}
       ,t_embed
     {$endif}
+    {$ifndef NOTARGETAROS}
+      ,t_aros
+    {$endif}
 
 {**************************************
              Assemblers

+ 84 - 64
compiler/i386/n386add.pas

@@ -229,8 +229,7 @@ interface
 
     procedure ti386addnode.second_cmp64bit;
       var
-        hregister,
-        hregister2 : tregister;
+        hlab       : tasmlabel;
         href       : treference;
         unsigned   : boolean;
 
@@ -247,10 +246,12 @@ interface
            case nodetype of
               ltn,gtn:
                 begin
-                   cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel);
+                   if (hlab<>current_procinfo.CurrTrueLabel) then
+                     cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel);
                    { cheat a little bit for the negative test }
                    toggleflag(nf_swapped);
-                   cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel);
+                   if (hlab<>current_procinfo.CurrFalseLabel) then
+                     cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel);
                    toggleflag(nf_swapped);
                 end;
               lten,gten:
@@ -260,13 +261,15 @@ interface
                      nodetype:=ltn
                    else
                      nodetype:=gtn;
-                   cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel);
+                   if (hlab<>current_procinfo.CurrTrueLabel) then
+                     cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel);
                    { cheat for the negative test }
                    if nodetype=ltn then
                      nodetype:=gtn
                    else
                      nodetype:=ltn;
-                   cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel);
+                   if (hlab<>current_procinfo.CurrFalseLabel) then
+                     cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel);
                    nodetype:=oldnodetype;
                 end;
               equaln:
@@ -309,24 +312,46 @@ interface
                   ((right.resultdef.typ=orddef) and
                    (torddef(right.resultdef).ordtype=u64bit));
 
+        { we have LOC_JUMP as result }
+        location_reset(location,LOC_JUMP,OS_NO);
+
+        { Relational compares against constants having low dword=0 can omit the
+          second compare based on the fact that any unsigned value is >=0 }
+        hlab:=nil;
+        if (right.location.loc=LOC_CONSTANT) and
+           (lo(right.location.value64)=0) then
+          begin
+            case getresflags(true) of
+              F_AE: hlab:=current_procinfo.CurrTrueLabel;
+              F_B:  hlab:=current_procinfo.CurrFalseLabel;
+            end;
+          end;
+
+        if (right.location.loc=LOC_CONSTANT) and
+           (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+          begin
+            tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,left.location.reference);
+            href:=left.location.reference;
+            inc(href.offset,4);
+            emit_const_ref(A_CMP,S_L,aint(hi(right.location.value64)),href);
+            firstjmp64bitcmp;
+            if assigned(hlab) then
+              cg.a_jmp_always(current_asmdata.CurrAsmList,hlab)
+            else
+              begin
+                emit_const_ref(A_CMP,S_L,aint(lo(right.location.value64)),left.location.reference);
+                secondjmp64bitcmp;
+              end;
+            location_freetemp(current_asmdata.CurrAsmList,left.location);
+            exit;
+          end;
+
         { left and right no register?  }
         { then one must be demanded    }
-        if (left.location.loc<>LOC_REGISTER) then
+        if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
          begin
-           if (right.location.loc<>LOC_REGISTER) then
-            begin
-              { we can reuse a CREGISTER for comparison }
-              if (left.location.loc<>LOC_CREGISTER) then
-               begin
-                 hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                 hregister2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                 cg64.a_load64_loc_reg(current_asmdata.CurrAsmList,left.location,joinreg64(hregister,hregister2));
-                 location_freetemp(current_asmdata.CurrAsmList,left.location);
-                 location_reset(left.location,LOC_REGISTER,left.location.size);
-                 left.location.register64.reglo:=hregister;
-                 left.location.register64.reghi:=hregister2;
-               end;
-            end
+           if not (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+             hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true)
            else
             begin
               location_swap(left.location,right.location);
@@ -334,51 +359,44 @@ interface
             end;
          end;
 
-        { at this point, left.location.loc should be LOC_REGISTER }
-        if right.location.loc=LOC_REGISTER then
-         begin
-           emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi);
-           firstjmp64bitcmp;
-           emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo);
-           secondjmp64bitcmp;
-         end
+        { at this point, left.location.loc should be LOC_[C]REGISTER }
+        case right.location.loc of
+          LOC_REGISTER,
+          LOC_CREGISTER :
+            begin
+              emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi);
+              firstjmp64bitcmp;
+              emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo);
+              secondjmp64bitcmp;
+            end;
+          LOC_CREFERENCE,
+          LOC_REFERENCE :
+            begin
+              tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,right.location.reference);
+              href:=right.location.reference;
+              inc(href.offset,4);
+              emit_ref_reg(A_CMP,S_L,href,left.location.register64.reghi);
+              firstjmp64bitcmp;
+              emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.register64.reglo);
+              secondjmp64bitcmp;
+              location_freetemp(current_asmdata.CurrAsmList,right.location);
+            end;
+          LOC_CONSTANT :
+            begin
+              current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.register64.reghi));
+              firstjmp64bitcmp;
+              if assigned(hlab) then
+                cg.a_jmp_always(current_asmdata.CurrAsmList,hlab)
+              else
+                begin
+                  current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.register64.reglo));
+                  secondjmp64bitcmp;
+                end;
+            end;
         else
-         begin
-           case right.location.loc of
-             LOC_CREGISTER :
-               begin
-                 emit_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi);
-                 firstjmp64bitcmp;
-                 emit_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo);
-                 secondjmp64bitcmp;
-               end;
-             LOC_CREFERENCE,
-             LOC_REFERENCE :
-               begin
-                 tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,right.location.reference);
-                 href:=right.location.reference;
-                 inc(href.offset,4);
-                 emit_ref_reg(A_CMP,S_L,href,left.location.register64.reghi);
-                 firstjmp64bitcmp;
-                 emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.register64.reglo);
-                 secondjmp64bitcmp;
-                 cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
-                 location_freetemp(current_asmdata.CurrAsmList,right.location);
-               end;
-             LOC_CONSTANT :
-               begin
-                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.register64.reghi));
-                 firstjmp64bitcmp;
-                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.register64.reglo));
-                 secondjmp64bitcmp;
-               end;
-             else
-               internalerror(200203282);
-           end;
-         end;
+          internalerror(200203282);
+        end;
 
-        { we have LOC_JUMP as result }
-        location_reset(location,LOC_JUMP,OS_NO)
       end;
 
 
@@ -424,6 +442,8 @@ interface
 
     begin
       pass_left_right;
+      reg:=NR_NO;
+      reference_reset(ref,sizeof(pint));
 
       { Mul supports registers and references, so if not register/reference,
         load the location into a register.

+ 36 - 2
compiler/i386/n386cal.pas

@@ -28,13 +28,16 @@ interface
 { $define AnsiStrRef}
 
     uses
-      nx86cal;
+      nx86cal,ncal;
 
     type
        ti386callnode = class(tx86callnode)
        protected
+          procedure gen_syscall_para(para: tcallparanode); override;
           procedure pop_parasize(pop_size:longint);override;
           procedure extra_interrupt_code;override;
+       public
+         procedure do_syscall;override;
        end;
 
 
@@ -46,7 +49,8 @@ implementation
       cgbase,cgutils,
       cpubase,paramgr,
       aasmtai,aasmdata,aasmcpu,
-      ncal,nbas,nmem,nld,ncnv,
+      nbas,nmem,nld,ncnv,
+      symdef,symsym,symcpu,
       cga,cgobj,cpuinfo;
 
 
@@ -55,6 +59,36 @@ implementation
 *****************************************************************************}
 
 
+    procedure ti386callnode.do_syscall;
+      var
+        tmpref: treference;
+      begin
+        case target_info.system of
+          system_i386_aros:
+            begin
+              // one syscall convention for AROS
+              current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('AROS SysCall')));
+              reference_reset(tmpref,sizeof(pint));
+              tmpref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(tcpuprocdef(procdefinition).libsym).mangledname);
+              cg.getcpuregister(current_asmdata.CurrAsmList,NR_EAX);
+              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_EAX);
+              reference_reset_base(tmpref,NR_EAX,-tprocdef(procdefinition).extnumber,sizeof(pint));
+              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpref,NR_EAX);
+              cg.a_call_reg(current_asmdata.CurrAsmList,NR_EAX);
+              cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EAX);
+            end;
+          else
+            internalerror(2014081801);
+        end;
+      end;
+
+
+    procedure ti386callnode.gen_syscall_para(para: tcallparanode);
+      begin
+        { lib parameter has no special type but proccalloptions must be a syscall }
+        para.left:=cloadnode.create(tcpuprocdef(procdefinition).libsym,tcpuprocdef(procdefinition).libsym.owner);
+      end;
+
     procedure ti386callnode.extra_interrupt_code;
       begin
         if not(target_info.system in [system_i386_darwin,system_i386_iphonesim,system_i386_android]) then

+ 10 - 5
compiler/i386/n386flw.pas

@@ -316,6 +316,7 @@ procedure ti386tryfinallynode.pass_generate_code;
     breakfinallylabel:=nil;
     exceptlabel:=nil;
     safecalllabel:=nil;
+    hreg:=NR_NO;
     is_safecall:=implicitframe and (current_procinfo.procdef.proccalloption=pocall_safecall);
 
     { check if child nodes do a break/continue/exit }
@@ -489,6 +490,12 @@ procedure ti386tryexceptnode.pass_generate_code;
       end;
     location_reset(location,LOC_VOID,OS_NO);
 
+    exceptflowcontrol:=[];
+    breakexceptlabel:=nil;
+    continueexceptlabel:=nil;
+    breaktrylabel:=nil;
+    continuetrylabel:=nil;
+
     oldflowcontrol:=flowcontrol;
     flowcontrol:=[fc_inflowcontrol];
     { this can be called recursivly }
@@ -528,7 +535,7 @@ procedure ti386tryexceptnode.pass_generate_code;
     { start of scope }
     if assigned(right) then
       begin
-        current_asmdata.getdatalabel(filterlabel);
+        current_asmdata.getaddrlabel(filterlabel);
         emit_scope_start(
           current_asmdata.RefAsmSymbol('__FPC_on_handler'),
           filterlabel);
@@ -602,8 +609,7 @@ procedure ti386tryexceptnode.pass_generate_code;
           begin
             if hnode.nodetype<>onn then
               InternalError(2011103101);
-            { TODO: make it done without using global label }
-            current_asmdata.getglobaljumplabel(onlabel);
+            current_asmdata.getjumplabel(onlabel);
             hlist.concat(tai_const.create_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
             hlist.concat(tai_const.create_sym(onlabel));
             cg.a_label(current_asmdata.CurrAsmList,onlabel);
@@ -619,8 +625,7 @@ procedure ti386tryexceptnode.pass_generate_code;
             inc(onnodecount.value);
           end;
         { now move filter table to permanent list all at once }
-        maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]);
-        current_asmdata.asmlists[al_typedconsts].concatlist(hlist);
+        current_procinfo.aktlocaldata.concatlist(hlist);
         hlist.free;
       end;
 

+ 58 - 1
compiler/i386/symcpu.pas

@@ -26,7 +26,7 @@ unit symcpu;
 interface
 
 uses
-  symtype,symdef,symsym,symx86,symi86;
+  symconst,symtype,symdef,symsym,symx86,symi86;
 
 type
   { defs }
@@ -91,6 +91,15 @@ type
   tcpuprocvardefclass = class of tcpuprocvardef;
 
   tcpuprocdef = class(ti86procdef)
+    procedure ppuload_platform(ppufile: tcompilerppufile); override;
+    procedure ppuwrite_platform(ppufile: tcompilerppufile); override;
+   public
+    { library symbol for AROS }
+    libsym : tsym;
+    libsymderef : tderef;
+    function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override;
+    procedure buildderef; override;
+    procedure deref; override;
   end;
   tcpuprocdefclass = class of tcpuprocdef;
 
@@ -170,6 +179,52 @@ const
 
 implementation
 
+{****************************************************************************
+                             tcpuprocdef
+****************************************************************************}
+
+  procedure tcpuprocdef.ppuload_platform(ppufile: tcompilerppufile);
+    begin
+      inherited;
+      if po_syscall_has_libsym in procoptions then
+        ppufile.getderef(libsymderef);
+    end;
+
+
+  procedure tcpuprocdef.ppuwrite_platform(ppufile: tcompilerppufile);
+    begin
+      inherited;
+      if po_syscall_has_libsym in procoptions then
+        ppufile.putderef(libsymderef);
+    end;
+
+
+  function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef;
+    begin
+      result:=inherited;
+      if newtyp=procdef then
+        tcpuprocdef(result).libsym:=libsym;
+    end;
+
+
+  procedure tcpuprocdef.buildderef;
+    begin
+      inherited;
+      if po_syscall_has_libsym in procoptions then
+        libsymderef.build(libsym);
+    end;
+
+
+  procedure tcpuprocdef.deref;
+    begin
+      inherited;
+      if po_syscall_has_libsym in procoptions then
+        libsym:=tsym(libsymderef.resolve)
+      else
+        libsym:=nil;
+    end;
+
+
 begin
   { used tdef classes }
   cfiledef:=tcpufiledef;
@@ -207,5 +262,7 @@ begin
   cconstsym:=tcpuconstsym;
   cenumsym:=tcpuenumsym;
   csyssym:=tcpusyssym;
+
+  cPtrDefHashSet:=tx86PtrDefHashSet;
 end.
 

+ 20 - 0
compiler/i8086/cpuinfo.pas

@@ -30,6 +30,9 @@ Interface
 
 Type
    bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TExtended80Rec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = extended;
@@ -66,8 +69,25 @@ Type
       fpu_avx2
      );
 
+   tcontrollertype =
+     (ct_none
+     );
+
 
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false;
+
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+
    { calling conventions supported by the code generator }
    supported_calling_conventions : tproccalloptions = [
      pocall_internproc,

+ 4 - 1
compiler/i8086/n8086add.pas

@@ -55,7 +55,7 @@ interface
     uses
       globtype,systems,
       cutils,verbose,globals,constexp,pass_1,
-      symconst,symdef,symtype,paramgr,defutil,
+      symconst,symdef,symtype,symcpu,paramgr,defutil,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       cgbase,procinfo,
       ncal,ncon,nset,cgutils,tgobj,
@@ -960,6 +960,9 @@ interface
       asmops: array[boolean] of tasmop = (A_IMUL, A_MUL);
 
     begin
+      reg:=NR_NO;
+      reference_reset(ref,sizeof(pint));
+
       pass_left_right;
 
       { MUL is faster than IMUL on the 8086 & 8088 (and equal in speed on 286+),

+ 43 - 3
compiler/i8086/n8086inl.pas

@@ -37,6 +37,7 @@ interface
          function first_seg: tnode; override;
          procedure second_seg; override;
          procedure second_get_frame;override;
+         function first_IncDec: tnode;override;
          procedure second_incdec;override;
        end;
 
@@ -51,10 +52,10 @@ implementation
     symconst,
     defutil,
     aasmbase,aasmtai,aasmdata,aasmcpu,
-    symtype,symdef,
-    cgbase,pass_2,
+    symtype,symdef,symcpu,
+    cgbase,pass_1,pass_2,
     cpuinfo,cpubase,paramgr,
-    nbas,ncon,ncal,ncnv,nld,ncgutil,
+    nbas,nadd,ncon,ncal,ncnv,nld,ncgutil,
     tgobj,
     cga,cgutils,cgx86,cgobj,hlcgobj,
     htypechk,procinfo;
@@ -138,6 +139,45 @@ implementation
            inherited second_get_frame;
        end;
 
+     function ti8086inlinenode.first_IncDec: tnode;
+       var
+         procname:string;
+         elesize: Tconstexprint;
+         hp: tnode;
+       begin
+         if is_hugepointer(tcallparanode(left).left.resultdef) then
+           begin
+             case inlinenumber of
+               in_inc_x:
+                 procname:='fpc_hugeptr_inc_longint';
+               in_dec_x:
+                 procname:='fpc_hugeptr_dec_longint';
+               else
+                 internalerror(2014121001);
+             end;
+             if cs_hugeptr_arithmetic_normalization in current_settings.localswitches then
+               procname:=procname+'_normalized';
+
+             if is_void(tpointerdef(tcallparanode(left).left.resultdef).pointeddef) then
+               elesize:=1
+             else
+               elesize:=tpointerdef(tcallparanode(left).left.resultdef).pointeddef.size;
+
+             hp := cordconstnode.create(elesize,s32inttype,false);
+             { extra parameter? }
+             if assigned(tcallparanode(left).right) then
+               hp:=caddnode.create(muln,hp,tcallparanode(tcallparanode(left).right).left.getcopy);
+
+             result:=ccallnode.createintern(procname,
+                       ccallparanode.create(hp,
+                       ccallparanode.create(tcallparanode(left).left.getcopy,nil)));
+             typecheckpass(result);
+             firstpass(result);
+           end
+         else
+           result:=inherited;
+       end;
+
      procedure ti8086inlinenode.second_incdec;
        const
          addsubop:array[in_inc_x..in_dec_x] of TOpCG=(OP_ADD,OP_SUB);

+ 1 - 0
compiler/i8086/n8086mat.pas

@@ -398,6 +398,7 @@ implementation
         hreg64hi:=left.location.register64.reghi;
         hreg64lo:=left.location.register64.reglo;
 
+        v:=0;
         if right.nodetype=ordconstn then
           v:=Tordconstnode(right).value and 63;
 

+ 46 - 4
compiler/i8086/n8086mem.pas

@@ -43,21 +43,23 @@ interface
 
        { tx86vecnode doesn't work for i8086, so we inherit tcgvecnode }
        ti8086vecnode = class(tcgvecnode)
+        protected
+         function first_arraydef: tnode;override;
          procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);override;
        end;
 
 implementation
 
     uses
-      systems,globals,
+      systems,globals,constexp,
       cutils,verbose,
-      symbase,symconst,symdef,symtable,symtype,symsym,symcpu,
+      symbase,symconst,symdef,symtable,symtype,symsym,symx86,symcpu,
       parabase,paramgr,
       aasmtai,aasmdata,
-      nld,ncon,nadd,
+      nld,ncon,nadd,ncal,ncnv,
       cgutils,cgobj,
       defutil,hlcgobj,
-      pass_2,ncgutil;
+      pass_1,pass_2,ncgutil;
 
 {*****************************************************************************
                              TI8086ADDRNODE
@@ -170,6 +172,46 @@ implementation
                              TI8086VECNODE
 *****************************************************************************}
 
+    function ti8086vecnode.first_arraydef: tnode;
+      var
+        arraydef: tcpuarraydef;
+        procname:string;
+      begin
+        if tcpuarraydef(left.resultdef).is_huge then
+          begin
+            arraydef:=tcpuarraydef(left.resultdef);
+
+            if not (ado_IsConvertedPointer in arraydef.arrayoptions) then
+              internalerror(2014080701);
+
+            if left.nodetype<>typeconvn then
+              internalerror(2014080702);
+
+            procname:='fpc_hugeptr_add_longint';
+            if cs_hugeptr_arithmetic_normalization in current_settings.localswitches then
+              procname:=procname+'_normalized';
+
+            if arraydef.elementdef.size>1 then
+              right:=caddnode.create(muln,right,
+                cordconstnode.create(arraydef.elementdef.size,s32inttype,true));
+
+            result:=ccallnode.createintern(procname,
+              ccallparanode.create(right,
+              ccallparanode.create(ttypeconvnode(left).left,nil)));
+            inserttypeconv_internal(result,getx86pointerdef(arraydef.elementdef,x86pt_huge));
+            result:=cderefnode.create(result);
+
+            ttypeconvnode(left).left:=nil;
+            ttypeconvnode(left).free;
+            left := nil;
+            right := nil;
+            firstpass(result);
+          end
+        else
+          result:=inherited;
+      end;
+
+
     procedure ti8086vecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint);
       var
         saveseg: TRegister;

+ 1 - 1
compiler/i8086/n8086tcon.pas

@@ -42,7 +42,7 @@ interface
 implementation
 
 uses
-  ncnv,defcmp,defutil,aasmtai;
+  ncnv,defcmp,defutil,aasmtai,symcpu;
 
     { ti8086typedconstbuilder }
 

+ 92 - 1
compiler/i8086/symcpu.pas

@@ -57,6 +57,7 @@ type
 
   tcpupointerdef = class(tx86pointerdef)
     class function default_x86_data_pointer_type: tx86pointertyp; override;
+    function pointer_arithmetic_int_type:tdef; override;
     function pointer_subtraction_result_type:tdef; override;
   end;
   tcpupointerdefclass = class of tcpupointerdef;
@@ -77,7 +78,19 @@ type
   end;
   tcpuclassrefdefclass = class of tcpuclassrefdef;
 
+  { tcpuarraydef }
+
   tcpuarraydef = class(tarraydef)
+   private
+    huge: Boolean;
+   protected
+    procedure ppuload_platform(ppufile: tcompilerppufile); override;
+    procedure ppuwrite_platform(ppufile: tcompilerppufile); override;
+   public
+    constructor create_from_pointer(def:tpointerdef);override;
+    function getcopy: tstoreddef; override;
+    function GetTypeName:string;override;
+    property is_huge: Boolean read huge write huge;
   end;
   tcpuarraydefclass = class of tcpuarraydef;
 
@@ -197,11 +210,16 @@ const
 
   function is_proc_far(p: tabstractprocdef): boolean;
 
+  {# Returns true if p is a far pointer def }
+  function is_farpointer(p : tdef) : boolean;
+
+  {# Returns true if p is a huge pointer def }
+  function is_hugepointer(p : tdef) : boolean;
 
 implementation
 
   uses
-    globals, cpuinfo, verbose;
+    globals, cpuinfo, verbose, fmodule;
 
 
   function is_proc_far(p: tabstractprocdef): boolean;
@@ -214,6 +232,68 @@ implementation
       internalerror(2014041301);
   end;
 
+  { true if p is a far pointer def }
+  function is_farpointer(p : tdef) : boolean;
+    begin
+      result:=(p.typ=pointerdef) and (tcpupointerdef(p).x86pointertyp=x86pt_far);
+    end;
+
+  { true if p is a huge pointer def }
+  function is_hugepointer(p : tdef) : boolean;
+    begin
+      result:=(p.typ=pointerdef) and (tcpupointerdef(p).x86pointertyp=x86pt_huge);
+    end;
+
+{****************************************************************************
+                               tcpuarraydef
+****************************************************************************}
+
+  constructor tcpuarraydef.create_from_pointer(def: tpointerdef);
+    begin
+      if tcpupointerdef(def).x86pointertyp=x86pt_huge then
+        begin
+          huge:=true;
+          { use -1 so that the elecount will not overflow }
+          self.create(0,high(asizeint)-1,s32inttype);
+          arrayoptions:=[ado_IsConvertedPointer];
+          setelementdef(def.pointeddef);
+        end
+      else
+        begin
+          huge:=false;
+          inherited create_from_pointer(def);
+        end;
+    end;
+
+
+  function tcpuarraydef.getcopy: tstoreddef;
+    begin
+      result:=inherited;
+      tcpuarraydef(result).huge:=huge;
+    end;
+
+
+  function tcpuarraydef.GetTypeName: string;
+    begin
+      Result:=inherited;
+      if is_huge then
+        Result:='Huge '+Result;
+    end;
+
+
+  procedure tcpuarraydef.ppuload_platform(ppufile: tcompilerppufile);
+    begin
+      inherited;
+      huge:=(ppufile.getbyte<>0);
+    end;
+
+
+  procedure tcpuarraydef.ppuwrite_platform(ppufile: tcompilerppufile);
+    begin
+      inherited;
+      ppufile.putbyte(byte(huge));
+    end;
+
 
 {****************************************************************************
                              tcpuprocdef
@@ -312,6 +392,15 @@ implementation
       end;
 
 
+    function tcpupointerdef.pointer_arithmetic_int_type:tdef;
+      begin
+        if x86pointertyp=x86pt_huge then
+          result:=s32inttype
+        else
+          result:=inherited;
+      end;
+
+
     function tcpupointerdef.pointer_subtraction_result_type:tdef;
       begin
         case x86pointertyp of
@@ -381,5 +470,7 @@ begin
   cconstsym:=tcpuconstsym;
   cenumsym:=tcpuenumsym;
   csyssym:=tcpusyssym;
+
+  cPtrDefHashSet:=tx86PtrDefHashSet;
 end.
 

+ 22 - 1
compiler/ia64/cpuinfo.pas

@@ -30,6 +30,9 @@ uses
 
 Type
    bestreal = extended;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TExtended80Rec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = extended;
@@ -49,7 +52,25 @@ Type
       fpu_itanium
      );
      
-const
+   tcontrollertype =
+     (ct_none
+     );
+
+
+Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false;
+
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+
    { calling conventions supported by the code generator }
    supported_calling_conventions : tproccalloptions = [
      pocall_internproc,

+ 1 - 1
compiler/impdef.pas

@@ -121,7 +121,7 @@ const
 {$ifdef unix}
   DirSep = '/';
 {$else}
-  {$if defined(amiga) or defined(morphos)}
+  {$ifdef hasamiga}
   DirSep = '/';
   {$else}
   DirSep = '\';

+ 20 - 0
compiler/jvm/cpuinfo.pas

@@ -21,6 +21,9 @@ Interface
 
 Type
    bestreal = double;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = extended;
@@ -44,8 +47,25 @@ Type
       fpu_standard
      );
 
+   tcontrollertype =
+     (ct_none
+     );
+
 
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false;
+
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+
    { calling conventions supported by the code generator }
    supported_calling_conventions : tproccalloptions = [
      pocall_internproc

+ 38 - 6
compiler/jvm/dbgjasm.pas

@@ -38,9 +38,10 @@ interface
       TDebugInfoJasmin=class(TDebugInfo)
       protected
         fcurrprocstart,
+        fcurrprocafterstart,
         fcurrprocend: tasmsymbol;
 
-        procedure appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym);
+        procedure appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym; startlab: tasmsymbol);
 
         procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
         procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
@@ -65,7 +66,7 @@ implementation
                               TDebugInfoJasmin
 ****************************************************************************}
 
-  procedure TDebugInfoJasmin.appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym);
+  procedure TDebugInfoJasmin.appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym; startlab: tasmsymbol);
     var
       jvar: tai_jvar;
       proc: tprocdef;
@@ -75,20 +76,20 @@ implementation
       if not(sym.localloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
         exit;
       proc:=tprocdef(sym.owner.defowner);
-      jvar:=tai_jvar.create(sym.localloc.reference.offset,jvmmangledbasename(sym,true),fcurrprocstart,fcurrprocend);
+      jvar:=tai_jvar.create(sym.localloc.reference.offset,jvmmangledbasename(sym,true),startlab,fcurrprocend);
       tcpuprocdef(proc).exprasmlist.InsertAfter(jvar,proc.procstarttai);
     end;
 
 
   procedure TDebugInfoJasmin.appendsym_paravar(list: TAsmList; sym: tparavarsym);
     begin
-      appendsym_localsym(list,sym);
+      appendsym_localsym(list,sym,fcurrprocstart);
     end;
 
 
   procedure TDebugInfoJasmin.appendsym_localvar(list: TAsmList; sym: tlocalvarsym);
     begin
-      appendsym_localsym(list,sym);
+      appendsym_localsym(list,sym,fcurrprocafterstart);
     end;
 
 
@@ -100,7 +101,11 @@ implementation
   procedure TDebugInfoJasmin.appendprocdef(list: TAsmList; def: tprocdef);
     var
       procstartlabel,
-      procendlabel    : tasmlabel;
+      procendlabel,
+      afterprocstartlabel : tasmlabel;
+      hp,
+      afterproccodestart  : tai;
+      instrcount          : longint;
     begin
       { insert debug information for local variables and parameters, but only
         for routines implemented in the Pascal code }
@@ -113,6 +118,33 @@ implementation
       tcpuprocdef(def).exprasmlist.insertbefore(tai_label.create(procendlabel),def.procendtai);
 
       fcurrprocstart:=procstartlabel;
+      { set the start label for local variables after the first instruction,
+        because javac's code completion support assumes that all info at
+        bytecode position 0 is for parameters }
+      instrcount:=0;
+      afterproccodestart:=def.procstarttai;
+      while assigned(afterproccodestart.next) do
+        begin
+          afterproccodestart:=tai(afterproccodestart.next);
+          if (afterproccodestart.typ=ait_instruction) then
+            break;
+        end;
+      { must be followed by at least one more instruction }
+      hp:=tai(afterproccodestart.next);
+      while assigned(hp) do
+        begin
+          if hp.typ=ait_instruction then
+            break;
+          hp:=tai(hp.next);
+        end;
+      if assigned(hp) then
+        begin
+          current_asmdata.getlabel(afterprocstartlabel,alt_dbgtype);
+          tcpuprocdef(def).exprasmlist.insertafter(tai_label.create(afterprocstartlabel),afterproccodestart);
+          fcurrprocafterstart:=afterprocstartlabel;
+        end
+      else
+        fcurrprocafterstart:=procstartlabel;
       fcurrprocend:=procendlabel;
 
       write_symtable_parasyms(list,def.paras);

+ 6 - 0
compiler/jvm/njvmflw.pas

@@ -340,6 +340,12 @@ implementation
          reasonbuf,
          exceptreg: tregister;
       begin
+         oldBreakLabel:=nil;
+         oldContinueLabel:=nil;
+         finallycodecopy:=nil;
+         continuefinallylabel:=nil;
+         breakfinallylabel:=nil;
+
          { not necessary on a garbage-collected platform }
          if implicitframe then
            internalerror(2011031803);

+ 4 - 2
compiler/jvm/njvminl.pas

@@ -87,13 +87,13 @@ implementation
 
     function tjvminlinenode.typecheck_length(var handled: boolean): tnode;
       begin
+        result:=nil;
         typecheckpass(left);
         if is_open_array(left.resultdef) or
            is_dynamic_array(left.resultdef) or
            is_array_of_const(left.resultdef) then
           begin
             resultdef:=s32inttype;
-            result:=nil;
             handled:=true;
           end;
       end;
@@ -101,6 +101,7 @@ implementation
 
     function tjvminlinenode.typecheck_high(var handled: boolean): tnode;
       begin
+        result:=nil;
         typecheckpass(left);
         if is_dynamic_array(left.resultdef) or
            is_open_array(left.resultdef) or
@@ -120,6 +121,7 @@ implementation
         para: tcallparanode;
         elemdef: tdef;
       begin
+        result:=nil;
         { normally never exists; used by the JVM backend to create new
           arrays because it requires special opcodes }
         tcallparanode(left).get_paratype;
@@ -150,7 +152,6 @@ implementation
                 para:=tcallparanode(para.right);
                 elemdef:=tarraydef(elemdef).elementdef;
               end;
-            result:=nil;
             resultdef:=left.resultdef;
             handled:=true;
           end;
@@ -289,6 +290,7 @@ implementation
       var
         handled: boolean;
       begin
+         result:=nil;
          handled:=false;
          case inlinenumber of
            in_length_x:

+ 2 - 0
compiler/jvm/njvmmem.pas

@@ -361,6 +361,8 @@ implementation
         newsize: tcgsize;
         isjump: boolean;
       begin
+        otl:=nil;
+        ofl:=nil;
         if left.resultdef.typ=stringdef then
           internalerror(2011052702);
 

+ 3 - 0
compiler/jvm/njvmutil.pas

@@ -75,6 +75,9 @@ implementation
       paras: tcallparanode;
       proc: string;
     begin
+      result:=nil;
+      proc:='';
+      temp:=nil;
       if not assigned(p.resultdef) then
         typecheckpass(p);
       if ((p.resultdef.typ=stringdef) and

+ 4 - 4
compiler/jvm/tgcpu.pas

@@ -46,7 +46,7 @@ unit tgcpu;
         public
          procedure setfirsttemp(l : longint); override;
          procedure getlocal(list: TAsmList; size: longint; alignment: shortint; def: tdef; var ref: treference); override;
-         procedure gethltemp(list: TAsmList; def: tdef; forcesize: aint; temptype: ttemptype; out ref: treference); override;
+         procedure gethltemp(list: TAsmList; def: tdef; forcesize: asizeint; temptype: ttemptype; out ref: treference); override;
          procedure gethltemptyped(list: TAsmList; def: tdef; temptype: ttemptype; out ref: treference); override;
        end;
 
@@ -145,8 +145,8 @@ unit tgcpu;
                       if tprocsym(sym).procdeflist.Count<>1 then
                         internalerror(2011062801);
                       pd:=tprocdef(tprocsym(sym).procdeflist[0]);
+                      hlcg.a_call_name(list,pd,pd.mangledname,nil,false);
                     end;
-                  hlcg.a_call_name(list,pd,pd.mangledname,nil,false);
                   { static calls method replaces parameter with set instance
                     -> no change in stack height }
                 end
@@ -202,8 +202,8 @@ unit tgcpu;
                       if tprocsym(sym).procdeflist.Count<>1 then
                         internalerror(2011052404);
                       pd:=tprocdef(tprocsym(sym).procdeflist[0]);
+                      hlcg.a_call_name(list,pd,pd.mangledname,nil,false);
                     end;
-                  hlcg.a_call_name(list,pd,pd.mangledname,nil,false);
                   { static calls method replaces parameter with string instance
                     -> no change in stack height }
                   { store reference to instance }
@@ -245,7 +245,7 @@ unit tgcpu;
       end;
 
 
-    procedure ttgjvm.gethltemp(list: TAsmList; def: tdef; forcesize: aint; temptype: ttemptype; out ref: treference);
+    procedure ttgjvm.gethltemp(list: TAsmList; def: tdef; forcesize: asizeint; temptype: ttemptype; out ref: treference);
       begin
         if not getifspecialtemp(list,def,forcesize,temptype,ref) then
           inherited;

+ 20 - 8
compiler/m68k/aasmcpu.pas

@@ -464,6 +464,7 @@ type
         result:=operand_read;
 
         case opcode of
+          // CPU opcodes
           A_MOVE, A_MOVEQ, A_MOVEA, A_MVZ, A_MVS, A_MOV3Q, A_LEA:
             if opnr=1 then
               result:=operand_write;
@@ -479,10 +480,21 @@ type
           A_CLR, A_SXX, A_SEQ, A_SNE, A_SLT, A_SLE, A_SGT, A_SGE, A_SCS, A_SCC,
           A_SMI, A_SPL, A_SF, A_ST, A_SVS, A_SVC, A_SHI, A_SLS:
             result:=operand_write;
-          A_NEG, A_NEGX, A_EXT, A_EXTB, A_NOT:
+          A_NEG, A_NEGX, A_EXT, A_EXTB, A_NOT, A_SWAP:
             result:=operand_readwrite;
           A_TST,A_CMP,A_CMPI:
             begin end; { Do nothing, default operand_read is fine here. }
+
+          // FPU opcodes
+          A_FMOVE:
+             if opnr=1 then
+               result:=operand_write;
+          A_FADD, A_FSUB, A_FMUL, A_FDIV:
+             if opnr=1 then
+               result:=operand_readwrite;
+          A_FCMP:
+             begin end; { operand_read }
+
           else begin
             internalerror(2004040903);
           end;
@@ -508,17 +520,17 @@ type
 
     function spilling_create_store(r:tregister; const ref:treference):Taicpu;
       begin
-	case getregtype(r) of
-	  R_INTREGISTER :
-	    result:=taicpu.op_reg_ref(A_MOVE,S_L,r,ref);
-	  R_ADDRESSREGISTER :
-	    result:=taicpu.op_reg_ref(A_MOVE,S_L,r,ref);
-	  R_FPUREGISTER :
+        case getregtype(r) of
+          R_INTREGISTER :
+            result:=taicpu.op_reg_ref(A_MOVE,S_L,r,ref);
+          R_ADDRESSREGISTER :
+            result:=taicpu.op_reg_ref(A_MOVE,S_L,r,ref);
+          R_FPUREGISTER :
             // no need to handle sizes here
             result:=taicpu.op_reg_ref(A_FMOVE,S_FS,r,ref);
           else
             internalerror(200602012);
-	end;
+        end;
       end;
 
 

+ 173 - 59
compiler/m68k/cgcpu.pas

@@ -108,6 +108,7 @@ unit cgcpu;
      tcg64f68k = class(tcg64f32)
        procedure a_op64_reg_reg(list : TAsmList;op:TOpCG; size: tcgsize; regsrc,regdst : tregister64);override;
        procedure a_op64_const_reg(list : TAsmList;op:TOpCG; size: tcgsize; value : int64;regdst : tregister64);override;
+       procedure a_op64_ref_reg(list : TAsmList;op:TOpCG;size : tcgsize;const ref : treference;reg : tregister64);override;
      end;
 
      { This function returns true if the reference+offset is valid.
@@ -377,8 +378,9 @@ unit cgcpu;
         if use_push(cgpara) then
           begin
             { Record copy? }
-            if (cgpara.size in [OS_NO,OS_F64]) or (size=OS_NO) then
+            if (cgpara.size in [OS_NO,OS_F64]) or (size in [OS_NO,OS_F64]) then
               begin
+                //list.concat(tai_comment.create(strpnew('a_load_ref_cgpara: g_concatcopy')));
                 cgpara.check_simple_location;
                 len:=align(cgpara.intsize,cgpara.alignment);
                 g_stackpointer_alloc(list,len);
@@ -751,7 +753,11 @@ unit cgcpu;
            list.concat(taicpu.op_reg(A_CLR,S_L,register))
         else
          begin
-           if (longint(a) >= low(shortint)) and (longint(a) <= high(shortint)) then
+           { Prefer MOV3Q if applicable, it allows replacement spilling for register }
+           if (current_settings.cputype in [cpu_isa_b,cpu_isa_c]) and
+             ((longint(a)=-1) or ((longint(a)>0) and (longint(a)<8))) then
+             list.concat(taicpu.op_const_reg(A_MOV3Q,S_L,longint(a),register))
+           else if (longint(a) >= low(shortint)) and (longint(a) <= high(shortint)) then
               list.concat(taicpu.op_const_reg(A_MOVEQ,S_L,longint(a),register))
            else
              begin
@@ -786,11 +792,18 @@ unit cgcpu;
         hreg : tregister;
         href : treference;
       begin
+        a:=longint(a);
         href:=ref;
         fixref(list,href);
+        if (a=0) and not (current_settings.cputype = cpu_mc68000) then
+          list.concat(taicpu.op_ref(A_CLR,tcgsize2opsize[tosize],href))
+        else if (tcgsize2opsize[tosize]=S_L) and
+           (current_settings.cputype in [cpu_isa_b,cpu_isa_c]) and
+           ((a=-1) or ((a>0) and (a<8))) then
+          list.concat(taicpu.op_const_ref(A_MOV3Q,S_L,a,href))
         { for coldfire we need to go through a temporary register if we have a
           offset, index or symbol given }
-        if (current_settings.cputype in cpu_coldfire) and
+        else if (current_settings.cputype in cpu_coldfire) and
             (
               (href.offset<>0) or
               { TODO : check whether we really need this second condition }
@@ -902,10 +915,13 @@ unit cgcpu;
       var
         instr : taicpu;
       begin
-         { move to destination register }
-         instr:=taicpu.op_reg_reg(A_MOVE,TCGSize2OpSize[fromsize],reg1,reg2);
-         add_move_instruction(instr);
-         list.concat(instr);
+        { move to destination register }
+        if (reg1<>reg2) then
+          begin
+            instr:=taicpu.op_reg_reg(A_MOVE,TCGSize2OpSize[fromsize],reg1,reg2);
+            add_move_instruction(instr);
+            list.concat(instr);
+          end;
          sign_extend(list, fromsize, reg2);
       end;
 
@@ -923,17 +939,25 @@ unit cgcpu;
            size:=tosize;
          list.concat(taicpu.op_ref_reg(A_MOVE,TCGSize2OpSize[size],href,register));
          { extend the value in the register }
-         sign_extend(list, fromsize, register);
+         sign_extend(list, size, register);
       end;
 
 
     procedure tcg68k.a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);
       var
         href : treference;
+        hreg : tregister;
       begin
         href:=ref;
         fixref(list, href);
-        list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,r));
+        if not isaddressregister(r) then
+          begin
+            hreg:=getaddressregister(list);
+            list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,hreg));
+            a_load_reg_reg(list, OS_ADDR, OS_ADDR, hreg, r);
+          end
+        else
+          list.concat(taicpu.op_ref_reg(A_LEA,S_L,href,r));
       end;
 
 
@@ -941,20 +965,16 @@ unit cgcpu;
       var
         instr : taicpu;
       begin
-        { in emulation mode, only 32-bit single is supported }
-        if (cs_fp_emulation in current_settings.moduleswitches) or (current_settings.fputype=fpu_soft) then
-          instr:=taicpu.op_reg_reg(A_MOVE,S_L,reg1,reg2)
-        else
-          instr:=taicpu.op_reg_reg(A_FMOVE,tcgsize2opsize[tosize],reg1,reg2);
-         add_move_instruction(instr);
-         list.concat(instr);
+        instr:=taicpu.op_reg_reg(A_FMOVE,S_FX,reg1,reg2);
+        add_move_instruction(instr);
+        list.concat(instr);
       end;
 
 
     procedure tcg68k.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister);
-     var
-      opsize : topsize;
-      href : treference;
+      var
+        opsize : topsize;
+        href : treference;
       begin
         opsize := tcgsize2opsize[fromsize];
         { extended is not supported, since it is not available on Coldfire }
@@ -962,50 +982,44 @@ unit cgcpu;
           internalerror(20020729);
         href := ref;
         fixref(list,href);
-        { in emulation mode, only 32-bit single is supported }
-        if (cs_fp_emulation in current_settings.moduleswitches) or (current_settings.fputype=fpu_soft) then
-           list.concat(taicpu.op_ref_reg(A_MOVE,S_L,href,reg))
-        else
-           begin
-             list.concat(taicpu.op_ref_reg(A_FMOVE,opsize,href,reg));
-             if (tosize < fromsize) then
-               a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg);
-           end;
+        list.concat(taicpu.op_ref_reg(A_FMOVE,opsize,href,reg));
       end;
 
     procedure tcg68k.a_loadfpu_reg_ref(list: TAsmList; fromsize,tosize: tcgsize; reg: tregister; const ref: treference);
       var
-       opsize : topsize;
+        opsize : topsize;
+        href : treference;
       begin
         opsize := tcgsize2opsize[tosize];
         { extended is not supported, since it is not available on Coldfire }
         if opsize = S_FX then
           internalerror(20020729);
-        { in emulation mode, only 32-bit single is supported }
-        if (cs_fp_emulation in current_settings.moduleswitches) or (current_settings.fputype=fpu_soft) then
-          list.concat(taicpu.op_reg_ref(A_MOVE,S_L,reg, ref))
-        else
-          list.concat(taicpu.op_reg_ref(A_FMOVE,opsize,reg, ref));
+        href := ref;
+        fixref(list,href);
+        list.concat(taicpu.op_reg_ref(A_FMOVE,opsize,reg,href));
       end;
 
 
     procedure tcg68k.a_loadfpu_ref_cgpara(list : TAsmList; size : tcgsize;const ref : treference;const cgpara : TCGPara);
       begin
-        case cgpara.location^.loc of
-          LOC_REFERENCE,LOC_CREFERENCE:
-            begin
-              case size of
-                OS_F64:
-                  cg64.a_load64_ref_cgpara(list,ref,cgpara);
-                OS_F32:
-                  a_load_ref_cgpara(list,size,ref,cgpara);
-                else
-                  internalerror(2013021201);
+        if current_settings.fputype = fpu_soft then
+          case cgpara.location^.loc of
+            LOC_REFERENCE,LOC_CREFERENCE:
+              begin
+                case size of
+                  OS_F64:
+                    cg64.a_load64_ref_cgpara(list,ref,cgpara);
+                  OS_F32:
+                    a_load_ref_cgpara(list,size,ref,cgpara);
+                  else
+                    internalerror(2013021201);
+                end;
               end;
-            end;
-          else
-            inherited a_loadfpu_ref_cgpara(list,size,ref,cgpara);
-        end;
+            else
+              inherited a_loadfpu_ref_cgpara(list,size,ref,cgpara);
+          end
+        else
+          inherited a_loadfpu_ref_cgpara(list,size,ref,cgpara);
       end;
 
 
@@ -1100,10 +1114,41 @@ unit cgcpu;
               begin
                 scratch_reg := force_to_dataregister(list, size, reg);
                 sign_extend(list, size, scratch_reg);
-                if (a >= 1) and (a <= 8) then
+
+                { some special cases which can generate smarter code 
+                  using the SWAP instruction }
+                if (a = 16) then
+                  begin
+                    if (op = OP_SHL) then
+                      begin
+                        list.concat(taicpu.op_reg(A_SWAP,S_NO,scratch_reg));
+                        list.concat(taicpu.op_reg(A_CLR,S_W,scratch_reg));
+                      end
+                    else if (op = OP_SHR) then
+                      begin
+                        list.concat(taicpu.op_reg(A_CLR,S_W,scratch_reg));
+                        list.concat(taicpu.op_reg(A_SWAP,S_NO,scratch_reg));
+                      end
+                    else if (op = OP_SAR) then
+                      begin
+                        list.concat(taicpu.op_reg(A_SWAP,S_NO,scratch_reg));
+                        list.concat(taicpu.op_reg(A_EXT,S_L,scratch_reg));
+                      end
+                    else if (op = OP_ROR) or (op = OP_ROL) then
+                      list.concat(taicpu.op_reg(A_SWAP,S_NO,scratch_reg))
+                  end
+                else if (a >= 1) and (a <= 8) then
                   begin
                     list.concat(taicpu.op_const_reg(opcode, S_L, a, scratch_reg));
                   end
+                else if (a >= 9) and (a < 16) then
+                  begin
+                    { Use two ops instead of const -> reg + shift with reg, because
+                      this way is the same in length and speed but has less register
+                      pressure }
+                    list.concat(taicpu.op_const_reg(opcode, S_L, 8, scratch_reg));
+                    list.concat(taicpu.op_const_reg(opcode, S_L, a-8, scratch_reg));
+                  end
                 else
                   begin
                     { move const to a register first }
@@ -1398,6 +1443,13 @@ unit cgcpu;
 
     procedure tcg68k.a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel);
       begin
+         if (current_settings.cputype in cpu_coldfire-[cpu_isa_b,cpu_isa_c]) then
+           begin
+             sign_extend(list,size,reg1);
+             sign_extend(list,size,reg2);
+             size:=OS_INT;
+           end;
+
          list.concat(taicpu.op_reg_reg(A_CMP,tcgsize2opsize[size],reg1,reg2));
          { emit the actual jump to the label }
          a_jmp_cond(list,cmp_op,l);
@@ -1473,10 +1525,8 @@ unit cgcpu;
          hp2 : treference;
          hl : tasmlabel;
          srcref,dstref : treference;
-         orglen : tcgint;
       begin
          hregister := getintregister(list,OS_INT);
-         orglen:=len;
 
          { from 12 bytes movs is being used }
          if ((len<=8) or (not(cs_opt_size in current_settings.optimizerswitches) and (len<=12))) then
@@ -1568,7 +1618,28 @@ unit cgcpu;
     end;
 
     procedure tcg68k.g_overflowcheck(list: TAsmList; const l:tlocation; def:tdef);
+      var
+        hl : tasmlabel;
+        ai : taicpu;
+        cond : TAsmCond;
       begin
+        if not(cs_check_overflow in current_settings.localswitches) then
+          exit;
+        current_asmdata.getjumplabel(hl);
+        if not ((def.typ=pointerdef) or
+               ((def.typ=orddef) and
+                (torddef(def).ordtype in [u64bit,u16bit,u32bit,u8bit,uchar,
+                                          pasbool8,pasbool16,pasbool32,pasbool64]))) then
+          cond:=C_VC
+        else
+          cond:=C_CC;
+        ai:=Taicpu.Op_Sym(A_Bxx,S_NO,hl);
+        ai.SetCondition(cond);
+        ai.is_jmp:=true;
+        list.concat(ai);
+
+        a_call_name(list,'FPC_OVERFLOW',false);
+        a_label(list,hl);
       end;
 
     procedure tcg68k.g_proc_entry(list: TAsmList; localsize: longint; nostackframe:boolean);
@@ -1582,13 +1653,13 @@ unit cgcpu;
             if (localsize < 0) then
               internalerror(2006122601);
 
-            { Not to complicate the code generator too much, and since some }
-            { of the systems only support this format, the localsize cannot }
-            { exceed 32K in size.                                           }
             if (localsize > high(smallint)) then
-              CGMessage(cg_e_localsize_too_big);
-
-            list.concat(taicpu.op_reg_const(A_LINK,S_W,NR_FRAME_POINTER_REG,-localsize));
+              begin
+                list.concat(taicpu.op_reg_const(A_LINK,S_W,NR_FRAME_POINTER_REG,0));
+                list.concat(taicpu.op_const_reg(A_SUBA,S_L,localsize,NR_STACK_POINTER_REG));
+              end
+            else
+              list.concat(taicpu.op_reg_const(A_LINK,S_W,NR_FRAME_POINTER_REG,-localsize));
           end;
       end;
 
@@ -1698,6 +1769,7 @@ unit cgcpu;
 
         { calculate temp. size }
         size:=0;
+        hreg:=NR_NO;
         for r:=low(saved_standard_registers) to high(saved_standard_registers) do
           if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
             begin
@@ -1724,9 +1796,16 @@ unit cgcpu;
             include(current_procinfo.flags,pi_has_saved_regs);
 
             { Copy registers to temp }
+            { NOTE: virtual registers allocated here won't be translated --> no higher-level stuff. }
             href:=current_procinfo.save_regs_ref;
+            if (href.offset<low(smallint)) and (current_settings.cputype in cpu_coldfire) then
+              begin
+                list.concat(taicpu.op_reg_reg(A_MOVE,S_L,href.base,NR_A0));
+                list.concat(taicpu.op_const_reg(A_ADDA,S_L,href.offset,NR_A0));
+                reference_reset_base(href,NR_A0,0,sizeof(pint));
+              end;
             if size = sizeof(aint) then
-              a_load_reg_ref(list, OS_32, OS_32, hreg, href)
+              list.concat(taicpu.op_reg_ref(A_MOVE,S_L,hreg,href))
             else
               list.concat(taicpu.op_regset_ref(A_MOVEM,S_L,dataregs,addrregs,href));
           end;
@@ -1750,6 +1829,7 @@ unit cgcpu;
           exit;
         { Copy registers from temp }
         size:=0;
+        hreg:=NR_NO;
         for r:=low(saved_standard_registers) to high(saved_standard_registers) do
           if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
             begin
@@ -1777,8 +1857,14 @@ unit cgcpu;
 
         { Restore registers from temp }
         href:=current_procinfo.save_regs_ref;
+        if (href.offset<low(smallint)) and (current_settings.cputype in cpu_coldfire) then
+          begin
+            list.concat(taicpu.op_reg_reg(A_MOVE,S_L,href.base,NR_A0));
+            list.concat(taicpu.op_const_reg(A_ADDA,S_L,href.offset,NR_A0));
+            reference_reset_base(href,NR_A0,0,sizeof(pint));
+          end;
         if size = sizeof(aint) then
-          a_load_ref_reg(list, OS_32, OS_32, href, hreg)
+          list.concat(taicpu.op_ref_reg(A_MOVE,S_L,href,hreg))
         else
           list.concat(taicpu.op_ref_regset(A_MOVEM,S_L,href,dataregs,addrregs));
 
@@ -2097,6 +2183,34 @@ unit cgcpu;
       end;
 
 
+    procedure tcg64f68k.a_op64_ref_reg(list : TAsmList;op:TOpCG;size : tcgsize;const ref : treference;reg : tregister64);
+      var
+        tempref : treference;
+      begin
+        case op of
+          OP_NEG,OP_NOT:
+            begin
+              a_load64_ref_reg(list,ref,reg);
+              a_op64_reg_reg(list,op,size,reg,reg);
+            end;
+
+          OP_AND,OP_OR:
+            begin
+              tempref:=ref;
+              tcg68k(cg).fixref(list,tempref);
+              inc(tempref.offset,4);
+              list.concat(taicpu.op_ref_reg(topcg2tasmop[op],S_L,tempref,reg.reglo));
+              dec(tempref.offset,4);
+              list.concat(taicpu.op_ref_reg(topcg2tasmop[op],S_L,tempref,reg.reghi));
+            end;
+        else
+          { XOR does not allow reference for source; ADD/SUB do not allow reference for
+            high dword, although low dword can still be handled directly. }
+          inherited a_op64_ref_reg(list,op,size,ref,reg);
+        end;
+      end;
+
+
     procedure tcg64f68k.a_op64_const_reg(list : TAsmList;op:TOpCG;size: tcgsize; value : int64;regdst : tregister64);
       var
         lowvalue : cardinal;

+ 6 - 3
compiler/m68k/cpubase.pas

@@ -67,7 +67,7 @@ unit cpubase;
          { mc64040 instructions }
          a_move16,
          { coldfire v4 instructions }
-         a_mov3q,a_mvz,a_mvs,a_sats,
+         a_mov3q,a_mvz,a_mvs,a_sats,a_byterev,a_ff1,
          { fpu processor instructions - directly supported only. }
          { ieee aware and misc. condition codes not supported   }
          a_fabs,a_fadd,
@@ -153,7 +153,7 @@ unit cpubase;
 
       { registers which may be destroyed by calls }
       VOLATILE_INTREGISTERS = [RS_D0,RS_D1];
-      VOLATILE_FPUREGISTERS = [];
+      VOLATILE_FPUREGISTERS = [RS_FP0,RS_FP1];
       VOLATILE_ADDRESSREGISTERS = [RS_A0,RS_A1];
 
     type
@@ -311,6 +311,7 @@ unit cpubase;
       }
       saved_standard_registers : array[0..5] of tsuperregister = (RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7);
       saved_address_registers : array[0..4] of tsuperregister = (RS_A2,RS_A3,RS_A4,RS_A5,RS_A6);
+      saved_fpu_registers : array[0..5] of tsuperregister = (RS_FP2,RS_FP3,RS_FP4,RS_FP5,RS_FP6,RS_FP7);
 
       { this is only for the generic code which is not used for this architecture }
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
@@ -471,7 +472,9 @@ implementation
           R_INTREGISTER :
             result:=OS_32;
           R_FPUREGISTER :
-            result:=OS_F64;
+            { 68881 & compatibles -> 80 bit }
+            { CF FPU -> 64 bit, but that's unsupported for now }
+            result:=OS_F80;
           else
             internalerror(200303181);
         end;

+ 29 - 6
compiler/m68k/cpuinfo.pas

@@ -21,6 +21,9 @@ Interface
 
 Type
    bestreal = double;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = extended;
@@ -48,7 +51,25 @@ Type
       fpu_68881
      );
 
+   tcontrollertype =
+     (ct_none
+     );
+
+
 Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false;
+
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+
    { calling conventions supported by the code generator }
    supported_calling_conventions : tproccalloptions = [
      pocall_internproc,
@@ -107,19 +128,21 @@ type
      (CPUM68K_HAS_DBRA,      { CPU supports the DBRA instruction                         }
       CPUM68K_HAS_CAS,       { CPU supports the CAS instruction                          }
       CPUM68K_HAS_TAS,       { CPU supports the TAS instruction                          }
-      CPUM68K_HAS_BRAL       { CPU supports the BRA.L/Bcc.L instructions                 }
+      CPUM68K_HAS_BRAL,      { CPU supports the BRA.L/Bcc.L instructions                 }
+      CPUM68K_HAS_ROLROR,    { CPU supports the ROL/ROR and ROXL/ROXR instructions       }
+      CPUM68K_HAS_BYTEREV    { CPU supports the BYTEREV instruction                      }
      );
 
 const
   cpu_capabilities : array[tcputype] of set of tcpuflags =
     ( { cpu_none     } [],
-      { cpu_68000    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_TAS],
-      { cpu_68020    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL],
-      { cpu_68040    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL],
+      { cpu_68000    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_TAS,CPUM68K_HAS_ROLROR],
+      { cpu_68020    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_ROLROR],
+      { cpu_68040    } [CPUM68K_HAS_DBRA,CPUM68K_HAS_CAS,CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL,CPUM68K_HAS_ROLROR],
       { cpu_isaa     } [],
-      { cpu_isaap    } [CPUM68K_HAS_BRAL],
+      { cpu_isaap    } [CPUM68K_HAS_BRAL,CPUM68K_HAS_BYTEREV],
       { cpu_isab     } [CPUM68K_HAS_TAS,CPUM68K_HAS_BRAL],
-      { cpu_isac     } [CPUM68K_HAS_TAS]
+      { cpu_isac     } [CPUM68K_HAS_TAS,CPUM68K_HAS_BYTEREV]
     );
 
   { all CPUs commonly called "coldfire" }

+ 1 - 1
compiler/m68k/itcpugas.pas

@@ -61,7 +61,7 @@ interface
          { mc64040 instructions }
          'move16',
          { coldfire v4 instructions }
-         'mov3q','mvz','mvs','sats',
+         'mov3q','mvz','mvs','sats','byterev','ff1',
          { fpu processor instructions - directly supported only. }
          { ieee aware and misc. condition codes not supported   }
          'fabs','fadd',

+ 268 - 494
compiler/m68k/n68kadd.pas

@@ -32,23 +32,13 @@ interface
     type
        t68kaddnode = class(tcgaddnode)
        private
-          function cmp64_lt(left_reg,right_reg:tregister64):tregister;
-          function cmp64_le(left_reg,right_reg:tregister64):tregister;
-          function cmp64_eq(left_reg,right_reg:tregister64):tregister;
-          function cmp64_ne(left_reg,right_reg:tregister64):tregister;
-          function cmp64_ltu(left_reg,right_reg:tregister64):tregister;
-          function cmp64_leu(left_reg,right_reg:tregister64):tregister;
-
           function getresflags(unsigned: boolean) : tresflags;
-          function getres64_register(unsigned:boolean;left_reg,right_reg:tregister64):tregister;
        protected
           procedure second_addfloat;override;
           procedure second_cmpfloat;override;
           procedure second_cmpordinal;override;
           procedure second_cmpsmallset;override;
           procedure second_cmp64bit;override;
-       public
-          function pass_1:tnode;override;
        end;
 
 
@@ -62,198 +52,12 @@ implementation
       cpuinfo,pass_1,pass_2,regvars,
       cpupara,cgutils,procinfo,
       ncon,nset,
-      ncgutil,tgobj,rgobj,rgcpu,cgobj,hlcgobj,cg64f32;
+      ncgutil,tgobj,rgobj,rgcpu,cgobj,cgcpu,hlcgobj,cg64f32;
 
 {*****************************************************************************
                                   Helpers
 *****************************************************************************}
 
-    function t68kaddnode.cmp64_lt(left_reg,right_reg:tregister64):tregister;
-      var
-        labelcmp64_1,labelcmp64_2 : tasmlabel;
-        tmpreg : tregister;
-      begin
-        tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
-
-        { load the value for "false" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
-
-        current_asmdata.getjumplabel(labelcmp64_1);
-        current_asmdata.getjumplabel(labelcmp64_2);
-
-        { check whether left_reg.reghi is less than right_reg.reghi }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reghi,left_reg.reghi));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_LT,S_NO,labelcmp64_2));
-
-        { are left_reg.reghi and right_reg.reghi equal? }
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64_1));
-
-        { is left_reg.reglo less than right_reg.reglo? }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reglo,left_reg.reglo));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_2));
-
-        current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_NO,labelcmp64_1));
-        cg.a_label(current_asmdata.currasmlist,labelcmp64_2);
-
-        { load the value for "true" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
-
-        cg.a_label(current_asmdata.currasmlist,labelcmp64_1);
-        result:=tmpreg;
-      end;
-
-    function t68kaddnode.cmp64_le(left_reg,right_reg:tregister64):tregister;
-      var
-        labelcmp64_1,labelcmp64_2 : tasmlabel;
-        tmpreg : tregister;
-      begin
-        tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
-
-        { load the value for "false" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
-
-        current_asmdata.getjumplabel(labelcmp64_1);
-        current_asmdata.getjumplabel(labelcmp64_2);
-
-        { check whether right_reg.reghi is less than left_reg.reghi }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reghi,right_reg.reghi));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_LT,S_NO,labelcmp64_1));
-
-        { are left_reg.reghi and right_reg.reghi equal? }
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64_2));
-
-        { is right_reg.reglo less than left_reg.reglo? }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reglo,right_reg.reglo));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_1));
-
-        cg.a_label(current_asmdata.currasmlist,labelcmp64_2);
-
-        { load the value for "true" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
-
-        cg.a_label(current_asmdata.currasmlist,labelcmp64_1);
-        result:=tmpreg;
-      end;
-
-    function t68kaddnode.cmp64_eq(left_reg,right_reg:tregister64):tregister;
-      var
-        labelcmp64 : tasmlabel;
-        tmpreg : tregister;
-      begin
-        tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
-        current_asmdata.getjumplabel(labelcmp64);
-
-        { load the value for "false" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
-
-        { is the high order longword equal? }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reghi,right_reg.reghi));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64));
-
-        { is the low order longword equal? }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reglo,right_reg.reglo));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64));
-
-        { load the value for "true" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
-
-        cg.a_label(current_asmdata.currasmlist,labelcmp64);
-        result:=tmpreg;
-      end;
-
-    function t68kaddnode.cmp64_ne(left_reg,right_reg:tregister64):tregister;
-      var
-        labelcmp64 : tasmlabel;
-        tmpreg : tregister;
-      begin
-        tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
-        current_asmdata.getjumplabel(labelcmp64);
-
-        { load the value for "true" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
-
-        { is the high order longword equal? }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reghi,right_reg.reghi));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64));
-
-        { is the low order longword equal? }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reglo,right_reg.reglo));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64));
-
-        { load the value for "false" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
-
-        cg.a_label(current_asmdata.currasmlist,labelcmp64);
-        result:=tmpreg;
-      end;
-
-    function t68kaddnode.cmp64_ltu(left_reg,right_reg:tregister64):tregister;
-      var
-        labelcmp64_1,labelcmp64_2 : tasmlabel;
-        tmpreg : tregister;
-      begin
-        tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
-
-        { load the value for "false" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
-
-        current_asmdata.getjumplabel(labelcmp64_1);
-        current_asmdata.getjumplabel(labelcmp64_2);
-
-        { check whether left_reg.reghi is less than right_reg.reghi }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reghi,left_reg.reghi));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_2));
-
-        { are left_reg.reghi and right_reg.reghi equal? }
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64_1));
-
-        { is left_reg.reglo less than right_reg.reglo? }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reglo,left_reg.reglo));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_2));
-
-        current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_NO,labelcmp64_1));
-        cg.a_label(current_asmdata.currasmlist,labelcmp64_2);
-
-        { load the value for "true" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
-
-        cg.a_label(current_asmdata.currasmlist,labelcmp64_1);
-        result:=tmpreg;
-      end;
-
-    function t68kaddnode.cmp64_leu(left_reg,right_reg:tregister64):tregister;
-      var
-        labelcmp64_1,labelcmp64_2 : tasmlabel;
-        tmpreg : tregister;
-      begin
-        tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
-
-        { load the value for "false" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
-
-        current_asmdata.getjumplabel(labelcmp64_1);
-        current_asmdata.getjumplabel(labelcmp64_2);
-
-        { check whether right_reg.reghi is less than left_reg.reghi }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reghi,right_reg.reghi));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_1));
-
-        { are left_reg.reghi and right_reg.reghi equal? }
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64_2));
-
-        { is right_reg.reglo less than left_reg.reglo? }
-        current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reglo,right_reg.reglo));
-        current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_1));
-
-        cg.a_label(current_asmdata.currasmlist,labelcmp64_2);
-
-        { load the value for "true" }
-        cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
-
-        cg.a_label(current_asmdata.currasmlist,labelcmp64_1);
-        result:=tmpreg;
-      end;
-
     function t68kaddnode.getresflags(unsigned : boolean) : tresflags;
       begin
          case nodetype of
@@ -268,6 +72,8 @@ implementation
                      lten : getresflags:=F_GE;
                      gtn : getresflags:=F_L;
                      gten : getresflags:=F_LE;
+                     else
+                       internalerror(2014082030);
                   end
                 else
                   case nodetype of
@@ -275,6 +81,8 @@ implementation
                      lten : getresflags:=F_LE;
                      gtn : getresflags:=F_G;
                      gten : getresflags:=F_GE;
+                     else
+                       internalerror(2014082031);
                   end;
              end
            else
@@ -285,6 +93,8 @@ implementation
                      lten : getresflags:=F_AE;
                      gtn : getresflags:=F_B;
                      gten : getresflags:=F_BE;
+                     else
+                       internalerror(2014082032);
                   end
                 else
                   case nodetype of
@@ -292,71 +102,13 @@ implementation
                      lten : getresflags:=F_BE;
                      gtn : getresflags:=F_A;
                      gten : getresflags:=F_AE;
+                     else
+                       internalerror(2014082033);
                   end;
              end;
          end;
       end;
 
-    function t68kaddnode.getres64_register(unsigned:boolean;left_reg,right_reg:tregister64):tregister;
-      begin
-        case nodetype of
-          equaln:
-            result:=cmp64_eq(left_reg,right_reg);
-          unequaln:
-            result:=cmp64_ne(left_reg,right_reg);
-          else
-            if not unsigned then
-            begin
-              if nf_swapped in flags then
-                case nodetype of
-                  ltn:
-                    result:=cmp64_lt(right_reg,left_reg);
-                  lten:
-                    result:=cmp64_le(right_reg,left_reg);
-                  gtn:
-                    result:=cmp64_lt(left_reg,right_reg);
-                  gten:
-                    result:=cmp64_le(left_reg,right_reg);
-                end
-              else
-                case nodetype of
-                  ltn:
-                    result:=cmp64_lt(left_reg,right_reg);
-                  lten:
-                    result:=cmp64_le(left_reg,right_reg);
-                  gtn:
-                    result:=cmp64_lt(right_reg,left_reg);
-                  gten:
-                    result:=cmp64_le(right_reg,left_reg);
-                end;
-            end
-            else
-            begin
-              if nf_swapped in Flags then
-                case nodetype of
-                  ltn:
-                    result:=cmp64_ltu(right_reg,left_reg);
-                  lten:
-                    result:=cmp64_leu(right_reg,left_reg);
-                  gtn:
-                    result:=cmp64_ltu(left_reg,right_reg);
-                  gten:
-                    result:=cmp64_leu(left_reg,right_reg);
-                end
-              else
-                case nodetype of
-                  ltn:
-                    result:=cmp64_ltu(left_reg,right_reg);
-                  lten:
-                    result:=cmp64_leu(left_reg,right_reg);
-                  gtn:
-                    result:=cmp64_ltu(right_reg,left_reg);
-                  gten:
-                    result:=cmp64_leu(right_reg,left_reg);
-                end;
-            end;
-        end;
-      end;
 
 {*****************************************************************************
                                 AddFloat
@@ -386,56 +138,53 @@ implementation
         if nf_swapped in flags then
           swapleftright;
 
-        // put both operands in a register
-        hlcg.location_force_fpureg(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
-        hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+        case current_settings.fputype of
+          fpu_68881:
+            begin
+              // put both operands in a register
+              hlcg.location_force_fpureg(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
+              hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
 
-        // initialize de result
-        location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
-        if left.location.loc = LOC_FPUREGISTER then
-          location.register := left.location.register
-        else if right.location.loc = LOC_FPUREGISTER then
-          location.register := right.location.register
-        else
-          location.register := cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
-
-        // emit the actual operation
-        {
-          current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,
-            location.register,left.location.register,
-            right.location.register))
-        }
+              // initialize the result
+              location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
+              location.register := cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
+
+              // emit the actual operation
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FMOVE,S_FX,left.location.register,location.register));
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,S_FX,right.location.register,location.register));
+            end;
+          else
+            // softfpu should be handled in pass1, others are not yet supported...
+            internalerror(2015010201);
+        end;
       end;
 
 
     procedure t68kaddnode.second_cmpfloat;
       begin
         pass_left_right;
-
-{
         if (nf_swapped in flags) then
           swapleftright;
-}
-        { force fpureg as location, left right doesn't matter
-          as both will be in a fpureg }
-        hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
-        hlcg.location_force_fpureg(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
 
-        location_reset(location,LOC_FLAGS,OS_NO);
-        location.resflags:=getresflags(true);
-{
-        if nodetype in [equaln,unequaln] then
-          current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_CMF,
-             left.location.register,right.location.register),
-             cgsize2fpuoppostfix[def_cgsize(resultdef)]))
-        else
-          current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_CMFE,
-             left.location.register,right.location.register),
-             cgsize2fpuoppostfix[def_cgsize(resultdef)]));
+        case current_settings.fputype of
+          fpu_68881:
+            begin
+              location_reset(location,LOC_FLAGS,OS_NO);
 
-        location_reset(location,LOC_FLAGS,OS_NO);
-        location.resflags:=getresflags(false);
-}
+              { force fpureg as location, left right doesn't matter
+                as both will be in a fpureg }
+              hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+              hlcg.location_force_fpureg(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
+
+              // emit compare
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FCMP,S_FX,right.location.register,left.location.register));
+
+              location.resflags:=getresflags(false);
+            end;
+          else
+            // softfpu should be handled in pass1, others are not yet supported...
+            internalerror(2015010201);
+        end;
       end;
 
 
@@ -500,111 +249,92 @@ implementation
     procedure t68kaddnode.second_cmpordinal;
      var
       unsigned : boolean;
-      useconst : boolean;
       tmpreg : tregister;
       opsize : topsize;
       cmpsize : tcgsize;
+      href: treference;
      begin
-       pass_left_right;
-       { set result location }
-       location_reset(location,LOC_JUMP,OS_NO);
-
-       { ToDo : set "allowconstants" to True, but this seems to upset Coldfire
-                a bit for the CMP instruction => check manual and implement
-                exception accordingly below }
-       { load values into registers (except constants) }
-       force_reg_left_right(true, false);
-
        { determine if the comparison will be unsigned }
        unsigned:=not(is_signed(left.resultdef)) or
                    not(is_signed(right.resultdef));
+       { this puts constant operand (if any) to the right }
+       pass_left_right;
+       { tentatively assume left size (correct for possible TST, will fix later) }
+       cmpsize:=def_cgsize(left.resultdef);
+       opsize:=tcgsize2opsize[cmpsize];
 
-        // get the constant on the right if there is one
-        if (left.location.loc = LOC_CONSTANT) then
-          swapleftright;
-        // can we use an immediate, or do we have to load the
-        // constant in a register first?
-        if (right.location.loc = LOC_CONSTANT) then
-          begin
-{$ifdef extdebug}
-            if (right.location.size in [OS_64,OS_S64]) and (hi(right.location.value64)<>0) and ((hi(right.location.value64)<>-1) or unsigned) then
-              internalerror(2002080301);
-{$endif extdebug}
-            if (nodetype in [equaln,unequaln]) then
-              if (unsigned and
-                  (right.location.value > high(word))) or
-                 (not unsigned and
-                  (longint(right.location.value) < low(smallint)) or
-                   (longint(right.location.value) > high(smallint))) then
-                { we can then maybe use a constant in the 'othersigned' case
-                 (the sign doesn't matter for // equal/unequal)}
-                unsigned := not unsigned;
-
-            if (unsigned and
-                ((right.location.value) <= high(word))) or
-               (not(unsigned) and
-                (longint(right.location.value) >= low(smallint)) and
-                (longint(right.location.value) <= high(smallint))) then
-               useconst := true
-            else
-              begin
-                useconst := false;
-                tmpreg := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,
-                  aword(right.location.value),tmpreg);
-               end
-          end
-        else
-          useconst := false;
-        location.loc := LOC_FLAGS;
-        location.resflags := getresflags(unsigned);
-        if tcgsize2size[right.location.size]=tcgsize2size[left.location.size] then
-          cmpsize:=left.location.size
-        else
-          { ToDo : zero/sign extend??? }
-          if tcgsize2size[right.location.size]<tcgsize2size[left.location.size] then
-            cmpsize:=left.location.size
-          else
-            cmpsize:=right.location.size;
-        opsize:=tcgsize2opsize[cmpsize];
-        if opsize=S_NO then
-          internalerror(2013090301);
-        { Attention: The RIGHT(!) operand is substracted from and must be a
-                     register! }
-        if (right.location.loc = LOC_CONSTANT) then
-          if useconst then
-            current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,opsize,
-              longint(right.location.value),left.location.register))
-          else
-            begin
-              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,opsize,
-                tmpreg,left.location.register));
-            end
-        else
-          current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,opsize,
-            right.location.register,left.location.register));
-     end;
+       { set result location }
+       location_reset(location,LOC_FLAGS,OS_NO);
 
+       { see if we can optimize into TST }
+       if (right.location.loc=LOC_CONSTANT) and (right.location.value=0) then
+         begin
+           { Unsigned <0 or >=0 should not reach pass2, most likely }
+           case left.location.loc of
+             LOC_REFERENCE,
+             LOC_CREFERENCE:
+               begin
+                 href:=left.location.reference;
+                 tcg68k(cg).fixref(current_asmdata.CurrAsmList,href);
+                 current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_TST,opsize,href));
+                 location_freetemp(current_asmdata.CurrAsmList,left.location);
+               end;
+           else
+             hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
+             current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_TST,opsize,left.location.register));
+           end;
+           location.resflags := getresflags(unsigned);
+           exit;
+         end;
 
-    function t68kaddnode.pass_1:tnode;
-      var
-        ld,rd : tdef;
-      begin
-        result:=inherited pass_1;
+       { Coldfire supports byte/word compares only starting with ISA_B,
+         !!see remark about Qemu weirdness in tcg68k.a_cmp_const_reg_label }
+       if (opsize<>S_L) and (current_settings.cputype in cpu_coldfire{-[cpu_isa_b,cpu_isa_c]}) then
+         begin
+           { 1) Extension is needed for LOC_REFERENCE, but what about LOC_REGISTER ? Perhaps after fixing cg we can assume
+                that high bits of registers are correct.
+             2) Assuming that extension depends only on source signedness --> destination OS_32 is acceptable. }
+           hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,cgsize_orddef(OS_32),false);
+           if (right.location.loc<>LOC_CONSTANT) then
+             hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,cgsize_orddef(OS_32),false);
+           opsize:=S_L;
+         end
+       else if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+         begin
+           if not (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+             hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true)
+           else
+             begin
+               location_swap(left.location,right.location);
+               toggleflag(nf_swapped);
+             end;
+         end;
+       { left is now in register }
+       case right.location.loc of
+         LOC_CONSTANT:
+           current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,opsize,
+             longint(right.location.value),left.location.register));
+         LOC_REFERENCE,
+         LOC_CREFERENCE:
+           begin
+             href:=right.location.reference;
+             tcg68k(cg).fixref(current_asmdata.CurrAsmList,href);
+             current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_CMP,opsize,href,
+               left.location.register));
+           end;
+         LOC_REGISTER,
+         LOC_CREGISTER:
+           current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,opsize,
+             right.location.register,left.location.register));
+       else
+         hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
+         current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,opsize,
+           right.location.register,left.location.register));
+       end;
 
-        { for 64 bit operations we return the resulting value in a register }
-        if not assigned(result) then
-          begin
-            rd:=right.resultdef;
-            ld:=left.resultdef;
-            if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
-                (
-                  ((ld.typ=orddef) and (torddef(ld).ordtype in [u64bit,s64bit,scurrency])) or
-                  ((rd.typ=orddef) and (torddef(rd).ordtype in [u64bit,s64bit,scurrency]))
-                ) then
-              expectloc:=LOC_REGISTER;
-          end;
-      end;
+       { update location because sides could have been swapped }
+       location.resflags:=getresflags(unsigned);
+     end;
 
 
 {*****************************************************************************
@@ -613,123 +343,167 @@ implementation
 
     procedure t68kaddnode.second_cmp64bit;
       var
+        hlab: tasmlabel;
         unsigned : boolean;
-        tmp_left_reg : tregister;
+        href: treference;
+
+      procedure firstjmp64bitcmp;
+        var
+          oldnodetype : tnodetype;
+        begin
+          case nodetype of
+            ltn,gtn:
+              begin
+                if (hlab<>current_procinfo.CurrTrueLabel) then
+                  cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel);
+                { cheat a little bit for the negative test }
+                toggleflag(nf_swapped);
+                if (hlab<>current_procinfo.CurrFalseLabel) then
+                  cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel);
+                toggleflag(nf_swapped);
+              end;
+            lten,gten:
+              begin
+                oldnodetype:=nodetype;
+                if nodetype=lten then
+                  nodetype:=ltn
+                else
+                  nodetype:=gtn;
+                if (hlab<>current_procinfo.CurrTrueLabel) then
+                  cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel);
+                { cheat for the negative test }
+                if nodetype=ltn then
+                  nodetype:=gtn
+                else
+                  nodetype:=ltn;
+                if (hlab<>current_procinfo.CurrFalseLabel) then
+                  cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel);
+                nodetype:=oldnodetype;
+              end;
+            equaln:
+              cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrFalseLabel);
+            unequaln:
+              cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrTrueLabel);
+          end;
+        end;
+
+      procedure secondjmp64bitcmp;
+        begin
+          case nodetype of
+            ltn,gtn,lten,gten:
+              begin
+                cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),current_procinfo.CurrTrueLabel);
+                cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
+              end;
+            equaln:
+              begin
+                cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrFalseLabel);
+                cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel);
+              end;
+            unequaln:
+              begin
+                cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrTrueLabel);
+                cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
+              end;
+          end;
+        end;
+
       begin
+        { This puts constant operand (if any) to the right }
         pass_left_right;
-        force_reg_left_right(false,false);
 
         unsigned:=not(is_signed(left.resultdef)) or
                   not(is_signed(right.resultdef));
 
-        location_reset(location,LOC_REGISTER,OS_INT);
-        location.register:=getres64_register(unsigned,left.location.register64,right.location.register64);
-
-        { keep the below code for now, as we could optimize the =/<> code later
-          on based on it }
-
-      // writeln('second_cmp64bit');
-//      pass_left_right;
+        location_reset(location,LOC_JUMP,OS_NO);
 
+        { Relational compares against constants having low dword=0 can omit the
+          second compare based on the fact that any unsigned value is >=0 }
+        hlab:=nil;
+        if (right.location.loc=LOC_CONSTANT) and
+           (lo(right.location.value64)=0) then
+          begin
+            case getresflags(true) of
+              F_AE: hlab:=current_procinfo.CurrTrueLabel;
+              F_B:  hlab:=current_procinfo.CurrFalseLabel;
+            end;
+          end;
 
-//     load_left_right(true,false);
-(*
-        case nodetype of
-          ltn,lten,
-          gtn,gten:
-           begin
-             emit_cmp64_hi;
-             firstjmp64bitcmp;
-             emit_cmp64_lo;
-             secondjmp64bitcmp;
-           end;
-          equaln,unequaln:
-           begin
-             // instead of doing a complicated compare, do
-             // (left.hi xor right.hi) or (left.lo xor right.lo)
-             // (somewhate optimized so that no superfluous 'mr's are
-             //  generated)
-                  if (left.location.loc = LOC_CONSTANT) then
-                    swapleftright;
-                  if (right.location.loc = LOC_CONSTANT) then
-                    begin
-                      if left.location.loc = LOC_REGISTER then
-                        begin
-                          tempreg64.reglo := left.location.register64.reglo;
-                          tempreg64.reghi := left.location.register64.reghi;
-                        end
-                      else
-                        begin
-                          if (aword(right.location.valueqword) <> 0) then
-                            tempreg64.reglo := cg.getintregister(current_asmdata.CurrAsmList)
-                          else
-                            tempreg64.reglo := left.location.register64.reglo;
-                          if ((right.location.valueqword shr 32) <> 0) then
-                            tempreg64.reghi := cg.getintregister(current_asmdata.CurrAsmList)
-                          else
-                            tempreg64.reghi := left.location.register64.reghi;
-                        end;
-
-                      if (aword(right.location.valueqword) <> 0) then
-                        { negative values can be handled using SUB, }
-                        { positive values < 65535 using XOR.        }
-                        if (longint(right.location.valueqword) >= -32767) and
-                           (longint(right.location.valueqword) < 0) then
-                          cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_INT,
-                            aword(right.location.valueqword),
-                            left.location.register64.reglo,tempreg64.reglo)
-                        else
-                          cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_INT,
-                            aword(right.location.valueqword),
-                            left.location.register64.reglo,tempreg64.reglo);
-
-                      if ((right.location.valueqword shr 32) <> 0) then
-                        if (longint(right.location.valueqword shr 32) >= -32767) and
-                           (longint(right.location.valueqword shr 32) < 0) then
-                          cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_INT,
-                            aword(right.location.valueqword shr 32),
-                            left.location.register64.reghi,tempreg64.reghi)
-                        else
-                          cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_INT,
-                            aword(right.location.valueqword shr 32),
-                            left.location.register64.reghi,tempreg64.reghi);
-                    end
-                  else
-                    begin
-                       tempreg64.reglo := cg.getintregister(current_asmdata.CurrAsmList);
-                       tempreg64.reghi := cg.getintregister(current_asmdata.CurrAsmList);
-                       cg64.a_op64_reg_reg_reg(current_asmdata.CurrAsmList,OP_XOR,
-                         left.location.register64,right.location.register64,
-                         tempreg64);
-                    end;
-
-                  cg.a_reg_alloc(current_asmdata.CurrAsmList,R_0);
-                  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR_,R_0,
-                    tempreg64.reglo,tempreg64.reghi));
-                  cg.a_reg_dealloc(current_asmdata.CurrAsmList,R_0);
-                  if (tempreg64.reglo <> left.location.register64.reglo) then
-                    cg.ungetregister(current_asmdata.CurrAsmList,tempreg64.reglo);
-                  if (tempreg64.reghi <> left.location.register64.reghi) then
-                    cg.ungetregister(current_asmdata.CurrAsmList,tempreg64.reghi);
-
-                  location_reset(location,LOC_FLAGS,OS_NO);
-                  location.resflags := getresflags;
+        if (right.location.loc=LOC_CONSTANT) and (right.location.value64=0) and
+          (nodetype in [equaln,unequaln]) then
+          begin
+            case left.location.loc of
+              LOC_REFERENCE,
+              LOC_CREFERENCE:
+                begin
+                  href:=left.location.reference;
+                  tcg68k(cg).fixref(current_asmdata.CurrAsmList,href);
+                  current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_TST,S_L,href));
+                  firstjmp64bitcmp;
+                  inc(href.offset,4);
+                  current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_TST,S_L,href));
+                  secondjmp64bitcmp;
+                  location_freetemp(current_asmdata.CurrAsmList,left.location);
                 end;
-              else
-                internalerror(2002072803);
+            else
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_TST,S_L,left.location.register64.reglo));
+              firstjmp64bitcmp;
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_TST,S_L,left.location.register64.reghi));
+              secondjmp64bitcmp;
             end;
+            exit;
+          end;
 
+        { left and right no register?  }
+        { then one must be demanded    }
+        if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+          begin
+            if not (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true)
+            else
+              begin
+                location_swap(left.location,right.location);
+                toggleflag(nf_swapped);
+              end;
+          end;
 
-        { set result location }
-        { (emit_compare sets it to LOC_FLAGS for compares, so set the }
-        {  real location only now) (JM)                               }
-        if cmpop and
-           not(nodetype in [equaln,unequaln]) then
-          location_reset(location,LOC_JUMP,OS_NO);
-*)
-  //     location_reset(location,LOC_JUMP,OS_NO);
-       // writeln('second_cmp64_exit');
-     end;
+        { left is now in register }
+        case right.location.loc of
+          LOC_REGISTER,LOC_CREGISTER:
+            begin
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi));
+              firstjmp64bitcmp;
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo));
+              secondjmp64bitcmp;
+            end;
+          LOC_REFERENCE,LOC_CREFERENCE:
+            begin
+              href:=right.location.reference;
+              tcg68k(cg).fixref(current_asmdata.CurrAsmList,href);
+              current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_CMP,S_L,href,left.location.register64.reghi));
+              firstjmp64bitcmp;
+              inc(href.offset,4);
+              current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_CMP,S_L,href,left.location.register64.reglo));
+              secondjmp64bitcmp;
+              location_freetemp(current_asmdata.CurrAsmList,right.location);
+            end;
+          LOC_CONSTANT:
+            begin
+              current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.register64.reghi));
+              firstjmp64bitcmp;
+              if assigned(hlab) then
+                cg.a_jmp_always(current_asmdata.CurrAsmList,hlab)
+              else
+                begin
+                  current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.register64.reglo));
+                  secondjmp64bitcmp;
+                end;
+            end;
+        else
+          InternalError(2014072501);
+        end;
+      end;
 
 
 begin

+ 7 - 1
compiler/m68k/n68kcnv.pas

@@ -68,8 +68,14 @@ implementation
           end
         else
         { converting a 64bit integer to a float requires a helper }
-        if is_64bitint(left.resultdef) then
+        if is_64bitint(left.resultdef) or
+            is_currency(left.resultdef) then
           begin
+            { hack to avoid double division by 10000, as it's
+              already done by typecheckpass.resultdef_int_to_real }
+            if is_currency(left.resultdef) then
+              left.resultdef := s64inttype;
+
             if is_signed(left.resultdef) then
               fname := 'fpc_int64_to_double'
             else

+ 3 - 6
compiler/m68k/n68kmat.pas

@@ -70,8 +70,7 @@ implementation
     procedure tm68knotnode.second_boolean;
       var
         hreg: tregister;
-         opsize : tcgsize;
-         loc : tcgloc;
+        opsize : tcgsize;
       begin
         if not handle_locjump then
           begin
@@ -154,10 +153,8 @@ implementation
 
 
   procedure tm68kmoddivnode.emit_mod_reg_reg(signed: boolean;denum,num : tregister);
-      var tmpreg : tregister;
-          continuelabel : tasmlabel;
-          signlabel : tasmlabel;
-          reg_d0,reg_d1 : tregister;
+    var
+      tmpreg : tregister;
     begin
      if current_settings.cputype=cpu_MC68020 then
        begin

+ 1 - 0
compiler/m68k/ra68k.pas

@@ -328,6 +328,7 @@ unit ra68k;
 
     function TM68kInstruction.ConcatLabeledInstr(p : TAsmList):tai;
       begin
+        result:=nil;
         if ((opcode >= A_BCC) and (opcode <= A_BVS)) or
            (opcode = A_BRA) or (opcode = A_BSR) or
            (opcode = A_JMP) or (opcode = A_JSR) or

+ 4 - 0
compiler/m68k/ra68kmot.pas

@@ -616,6 +616,7 @@ const
       l : longint;
       errorflag: boolean;
   begin
+    BuildExpression:=0;
     errorflag := FALSE;
     expr := '';
     tempstr := '';
@@ -986,6 +987,7 @@ const
       l: longint;
       code: integer;
   begin
+     str:='';
      Consume(AS_STAR);
      if (oper.opr.ref.scalefactor <> 0)
      and (oper.opr.ref.scalefactor <> 1) then
@@ -1180,6 +1182,7 @@ const
       code: integer;
       str: string;
     begin
+       str:='';
        Consume(AS_LPAREN);
        case actasmtoken of
          { // (reg ... // }
@@ -1309,6 +1312,7 @@ const
    dataregset := [];
    addrregset := [];
    tempstr := '';
+   r:=NR_NO;
    case actasmtoken of
    { // Memory reference //  }
      AS_LPAREN:

+ 138 - 2
compiler/m68k/rgcpu.pas

@@ -27,14 +27,150 @@ unit rgcpu;
   interface
 
      uses
-       aasmbase,aasmtai,aasmdata,
-       cpubase,
+       aasmbase,aasmtai,aasmdata,aasmcpu,
+       cgbase,cgutils,cpubase,
        rgobj;
 
      type
        trgcpu = class(trgobj)
+         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;
+         function do_spill_replace(list:TAsmList;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;override;
        end;
 
   implementation
 
+    uses
+      cutils,cgobj,verbose,globtype,globals,cpuinfo;
+
+    { returns True if source operand of MOVE can be replaced with spilltemp when its destination is ref^. }
+    function isvalidmovedest(ref: preference): boolean; inline;
+      begin
+        { The following is for Coldfire, for other CPUs it maybe can be relaxed. }
+        result:=(ref^.symbol=nil) and (ref^.scalefactor<=1) and
+          (ref^.index=NR_NO) and (ref^.base<>NR_NO) and (ref^.offset>=low(smallint)) and
+          (ref^.offset<=high(smallint));
+      end;
+
+
+    procedure trgcpu.do_spill_read(list:tasmlist;pos:tai;const spilltemp:treference;tempreg:tregister);
+      var
+        helpins  : tai;
+        tmpref   : treference;
+        helplist : tasmlist;
+        hreg     : tregister;
+      begin
+        if (abs(spilltemp.offset)>32767) and (current_settings.cputype in (cpu_coldfire + [cpu_mc68000])) then
+          begin
+            helplist:=tasmlist.create;
+
+            if getregtype(tempreg)=R_INTREGISTER then
+              hreg:=tempreg
+            else
+              hreg:=cg.getintregister(helplist,OS_ADDR);
+{$ifdef DEBUG_SPILLING}
+            helplist.concat(tai_comment.Create(strpnew('Spilling: Read, large offset')));
+{$endif}
+
+            helplist.concat(taicpu.op_const_reg(A_MOVE,S_L,spilltemp.offset,hreg));
+            reference_reset_base(tmpref,spilltemp.base,0,sizeof(aint));
+            tmpref.index:=hreg;
+
+            helpins:=spilling_create_load(tmpref,tempreg);
+            helplist.concat(helpins);
+            list.insertlistafter(pos,helplist);
+            helplist.free;
+          end
+        else
+          inherited do_spill_read(list,pos,spilltemp,tempreg);
+      end;
+
+
+    procedure trgcpu.do_spill_written(list:tasmlist;pos:tai;const spilltemp:treference;tempreg:tregister);
+      var
+        tmpref   : treference;
+        helplist : tasmlist;
+        hreg     : tregister;
+      begin
+        if (abs(spilltemp.offset)>32767) and (current_settings.cputype in (cpu_coldfire + [cpu_mc68000])) then
+          begin
+            helplist:=tasmlist.create;
+
+            if getregtype(tempreg)=R_INTREGISTER then
+              hreg:=getregisterinline(helplist,[R_SUBWHOLE])
+            else
+              hreg:=cg.getintregister(helplist,OS_ADDR);
+{$ifdef DEBUG_SPILLING}
+            helplist.concat(tai_comment.Create(strpnew('Spilling: Write, large offset')));
+{$endif}
+
+            helplist.concat(taicpu.op_const_reg(A_MOVE,S_L,spilltemp.offset,hreg));
+            reference_reset_base(tmpref,spilltemp.base,0,sizeof(aint));
+            tmpref.index:=hreg;
+
+            helplist.concat(spilling_create_store(tempreg,tmpref));
+            if getregtype(tempreg)=R_INTREGISTER then
+              ungetregisterinline(helplist,hreg);
+
+            list.insertlistafter(pos,helplist);
+            helplist.free;
+          end
+        else
+          inherited do_spill_written(list,pos,spilltemp,tempreg);
+    end;
+
+
+    function trgcpu.do_spill_replace(list:TAsmList;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;
+      var
+        opidx: longint;
+      begin
+        result:=false;
+        opidx:=-1;
+        if (abs(spilltemp.offset)>32767) and (current_settings.cputype in cpu_coldfire) then
+          exit;
+        case instr.ops of
+          1:
+            begin
+              if (instr.oper[0]^.typ=top_reg) and (getregtype(instr.oper[0]^.reg)=regtype) and
+                ((instr.opcode=A_TST) or (instr.opcode=A_CLR)) then
+                begin
+                  if get_alias(getsupreg(instr.oper[0]^.reg))<>orgreg then
+                    InternalError(2014080101);
+                  opidx:=0;
+                end;
+            end;
+          2:
+            begin
+              if (instr.oper[0]^.typ=top_reg) and (getregtype(instr.oper[0]^.reg)=regtype) and
+                (get_alias(getsupreg(instr.oper[0]^.reg))=orgreg) then
+                begin
+                  { source can be replaced if dest is register... }
+                  if ((instr.oper[1]^.typ=top_reg) and (instr.opcode in [A_MOVE,A_ADD,A_SUB,A_AND,A_OR,A_CMP])) or
+                    {... or a "simple" reference in case of MOVE }
+                    ((instr.opcode=A_MOVE) and (instr.oper[1]^.typ=top_ref) and isvalidmovedest(instr.oper[1]^.ref)) then
+                    opidx:=0;
+                end
+              else if (instr.oper[1]^.typ=top_reg) and (getregtype(instr.oper[1]^.reg)=regtype) and
+                (get_alias(getsupreg(instr.oper[1]^.reg))=orgreg) and
+                (
+                  (instr.opcode in [A_MOVE,A_ADD,A_SUB,A_AND,A_OR]) and
+                  (instr.oper[0]^.typ=top_reg)
+                ) or
+                (instr.opcode in [A_ADDQ,A_SUBQ,A_MOV3Q]) then
+                opidx:=1;
+            end;
+        end;
+
+        if (opidx<0) then
+          exit;
+        instr.oper[opidx]^.typ:=top_ref;
+        new(instr.oper[opidx]^.ref);
+        instr.oper[opidx]^.ref^:=spilltemp;
+        case instr.opsize of
+          S_B: inc(instr.oper[opidx]^.ref^.offset,3);
+          S_W: inc(instr.oper[opidx]^.ref^.offset,2);
+        end;
+        result:=true;
+      end;
+
 end.

+ 10 - 4
compiler/m68k/symcpu.pas

@@ -186,14 +186,16 @@ implementation
   procedure tcpuprocdef.ppuload_platform(ppufile: tcompilerppufile);
     begin
       inherited;
-      ppufile.getderef(libsymderef);
+      if po_syscall_has_libsym in procoptions then
+        ppufile.getderef(libsymderef);
     end;
 
 
   procedure tcpuprocdef.ppuwrite_platform(ppufile: tcompilerppufile);
     begin
       inherited;
-      ppufile.putderef(libsymderef);
+      if po_syscall_has_libsym in procoptions then
+        ppufile.putderef(libsymderef);
     end;
 
 
@@ -208,14 +210,18 @@ implementation
   procedure tcpuprocdef.buildderef;
     begin
       inherited;
-      libsymderef.build(libsym);
+      if po_syscall_has_libsym in procoptions then
+        libsymderef.build(libsym);
     end;
 
 
   procedure tcpuprocdef.deref;
     begin
       inherited;
-      libsym:=tsym(libsymderef.resolve);
+      if po_syscall_has_libsym in procoptions then
+        libsym:=tsym(libsymderef.resolve)
+      else
+        libsym:=nil;
     end;
 
 begin

+ 15 - 6
compiler/mips/aasmcpu.pas

@@ -33,9 +33,9 @@ uses
 
 const
   { "mov reg,reg" source operand number }
-  O_MOV_SOURCE = 0;
+  O_MOV_SOURCE = 1;
   { "mov reg,reg" source operand number }
-  O_MOV_DEST   = 1;
+  O_MOV_DEST   = 0;
 
 type
   { taicpu }
@@ -401,13 +401,22 @@ end;
       A_SNE,
       A_EXT,
       A_INS,
-      A_MFC0];
+      A_MFC0,
+      A_SEB,
+      A_SEH];
 
       begin
         result := operand_read;
-        if opcode in op_write_set then
-          if opnr = 0 then
-            result := operand_write;
+        case opcode of
+          A_DIV,   { these have 3 operands if used as macros }
+          A_DIVU:
+            if (ops=3) and (opnr=0) then
+              result:=operand_write;
+        else
+          if opcode in op_write_set then
+            if opnr = 0 then
+              result := operand_write;
+        end;
       end;
 
 

+ 271 - 45
compiler/mips/aoptcpu.pas

@@ -28,15 +28,18 @@ unit aoptcpu;
   Interface
 
     uses
-      cgbase, cpubase, aoptobj, aoptcpub, aopt, aasmtai;
+      cgbase, cpubase, aoptobj, aoptcpub, aopt, aasmtai, aasmcpu;
 
     Type
+      TAsmOpSet = set of TAsmOp;
+
       TCpuAsmOptimizer = class(TAsmOptimizer)
+        function RegModifiedByInstruction(Reg: TRegister; p1: tai): boolean; override;
         function GetNextInstructionUsingReg(Current: tai;
           var Next: tai; reg: TRegister): Boolean;
-        function RegUsedAfterInstruction(reg: Tregister; p: tai;
-          var AllUsedRegs: TAllUsedRegs): Boolean;
         function TryRemoveMov(var p: tai; opcode: TAsmOp): boolean;
+        function TryRemoveMovToRefIndex(var p: tai; next: taicpu): boolean;
+        function TryRemoveMovBeforeStore(var p: tai; next: taicpu; const storeops: TAsmOpSet): boolean;
         function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
         procedure PeepHoleOptPass2; override;
       End;
@@ -44,7 +47,7 @@ unit aoptcpu;
   Implementation
 
      uses
-       globals,aasmbase,aasmcpu,cpuinfo,verbose;
+       cutils,globtype,globals,aasmbase,cpuinfo,verbose;
 
 
   function MatchInstruction(const instr: tai; const op: TAsmOp): boolean;
@@ -93,10 +96,15 @@ unit aoptcpu;
     end;
 
 
-  function CanBeCMOV(p: tai): boolean;
+  function CanBeCMOV(p: tai; condreg: tregister): boolean;
     begin
       result:=assigned(p) and (p.typ=ait_instruction) and
-        (taicpu(p).opcode in [A_MOV_D,A_MOV_S,A_MOVE]);
+        ((taicpu(p).opcode in [A_MOV_D,A_MOV_S]) or
+        (
+          { register with condition must not be overwritten }
+          (taicpu(p).opcode=A_MOVE) and
+          (taicpu(p).oper[0]^.reg<>condreg)
+        ));
     end;
 
 
@@ -170,6 +178,20 @@ unit aoptcpu;
     end;
 
 
+  function TCpuAsmOptimizer.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;
+
+
   function TCpuAsmOptimizer.GetNextInstructionUsingReg(Current: tai;
     var Next: tai; reg: TRegister): Boolean;
     begin
@@ -178,7 +200,7 @@ unit aoptcpu;
         Result:=GetNextInstruction(Next,Next);
       until {not(cs_opt_level3 in current_settings.optimizerswitches) or} not(Result) or (Next.typ<>ait_instruction) or (RegInInstruction(reg,Next)) or
         (is_calljmp(taicpu(Next).opcode));
-      if Result and is_calljmp(taicpu(next).opcode) then
+      if Result and (next.typ=ait_instruction) and is_calljmp(taicpu(next).opcode) then
         begin
           result:=false;
           next:=nil;
@@ -186,21 +208,6 @@ unit aoptcpu;
     end;
 
 
-  function TCpuAsmOptimizer.RegUsedAfterInstruction(reg: Tregister; p: tai;
-    var AllUsedRegs: TAllUsedRegs): Boolean;
-    begin
-      AllUsedRegs[getregtype(reg)].Update(tai(p.Next),true);
-      RegUsedAfterInstruction :=
-        AllUsedRegs[getregtype(reg)].IsUsed(reg) and
-        not(regLoadedWithNewValue(reg,p)) and
-        (
-          not(GetNextInstruction(p,p)) or
-          instructionLoadsFromReg(reg,p) or
-          not(regLoadedWithNewValue(reg,p))
-        );
-    end;
-
-
   function TCpuAsmOptimizer.TryRemoveMov(var p: tai; opcode: TAsmOp): boolean;
     var
       next,hp1: tai;
@@ -215,7 +222,7 @@ unit aoptcpu;
         opcode may be A_MOVE, A_MOV_s, A_MOV_d, etc.
       }
       result:=false;
-      if (taicpu(p).ops>1) and
+      if (taicpu(p).ops>0) and
          GetNextInstructionUsingReg(p,next,taicpu(p).oper[0]^.reg) and
          MatchInstruction(next,opcode) and
          MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) and
@@ -256,21 +263,96 @@ unit aoptcpu;
               taicpu(p).loadreg(0,taicpu(next).oper[0]^.reg);
               asml.remove(next);
               next.free;
+              result:=true;
+            end
+          else       // no dealloc found
+            begin
+              { try to optimize the typical call sequence
+                lw  $reg, (whatever)
+                <alloc volatile registers>
+                move $t9,$reg
+                jalr $t9
+                Do not do so if the used register might contain a 
+                register variable.      }
+              if (opcode=A_MOVE) and
+                 not(cs_opt_regvar in current_settings.optimizerswitches) and
+                 (taicpu(next).oper[0]^.reg=NR_R25) and
+                 GetNextInstruction(next,hp1) and
+                 MatchInstruction(hp1,A_JALR) and
+                 MatchOperand(taicpu(hp1).oper[0]^,NR_R25) then
+                begin
+                  taicpu(p).loadreg(0,taicpu(next).oper[0]^.reg);
+                  asml.remove(next);
+                  next.free;
+                  result:=true;
+                end;
             end;
         end;
     end;
 
 
+  function TCpuAsmOptimizer.TryRemoveMovBeforeStore(var p: tai; next: taicpu; const storeops: TAsmOpSet): boolean;
+    begin
+      result:=(next.opcode in storeops) and
+        MatchOperand(next.oper[0]^,taicpu(p).oper[0]^.reg) and
+        { Ry cannot be modified between move and store }
+        (not RegModifiedBetween(taicpu(p).oper[1]^.reg,p,next)) and
+        Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next)));
+      if result then
+        begin
+          next.loadreg(0,taicpu(p).oper[1]^.reg);
+          asml.remove(p);
+          p.free;
+          p:=next;
+        end;
+    end;
+
+
+  function TCpuAsmOptimizer.TryRemoveMovToRefIndex(var p: tai; next: taicpu): boolean;
+    begin
+      result:=(next.oper[1]^.typ=top_ref) and
+        (next.oper[1]^.ref^.base=taicpu(p).oper[0]^.reg) and
+        (not RegModifiedBetween(taicpu(p).oper[1]^.reg,p,next)) and
+        Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next)));
+      if result then
+        begin
+          next.oper[1]^.ref^.base:=taicpu(p).oper[1]^.reg;
+          asml.remove(p);
+          p.free;
+          p:=next;
+        end;
+    end;
+
+
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
     var
       next,next2: tai;
-      TmpUsedRegs: TAllUsedRegs;
     begin
       result:=false;
       case p.typ of
         ait_instruction:
           begin
             case taicpu(p).opcode of
+              A_SEH:
+                begin
+                  if GetNextInstructionUsingReg(p,next,taicpu(p).oper[0]^.reg) and
+                    MatchInstruction(next,A_SH) and
+                    MatchOperand(taicpu(next).oper[0]^,taicpu(p).oper[0]^.reg) and
+                    (not RegUsedBetween(taicpu(p).oper[1]^.reg,p,next)) and
+                    Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
+                    begin
+                      taicpu(next).loadreg(0,taicpu(p).oper[1]^.reg);
+                      asml.remove(p);
+                      p.free;
+                      p:=next;
+                    end
+                  else
+                    TryRemoveMov(p,A_MOVE);
+                end;
+              A_SEB:
+                { TODO: can be handled similar to A_SEH, but it's almost never encountered }
+                TryRemoveMov(p,A_MOVE);
+
               A_SLL:
                 begin
                   { if this is a sign extension... }
@@ -289,10 +371,7 @@ unit aoptcpu;
                     { the initial register may not be reused }
                     (not RegUsedBetween(taicpu(p).oper[1]^.reg,next,next2)) then
                     begin
-                      CopyUsedRegs(TmpUsedRegs);
-                      UpdateUsedRegs(TmpUsedRegs, tai(p.next));
-                      UpdateUsedRegs(TmpUsedRegs, tai(next.next));
-                      if not RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,next2,TmpUsedRegs) then
+                      if Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next2.next))) then
                         begin
                           taicpu(next2).loadreg(0,taicpu(p).oper[1]^.reg);
                           asml.remove(p);
@@ -301,7 +380,6 @@ unit aoptcpu;
                           next.free;
                           p:=next2;
                         end;
-                      ReleaseUsedRegs(TmpUsedRegs);
                     end
                   else
                     TryRemoveMov(p,A_MOVE);
@@ -309,6 +387,7 @@ unit aoptcpu;
 
               A_SRL:
                 begin
+                  { TODO: also kill sign-extensions that follow, both SLL+SRA and SEB/SEH versions }
                   { Remove 'andi' in sequences
                       srl   Rx,Ry,16
                       andi  Rx,Rx,65535
@@ -368,37 +447,184 @@ unit aoptcpu;
                     ((taicpu(p).oper[2]^.val=255) and MatchInstruction(next,A_SB)) or
                     ((taicpu(p).oper[2]^.val=65535) and MatchInstruction(next,A_SH)) and
                     (taicpu(next).oper[0]^.typ=top_reg) and
-                    (taicpu(next).oper[0]^.reg=taicpu(p).oper[0]^.reg) then
+                    (taicpu(next).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
+                    assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
                     begin
-                      CopyUsedRegs(TmpUsedRegs);
-                      UpdateUsedRegs(TmpUsedRegs, tai(p.next));
-                      if not RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,next,TmpUsedRegs) then
+                      taicpu(next).loadreg(0,taicpu(p).oper[1]^.reg);
+                      asml.remove(p);
+                      p.free;
+                      p:=next;
+                    end
+                  else
+                    TryRemoveMov(p,A_MOVE);
+                end;
+
+              A_MOV_S:
+                begin
+                  if GetNextInstructionUsingReg(p,next,taicpu(p).oper[0]^.reg) and
+                     (next.typ=ait_instruction) then
+                    begin
+                      if TryRemoveMovBeforeStore(p,taicpu(next),[A_SWC1]) then
+                        { optimization successful };
+                    end;
+                end;
+
+              A_MOV_D:
+                begin
+                  if GetNextInstructionUsingReg(p,next,taicpu(p).oper[0]^.reg) and
+                     (next.typ=ait_instruction) then
+                    begin
+                      if TryRemoveMovBeforeStore(p,taicpu(next),[A_SDC1]) then
+                        { optimization successful };
+                    end;
+                end;
+
+              A_MOVE:
+                begin
+                  if GetNextInstructionUsingReg(p,next,taicpu(p).oper[0]^.reg) and
+                    (next.typ=ait_instruction) and
+                    (not RegModifiedBetween(taicpu(p).oper[1]^.reg,p,next)) then
+                    begin
+                      { MOVE  Rx,Ry; store Rx,(ref); dealloc Rx   ==> store Ry,(ref) }
+                      if TryRemoveMovBeforeStore(p,taicpu(next),[A_SB,A_SH,A_SW]) then
+                        { optimization successful }
+                      else if TryRemoveMovToRefIndex(p,taicpu(next)) then
+                        { successful as well }
+                      { MOVE  Rx,Ry; opcode  Rx,Rx,any              ==> opcode Rx,Ry,any
+                        MOVE  Rx,Ry; opcode  Rx,Rz,Rx               ==> opcode Rx,Rz,Ry   }
+                      else if (taicpu(next).opcode in [A_ADD,A_ADDU,A_ADDI,A_ADDIU,A_SUB,A_SUBU]) and
+                         MatchOperand(taicpu(next).oper[0]^,taicpu(p).oper[0]^.reg) then
                         begin
-                          taicpu(next).loadreg(0,taicpu(p).oper[1]^.reg);
-                          asml.remove(p);
-                          p.free;
-                          p:=next;
+                          if MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) and
+                             Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
+                            begin
+                              taicpu(next).loadreg(1,taicpu(p).oper[1]^.reg);
+                              asml.remove(p);
+                              p.free;
+                              p:=next;
+                            end
+                          { TODO: if Ry=NR_R0, this effectively changes instruction into MOVE,
+                            providing further optimization possibilities }
+                          else if MatchOperand(taicpu(next).oper[2]^,taicpu(p).oper[0]^.reg) and
+                                  Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
+                            begin
+                              taicpu(next).loadreg(2,taicpu(p).oper[1]^.reg);
+                              asml.remove(p);
+                              p.free;
+                              p:=next;
+                            end;
+                        end
+                      { MOVE  Rx,Ry; opcode Rz,Rx,any; dealloc Rx  ==> opcode Rz,Ry,any }
+                      else if (taicpu(next).opcode in [A_ADD,A_ADDU,A_ADDI,A_ADDIU,A_SUB,A_SUBU,A_SLT,A_SLTU,A_DIV,A_DIVU]) and
+                         Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
+                        begin
+                          if MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) then
+                            begin
+                              taicpu(next).loadreg(1,taicpu(p).oper[1]^.reg);
+                              asml.remove(p);
+                              p.free;
+                              p:=next;
+                            end
+                          else if MatchOperand(taicpu(next).oper[2]^,taicpu(p).oper[0]^.reg) then
+                            begin
+                              taicpu(next).loadreg(2,taicpu(p).oper[1]^.reg);
+                              asml.remove(p);
+                              p.free;
+                              p:=next;
+                            end;
+                        end
+                      { MULT[U] must be handled separately due to different operand numbers }
+                      else if (taicpu(next).opcode in [A_MULT,A_MULTU]) and
+                         Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
+                        begin
+                          if MatchOperand(taicpu(next).oper[0]^,taicpu(p).oper[0]^.reg) then
+                            begin
+                              taicpu(next).loadreg(0,taicpu(p).oper[1]^.reg);
+                              asml.remove(p);
+                              p.free;
+                              p:=next;
+                            end
+                          else if MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) then
+                            begin
+                              taicpu(next).loadreg(1,taicpu(p).oper[1]^.reg);
+                              asml.remove(p);
+                              p.free;
+                              p:=next;
+                            end;
+                        end
+                      else if TryRemoveMov(p,A_MOVE) then
+                        begin
+                          { Ended up with move between same register? Suicide then. }
+                          if (taicpu(p).oper[0]^.reg=taicpu(p).oper[1]^.reg) then
+                            begin
+                              GetNextInstruction(p,next);
+                              asml.remove(p);
+                              p.free;
+                              p:=next;
+                            end;
                         end;
-                      ReleaseUsedRegs(TmpUsedRegs);
+                      { TODO: MOVE  Rx,Ry; Bcc Rx,Rz,label; dealloc Rx   ==> Bcc Ry,Rz,label  }
+                    end;
+                end;
+
+              A_ADDIU:
+                begin
+                  { ADDIU  Rx,Ry,const;    load/store  Rz,(Rx); dealloc Rx  ==> load/store Rz,const(Ry)
+                    ADDIU  Rx,Ry,%lo(sym); load/store  Rz,(Rx); dealloc Rx  ==> load/store Rz,%lo(sym)(Ry)
+                    ADDIU  Rx,Ry,const;    load Rx,(Rx)                     ==> load Rx,const(Ry)
+                    ADDIU  Rx,Ry,%lo(sym); load Rx,(Rx)                     ==> load Rx,%lo(sym)(Ry)    }
+                  if GetNextInstructionUsingReg(p,next,taicpu(p).oper[0]^.reg) and
+                    (next.typ=ait_instruction) and
+                    (taicpu(next).opcode in [A_LB,A_LBU,A_LH,A_LHU,A_LW,A_SB,A_SH,A_SW]) and
+                    (taicpu(p).oper[0]^.reg=taicpu(next).oper[1]^.ref^.base) and
+                    (taicpu(next).oper[1]^.ref^.offset=0) and
+                    (taicpu(next).oper[1]^.ref^.symbol=nil) and
+                    (
+                      Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) or
+                      (
+                        (taicpu(p).oper[0]^.reg=taicpu(next).oper[0]^.reg) and
+                        (taicpu(next).opcode in [A_LB,A_LBU,A_LH,A_LHU,A_LW])
+                      )
+                    )  and
+                    (not RegModifiedBetween(taicpu(p).oper[1]^.reg,p,next)) then
+                    begin
+                      case taicpu(p).oper[2]^.typ of
+                        top_const:
+                          taicpu(next).oper[1]^.ref^.offset:=taicpu(p).oper[2]^.val;
+
+                        top_ref:
+                          taicpu(next).oper[1]^.ref^:=taicpu(p).oper[2]^.ref^;
+                      else
+                        InternalError(2014100401);
+                      end;
+                      taicpu(next).oper[1]^.ref^.base:=taicpu(p).oper[1]^.reg;
+                      asml.remove(p);
+                      p.free;
+                      p:=next;
+                      result:=true;
                     end
                   else
-                    TryRemoveMov(p,A_MOVE);
+                    result:=TryRemoveMov(p,A_MOVE);
                 end;
 
+              A_LB,A_LBU,A_LH,A_LHU,A_LW,
               A_ADD,A_ADDU,
-              A_ADDI,A_ADDIU,
+              A_ADDI,
               A_SUB,A_SUBU,
               A_SRA,A_SRAV,
               A_SRLV,
               A_SLLV,
+              A_MFLO,A_MFHI,
               A_AND,A_OR,A_XOR,A_ORI,A_XORI:
                 TryRemoveMov(p,A_MOVE);
 
+              A_LWC1,
               A_ADD_s, A_SUB_s, A_MUL_s, A_DIV_s,
               A_ABS_s, A_NEG_s, A_SQRT_s,
               A_CVT_s_w, A_CVT_s_l, A_CVT_s_d:
                 TryRemoveMov(p,A_MOV_s);
 
+              A_LDC1,
               A_ADD_d, A_SUB_d, A_MUL_d, A_DIV_d,
               A_ABS_d, A_NEG_d, A_SQRT_d,
               A_CVT_d_w, A_CVT_d_l, A_CVT_d_s:
@@ -452,7 +678,7 @@ unit aoptcpu;
                           }
                           l:=0;
                           GetNextInstruction(p, hp1);
-                          while CanBeCMOV(hp1) do       // CanBeCMOV returns False for nil or labels
+                          while CanBeCMOV(hp1,condreg) do       // CanBeCMOV returns False for nil or labels
                             begin
                               inc(l);
                               GetNextInstruction(hp1,hp1);
@@ -470,7 +696,7 @@ unit aoptcpu;
                                       repeat
                                         ChangeToCMOV(taicpu(hp1),condition,condreg);
                                         GetNextInstruction(hp1,hp1);
-                                      until not CanBeCMOV(hp1);
+                                      until not CanBeCMOV(hp1,condreg);
                                       { wait with removing else GetNextInstruction could
                                         ignore the label if it was the only usage in the
                                         jump moved away }
@@ -508,7 +734,7 @@ unit aoptcpu;
                                       l:=0;
                                       { skip hp1 to <several moves 2> }
                                       GetNextInstruction(hp1, hp1);
-                                      while CanBeCMOV(hp1) do
+                                      while CanBeCMOV(hp1,condreg) do
                                         begin
                                           inc(l);
                                           GetNextInstruction(hp1, hp1);
@@ -524,7 +750,7 @@ unit aoptcpu;
                                           repeat
                                             ChangeToCMOV(taicpu(hp1),condition,condreg);
                                             GetNextInstruction(hp1,hp1);
-                                          until not CanBeCMOV(hp1);
+                                          until not CanBeCMOV(hp1,condreg);
                                           { hp2 is still at b yyy }
                                           GetNextInstruction(hp2,hp1);
                                           { hp2 is now at xxx: }
@@ -534,7 +760,7 @@ unit aoptcpu;
                                           repeat
                                             ChangeToCMOV(taicpu(hp1),condition,condreg);
                                             GetNextInstruction(hp1,hp1);
-                                          until not CanBeCMOV(hp1);
+                                          until not CanBeCMOV(hp1,condreg);
                                           { remove bCC }
                                           tasmlabel(taicpu(hp3).oper[taicpu(hp3).ops-1]^.ref^.symbol).decrefs;
                                           RemoveDelaySlot(hp3);

+ 90 - 41
compiler/mips/cgcpu.pas

@@ -197,16 +197,9 @@ begin
 
       { PIC global symbol }
       ref.symbol:=nil;
-      if (ref.offset=0) then
-        exit;
-
       if (ref.offset>=simm16lo) and
         (ref.offset<=simm16hi-sizeof(pint)) then
-        begin
-          list.concat(taicpu.op_reg_reg_const(A_ADDIU,ref.base,ref.base,ref.offset));
-          ref.offset:=0;
-          exit;
-        end;
+        exit;
       { fallthrough to the case of large offset }
     end;
 
@@ -295,10 +288,6 @@ begin
     [RS_F0,RS_F2,RS_F4,RS_F6, RS_F8,RS_F10,RS_F12,RS_F14,
      RS_F16,RS_F18,RS_F20,RS_F22, RS_F24,RS_F26,RS_F28,RS_F30],
     first_fpu_imreg, []);
-
-  { needs at least one element for rgobj not to crash }
-  rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
-      [RS_R0],first_mm_imreg,[]);
 end;
 
 
@@ -307,7 +296,6 @@ procedure TCGMIPS.done_register_allocators;
 begin
   rg[R_INTREGISTER].Free;
   rg[R_FPUREGISTER].Free;
-  rg[R_MMREGISTER].Free;
   inherited done_register_allocators;
 end;
 
@@ -441,7 +429,7 @@ end;
 procedure TCGMIPS.a_load_const_reg(list: tasmlist; size: TCGSize; a: tcgint; reg: TRegister);
 begin
   if (a = 0) then
-    list.concat(taicpu.op_reg_reg(A_MOVE, reg, NR_R0))
+    a_load_reg_reg(list, OS_INT, OS_INT, NR_R0, reg)
   else if (a >= simm16lo) and (a <= simm16hi) then
     list.concat(taicpu.op_reg_reg_const(A_ADDIU, reg, NR_R0, a))
   else if (a>=0) and (a <= 65535) then
@@ -546,13 +534,23 @@ begin
         done:=false;
       OS_S8:
       begin
-        list.concat(taicpu.op_reg_reg_const(A_SLL, reg2, reg1, 24));
-        list.concat(taicpu.op_reg_reg_const(A_SRA, reg2, reg2, 24));
+        if (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]) then
+          list.concat(taicpu.op_reg_reg(A_SEB,reg2,reg1))
+        else
+          begin
+            list.concat(taicpu.op_reg_reg_const(A_SLL, reg2, reg1, 24));
+            list.concat(taicpu.op_reg_reg_const(A_SRA, reg2, reg2, 24));
+          end;
       end;
       OS_S16:
       begin
-        list.concat(taicpu.op_reg_reg_const(A_SLL, reg2, reg1, 16));
-        list.concat(taicpu.op_reg_reg_const(A_SRA, reg2, reg2, 16));
+        if (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]) then
+          list.concat(taicpu.op_reg_reg(A_SEH,reg2,reg1))
+        else
+          begin
+            list.concat(taicpu.op_reg_reg_const(A_SLL, reg2, reg1, 16));
+            list.concat(taicpu.op_reg_reg_const(A_SRA, reg2, reg2, 16));
+          end;
       end;
       else
         internalerror(2002090901);
@@ -820,6 +818,7 @@ var
   hreg: TRegister;
   asmop: TAsmOp;
 begin
+  a:=aint(a);
   ovloc.loc := LOC_VOID;
   optimize_op_const(size,op,a);
   signed:=(size in [OS_S8,OS_S16,OS_S32]);
@@ -935,23 +934,30 @@ begin
       end;
     OP_MUL,OP_IMUL:
       begin
-        list.concat(taicpu.op_reg_reg(TOpCg2AsmOp[op], src2, src1));
-        list.concat(taicpu.op_reg(A_MFLO, dst));
-        if setflags then
+        if (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]) and
+           (not setflags) then
+          { NOTE: MUL is actually mips32r1 instruction; on older cores it is handled as macro }
+          list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src2,src1))
+        else
           begin
-            current_asmdata.getjumplabel(hl);
-            hreg:=GetIntRegister(list,OS_INT);
-            list.concat(taicpu.op_reg(A_MFHI,hreg));
-            if (op=OP_IMUL) then
+            list.concat(taicpu.op_reg_reg(TOpCg2AsmOp[op], src2, src1));
+            list.concat(taicpu.op_reg(A_MFLO, dst));
+            if setflags then
               begin
-                hreg2:=GetIntRegister(list,OS_INT);
-                list.concat(taicpu.op_reg_reg_const(A_SRA,hreg2,dst,31));
-                a_cmp_reg_reg_label(list,OS_INT,OC_EQ,hreg2,hreg,hl);
-              end
-            else
-              a_cmp_reg_reg_label(list,OS_INT,OC_EQ,hreg,NR_R0,hl);
-            list.concat(taicpu.op_const(A_BREAK,6));
-            a_label(list,hl);
+                current_asmdata.getjumplabel(hl);
+                hreg:=GetIntRegister(list,OS_INT);
+                list.concat(taicpu.op_reg(A_MFHI,hreg));
+                if (op=OP_IMUL) then
+                  begin
+                    hreg2:=GetIntRegister(list,OS_INT);
+                    list.concat(taicpu.op_reg_reg_const(A_SRA,hreg2,dst,31));
+                    a_cmp_reg_reg_label(list,OS_INT,OC_EQ,hreg2,hreg,hl);
+                  end
+                else
+                  a_cmp_reg_reg_label(list,OS_INT,OC_EQ,hreg,NR_R0,hl);
+                list.concat(taicpu.op_const(A_BREAK,6));
+                a_label(list,hl);
+              end;
           end;
       end;
     OP_AND,OP_OR,OP_XOR:
@@ -1071,7 +1077,28 @@ end;
 
 
 procedure TCGMIPS.a_jmp_flags(list: tasmlist; const f: TResFlags; l: tasmlabel);
+  var
+    ai: taicpu;
   begin
+    case f.reg1 of
+      NR_FCC0..NR_FCC7:
+        begin
+          if (f.reg1=NR_FCC0) then
+            ai:=taicpu.op_sym(A_BC,l)
+          else
+            ai:=taicpu.op_reg_sym(A_BC,f.reg1,l);
+          list.concat(ai);
+          { delay slot }
+          list.concat(taicpu.op_none(A_NOP));
+          case f.cond of
+            OC_NE: ai.SetCondition(C_COP1TRUE);
+            OC_EQ: ai.SetCondition(C_COP1FALSE);
+          else
+            InternalError(2014082901);
+          end;
+          exit;
+        end;
+    end;
     if f.use_const then
       a_cmp_const_reg_label(list,OS_INT,f.cond,f.value,f.reg1,l)
     else
@@ -1083,7 +1110,33 @@ procedure TCGMIPS.g_flags2reg(list: tasmlist; size: tcgsize; const f: tresflags;
   var
     left,right: tregister;
     unsigned: boolean;
+    hl: tasmlabel;
   begin
+    case f.reg1 of
+      NR_FCC0..NR_FCC7:
+        begin
+          if (current_settings.cputype>=cpu_mips4) then
+            begin
+              a_load_const_reg(list,size,1,reg);
+              case f.cond of
+                OC_NE: list.concat(taicpu.op_reg_reg_reg(A_MOVF,reg,NR_R0,f.reg1));
+                OC_EQ: list.concat(taicpu.op_reg_reg_reg(A_MOVT,reg,NR_R0,f.reg1));
+              else
+                InternalError(2014082902);
+              end;
+            end
+          else
+            begin
+              { TODO: still possible to do branchless by extracting appropriate bit from FCSR? }
+              current_asmdata.getjumplabel(hl);
+              a_load_const_reg(list,size,1,reg);
+              a_jmp_flags(list,f,hl);
+              a_load_const_reg(list,size,0,reg);
+              a_label(list,hl);
+            end;
+          exit;
+        end;
+    end;
     if (f.cond in [OC_EQ,OC_NE]) then
       begin
         left:=reg;
@@ -1212,7 +1265,6 @@ var
   largeoffs : boolean;
 begin
   list.concat(tai_directive.create(asd_ent,current_procinfo.procdef.mangledname));
-  a_reg_alloc(list,NR_STACK_POINTER_REG);
 
   if nostackframe then
     begin
@@ -1221,9 +1273,6 @@ begin
       exit;
     end;
 
-  if (pi_needs_stackframe in current_procinfo.flags) then
-    a_reg_alloc(list,NR_FRAME_POINTER_REG);
-
   helplist:=TAsmList.Create;
 
   reference_reset(href,0);
@@ -1236,7 +1285,7 @@ begin
     begin
       if reg in (rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall)) then
         begin
-          fmask:=fmask or (1 shl ord(reg));
+          fmask:=fmask or (longword(1) shl ord(reg));
           href.offset:=nextoffset;
           lastfpuoffset:=nextoffset;
           helplist.concat(taicpu.op_reg_ref(A_SWC1,newreg(R_FPUREGISTER,reg,R_SUBFS),href));
@@ -1266,7 +1315,7 @@ begin
     begin
       if reg in saveregs then
         begin
-          mask:=mask or (1 shl ord(reg));
+          mask:=mask or (longword(1) shl ord(reg));
           href.offset:=nextoffset;
           lastintoffset:=nextoffset;
           if (reg=RS_FRAME_POINTER_REG) then
@@ -1282,8 +1331,8 @@ begin
   //list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG,NR_STACK_POINTER_REG,current_procinfo.para_stack_size));
   list.concat(Taicpu.op_none(A_P_SET_NOMIPS16));
   list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,current_procinfo.framepointer,LocalSize,NR_R31));
-  list.concat(Taicpu.op_const_const(A_P_MASK,mask,-(LocalSize-lastintoffset)));
-  list.concat(Taicpu.op_const_const(A_P_FMASK,Fmask,-(LocalSize-lastfpuoffset)));
+  list.concat(Taicpu.op_const_const(A_P_MASK,aint(mask),-(LocalSize-lastintoffset)));
+  list.concat(Taicpu.op_const_const(A_P_FMASK,aint(Fmask),-(LocalSize-lastfpuoffset)));
   list.concat(Taicpu.op_none(A_P_SET_NOREORDER));
   if (cs_create_pic in current_settings.moduleswitches) and
      (pi_needs_got in current_procinfo.flags) then

+ 7 - 5
compiler/mips/cpuelf.pas

@@ -207,6 +207,8 @@ implementation
           result:=R_MIPS_NONE;
         RELOC_ABSOLUTE:
           result:=R_MIPS_32;
+        RELOC_GOTOFF:               {For case jumptables only }
+          result:=R_MIPS_GPREL32;
       else
         result:=0;
         InternalError(2012110602);
@@ -739,15 +741,15 @@ implementation
                     if (lowreloc.ftype=R_MIPS_LO16) then
                       begin;
                         found:=true;
+                        objsec.Data.Seek(objreloc.DataOffset);
+                        objsec.Data.Read(hipart,sizeof(hipart));
+                        objsec.Data.Seek(lowreloc.DataOffset);
+                        objsec.Data.Read(lopart,sizeof(lopart));
                         break;
                       end;
                   end;
                 if not found then
                   InternalError(2013030102);
-                objsec.Data.Seek(objreloc.DataOffset);
-                objsec.Data.Read(hipart,sizeof(hipart));
-                objsec.Data.Seek(lowreloc.DataOffset);
-                objsec.Data.Read(lopart,sizeof(lopart));
                 if (source_info.endian<>target_info.endian) then
                   begin
                     hipart:=swapendian(hipart);
@@ -809,7 +811,7 @@ implementation
           else
             reltyp:=objreloc.ftype;
 
-          if ElfTarget.relocs_use_addend then
+          if (oso_rela_relocs in objsec.SecOptions) then
             address:=objreloc.orgsize
           else
             begin

+ 1 - 1
compiler/mips/cpugas.pas

@@ -225,7 +225,7 @@ unit cpugas;
             not (ai.condition in [C_EQ,C_NE,C_GTZ,C_GEZ,C_LTZ,C_LEZ,C_COP1TRUE,C_COP1FALSE])) {or (op=A_JAL)}
           or (op=A_REM) or (op=A_REMU)
           { DIV and DIVU are normally macros, but use $zero as first arg to generate a CPU instruction. }
-          or ((op=A_DIV) or (op=A_DIVU) and
+          or (((op=A_DIV) or (op=A_DIVU)) and
             ((ai.ops<>3) or (ai.oper[0]^.typ<>top_reg) or (ai.oper[0]^.reg<>NR_R0)))
           or (op=A_MULO) or (op=A_MULOU)
           { A_LI is only a macro if the immediate is not in thez 16-bit range }

+ 41 - 12
compiler/mips/cpuinfo.pas

@@ -21,6 +21,9 @@ Interface
 
 Type
    bestreal = double;
+{$if FPC_FULLVERSION>20700}
+   bestrealrec = TDoubleRec;
+{$endif FPC_FULLVERSION>20700}
    ts32real = single;
    ts64real = double;
    ts80real = type double;
@@ -87,7 +90,7 @@ Const
 
    fputypestr : array[tfputype] of string[9] = ('',
      'SOFT',
-     'FPU_MIPS2','FPU_MIPS3'
+     'MIPS2','MIPS3'
    );
 
    { abi strings as accepted by 
@@ -104,23 +107,49 @@ Const
 
    mips_abi : tabitype = abi_default;
 
-{$ifdef MIPSEL}
 type
-   tcpuflags=(CPUMIPS_HAS_XXXX); //Todo: Does this need to be filled?
+   tcpuflags=(
+     CPUMIPS_HAS_CMOV,             { conditional move instructions (mips4+) }
+     CPUMIPS_HAS_ISA32R2           { mips32r2 instructions (also on PIC32)  }
+   );
 
 const
   cpu_capabilities : array[tcputype] of set of tcpuflags =
-    ( { cpu_none } [],
-      { cpu_mips1 } [],
-      { cpu_mips2 } [],
-      { cpu_mips3 } [],
-      { cpu_mips4 } [],
-      { cpu_mips5 } [],
-      { cpu_mips32 } [],
-      { cpu_mips32r2 } [],
-      { cpu_pic32mx } []
+    ( { cpu_none }     [],
+      { cpu_mips1 }    [],
+      { cpu_mips2 }    [],
+      { cpu_mips3 }    [],
+      { cpu_mips4 }    [CPUMIPS_HAS_CMOV],
+      { cpu_mips5 }    [CPUMIPS_HAS_CMOV],
+      { cpu_mips32 }   [CPUMIPS_HAS_CMOV],
+      { cpu_mips32r2 } [CPUMIPS_HAS_CMOV,CPUMIPS_HAS_ISA32R2],
+      { cpu_pic32mx }  [CPUMIPS_HAS_CMOV,CPUMIPS_HAS_ISA32R2]
     );
 
+{$ifndef MIPSEL}
+type
+   tcontrollertype =
+     (ct_none
+     );
+
+
+Const
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = false;
+
+   { We know that there are fields after sramsize
+     but we don't care about this warning }
+   {$PUSH}
+    {$WARN 3177 OFF}
+   embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
+   (
+      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+   {$POP}
+{$ELSE MIPSEL}
+   { Is there support for dealing with multiple microcontrollers available }
+   { for this platform? }
+   ControllerSupport = true;
 
 type
    tcontrollertype =

+ 96 - 24
compiler/mips/ncpuadd.pas

@@ -37,27 +37,30 @@ type
     procedure cmp64_lt(left_reg, right_reg: TRegister64;unsigned:boolean);
     procedure cmp64_le(left_reg, right_reg: TRegister64;unsigned:boolean);
     procedure second_generic_cmp32(unsigned: boolean);
+    procedure second_mul64bit;
   protected
     procedure second_addfloat; override;
     procedure second_cmpfloat; override;
     procedure second_cmpboolean; override;
     procedure second_cmpsmallset; override;
+    procedure second_add64bit; override;
     procedure second_cmp64bit; override;
     procedure second_cmpordinal; override;
     procedure second_addordinal; override;
   public
-    function pass_1: tnode; override;
     function use_generic_mul32to64: boolean; override;
+    function use_generic_mul64bit: boolean; override;
   end;
 
 implementation
 
 uses
-  systems,
+  systems, globtype, globals,
   cutils, verbose,
   paramgr,
   aasmtai, aasmcpu, aasmdata,
   defutil,
+  cpuinfo,
   {cgbase,} cgcpu, cgutils,
   cpupara,
   procinfo,
@@ -91,6 +94,15 @@ begin
 end;
 
 
+procedure tmipsaddnode.second_add64bit;
+begin
+  if (nodetype=muln) then
+    second_mul64bit
+  else
+    inherited second_add64bit;
+end;
+
+
 const
   cmpops: array[boolean] of TOpCmp = (OC_LT,OC_B);
 
@@ -185,21 +197,6 @@ begin
 end;
 
 
-function tmipsaddnode.pass_1 : tnode;
-  begin
-    result:=inherited pass_1;
-
-    if not(assigned(result)) then
-      begin
-        if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) then
-          begin
-            if (left.resultdef.typ=floatdef) or (right.resultdef.typ=floatdef) then
-              expectloc:=LOC_JUMP;
-          end;
-      end;
-  end;
-
-
 procedure tmipsaddnode.second_addfloat;
 var
   op: TAsmOp;
@@ -273,7 +270,7 @@ begin
 
   hlcg.location_force_fpureg(current_asmdata.CurrAsmList, left.location, left.resultdef, True);
   hlcg.location_force_fpureg(current_asmdata.CurrAsmList, right.location, right.resultdef, True);
-  location_reset(location, LOC_JUMP, OS_NO);
+  location_reset(location, LOC_FLAGS, OS_NO);
 
   op:=ops_cmpfloat[left.location.size=OS_F64,nodetype];
 
@@ -289,14 +286,11 @@ begin
     end;
 
   current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,lreg,rreg));
-  ai:=taicpu.op_sym(A_BC,current_procinfo.CurrTrueLabel);
+  location.resflags.reg1:=NR_FCC0;
   if (nodetype=unequaln) then
-    ai.SetCondition(C_COP1FALSE)
+    location.resflags.cond:=OC_EQ
   else
-    ai.SetCondition(C_COP1TRUE);
-  current_asmdata.CurrAsmList.concat(ai);
-  current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
-  cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
+    location.resflags.cond:=OC_NE;
 end;
 
 
@@ -345,12 +339,90 @@ begin
     inherited second_addordinal;
 end;
 
+procedure tmipsaddnode.second_mul64bit;
+var
+  list: TAsmList;
+  hreg1,hreg2,tmpreg: TRegister;
+begin
+  list:=current_asmdata.CurrAsmList;
+  pass_left_right;
+  location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+  hlcg.location_force_reg(list,left.location,left.resultdef,left.resultdef,true);
+  { calculate 32-bit terms lo(right)*hi(left) and hi(left)*lo(right) }
+  hreg1:=NR_NO;
+  hreg2:=NR_NO;
+  tmpreg:=NR_NO;
+  if (right.location.loc=LOC_CONSTANT) then
+    begin
+      { Omit zero terms, if any }
+      if hi(right.location.value64)<>0 then
+        begin
+          hreg2:=cg.getintregister(list,OS_INT);
+          tmpreg:=cg.getintregister(list,OS_INT);
+          cg.a_load_const_reg(list,OS_INT,longint(hi(right.location.value64)),tmpreg);
+          list.concat(taicpu.op_reg_reg_reg(A_MUL,hreg2,tmpreg,left.location.register64.reglo));
+        end;
+      tmpreg:=NR_NO;
+      if lo(right.location.value64)<>0 then
+        begin
+          hreg1:=cg.getintregister(list,OS_INT);
+          tmpreg:=cg.getintregister(list,OS_INT);
+          cg.a_load_const_reg(list,OS_INT,longint(lo(right.location.value64)),tmpreg);
+          list.concat(taicpu.op_reg_reg_reg(A_MUL,hreg1,tmpreg,left.location.register64.reghi));
+        end;
+    end
+  else
+    begin
+      hlcg.location_force_reg(list,right.location,right.resultdef,right.resultdef,true);
+      tmpreg:=right.location.register64.reglo;
+      hreg1:=cg.getintregister(list,OS_INT);
+      hreg2:=cg.getintregister(list,OS_INT);
+      list.concat(taicpu.op_reg_reg_reg(A_MUL,hreg1,right.location.register64.reglo,left.location.register64.reghi));
+      list.concat(taicpu.op_reg_reg_reg(A_MUL,hreg2,right.location.register64.reghi,left.location.register64.reglo));
+    end;
+
+  { At this point, tmpreg is either lo(right) or NR_NO if lo(left)*lo(right) is zero }
+  if (tmpreg=NR_NO) then
+    begin
+      if (hreg2<>NR_NO) and (hreg1<>NR_NO) then
+        begin
+          location.register64.reghi:=cg.getintregister(list,OS_INT);
+          list.concat(taicpu.op_reg_reg_reg(A_ADDU,location.register64.reghi,hreg1,hreg2));
+        end
+      else if (hreg2<>NR_NO) then
+        location.register64.reghi:=hreg2
+      else if (hreg1<>NR_NO) then
+        location.register64.reghi:=hreg1
+      else
+        InternalError(2014122701);
+      location.register64.reglo:=NR_R0;
+    end
+  else
+    begin
+      list.concat(taicpu.op_reg_reg(A_MULTU,left.location.register64.reglo,tmpreg));
+      location.register64.reghi:=cg.getintregister(list,OS_INT);
+      location.register64.reglo:=cg.getintregister(list,OS_INT);
+      current_asmdata.CurrAsmList.Concat(taicpu.op_reg(A_MFLO,location.register64.reglo));
+      current_asmdata.CurrAsmList.Concat(taicpu.op_reg(A_MFHI,location.register64.reghi));
+      if (hreg2<>NR_NO) then
+        list.concat(taicpu.op_reg_reg_reg(A_ADDU,location.register64.reghi,location.register64.reghi,hreg2));
+      if (hreg1<>NR_NO) then
+        list.concat(taicpu.op_reg_reg_reg(A_ADDU,location.register64.reghi,location.register64.reghi,hreg1));
+    end;
+end;
 
 function tmipsaddnode.use_generic_mul32to64: boolean;
 begin
   result:=false;
 end;
 
+function tmipsaddnode.use_generic_mul64bit: boolean;
+begin
+  result:=(cs_check_overflow in current_settings.localswitches) or
+    (not (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]));
+end;
+
+
 begin
   caddnode := tmipsaddnode;
 end.

+ 2 - 3
compiler/mips/ncpucnv.pas

@@ -156,12 +156,11 @@ begin
     current_asmdata.getdatalabel(l1);
     current_asmdata.getjumplabel(l2);
     reference_reset_symbol(href, l1, 0, sizeof(aint));
-    hregister := cg.getintregister(current_asmdata.CurrAsmList, OS_32);
-    hlcg.a_load_loc_reg(current_asmdata.CurrAsmList, left.resultdef, u32inttype, left.location, hregister);
+    hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
 
     { Always load into 64-bit FPU register }
     loadsigned(s64real);
-    cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, OS_INT, OC_GTE, 0, hregister, l2);
+    cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, OS_INT, OC_GTE, 0, left.location.register, l2);
 
     case tfloatdef(resultdef).floattype of
       { converting dword to s64real first and cut off at the end avoids precision loss }

+ 35 - 7
compiler/mips/rgcpu.pas

@@ -131,22 +131,50 @@ implementation
         result:=false;
         { Replace 'move  orgreg,src' with 'sw  src,spilltemp'
               and 'move  dst,orgreg' with 'lw  dst,spilltemp' }
-        { TODO: A_MOV_S and A_MOV_D for float registers are also replaceable }
-        if (instr.opcode<>A_MOVE) or (abs(spilltemp.offset)>32767) then
+
+        if (not (instr.opcode in [A_MOVE,A_MOV_S,A_MOV_D,A_MTC1])) or (abs(spilltemp.offset)>32767) then
           exit;
         if (instr.ops<>2) or
            (instr.oper[0]^.typ<>top_reg) or
-           (instr.oper[1]^.typ<>top_reg) or
-           (getregtype(instr.oper[0]^.reg)<>regtype) or
-           (getregtype(instr.oper[1]^.reg)<>regtype) then
+           (instr.oper[1]^.typ<>top_reg) then
           InternalError(2013061001);
+        if (getregtype(instr.oper[0]^.reg)<>regtype) or
+           (getregtype(instr.oper[1]^.reg)<>regtype) then
+          begin
+            if (instr.opcode=A_MTC1) then
+              begin
+                { TODO: MTC1 src,orgreg  ==>  SW    src,0/4(spilltemp) (endian-dependent!!) }
+                if (regtype=R_FPUREGISTER) then
+                  exit;
+              end
+            else
+              InternalError(2013061003);
+          end;
         if get_alias(getsupreg(instr.oper[1]^.reg))=orgreg then
           begin
-            instr.opcode:=A_LW;
+            case instr.opcode of
+              A_MOVE:  instr.opcode:=A_LW;
+              A_MOV_S: instr.opcode:=A_LWC1;
+              A_MOV_D: instr.opcode:=A_LDC1;
+            else
+              InternalError(2013061004);
+            end;
           end
         else if get_alias(getsupreg(instr.oper[0]^.reg))=orgreg then
           begin
-            instr.opcode:=A_SW;
+            case instr.opcode of
+              A_MOVE:  instr.opcode:=A_SW;
+              A_MOV_S: instr.opcode:=A_SWC1;
+              A_MOV_D: instr.opcode:=A_SDC1;
+              A_MTC1:
+                begin
+                  if (getregtype(instr.oper[0]^.reg)<>R_INTREGISTER) then
+                    InternalError(2013061006);
+                  instr.opcode:=A_LWC1;
+                end
+            else
+              InternalError(2013061005);
+            end;
             instr.oper[0]^:=instr.oper[1]^;
           end
         else

+ 2 - 2
compiler/msg/errorct.msg

@@ -264,7 +264,7 @@ scan_e_unsupported_asmmode_specifier=02050_E_L'estil d'assemblador especificat "
 % the compiler didn't recognize the mode you specified.
 scan_w_no_asm_reader_switch_inside_asm=02051_W_No es permet el commutador de lector d'ASM dins d'una declaració ASM, "$1" serà efectiu a continuació
 % It is not possible to switch from one assembler reader to another
-% inside an assmebler block. The new reader will be used for next
+% inside an assembler block. The new reader will be used for next
 % assembler statements only.
 scan_e_wrong_switch_toggle=02052_E_El modificador del commutador és erroni, utilitzeu ON/OFF o +/-
 % You need to use ON or OFF or a + or - to toggle the switch
@@ -2100,7 +2100,7 @@ option_code_page_not_available=11039_E_La p
 #
 option_logo=11023_[
 Free Pascal Compiler versió $FPCFULLVERSION [$FPCDATE] per $FPCCPU
-Copyright (c) 1993-2014 per Florian Klaempfl
+Copyright (c) 1993-2015 per Florian Klaempfl and others
 ]
 
 #

+ 100 - 37
compiler/msg/errord.msg

@@ -3,7 +3,7 @@
 #   Latest updates contributed by Karl-Michael Schindler aka mischi
 #   <karl-michael.schindler at web.de>
 #
-#   Based on errore.msg of SVN revision 28127
+#   Based on errore.msg of SVN revision 29129
 #
 #   This file is part of the Free Pascal Compiler
 #   Copyright (c) 1998-2014 by the Free Pascal Development team
@@ -181,9 +181,9 @@ scan_n_ignored_switch=02008_N_Compilerschalter $1 wurde ignoriert
 scan_w_illegal_switch=02009_W_Compilerschalter $1 ist ung�ltig
 % You included a compiler switch (i.e. \var{\{\$... \}}) which the compiler
 % does not recognise.
-scan_w_switch_is_global=02010_W_Dieser Compilerschalter hat globale Auswirkung
-% The compiler switch is misplaced, and should be located at
-% the start of the unit or program.
+scan_w_switch_is_global=02010_W_Dieser globale Compilerschalter ist an der falschen Stelle und wird deshalb ignoriert
+% The compiler switch is misplaced. It must be located at
+% the start of the compilation unit, before the uses clause or any declaration.
 scan_e_illegal_char_const=02011_E_Ung�ltige Char-Konstante
 % This happens when you specify a character with its ASCII code, as in
 % \var{\#96}, but the number is either illegal, or out of range.
@@ -411,8 +411,9 @@ scan_w_invalid_stacksize=02096_W_Die spezifizierte Gr
 scan_w_heapmax_lessthan_heapmin=02097_W_Die spezifizierte GrӇe des HeapMax ist kleiner als der des HeapMin. Setzen der GrӇe des HeapMax ignoriert.
 % The HeapMax value (if specified) must be greater than or equal to the HeapMin
 % value. Otherwise, the HeapMax value is ignored.
-scan_w_hugepointernormalization_not_support=02098_W_HUGEPOINTERNORMALIZATION wird auf der Zielplatform nicht unterst�tzt
-% The \var{\{\$HUGEPOINTERNORMALIZATION\}} directive is not supported by the target platform.
+scan_e_illegal_hugepointernormalization=02098_E_Illegales Argument f�r HUGEPOINTERNORMALIZATION
+% The only allowed values for HUGEPOINTERNORMALIZATION are BORLANDC, MICROSOFTC
+% and WATCOMC.%
 %
 % \end{description}
 # EndOfTeX
@@ -876,7 +877,7 @@ parser_e_self_in_non_message_handler=03146_E_SELF darf nur in Message-Handlern e
 % The \var{Self} parameter can only be passed explicitly to a method which
 % is declared as message method handler
 parser_e_threadvars_only_sg=03147_E_Threadvariablen k”nnen nur statisch oder global sein
-% Threadvars must be static or global; you can't declare a thread
+% Threadvars must be static or global; you cannot declare a thread
 % local to a procedure. Local variables are always local to a thread,
 % because every thread has its own stack and local variables
 % are stored on the stack.
@@ -893,7 +894,7 @@ parser_e_no_object_override=03150_E_OVERRIDE darf in Objekten nicht verwendet we
 parser_e_cant_use_inittable_here=03151_E_Datentypen, die ein Initialiserung oder Finalisierung ben”tigen, k”nnen in varianten Records nicht verwendet werden
 % Some data types (e.g. \var{ansistring}) need initialization/finalization
 % code which is implicitly generated by the compiler. Such data types
-% can't be used in the variant part of a record.
+% cannot be used in the variant part of a record.
 parser_e_resourcestring_only_sg=03152_E_Resourcestrings d�rfen nur statisch oder global sein
 % Resourcestring cannot be declared local, only global or using the static
 % directive.
@@ -981,7 +982,7 @@ parser_w_skipped_fields_before=03175_W_Einige Felder vor dem Feld "$1" sind nich
 % In Delphi mode, not all fields of a typed constant record have to be
 % initialized, but the compiler warns you when it detects such situations.
 parser_e_skipped_fields_before=03176_E_Einige Felder vor dem Feld "$1" sind nicht initialisiert
-% In all syntax modes but Delphi mode, you can't leave some fields uninitialized
+% In all syntax modes but Delphi mode, you cannot leave some fields uninitialized
 % in the middle of a typed constant record.
 parser_w_skipped_fields_after=03177_W_Einige Felder nach dem Feld "$1" sind nicht initialisiert
 % You can leave some fields at the end of a type constant record uninitialized
@@ -1972,7 +1973,7 @@ type_e_type_not_allowed_for_type_helper=04120_E_Typ "$1" kann durch einen Typhel
 type_e_procedure_must_be_far=04121_E_Prozedur oder Funktion muss weit ("far") sein, damit seine Adresse verwendet werden kann: "$1"
 % In certain i8086 memory models (medium, large and huge), procedures and functions
 % have to be declared 'far' in order to allow their address to be taken.
-type_w_instance_abstract_class=04122_-W_Erzeugung einer Instanz der abstrakten Klasse "$1"
+type_w_instance_abstract_class=04122_W_Erzeugung einer Instanz der abstrakten Klasse "$1"
 % The specified class is declared as \var{abstract} and thus no instance of this class
 % should be created. This is merely a warning for Delphi compatibility.
 %
@@ -2317,7 +2318,7 @@ cg_e_cannot_call_cons_dest_inside_with=06037_E_Konstruktoren und Destruktoren k
 % Inside a \var{With} clause you cannot call a constructor or destructor for the
 % object you have in the \var{with} clause.
 cg_e_cannot_call_message_direct=06038_E_Kann Messagehandler-Methode nicht direkt aufrufen
-% A message method handler method can't be called directly if it contains an
+% A message method handler method cannot be called directly if it contains an
 % explicit \var{Self} argument.
 cg_e_goto_inout_of_exception_block=06039_E_Sprung in- oder aus dem Exceptionblock heraus
 % It is not allowed to jump in or outside of an exception block like \var{try..finally..end;}.
@@ -2713,6 +2714,9 @@ asmr_e_invalid_ref_register=07125_E_Ung
 % FPU, vector and sometimes integer registers cannot be used in memory reference
 % expressions, due to limitations of the cpu architecture or simple because
 % it is not meaningful.
+%
+% \end{description}
+# EndOfTeX
 
 #
 # Assembler/binary writers
@@ -2761,6 +2765,9 @@ asmw_e_handlerdata_no_handler=08025_E_".seh_handlerdata"-Direktive ohne vorangeh
 asmw_f_too_many_relocations=08026_F_Relocationz„hler f�r Sektion $1 �bersteigt 65535
 % Legacy COFF targets limit number of relocations per section to 65535 because they use a 2-byte field
 % to store the relocation count. Targets using newer PECOFF format do not have this limitation.
+%
+% \end{description}
+# EndOfTeX
 
 #
 # Executing linker/assembler
@@ -3361,7 +3368,7 @@ wpo_cant_create_feedback_file=12019_E_Die angegebene Feedback-Eingabe-Datei "$1"
 #
 option_logo=11023_[
 Free Pascal Compiler Version $FPCFULLVERSION [$FPCDATE] f�r $FPCTARGET
-Copyright (c) 1993-2014 Florian Kl„mpfl und andere
+Copyright (c) 1993-2015 Florian Kl„mpfl und andere
 ]
 
 #
@@ -3370,10 +3377,10 @@ Copyright (c) 1993-2014 Florian Kl
 option_info=11024_[
 Free Pascal Compiler Version $FPCVERSION
 
-Compiler Datum:      $FPCDATE
-Compiler Zielsystem: $FPCCPU
+Compiler-Datum:      $FPCDATE
+Compiler-Zielsystem: $FPCCPU
 
-Unterst�tzte Zielbetriebssysteme:
+Unterst�tzte Zielbetriebssysteme (Mit '{*}' markierte Ziele sind in Entwicklung):
   $OSTARGETS
 
 Unterst�tzte CPU Instruktionen:
@@ -3385,6 +3392,9 @@ Unterst
 Unterst�tzte Inline-Assembler Modi:
   $ASMMODES
 
+Bekannte Compiler und RTL Feature:
+  $FEATURELIST
+
 Unterst�tzte ABI Ziele:
   $ABITARGETS
 
@@ -3395,7 +3405,7 @@ Unterst
   All
   $WPOPTIMIZATIONS
 
-Unterst�tzte Microcontroller:
+Unterst�tzte Mikro-Kontroller:
   $CONTROLLERTYPES
 
 Dieses Programm unterliegt der GNU General Public Licence
@@ -3404,7 +3414,7 @@ Weitere Informationen sind in COPYING.v2 zu finden
 Fehlerberichte bitte senden an:
              http://bugs.freepascal.org
 
-Weiter Information stehen auf unseren WWW Seiten (einschlieálich Links zu
+Weitere Informationen stehen auf unseren WWW Seiten (einschlieálich Links zu
 Mailing-Listen, auf denen Fragen gestellt und potentielle neue Features 
 diskutiert werden k”nnen, usw.):
                  http://www.freepascal.org
@@ -3423,9 +3433,14 @@ diskutiert werden k
 #    A = ARM
 #    e = in extended debug mode only
 #    F = help for the 'fpc' binary (independent of the target compiler)
+#    I = VIS
+#    J = JVM
+#    M = MIPS (MIPSEB) targets
+#    m = MIPSEL targets
 #    P = PowerPC targets
+#    p = PowerPC64 targets
 #    S = Sparc targets
-#    V = Virtual machine targets
+#    V = AVR
 # The second character also indicates who will display this line,
 # (if the above character was TRUE) the current possibilities are :
 #    * = everyone
@@ -3435,8 +3450,10 @@ diskutiert werden k
 #  The third character represents the indentation level.
 #
 option_help_pages=11025_[
+F*0*_Es werden nur Optionen aufgelistet, die f�r die voreingestellte oder ausgew„hlte Platform g�ltig sind.
 **0*_Nach booleschen Optionen geben Sie + zum Ein- bzw. - zum Ausschalten an
-**1a_L”sche die erzeugte Assembler-Datei nicht
+**1@<x>_Lese zus„tzlich zu den voreingestellten Compiler-Optionen aus fpc.cfg auch die aus <x>
+**1a_Erzeugte Assembler-Datei nicht l”schen
 **2al_Liste Quellcode-Zeilen in der Assembler-Datei
 **2an_Liste "node info" in der Assembler-Datei (-dEXTDEBUG Compiler)
 **2ao_F�ge eine zus„tzliche Option zum Aufruf des externen Assemblers hinzu (ignoriert f�r den internen Assembler)
@@ -3486,12 +3503,12 @@ S*2Aas_Assembliere mit Hilfe von GNU AS
 **1B_Erzeuge alle Module (Build)
 **1C<x>_Optionen f�r Code-Erzeugung:
 **2C3<x>_Schalte ieee-Pr�fung von Konstanten ein
-**2Ca<x>_W„hle ABI aus; fpc -i gibt die m”glichen Werte aus
+**2Ca<x>_W„hle ABI aus; fpc -i oder fpc -ia geben die m”glichen Werte aus
 **2Cb_Erzeuge Code f�r die "big-endian"-Variante der Zielarchitektur
 **2Cc<x>_Setze "default calling convention" zu <x>
 **2CD_Erzeuge auch eine dynamische Bibliothek (nicht unterst�tzt)
 **2Ce_šbersetze mit emulierten Fliesskomma opcodes
-**2Cf<x>_W„hle den Fliesskomma-Instruction-Set aus; fpc -i gibt die m”glichen Werte aus
+**2Cf<x>_W„hle den Fliesskomma-Instruction-Set aus; fpc -i oder fpc -if geben die m”glichen Werte aus
 **2CF<x>_Minimale Pr„zission von Fliesskommakonstanten (default, 32, 64)
 **2Cg_Erzeuge PIC code
 **2Ch<n>_<n> Bytes Heap (zwischen 1023 und 67107840)
@@ -3501,7 +3518,7 @@ A*2CI<x>_W
 P*2CN_Erzeuge šberpr�fungen auf Nil-Zeiger (nur AIX)
 **2Co_Pr�fe auf šberlauf von Integer-Operationen
 **2CO_Pr�fe auf m”glichen šberlauf von Integer-Operationen
-**2Cp<x>_W„hle Instruction-Set aus; fpc -i gibt die m”glichen Werte aus
+**2Cp<x>_W„hle Instruction-Set aus; fpc -i oder fpc -ic geben die m”glichen Werte aus
 **2CP<x>=<y>_ Einstellungen f�r packing
 **3CPPACKSET=<y>_ <y> Belegung von Sets: 0, 1 oder DEFAULT oder NORMAL, 2, 4 und 8
 **2Cr_F�hre Bereichspr�fung durch
@@ -3568,20 +3585,29 @@ J*2Cv_Var/out Parameter copy-out 
 *g3godwarfmethodclassprefix_ Stelle Methodennamen in DWARF den Namen der Klasse voran
 *g2gp_Erhalte Gross/Kleinschreibung in Stabs-Symbolnamen
 *g2gs_Erzeuge Stabs-Debug-Informationen
-*g2gt_L”sche lokale Variablen (um eine Verwendung ohne Initialisierung zu finden)
+*g2gt_L”sche lokale Variablen (um eine Verwendung ohne Initialisierung zu finden; mehrere 't' „ndern den Wert, mit dem �berschrieben wird)
 *g2gv_Erzeuge ein mit Valgrind verfolgbares (traceable) Programm
 *g2gw_Erzeuge DWARFv2-Debug-Informationen (wie -gw2)
 *g2gw2_Erzeuge DWARFv2-Debug-Informationen
 *g2gw3_Erzeuge DWARFv3-Debug-Informationen
-*g2gw4_Generate DWARFv4-Debug-Informationen (experimentell)
+*g2gw4_Erzeuge DWARFv4-Debug-Informationen (experimentell)
 **1i_Zeige alle Informationen �ber den Compiler
 **2iD_Zeige Compilerdatum
-**2iV_Zeige Compilerversion
-**2iW_Zeige vollst„ndige Compilerversion
 **2iSO_Zeige Compilerbetriebssystem
 **2iSP_Zeige Compilerprozessor
 **2iTO_Zeige Zielbetriebssystem
 **2iTP_Zeige Zielprozessor
+**2iV_Zeige kurze Compilerversion
+**2iW_Zeige vollst„ndige Compilerversion
+**2ia_Zeige Liste der unterst�tzten ABI-Ziele
+**2ic_Zeige Liste der unterst�tzten CPU-Instruction-Sets
+**2if_Zeige Liste der unterst�tzten Fliesskomma-Instruction-Sets
+**2ii_Zeige Liste der unterst�tzten Inline-Assembler-Modi
+**2io_Zeige Liste der unterst�tzten Optimierungen
+**2ir_Zeige Liste der erkannten Compiler- und RTL-Feature
+**2it_Zeige Liste der unterst�tzten Ziele
+**2iu_Zeige Liste der unterst�tzten Mikro-Kontrollertypen
+**2iw_Zeige Liste der unterst�tzten Gesamtprogramm-Optimierungen
 **1I<x>_Erg„nze <x> zum Include-Pfad
 **1k<x>_šbergebe <x> an den Linker
 **1l_Zeige Logo
@@ -3600,16 +3626,16 @@ J*2Cv_Var/out Parameter copy-out 
 **2O3_Level 3 Optimierung (-O2 + langsame Optimierungen)
 **2O4_Level 4 Optimierung (-O3 + Optimierungen, die unerwartete Nebeneffekte haben k”nnen)
 **2Oa<x>=<y>_Ausrichtung (alignment) von Mengen
-**2Oo[NO]<x>_Optimierungen ein- oder ausschalten; fpc -i gibt die m”glichen Werte aus
-**2Op<x>_Setze Zielprozessor f�r die Optimierung; fpc -i gibt die m”glichen Werte aus
-**2OW<x>_Erzeuge Feedback f�r die Gesamtprogramm-Optimierung f�r Optimierung <x>, siehe fpc -i f�r m”gliche Werte
-**2Ow<x>_F�hre die Gesamtprogramm-Optimierung durch <x>, siehe fpc -i f�r m”gliche Werte
+**2Oo[NO]<x>_Optimierungen ein- oder ausschalten; fpc -i oder fpc -io geben die m”glichen Werte aus
+**2Op<x>_Setze Zielprozessor f�r die Optimierung; fpc -i oder fpc -ic geben die m”glichen Werte aus
+**2OW<x>_Erzeuge Feedback f�r die Gesamtprogramm-Optimierung f�r Optimierung <x>; fpc -i oder fpc -iw geben die m”glichen Werte aus
+**2Ow<x>_F�hre die Gesamtprogramm-Optimierung durch <x>; fpc -i oder fpc -iw  geben die m”glichen Werte aus
 **2Os_Erzeuge k�rzeren Code
 **1pg_Erzeuge Profiler-Code f�r gprof
 F*1P<x>_Ziel CPU / Compiler bezogene Optionen:
 F*2PB_Zeige die voreingestellte Compilerbin„rdatei
 F*2PP_Zeige die voreingestellte Ziel-CPU
-F*2P<x>_Setze die Ziel-CPU (arm, i386, m68k, mips, mipsel, powerpc, powerpc64, sparc, x86_64)
+F*2P<x>_Setze die Ziel-CPU (arm, avr, i386, jvm, m68k, mips, mipsel, powerpc, powerpc64, sparc, x86_64)
 **1R<x>_Assembler Code-Format:
 **2Rdefault_Benutze den voreingestellten Assembler
 3*2Ratt_Lese Assembler Code im AT&T-Format
@@ -3625,6 +3651,7 @@ F*2P<x>_Setze die Ziel-CPU (arm, i386, m68k, mips, mipsel, powerpc, powerpc64, s
 **3*_w : Compiler h„lt auch nach Warnungen
 **3*_n : Compiler h„lt auch nach Anmerkungen
 **3*_h : Compiler h„lt auch nach Hinweisen
+**2Sf_Schalte bestimmte Feature in Compiler und RTL ein; fpc -i oder fpc -ir geben die m”glichen Werte aus
 **2Sg_Erlaube LABEL und GOTO
 **2Sh_Benutze ANSI-Strings
 **2Si_Benutze C++ artige INLINE
@@ -3635,6 +3662,7 @@ F*2P<x>_Setze die Ziel-CPU (arm, i386, m68k, mips, mipsel, powerpc, powerpc64, s
 **2Sm_Unterst�tze Makros wie in C (global)
 **2So_Sei TP/BP 7.0 kompatibel (wie -Mtp)
 **2Ss_Konstruktor- und Destruktorname m�ssen "Init" und "Done" sein
+**2Sv_Unterst�tze Vektor-Verarbeitung (soweit vorhanden benutze CPU-Vektorerweiterungen)
 **2Sx_Exception Schl�sselw”rter einschalten (Voreinstellung in Delphi/ObjFPC Moden)
 **2Sy_@<pointer> gibt einen typisierten Zeiger zur�ck, genau wie $T+
 **1s_Rufe weder Assembler noch Linker auf (nur mit -a)
@@ -3642,10 +3670,15 @@ F*2P<x>_Setze die Ziel-CPU (arm, i386, m68k, mips, mipsel, powerpc, powerpc64, s
 **2st_Erzeuge Script um auf dem Zielsystem zu linken
 **2sr_šberspringe die Phase der "register allocation" (mit -alr benutzen)
 **1T<x>_Zielbetriebssystem::
+3*2Tandroid_Android
+3*2Taros_AROS
+3*2Tbeos_BeOS
 3*2Tdarwin_Darwin/Mac OS X
+3*2Tembedded_Embedded
 3*2Temx_OS/2 via EMX (einschliesslich EMX/RSX extender)
 3*2Tfreebsd_FreeBSD
 3*2Tgo32v2_Version 2 des DJ Delorie DOS extender
+3*2Thaiku_Haiku
 3*2Tlinux_Linux
 3*2Tnativent_Native NT API (experimentell)
 3*2Tnetbsd_NetBSD
@@ -3661,22 +3694,45 @@ F*2P<x>_Setze die Ziel-CPU (arm, i386, m68k, mips, mipsel, powerpc, powerpc64, s
 3*2Twin32_Windows 32 Bit
 3*2Twince_Windows CE
 4*2Tdarwin_Darwin/Mac OS X
+4*2Tfreebsd_FreeBSD
 4*2Tlinux_Linux
-4*2Twin64_Win64 (64 bit Windows systems)
+4*2Tnetbsd_NetBSD
+4*2Topenbsd_OpenBSD
+4*2Tsolaris_Solaris
+4*2Twin64_Win64 (64 bit Windows Systeme)
 6*2Tamiga_Commodore Amiga
 6*2Tatari_Atari ST/STe/TT
 6*2Tlinux_Linux
 6*2Tpalmos_PalmOS
+8*2Tmsdos_MS-DOS (und kompatible)
+A*2Tandroid_Android
 A*2Tdarwin_Darwin/iPhoneOS/iOS
+A*2Tembedded_Embedded
+A*2Tgba_Game Boy Advance
 A*2Tlinux_Linux
+A*2Tnds_Nintendo DS
+A*2Tsymbian_Symbian
 A*2Twince_Windows CE
+J*2Tandroid_Android
+J*2Tjava_Java
+m*2Tembedded_Embedded
+M*2Tandroid_Android
+M*2Tembedded_Embedded
+M*2Tlinux_Linux
+P*2Taix_AIX
 P*2Tamiga_AmigaOS
 P*2Tdarwin_Darwin und Mac OS X
 P*2Tlinux_Linux
 P*2Tmacos_Mac OS (classic)
 P*2Tmorphos_MorphOS
+P*2Tnetbsd_NetBSD
+P*2Twii_Wii
+p*2Taix_AIX
+p*2Tdarwin_Darwin/Mac OS X
+p*2Tlinux_Linux
 S*2Tsolaris_Solaris
 S*2Tlinux_Linux
+V*2Tembedded_Embedded
 **1u<x>_Entferne die Definition f�r das Symbol <x>
 **1U<x>_Unit-Optionen:
 **2Un_Pr�fe den Unitnamen nicht
@@ -3690,7 +3746,7 @@ S*2Tlinux_Linux
 **2*_i : Allgemeine Informationen      d : Debug Informationen
 **2*_l : Zeilennummern                 r : Rhide/GCC kompatibler Modus
 **2*_s : Zeitstempel                   q : Nummer der Meldung
-**2*_a : Alles                         x : Exe-Datei Informationen (nur Win32)
+**2*_a : Alles                         x : Zeige Infos �ber aufgerufene Tools
 **2*_b : Schreibe bei Meldungen mit    p : Schreibe tree.log mit Analysenbaum (parse tree)
 **2*_    Dateinamen den vollst„ndigen  v : Schreibe fpcdebug.txt mit 
 **2*_    Pfad                              ganz viel Information
@@ -3712,7 +3768,7 @@ A*2Wb_Erzeuge statt einer Bibliothek ein Bundle (Darwin)
 A*2WB_Erzeuge ein relozierbares Image (Windows, Symbian)
 A*2WBxxxx_Setze die Imagebasis auf xxxx (Windows)
 3*2WC_Spezifiziere "console type application" (EMX, OS/2, Windows)
-4*2WC_Spezifiziere "console type application" (EMX, OS/2, Windows)
+4*2WC_Spezifiziere "console type application" (Windows)
 A*2WC_Spezifiziere "console type application" (Windows)
 P*2WC_Spezifiziere "console type application" (Classic Mac OS)
 3*2WD_Benutze DEFFILE um Funktionen der DLL oder EXE zu exportieren (Windows)
@@ -3725,7 +3781,7 @@ P*2We_Benutze externe Resourcen (Darwin)
 p*2We_Benutze externe Resourcen (Darwin)
 3*2WF_Spezifiziere "full-screen type application" (EMX, OS/2)
 3*2WG_Spezifiziere "graphic type application" (EMX, OS/2, Windows)
-4*2WG_Spezifiziere "graphic type application" (EMX, OS/2, Windows)
+4*2WG_Spezifiziere "graphic type application" (Windows)
 A*2WG_Spezifiziere "graphic type application" (Windows)
 P*2WG_Spezifiziere "graphic type application" (Classic Mac OS)
 3*2Wi_Benutze interne Resourcen (Darwin)
@@ -3749,8 +3805,9 @@ P*2WM<x>_Minimale Mac OS X Deployment Version: 10.4, 10.5.1, ... (Darwin)
 3*2WN_Erzeuge keinen "relocation code" (notwendig f�r debugging) (Windows)
 4*2WN_Erzeuge keinen "relocation code" (notwendig f�r debugging) (Windows)
 A*2WN_Erzeuge keinen "relocation code" (notwendig f�r debugging) (Windows)
-A*2Wpxxxx_Spezifiziere den Kontrollertyp, m”gliche Werte liefert fpc -i
-V*2Wpxxxx_Spezifiziere den Kontrollertyp, m”gliche Werte liefert fpc -i
+A*2Wpxxxx_Spezifiziere den Kontrollertyp; fpc -i oder fpc -iu geben m”gliche Werte aus
+m*2Wpxxxx_Spezifiziere den Kontrollertyp; fpc -i oder fpc -iu geben m”gliche Werte aus
+V*2Wpxxxx_Spezifiziere den Kontrollertyp; fpc -i oder fpc -iu  geben m”gliche Werte aus
 3*2WP<x>_Minimale iOS Deployment Version: 3.0, 5.0.1, ... (iphonesim)
 A*2WP<x>_Minimale iOS Deployment Version: 3.0, 5.0.1, ... (Darwin)
 3*2WR_Erzeuge "relocation code" (Windows)
@@ -3765,11 +3822,16 @@ P*2WF_Spezifiziere "MPW tool type application" (Classic Mac OS)
 **2Xc_šbergebe --shared an den Linker (nur Unix)
 **2Xd_Den Standard Bibliotheks-Suchpfad NICHT nutzen (ben”tigt f�r cross compile, wenn nicht -XR verwendet wird)
 **2Xe_Verwende den externen Linker
+**2Xf_Ersetze zum Linken den Namen der pthread-Bibliothek (BSD)
 **2Xg_Erstelle die Debug-Informationen in einer separaten Datei und einen "Debug-Link"-Abschnitt im ausf�hrbaren Programm
 **2XD_Versuche Units dynamisch zu linken             (definiert FPC_LINK_DYNAMIC)
 **2Xi_Verwende den internen Linker
+**2XLA_Definiere Bibliotheksersetzungen f�r das Linken
+**2XLO_Definiere die Reihenfolge der Bibliotheken f�r das Linken
+**2XLD_Schlieáe die voreingestellte Reihenfolge der Standard-Bibliotheken aus
 **2Xm_Erzeuge die "link map"
 **2XM<x>_Setze den Namen der 'main' program Routine   (default ist 'main')
+**2Xn_Nutze den platformeigenen linker des Zielsystem anstelle des GNU ld (Solaris, AIX)
 F*2Xp<x>_Suche nach der Compilerbinary zuerst im Verzeichnis <x>
 **2XP<x>_Stelle dem Namen der Compiler-Hilfsprogramme (binutils) den Prefix <x> voran
 **2Xr<x>_Setze den rlink-Pfad des Linker zu <x> (ben”tigt f�r cross compile, siehe ld-Manual f�r mehr Informationen) (BeOS, Linux)
@@ -3777,6 +3839,7 @@ F*2Xp<x>_Suche nach der Compilerbinary zuerst im Verzeichnis <x>
 **2Xs_Entferne alle Symbole aus der ausf�hrbaren Datei
 **2XS_Versuche Units statisch zu linken (default)    (definiert FPC_LINK_STATIC)
 **2Xt_Linke mit statischen Bibliotheken              (-static wird an den Linker �bergeben)
+**2Xv_Erzeuge eine Tabelle mit den virtuellen Entry-Aufrufen
 **2XX_Versuche Units smart zu linken                 (definiert FPC_LINK_SMART)
 **1*_
 **1?_Zeigt diese Hilfe an

+ 2 - 2
compiler/msg/errorda.msg

@@ -271,7 +271,7 @@ scan_e_illegal_asmmode_specifier=02050_E_Ugyldig assemblerstil angivet "$1"
 % the compiler didn't recognize the mode you specified.
 scan_w_no_asm_reader_switch_inside_asm=02051_W_Kan ikke skifte assemblerlæser midt i en assemblerblok. Skifter til "$1" i næste blok
 % It is not possible to switch from one assembler reader to another
-% inside an assmebler block. The new reader will be used for next
+% inside an assembler block. The new reader will be used for next
 % assembler statements only.
 scan_e_wrong_switch_toggle=02052_E_Forkert indstillingsparameter. Brug ON/OFF eller +/-
 % You need to use ON or OFF or a + or - to toggle the switch
@@ -2207,7 +2207,7 @@ option_config_is_dir=11040_F_Konfigurationsfilen $1 er et directory
 #
 option_logo=11023_[
 Free Pascal Compiler version $FPCFULLVERSION [$FPCDATE] til $FPCTARGET
-Copyright (c) 1993-2014 Florian Klaempfl
+Copyright (c) 1993-2015 Florian Klaempfl and others
 ]
 
 #

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor