فهرست منبع

* synchronised with trunk till r29513

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

+ 230 - 47
.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
@@ -969,6 +971,12 @@ packages/a52/Makefile.fpc svneol=native#text/plain
 packages/a52/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/a52/fpmake.pp svneol=native#text/plain
 packages/a52/src/a52.pas svneol=native#text/plain
+packages/ami-extra/Makefile svneol=native#text/plain
+packages/ami-extra/Makefile.fpc svneol=native#text/plain
+packages/ami-extra/Makefile.fpc.fpcmake svneol=native#text/plain
+packages/ami-extra/README.txt svneol=native#text/plain
+packages/ami-extra/fpmake.pp svneol=native#text/plain
+packages/ami-extra/src/cliputils.pas svneol=native#text/plain
 packages/amunits/Makefile svneol=native#text/plain
 packages/amunits/Makefile.fpc svneol=native#text/plain
 packages/amunits/Makefile.fpc.fpcmake svneol=native#text/plain
@@ -1028,6 +1036,8 @@ packages/amunits/examples/wbtest.pas svneol=native#text/plain
 packages/amunits/fpmake.pp svneol=native#text/plain
 packages/amunits/scripts/getrecord.rexx svneol=native#text/plain
 packages/amunits/scripts/make.rexx svneol=native#text/plain
+packages/amunits/src/coreunits/agraphics.pas svneol=native#text/plain
+packages/amunits/src/coreunits/akeyboard.pas svneol=native#text/plain
 packages/amunits/src/coreunits/amigados.pas svneol=native#text/plain
 packages/amunits/src/coreunits/amigaguide.pas svneol=native#text/plain
 packages/amunits/src/coreunits/amigalib.pas svneol=native#text/plain
@@ -1046,13 +1056,12 @@ packages/amunits/src/coreunits/console.pas svneol=native#text/plain
 packages/amunits/src/coreunits/conunit.pas svneol=native#text/plain
 packages/amunits/src/coreunits/datatypes.pas svneol=native#text/plain
 packages/amunits/src/coreunits/diskfont.pas svneol=native#text/plain
-packages/amunits/src/coreunits/exec.pp svneol=native#text/plain
+packages/amunits/src/coreunits/exec.pas svneol=native#text/plain
 packages/amunits/src/coreunits/expansion.pas svneol=native#text/plain
 packages/amunits/src/coreunits/expansionbase.pas svneol=native#text/plain
 packages/amunits/src/coreunits/gadtools.pas svneol=native#text/plain
 packages/amunits/src/coreunits/gameport.pas svneol=native#text/plain
 packages/amunits/src/coreunits/gradientslider.pas svneol=native#text/plain
-packages/amunits/src/coreunits/graphics.pas svneol=native#text/plain
 packages/amunits/src/coreunits/hardblocks.pas svneol=native#text/plain
 packages/amunits/src/coreunits/hardware.pas svneol=native#text/plain
 packages/amunits/src/coreunits/icon.pas svneol=native#text/plain
@@ -1060,7 +1069,6 @@ packages/amunits/src/coreunits/iffparse.pas svneol=native#text/plain
 packages/amunits/src/coreunits/input.pas svneol=native#text/plain
 packages/amunits/src/coreunits/inputevent.pas svneol=native#text/plain
 packages/amunits/src/coreunits/intuition.pas svneol=native#text/plain
-packages/amunits/src/coreunits/keyboard.pas svneol=native#text/plain
 packages/amunits/src/coreunits/keymap.pas svneol=native#text/plain
 packages/amunits/src/coreunits/layers.pas svneol=native#text/plain
 packages/amunits/src/coreunits/locale.pas svneol=native#text/plain
@@ -1106,6 +1114,7 @@ packages/amunits/src/useautoopenlib.inc svneol=native#text/plain
 packages/amunits/src/utilunits/Makefile svneol=native#text/plain
 packages/amunits/src/utilunits/Makefile.fpc svneol=native#text/plain
 packages/amunits/src/utilunits/amigautils.pas svneol=native#text/plain
+packages/amunits/src/utilunits/amsgbox.pas svneol=native#text/plain
 packages/amunits/src/utilunits/consoleio.pas svneol=native#text/plain
 packages/amunits/src/utilunits/deadkeys.pas svneol=native#text/plain
 packages/amunits/src/utilunits/doublebuffer.pas svneol=native#text/plain
@@ -1113,7 +1122,6 @@ packages/amunits/src/utilunits/easyasl.pas svneol=native#text/plain
 packages/amunits/src/utilunits/hisoft.pas svneol=native#text/plain
 packages/amunits/src/utilunits/linklist.pas svneol=native#text/plain
 packages/amunits/src/utilunits/longarray.pas svneol=native#text/plain
-packages/amunits/src/utilunits/msgbox.pas svneol=native#text/plain
 packages/amunits/src/utilunits/pastoc.pas svneol=native#text/plain
 packages/amunits/src/utilunits/pcq.pas svneol=native#text/plain
 packages/amunits/src/utilunits/systemvartags.pas svneol=native#text/plain
@@ -1122,6 +1130,31 @@ packages/amunits/src/utilunits/timerutils.pas svneol=native#text/plain
 packages/amunits/src/utilunits/vartags.pas svneol=native#text/plain
 packages/amunits/src/utilunits/wbargs.pas svneol=native#text/plain
 packages/amunits/units.txt svneol=native#text/plain
+packages/arosunits/Makefile svneol=native#text/plain
+packages/arosunits/Makefile.fpc svneol=native#text/plain
+packages/arosunits/Makefile.fpc.fpcmake svneol=native#text/plain
+packages/arosunits/fpmake.pp svneol=native#text/plain
+packages/arosunits/src/agraphics.pas svneol=native#text/plain
+packages/arosunits/src/amigados.pas svneol=native#text/plain
+packages/arosunits/src/asl.pas svneol=native#text/plain
+packages/arosunits/src/clipboard.pas svneol=native#text/plain
+packages/arosunits/src/cybergraphics.pas svneol=native#text/plain
+packages/arosunits/src/diskfont.pas svneol=native#text/plain
+packages/arosunits/src/exec.pas svneol=native#text/plain
+packages/arosunits/src/gadtools.pas svneol=native#text/plain
+packages/arosunits/src/hardware.pas svneol=native#text/plain
+packages/arosunits/src/icon.pas svneol=native#text/plain
+packages/arosunits/src/iffparse.pas svneol=native#text/plain
+packages/arosunits/src/inputevent.pas svneol=native#text/plain
+packages/arosunits/src/intuition.pas svneol=native#text/plain
+packages/arosunits/src/keymap.pas svneol=native#text/plain
+packages/arosunits/src/layers.pas svneol=native#text/plain
+packages/arosunits/src/longarray.pas svneol=native#text/plain
+packages/arosunits/src/mui.pas svneol=native#text/plain
+packages/arosunits/src/tagsarray.pas svneol=native#text/plain
+packages/arosunits/src/timer.pas svneol=native#text/plain
+packages/arosunits/src/utility.pas svneol=native#text/plain
+packages/arosunits/src/workbench.pas svneol=native#text/plain
 packages/aspell/LICENSE svneol=native#text/plain
 packages/aspell/LICENSE.ADDON svneol=native#text/plain
 packages/aspell/Makefile svneol=native#text/plain
@@ -1183,6 +1216,7 @@ packages/cdrom/src/wnaspi32.pp svneol=native#text/plain
 packages/chm/Makefile svneol=native#text/plain
 packages/chm/Makefile.fpc svneol=native#text/plain
 packages/chm/Makefile.fpc.fpcmake svneol=native#text/plain
+packages/chm/examples/chmsearch.lpr svneol=native#text/plain
 packages/chm/fpmake.pp svneol=native#text/plain
 packages/chm/src/chmbase.pas svneol=native#text/plain
 packages/chm/src/chmcmd.lpi svneol=native#text/plain
@@ -2091,6 +2125,8 @@ packages/fcl-db/src/dbase/dbf_str_pl.pas svneol=native#text/plain
 packages/fcl-db/src/dbase/dbf_str_pt.pas svneol=native#text/plain
 packages/fcl-db/src/dbase/dbf_str_ru.pas svneol=native#text/plain
 packages/fcl-db/src/dbase/dbf_struct.inc svneol=native#text/plain
+packages/fcl-db/src/dbase/dbf_wnix.inc svneol=native#text/plain
+packages/fcl-db/src/dbase/dbf_wos2.inc svneol=native#text/plain
 packages/fcl-db/src/dbase/dbf_wtil.pas svneol=native#text/plain
 packages/fcl-db/src/dbase/fpmake.inc svneol=native#text/plain
 packages/fcl-db/src/dbase/fpmake.pp svneol=native#text/plain
@@ -2446,6 +2482,8 @@ packages/fcl-net/examples/testproto.pp svneol=native#text/plain
 packages/fcl-net/examples/testsvc.pp svneol=native#text/plain
 packages/fcl-net/examples/testuri.pp svneol=native#text/plain
 packages/fcl-net/fpmake.pp svneol=native#text/plain
+packages/fcl-net/src/amiga/resolve.inc svneol=native#text/plain
+packages/fcl-net/src/aros/resolve.inc svneol=native#text/plain
 packages/fcl-net/src/cnetdb.pp svneol=native#text/plain
 packages/fcl-net/src/fpsock.pp svneol=native#text/plain
 packages/fcl-net/src/httpsvlt.pp svneol=native#text/plain
@@ -4104,14 +4142,18 @@ packages/hash/examples/crctest.pas svneol=native#text/plain
 packages/hash/examples/hmd5.pp svneol=native#text/pascal
 packages/hash/examples/hsha1.pp svneol=native#text/pascal
 packages/hash/examples/md5.ref svneol=native#text/plain
+packages/hash/examples/md5performancetest.pas svneol=native#text/plain
 packages/hash/examples/mdtest.pas svneol=native#text/plain
+packages/hash/examples/sha1performancetest.pas svneol=native#text/plain
 packages/hash/examples/sha1test.pp svneol=native#text/plain
 packages/hash/fpmake.pp svneol=native#text/plain
 packages/hash/src/crc.pas svneol=native#text/plain
 packages/hash/src/hmac.pp svneol=native#text/pascal
 packages/hash/src/md5.pp svneol=native#text/plain
+packages/hash/src/md5i386.inc svneol=native#text/plain
 packages/hash/src/ntlm.pas svneol=native#text/plain
 packages/hash/src/sha1.pp svneol=native#text/plain
+packages/hash/src/sha1i386.inc svneol=native#text/plain
 packages/hash/src/unixcrypt.pas svneol=native#text/plain
 packages/hash/src/uuid.pas svneol=native#text/plain
 packages/hash/tests/tests.pp svneol=native#text/pascal
@@ -4718,7 +4760,7 @@ packages/libgbafpc/examples/template/Makefile.fpc svneol=native#text/plain
 packages/libgbafpc/examples/template/template.pp svneol=native#text/plain
 packages/libgbafpc/fpmake.pp svneol=native#text/plain
 packages/libgbafpc/src/gba.pp svneol=native#text/plain
-packages/libgbafpc/src/gba/BoyScout.inc svneol=native#text/plain
+packages/libgbafpc/src/gba/boyscout.inc svneol=native#text/plain
 packages/libgbafpc/src/gba/core_asm.as svneol=native#text/plain
 packages/libgbafpc/src/gba/disc.inc svneol=native#text/plain
 packages/libgbafpc/src/gba/disc_io.inc svneol=native#text/plain
@@ -5073,6 +5115,24 @@ packages/libndsfpc/examples/graphics/Backgrounds/rotation/Makefile.fpc svneol=na
 packages/libndsfpc/examples/graphics/Backgrounds/rotation/Rotation.pp svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Backgrounds/rotation/data/drunkenlogo.bin -text svneol=unset#application/octet-stream
 packages/libndsfpc/examples/graphics/Backgrounds/rotation/data/palette.bin -text
+packages/libndsfpc/examples/graphics/Effects/Makefile svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Effects/Makefile.fpc svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Effects/windows/Makefile svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Effects/windows/Makefile.fpc svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Effects/windows/gfx/drunkenlogo.grit svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Effects/windows/gfx/drunkenlogo.png -text
+packages/libndsfpc/examples/graphics/Effects/windows/windows.pp svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/Makefile svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/Makefile.fpc svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/Makefile svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/Makefile.fpc svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/backgrounds.pp svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/gfx/devkitlogo.grit svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/gfx/devkitlogo.png -text
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/gfx/drunkenlogo.grit svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/gfx/drunkenlogo.png -text
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/inc/devkitlogo.inc svneol=native#text/plain
+packages/libndsfpc/examples/graphics/Ext_Palettes/backgrounds/inc/drunkenlogo.inc svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Makefile svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Makefile.fpc svneol=native#text/plain
 packages/libndsfpc/examples/graphics/Printing/Makefile svneol=native#text/plain
@@ -5221,6 +5281,7 @@ packages/libndsfpc/src/nds/arm9/sprite.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/trig_lut.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/video.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/arm9/videoGL.inc svneol=native#text/plain
+packages/libndsfpc/src/nds/arm9/window.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/bios.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/card.inc svneol=native#text/plain
 packages/libndsfpc/src/nds/debug.inc svneol=native#text/plain
@@ -5544,6 +5605,31 @@ packages/modplug/Makefile.fpc svneol=native#text/plain
 packages/modplug/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/modplug/fpmake.pp svneol=native#text/plain
 packages/modplug/src/modplug.pas svneol=native#text/plain
+packages/morphunits/Makefile svneol=native#text/plain
+packages/morphunits/Makefile.fpc svneol=native#text/plain
+packages/morphunits/Makefile.fpc.fpcmake svneol=native#text/plain
+packages/morphunits/fpmake.pp svneol=native#text/plain
+packages/morphunits/src/agraphics.pas svneol=native#text/plain
+packages/morphunits/src/ahi.pas svneol=native#text/plain
+packages/morphunits/src/amigados.pas svneol=native#text/plain
+packages/morphunits/src/amigalib.pas svneol=native#text/plain
+packages/morphunits/src/asl.pas svneol=native#text/plain
+packages/morphunits/src/clipboard.pas svneol=native#text/plain
+packages/morphunits/src/datatypes.pas svneol=native#text/plain
+packages/morphunits/src/exec.pas svneol=native#text/plain
+packages/morphunits/src/get9.pas svneol=native#text/plain
+packages/morphunits/src/hardware.pas svneol=native#text/plain
+packages/morphunits/src/iffparse.pas svneol=native#text/plain
+packages/morphunits/src/inputevent.pas svneol=native#text/plain
+packages/morphunits/src/intuition.pas svneol=native#text/plain
+packages/morphunits/src/keymap.pas svneol=native#text/plain
+packages/morphunits/src/kvm.pas svneol=native#text/plain
+packages/morphunits/src/layers.pas svneol=native#text/plain
+packages/morphunits/src/mui.pas svneol=native#text/plain
+packages/morphunits/src/muihelper.pas svneol=native#text/plain
+packages/morphunits/src/timer.pas svneol=native#text/plain
+packages/morphunits/src/tinygl.pas svneol=native#text/plain
+packages/morphunits/src/utility.pas svneol=native#text/plain
 packages/mysql/Makefile svneol=native#text/plain
 packages/mysql/Makefile.fpc svneol=native#text/plain
 packages/mysql/Makefile.fpc.fpcmake svneol=native#text/plain
@@ -6517,6 +6603,11 @@ packages/rtl-console/Makefile svneol=native#text/plain
 packages/rtl-console/Makefile.fpc svneol=native#text/plain
 packages/rtl-console/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/rtl-console/fpmake.pp svneol=native#text/plain
+packages/rtl-console/src/amicommon/keyboard.pp svneol=native#text/plain
+packages/rtl-console/src/amicommon/mouse.pp svneol=native#text/plain
+packages/rtl-console/src/amicommon/video.pp svneol=native#text/plain
+packages/rtl-console/src/amicommon/videodata.inc svneol=native#text/plain
+packages/rtl-console/src/amiga/crt.pp svneol=native#text/plain
 packages/rtl-console/src/emx/crt.pp svneol=native#text/plain
 packages/rtl-console/src/go32v2/crt.pp svneol=native#text/plain
 packages/rtl-console/src/go32v2/keyboard.pp svneol=native#text/plain
@@ -6532,10 +6623,6 @@ packages/rtl-console/src/inc/mouse.inc svneol=native#text/plain
 packages/rtl-console/src/inc/mouseh.inc svneol=native#text/plain
 packages/rtl-console/src/inc/video.inc svneol=native#text/plain
 packages/rtl-console/src/inc/videoh.inc svneol=native#text/plain
-packages/rtl-console/src/morphos/keyboard.pp svneol=native#text/plain
-packages/rtl-console/src/morphos/mouse.pp svneol=native#text/plain
-packages/rtl-console/src/morphos/video.pp svneol=native#text/plain
-packages/rtl-console/src/morphos/videodata.inc svneol=native#text/plain
 packages/rtl-console/src/msdos/crt.pp svneol=native#text/plain
 packages/rtl-console/src/msdos/keyboard.pp svneol=native#text/plain
 packages/rtl-console/src/netware/crt.pp svneol=native#text/plain
@@ -6571,10 +6658,12 @@ packages/rtl-extra/src/aix/clocale.inc svneol=native#text/plain
 packages/rtl-extra/src/aix/osdefs.inc svneol=native#text/plain
 packages/rtl-extra/src/aix/unxsockh.inc svneol=native#text/plain
 packages/rtl-extra/src/amiga/printer.pp svneol=native#text/plain
+packages/rtl-extra/src/amiga/sockets.pp svneol=native#text/plain
 packages/rtl-extra/src/android/clocale.pp svneol=native#text/plain
 packages/rtl-extra/src/android/osdefs.inc svneol=native#text/plain
 packages/rtl-extra/src/android/unixsock.inc svneol=native#text/plain
 packages/rtl-extra/src/android/unxsockh.inc svneol=native#text/plain
+packages/rtl-extra/src/aros/sockets.pp svneol=native#text/plain
 packages/rtl-extra/src/beos/osdefs.inc svneol=native#text/plain
 packages/rtl-extra/src/beos/unixsock.inc svneol=native#text/plain
 packages/rtl-extra/src/beos/unxsockh.inc svneol=native#text/plain
@@ -6646,6 +6735,7 @@ packages/rtl-objpas/Makefile.fpc svneol=native#text/plain
 packages/rtl-objpas/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/rtl-objpas/fpmake.pp svneol=native#text/plain
 packages/rtl-objpas/src/amiga/varutils.pp svneol=native#text/plain
+packages/rtl-objpas/src/aros/varutils.pp svneol=native#text/plain
 packages/rtl-objpas/src/gba/varutils.pp svneol=native#text/plain
 packages/rtl-objpas/src/go32v2/varutils.pp svneol=native#text/plain
 packages/rtl-objpas/src/inc/convutil.inc svneol=native#text/plain
@@ -6674,6 +6764,8 @@ packages/rtl-objpas/src/watcom/varutils.pp svneol=native#text/plain
 packages/rtl-objpas/src/wii/varutils.pp svneol=native#text/plain
 packages/rtl-objpas/src/win/varutils.pp svneol=native#text/plain
 packages/rtl-objpas/src/wince/varutils.pp svneol=native#text/plain
+packages/rtl-unicode/Makefile svneol=native#text/plain
+packages/rtl-unicode/Makefile.fpc svneol=native#text/plain
 packages/rtl-unicode/fpmake.pp svneol=native#text/plain
 packages/rtl-unicode/src/collations/buildcollations.pas svneol=native#text/pascal
 packages/rtl-unicode/src/collations/collation_de.pas svneol=native#text/pascal
@@ -7785,11 +7877,20 @@ rtl/aix/termios.inc svneol=native#text/plain
 rtl/aix/termiosproc.inc svneol=native#text/plain
 rtl/aix/unxconst.inc svneol=native#text/plain
 rtl/aix/unxfunc.inc svneol=native#text/plain
+rtl/amicommon/README.TXT svneol=native#text/plain
+rtl/amicommon/classes.pp svneol=native#text/plain
+rtl/amicommon/dos.pp svneol=native#text/plain
+rtl/amicommon/osdebug.inc svneol=native#text/plain
+rtl/amicommon/osdebugh.inc svneol=native#text/plain
+rtl/amicommon/rtldefs.inc svneol=native#text/plain
+rtl/amicommon/sysdir.inc svneol=native#text/plain
+rtl/amicommon/sysfile.inc svneol=native#text/plain
+rtl/amicommon/sysheap.inc svneol=native#text/plain
+rtl/amicommon/sysos.inc svneol=native#text/plain
+rtl/amicommon/sysosh.inc svneol=native#text/plain
+rtl/amicommon/sysutils.pp svneol=native#text/plain
 rtl/amiga/Makefile svneol=native#text/plain
 rtl/amiga/Makefile.fpc svneol=native#text/plain
-rtl/amiga/classes.pp svneol=native#text/plain
-rtl/amiga/crt.pp svneol=native#text/plain
-rtl/amiga/dos.pp svneol=native#text/plain
 rtl/amiga/doslibd.inc svneol=native#text/plain
 rtl/amiga/m68k/doslibf.inc svneol=native#text/plain
 rtl/amiga/m68k/execd.inc svneol=native#text/plain
@@ -7805,14 +7906,7 @@ rtl/amiga/powerpc/prt0.as svneol=native#text/plain
 rtl/amiga/powerpc/utild1.inc svneol=native#text/plain
 rtl/amiga/powerpc/utild2.inc svneol=native#text/plain
 rtl/amiga/powerpc/utilf.inc svneol=native#text/plain
-rtl/amiga/rtldefs.inc svneol=native#text/plain
-rtl/amiga/sysdir.inc svneol=native#text/plain
-rtl/amiga/sysfile.inc svneol=native#text/plain
-rtl/amiga/sysheap.inc svneol=native#text/plain
-rtl/amiga/sysos.inc svneol=native#text/plain
-rtl/amiga/sysosh.inc svneol=native#text/plain
 rtl/amiga/system.pp svneol=native#text/plain
-rtl/amiga/sysutils.pp svneol=native#text/plain
 rtl/amiga/timerd.inc svneol=native#text/plain
 rtl/amiga/tthread.inc svneol=native#text/plain
 rtl/android/Makefile svneol=native#text/plain
@@ -7820,6 +7914,7 @@ rtl/android/Makefile.fpc svneol=native#text/plain
 rtl/android/arm/dllprt0.as svneol=native#text/plain
 rtl/android/arm/prt0.as svneol=native#text/plain
 rtl/android/cwstring.pp svneol=native#text/plain
+rtl/android/dlandroid.inc svneol=native#text/plain
 rtl/android/i386/dllprt0.as svneol=native#text/plain
 rtl/android/i386/prt0.as svneol=native#text/plain
 rtl/android/jvm/Makefile svneol=native#text/plain
@@ -7833,6 +7928,7 @@ rtl/android/mipsel/dllprt0.as svneol=native#text/plain
 rtl/android/mipsel/prt0.as svneol=native#text/plain
 rtl/arm/arm.inc svneol=native#text/plain
 rtl/arm/armdefines.inc svneol=native#text/plain
+rtl/arm/divide.inc svneol=native#text/plain
 rtl/arm/int64p.inc svneol=native#text/plain
 rtl/arm/makefile.cpu svneol=native#text/plain
 rtl/arm/math.inc svneol=native#text/plain
@@ -7844,6 +7940,22 @@ rtl/arm/strings.inc svneol=native#text/plain
 rtl/arm/stringss.inc svneol=native#text/plain
 rtl/arm/thumb.inc svneol=native#text/plain
 rtl/arm/thumb2.inc svneol=native#text/plain
+rtl/aros/Makefile svneol=native#text/plain
+rtl/aros/Makefile.fpc svneol=native#text/plain
+rtl/aros/arosthreads.inc svneol=native#text/plain
+rtl/aros/doslibd.inc svneol=native#text/plain
+rtl/aros/i386/doslibf.inc svneol=native#text/plain
+rtl/aros/i386/execd.inc svneol=native#text/plain
+rtl/aros/i386/execf.inc svneol=native#text/plain
+rtl/aros/i386/prt0.as svneol=native#text/plain
+rtl/aros/i386/utild1.inc svneol=native#text/plain
+rtl/aros/i386/utild2.inc svneol=native#text/plain
+rtl/aros/i386/utilf.inc svneol=native#text/plain
+rtl/aros/system.pp svneol=native#text/plain
+rtl/aros/systemthreadh.inc svneol=native#text/plain
+rtl/aros/systhrd.inc svneol=native#text/plain
+rtl/aros/timerd.inc svneol=native#text/plain
+rtl/aros/tthread.inc svneol=native#text/plain
 rtl/atari/Makefile svneol=native#text/plain
 rtl/atari/Makefile.fpc svneol=native#text/plain
 rtl/atari/prt0.as svneol=native#text/plain
@@ -7970,6 +8082,34 @@ rtl/darwin/x86/sig_x86.inc svneol=native#text/plain
 rtl/darwin/x86/x86hnd.inc svneol=native#text/plain
 rtl/darwin/x86_64/sig_cpu.inc svneol=native#text/plain
 rtl/darwin/x86_64/sighnd.inc svneol=native#text/plain
+rtl/dragonfly/Makefile svneol=native#text/plain
+rtl/dragonfly/Makefile.fpc svneol=native#text/plain
+rtl/dragonfly/buildrtl.pp svneol=native#text/plain
+rtl/dragonfly/console.pp svneol=native#text/plain
+rtl/dragonfly/errno.inc svneol=native#text/plain
+rtl/dragonfly/errnostr.inc svneol=native#text/plain
+rtl/dragonfly/pmutext.inc svneol=native#text/plain
+rtl/dragonfly/pthread.inc svneol=native#text/plain
+rtl/dragonfly/ptypes.inc svneol=native#text/plain
+rtl/dragonfly/rtldefs.inc svneol=native#text/plain
+rtl/dragonfly/si_crt.pp svneol=native#text/plain
+rtl/dragonfly/si_intf.inc svneol=native#text/plain
+rtl/dragonfly/sysctlh.inc svneol=native#text/plain
+rtl/dragonfly/sysnr.inc svneol=native#text/plain
+rtl/dragonfly/termio.pp svneol=native#text/plain
+rtl/dragonfly/termios.inc svneol=native#text/plain
+rtl/dragonfly/termiosproc.inc svneol=native#text/plain
+rtl/dragonfly/unxconst.inc svneol=native#text/plain
+rtl/dragonfly/unxfunc.inc svneol=native#text/plain
+rtl/dragonfly/unxsysc.inc svneol=native#text/plain
+rtl/dragonfly/x86_64/bsyscall.inc svneol=native#text/plain
+rtl/dragonfly/x86_64/cprt0.as svneol=native#text/plain
+rtl/dragonfly/x86_64/dllprt0.as svneol=native#text/plain
+rtl/dragonfly/x86_64/gprt0.as svneol=native#text/plain
+rtl/dragonfly/x86_64/prt0.as svneol=native#text/plain
+rtl/dragonfly/x86_64/si_c.inc svneol=native#text/plain
+rtl/dragonfly/x86_64/sighnd.inc svneol=native#text/plain
+rtl/dragonfly/x86_64/signal.inc svneol=native#text/plain
 rtl/embedded/Makefile svneol=native#text/plain
 rtl/embedded/Makefile.fpc svneol=native#text/plain
 rtl/embedded/arm/at91sam7x256.pp svneol=native#text/plain
@@ -8247,6 +8387,7 @@ rtl/inc/readme -text
 rtl/inc/real2str.inc svneol=native#text/plain
 rtl/inc/resh.inc svneol=native#text/plain
 rtl/inc/rtti.inc svneol=native#text/plain
+rtl/inc/rttih.inc svneol=native#text/plain
 rtl/inc/sfpu128.pp svneol=native#text/pascal
 rtl/inc/sfpux80.pp svneol=native#text/pascal
 rtl/inc/softfpu.pp svneol=native#text/plain
@@ -8263,6 +8404,7 @@ rtl/inc/thread.inc svneol=native#text/plain
 rtl/inc/threadh.inc svneol=native#text/plain
 rtl/inc/threadvr.inc svneol=native#text/plain
 rtl/inc/tinyheap.inc svneol=native#text/plain
+rtl/inc/tnyheaph.inc svneol=native#text/plain
 rtl/inc/typefile.inc svneol=native#text/plain
 rtl/inc/ufloat128.pp svneol=native#text/plain
 rtl/inc/ustringh.inc svneol=native#text/plain
@@ -8527,48 +8669,20 @@ rtl/mipsel/strings.inc svneol=native#text/plain
 rtl/mipsel/stringss.inc svneol=native#text/plain
 rtl/morphos/Makefile svneol=native#text/plain
 rtl/morphos/Makefile.fpc svneol=native#text/plain
-rtl/morphos/aboxlib.pas -text svneol=unset#text/plain
-rtl/morphos/ahi.pas svneol=native#text/plain
-rtl/morphos/asl.pas svneol=native#text/plain
-rtl/morphos/classes.pp svneol=native#text/plain
-rtl/morphos/clipboard.pas svneol=native#text/plain
-rtl/morphos/datatypes.pas -text svneol=unset#text/plain
-rtl/morphos/dos.pp svneol=native#text/plain
-rtl/morphos/doslib.pp svneol=native#text/plain
 rtl/morphos/doslibd.inc svneol=native#text/plain
 rtl/morphos/doslibf.inc svneol=native#text/plain
 rtl/morphos/emuld.inc svneol=native#text/plain
-rtl/morphos/exec.pp svneol=native#text/plain
 rtl/morphos/execd.inc svneol=native#text/plain
 rtl/morphos/execf.inc svneol=native#text/plain
-rtl/morphos/get9.pas svneol=native#text/plain
-rtl/morphos/graphics.pas svneol=native#text/plain
-rtl/morphos/hardware.pas svneol=native#text/plain
-rtl/morphos/inputevent.pas svneol=native#text/plain
-rtl/morphos/intuition.pas svneol=native#text/plain
-rtl/morphos/keymap.pas svneol=native#text/plain
-rtl/morphos/kvm.pp svneol=native#text/plain
-rtl/morphos/layers.pas svneol=native#text/plain
-rtl/morphos/mui.pas -text svneol=unset#text/plain
-rtl/morphos/muihelper.pas -text svneol=unset#text/plain
 rtl/morphos/prt0.as svneol=native#text/plain
-rtl/morphos/rtldefs.inc svneol=native#text/plain
-rtl/morphos/sysdir.inc svneol=native#text/plain
-rtl/morphos/sysfile.inc svneol=native#text/plain
-rtl/morphos/sysheap.inc svneol=native#text/plain
-rtl/morphos/sysos.inc svneol=native#text/plain
 rtl/morphos/sysosh.inc svneol=native#text/plain
 rtl/morphos/system.pp svneol=native#text/plain
-rtl/morphos/sysutils.pp svneol=native#text/plain
-rtl/morphos/timer.pp svneol=native#text/plain
 rtl/morphos/timerd.inc svneol=native#text/plain
 rtl/morphos/timerf.inc svneol=native#text/plain
-rtl/morphos/tinygl.pp svneol=native#text/plain
 rtl/morphos/tthread.inc svneol=native#text/plain
 rtl/morphos/utild1.inc svneol=native#text/plain
 rtl/morphos/utild2.inc svneol=native#text/plain
 rtl/morphos/utilf.inc svneol=native#text/plain
-rtl/morphos/utility.pp svneol=native#text/plain
 rtl/msdos/Makefile svneol=native#text/plain
 rtl/msdos/Makefile.fpc svneol=native#text/plain
 rtl/msdos/classes.pp svneol=native#text/plain
@@ -8871,6 +8985,7 @@ rtl/openbsd/pmutext.inc svneol=native#text/plain
 rtl/openbsd/pthread.inc svneol=native#text/plain
 rtl/openbsd/ptypes.inc svneol=native#text/plain
 rtl/openbsd/rtldefs.inc svneol=native#text/plain
+rtl/openbsd/setsysnr.inc svneol=native#text/plain
 rtl/openbsd/signal.inc svneol=native#text/plain
 rtl/openbsd/syscalls.inc svneol=native#text/plain
 rtl/openbsd/sysconst.inc svneol=native#text/plain
@@ -8896,6 +9011,7 @@ rtl/os2/Makefile svneol=native#text/plain
 rtl/os2/Makefile.fpc svneol=native#text/plain
 rtl/os2/classes.pp svneol=native#text/plain
 rtl/os2/dos.pas svneol=native#text/plain
+rtl/os2/doscall2.pas svneol=native#text/plain
 rtl/os2/doscalls.pas svneol=native#text/plain
 rtl/os2/dynlibs.inc svneol=native#text/plain
 rtl/os2/exe.pas svneol=native#text/plain
@@ -8927,6 +9043,7 @@ rtl/os2/sysos2.pas svneol=native#text/plain
 rtl/os2/sysosh.inc svneol=native#text/plain
 rtl/os2/system.pas svneol=native#text/plain
 rtl/os2/systhrd.inc svneol=native#text/plain
+rtl/os2/sysucode.inc svneol=native#text/plain
 rtl/os2/sysutils.pp svneol=native#text/plain
 rtl/os2/tests/atx.pas svneol=native#text/plain
 rtl/os2/tests/basicpm.pas svneol=native#text/plain
@@ -9233,6 +9350,7 @@ rtl/win32/winsysut.pp svneol=native#text/plain
 rtl/win32/wprt0.as svneol=native#text/plain
 rtl/win64/Makefile svneol=native#text/plain
 rtl/win64/Makefile.fpc svneol=native#text/plain
+rtl/win64/buildrtl.lpi svneol=native#text/plain
 rtl/win64/buildrtl.pp svneol=native#text/plain
 rtl/win64/classes.pp svneol=native#text/plain
 rtl/win64/rtldefs.inc svneol=native#text/plain
@@ -9620,6 +9738,8 @@ tests/tbf/tb0245.pp svneol=native#text/pascal
 tests/tbf/tb0246.pp svneol=native#text/pascal
 tests/tbf/tb0247.pp svneol=native#text/pascal
 tests/tbf/tb0248.pp svneol=native#text/pascal
+tests/tbf/tb0249.pp svneol=native#text/pascal
+tests/tbf/tb0250.pp svneol=native#text/pascal
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
@@ -10229,6 +10349,7 @@ tests/tbs/tb0604.pp svneol=native#text/pascal
 tests/tbs/tb0605.pp svneol=native#text/pascal
 tests/tbs/tb0606.pp svneol=native#text/pascal
 tests/tbs/tb0607.pp svneol=native#text/plain
+tests/tbs/tb0608.pp svneol=native#text/pascal
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/ub0060.pp svneol=native#text/plain
@@ -10874,6 +10995,7 @@ tests/test/cpu16/i8086/tmmm.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmms.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmmt.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tptrsize.pp svneol=native#text/pascal
+tests/test/cpu16/i8086/ttheap1.pp svneol=native#text/pascal
 tests/test/cpu16/taddint1.pp svneol=native#text/pascal
 tests/test/dumpclass.pp svneol=native#text/plain
 tests/test/dumpmethods.pp svneol=native#text/plain
@@ -10942,6 +11064,7 @@ tests/test/jvm/tset1.pp svneol=native#text/plain
 tests/test/jvm/tset3.pp svneol=native#text/plain
 tests/test/jvm/tset7.pp svneol=native#text/plain
 tests/test/jvm/tsetansistr.pp svneol=native#text/plain
+tests/test/jvm/tsetstring.pp svneol=native#text/plain
 tests/test/jvm/tsmallintarr.pp svneol=native#text/plain
 tests/test/jvm/tstr.pp svneol=native#text/plain
 tests/test/jvm/tstring1.pp svneol=native#text/plain
@@ -11307,6 +11430,7 @@ tests/test/tcpstr8.pp svneol=native#text/pascal
 tests/test/tcpstr9.pp svneol=native#text/pascal
 tests/test/tcpstransistr2shortstring.pp svneol=native#text/plain
 tests/test/tcpstransistr2widechararray.pp svneol=native#text/plain
+tests/test/tcpstransistr2widechararray2.pp svneol=native#text/plain
 tests/test/tcpstransistrcompare.pp svneol=native#text/plain
 tests/test/tcpstransistrcompareequal.pp svneol=native#text/plain
 tests/test/tcpstransistrcopy.pp svneol=native#text/plain
@@ -11486,7 +11610,11 @@ tests/test/tgenconstraint33.pp svneol=native#text/pascal
 tests/test/tgenconstraint34.pp svneol=native#text/pascal
 tests/test/tgenconstraint35.pp svneol=native#text/pascal
 tests/test/tgenconstraint36.pp svneol=native#text/pascal
+tests/test/tgenconstraint37.pp svneol=native#text/pascal
+tests/test/tgenconstraint38.pp svneol=native#text/pascal
+tests/test/tgenconstraint39.pp svneol=native#text/pascal
 tests/test/tgenconstraint4.pp svneol=native#text/pascal
+tests/test/tgenconstraint40.pp svneol=native#text/pascal
 tests/test/tgenconstraint5.pp svneol=native#text/pascal
 tests/test/tgenconstraint6.pp svneol=native#text/pascal
 tests/test/tgenconstraint7.pp svneol=native#text/pascal
@@ -11588,6 +11716,8 @@ tests/test/tgeneric93.pp svneol=native#text/pascal
 tests/test/tgeneric94.pp svneol=native#text/pascal
 tests/test/tgeneric95.pp svneol=native#text/pascal
 tests/test/tgeneric96.pp svneol=native#text/pascal
+tests/test/tgeneric97.pp svneol=native#text/pascal
+tests/test/tgeneric98.pp svneol=native#text/pascal
 tests/test/tgoto.pp svneol=native#text/plain
 tests/test/theap.pp svneol=native#text/plain
 tests/test/theapthread.pp svneol=native#text/plain
@@ -11636,6 +11766,8 @@ tests/test/thlp43.pp svneol=native#text/pascal
 tests/test/thlp44.pp svneol=native#text/pascal
 tests/test/thlp45.pp svneol=native#text/pascal
 tests/test/thlp46.pp svneol=native#text/pascal
+tests/test/thlp47.pp svneol=native#text/pascal
+tests/test/thlp48.pp svneol=native#text/plain
 tests/test/thlp5.pp svneol=native#text/pascal
 tests/test/thlp6.pp svneol=native#text/pascal
 tests/test/thlp7.pp svneol=native#text/pascal
@@ -11689,6 +11821,7 @@ tests/test/tisoread.pp svneol=native#text/pascal
 tests/test/tisorec1.pp svneol=native#text/pascal
 tests/test/tisorec2.pp svneol=native#text/pascal
 tests/test/tisorec3.pp svneol=native#text/pascal
+tests/test/tisorec4.pp svneol=native#text/pascal
 tests/test/tlea1.pp svneol=native#text/plain
 tests/test/tlea2.pp svneol=native#text/plain
 tests/test/tlib1a.pp svneol=native#text/plain
@@ -11812,6 +11945,7 @@ tests/test/tobjc38.pp svneol=native#text/plain
 tests/test/tobjc39.pp svneol=native#text/plain
 tests/test/tobjc4.pp svneol=native#text/plain
 tests/test/tobjc40.pp svneol=native#text/plain
+tests/test/tobjc41.pp svneol=native#text/plain
 tests/test/tobjc4a.pp svneol=native#text/plain
 tests/test/tobjc5.pp svneol=native#text/plain
 tests/test/tobjc5a.pp svneol=native#text/plain
@@ -12361,6 +12495,7 @@ tests/test/units/math/tmask.pp svneol=native#text/plain
 tests/test/units/math/tmask2.pp svneol=native#text/plain
 tests/test/units/math/tnaninf.pp svneol=native#text/plain
 tests/test/units/math/tpower.pp svneol=native#text/pascal
+tests/test/units/math/troundm.pp svneol=native#text/plain
 tests/test/units/math/tsincos.pp svneol=native#text/pascal
 tests/test/units/math/ttrig1.pp svneol=native#text/plain
 tests/test/units/matrix/tinv1.pp svneol=native#text/pascal
@@ -12400,6 +12535,7 @@ tests/test/units/system/testpc.txt svneol=native#text/plain
 tests/test/units/system/teststk.pp svneol=native#text/plain
 tests/test/units/system/testux.txt svneol=native#text/plain
 tests/test/units/system/tfiledir.pp svneol=native#text/plain
+tests/test/units/system/tfloatrecs.pp svneol=native#text/pascal
 tests/test/units/system/tgenstr.pp svneol=native#text/pascal
 tests/test/units/system/tincdec.pp svneol=native#text/plain
 tests/test/units/system/tint.pp svneol=native#text/plain
@@ -12480,6 +12616,8 @@ tests/test/units/sysutils/twstrcmp.pp svneol=native#text/plain
 tests/test/units/ucomplex/tcsqr1.pp svneol=native#text/pascal
 tests/test/units/variants/tcustomvariant.pp svneol=native#text/plain
 tests/test/units/variants/tvararrayofintf.pp svneol=native#text/plain
+tests/test/units/variants/tw26370.pp svneol=native#text/plain
+tests/test/units/variants/tw27044.pp svneol=native#text/plain
 tests/test/uobjc24.pp svneol=native#text/plain
 tests/test/uobjc26.pp svneol=native#text/plain
 tests/test/uobjc27a.pp svneol=native#text/plain
@@ -12490,6 +12628,7 @@ tests/test/uobjc35e.pp svneol=native#text/plain
 tests/test/uobjc35f.pp svneol=native#text/plain
 tests/test/uobjc35g.pp svneol=native#text/plain
 tests/test/uobjc39.pp svneol=native#text/plain
+tests/test/uobjc41.pp svneol=native#text/plain
 tests/test/uobjc7.pp svneol=native#text/plain
 tests/test/uobjcl1.pp svneol=native#text/plain
 tests/test/uprec6.pp svneol=native#text/plain
@@ -12780,9 +12919,11 @@ tests/webtbf/tw26176.pp svneol=native#text/pascal
 tests/webtbf/tw26193.pp svneol=native#text/pascal
 tests/webtbf/tw26363.pp svneol=native#text/plain
 tests/webtbf/tw26363a.pp svneol=native#text/plain
+tests/webtbf/tw26456.pp svneol=native#text/pascal
 tests/webtbf/tw2650.pp svneol=native#text/plain
 tests/webtbf/tw2657.pp svneol=native#text/plain
 tests/webtbf/tw2670.pp svneol=native#text/plain
+tests/webtbf/tw26704.pp svneol=native#text/plain
 tests/webtbf/tw2719.pp svneol=native#text/plain
 tests/webtbf/tw2721.pp svneol=native#text/plain
 tests/webtbf/tw2724.pp svneol=native#text/plain
@@ -13630,6 +13771,8 @@ tests/webtbs/tw19368.pp svneol=native#text/pascal
 tests/webtbs/tw1938.pp svneol=native#text/plain
 tests/webtbs/tw19434a.pp svneol=native#text/plain
 tests/webtbs/tw19434b.pp svneol=native#text/plain
+tests/webtbs/tw19452.pp svneol=native#text/plain
+tests/webtbs/tw19452a.pp svneol=native#text/plain
 tests/webtbs/tw1948.pp svneol=native#text/plain
 tests/webtbs/tw19498.pp svneol=native#text/pascal
 tests/webtbs/tw19499.pp svneol=native#text/pascal
@@ -13745,6 +13888,7 @@ tests/webtbs/tw21350a.pp svneol=native#text/pascal
 tests/webtbs/tw21350b.pp svneol=native#text/pascal
 tests/webtbs/tw21443.pp svneol=native#text/plain
 tests/webtbs/tw21443a.pp svneol=native#text/plain
+tests/webtbs/tw21449.pp -text svneol=native#text/plain
 tests/webtbs/tw2145.pp svneol=native#text/plain
 tests/webtbs/tw21457.pp svneol=native#text/pascal
 tests/webtbs/tw21472.pp svneol=native#text/pascal
@@ -13800,6 +13944,7 @@ tests/webtbs/tw22329.pp svneol=native#text/pascal
 tests/webtbs/tw2233.pp svneol=native#text/plain
 tests/webtbs/tw22331.pp svneol=native#text/plain
 tests/webtbs/tw22344.pp svneol=native#text/plain
+tests/webtbs/tw22376.pp svneol=native#text/plain
 tests/webtbs/tw2242.pp svneol=native#text/plain
 tests/webtbs/tw22427.pp svneol=native#text/pascal
 tests/webtbs/tw22428.pp svneol=native#text/pascal
@@ -13848,6 +13993,7 @@ tests/webtbs/tw2300.pp svneol=native#text/plain
 tests/webtbs/tw2305.pp svneol=native#text/plain
 tests/webtbs/tw2306.pp svneol=native#text/plain
 tests/webtbs/tw2307.pp svneol=native#text/plain
+tests/webtbs/tw23109.pp svneol=native#text/plain
 tests/webtbs/tw2311.pp svneol=native#text/plain
 tests/webtbs/tw23130.pp svneol=native#text/pascal
 tests/webtbs/tw23136.pp svneol=native#text/pascal
@@ -13926,6 +14072,7 @@ tests/webtbs/tw24863.pp svneol=native#text/plain
 tests/webtbs/tw24865.pp svneol=native#text/pascal
 tests/webtbs/tw24867.pp svneol=native#text/pascal
 tests/webtbs/tw24871.pp svneol=native#text/pascal
+tests/webtbs/tw24872.pp svneol=native#text/pascal
 tests/webtbs/tw24915.pp svneol=native#text/pascal
 tests/webtbs/tw2492.pp svneol=native#text/plain
 tests/webtbs/tw2494.pp svneol=native#text/plain
@@ -13969,6 +14116,7 @@ tests/webtbs/tw25600.pp svneol=native#text/pascal
 tests/webtbs/tw25603.pp svneol=native#text/pascal
 tests/webtbs/tw25604.pp svneol=native#text/pascal
 tests/webtbs/tw25605.pp svneol=native#text/pascal
+tests/webtbs/tw25606.pp svneol=native#text/pascal
 tests/webtbs/tw2561.pp svneol=native#text/plain
 tests/webtbs/tw25610.pp -text svneol=native#text/plain
 tests/webtbs/tw25685.pp svneol=native#text/pascal
@@ -13979,6 +14127,9 @@ tests/webtbs/tw25869.pp svneol=native#text/plain
 tests/webtbs/tw2588.pp svneol=native#text/plain
 tests/webtbs/tw2589.pp svneol=native#text/plain
 tests/webtbs/tw25895.pp svneol=native#text/pascal
+tests/webtbs/tw25916a.pp svneol=native#text/pascal
+tests/webtbs/tw25916b.pp svneol=native#text/pascal
+tests/webtbs/tw25917.pp svneol=native#text/pascal
 tests/webtbs/tw25929.pp svneol=native#text/pascal
 tests/webtbs/tw25930.pp svneol=native#text/plain
 tests/webtbs/tw25931.pp -text svneol=native#text/plain
@@ -13988,7 +14139,10 @@ tests/webtbs/tw2595.pp svneol=native#text/plain
 tests/webtbs/tw25956.pp svneol=native#text/pascal
 tests/webtbs/tw25959.pp svneol=native#text/pascal
 tests/webtbs/tw2602.pp svneol=native#text/plain
+tests/webtbs/tw26069.pp svneol=native#text/plain
 tests/webtbs/tw2607.pp svneol=native#text/plain
+tests/webtbs/tw26075.pp svneol=native#text/pascal
+tests/webtbs/tw26075b.pp svneol=native#text/pascal
 tests/webtbs/tw26123.pp svneol=native#text/pascal
 tests/webtbs/tw26162.pp svneol=native#text/pascal
 tests/webtbs/tw26177.pp svneol=native#text/pascal
@@ -14001,23 +14155,40 @@ tests/webtbs/tw2627.pp svneol=native#text/plain
 tests/webtbs/tw26271.pp svneol=native#text/pascal
 tests/webtbs/tw26288.pp svneol=native#text/pascal
 tests/webtbs/tw2631.pp svneol=native#text/plain
+tests/webtbs/tw26403.pp svneol=native#text/pascal
 tests/webtbs/tw26408.pp svneol=native#text/pascal
 tests/webtbs/tw2643.pp svneol=native#text/plain
 tests/webtbs/tw2645.pp svneol=native#text/plain
+tests/webtbs/tw26467.pp svneol=native#text/pascal
 tests/webtbs/tw2647.pp svneol=native#text/plain
+tests/webtbs/tw26481.pp svneol=native#text/pascal
+tests/webtbs/tw26482.pp svneol=native#text/pascal
+tests/webtbs/tw26483.pp svneol=native#text/pascal
 tests/webtbs/tw2649.pp svneol=native#text/plain
 tests/webtbs/tw2651.pp svneol=native#text/plain
+tests/webtbs/tw26536.pp svneol=native#text/plain
 tests/webtbs/tw2656.pp svneol=native#text/plain
 tests/webtbs/tw2659.pp svneol=native#text/plain
+tests/webtbs/tw26599.pp svneol=native#text/pascal
+tests/webtbs/tw26615.pp svneol=native#text/pascal
+tests/webtbs/tw26627.pp svneol=native#text/plain
 tests/webtbs/tw2666.pp svneol=native#text/plain
+tests/webtbs/tw26668.pp svneol=native#text/plain
 tests/webtbs/tw2668.pp svneol=native#text/plain
 tests/webtbs/tw2669.pp svneol=native#text/plain
+tests/webtbs/tw26749.pp svneol=native#text/pascal
 tests/webtbs/tw2676.pp svneol=native#text/plain
+tests/webtbs/tw26773.pp svneol=native#text/plain
 tests/webtbs/tw2678.pp svneol=native#text/plain
 tests/webtbs/tw2690.pp svneol=native#text/plain
 tests/webtbs/tw2691.pp svneol=native#text/plain
+tests/webtbs/tw26922.pp svneol=native#text/pascal
 tests/webtbs/tw2696.pp svneol=native#text/plain
+tests/webtbs/tw26976.pp svneol=native#text/plain
+tests/webtbs/tw26993.pp svneol=native#text/plain
+tests/webtbs/tw26993a.pp svneol=native#text/plain
 tests/webtbs/tw2702.pp svneol=native#text/plain
+tests/webtbs/tw27029.pp svneol=native#text/pascal
 tests/webtbs/tw2703.pp svneol=native#text/plain
 tests/webtbs/tw2704.pp svneol=native#text/plain
 tests/webtbs/tw2705.pp svneol=native#text/plain
@@ -14025,14 +14196,21 @@ tests/webtbs/tw2706.pp svneol=native#text/plain
 tests/webtbs/tw2707.pp svneol=native#text/plain
 tests/webtbs/tw2708.pp svneol=native#text/plain
 tests/webtbs/tw2710.pp svneol=native#text/plain
+tests/webtbs/tw27120.pp svneol=native#text/pascal
 tests/webtbs/tw2713.pp svneol=native#text/plain
+tests/webtbs/tw27153.pp svneol=native#text/pascal
+tests/webtbs/tw27173.pp svneol=native#text/pascal
+tests/webtbs/tw27185.pp svneol=native#text/pascal
 tests/webtbs/tw2721.pp svneol=native#text/plain
 tests/webtbs/tw2723.pp svneol=native#text/plain
 tests/webtbs/tw2725.pp svneol=native#text/plain
+tests/webtbs/tw27256.pp svneol=native#text/pascal
 tests/webtbs/tw2727.pp svneol=native#text/plain
 tests/webtbs/tw2728.pp svneol=native#text/plain
 tests/webtbs/tw2729.pp svneol=native#text/plain
+tests/webtbs/tw27294.pp svneol=native#text/plain
 tests/webtbs/tw2730.pp svneol=native#text/plain
+tests/webtbs/tw27300a.pp svneol=native#text/pascal
 tests/webtbs/tw2731.pp svneol=native#text/plain
 tests/webtbs/tw2736.pp svneol=native#text/plain
 tests/webtbs/tw2737.pp svneol=native#text/plain
@@ -14771,8 +14949,11 @@ tests/webtbs/uw25598.pp svneol=native#text/plain
 tests/webtbs/uw25610a.pp -text svneol=native#text/plain
 tests/webtbs/uw25610b.pp -text svneol=native#text/plain
 tests/webtbs/uw25814.pp svneol=native#text/plain
+tests/webtbs/uw26922a.pp svneol=native#text/pascal
+tests/webtbs/uw26922b.pp svneol=native#text/pascal
 tests/webtbs/uw2706a.pp svneol=native#text/plain
 tests/webtbs/uw2706b.pp svneol=native#text/plain
+tests/webtbs/uw27294.pp svneol=native#text/plain
 tests/webtbs/uw2731.pp svneol=native#text/plain
 tests/webtbs/uw2738.pp svneol=native#text/plain
 tests/webtbs/uw2834.pp svneol=native#text/plain
@@ -14848,6 +15029,7 @@ utils/debugsvr/gtk/frmmain.pp svneol=native#text/plain
 utils/debugsvr/msgintf.pp svneol=native#text/plain
 utils/debugsvr/speeddebug.pp svneol=native#text/plain
 utils/debugsvr/testdebug.pp svneol=native#text/plain
+utils/delp.lpi svneol=native#text/plain
 utils/delp.pp svneol=native#text/plain
 utils/dxegen/Makefile svneol=native#text/plain
 utils/dxegen/Makefile.fpc svneol=native#text/plain
@@ -15143,6 +15325,7 @@ utils/javapp/src/fpc/tools/javapp/StackMapTableData.java svneol=native#text/plai
 utils/javapp/src/fpc/tools/javapp/Tables.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/TrapData.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/TypeSignature.java svneol=native#text/plain
+utils/mkinsadd.pp svneol=native#text/plain
 utils/mksymbian/Makefile svneol=native#text/plain
 utils/mksymbian/Makefile.fpc svneol=native#text/plain
 utils/mksymbian/Makefile.fpc.fpcmake svneol=native#text/plain

+ 18 - 27
.gitignore

@@ -1344,6 +1344,24 @@ packages/fcl-net/src/*.o
 packages/fcl-net/src/*.ppu
 packages/fcl-net/src/*.s
 packages/fcl-net/src/Package.fpc
+packages/fcl-net/src/amiga/*.bak
+packages/fcl-net/src/amiga/*.exe
+packages/fcl-net/src/amiga/*.o
+packages/fcl-net/src/amiga/*.ppu
+packages/fcl-net/src/amiga/*.s
+packages/fcl-net/src/amiga/Package.fpc
+packages/fcl-net/src/amiga/build-stamp.*
+packages/fcl-net/src/amiga/fpcmade.*
+packages/fcl-net/src/amiga/units
+packages/fcl-net/src/aros/*.bak
+packages/fcl-net/src/aros/*.exe
+packages/fcl-net/src/aros/*.o
+packages/fcl-net/src/aros/*.ppu
+packages/fcl-net/src/aros/*.s
+packages/fcl-net/src/aros/Package.fpc
+packages/fcl-net/src/aros/build-stamp.*
+packages/fcl-net/src/aros/fpcmade.*
+packages/fcl-net/src/aros/units
 packages/fcl-net/src/fpcmade.*
 packages/fcl-net/src/netware/*.bak
 packages/fcl-net/src/netware/*.exe
@@ -1801,15 +1819,6 @@ packages/gdbint/src/Package.fpc
 packages/gdbint/src/build-stamp.*
 packages/gdbint/src/fpcmade.*
 packages/gdbint/src/units
-packages/gdbint/tests/*.bak
-packages/gdbint/tests/*.exe
-packages/gdbint/tests/*.o
-packages/gdbint/tests/*.ppu
-packages/gdbint/tests/*.s
-packages/gdbint/tests/Package.fpc
-packages/gdbint/tests/build-stamp.*
-packages/gdbint/tests/fpcmade.*
-packages/gdbint/tests/units
 packages/gdbint/units
 packages/gdbm/*.bak
 packages/gdbm/*.exe
@@ -2723,15 +2732,6 @@ packages/imlib/*.ppu
 packages/imlib/*.s
 packages/imlib/Package.fpc
 packages/imlib/build-stamp.*
-packages/imlib/examples/*.bak
-packages/imlib/examples/*.exe
-packages/imlib/examples/*.o
-packages/imlib/examples/*.ppu
-packages/imlib/examples/*.s
-packages/imlib/examples/Package.fpc
-packages/imlib/examples/build-stamp.*
-packages/imlib/examples/fpcmade.*
-packages/imlib/examples/units
 packages/imlib/fpcmade.*
 packages/imlib/src/*.bak
 packages/imlib/src/*.exe
@@ -2742,15 +2742,6 @@ packages/imlib/src/Package.fpc
 packages/imlib/src/build-stamp.*
 packages/imlib/src/fpcmade.*
 packages/imlib/src/units
-packages/imlib/tests/*.bak
-packages/imlib/tests/*.exe
-packages/imlib/tests/*.o
-packages/imlib/tests/*.ppu
-packages/imlib/tests/*.s
-packages/imlib/tests/Package.fpc
-packages/imlib/tests/build-stamp.*
-packages/imlib/tests/fpcmade.*
-packages/imlib/tests/units
 packages/imlib/units
 packages/ldap/*.bak
 packages/ldap/*.exe

+ 69 - 13
Makefile

@@ -1,9 +1,9 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2014-02-06 rev 26692]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-01-04 rev 29399]
 #
 default: help
-MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim 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-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
@@ -184,6 +184,12 @@ $(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t
 endif
 override FPCOPT+=-Cp$(SUBARCH)
 endif
+ifeq ($(FULL_TARGET),mipsel-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 TARGETSUFFIX=$(OS_TARGET)
 SOURCESUFFIX=$(OS_SOURCE)
@@ -320,7 +326,7 @@ FPCFPMAKE=$(FPC)
 endif
 endif
 override PACKAGE_NAME=fpc
-override PACKAGE_VERSION=2.7.1
+override PACKAGE_VERSION=3.1.1
 REQUIREDVERSION=2.6.4
 REQUIREDVERSION2=2.6.2
 ifndef inOS2
@@ -461,7 +467,7 @@ endif
 endif
 BuildOnlyBaseCPUs=jvm
 ifneq ($(wildcard utils),)
-NOUTILSTARGETS=embedded gba $(BuildOnlyBaseCPUs)
+NOUTILSTARGETS=embedded gba msdos $(BuildOnlyBaseCPUs)
 ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
 ifdef BUILDFULLNATIVE
 UTILS=1
@@ -537,6 +543,9 @@ endif
 ifeq ($(FULL_TARGET),i386-android)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
@@ -624,6 +633,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
@@ -678,6 +690,9 @@ endif
 ifeq ($(FULL_TARGET),mipsel-linux)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
+ifeq ($(FULL_TARGET),mipsel-embedded)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),mipsel-android)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
@@ -933,6 +948,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=
@@ -978,6 +999,11 @@ EXEEXT=
 SHAREDLIBEXT=.library
 SHORTSUFFIX=amg
 endif
+ifeq ($(OS_TARGET),aros)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=aros
+endif
 ifeq ($(OS_TARGET),morphos)
 EXEEXT=
 SHAREDLIBEXT=.library
@@ -1442,8 +1468,8 @@ endif
 ifdef CREATESHARED
 override FPCOPT+=-Cg
 endif
-ifneq ($(findstring $(OS_TARGET),freebsd openbsd netbsd linux solaris),)
-ifeq ($(CPU_TARGET),x86_64)
+ifneq ($(findstring $(OS_TARGET),dragonfly freebsd openbsd netbsd linux solaris),)
+ifneq ($(findstring $(CPU_TARGET),x86_64 mips mipsel),)
 override FPCOPT+=-Cg
 endif
 endif
@@ -1472,17 +1498,23 @@ ifdef ACROSSCOMPILE
 override FPCOPT+=$(CROSSOPT)
 endif
 override COMPILER:=$(strip $(FPC) $(FPCOPT))
-ifeq (,$(findstring -s ,$(COMPILER)))
+ifneq (,$(findstring -sh ,$(COMPILER)))
+UseEXECPPAS=1
+endif
+ifneq (,$(findstring -s ,$(COMPILER)))
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+UseEXECPPAS=1
+endif
+endif
+ifneq ($(UseEXECPPAS),1)
 EXECPPAS=
 else
-ifeq ($(FULL_SOURCE),$(FULL_TARGET))
 ifdef RUNBATCH
 EXECPPAS:=@$(RUNBATCH) $(PPAS)
 else
 EXECPPAS:=@$(PPAS)
 endif
 endif
-endif
 ifdef TARGET_RSTS
 override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
 override CLEANRSTFILES+=$(RSTFILES)
@@ -2008,6 +2040,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 endif
+ifeq ($(FULL_TARGET),i386-aros)
+TARGET_DIRS_COMPILER=1
+TARGET_DIRS_RTL=1
+TARGET_DIRS_UTILS=1
+TARGET_DIRS_PACKAGES=1
+TARGET_DIRS_IDE=1
+TARGET_DIRS_INSTALLER=1
+endif
 ifeq ($(FULL_TARGET),m68k-linux)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
@@ -2240,6 +2280,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 endif
+ifeq ($(FULL_TARGET),x86_64-dragonfly)
+TARGET_DIRS_COMPILER=1
+TARGET_DIRS_RTL=1
+TARGET_DIRS_UTILS=1
+TARGET_DIRS_PACKAGES=1
+TARGET_DIRS_IDE=1
+TARGET_DIRS_INSTALLER=1
+endif
 ifeq ($(FULL_TARGET),arm-linux)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
@@ -2384,6 +2432,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 endif
+ifeq ($(FULL_TARGET),mipsel-embedded)
+TARGET_DIRS_COMPILER=1
+TARGET_DIRS_RTL=1
+TARGET_DIRS_UTILS=1
+TARGET_DIRS_PACKAGES=1
+TARGET_DIRS_IDE=1
+TARGET_DIRS_INSTALLER=1
+endif
 ifeq ($(FULL_TARGET),mipsel-android)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
@@ -2726,14 +2782,14 @@ BUILDSTAMP=build-stamp.$(FULL_TARGET)
 .PHONY: all clean distclean build buildbase install installbase
 .PHONY: installother zipinstallbase zipinstallotherzipinstall
 .PHONY: singlezipinstall versioncheckstartingcompiler
-versioncheckstartingcompiler: 
+versioncheckstartingcompiler:
 ifndef CROSSCOMPILE
 ifneq ($(FPC_VERSION),$(REQUIREDVERSION))
 ifneq ($(FPC_VERSION),$(REQUIREDVERSION2))
 ifndef OVERRIDEVERSIONCHECK
-	$(error The only supported starting compiler version is $(REQUIREDVERSION). You are trying to build with $(FPC_VERSION). If you are absolutely sure that the current compiler is built from the exact same version/revision, you can try to use OVERRIDEVERSIONCHECK=1 to override )
+	$(error The only supported starting compiler version is $(REQUIREDVERSION). You are trying to build with $(FPC_VERSION).)
 else
-	@$(ECHO) You have overriden the starting compiler versioncheck while using starting compiler version $(FPC_VERSION). This situation is not supported and strange things and errors may happen. Remove OVERRIDEVERSIONCHECK=1 to fix this. 
+	@$(ECHO) You have overriden the starting compiler versioncheck while using starting compiler version $(FPC_VERSION). This situation is not supported and strange things and errors may happen. Remove OVERRIDEVERSIONCHECK=1 to fix this.
 endif
 endif
 endif

+ 5 - 5
Makefile.fpc

@@ -4,7 +4,7 @@
 
 [package]
 name=fpc
-version=2.7.1
+version=3.1.1
 
 [target]
 dirs=compiler rtl utils packages ide installer
@@ -204,7 +204,7 @@ endif
 BuildOnlyBaseCPUs=jvm
 
 ifneq ($(wildcard utils),)
-NOUTILSTARGETS=embedded gba $(BuildOnlyBaseCPUs)
+NOUTILSTARGETS=embedded gba msdos $(BuildOnlyBaseCPUs)
 ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
 ifdef BUILDFULLNATIVE
 UTILS=1
@@ -263,14 +263,14 @@ BUILDSTAMP=build-stamp.$(FULL_TARGET)
 .PHONY: installother zipinstallbase zipinstallotherzipinstall
 .PHONY: singlezipinstall versioncheckstartingcompiler
 
-versioncheckstartingcompiler: 
+versioncheckstartingcompiler:
 ifndef CROSSCOMPILE
 ifneq ($(FPC_VERSION),$(REQUIREDVERSION))
 ifneq ($(FPC_VERSION),$(REQUIREDVERSION2))
 ifndef OVERRIDEVERSIONCHECK
-	$(error The only supported starting compiler version is $(REQUIREDVERSION). You are trying to build with $(FPC_VERSION). If you are absolutely sure that the current compiler is built from the exact same version/revision, you can try to use OVERRIDEVERSIONCHECK=1 to override )
+	$(error The only supported starting compiler version is $(REQUIREDVERSION). You are trying to build with $(FPC_VERSION).)
 else
-	@$(ECHO) You have overriden the starting compiler versioncheck while using starting compiler version $(FPC_VERSION). This situation is not supported and strange things and errors may happen. Remove OVERRIDEVERSIONCHECK=1 to fix this. 
+	@$(ECHO) You have overriden the starting compiler versioncheck while using starting compiler version $(FPC_VERSION). This situation is not supported and strange things and errors may happen. Remove OVERRIDEVERSIONCHECK=1 to fix this.
 endif
 endif
 endif

+ 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 - 40
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
@@ -1449,29 +1434,4 @@ implementation
         result:=(def.typ=procvardef) and (po_is_block in tprocvardef(def).procoptions)
       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

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است