ソースを参照

reintegration merge trunk

git-svn-id: branches/interfacertti@31422 -
steve 10 年 前
コミット
08df85cd45
100 ファイル変更2632 行追加8002 行削除
  1. 136 43
      .gitattributes
  2. 45 4
      Makefile
  3. 4 1
      Makefile.fpc
  4. 63 12
      compiler/Makefile
  5. 3 11
      compiler/Makefile.fpc
  6. 1 1
      compiler/aarch64/a64att.inc
  7. 1 1
      compiler/aarch64/a64atts.inc
  8. 1 1
      compiler/aarch64/a64op.inc
  9. 1 1
      compiler/aarch64/a64tab.inc
  10. 32 4
      compiler/aarch64/agcpugas.pas
  11. 52 61
      compiler/aarch64/cgcpu.pas
  12. 1 1
      compiler/aarch64/cpubase.pas
  13. 2 2
      compiler/aarch64/cpupara.pas
  14. 1 1
      compiler/aarch64/cputarg.pas
  15. 4 0
      compiler/aarch64/ncpucnv.pas
  16. 4 0
      compiler/aarch64/symcpu.pas
  17. 186 56
      compiler/aasmcnst.pas
  18. 4 2
      compiler/aasmtai.pas
  19. 22 5
      compiler/aggas.pas
  20. 0 1232
      compiler/agjasmin.pas
  21. 0 268
      compiler/alpha/aasmcpu.pas
  22. 0 126
      compiler/alpha/agaxpgas.pas
  23. 0 38
      compiler/alpha/aoptcpu.pas
  24. 0 112
      compiler/alpha/aoptcpub.pas
  25. 0 38
      compiler/alpha/aoptcpuc.pas
  26. 0 39
      compiler/alpha/aoptcpud.pas
  27. 0 168
      compiler/alpha/cgcpu.pas
  28. 0 431
      compiler/alpha/cpubase.pas
  29. 0 91
      compiler/alpha/cpuinfo.pas
  30. 0 56
      compiler/alpha/cpunode.pas
  31. 0 270
      compiler/alpha/cpupara.pas
  32. 0 43
      compiler/alpha/cpupi.pas
  33. 0 51
      compiler/alpha/cputarg.pas
  34. 0 0
      compiler/alpha/radirect.pas
  35. 0 65
      compiler/alpha/rasm.pas
  36. 0 69
      compiler/alpha/rgcpu.pas
  37. 0 211
      compiler/alpha/symcpu.pas
  38. 0 42
      compiler/alpha/tgcpu.pas
  39. 0 8
      compiler/aopt.pas
  40. 4 0
      compiler/aoptobj.pas
  41. 8 2
      compiler/arm/aasmcpu.pas
  42. 32 0
      compiler/arm/cpuinfo.pas
  43. 9 6
      compiler/arm/cpupara.pas
  44. 4 0
      compiler/arm/narmcnv.pas
  45. 1 0
      compiler/arm/narmset.pas
  46. 5 0
      compiler/arm/symcpu.pas
  47. 24 9
      compiler/assemble.pas
  48. 36 14
      compiler/avr/aasmcpu.pas
  49. 4 0
      compiler/avr/agavrgas.pas
  50. 822 242
      compiler/avr/aoptcpu.pas
  51. 8 1
      compiler/avr/aoptcpub.pas
  52. 394 102
      compiler/avr/cgcpu.pas
  53. 15 8
      compiler/avr/cpubase.pas
  54. 295 62
      compiler/avr/cpuinfo.pas
  55. 8 4
      compiler/avr/cpupara.pas
  56. 10 3
      compiler/avr/cpupi.pas
  57. 6 4
      compiler/avr/itcpugas.pas
  58. 23 10
      compiler/avr/navradd.pas
  59. 64 159
      compiler/avr/navrmat.pas
  60. 33 10
      compiler/avr/raavrgas.pas
  61. 1 1
      compiler/avr/rgcpu.pas
  62. 5 0
      compiler/avr/symcpu.pas
  63. 0 3
      compiler/bsdcompile
  64. 2 0
      compiler/cgbase.pas
  65. 14 47
      compiler/cgobj.pas
  66. 6 0
      compiler/dbgdwarf.pas
  67. 9 6
      compiler/defcmp.pas
  68. 5 16
      compiler/defutil.pas
  69. 9 4
      compiler/fmodule.pas
  70. 5 4
      compiler/fpcdefs.inc
  71. 5 0
      compiler/generic/symcpu.pas
  72. 1 1
      compiler/globals.pas
  73. 2 2
      compiler/globtype.pas
  74. 69 12
      compiler/hlcgobj.pas
  75. 17 9
      compiler/htypechk.pas
  76. 1 8
      compiler/i386/aopt386.pas
  77. 1 1
      compiler/i386/cpuinfo.pas
  78. 4 3
      compiler/i386/cpupara.pas
  79. 0 2265
      compiler/i386/csopt386.pas
  80. 2 2
      compiler/i386/popt386.pas
  81. 0 372
      compiler/i386/rropt386.pas
  82. 5 2
      compiler/i386/symcpu.pas
  83. 1 1
      compiler/i8086/cpuinfo.pas
  84. 5 4
      compiler/i8086/cpupara.pas
  85. 31 1
      compiler/i8086/cpupi.pas
  86. 2 1
      compiler/i8086/hlcgcpu.pas
  87. 1 1
      compiler/i8086/i8086nop.inc
  88. 14 0
      compiler/i8086/i8086tab.inc
  89. 1 1
      compiler/i8086/n8086mem.pas
  90. 24 2
      compiler/i8086/symcpu.pas
  91. 0 287
      compiler/ia64/aasmcpu.pas
  92. 0 150
      compiler/ia64/cpubase.pas
  93. 0 105
      compiler/ia64/cpuinfo.pas
  94. 0 268
      compiler/ia64/ia64reg.dat
  95. 0 211
      compiler/ia64/symcpu.pas
  96. 2 2
      compiler/jvm/cpupara.pas
  97. 1 0
      compiler/jvm/hlcgcpu.pas
  98. 1 1
      compiler/jvm/njvmadd.pas
  99. 13 3
      compiler/jvm/njvmcal.pas
  100. 5 5
      compiler/jvm/njvmcnv.pas

+ 136 - 43
.gitattributes

@@ -52,25 +52,6 @@ compiler/aasmdata.pas svneol=native#text/plain
 compiler/aasmsym.pas svneol=native#text/plain
 compiler/aasmsym.pas svneol=native#text/plain
 compiler/aasmtai.pas svneol=native#text/plain
 compiler/aasmtai.pas svneol=native#text/plain
 compiler/aggas.pas svneol=native#text/plain
 compiler/aggas.pas svneol=native#text/plain
-compiler/agjasmin.pas svneol=native#text/plain
-compiler/alpha/aasmcpu.pas svneol=native#text/plain
-compiler/alpha/agaxpgas.pas svneol=native#text/plain
-compiler/alpha/aoptcpu.pas svneol=native#text/plain
-compiler/alpha/aoptcpub.pas svneol=native#text/plain
-compiler/alpha/aoptcpuc.pas svneol=native#text/plain
-compiler/alpha/aoptcpud.pas svneol=native#text/plain
-compiler/alpha/cgcpu.pas svneol=native#text/plain
-compiler/alpha/cpubase.pas svneol=native#text/plain
-compiler/alpha/cpuinfo.pas svneol=native#text/plain
-compiler/alpha/cpunode.pas svneol=native#text/plain
-compiler/alpha/cpupara.pas svneol=native#text/plain
-compiler/alpha/cpupi.pas svneol=native#text/plain
-compiler/alpha/cputarg.pas svneol=native#text/plain
-compiler/alpha/radirect.pas svneol=native#text/plain
-compiler/alpha/rasm.pas svneol=native#text/plain
-compiler/alpha/rgcpu.pas svneol=native#text/plain
-compiler/alpha/symcpu.pas svneol=native#text/plain
-compiler/alpha/tgcpu.pas svneol=native#text/plain
 compiler/aopt.pas svneol=native#text/plain
 compiler/aopt.pas svneol=native#text/plain
 compiler/aoptbase.pas svneol=native#text/plain
 compiler/aoptbase.pas svneol=native#text/plain
 compiler/aoptcs.pas svneol=native#text/plain
 compiler/aoptcs.pas svneol=native#text/plain
@@ -155,7 +136,6 @@ compiler/avr/rgcpu.pas svneol=native#text/plain
 compiler/avr/symcpu.pas svneol=native#text/plain
 compiler/avr/symcpu.pas svneol=native#text/plain
 compiler/blockutl.pas svneol=native#text/plain
 compiler/blockutl.pas svneol=native#text/plain
 compiler/browcol.pas svneol=native#text/plain
 compiler/browcol.pas svneol=native#text/plain
-compiler/bsdcompile -text
 compiler/catch.pas svneol=native#text/plain
 compiler/catch.pas svneol=native#text/plain
 compiler/ccharset.pas svneol=native#text/plain
 compiler/ccharset.pas svneol=native#text/plain
 compiler/cclasses.pas svneol=native#text/plain
 compiler/cclasses.pas svneol=native#text/plain
@@ -213,7 +193,6 @@ compiler/i386/cpunode.pas svneol=native#text/plain
 compiler/i386/cpupara.pas svneol=native#text/plain
 compiler/i386/cpupara.pas svneol=native#text/plain
 compiler/i386/cpupi.pas svneol=native#text/plain
 compiler/i386/cpupi.pas svneol=native#text/plain
 compiler/i386/cputarg.pas svneol=native#text/plain
 compiler/i386/cputarg.pas svneol=native#text/plain
-compiler/i386/csopt386.pas svneol=native#text/plain
 compiler/i386/daopt386.pas svneol=native#text/plain
 compiler/i386/daopt386.pas svneol=native#text/plain
 compiler/i386/hlcgcpu.pas svneol=native#text/plain
 compiler/i386/hlcgcpu.pas svneol=native#text/plain
 compiler/i386/i386att.inc svneol=native#text/plain
 compiler/i386/i386att.inc svneol=native#text/plain
@@ -250,7 +229,6 @@ compiler/i386/r386std.inc svneol=native#text/plain
 compiler/i386/ra386att.pas svneol=native#text/plain
 compiler/i386/ra386att.pas svneol=native#text/plain
 compiler/i386/ra386int.pas svneol=native#text/plain
 compiler/i386/ra386int.pas svneol=native#text/plain
 compiler/i386/rgcpu.pas svneol=native#text/plain
 compiler/i386/rgcpu.pas svneol=native#text/plain
-compiler/i386/rropt386.pas svneol=native#text/plain
 compiler/i386/symcpu.pas svneol=native#text/plain
 compiler/i386/symcpu.pas svneol=native#text/plain
 compiler/i8086/aoptcpu.pas svneol=native#text/plain
 compiler/i8086/aoptcpu.pas svneol=native#text/plain
 compiler/i8086/aoptcpub.pas svneol=native#text/plain
 compiler/i8086/aoptcpub.pas svneol=native#text/plain
@@ -300,11 +278,6 @@ compiler/i8086/ra8086int.pas svneol=native#text/plain
 compiler/i8086/rgcpu.pas svneol=native#text/plain
 compiler/i8086/rgcpu.pas svneol=native#text/plain
 compiler/i8086/symcpu.pas svneol=native#text/plain
 compiler/i8086/symcpu.pas svneol=native#text/plain
 compiler/i8086/tgcpu.pas svneol=native#text/plain
 compiler/i8086/tgcpu.pas svneol=native#text/plain
-compiler/ia64/aasmcpu.pas svneol=native#text/plain
-compiler/ia64/cpubase.pas svneol=native#text/plain
-compiler/ia64/cpuinfo.pas svneol=native#text/plain
-compiler/ia64/ia64reg.dat svneol=native#text/plain
-compiler/ia64/symcpu.pas svneol=native#text/plain
 compiler/impdef.pas svneol=native#text/plain
 compiler/impdef.pas svneol=native#text/plain
 compiler/import.pas svneol=native#text/plain
 compiler/import.pas svneol=native#text/plain
 compiler/jvm/aasmcpu.pas svneol=native#text/plain
 compiler/jvm/aasmcpu.pas svneol=native#text/plain
@@ -813,11 +786,6 @@ compiler/utils/ppuutils/ppuxml.pp svneol=native#text/plain
 compiler/utils/samplecfg svneol=native#text/plain
 compiler/utils/samplecfg svneol=native#text/plain
 compiler/verbose.pas svneol=native#text/plain
 compiler/verbose.pas svneol=native#text/plain
 compiler/version.pas svneol=native#text/plain
 compiler/version.pas svneol=native#text/plain
-compiler/vis/aasmcpu.pas svneol=native#text/plain
-compiler/vis/cpubase.pas svneol=native#text/plain
-compiler/vis/cpuinfo.pas svneol=native#text/plain
-compiler/vis/cpunode.pas svneol=native#text/plain
-compiler/vis/cpupara.pas svneol=native#text/plain
 compiler/widestr.pas svneol=native#text/plain
 compiler/widestr.pas svneol=native#text/plain
 compiler/wpo.pas svneol=native#text/plain
 compiler/wpo.pas svneol=native#text/plain
 compiler/wpobase.pas svneol=native#text/plain
 compiler/wpobase.pas svneol=native#text/plain
@@ -2577,6 +2545,9 @@ packages/fcl-process/Makefile svneol=native#text/plain
 packages/fcl-process/Makefile.fpc svneol=native#text/plain
 packages/fcl-process/Makefile.fpc svneol=native#text/plain
 packages/fcl-process/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/fcl-process/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/fcl-process/fpmake.pp svneol=native#text/plain
 packages/fcl-process/fpmake.pp svneol=native#text/plain
+packages/fcl-process/src/amicommon/pipes.inc svneol=native#text/plain
+packages/fcl-process/src/amicommon/process.inc svneol=native#text/plain
+packages/fcl-process/src/amicommon/simpleipc.inc svneol=native#text/plain
 packages/fcl-process/src/dbugintf.pp svneol=native#text/plain
 packages/fcl-process/src/dbugintf.pp svneol=native#text/plain
 packages/fcl-process/src/dbugmsg.pp svneol=native#text/plain
 packages/fcl-process/src/dbugmsg.pp svneol=native#text/plain
 packages/fcl-process/src/dummy/pipes.inc svneol=native#text/plain
 packages/fcl-process/src/dummy/pipes.inc svneol=native#text/plain
@@ -3520,6 +3491,92 @@ packages/gnome1/src/zvt/libzvt.pp svneol=native#text/plain
 packages/gnome1/src/zvt/lists.inc svneol=native#text/plain
 packages/gnome1/src/zvt/lists.inc svneol=native#text/plain
 packages/gnome1/src/zvt/vt.inc svneol=native#text/plain
 packages/gnome1/src/zvt/vt.inc svneol=native#text/plain
 packages/gnome1/src/zvt/vtx.inc svneol=native#text/plain
 packages/gnome1/src/zvt/vtx.inc svneol=native#text/plain
+packages/googleapi/Makefile svneol=native#text/plain
+packages/googleapi/Makefile.fpc svneol=native#text/plain
+packages/googleapi/README.txt svneol=native#text/plain
+packages/googleapi/examples/generator/googleapiconv.lpi svneol=native#text/plain
+packages/googleapi/examples/generator/googleapiconv.pp svneol=native#text/plain
+packages/googleapi/fpmake.pp svneol=native#text/plain
+packages/googleapi/src/googleadexchangebuyer.pp svneol=native#text/plain
+packages/googleapi/src/googleadexchangeseller.pp svneol=native#text/plain
+packages/googleapi/src/googleadmin.pp svneol=native#text/plain
+packages/googleapi/src/googleadsense.pp svneol=native#text/plain
+packages/googleapi/src/googleadsensehost.pp svneol=native#text/plain
+packages/googleapi/src/googleanalytics.pp svneol=native#text/plain
+packages/googleapi/src/googleandroidenterprise.pp svneol=native#text/plain
+packages/googleapi/src/googleandroidpublisher.pp svneol=native#text/plain
+packages/googleapi/src/googleappsactivity.pp svneol=native#text/plain
+packages/googleapi/src/googleappstate.pp svneol=native#text/plain
+packages/googleapi/src/googleaudit.pp svneol=native#text/plain
+packages/googleapi/src/googleautoscaler.pp svneol=native#text/plain
+packages/googleapi/src/googlebase.pp svneol=native#text/plain
+packages/googleapi/src/googlebigquery.pp svneol=native#text/plain
+packages/googleapi/src/googleblogger.pp svneol=native#text/plain
+packages/googleapi/src/googlebooks.pp svneol=native#text/plain
+packages/googleapi/src/googlecalendar.pp svneol=native#text/plain
+packages/googleapi/src/googlecivicinfo.pp svneol=native#text/plain
+packages/googleapi/src/googleclient.pp svneol=native#text/plain
+packages/googleapi/src/googlecloudlatencytest.pp svneol=native#text/plain
+packages/googleapi/src/googlecloudmonitoring.pp svneol=native#text/plain
+packages/googleapi/src/googlecloudsearch.pp svneol=native#text/plain
+packages/googleapi/src/googlecompute.pp svneol=native#text/plain
+packages/googleapi/src/googlecomputeaccounts.pp svneol=native#text/plain
+packages/googleapi/src/googlecontainer.pp svneol=native#text/plain
+packages/googleapi/src/googlecontent.pp svneol=native#text/plain
+packages/googleapi/src/googlecoordinate.pp svneol=native#text/plain
+packages/googleapi/src/googlecustomsearch.pp svneol=native#text/plain
+packages/googleapi/src/googledataflow.pp svneol=native#text/plain
+packages/googleapi/src/googledatastore.pp svneol=native#text/plain
+packages/googleapi/src/googledeploymentmanager.pp svneol=native#text/plain
+packages/googleapi/src/googledfareporting.pp svneol=native#text/plain
+packages/googleapi/src/googlediscovery.pp svneol=native#text/plain
+packages/googleapi/src/googlediscoverytopas.pp svneol=native#text/plain
+packages/googleapi/src/googledns.pp svneol=native#text/plain
+packages/googleapi/src/googledoubleclickbidmanager.pp svneol=native#text/plain
+packages/googleapi/src/googledoubleclicksearch.pp svneol=native#text/plain
+packages/googleapi/src/googledrive.pp svneol=native#text/plain
+packages/googleapi/src/googlefitness.pp svneol=native#text/plain
+packages/googleapi/src/googlefreebase.pp svneol=native#text/plain
+packages/googleapi/src/googlefusiontables.pp svneol=native#text/plain
+packages/googleapi/src/googlegames.pp svneol=native#text/plain
+packages/googleapi/src/googlegamesConfiguration.pp svneol=native#text/plain
+packages/googleapi/src/googlegamesManagement.pp svneol=native#text/plain
+packages/googleapi/src/googlegan.pp svneol=native#text/plain
+packages/googleapi/src/googlegenomics.pp svneol=native#text/plain
+packages/googleapi/src/googlegmail.pp svneol=native#text/plain
+packages/googleapi/src/googlegroupsmigration.pp svneol=native#text/plain
+packages/googleapi/src/googlegroupssettings.pp svneol=native#text/plain
+packages/googleapi/src/googleidentitytoolkit.pp svneol=native#text/plain
+packages/googleapi/src/googlelicensing.pp svneol=native#text/plain
+packages/googleapi/src/googlelogging.pp svneol=native#text/plain
+packages/googleapi/src/googlemanager.pp svneol=native#text/plain
+packages/googleapi/src/googlemapsengine.pp svneol=native#text/plain
+packages/googleapi/src/googlemirror.pp svneol=native#text/plain
+packages/googleapi/src/googleoauth2.pp svneol=native#text/plain
+packages/googleapi/src/googlepagespeedonline.pp svneol=native#text/plain
+packages/googleapi/src/googleplus.pp svneol=native#text/plain
+packages/googleapi/src/googleplusDomains.pp svneol=native#text/plain
+packages/googleapi/src/googleprediction.pp svneol=native#text/plain
+packages/googleapi/src/googlepubsub.pp svneol=native#text/plain
+packages/googleapi/src/googleqpxExpress.pp svneol=native#text/plain
+packages/googleapi/src/googlereplicapool.pp svneol=native#text/plain
+packages/googleapi/src/googlereplicapoolupdater.pp svneol=native#text/plain
+packages/googleapi/src/googlereseller.pp svneol=native#text/plain
+packages/googleapi/src/googleresourceviews.pp svneol=native#text/plain
+packages/googleapi/src/googleservice.pp svneol=native#text/plain
+packages/googleapi/src/googlesiteVerification.pp svneol=native#text/plain
+packages/googleapi/src/googlespectrum.pp svneol=native#text/plain
+packages/googleapi/src/googlesqladmin.pp svneol=native#text/plain
+packages/googleapi/src/googlestorage.pp svneol=native#text/plain
+packages/googleapi/src/googletagmanager.pp svneol=native#text/plain
+packages/googleapi/src/googletaskqueue.pp svneol=native#text/plain
+packages/googleapi/src/googletasks.pp svneol=native#text/plain
+packages/googleapi/src/googletranslate.pp svneol=native#text/plain
+packages/googleapi/src/googleurlshortener.pp svneol=native#text/plain
+packages/googleapi/src/googlewebfonts.pp svneol=native#text/plain
+packages/googleapi/src/googlewebmasters.pp svneol=native#text/plain
+packages/googleapi/src/googleyoutube.pp svneol=native#text/plain
+packages/googleapi/src/googleyoutubeAnalytics.pp svneol=native#text/plain
 packages/graph/Makefile svneol=native#text/plain
 packages/graph/Makefile svneol=native#text/plain
 packages/graph/Makefile.fpc svneol=native#text/plain
 packages/graph/Makefile.fpc svneol=native#text/plain
 packages/graph/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/graph/Makefile.fpc.fpcmake svneol=native#text/plain
@@ -4782,6 +4839,21 @@ packages/libcurl/examples/testcurl.pp svneol=native#text/plain
 packages/libcurl/examples/teststream.pp svneol=native#text/plain
 packages/libcurl/examples/teststream.pp svneol=native#text/plain
 packages/libcurl/fpmake.pp svneol=native#text/plain
 packages/libcurl/fpmake.pp svneol=native#text/plain
 packages/libcurl/src/libcurl.pp svneol=native#text/plain
 packages/libcurl/src/libcurl.pp svneol=native#text/plain
+packages/libenet/Makefile svneol=native#text/plain
+packages/libenet/Makefile.fpc svneol=native#text/plain
+packages/libenet/examples/clientapp.lpi svneol=native#text/plain
+packages/libenet/examples/clientapp.pp svneol=native#text/plain
+packages/libenet/examples/serverapp.lpi svneol=native#text/plain
+packages/libenet/examples/serverapp.pp svneol=native#text/plain
+packages/libenet/fpmake.pp svneol=native#text/plain
+packages/libenet/src/enet.pp svneol=native#text/plain
+packages/libenet/src/enetcallbacks.pp svneol=native#text/plain
+packages/libenet/src/enetlist.pp svneol=native#text/plain
+packages/libenet/src/enetplatform.pp svneol=native#text/plain
+packages/libenet/src/enetprotocol.pp svneol=native#text/plain
+packages/libenet/src/enettime.pp svneol=native#text/plain
+packages/libenet/src/enettypes.pp svneol=native#text/plain
+packages/libenet/src/uenetclass.pp svneol=native#text/plain
 packages/libgbafpc/Makefile svneol=native#text/plain
 packages/libgbafpc/Makefile svneol=native#text/plain
 packages/libgbafpc/Makefile.fpc svneol=native#text/plain
 packages/libgbafpc/Makefile.fpc svneol=native#text/plain
 packages/libgbafpc/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/libgbafpc/Makefile.fpc.fpcmake svneol=native#text/plain
@@ -5696,6 +5768,7 @@ packages/mysql/examples/mysqls.c svneol=native#text/plain
 packages/mysql/examples/mysqls.pp svneol=native#text/plain
 packages/mysql/examples/mysqls.pp svneol=native#text/plain
 packages/mysql/examples/testdb3.pp svneol=native#text/plain
 packages/mysql/examples/testdb3.pp svneol=native#text/plain
 packages/mysql/examples/testdb4.pp svneol=native#text/plain
 packages/mysql/examples/testdb4.pp svneol=native#text/plain
+packages/mysql/examples/testdb5.pp svneol=native#text/plain
 packages/mysql/fpmake.pp svneol=native#text/plain
 packages/mysql/fpmake.pp svneol=native#text/plain
 packages/mysql/scripts/mkdb svneol=native#text/plain
 packages/mysql/scripts/mkdb svneol=native#text/plain
 packages/mysql/scripts/rmdb svneol=native#text/plain
 packages/mysql/scripts/rmdb svneol=native#text/plain
@@ -6727,6 +6800,8 @@ packages/rtl-extra/src/bsd/clocale.inc svneol=native#text/plain
 packages/rtl-extra/src/bsd/ipcbsd.inc svneol=native#text/plain
 packages/rtl-extra/src/bsd/ipcbsd.inc svneol=native#text/plain
 packages/rtl-extra/src/bsd/osdefs.inc svneol=native#text/plain
 packages/rtl-extra/src/bsd/osdefs.inc svneol=native#text/plain
 packages/rtl-extra/src/darwin/unxsockh.inc svneol=native#text/plain
 packages/rtl-extra/src/darwin/unxsockh.inc svneol=native#text/plain
+packages/rtl-extra/src/dragonfly/unixsock.inc svneol=native#text/plain
+packages/rtl-extra/src/dragonfly/unxsockh.inc svneol=native#text/plain
 packages/rtl-extra/src/freebsd/unixsock.inc svneol=native#text/plain
 packages/rtl-extra/src/freebsd/unixsock.inc svneol=native#text/plain
 packages/rtl-extra/src/freebsd/unxsockh.inc svneol=native#text/plain
 packages/rtl-extra/src/freebsd/unxsockh.inc svneol=native#text/plain
 packages/rtl-extra/src/go32v2/printer.pp svneol=native#text/plain
 packages/rtl-extra/src/go32v2/printer.pp svneol=native#text/plain
@@ -6751,7 +6826,6 @@ packages/rtl-extra/src/linux/unixsock.inc svneol=native#text/plain
 packages/rtl-extra/src/linux/unixsockets.inc svneol=native#text/plain
 packages/rtl-extra/src/linux/unixsockets.inc svneol=native#text/plain
 packages/rtl-extra/src/linux/unixsocketsh.inc svneol=native#text/plain
 packages/rtl-extra/src/linux/unixsocketsh.inc svneol=native#text/plain
 packages/rtl-extra/src/linux/unxsockh.inc svneol=native#text/plain
 packages/rtl-extra/src/linux/unxsockh.inc svneol=native#text/plain
-packages/rtl-extra/src/morphos/sockets.pp svneol=native#text/plain
 packages/rtl-extra/src/msdos/printer.pp svneol=native#text/plain
 packages/rtl-extra/src/msdos/printer.pp svneol=native#text/plain
 packages/rtl-extra/src/netbsd/unixsock.inc svneol=native#text/plain
 packages/rtl-extra/src/netbsd/unixsock.inc svneol=native#text/plain
 packages/rtl-extra/src/netbsd/unxsockh.inc svneol=native#text/plain
 packages/rtl-extra/src/netbsd/unxsockh.inc svneol=native#text/plain
@@ -7031,6 +7105,8 @@ packages/univint/src/CFDateFormatter.pas svneol=native#text/plain
 packages/univint/src/CFDictionary.pas svneol=native#text/plain
 packages/univint/src/CFDictionary.pas svneol=native#text/plain
 packages/univint/src/CFError.pas svneol=native#text/plain
 packages/univint/src/CFError.pas svneol=native#text/plain
 packages/univint/src/CFFTPStream.pas svneol=native#text/plain
 packages/univint/src/CFFTPStream.pas svneol=native#text/plain
+packages/univint/src/CFFileDescriptor.pas svneol=native#text/plain
+packages/univint/src/CFFileSecurity.pas svneol=native#text/plain
 packages/univint/src/CFHTTPAuthentication.pas svneol=native#text/plain
 packages/univint/src/CFHTTPAuthentication.pas svneol=native#text/plain
 packages/univint/src/CFHTTPMessage.pas svneol=native#text/plain
 packages/univint/src/CFHTTPMessage.pas svneol=native#text/plain
 packages/univint/src/CFHTTPStream.pas svneol=native#text/plain
 packages/univint/src/CFHTTPStream.pas svneol=native#text/plain
@@ -7061,6 +7137,7 @@ packages/univint/src/CFTimeZone.pas svneol=native#text/plain
 packages/univint/src/CFTree.pas svneol=native#text/plain
 packages/univint/src/CFTree.pas svneol=native#text/plain
 packages/univint/src/CFURL.pas svneol=native#text/plain
 packages/univint/src/CFURL.pas svneol=native#text/plain
 packages/univint/src/CFURLAccess.pas svneol=native#text/plain
 packages/univint/src/CFURLAccess.pas svneol=native#text/plain
+packages/univint/src/CFURLEnumerator.pas svneol=native#text/plain
 packages/univint/src/CFUUID.pas svneol=native#text/plain
 packages/univint/src/CFUUID.pas svneol=native#text/plain
 packages/univint/src/CFUserNotification.pas svneol=native#text/plain
 packages/univint/src/CFUserNotification.pas svneol=native#text/plain
 packages/univint/src/CFXMLNode.pas svneol=native#text/plain
 packages/univint/src/CFXMLNode.pas svneol=native#text/plain
@@ -7355,6 +7432,11 @@ packages/univint/src/SCSI.pas svneol=native#text/plain
 packages/univint/src/SCSchemaDefinitions.pas svneol=native#text/plain
 packages/univint/src/SCSchemaDefinitions.pas svneol=native#text/plain
 packages/univint/src/SFNTLayoutTypes.pas svneol=native#text/plain
 packages/univint/src/SFNTLayoutTypes.pas svneol=native#text/plain
 packages/univint/src/SFNTTypes.pas svneol=native#text/plain
 packages/univint/src/SFNTTypes.pas svneol=native#text/plain
+packages/univint/src/SKAnalysis.pas svneol=native#text/plain
+packages/univint/src/SKDocument.pas svneol=native#text/plain
+packages/univint/src/SKIndex.pas svneol=native#text/plain
+packages/univint/src/SKSearch.pas svneol=native#text/plain
+packages/univint/src/SKSummary.pas svneol=native#text/plain
 packages/univint/src/ScalerStreamTypes.pas svneol=native#text/plain
 packages/univint/src/ScalerStreamTypes.pas svneol=native#text/plain
 packages/univint/src/Scrap.pas svneol=native#text/plain
 packages/univint/src/Scrap.pas svneol=native#text/plain
 packages/univint/src/Script.pas svneol=native#text/plain
 packages/univint/src/Script.pas svneol=native#text/plain
@@ -7392,6 +7474,7 @@ packages/univint/src/Video.pas svneol=native#text/plain
 packages/univint/src/WSMethodInvocation.pas svneol=native#text/plain
 packages/univint/src/WSMethodInvocation.pas svneol=native#text/plain
 packages/univint/src/WSProtocolHandler.pas svneol=native#text/plain
 packages/univint/src/WSProtocolHandler.pas svneol=native#text/plain
 packages/univint/src/WSTypes.pas svneol=native#text/plain
 packages/univint/src/WSTypes.pas svneol=native#text/plain
+packages/univint/src/acl.pas svneol=native#text/plain
 packages/univint/src/cblas.pas svneol=native#text/plain
 packages/univint/src/cblas.pas svneol=native#text/plain
 packages/univint/src/certextensions.pas svneol=native#text/plain
 packages/univint/src/certextensions.pas svneol=native#text/plain
 packages/univint/src/cssmapple.pas svneol=native#text/plain
 packages/univint/src/cssmapple.pas svneol=native#text/plain
@@ -7975,7 +8058,6 @@ rtl/amiga/powerpc/utild2.inc svneol=native#text/plain
 rtl/amiga/powerpc/utilf.inc svneol=native#text/plain
 rtl/amiga/powerpc/utilf.inc svneol=native#text/plain
 rtl/amiga/system.pp svneol=native#text/plain
 rtl/amiga/system.pp svneol=native#text/plain
 rtl/amiga/timerd.inc 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
 rtl/android/Makefile svneol=native#text/plain
 rtl/android/Makefile.fpc svneol=native#text/plain
 rtl/android/Makefile.fpc svneol=native#text/plain
 rtl/android/arm/dllprt0.as svneol=native#text/plain
 rtl/android/arm/dllprt0.as svneol=native#text/plain
@@ -8009,7 +8091,6 @@ rtl/arm/thumb.inc svneol=native#text/plain
 rtl/arm/thumb2.inc svneol=native#text/plain
 rtl/arm/thumb2.inc svneol=native#text/plain
 rtl/aros/Makefile svneol=native#text/plain
 rtl/aros/Makefile svneol=native#text/plain
 rtl/aros/Makefile.fpc 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/doslibd.inc svneol=native#text/plain
 rtl/aros/i386/doslibf.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/execd.inc svneol=native#text/plain
@@ -8019,10 +8100,8 @@ rtl/aros/i386/utild1.inc svneol=native#text/plain
 rtl/aros/i386/utild2.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/i386/utilf.inc svneol=native#text/plain
 rtl/aros/system.pp 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/timerd.inc svneol=native#text/plain
-rtl/aros/tthread.inc svneol=native#text/plain
+rtl/aros/x86_64/prt0.as svneol=native#text/plain
 rtl/atari/Makefile svneol=native#text/plain
 rtl/atari/Makefile svneol=native#text/plain
 rtl/atari/Makefile.fpc svneol=native#text/plain
 rtl/atari/Makefile.fpc svneol=native#text/plain
 rtl/atari/prt0.as svneol=native#text/plain
 rtl/atari/prt0.as svneol=native#text/plain
@@ -8354,6 +8433,7 @@ rtl/haiku/classes.pp svneol=native#text/plain
 rtl/haiku/errno.inc svneol=native#text/plain
 rtl/haiku/errno.inc svneol=native#text/plain
 rtl/haiku/errnostr.inc svneol=native#text/plain
 rtl/haiku/errnostr.inc svneol=native#text/plain
 rtl/haiku/i386/cprt0.as svneol=native#text/plain
 rtl/haiku/i386/cprt0.as svneol=native#text/plain
+rtl/haiku/i386/dllcprt0.as svneol=native#text/plain
 rtl/haiku/i386/dllprt.as svneol=native#text/plain
 rtl/haiku/i386/dllprt.as svneol=native#text/plain
 rtl/haiku/i386/dllprt.cpp svneol=native#text/plain
 rtl/haiku/i386/dllprt.cpp svneol=native#text/plain
 rtl/haiku/i386/func.as svneol=native#text/plain
 rtl/haiku/i386/func.as svneol=native#text/plain
@@ -8453,6 +8533,7 @@ rtl/inc/int64.inc svneol=native#text/plain
 rtl/inc/intres.inc svneol=native#text/plain
 rtl/inc/intres.inc svneol=native#text/plain
 rtl/inc/iso7185.pp svneol=native#text/pascal
 rtl/inc/iso7185.pp svneol=native#text/pascal
 rtl/inc/lineinfo.pp svneol=native#text/plain
 rtl/inc/lineinfo.pp svneol=native#text/plain
+rtl/inc/llvmintr.inc svneol=native#text/plain
 rtl/inc/lnfodwrf.pp svneol=native#text/plain
 rtl/inc/lnfodwrf.pp svneol=native#text/plain
 rtl/inc/lstrings.pp svneol=native#text/plain
 rtl/inc/lstrings.pp svneol=native#text/plain
 rtl/inc/macpas.pp svneol=native#text/plain
 rtl/inc/macpas.pp svneol=native#text/plain
@@ -8477,7 +8558,7 @@ rtl/inc/sstrings.inc svneol=native#text/plain
 rtl/inc/strings.pp svneol=native#text/plain
 rtl/inc/strings.pp svneol=native#text/plain
 rtl/inc/stringsi.inc svneol=native#text/plain
 rtl/inc/stringsi.inc svneol=native#text/plain
 rtl/inc/sysres.inc svneol=native#text/plain
 rtl/inc/sysres.inc svneol=native#text/plain
-rtl/inc/system.fpd -text
+rtl/inc/system.fpd svneol=native#text/plain
 rtl/inc/system.inc svneol=native#text/plain
 rtl/inc/system.inc svneol=native#text/plain
 rtl/inc/systemh.inc svneol=native#text/plain
 rtl/inc/systemh.inc svneol=native#text/plain
 rtl/inc/text.inc svneol=native#text/plain
 rtl/inc/text.inc svneol=native#text/plain
@@ -8544,6 +8625,17 @@ rtl/jvm/setjump.inc svneol=native#text/plain
 rtl/jvm/setjumph.inc svneol=native#text/plain
 rtl/jvm/setjumph.inc svneol=native#text/plain
 rtl/linux/Makefile svneol=native#text/plain
 rtl/linux/Makefile svneol=native#text/plain
 rtl/linux/Makefile.fpc svneol=native#text/plain
 rtl/linux/Makefile.fpc svneol=native#text/plain
+rtl/linux/aarch64/bsyscall.inc svneol=native#text/plain
+rtl/linux/aarch64/cprt0.as svneol=native#text/plain
+rtl/linux/aarch64/dllprt0.as svneol=native#text/plain
+rtl/linux/aarch64/gprt0.as svneol=native#text/plain
+rtl/linux/aarch64/prt0.as svneol=native#text/plain
+rtl/linux/aarch64/sighnd.inc svneol=native#text/plain
+rtl/linux/aarch64/sighndh.inc svneol=native#text/plain
+rtl/linux/aarch64/stat.inc svneol=native#text/plain
+rtl/linux/aarch64/syscall.inc svneol=native#text/plain
+rtl/linux/aarch64/syscallh.inc svneol=native#text/plain
+rtl/linux/aarch64/sysnr.inc svneol=native#text/plain
 rtl/linux/arm/bsyscall.inc svneol=native#text/plain
 rtl/linux/arm/bsyscall.inc svneol=native#text/plain
 rtl/linux/arm/cprt0.as svneol=native#text/plain
 rtl/linux/arm/cprt0.as svneol=native#text/plain
 rtl/linux/arm/dllprt0.as svneol=native#text/plain
 rtl/linux/arm/dllprt0.as svneol=native#text/plain
@@ -8762,11 +8854,9 @@ rtl/morphos/emuld.inc svneol=native#text/plain
 rtl/morphos/execd.inc svneol=native#text/plain
 rtl/morphos/execd.inc svneol=native#text/plain
 rtl/morphos/execf.inc svneol=native#text/plain
 rtl/morphos/execf.inc svneol=native#text/plain
 rtl/morphos/prt0.as svneol=native#text/plain
 rtl/morphos/prt0.as svneol=native#text/plain
-rtl/morphos/sysosh.inc svneol=native#text/plain
 rtl/morphos/system.pp svneol=native#text/plain
 rtl/morphos/system.pp svneol=native#text/plain
 rtl/morphos/timerd.inc svneol=native#text/plain
 rtl/morphos/timerd.inc svneol=native#text/plain
 rtl/morphos/timerf.inc svneol=native#text/plain
 rtl/morphos/timerf.inc svneol=native#text/plain
-rtl/morphos/tthread.inc svneol=native#text/plain
 rtl/morphos/utild1.inc svneol=native#text/plain
 rtl/morphos/utild1.inc svneol=native#text/plain
 rtl/morphos/utild2.inc svneol=native#text/plain
 rtl/morphos/utild2.inc svneol=native#text/plain
 rtl/morphos/utilf.inc svneol=native#text/plain
 rtl/morphos/utilf.inc svneol=native#text/plain
@@ -14404,6 +14494,8 @@ tests/webtbs/tw2830.pp svneol=native#text/plain
 tests/webtbs/tw2832.pp svneol=native#text/plain
 tests/webtbs/tw2832.pp svneol=native#text/plain
 tests/webtbs/tw2834.pp svneol=native#text/plain
 tests/webtbs/tw2834.pp svneol=native#text/plain
 tests/webtbs/tw2841.pp svneol=native#text/plain
 tests/webtbs/tw2841.pp svneol=native#text/plain
+tests/webtbs/tw28442.pp svneol=native#text/pascal
+tests/webtbs/tw28454.pp svneol=native#text/plain
 tests/webtbs/tw2853.pp svneol=native#text/plain
 tests/webtbs/tw2853.pp svneol=native#text/plain
 tests/webtbs/tw2853a.pp svneol=native#text/plain
 tests/webtbs/tw2853a.pp svneol=native#text/plain
 tests/webtbs/tw2853b.pp svneol=native#text/plain
 tests/webtbs/tw2853b.pp svneol=native#text/plain
@@ -15121,6 +15213,7 @@ tests/webtbs/uw2731.pp svneol=native#text/plain
 tests/webtbs/uw27320.defaults.pp svneol=native#text/pascal
 tests/webtbs/uw27320.defaults.pp svneol=native#text/pascal
 tests/webtbs/uw2738.pp svneol=native#text/plain
 tests/webtbs/uw2738.pp svneol=native#text/plain
 tests/webtbs/uw2834.pp svneol=native#text/plain
 tests/webtbs/uw2834.pp svneol=native#text/plain
+tests/webtbs/uw28442.pp svneol=native#text/pascal
 tests/webtbs/uw2920.pp svneol=native#text/plain
 tests/webtbs/uw2920.pp svneol=native#text/plain
 tests/webtbs/uw2956.pp svneol=native#text/plain
 tests/webtbs/uw2956.pp svneol=native#text/plain
 tests/webtbs/uw2984.pp svneol=native#text/plain
 tests/webtbs/uw2984.pp svneol=native#text/plain
@@ -15440,8 +15533,8 @@ utils/h2pas/h2pyacclib.pas svneol=native#text/plain
 utils/h2pas/scan.l svneol=native#text/plain
 utils/h2pas/scan.l svneol=native#text/plain
 utils/h2pas/scan.pas svneol=native#text/plain
 utils/h2pas/scan.pas svneol=native#text/plain
 utils/h2pas/testit.h -text
 utils/h2pas/testit.h -text
-utils/h2pas/yylex.cod -text
-utils/h2pas/yyparse.cod -text
+utils/h2pas/yylex.cod svneol=native#text/plain
+utils/h2pas/yyparse.cod svneol=native#text/plain
 utils/importtl/Makefile svneol=native#text/plain
 utils/importtl/Makefile svneol=native#text/plain
 utils/importtl/Makefile.fpc svneol=native#text/plain
 utils/importtl/Makefile.fpc svneol=native#text/plain
 utils/importtl/Makefile.fpc.fpcmake svneol=native#text/plain
 utils/importtl/Makefile.fpc.fpcmake svneol=native#text/plain

+ 45 - 4
Makefile

@@ -1,8 +1,8 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-02-23 rev 29972]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-07-28 rev 31240]
 #
 #
 default: help
 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 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-iphonesim 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 aarch64-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-iphonesim x86_64-aros 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 aarch64-linux aarch64-darwin
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos
 LIMIT83fs = go32v2 os2 emx watcom msdos
@@ -184,6 +184,12 @@ $(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t
 endif
 endif
 override FPCOPT+=-Cp$(SUBARCH)
 override FPCOPT+=-Cp$(SUBARCH)
 endif
 endif
+ifeq ($(FULL_TARGET),avr-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for avr-embedded, a sub-architecture (e.g. SUBARCH=avr25 or SUBARCH=avr35) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
 ifeq ($(FULL_TARGET),mipsel-embedded)
 ifeq ($(FULL_TARGET),mipsel-embedded)
 ifeq ($(SUBARCH),)
 ifeq ($(SUBARCH),)
 $(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
 $(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
@@ -328,7 +334,7 @@ endif
 override PACKAGE_NAME=fpc
 override PACKAGE_NAME=fpc
 override PACKAGE_VERSION=3.1.1
 override PACKAGE_VERSION=3.1.1
 REQUIREDVERSION=2.6.4
 REQUIREDVERSION=2.6.4
-REQUIREDVERSION2=2.6.2
+REQUIREDVERSION2=3.0.0
 ifndef inOS2
 ifndef inOS2
 override FPCDIR:=$(BASEDIR)
 override FPCDIR:=$(BASEDIR)
 export FPCDIR
 export FPCDIR
@@ -639,6 +645,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
 endif
@@ -711,6 +720,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
 endif
@@ -1110,6 +1122,10 @@ STATICLIBPREFIX=
 STATICLIBEXT=.a
 STATICLIBEXT=.a
 SHORTSUFFIX=d16
 SHORTSUFFIX=d16
 endif
 endif
+ifeq ($(OS_TARGET),embedded)
+EXEEXT=.bin
+SHORTSUFFIX=emb
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -1376,6 +1392,7 @@ endif
 ifeq ($(OS_SOURCE),openbsd)
 ifeq ($(OS_SOURCE),openbsd)
 override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
 override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
 override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
 override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
+override FPMAKE_BUILD_OPT+=-FD$(NEW_BINUTILS_PATH)
 endif
 endif
 ifndef CROSSBOOTSTRAP
 ifndef CROSSBOOTSTRAP
 ifneq ($(BINUTILSPREFIX),)
 ifneq ($(BINUTILSPREFIX),)
@@ -1388,6 +1405,7 @@ endif
 ifndef CROSSCOMPILE
 ifndef CROSSCOMPILE
 ifneq ($(BINUTILSPREFIX),)
 ifneq ($(BINUTILSPREFIX),)
 override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
 override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
+override FPMAKE_BUILD_OPT+=-XP$(BINUTILSPREFIX)
 endif
 endif
 endif
 endif
 ifdef UNITDIR
 ifdef UNITDIR
@@ -1487,6 +1505,9 @@ endif
 ifdef OPT
 ifdef OPT
 override FPCOPT+=$(OPT)
 override FPCOPT+=$(OPT)
 endif
 endif
+ifdef FPMAKEBUILDOPT
+override FPMAKE_BUILD_OPT+=$(FPMAKEBUILDOPT)
+endif
 ifdef FPCOPTDEF
 ifdef FPCOPTDEF
 override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
 override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
 endif
 endif
@@ -1585,7 +1606,7 @@ endif
 fpc_sourceinstall: distclean
 fpc_sourceinstall: distclean
 	$(MKDIR) $(INSTALL_SOURCEDIR)
 	$(MKDIR) $(INSTALL_SOURCEDIR)
 	$(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
 	$(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
-fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+fpc_exampleinstall: $(EXAMPLEINSTALLTARGET) $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
 ifdef HASEXAMPLES
 ifdef HASEXAMPLES
 	$(MKDIR) $(INSTALL_EXAMPLEDIR)
 	$(MKDIR) $(INSTALL_EXAMPLEDIR)
 endif
 endif
@@ -1757,6 +1778,10 @@ endif
 ifdef DEBUGSYMEXT
 ifdef DEBUGSYMEXT
 	-$(DEL) *$(DEBUGSYMEXT)
 	-$(DEL) *$(DEBUGSYMEXT)
 endif
 endif
+ifdef LOCALFPMAKEBIN
+	-$(DEL) $(LOCALFPMAKEBIN)
+	-$(DEL) $(FPMAKEBINOBJ)
+endif
 fpc_distclean: cleanall
 fpc_distclean: cleanall
 .PHONY: fpc_baseinfo
 .PHONY: fpc_baseinfo
 override INFORULES+=fpc_baseinfo
 override INFORULES+=fpc_baseinfo
@@ -2297,6 +2322,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 TARGET_DIRS_INSTALLER=1
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-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),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
 TARGET_DIRS_RTL=1
@@ -2489,6 +2522,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 TARGET_DIRS_INSTALLER=1
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+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),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
 TARGET_DIRS_RTL=1

+ 4 - 1
Makefile.fpc

@@ -21,7 +21,10 @@ rule=help
 
 
 [prerules]
 [prerules]
 REQUIREDVERSION=2.6.4
 REQUIREDVERSION=2.6.4
-REQUIREDVERSION2=2.6.2
+# Accept 3.0.0, without requiring to using OVERRIDEVERSIONCHECK=1
+# 3.0.0 should become REQUIREDVERSION after 3.0.0 final release
+# and 2.6.4 should be moved to REQUIREDVERSION2
+REQUIREDVERSION2=3.0.0
 
 
 
 
 # make versions < 3.77 (OS2 version) are buggy
 # make versions < 3.77 (OS2 version) are buggy

+ 63 - 12
compiler/Makefile

@@ -1,8 +1,8 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-02-24 rev 29972]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015/06/28]
 #
 #
 default: all
 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 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-iphonesim 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 aarch64-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-iphonesim x86_64-aros 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 aarch64-linux aarch64-darwin
 BSDs = freebsd netbsd openbsd darwin dragonfly
 BSDs = freebsd netbsd openbsd darwin dragonfly
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 UNIXs = linux $(BSDs) solaris qnx haiku aix
 LIMIT83fs = go32v2 os2 emx watcom msdos
 LIMIT83fs = go32v2 os2 emx watcom msdos
@@ -184,6 +184,12 @@ $(error When compiling for arm-embedded, a sub-architecture (e.g. SUBARCH=armv4t
 endif
 endif
 override FPCOPT+=-Cp$(SUBARCH)
 override FPCOPT+=-Cp$(SUBARCH)
 endif
 endif
+ifeq ($(FULL_TARGET),avr-embedded)
+ifeq ($(SUBARCH),)
+$(error When compiling for avr-embedded, a sub-architecture (e.g. SUBARCH=avr25 or SUBARCH=avr35) must be defined)
+endif
+override FPCOPT+=-Cp$(SUBARCH)
+endif
 ifeq ($(FULL_TARGET),mipsel-embedded)
 ifeq ($(FULL_TARGET),mipsel-embedded)
 ifeq ($(SUBARCH),)
 ifeq ($(SUBARCH),)
 $(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
 $(error When compiling for mipsel-embedded, a sub-architecture (e.g. SUBARCH=pic32mx) must be defined)
@@ -330,9 +336,6 @@ override PACKAGE_VERSION=3.1.1
 unexport FPC_VERSION FPC_COMPILERINFO
 unexport FPC_VERSION FPC_COMPILERINFO
 CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 aarch64
 CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr jvm i8086 aarch64
 ALLTARGETS=$(CYCLETARGETS)
 ALLTARGETS=$(CYCLETARGETS)
-ifdef ALPHA
-PPC_TARGET=alpha
-endif
 ifdef POWERPC
 ifdef POWERPC
 PPC_TARGET=powerpc
 PPC_TARGET=powerpc
 endif
 endif
@@ -436,11 +439,9 @@ MSGFILES=$(wildcard msg/error*.msg)
 ifeq ($(CPC_TARGET),i386)
 ifeq ($(CPC_TARGET),i386)
 CPUSUF=386
 CPUSUF=386
 endif
 endif
-ifeq ($(CPC_TARGET),alpha)
-CPUSUF=axp
-endif
 ifeq ($(CPC_TARGET),m68k)
 ifeq ($(CPC_TARGET),m68k)
 CPUSUF=68k
 CPUSUF=68k
+ALLOW_WARNINGS=1
 endif
 endif
 ifeq ($(CPC_TARGET),powerpc)
 ifeq ($(CPC_TARGET),powerpc)
 CPUSUF=ppc
 CPUSUF=ppc
@@ -465,6 +466,7 @@ CPUSUF=mipsel
 endif
 endif
 ifeq ($(CPC_TARGET),avr)
 ifeq ($(CPC_TARGET),avr)
 CPUSUF=avr
 CPUSUF=avr
+ALLOW_WARNINGS=1
 endif
 endif
 ifeq ($(CPC_TARGET),jvm)
 ifeq ($(CPC_TARGET),jvm)
 CPUSUF=jvm
 CPUSUF=jvm
@@ -716,6 +718,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 override TARGET_DIRS+=utils
 override TARGET_DIRS+=utils
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 override TARGET_DIRS+=utils
 override TARGET_DIRS+=utils
 endif
 endif
@@ -788,6 +793,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 override TARGET_DIRS+=utils
 override TARGET_DIRS+=utils
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 override TARGET_DIRS+=utils
 override TARGET_DIRS+=utils
 endif
 endif
@@ -953,6 +961,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 override TARGET_PROGRAMS+=pp
 override TARGET_PROGRAMS+=pp
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+override TARGET_PROGRAMS+=pp
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 override TARGET_PROGRAMS+=pp
 override TARGET_PROGRAMS+=pp
 endif
 endif
@@ -1025,6 +1036,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 override TARGET_PROGRAMS+=pp
 override TARGET_PROGRAMS+=pp
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override TARGET_PROGRAMS+=pp
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 override TARGET_PROGRAMS+=pp
 override TARGET_PROGRAMS+=pp
 endif
 endif
@@ -1191,6 +1205,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
 endif
@@ -1263,6 +1280,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
 endif
@@ -1428,6 +1448,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
 endif
@@ -1500,6 +1523,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
 endif
@@ -1665,6 +1691,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 override COMPILER_TARGETDIR+=.
 override COMPILER_TARGETDIR+=.
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 override COMPILER_TARGETDIR+=.
 override COMPILER_TARGETDIR+=.
 endif
 endif
@@ -1737,6 +1766,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_TARGETDIR+=.
 override COMPILER_TARGETDIR+=.
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 override COMPILER_TARGETDIR+=.
 override COMPILER_TARGETDIR+=.
 endif
 endif
@@ -1902,6 +1934,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
 endif
@@ -1974,6 +2009,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
 endif
@@ -2372,6 +2410,10 @@ STATICLIBPREFIX=
 STATICLIBEXT=.a
 STATICLIBEXT=.a
 SHORTSUFFIX=d16
 SHORTSUFFIX=d16
 endif
 endif
+ifeq ($(OS_TARGET),embedded)
+EXEEXT=.bin
+SHORTSUFFIX=emb
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -2789,6 +2831,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
@@ -2861,6 +2906,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
@@ -3658,6 +3706,9 @@ endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
 TARGET_DIRS_UTILS=1
 TARGET_DIRS_UTILS=1
 endif
 endif
+ifeq ($(FULL_TARGET),x86_64-aros)
+TARGET_DIRS_UTILS=1
+endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
 TARGET_DIRS_UTILS=1
 TARGET_DIRS_UTILS=1
 endif
 endif
@@ -3730,6 +3781,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 TARGET_DIRS_UTILS=1
 TARGET_DIRS_UTILS=1
 endif
 endif
+ifeq ($(FULL_TARGET),aarch64-linux)
+TARGET_DIRS_UTILS=1
+endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
 ifeq ($(FULL_TARGET),aarch64-darwin)
 TARGET_DIRS_UTILS=1
 TARGET_DIRS_UTILS=1
 endif
 endif
@@ -3861,7 +3915,7 @@ INSTALLEXEFILE=$(PPCROSSNAME)
 else
 else
 INSTALLEXEFILE=$(EXENAME)
 INSTALLEXEFILE=$(EXENAME)
 endif
 endif
-PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 alpha vis ia64 mips mipsel avr jvm i8086 aarch64
+PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 mips mipsel avr jvm i8086 aarch64
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS)
 .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS)
 $(PPC_TARGETS):
 $(PPC_TARGETS):
@@ -3936,9 +3990,6 @@ insdat: insdatx86 insdatarm insdataarch64
 regdatarm : arm/armreg.dat
 regdatarm : arm/armreg.dat
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkarmreg.pp
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkarmreg.pp
 	cd arm && ..$(PATHSEP)utils$(PATHSEP)mkarmreg$(SRCEXEEXT)
 	cd arm && ..$(PATHSEP)utils$(PATHSEP)mkarmreg$(SRCEXEEXT)
-regdatia64 : ia64/ia64reg.dat
-	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkia64reg.pp
-	cd ia64 && ..$(PATHSEP)utils$(PATHSEP)mkia64reg$(SRCEXEEXT)
 regdatsp : sparc/spreg.dat
 regdatsp : sparc/spreg.dat
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkspreg.pp
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkspreg.pp
 	cd sparc && ..$(PATHSEP)utils$(PATHSEP)mkspreg$(SRCEXEEXT)
 	cd sparc && ..$(PATHSEP)utils$(PATHSEP)mkspreg$(SRCEXEEXT)

+ 3 - 11
compiler/Makefile.fpc

@@ -38,9 +38,6 @@ CYCLETARGETS=i386 powerpc sparc arm x86_64 powerpc64 m68k armeb mipsel mips avr
 ALLTARGETS=$(CYCLETARGETS)
 ALLTARGETS=$(CYCLETARGETS)
 
 
 # Allow ALPHA, POWERPC, POWERPC64, M68K, I386, jvm defines for target cpu
 # Allow ALPHA, POWERPC, POWERPC64, M68K, I386, jvm defines for target cpu
-ifdef ALPHA
-PPC_TARGET=alpha
-endif
 ifdef POWERPC
 ifdef POWERPC
 PPC_TARGET=powerpc
 PPC_TARGET=powerpc
 endif
 endif
@@ -172,11 +169,9 @@ MSGFILES=$(wildcard msg/error*.msg)
 ifeq ($(CPC_TARGET),i386)
 ifeq ($(CPC_TARGET),i386)
 CPUSUF=386
 CPUSUF=386
 endif
 endif
-ifeq ($(CPC_TARGET),alpha)
-CPUSUF=axp
-endif
 ifeq ($(CPC_TARGET),m68k)
 ifeq ($(CPC_TARGET),m68k)
 CPUSUF=68k
 CPUSUF=68k
+ALLOW_WARNINGS=1
 endif
 endif
 ifeq ($(CPC_TARGET),powerpc)
 ifeq ($(CPC_TARGET),powerpc)
 CPUSUF=ppc
 CPUSUF=ppc
@@ -201,6 +196,7 @@ CPUSUF=mipsel
 endif
 endif
 ifeq ($(CPC_TARGET),avr)
 ifeq ($(CPC_TARGET),avr)
 CPUSUF=avr
 CPUSUF=avr
+ALLOW_WARNINGS=1
 endif
 endif
 ifeq ($(CPC_TARGET),jvm)
 ifeq ($(CPC_TARGET),jvm)
 CPUSUF=jvm
 CPUSUF=jvm
@@ -406,7 +402,7 @@ endif
 # CPU targets
 # CPU targets
 #####################################################################
 #####################################################################
 
 
-PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 alpha vis ia64 mips mipsel avr jvm i8086 aarch64
+PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 mips mipsel avr jvm i8086 aarch64
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 
 
 .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS)
 .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS)
@@ -521,10 +517,6 @@ regdatarm : arm/armreg.dat
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkarmreg.pp
 	    $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkarmreg.pp
         cd arm && ..$(PATHSEP)utils$(PATHSEP)mkarmreg$(SRCEXEEXT)
         cd arm && ..$(PATHSEP)utils$(PATHSEP)mkarmreg$(SRCEXEEXT)
 
 
-regdatia64 : ia64/ia64reg.dat
-            $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkia64reg.pp
-        cd ia64 && ..$(PATHSEP)utils$(PATHSEP)mkia64reg$(SRCEXEEXT)
-
 regdatsp : sparc/spreg.dat
 regdatsp : sparc/spreg.dat
             $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkspreg.pp
             $(COMPILER) -FE$(COMPILERUTILSDIR) $(COMPILERUTILSDIR)/mkspreg.pp
         cd sparc && ..$(PATHSEP)utils$(PATHSEP)mkspreg$(SRCEXEEXT)
         cd sparc && ..$(PATHSEP)utils$(PATHSEP)mkspreg$(SRCEXEEXT)

+ 1 - 1
compiler/aarch64/a64att.inc

@@ -1,4 +1,4 @@
-{ don't edit, this file is generated from armins.dat }
+{ don't edit, this file is generated from a64ins.dat }
 (
 (
 'none',
 'none',
 'b',
 'b',

+ 1 - 1
compiler/aarch64/a64atts.inc

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

+ 1 - 1
compiler/aarch64/a64op.inc

@@ -1,4 +1,4 @@
-{ don't edit, this file is generated from armins.dat }
+{ don't edit, this file is generated from a64ins.dat }
 (
 (
 A_NONE,
 A_NONE,
 A_B,
 A_B,

+ 1 - 1
compiler/aarch64/a64tab.inc

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

+ 32 - 4
compiler/aarch64/agcpugas.pas

@@ -39,6 +39,10 @@ unit agcpugas;
         procedure WriteInstruction(hp : tai);override;
         procedure WriteInstruction(hp : tai);override;
       end;
       end;
 
 
+      TAArch64Assembler=class(TGNUassembler)
+        constructor create(smart: boolean); override;
+      end;
+
       TAArch64AppleAssembler=class(TAppleGNUassembler)
       TAArch64AppleAssembler=class(TAppleGNUassembler)
         constructor create(smart: boolean); override;
         constructor create(smart: boolean); override;
         function MakeCmdLine: TCmdStr; override;
         function MakeCmdLine: TCmdStr; override;
@@ -68,6 +72,16 @@ unit agcpugas;
        cgbase,cgutils;
        cgbase,cgutils;
 
 
 
 
+{****************************************************************************}
+{                      AArch64 Assembler writer                              }
+{****************************************************************************}
+
+    constructor TAArch64Assembler.create(smart: boolean);
+      begin
+        inherited create(smart);
+        InstrWriter := TAArch64InstrWriter.create(self);
+      end;
+
 {****************************************************************************}
 {****************************************************************************}
 {                      Apple AArch64 Assembler writer                        }
 {                      Apple AArch64 Assembler writer                        }
 {****************************************************************************}
 {****************************************************************************}
@@ -99,6 +113,8 @@ unit agcpugas;
       const
       const
         darwin_addrpage2str: array[addr_page..addr_gotpageoffset] of string[11] =
         darwin_addrpage2str: array[addr_page..addr_gotpageoffset] of string[11] =
            ('@PAGE','@PAGEOFF','@GOTPAGE','@GOTPAGEOFF');
            ('@PAGE','@PAGEOFF','@GOTPAGE','@GOTPAGEOFF');
+        linux_addrpage2str: array[addr_page..addr_gotpageoffset] of string[10] =
+           ('',':lo12:',':got:',':got_lo12:');
       begin
       begin
         if ref.base=NR_NO then
         if ref.base=NR_NO then
           begin
           begin
@@ -117,8 +133,7 @@ unit agcpugas;
                   if target_asm.id=as_darwin then
                   if target_asm.id=as_darwin then
                     result:=ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                     result:=ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                   else
                   else
-                    { todo }
-                    internalerror(2014121502);
+                    result:=linux_addrpage2str[ref.refaddr]+ref.symbol.name
                 end
                 end
               else
               else
                 internalerror(2015022301);
                 internalerror(2015022301);
@@ -160,8 +175,7 @@ unit agcpugas;
                           if target_asm.id=as_darwin then
                           if target_asm.id=as_darwin then
                             result:=result+', '+ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                             result:=result+', '+ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                           else
                           else
-                            { todo }
-                            internalerror(2014122510);
+                            result:=result+', '+linux_addrpage2str[ref.refaddr]+ref.symbol.name
                         end
                         end
                       else
                       else
                         { todo: not yet generated/don't know syntax }
                         { todo: not yet generated/don't know syntax }
@@ -269,6 +283,19 @@ unit agcpugas;
 
 
 
 
     const
     const
+       as_aarch64_gas_info : tasminfo =
+          (
+            id     : as_gas;
+            idtxt  : 'AS';
+            asmbin : 'as';
+            asmcmd : '-o $OBJ $EXTRAOPT $ASM';
+            supported_targets : [system_aarch64_linux];
+            flags : [af_needar,af_smartlink_sections];
+            labelprefix : '.L';
+            comment : '// ';
+            dollarsign: '$';
+          );
+
        as_aarch64_gas_darwin_info : tasminfo =
        as_aarch64_gas_darwin_info : tasminfo =
           (
           (
             id     : as_darwin;
             id     : as_darwin;
@@ -284,5 +311,6 @@ unit agcpugas;
 
 
 
 
 begin
 begin
+  RegisterAssembler(as_aarch64_gas_info,TAArch64Assembler);
   RegisterAssembler(as_aarch64_gas_darwin_info,TAArch64AppleAssembler);
   RegisterAssembler(as_aarch64_gas_darwin_info,TAArch64AppleAssembler);
 end.
 end.

+ 52 - 61
compiler/aarch64/cgcpu.pas

@@ -165,66 +165,59 @@ implementation
             { no relative symbol support (needed) yet }
             { no relative symbol support (needed) yet }
             if assigned(ref.relsymbol) then
             if assigned(ref.relsymbol) then
               internalerror(2014111001);
               internalerror(2014111001);
-            { on Darwin: load the address from the GOT. There does not appear to
-              be a non-GOT variant. This consists of first loading the address
-              of the page containing the GOT entry for this variable, and then
-              the address of the entry itself from that page (can be relaxed by
-              the linker in case the variable itself can be stored directly in
-              the GOT) }
-            if target_info.system in systems_darwin then
+            { loading a symbol address (whether it's in the GOT or not) consists
+              of two parts: first load the page on which it is located, then
+              either the offset in the page or load the value at that offset in
+              the page. This final GOT-load can be relaxed by the linker in case
+              the variable itself can be stored directly in the GOT }
+            if (preferred_newbasereg=NR_NO) or
+               (ref.base=preferred_newbasereg) or
+               (ref.index=preferred_newbasereg) then
+              preferred_newbasereg:=getaddressregister(list);
+            { load the (GOT) page }
+            reference_reset_symbol(href,ref.symbol,0,8);
+            if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and
+                (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or
+               ((ref.symbol.typ=AT_DATA) and
+                (ref.symbol.bind=AB_LOCAL)) then
+              href.refaddr:=addr_page
+            else
+              href.refaddr:=addr_gotpage;
+            list.concat(taicpu.op_reg_ref(A_ADRP,preferred_newbasereg,href));
+            { load the GOT entry (= address of the variable) }
+            reference_reset_base(href,preferred_newbasereg,0,sizeof(pint));
+            href.symbol:=ref.symbol;
+            { code symbols defined in the current compilation unit do not
+              have to be accessed via the GOT }
+            if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and
+                (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or
+               ((ref.symbol.typ=AT_DATA) and
+                (ref.symbol.bind=AB_LOCAL)) then
               begin
               begin
-                if (preferred_newbasereg=NR_NO) or
-                   (ref.base=preferred_newbasereg) or
-                   (ref.index=preferred_newbasereg) then
-                  preferred_newbasereg:=getaddressregister(list);
-                { load the (GOT) page }
-                reference_reset_symbol(href,ref.symbol,0,8);
-                if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and
-                    (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or
-                   ((ref.symbol.typ=AT_DATA) and
-                    (ref.symbol.bind=AB_LOCAL)) then
-                  href.refaddr:=addr_page
-                else
-                  href.refaddr:=addr_gotpage;
-                list.concat(taicpu.op_reg_ref(A_ADRP,preferred_newbasereg,href));
-                { load the GOT entry (= address of the variable) }
-                reference_reset_base(href,preferred_newbasereg,0,sizeof(pint));
-                href.symbol:=ref.symbol;
-                { code symbols defined in the current compilation unit do not
-                  have to be accessed via the GOT }
-                if ((ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) and
-                    (ref.symbol.bind in [AB_LOCAL,AB_GLOBAL])) or
-                   ((ref.symbol.typ=AT_DATA) and
-                    (ref.symbol.bind=AB_LOCAL)) then
-                  begin
-                    href.base:=NR_NO;
-                    href.refaddr:=addr_pageoffset;
-                    list.concat(taicpu.op_reg_reg_ref(A_ADD,preferred_newbasereg,preferred_newbasereg,href));
-                  end
-                else
-                  begin
-                    href.refaddr:=addr_gotpageoffset;
-                    { use a_load_ref_reg() rather than directly encoding the LDR,
-                      so that we'll check the validity of the reference }
-                    a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,preferred_newbasereg);
-                  end;
-                { set as new base register }
-                if ref.base=NR_NO then
-                  ref.base:=preferred_newbasereg
-                else if ref.index=NR_NO then
-                  ref.index:=preferred_newbasereg
-                else
-                  begin
-                    { make sure it's valid in case ref.base is SP -> make it
-                      the second operand}
-                    a_op_reg_reg_reg(list,OP_ADD,OS_ADDR,preferred_newbasereg,ref.base,preferred_newbasereg);
-                    ref.base:=preferred_newbasereg
-                  end;
-                ref.symbol:=nil;
+                href.base:=NR_NO;
+                href.refaddr:=addr_pageoffset;
+                list.concat(taicpu.op_reg_reg_ref(A_ADD,preferred_newbasereg,preferred_newbasereg,href));
               end
               end
             else
             else
-              { todo }
-              internalerror(2014111003);
+              begin
+                href.refaddr:=addr_gotpageoffset;
+                { use a_load_ref_reg() rather than directly encoding the LDR,
+                  so that we'll check the validity of the reference }
+                a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,preferred_newbasereg);
+              end;
+            { set as new base register }
+            if ref.base=NR_NO then
+              ref.base:=preferred_newbasereg
+            else if ref.index=NR_NO then
+              ref.index:=preferred_newbasereg
+            else
+              begin
+                { make sure it's valid in case ref.base is SP -> make it
+                  the second operand}
+                a_op_reg_reg_reg(list,OP_ADD,OS_ADDR,preferred_newbasereg,ref.base,preferred_newbasereg);
+                ref.base:=preferred_newbasereg
+              end;
+            ref.symbol:=nil;
           end;
           end;
 
 
         { base & index }
         { base & index }
@@ -1110,7 +1103,7 @@ implementation
         list.Concat(taicpu.op_reg_reg_reg_cond(A_CSINV,dst,dst,makeregsize(NR_XZR,dstsize),C_NE));
         list.Concat(taicpu.op_reg_reg_reg_cond(A_CSINV,dst,dst,makeregsize(NR_XZR,dstsize),C_NE));
         { mask the -1 to 255 if src was 0 (anyone find a two-instruction
         { mask the -1 to 255 if src was 0 (anyone find a two-instruction
           branch-free version? All of mine are 3...) }
           branch-free version? All of mine are 3...) }
-        list.Concat(setoppostfix(taicpu.op_reg_reg(A_UXT,dst,dst),PF_B));
+        list.Concat(setoppostfix(taicpu.op_reg_reg(A_UXT,makeregsize(dst,OS_32),makeregsize(dst,OS_32)),PF_B));
       end;
       end;
 
 
 
 
@@ -1631,9 +1624,7 @@ implementation
 
 
     procedure tcgaarch64.g_maybe_got_init(list : TAsmList);
     procedure tcgaarch64.g_maybe_got_init(list : TAsmList);
       begin
       begin
-        { nothing to do on Darwin; check on ELF targets }
-        if not(target_info.system in systems_darwin) then
-          internalerror(2014112601);
+        { nothing to do on Darwin or Linux }
       end;
       end;
 
 
 
 

+ 1 - 1
compiler/aarch64/cpubase.pas

@@ -429,7 +429,7 @@ unit cpubase;
 
 
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
       begin
-        is_calljmp:=o in [A_B,A_BL,A_BLR,A_RET,A_CBNZ,A_CBZ];
+        is_calljmp:=o in [A_B,A_BL,A_BLR,A_RET,A_CBNZ,A_CBZ,A_TBNZ,A_TBZ];
       end;
       end;
 
 
 
 

+ 2 - 2
compiler/aarch64/cpupara.pas

@@ -318,7 +318,7 @@ unit cpupara;
                 hp.paraloc[side].size:=OS_ADDR;
                 hp.paraloc[side].size:=OS_ADDR;
                 hp.paraloc[side].alignment:=voidpointertype.alignment;
                 hp.paraloc[side].alignment:=voidpointertype.alignment;
                 hp.paraloc[side].intsize:=voidpointertype.size;
                 hp.paraloc[side].intsize:=voidpointertype.size;
-                hp.paraloc[side].def:=getpointerdef(hp.vardef);
+                hp.paraloc[side].def:=cpointerdef.getreusable(hp.vardef);
                 with hp.paraloc[side].add_location^ do
                 with hp.paraloc[side].add_location^ do
                   begin
                   begin
                     size:=OS_ADDR;
                     size:=OS_ADDR;
@@ -397,7 +397,7 @@ unit cpupara;
 
 
         if push_addr_param(varspez,paradef,p.proccalloption) then
         if push_addr_param(varspez,paradef,p.proccalloption) then
           begin
           begin
-            paradef:=getpointerdef(paradef);
+            paradef:=cpointerdef.getreusable(paradef);
             loc:=LOC_REGISTER;
             loc:=LOC_REGISTER;
             paracgsize:=OS_ADDR;
             paracgsize:=OS_ADDR;
             paralen:=tcgsize2size[OS_ADDR];
             paralen:=tcgsize2size[OS_ADDR];

+ 1 - 1
compiler/aarch64/cputarg.pas

@@ -36,7 +36,7 @@ implementation
 **************************************}
 **************************************}
 
 
     {$ifndef NOTARGETLINUX}
     {$ifndef NOTARGETLINUX}
-//      ,t_linux
+      ,t_linux
     {$endif}
     {$endif}
     {$ifndef NOTARGETBSD}
     {$ifndef NOTARGETBSD}
       ,t_bsd
       ,t_bsd

+ 4 - 0
compiler/aarch64/ncpucnv.pas

@@ -163,6 +163,10 @@ implementation
        exit;
        exit;
 
 
       case left.location.loc of
       case left.location.loc of
+        LOC_SUBSETREG,
+        LOC_CSUBSETREG,
+        LOC_SUBSETREF,
+        LOC_CSUBSETREF,
         LOC_CREFERENCE,
         LOC_CREFERENCE,
         LOC_REFERENCE,
         LOC_REFERENCE,
         LOC_REGISTER,
         LOC_REGISTER,

+ 4 - 0
compiler/aarch64/symcpu.pas

@@ -94,6 +94,9 @@ type
   tcpuunitsym = class(tunitsym)
   tcpuunitsym = class(tunitsym)
   end;
   end;
 
 
+  tcpuprogramparasym = class(tprogramparasym)
+  end;
+
   tcpunamespacesym = class(tnamespacesym)
   tcpunamespacesym = class(tnamespacesym)
   end;
   end;
 
 
@@ -162,6 +165,7 @@ begin
   { used tsym classes }
   { used tsym classes }
   clabelsym:=tcpulabelsym;
   clabelsym:=tcpulabelsym;
   cunitsym:=tcpuunitsym;
   cunitsym:=tcpuunitsym;
+  cprogramparasym:=tcpuprogramparasym;
   cnamespacesym:=tcpunamespacesym;
   cnamespacesym:=tcpunamespacesym;
   cprocsym:=tcpuprocsym;
   cprocsym:=tcpuprocsym;
   ctypesym:=tcputypesym;
   ctypesym:=tcputypesym;

+ 186 - 56
compiler/aasmcnst.pas

@@ -52,11 +52,13 @@ type
 
 
    { a simple data element; the value is stored as a tai }
    { a simple data element; the value is stored as a tai }
    tai_simpletypedconst = class(tai_abstracttypedconst)
    tai_simpletypedconst = class(tai_abstracttypedconst)
+   private
+     procedure setval(AValue: tai);
     protected
     protected
      fval: tai;
      fval: tai;
     public
     public
      constructor create(_adetyp: ttypedconstkind; _def: tdef; _val: tai);
      constructor create(_adetyp: ttypedconstkind; _def: tdef; _val: tai);
-     property val: tai read fval;
+     property val: tai read fval write setval;
    end;
    end;
 
 
 
 
@@ -118,8 +120,10 @@ type
    { information about aggregates we are parsing }
    { information about aggregates we are parsing }
    taggregateinformation = class
    taggregateinformation = class
     private
     private
+     fnextfieldname: TIDString;
      function getcuroffset: asizeint;
      function getcuroffset: asizeint;
      function getfieldoffset(l: longint): asizeint;
      function getfieldoffset(l: longint): asizeint;
+     procedure setnextfieldname(AValue: TIDString);
     protected
     protected
      { type of the aggregate }
      { type of the aggregate }
      fdef: tdef;
      fdef: tdef;
@@ -151,12 +155,13 @@ type
      constructor create(_def: tdef; _typ: ttypedconstkind); virtual;
      constructor create(_def: tdef; _typ: ttypedconstkind); virtual;
      { calculated padding bytes for alignment if needed, and add the def of the
      { calculated padding bytes for alignment if needed, and add the def of the
        next field in case we are constructing an anonymous record }
        next field in case we are constructing an anonymous record }
-     function prepare_next_field(nextfielddef: tdef): asizeint;
+     function prepare_next_field(nextfielddef: tdef): asizeint; virtual;
 
 
      property def: tdef read fdef;
      property def: tdef read fdef;
      property typ: ttypedconstkind read ftyp;
      property typ: ttypedconstkind read ftyp;
      property curfield: tfieldvarsym read fcurfield write fcurfield;
      property curfield: tfieldvarsym read fcurfield write fcurfield;
      property nextfield: tfieldvarsym read fnextfield write fnextfield;
      property nextfield: tfieldvarsym read fnextfield write fnextfield;
+     property nextfieldname: TIDString write setnextfieldname;
      property fieldoffset[l: longint]: asizeint read getfieldoffset;
      property fieldoffset[l: longint]: asizeint read getfieldoffset;
      property curoffset: asizeint read getcuroffset;
      property curoffset: asizeint read getcuroffset;
      property anonrecord: boolean read fanonrecord write fanonrecord;
      property anonrecord: boolean read fanonrecord write fanonrecord;
@@ -172,6 +177,7 @@ type
     private
     private
      function getcurragginfo: taggregateinformation;
      function getcurragginfo: taggregateinformation;
      procedure set_next_field(AValue: tfieldvarsym);
      procedure set_next_field(AValue: tfieldvarsym);
+     procedure set_next_field_name(AValue: TIDString);
     protected
     protected
      { temporary list in which all data is collected }
      { temporary list in which all data is collected }
      fasmlist: tasmlist;
      fasmlist: tasmlist;
@@ -181,6 +187,7 @@ type
      { while queueing elements of a compound expression, this is the current
      { while queueing elements of a compound expression, this is the current
        offset in the top-level array/record }
        offset in the top-level array/record }
      fqueue_offset: asizeint;
      fqueue_offset: asizeint;
+     fqueued_def: tdef;
 
 
      { array of caggregateinformation instances }
      { array of caggregateinformation instances }
      faggregateinformation: tfpobjectlist;
      faggregateinformation: tfpobjectlist;
@@ -267,6 +274,7 @@ type
      procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
      procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
 
 
     protected
     protected
+     procedure maybe_emit_tail_padding(def: tdef); virtual;
      function emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel):tasmlabofs;
      function emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel):tasmlabofs;
      procedure begin_aggregate_internal(def: tdef; anonymous: boolean); virtual;
      procedure begin_aggregate_internal(def: tdef; anonymous: boolean); virtual;
      procedure end_aggregate_internal(def: tdef; anonymous: boolean); virtual;
      procedure end_aggregate_internal(def: tdef; anonymous: boolean); virtual;
@@ -306,8 +314,17 @@ type
         a) it's definitely a record
         a) it's definitely a record
         b) the def of the record should be automatically constructed based on
         b) the def of the record should be automatically constructed based on
            the types of the emitted fields
            the types of the emitted fields
+
+        packrecords: same as "pacrecords x"
+        recordalign: specify the (minimum) alignment of the start of the record
+          (no equivalent in source code), used as an alternative for explicit
+          align statements. Use "1" if it should be calculated based on the
+          fields
+        recordalignmin: same as "codealign recordmin=x"
+        maxcrecordalign: specify maximum C record alignment (no equivalent in
+          source code)
      }
      }
-     function begin_anonymous_record(const optionalname: string; packrecords, recordalignmin, maxcrecordalign: shortint): trecorddef; virtual;
+     function begin_anonymous_record(const optionalname: string; packrecords, recordalign, recordalignmin, maxcrecordalign: shortint): trecorddef; virtual;
      function end_anonymous_record: trecorddef; virtual;
      function end_anonymous_record: trecorddef; virtual;
 
 
      { The next group of routines are for constructing complex expressions.
      { The next group of routines are for constructing complex expressions.
@@ -321,10 +338,11 @@ type
      procedure queue_vecn(def: tdef; const index: tconstexprint); virtual;
      procedure queue_vecn(def: tdef; const index: tconstexprint); virtual;
      { queue a subscripting operation }
      { queue a subscripting operation }
      procedure queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym); virtual;
      procedure queue_subscriptn(def: tabstractrecorddef; vs: tfieldvarsym); virtual;
+     { queue indexing a record recursively via several field names. The fields
+       are specified in the inner to outer order (i.e., def.field1.field2) }
+     function queue_subscriptn_multiple_by_name(def: tabstractrecorddef; const fields: array of TIDString): tdef;
      { queue a type conversion operation }
      { queue a type conversion operation }
      procedure queue_typeconvn(fromdef, todef: tdef); virtual;
      procedure queue_typeconvn(fromdef, todef: tdef); virtual;
-     { queue an address taking operation }
-     procedure queue_addrn(fromdef, todef: tdef); virtual;
      { finalise the queue (so a new one can be created) and flush the
      { finalise the queue (so a new one can be created) and flush the
         previously queued operations, applying them in reverse order on a...}
         previously queued operations, applying them in reverse order on a...}
      { ... procdef }
      { ... procdef }
@@ -339,6 +357,11 @@ type
      procedure queue_emit_asmsym(sym: tasmsymbol; def: tdef); virtual;
      procedure queue_emit_asmsym(sym: tasmsymbol; def: tdef); virtual;
      { ... an ordinal constant }
      { ... an ordinal constant }
      procedure queue_emit_ordconst(value: int64; def: tdef); virtual;
      procedure queue_emit_ordconst(value: int64; def: tdef); virtual;
+    protected
+     { returns whether queue_init has been called without a corresponding
+       queue_emit_* to finish it }
+     function queue_is_active: boolean;
+    public
 
 
      { finalize the internal asmlist (if necessary) and return it.
      { finalize the internal asmlist (if necessary) and return it.
        This asmlist will be freed when the builder is destroyed, so add its
        This asmlist will be freed when the builder is destroyed, so add its
@@ -357,6 +380,9 @@ type
        initialised. Also in case of objects, because the fieldvarsyms are spread
        initialised. Also in case of objects, because the fieldvarsyms are spread
        over the symtables of the entire inheritance tree }
        over the symtables of the entire inheritance tree }
      property next_field: tfieldvarsym write set_next_field;
      property next_field: tfieldvarsym write set_next_field;
+     { set the name of the next field that will be emitted for an anonymous
+       record (or the next of the next started anonymous record) }
+     property next_field_name: TIDString write set_next_field_name;
     protected
     protected
      { this one always return the actual offset, called by the above (and
      { this one always return the actual offset, called by the above (and
        overridden versions) }
        overridden versions) }
@@ -387,6 +413,7 @@ implementation
 
 
    uses
    uses
      verbose,globals,systems,widestr,
      verbose,globals,systems,widestr,
+     fmodule,
      symbase,symtable,defutil;
      symbase,symtable,defutil;
 
 
 {****************************************************************************
 {****************************************************************************
@@ -418,6 +445,15 @@ implementation
       end;
       end;
 
 
 
 
+    procedure taggregateinformation.setnextfieldname(AValue: TIDString);
+      begin
+        if (fnextfieldname<>'') or
+           not anonrecord then
+          internalerror(2015071503);
+        fnextfieldname:=AValue;
+      end;
+
+
     constructor taggregateinformation.create(_def: tdef; _typ: ttypedconstkind);
     constructor taggregateinformation.create(_def: tdef; _typ: ttypedconstkind);
       begin
       begin
         fdef:=_def;
         fdef:=_def;
@@ -451,12 +487,18 @@ implementation
             { if we are constructing this record as data gets emitted, add a field
             { if we are constructing this record as data gets emitted, add a field
               for this data }
               for this data }
             if anonrecord then
             if anonrecord then
-              trecorddef(def).add_field_by_def(nextfielddef);
+              begin
+                trecorddef(def).add_field_by_def(fnextfieldname,nextfielddef);
+                fnextfieldname:='';
+              end
+            else if fnextfieldname<>'' then
+              internalerror(2015071501);
             { find next field }
             { find next field }
             i:=curindex;
             i:=curindex;
             repeat
             repeat
               inc(i);
               inc(i);
-            until tsym(tabstractrecorddef(def).symtable.symlist[i]).typ=fieldvarsym;
+            until (tsym(tabstractrecorddef(def).symtable.symlist[i]).typ=fieldvarsym) and
+              not(sp_static in tsym(tabstractrecorddef(def).symtable.symlist[i]).symoptions);
             nextoffset:=fieldoffset[i];
             nextoffset:=fieldoffset[i];
             currentoffset:=curoffset;
             currentoffset:=curoffset;
             curindex:=i;
             curindex:=i;
@@ -491,6 +533,12 @@ implementation
                                 tai_simpletypedconst
                                 tai_simpletypedconst
  ****************************************************************************}
  ****************************************************************************}
 
 
+    procedure tai_simpletypedconst.setval(AValue: tai);
+      begin
+        fval:=AValue;
+      end;
+
+
    constructor tai_simpletypedconst.create(_adetyp: ttypedconstkind; _def: tdef; _val: tai);
    constructor tai_simpletypedconst.create(_adetyp: ttypedconstkind; _def: tdef; _val: tai);
      begin
      begin
        inherited create(_adetyp,_def);
        inherited create(_adetyp,_def);
@@ -646,7 +694,7 @@ implementation
            if fvalues.count<>1 then
            if fvalues.count<>1 then
              internalerror(2014070105);
              internalerror(2014070105);
            tai_simpletypedconst(fvalues[0]).fdef:=
            tai_simpletypedconst(fvalues[0]).fdef:=
-             getarraydef(cansichartype,
+             carraydef.getreusable(cansichartype,
                tai_string(tai_simpletypedconst(fvalues[0]).val).len);
                tai_string(tai_simpletypedconst(fvalues[0]).val).len);
          end;
          end;
      end;
      end;
@@ -684,6 +732,17 @@ implementation
      end;
      end;
 
 
 
 
+    procedure ttai_typedconstbuilder.set_next_field_name(AValue: TIDString);
+      var
+        info: taggregateinformation;
+      begin
+        info:=curagginfo;
+        if not assigned(info) then
+          internalerror(2015071502);
+        info.nextfieldname:='$'+AValue;
+      end;
+
+
    procedure ttai_typedconstbuilder.pad_next_field(nextfielddef: tdef);
    procedure ttai_typedconstbuilder.pad_next_field(nextfielddef: tdef);
      var
      var
        fillbytes: asizeint;
        fillbytes: asizeint;
@@ -755,6 +814,11 @@ implementation
      var
      var
        prelist: tasmlist;
        prelist: tasmlist;
      begin
      begin
+       { have we finished all aggregates? }
+       if (getcurragginfo<>nil) and
+          { in case of syntax errors, the aggregate may not have been finished }
+          (ErrorCount=0) then
+         internalerror(2015072301);
        prelist:=tasmlist.create;
        prelist:=tasmlist.create;
        { only now add items based on the symbolname, because it may be
        { only now add items based on the symbolname, because it may be
          modified by the "section" specifier in case of a typed constant }
          modified by the "section" specifier in case of a typed constant }
@@ -976,8 +1040,10 @@ implementation
          an anonymous record also add the next field }
          an anonymous record also add the next field }
        if assigned(info) then
        if assigned(info) then
          begin
          begin
-           if ((info.def.typ=recorddef) or
-               is_object(info.def)) and
+           { queue_init already adds padding }
+           if not queue_is_active and
+               (is_record(info.def) or
+                is_object(info.def)) and
               { may add support for these later }
               { may add support for these later }
               not is_packed_record_or_object(info.def) then
               not is_packed_record_or_object(info.def) then
              pad_next_field(def);
              pad_next_field(def);
@@ -994,6 +1060,30 @@ implementation
      end;
      end;
 
 
 
 
+   procedure ttai_typedconstbuilder.maybe_emit_tail_padding(def: tdef);
+     var
+       info: taggregateinformation;
+       fillbytes: asizeint;
+     begin
+       info:=curagginfo;
+       if not assigned(info) then
+         internalerror(2014091002);
+       if def<>info.def then
+         internalerror(2014091205);
+       if (is_record(def) or
+           is_object(def)) and
+          not is_packed_record_or_object(def) then
+         begin
+           fillbytes:=def.size-info.curoffset;
+           while fillbytes>0 do
+             begin
+               do_emit_tai(Tai_const.Create_8bit(0),u8inttype);
+               dec(fillbytes)
+             end;
+         end;
+     end;
+
+
    function ttai_typedconstbuilder.emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel): tasmlabofs;
    function ttai_typedconstbuilder.emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel): tasmlabofs;
      var
      var
        string_symofs: asizeint;
        string_symofs: asizeint;
@@ -1004,7 +1094,7 @@ implementation
        result.ofs:=0;
        result.ofs:=0;
        { pack the data, so that we don't add unnecessary null bytes after the
        { pack the data, so that we don't add unnecessary null bytes after the
          constant string }
          constant string }
-       begin_anonymous_record('$'+get_dynstring_rec_name(stringtype,false,len),1,1,1);
+       begin_anonymous_record('$'+get_dynstring_rec_name(stringtype,false,len),1,sizeof(TConstPtrUInt),1,1);
        string_symofs:=get_string_symofs(stringtype,false);
        string_symofs:=get_string_symofs(stringtype,false);
        { encoding }
        { encoding }
        emit_tai(tai_const.create_16bit(encoding),u16inttype);
        emit_tai(tai_const.create_16bit(encoding),u16inttype);
@@ -1069,9 +1159,14 @@ implementation
          begin
          begin
            { add padding if necessary, and update the current field/offset }
            { add padding if necessary, and update the current field/offset }
            info:=curagginfo;
            info:=curagginfo;
-           if is_record(curagginfo.def) or
-              is_object(curagginfo.def) then
-             pad_next_field(def);
+           if (is_record(curagginfo.def) or
+               is_object(curagginfo.def)) and
+              not is_packed_record_or_object(curagginfo.def) then
+             begin
+               if queue_is_active then
+                 internalerror(2015073001);
+               pad_next_field(def);
+             end;
          end
          end
        { if this is the outer record, no padding is required; the alignment
        { if this is the outer record, no padding is required; the alignment
          has to be specified explicitly in that case via get_final_asmlist() }
          has to be specified explicitly in that case via get_final_asmlist() }
@@ -1087,30 +1182,15 @@ implementation
    procedure ttai_typedconstbuilder.end_aggregate_internal(def: tdef; anonymous: boolean);
    procedure ttai_typedconstbuilder.end_aggregate_internal(def: tdef; anonymous: boolean);
      var
      var
        info: taggregateinformation;
        info: taggregateinformation;
-       fillbytes: asizeint;
        tck: ttypedconstkind;
        tck: ttypedconstkind;
      begin
      begin
        tck:=aggregate_kind(def);
        tck:=aggregate_kind(def);
        if tck=tck_simple then
        if tck=tck_simple then
          exit;
          exit;
-       info:=curagginfo;
-       if not assigned(info) then
-         internalerror(2014091002);
-       if def<>info.def then
-         internalerror(2014091205);
        { add tail padding if necessary }
        { add tail padding if necessary }
-       if (is_record(def) or
-           is_object(def)) and
-          not is_packed_record_or_object(def) then
-         begin
-           fillbytes:=def.size-info.curoffset;
-           while fillbytes>0 do
-             begin
-               do_emit_tai(Tai_const.Create_8bit(0),u8inttype);
-               dec(fillbytes)
-             end;
-         end;
+       maybe_emit_tail_padding(def);
        { pop and free the information }
        { pop and free the information }
+       info:=curagginfo;
        faggregateinformation.count:=faggregateinformation.count-1;
        faggregateinformation.count:=faggregateinformation.count-1;
        info.free;
        info.free;
      end;
      end;
@@ -1150,7 +1230,7 @@ implementation
        move(data^,s^,len);
        move(data^,s^,len);
        s[len]:=#0;
        s[len]:=#0;
        { terminating zero included }
        { terminating zero included }
-       datadef:=getarraydef(cansichartype,len+1);
+       datadef:=carraydef.getreusable(cansichartype,len+1);
        datatcb.maybe_begin_aggregate(datadef);
        datatcb.maybe_begin_aggregate(datadef);
        datatcb.emit_tai(tai_string.create_pchar(s,len+1),datadef);
        datatcb.emit_tai(tai_string.create_pchar(s,len+1),datadef);
        datatcb.maybe_end_aggregate(datadef);
        datatcb.maybe_end_aggregate(datadef);
@@ -1174,7 +1254,7 @@ implementation
          begin
          begin
            result.lab:=startlab;
            result.lab:=startlab;
            datatcb.begin_anonymous_record('$'+get_dynstring_rec_name(st_widestring,true,strlength),
            datatcb.begin_anonymous_record('$'+get_dynstring_rec_name(st_widestring,true,strlength),
-             4,
+             4,4,
              targetinfos[target_info.system]^.alignment.recordalignmin,
              targetinfos[target_info.system]^.alignment.recordalignmin,
              targetinfos[target_info.system]^.alignment.maxCrecordalign);
              targetinfos[target_info.system]^.alignment.maxCrecordalign);
            datatcb.emit_tai(Tai_const.Create_32bit(strlength*cwidechartype.size),s32inttype);
            datatcb.emit_tai(Tai_const.Create_32bit(strlength*cwidechartype.size),s32inttype);
@@ -1199,7 +1279,7 @@ implementation
          end;
          end;
        if cwidechartype.size = 2 then
        if cwidechartype.size = 2 then
          begin
          begin
-           datadef:=getarraydef(cwidechartype,strlength+1);
+           datadef:=carraydef.getreusable(cwidechartype,strlength+1);
            datatcb.maybe_begin_aggregate(datadef);
            datatcb.maybe_begin_aggregate(datadef);
            for i:=0 to strlength-1 do
            for i:=0 to strlength-1 do
              datatcb.emit_tai(Tai_const.Create_16bit(pcompilerwidestring(data)^.data[i]),cwidechartype);
              datatcb.emit_tai(Tai_const.Create_16bit(pcompilerwidestring(data)^.data[i]),cwidechartype);
@@ -1227,11 +1307,11 @@ implementation
          functionality in place yet to reuse shortstringdefs of the same length
          functionality in place yet to reuse shortstringdefs of the same length
          and neither the lowlevel nor the llvm typedconst builder cares about
          and neither the lowlevel nor the llvm typedconst builder cares about
          this difference }
          this difference }
-       result:=getarraydef(cansichartype,length(str)+1);
+       result:=carraydef.getreusable(cansichartype,length(str)+1);
        maybe_begin_aggregate(result);
        maybe_begin_aggregate(result);
        emit_tai(Tai_const.Create_8bit(length(str)),u8inttype);
        emit_tai(Tai_const.Create_8bit(length(str)),u8inttype);
        if str<>'' then
        if str<>'' then
-         emit_tai(Tai_string.Create(str),getarraydef(cansichartype,length(str)));
+         emit_tai(Tai_string.Create(str),carraydef.getreusable(cansichartype,length(str)));
        maybe_end_aggregate(result);
        maybe_end_aggregate(result);
      end;
      end;
 
 
@@ -1259,7 +1339,7 @@ implementation
 
 
    procedure ttai_typedconstbuilder.emit_procdef_const(pd: tprocdef);
    procedure ttai_typedconstbuilder.emit_procdef_const(pd: tprocdef);
      begin
      begin
-       emit_tai(Tai_const.Createname(pd.mangledname,AT_FUNCTION,0),pd.getcopyas(procvardef,pc_address_only));
+       emit_tai(Tai_const.Createname(pd.mangledname,AT_FUNCTION,0),cprocvardef.getreusableprocaddr(pd));
      end;
      end;
 
 
 
 
@@ -1292,33 +1372,29 @@ implementation
      end;
      end;
 
 
 
 
-   function ttai_typedconstbuilder.begin_anonymous_record(const optionalname: string; packrecords, recordalignmin, maxcrecordalign: shortint): trecorddef;
+   function ttai_typedconstbuilder.begin_anonymous_record(const optionalname: string; packrecords, recordalign, recordalignmin, maxcrecordalign: shortint): trecorddef;
      var
      var
        anonrecorddef: trecorddef;
        anonrecorddef: trecorddef;
-       srsym: tsym;
-       srsymtable: tsymtable;
-       found: boolean;
+       typesym: ttypesym;
      begin
      begin
        { if the name is specified, we create a typesym with that name in order
        { if the name is specified, we create a typesym with that name in order
          to ensure we can find it again later with that name -> reuse here as
          to ensure we can find it again later with that name -> reuse here as
          well if possible (and that also avoids duplicate type name issues) }
          well if possible (and that also avoids duplicate type name issues) }
        if optionalname<>'' then
        if optionalname<>'' then
          begin
          begin
-           if optionalname[1]='$' then
-             found:=searchsym_type(copy(optionalname,2,length(optionalname)),srsym,srsymtable)
-           else
-             found:=searchsym_type(optionalname,srsym,srsymtable);
-           if found then
+           typesym:=try_search_current_module_type(optionalname);
+           if assigned(typesym) then
              begin
              begin
-               if ttypesym(srsym).typedef.typ<>recorddef then
-                 internalerror(2014091207);
-               result:=trecorddef(ttypesym(srsym).typedef);
+               if typesym.typedef.typ<>recorddef then
+                 internalerror(2015071401);
+               result:=trecorddef(typesym.typedef);
                maybe_begin_aggregate(result);
                maybe_begin_aggregate(result);
                exit;
                exit;
              end;
              end;
          end;
          end;
        { create skeleton def }
        { create skeleton def }
        anonrecorddef:=crecorddef.create_global_internal(optionalname,packrecords,recordalignmin,maxcrecordalign);
        anonrecorddef:=crecorddef.create_global_internal(optionalname,packrecords,recordalignmin,maxcrecordalign);
+       trecordsymtable(anonrecorddef.symtable).recordalignment:=recordalign;
        { generic aggregate housekeeping }
        { generic aggregate housekeeping }
        begin_aggregate_internal(anonrecorddef,true);
        begin_aggregate_internal(anonrecorddef,true);
        { mark as anonymous record }
        { mark as anonymous record }
@@ -1355,11 +1431,27 @@ implementation
 
 
 
 
    procedure ttai_typedconstbuilder.queue_init(todef: tdef);
    procedure ttai_typedconstbuilder.queue_init(todef: tdef);
+     var
+       info: taggregateinformation;
      begin
      begin
        { nested call to init? }
        { nested call to init? }
        if fqueue_offset<>low(fqueue_offset) then
        if fqueue_offset<>low(fqueue_offset) then
          internalerror(2014062101);
          internalerror(2014062101);
+
+       { insert padding bytes before starting the queue, so that the first
+         padding byte won't be interpreted as the emitted value for this queue }
+       info:=curagginfo;
+       if assigned(info) then
+         begin
+           if ((info.def.typ=recorddef) or
+               is_object(info.def)) and
+              { may add support for these later }
+              not is_packed_record_or_object(info.def) then
+             pad_next_field(todef);
+         end;
+
        fqueue_offset:=0;
        fqueue_offset:=0;
+       fqueued_def:=todef;
      end;
      end;
 
 
 
 
@@ -1404,12 +1496,43 @@ implementation
      end;
      end;
 
 
 
 
-   procedure ttai_typedconstbuilder.queue_typeconvn(fromdef, todef: tdef);
+   function ttai_typedconstbuilder.queue_subscriptn_multiple_by_name(def: tabstractrecorddef; const fields: array of TIDString): tdef;
+     var
+       syms,
+       parentdefs: tfplist;
+       sym: tsym;
+       curdef: tdef;
+       i: longint;
      begin
      begin
-       { do nothing }
+       result:=nil;
+       if length(fields)=0 then
+         internalerror(2015071601);
+       syms:=tfplist.Create;
+       syms.count:=length(fields);
+       parentdefs:=tfplist.create;
+       parentdefs.Count:=length(fields);
+       curdef:=def;
+       for i:=low(fields) to high(fields) do
+         begin
+           sym:=search_struct_member_no_helper(tabstractrecorddef(curdef),fields[i]);
+           if not assigned(sym) or
+              (sym.typ<>fieldvarsym) or
+              ((i<>high(fields)) and
+               not(tfieldvarsym(sym).vardef.typ in [objectdef,recorddef])) then
+             internalerror(2015071505);
+           syms[i]:=sym;
+           parentdefs[i]:=curdef;
+           curdef:=tfieldvarsym(sym).vardef;
+           result:=curdef;
+         end;
+       for i:=high(fields) downto low(fields) do
+         queue_subscriptn(tabstractrecorddef(parentdefs[i]),tfieldvarsym(syms[i]));
+       syms.free;
+       parentdefs.free;
      end;
      end;
 
 
-   procedure ttai_typedconstbuilder.queue_addrn(fromdef, todef: tdef);
+
+   procedure ttai_typedconstbuilder.queue_typeconvn(fromdef, todef: tdef);
      begin
      begin
        { do nothing }
        { do nothing }
      end;
      end;
@@ -1426,9 +1549,9 @@ implementation
 
 
    procedure ttai_typedconstbuilder.queue_emit_staticvar(vs: tstaticvarsym);
    procedure ttai_typedconstbuilder.queue_emit_staticvar(vs: tstaticvarsym);
      begin
      begin
-       { getpointerdef because we are emitting a pointer to the staticvarsym
+       { pointerdef because we are emitting a pointer to the staticvarsym
          data, not the data itself }
          data, not the data itself }
-       emit_tai(Tai_const.Createname(vs.mangledname,fqueue_offset),getpointerdef(vs.vardef));
+       emit_tai(Tai_const.Createname(vs.mangledname,fqueue_offset),cpointerdef.getreusable(vs.vardef));
        fqueue_offset:=low(fqueue_offset);
        fqueue_offset:=low(fqueue_offset);
      end;
      end;
 
 
@@ -1454,13 +1577,14 @@ implementation
 
 
    procedure ttai_typedconstbuilder.queue_emit_asmsym(sym: tasmsymbol; def: tdef);
    procedure ttai_typedconstbuilder.queue_emit_asmsym(sym: tasmsymbol; def: tdef);
      begin
      begin
-       { getpointerdef, because "sym" represents the address of whatever the
+       { pointerdef, because "sym" represents the address of whatever the
          data is }
          data is }
-       def:=getpointerdef(def);
+       def:=cpointerdef.getreusable(def);
        emit_tai(Tai_const.Create_sym_offset(sym,fqueue_offset),def);
        emit_tai(Tai_const.Create_sym_offset(sym,fqueue_offset),def);
        fqueue_offset:=low(fqueue_offset);
        fqueue_offset:=low(fqueue_offset);
      end;
      end;
 
 
+
    procedure ttai_typedconstbuilder.queue_emit_ordconst(value: int64; def: tdef);
    procedure ttai_typedconstbuilder.queue_emit_ordconst(value: int64; def: tdef);
      begin
      begin
        emit_ord_const(value,def);
        emit_ord_const(value,def);
@@ -1468,6 +1592,12 @@ implementation
      end;
      end;
 
 
 
 
+   function ttai_typedconstbuilder.queue_is_active: boolean;
+     begin
+       result:=fqueue_offset<>low(fqueue_offset)
+     end;
+
+
 {****************************************************************************
 {****************************************************************************
                            tai_abstracttypedconst
                            tai_abstracttypedconst
  ****************************************************************************}
  ****************************************************************************}

+ 4 - 2
compiler/aasmtai.pas

@@ -253,6 +253,7 @@ interface
        { llvm only }
        { llvm only }
        ,top_single
        ,top_single
        ,top_double
        ,top_double
+       ,top_undef
 {$ifdef cpuextended}
 {$ifdef cpuextended}
        ,top_extended80
        ,top_extended80
 {$endif cpuextended}
 {$endif cpuextended}
@@ -433,6 +434,7 @@ interface
         {$ifdef llvm}
         {$ifdef llvm}
             top_single : (sval:single);
             top_single : (sval:single);
             top_double : (dval:double);
             top_double : (dval:double);
+            top_undef :  ();
           {$ifdef cpuextended}
           {$ifdef cpuextended}
             top_extended80 : (eval:extended);
             top_extended80 : (eval:extended);
           {$endif cpuextended}
           {$endif cpuextended}
@@ -574,7 +576,7 @@ interface
           is_global : boolean;
           is_global : boolean;
           sym       : tasmsymbol;
           sym       : tasmsymbol;
           size      : asizeint;
           size      : asizeint;
-          constructor Create(const _name : string;_size : aint);
+          constructor Create(const _name : string;_size : asizeint);
           constructor Create_global(const _name : string;_size : asizeint);
           constructor Create_global(const _name : string;_size : asizeint);
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -1246,7 +1248,7 @@ implementation
                              TAI_DATABLOCK
                              TAI_DATABLOCK
  ****************************************************************************}
  ****************************************************************************}
 
 
-    constructor tai_datablock.Create(const _name : string;_size : aint);
+    constructor tai_datablock.Create(const _name : string;_size : asizeint);
 
 
       begin
       begin
          inherited Create;
          inherited Create;

+ 22 - 5
compiler/aggas.pas

@@ -26,6 +26,8 @@ unit aggas;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
+{ $define DEBUG_AGGAS}
+
 interface
 interface
 
 
     uses
     uses
@@ -1261,10 +1263,18 @@ implementation
 
 
            ait_force_line,
            ait_force_line,
            ait_function_name :
            ait_function_name :
-             ;
+             begin
+{$ifdef DEBUG_AGGAS}
+               WriteStr(s,hp.typ);
+               AsmWriteLn('# '+s);
+{$endif DEBUG_AGGAS}
+             end;
 
 
            ait_cutobject :
            ait_cutobject :
              begin
              begin
+{$ifdef DEBUG_AGGAS}
+               AsmWriteLn('# ait_cutobject');
+{$endif DEBUG_AGGAS}
                if SmartAsm then
                if SmartAsm then
                 begin
                 begin
                 { only reset buffer if nothing has changed }
                 { only reset buffer if nothing has changed }
@@ -1290,10 +1300,16 @@ implementation
              end;
              end;
 
 
            ait_marker :
            ait_marker :
-             if tai_marker(hp).kind=mark_NoLineInfoStart then
-               inc(InlineLevel)
-             else if tai_marker(hp).kind=mark_NoLineInfoEnd then
-               dec(InlineLevel);
+             begin
+{$ifdef DEBUG_AGGAS}
+               WriteStr(s,tai_marker(hp).Kind);
+               AsmWriteLn('# ait_marker, kind: '+s);
+{$endif DEBUG_AGGAS}
+               if tai_marker(hp).kind=mark_NoLineInfoStart then
+                 inc(InlineLevel)
+               else if tai_marker(hp).kind=mark_NoLineInfoEnd then
+                 dec(InlineLevel);
+             end;
 
 
            ait_directive :
            ait_directive :
              begin
              begin
@@ -1333,6 +1349,7 @@ implementation
                AsmLn;
                AsmLn;
 {$endif DISABLE_WIN64_SEH}
 {$endif DISABLE_WIN64_SEH}
              end;
              end;
+
            ait_varloc:
            ait_varloc:
              begin
              begin
                if tai_varloc(hp).newlocationhi<>NR_NO then
                if tai_varloc(hp).newlocationhi<>NR_NO then

+ 0 - 1232
compiler/agjasmin.pas

@@ -1,1232 +0,0 @@
-{
-    Copyright (c) 1998-2010 by the Free Pascal team
-
-    This unit implements the Jasmin assembler writer
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-{ Unit for writing Jasmin assembler (JVM bytecode) output.
-}
-unit agjasmin;
-
-{$i fpcdefs.inc}
-
-interface
-
-    uses
-      cclasses,
-      globtype,globals,
-      symconst,symbase,symdef,symsym,
-      aasmbase,aasmtai,aasmdata,aasmcpu,
-      assemble;
-
-    type
-      TJasminInstrWriter = class;
-      {# This is a derived class which is used to write
-         Jasmin-styled assembler.
-      }
-
-      { TJasminAssembler }
-
-      TJasminAssembler=class(texternalassembler)
-       protected
-        jasminjar: tcmdstr;
-        asmfiles: TCmdStrList;
-
-        procedure WriteExtraHeader(obj: tabstractrecorddef);
-        procedure WriteInstruction(hp: tai);
-        procedure NewAsmFileForStructDef(obj: tabstractrecorddef);
-
-        function VisibilityToStr(vis: tvisibility): ansistring;
-        function MethodDefinition(pd: tprocdef): ansistring;
-        function ConstValue(csym: tconstsym): ansistring;
-        function ConstAssignmentValue(csym: tconstsym): ansistring;
-        function ConstDefinition(sym: tconstsym): ansistring;
-        function FieldDefinition(sym: tabstractvarsym): ansistring;
-        function InnerStructDef(obj: tabstractrecorddef): ansistring;
-
-        procedure WriteProcDef(pd: tprocdef);
-        procedure WriteFieldSym(sym: tabstractvarsym);
-        procedure WriteConstSym(sym: tconstsym);
-        procedure WriteSymtableVarSyms(st: TSymtable);
-        procedure WriteSymtableProcdefs(st: TSymtable);
-        procedure WriteSymtableStructDefs(st: TSymtable);
-       public
-        constructor Create(smart: boolean); override;
-        function MakeCmdLine: TCmdStr;override;
-        procedure WriteTree(p:TAsmList);override;
-        procedure WriteAsmList;override;
-        procedure RemoveAsm; override;
-        destructor destroy; override;
-       protected
-        InstrWriter: TJasminInstrWriter;
-      end;
-
-
-      {# This is the base class for writing instructions.
-
-         The WriteInstruction() method must be overridden
-         to write a single instruction to the assembler
-         file.
-      }
-
-      { TJasminInstrWriter }
-
-      TJasminInstrWriter = class
-        constructor create(_owner: TJasminAssembler);
-        procedure WriteInstruction(hp : tai); virtual;
-       protected
-        owner: TJasminAssembler;
-      end;
-
-
-implementation
-
-    uses
-      SysUtils,
-      cutils,cfileutl,systems,script,
-      fmodule,finput,verbose,
-      symtype,symcpu,symtable,jvmdef,
-      itcpujas,cpubase,cpuinfo,cgutils,
-      widestr
-      ;
-
-    const
-      line_length = 70;
-
-    type
-      t64bitarray = array[0..7] of byte;
-      t32bitarray = array[0..3] of byte;
-
-{****************************************************************************}
-{                          Support routines                                  }
-{****************************************************************************}
-
-   function fixline(s:string):string;
-   {
-     return s with all leading and ending spaces and tabs removed
-   }
-     var
-       i,j,k : integer;
-     begin
-       i:=length(s);
-       while (i>0) and (s[i] in [#9,' ']) do
-        dec(i);
-       j:=1;
-       while (j<i) and (s[j] in [#9,' ']) do
-        inc(j);
-       for k:=j to i do
-        if s[k] in [#0..#31,#127..#255] then
-         s[k]:='.';
-       fixline:=Copy(s,j,i-j+1);
-     end;
-
-
-   function constastr(p: pchar; len: longint): ansistring;
-     var
-       i,runstart,runlen: longint;
-
-       procedure flush;
-         begin
-           if runlen>0 then
-             begin
-               setlength(result,length(result)+runlen);
-               move(p[runstart],result[length(result)-runlen+1],runlen);
-               runlen:=0;
-             end;
-         end;
-
-     begin
-       result:='"';
-       runlen:=0;
-       runstart:=0;
-       for i:=0 to len-1 do
-         begin
-           { escape control codes }
-           case p[i] of
-             { LF and CR must be escaped specially, because \uXXXX parsing
-               happens in the pre-processor, so it's the same as actually
-               inserting a newline in the middle of a string constant }
-             #10:
-               begin
-                 flush;
-                 result:=result+'\n';
-               end;
-             #13:
-               begin
-                 flush;
-                 result:=result+'\r';
-               end;
-             '"','\':
-               begin
-                 flush;
-                 result:=result+'\'+p[i];
-               end
-             else if p[i]<#32 then
-               begin
-                 flush;
-                 result:=result+'\u'+hexstr(ord(p[i]),4);
-               end
-             else if p[i]<#127 then
-               begin
-                 if runlen=0 then
-                   runstart:=i;
-                 inc(runlen);
-               end
-             else
-               begin
-                 { see comments in njvmcon }
-                 flush;
-                 result:=result+'\u'+hexstr(ord(p[i]),4)
-               end;
-           end;
-         end;
-       flush;
-       result:=result+'"';
-     end;
-
-
-   function constwstr(w: pcompilerwidechar; len: longint): ansistring;
-     var
-       i: longint;
-     begin
-       result:='"';
-       for i:=0 to len-1 do
-         begin
-           { escape control codes }
-           case w[i] of
-             10:
-               result:=result+'\n';
-             13:
-               result:=result+'\r';
-             ord('"'),ord('\'):
-               result:=result+'\'+chr(w[i]);
-             else if (w[i]<32) or
-                (w[i]>=127) then
-               result:=result+'\u'+hexstr(w[i],4)
-             else
-               result:=result+char(w[i]);
-           end;
-         end;
-       result:=result+'"';
-     end;
-
-
-   function constsingle(s: single): ansistring;
-     begin
-       result:='0fx'+hexstr(longint(t32bitarray(s)),8);
-     end;
-
-
-   function constdouble(d: double): ansistring;
-      begin
-        // force interpretation as double (since we write it out as an
-        // integer, we never have to swap the endianess). We have to
-        // include the sign separately because of the way Java parses
-        // hex numbers (0x8000000000000000 is not a valid long)
-       result:=hexstr(abs(int64(t64bitarray(d))),16);
-       if int64(t64bitarray(d))<0 then
-         result:='-'+result;
-       result:='0dx'+result;
-      end;
-
-{****************************************************************************}
-{                       Jasmin Assembler writer                              }
-{****************************************************************************}
-
-    destructor TJasminAssembler.Destroy;
-      begin
-        InstrWriter.free;
-        asmfiles.free;
-        inherited destroy;
-      end;
-
-
-    procedure TJasminAssembler.WriteTree(p:TAsmList);
-      var
-        ch       : char;
-        hp       : tai;
-        hp1      : tailineinfo;
-        s        : ansistring;
-        i,pos    : longint;
-        InlineLevel : longint;
-        do_line  : boolean;
-      begin
-        if not assigned(p) then
-         exit;
-
-        InlineLevel:=0;
-        { lineinfo is only needed for al_procedures (PFV) }
-        do_line:=(cs_asm_source in current_settings.globalswitches);
-        hp:=tai(p.first);
-        while assigned(hp) do
-         begin
-           prefetch(pointer(hp.next)^);
-           if not(hp.typ in SkipLineInfo) then
-            begin
-              hp1 := hp as tailineinfo;
-              current_filepos:=hp1.fileinfo;
-               { no line info for inlined code }
-               if do_line and (inlinelevel=0) then
-                begin
-                  { load infile }
-                  if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
-                   begin
-                     infile:=current_module.sourcefiles.get_file(hp1.fileinfo.fileindex);
-                     if assigned(infile) then
-                      begin
-                        { open only if needed !! }
-                        if (cs_asm_source in current_settings.globalswitches) then
-                         infile.open;
-                      end;
-                     { avoid unnecessary reopens of the same file !! }
-                     lastfileinfo.fileindex:=hp1.fileinfo.fileindex;
-                     { be sure to change line !! }
-                     lastfileinfo.line:=-1;
-                   end;
-
-                { write source }
-                  if (cs_asm_source in current_settings.globalswitches) and
-                     assigned(infile) then
-                   begin
-                     if (infile<>lastinfile) then
-                       begin
-                         AsmWriteLn(target_asm.comment+'['+infile.name+']');
-                         if assigned(lastinfile) then
-                           lastinfile.close;
-                       end;
-                     if (hp1.fileinfo.line<>lastfileinfo.line) and
-                        ((hp1.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
-                       begin
-                         if (hp1.fileinfo.line<>0) and
-                            ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
-                           AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
-                             fixline(infile.GetLineStr(hp1.fileinfo.line)));
-                         { set it to a negative value !
-                         to make that is has been read already !! PM }
-                         if (infile.linebuf^[hp1.fileinfo.line]>=0) then
-                           infile.linebuf^[hp1.fileinfo.line]:=-infile.linebuf^[hp1.fileinfo.line]-1;
-                       end;
-                   end;
-                  lastfileinfo:=hp1.fileinfo;
-                  lastinfile:=infile;
-                end;
-            end;
-
-           case hp.typ of
-
-             ait_comment :
-               Begin
-                 AsmWrite(target_asm.comment);
-                 AsmWritePChar(tai_comment(hp).str);
-                 AsmLn;
-               End;
-
-             ait_regalloc :
-               begin
-                 if (cs_asm_regalloc in current_settings.globalswitches) then
-                   begin
-                     AsmWrite(#9+target_asm.comment+'Register ');
-                     repeat
-                       AsmWrite(std_regname(Tai_regalloc(hp).reg));
-                       if (hp.next=nil) or
-                          (tai(hp.next).typ<>ait_regalloc) or
-                          (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
-                         break;
-                       hp:=tai(hp.next);
-                       AsmWrite(',');
-                     until false;
-                     AsmWrite(' ');
-                     AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
-                   end;
-               end;
-
-             ait_tempalloc :
-               begin
-                 if (cs_asm_tempalloc in current_settings.globalswitches) then
-                   begin
-  {$ifdef EXTDEBUG}
-                     if assigned(tai_tempalloc(hp).problem) then
-                       AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
-                         tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
-                     else
-  {$endif EXTDEBUG}
-                       AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
-                         tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
-                   end;
-               end;
-
-             ait_align :
-               begin
-
-               end;
-
-             ait_section :
-               begin
-
-               end;
-
-             ait_datablock :
-               begin
-                 internalerror(2010122701);
-               end;
-
-             ait_const:
-               begin
-                 AsmWriteln('constant');
-//                 internalerror(2010122702);
-               end;
-
-             ait_realconst :
-               begin
-                 internalerror(2010122703);
-               end;
-
-             ait_string :
-               begin
-                 pos:=0;
-                  for i:=1 to tai_string(hp).len do
-                   begin
-                     if pos=0 then
-                      begin
-                        AsmWrite(#9'strconst: '#9'"');
-                        pos:=20;
-                      end;
-                     ch:=tai_string(hp).str[i-1];
-                     case ch of
-                        #0, {This can't be done by range, because a bug in FPC}
-                   #1..#31,
-                #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
-                       '"' : s:='\"';
-                       '\' : s:='\\';
-                     else
-                      s:=ch;
-                     end;
-                     AsmWrite(s);
-                     inc(pos,length(s));
-                     if (pos>line_length) or (i=tai_string(hp).len) then
-                      begin
-                        AsmWriteLn('"');
-                        pos:=0;
-                      end;
-                   end;
-               end;
-
-             ait_label :
-               begin
-                 if (tai_label(hp).labsym.is_used) then
-                  begin
-                    AsmWrite(tai_label(hp).labsym.name);
-                    AsmWriteLn(':');
-                  end;
-               end;
-
-             ait_symbol :
-               begin
-                  if (tai_symbol(hp).sym.typ = AT_FUNCTION) then
-                    begin
-                    end
-                  else
-                   begin
-                     AsmWrite('data symbol: ');
-                     AsmWriteln(tai_symbol(hp).sym.name);
-//                     internalerror(2010122706);
-                   end;
-               end;
-             ait_symbol_end :
-               begin
-               end;
-
-             ait_instruction :
-               begin
-                 WriteInstruction(hp);
-               end;
-
-             ait_force_line,
-             ait_function_name : ;
-
-             ait_cutobject :
-               begin
-               end;
-
-             ait_marker :
-               if tai_marker(hp).kind=mark_NoLineInfoStart then
-                 inc(InlineLevel)
-               else if tai_marker(hp).kind=mark_NoLineInfoEnd then
-                 dec(InlineLevel);
-
-             ait_directive :
-               begin
-                 AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
-                 if tai_directive(hp).name<>'' then
-                   AsmWrite(tai_directive(hp).name);
-                 AsmLn;
-               end;
-
-             ait_jvar:
-               begin
-                 AsmWrite('.var ');
-                 AsmWrite(tostr(tai_jvar(hp).stackslot));
-                 AsmWrite(' is ');
-                 AsmWrite(tai_jvar(hp).desc^);
-                 AsmWrite(' from ');
-                 AsmWrite(tai_jvar(hp).startlab.name);
-                 AsmWrite(' to ');
-                 AsmWriteLn(tai_jvar(hp).stoplab.name);
-               end;
-
-             ait_jcatch:
-               begin
-                 AsmWrite('.catch ');
-                 AsmWrite(tai_jcatch(hp).name^);
-                 AsmWrite(' from ');
-                 AsmWrite(tai_jcatch(hp).startlab.name);
-                 AsmWrite(' to ');
-                 AsmWrite(tai_jcatch(hp).stoplab.name);
-                 AsmWrite(' using ');
-                 AsmWriteLn(tai_jcatch(hp).handlerlab.name);
-               end;
-             else
-               internalerror(2010122707);
-           end;
-           hp:=tai(hp.next);
-         end;
-      end;
-
-
-    procedure TJasminAssembler.WriteExtraHeader(obj: tabstractrecorddef);
-      var
-        superclass,
-        intf: tobjectdef;
-        n: ansistring;
-        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
-        // source file must not be specified
-        if current_module.mainsource<>'' then
-          n:=ExtractFileName(current_module.mainsource)
-        else
-          n:=InputFileName;
-        AsmWriteLn('.source '+ExtractFileName(n));
-
-        { class/interface name }
-        if not assigned(obj) then
-          begin
-            { fake class type for unit -> name=unitname and
-              superclass=java.lang.object, make final so you cannot descend
-              from it }
-            AsmWrite('.class final public ');
-            if assigned(current_module.namespace) then
-              AsmWrite(current_module.namespace^+'.');
-            AsmWriteln(current_module.realmodulename^);
-            AsmWriteLn('.super java/lang/Object');
-          end
-        else
-          begin
-            toplevelowner:=obj.owner;
-            while not(toplevelowner.symtabletype in [staticsymtable,globalsymtable]) do
-              toplevelowner:=toplevelowner.defowner.owner;
-            case obj.typ of
-              recorddef:
-                begin
-                  { can't inherit from records }
-                  AsmWrite('.class final ');
-                  if toplevelowner.symtabletype=globalsymtable then
-                    AsmWrite('public ');
-                  AsmWriteln(obj.jvm_full_typename(true));
-                  superclass:=java_fpcbaserecordtype;
-                end;
-              objectdef:
-                begin
-                  case tobjectdef(obj).objecttype of
-                    odt_javaclass:
-                      begin
-                        AsmWrite('.class ');
-                        if oo_is_sealed in tobjectdef(obj).objectoptions then
-                          AsmWrite('final ');
-                        if (oo_is_abstract in tobjectdef(obj).objectoptions) or
-                           (tobjectdef(obj).abstractcnt<>0) then
-                          AsmWrite('abstract ');
-                        if toplevelowner.symtabletype=globalsymtable then
-                          AsmWrite('public ');
-                        if (oo_is_enum_class in tobjectdef(obj).objectoptions) then
-                          AsmWrite('enum ');
-                        AsmWriteln(obj.jvm_full_typename(true));
-                        superclass:=tobjectdef(obj).childof;
-                      end;
-                    odt_interfacejava:
-                      begin
-                        AsmWrite('.interface abstract ');
-                        if toplevelowner.symtabletype=globalsymtable then
-                          AsmWrite('public ');
-                        AsmWriteLn(obj.jvm_full_typename(true));
-                        { interfaces must always specify Java.lang.object as
-                          superclass }
-                        superclass:=java_jlobject;
-                      end
-                    else
-                      internalerror(2011010906);
-                  end;
-                end;
-            end;
-            { superclass }
-            if assigned(superclass) then
-              begin
-                AsmWrite('.super ');
-                if assigned(superclass.import_lib) then
-                  AsmWrite(superclass.import_lib^+'/');
-                AsmWriteln(superclass.objextname^);
-              end;
-            { implemented interfaces }
-            if (obj.typ=objectdef) and
-               assigned(tobjectdef(obj).ImplementedInterfaces) then
-              begin
-                for i:=0 to tobjectdef(obj).ImplementedInterfaces.count-1 do
-                  begin
-                    intf:=TImplementedInterface(tobjectdef(obj).ImplementedInterfaces[i]).IntfDef;
-                    AsmWrite('.implements ');
-                    AsmWriteLn(intf.jvm_full_typename(true));
-                  end;
-              end;
-            { signature for enum classes (must come after superclass and
-              implemented interfaces) }
-            if (obj.typ=objectdef) and
-               (oo_is_enum_class in tobjectdef(obj).objectoptions) then
-              AsmWriteln('.signature "Ljava/lang/Enum<L'+obj.jvm_full_typename(true)+';>;"');
-            { in case of nested class: relation to parent class }
-            if obj.owner.symtabletype in [objectsymtable,recordsymtable] then
-              AsmWriteln(InnerStructDef(obj));
-            { add all nested classes }
-            for i:=0 to obj.symtable.deflist.count-1 do
-              if (is_java_class_or_interface(tdef(obj.symtable.deflist[i])) or
-                  (tdef(obj.symtable.deflist[i]).typ=recorddef)) and
-                 not(df_generic in tdef(obj.symtable.deflist[i]).defoptions) then
-                AsmWriteln(InnerStructDef(tabstractrecorddef(obj.symtable.deflist[i])));
-          end;
-        AsmLn;
-      end;
-
-
-    procedure TJasminAssembler.WriteInstruction(hp: tai);
-      begin
-        InstrWriter.WriteInstruction(hp);
-      end;
-
-
-   function TJasminAssembler.MakeCmdLine: TCmdStr;
-     const
-       jasminjarname = 'jasmin.jar';
-     var
-       filenames: tcmdstr;
-       asmfile: tcmdstrlistitem;
-       jasminjarfound: boolean;
-     begin
-       if jasminjar='' then
-         begin
-           jasminjarfound:=false;
-           if utilsdirectory<>'' then
-             jasminjarfound:=FindFile(jasminjarname,utilsdirectory,false,jasminjar);
-           if not jasminjarfound then
-             jasminjarfound:=FindFileInExeLocations(jasminjarname,false,jasminjar);
-           if (not jasminjarfound) and not(cs_asm_extern in current_settings.globalswitches) then
-             begin
-               Message1(exec_e_assembler_not_found,jasminjarname);
-               current_settings.globalswitches:=current_settings.globalswitches+[cs_asm_extern];
-             end;
-           if jasminjarfound then
-             Message1(exec_t_using_assembler,jasminjar);
-         end;
-       result:=target_asm.asmcmd;
-       filenames:=ScriptFixFileName(AsmFileName);
-       if cs_asm_extern in current_settings.globalswitches then
-         filenames:=maybequoted(filenames);
-       asmfile:=tcmdstrlistitem(asmfiles.First);
-       while assigned(asmfile) do
-         begin
-           if cs_asm_extern in current_settings.globalswitches then
-             filenames:=filenames+' '+maybequoted(ScriptFixFileName(asmfile.str))
-           else
-            filenames:=filenames+' '+ScriptFixFileName(asmfile.str);
-           asmfile:=tcmdstrlistitem(asmfile.next);
-        end;
-       Replace(result,'$ASM',filenames);
-       if (path<>'') then
-         if cs_asm_extern in current_settings.globalswitches then
-           Replace(result,'$OBJDIR',maybequoted(ScriptFixFileName(path)))
-         else
-           Replace(result,'$OBJDIR',ScriptFixFileName(path))
-       else
-         Replace(result,'$OBJDIR','.');
-       if cs_asm_extern in current_settings.globalswitches then
-         Replace(result,'$JASMINJAR',maybequoted(ScriptFixFileName(jasminjar)))
-       else
-         Replace(result,'$JASMINJAR',ScriptFixFileName(jasminjar));
-       Replace(result,'$EXTRAOPT',asmextraopt);
-     end;
-
-
-   procedure TJasminAssembler.NewAsmFileForStructDef(obj: tabstractrecorddef);
-      begin
-        if AsmSize<>AsmStartSize then
-          begin
-            AsmClose;
-            asmfiles.Concat(AsmFileName);
-          end
-        else
-          AsmClear;
-
-        AsmFileName:=obj.jvm_full_typename(false);
-        AsmFileName:=Path+FixFileName(AsmFileName)+target_info.asmext;
-        AsmCreate(cut_normal);
-      end;
-
-
-    function TJasminAssembler.VisibilityToStr(vis: tvisibility): ansistring;
-      begin
-        case vis of
-          vis_hidden,
-          vis_strictprivate:
-            result:='private ';
-          { protected in Java means "accessible by subclasses *and* by classes
-            in the same package" -> similar to regular "protected" in Pascal;
-            "strict protected" is actually more strict in Pascal than in Java,
-            but there's not much we can do about that }
-          vis_protected,
-          vis_strictprotected:
-            result:='protected ';
-          vis_private:
-            { pick default visibility = "package" visibility; required because
-              other classes in the same unit can also access these symbols }
-            result:='';
-          vis_public:
-            result:='public '
-          else
-            internalerror(2010122609);
-        end;
-      end;
-
-
-    function TJasminAssembler.MethodDefinition(pd: tprocdef): ansistring;
-      begin
-        result:=VisibilityToStr(pd.visibility);
-        if (pd.procsym.owner.symtabletype in [globalsymtable,staticsymtable,localsymtable]) or
-           (po_classmethod in pd.procoptions) then
-          result:=result+'static ';
-        if (po_abstractmethod in pd.procoptions) or
-           is_javainterface(tdef(pd.owner.defowner)) then
-          result:=result+'abstract ';
-        if (pd.procsym.owner.symtabletype in [globalsymtable,staticsymtable,localsymtable]) or
-           (po_finalmethod in pd.procoptions) or
-           (not(po_virtualmethod in pd.procoptions) and
-            not(po_classmethod in pd.procoptions) and
-            not(pd.proctypeoption in [potype_constructor,potype_class_constructor])) then
-          result:=result+'final ';
-        result:=result+tcpuprocdef(pd).jvmmangledbasename(false);
-      end;
-
-
-    function TJasminAssembler.ConstValue(csym: tconstsym): ansistring;
-      begin
-        case csym.consttyp of
-          constord:
-            { always interpret as signed value, because the JVM does not
-              support unsigned values }
-            case csym.constdef.size of
-              1:result:=tostr(shortint(csym.value.valueord.svalue));
-              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);
-          constreal:
-            case tfloatdef(csym.constdef).floattype of
-              s32real:
-                result:=constsingle(pbestreal(csym.value.valueptr)^);
-              s64real:
-                result:=constdouble(pbestreal(csym.value.valueptr)^);
-              else
-                internalerror(2011021204);
-              end;
-          constset:
-            result:='TODO: add support for constant sets';
-          constpointer:
-            { can only be null, but that's the default value and should not
-              be written; there's no primitive type that can hold nill }
-            internalerror(2011021201);
-          constnil:
-            internalerror(2011021202);
-          constresourcestring:
-            result:='TODO: add support for constant resource strings';
-          constwstring:
-            result:=constwstr(pcompilerwidestring(csym.value.valueptr)^.data,pcompilerwidestring(csym.value.valueptr)^.len);
-          constguid:
-            result:='TODO: add support for constant guids';
-          else
-            internalerror(2011021205);
-        end;
-      end;
-
-
-    function TJasminAssembler.ConstAssignmentValue(csym: tconstsym): ansistring;
-      begin
-        result:='';
-        { nil is the default value -> don't write explicitly }
-        case csym.consttyp of
-          constpointer:
-            begin
-              if csym.value.valueordptr<>0 then
-                internalerror(2011021206);
-            end;
-          constnil:
-            ;
-        else
-          begin
-            { enums and sets are initialized as typed constants }
-            if not assigned(csym.constdef) or
-               not(csym.constdef.typ in [enumdef,setdef]) then
-              result:=' = '+ConstValue(csym);
-          end;
-        end;
-      end;
-
-
-    function TJasminAssembler.ConstDefinition(sym: tconstsym): ansistring;
-      begin
-        result:=VisibilityToStr(sym.visibility);
-        { formal constants are always class-level, not instance-level }
-        result:=result+'static final ';
-        if sp_internal in sym.symoptions then
-          result:=result+'synthetic ';
-        result:=result+jvmmangledbasename(sym,true);
-        result:=result+ConstAssignmentValue(tconstsym(sym));
-      end;
-
-
-    function TJasminAssembler.FieldDefinition(sym: tabstractvarsym): ansistring;
-      begin
-        case sym.typ of
-          staticvarsym:
-            begin
-              if sym.owner.symtabletype=globalsymtable then
-                result:='public '
-              else
-                { package visbility }
-                result:='';
-            end;
-          fieldvarsym,
-          absolutevarsym:
-            result:=VisibilityToStr(tstoredsym(sym).visibility);
-          else
-            internalerror(2011011204);
-        end;
-        if (sym.typ=staticvarsym) or
-           (sp_static in sym.symoptions) then
-          result:=result+'static ';
-        if sym.varspez in [vs_const,vs_final] then
-          result:=result+'final ';
-        if sp_internal in sym.symoptions then
-          result:=result+'synthetic ';
-        { mark the class fields of enum classes that contain the initialised
-          enum instances as "enum" (recognise them by the fact that their type
-          is the same as their parent class, and that this parent class is
-          marked as oo_is_enum_class) }
-        if assigned(sym.owner.defowner) and
-           (tdef(sym.owner.defowner).typ=objectdef) and
-           (oo_is_enum_class in tobjectdef(sym.owner.defowner).objectoptions) and
-           (sym.typ=staticvarsym) and
-           (tstaticvarsym(sym).vardef=tdef(sym.owner.defowner)) then
-          result:=result+'enum ';
-        result:=result+jvmmangledbasename(sym,true);
-      end;
-
-
-    function TJasminAssembler.InnerStructDef(obj: tabstractrecorddef): ansistring;
-      var
-        extname: pshortstring;
-        kindname: ansistring;
-      begin
-        if not(obj.owner.defowner.typ in [objectdef,recorddef]) then
-          internalerror(2011021701);
-        { Nested classes in the Pascal sense are equivalent to "static"
-          inner classes in Java -- will be changed when support for
-          Java-style non-static classes is added }
-        case obj.typ of
-          recorddef:
-            begin
-              kindname:='class static ';
-              extname:=obj.symtable.realname;
-            end;
-          objectdef:
-            begin
-              extname:=tobjectdef(obj).objextname;
-              case tobjectdef(obj).objecttype of
-                odt_javaclass:
-                  kindname:='class static ';
-                odt_interfacejava:
-                  kindname:='interface static abstract ';
-                else
-                  internalerror(2011021702);
-              end;
-            end;
-          else
-            internalerror(2011032809);
-        end;
-        result:=
-          '.inner '+
-          kindname+
-          VisibilityToStr(obj.typesym.visibility)+
-         extname^+
-         ' inner '+
-         obj.jvm_full_typename(true)+
-         ' outer '+
-         tabstractrecorddef(obj.owner.defowner).jvm_full_typename(true);
-      end;
-
-
-    procedure TJasminAssembler.WriteProcDef(pd: tprocdef);
-      begin
-        if not assigned(tcpuprocdef(pd).exprasmlist) and
-           not(po_abstractmethod in pd.procoptions) and
-           (not is_javainterface(pd.struct) or
-            (pd.proctypeoption in [potype_unitinit,potype_unitfinalize])) then
-          exit;
-        AsmWrite('.method ');
-        AsmWriteln(MethodDefinition(pd));
-        if jvmtypeneedssignature(pd) then
-          begin
-            AsmWrite('.signature "');
-            AsmWrite(tcpuprocdef(pd).jvmmangledbasename(true));
-            AsmWriteln('"');
-          end;
-        WriteTree(tcpuprocdef(pd).exprasmlist);
-        AsmWriteln('.end method');
-        AsmLn;
-      end;
-
-
-    procedure TJasminAssembler.WriteFieldSym(sym: tabstractvarsym);
-      begin
-        { internal static field definition alias -> skip }
-        if (sym.owner.symtabletype in [recordsymtable,ObjectSymtable]) and
-           (sym.typ=staticvarsym) then
-          exit;
-        { external or threadvar definition -> no definition here }
-        if ([vo_is_external,vo_is_thread_var]*sym.varoptions)<>[] then
-          exit;
-        AsmWrite('.field ');
-        AsmWriteln(FieldDefinition(sym));
-      end;
-
-
-    procedure TJasminAssembler.WriteConstSym(sym: tconstsym);
-      begin
-        AsmWrite('.field ');
-        AsmWriteln(ConstDefinition(sym));
-      end;
-
-
-    procedure TJasminAssembler.WriteSymtableVarSyms(st: TSymtable);
-      var
-        sym : tsym;
-        i,j : longint;
-      begin
-        if not assigned(st) then
-          exit;
-        for i:=0 to st.SymList.Count-1 do
-         begin
-           sym:=tsym(st.SymList[i]);
-           case sym.typ of
-             staticvarsym,
-             fieldvarsym:
-               begin
-                 WriteFieldSym(tabstractvarsym(sym));
-                 if (sym.typ=staticvarsym) and
-                    assigned(tstaticvarsym(sym).defaultconstsym) then
-                   WriteFieldSym(tabstractvarsym(tstaticvarsym(sym).defaultconstsym));
-               end;
-             constsym:
-               begin
-                 { multiple procedures can have constants with the same name }
-                 if not assigned(sym.owner.defowner) or
-                    (tdef(sym.owner.defowner).typ<>procdef) then
-                   WriteConstSym(tconstsym(sym));
-               end;
-             procsym:
-               begin
-                 for j:=0 to tprocsym(sym).procdeflist.count-1 do
-                   if not(df_generic in tprocdef(tprocsym(sym).procdeflist[j]).defoptions) then
-                     WriteSymtableVarSyms(tprocdef(tprocsym(sym).procdeflist[j]).localst);
-               end;
-           end;
-         end;
-      end;
-
-
-    procedure TJasminAssembler.WriteSymtableProcdefs(st: TSymtable);
-      var
-        i   : longint;
-        def : tdef;
-      begin
-        if not assigned(st) then
-          exit;
-        for i:=0 to st.DefList.Count-1 do
-          begin
-            def:=tdef(st.DefList[i]);
-            case def.typ of
-              procdef :
-                begin
-                  { methods are also in the static/globalsymtable of the unit
-                    -> make sure they are only written for the objectdefs that
-                    own them }
-                  if (not(st.symtabletype in [staticsymtable,globalsymtable]) or
-                      (def.owner=st)) and
-                     not(df_generic in def.defoptions) then
-                    begin
-                      WriteProcDef(tprocdef(def));
-                      if assigned(tprocdef(def).localst) then
-                        WriteSymtableProcdefs(tprocdef(def).localst);
-                    end;
-                end;
-            end;
-          end;
-      end;
-
-    procedure TJasminAssembler.WriteSymtableStructDefs(st: TSymtable);
-      var
-        i   : longint;
-        def : tdef;
-        obj : tabstractrecorddef;
-        nestedstructs: tfpobjectlist;
-      begin
-        if not assigned(st) then
-          exit;
-        nestedstructs:=tfpobjectlist.create(false);
-        for i:=0 to st.DefList.Count-1 do
-          begin
-            def:=tdef(st.DefList[i]);
-            if df_generic in def.defoptions then
-              continue;
-            case def.typ of
-              objectdef:
-                if not(oo_is_external in tobjectdef(def).objectoptions) then
-                  nestedstructs.add(def);
-              recorddef:
-                nestedstructs.add(def);
-            end;
-          end;
-        for i:=0 to nestedstructs.count-1 do
-          begin
-            obj:=tabstractrecorddef(nestedstructs[i]);
-            NewAsmFileForStructDef(obj);
-            WriteExtraHeader(obj);
-            WriteSymtableVarSyms(obj.symtable);
-            AsmLn;
-            WriteSymtableProcDefs(obj.symtable);
-            WriteSymtableStructDefs(obj.symtable);
-          end;
-        nestedstructs.free;
-      end;
-
-    constructor TJasminAssembler.Create(smart: boolean);
-      begin
-        inherited create(smart);
-        InstrWriter:=TJasminInstrWriter.Create(self);
-        asmfiles:=TCmdStrList.Create;
-      end;
-
-
-    procedure TJasminAssembler.WriteAsmList;
-    begin
-{$ifdef EXTDEBUG}
-      if assigned(current_module.mainsource) then
-       Comment(V_Debug,'Start writing Jasmin-styled assembler output for '+current_module.mainsource);
-{$endif}
-
-      AsmStartSize:=AsmSize;
-      WriteExtraHeader(nil);
-(*
-      for hal:=low(TasmlistType) to high(TasmlistType) do
-        begin
-          AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
-          writetree(current_asmdata.asmlists[hal]);
-          AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
-        end;
-*)
-      { print all global variables }
-      WriteSymtableVarSyms(current_module.globalsymtable);
-      WriteSymtableVarSyms(current_module.localsymtable);
-      AsmLn;
-      { print all global procedures/functions }
-      WriteSymtableProcdefs(current_module.globalsymtable);
-      WriteSymtableProcdefs(current_module.localsymtable);
-
-      WriteSymtableStructDefs(current_module.globalsymtable);
-      WriteSymtableStructDefs(current_module.localsymtable);
-
-      AsmLn;
-{$ifdef EXTDEBUG}
-      if assigned(current_module.mainsource) then
-       Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource);
-{$endif EXTDEBUG}
-    end;
-
-
-    procedure TJasminAssembler.RemoveAsm;
-      var
-        g : file;
-      begin
-        inherited;
-        if cs_asm_leave in current_settings.globalswitches then
-         exit;
-        while not asmfiles.empty do
-          begin
-            if cs_asm_extern in current_settings.globalswitches then
-             AsmRes.AddDeleteCommand(asmfiles.GetFirst)
-            else
-             begin
-               assign(g,asmfiles.GetFirst);
-               {$I-}
-                erase(g);
-               {$I+}
-               if ioresult<>0 then;
-             end;
-          end;
-      end;
-
-{****************************************************************************}
-{                         Jasmin Instruction Writer                          }
-{****************************************************************************}
-
-     constructor TJasminInstrWriter.create(_owner: TJasminAssembler);
-       begin
-         inherited create;
-         owner := _owner;
-       end;
-
-    function getreferencestring(var ref : treference) : ansistring;
-      begin
-        if (ref.arrayreftype<>art_none) or
-           (ref.index<>NR_NO) then
-          internalerror(2010122809);
-        if assigned(ref.symbol) then
-          begin
-            // global symbol or field -> full type and name
-            // ref.base can be <> NR_NO in case an instance field is loaded.
-            // This register is not part of this instruction, it will have
-            // been placed on the stack by the previous one.
-            if (ref.offset<>0) then
-              internalerror(2010122811);
-            result:=ref.symbol.name;
-          end
-        else
-          begin
-            // local symbol -> stack slot, stored in offset
-            if ref.base<>NR_STACK_POINTER_REG then
-              internalerror(2010122810);
-            result:=tostr(ref.offset);
-          end;
-      end;
-
-
-    function getopstr(const o:toper) : ansistring;
-      var
-        d: double;
-        s: single;
-      begin
-        case o.typ of
-          top_reg:
-            // should have been translated into a memory location by the
-            // register allocator)
-            if (cs_no_regalloc in current_settings.globalswitches) then
-              getopstr:=std_regname(o.reg)
-            else
-              internalerror(2010122803);
-          top_const:
-            str(o.val,result);
-          top_ref:
-            getopstr:=getreferencestring(o.ref^);
-          top_single:
-            begin
-              result:=constsingle(o.sval);
-            end;
-          top_double:
-            begin
-              result:=constdouble(o.dval);
-            end;
-          top_string:
-            begin
-              result:=constastr(o.pcval,o.pcvallen);
-            end;
-          top_wstring:
-            begin
-              result:=constwstr(o.pwstrval^.data,getlengthwidestring(o.pwstrval));
-            end
-          else
-            internalerror(2010122802);
-        end;
-      end;
-
-
-    procedure TJasminInstrWriter.WriteInstruction(hp: tai);
-      var
-        s: ansistring;
-        i: byte;
-        sep: ansistring;
-      begin
-        s:=#9+jas_op2str[taicpu(hp).opcode];
-        if taicpu(hp).ops<>0 then
-          begin
-            sep:=#9;
-            for i:=0 to taicpu(hp).ops-1 do
-              begin
-                 s:=s+sep+getopstr(taicpu(hp).oper[i]^);
-                 sep:=' ';
-              end;
-          end;
-        owner.AsmWriteLn(s);
-      end;
-
-{****************************************************************************}
-{                         Jasmin Instruction Writer                          }
-{****************************************************************************}
-
-  const
-    as_jvm_jasmin_info : tasminfo =
-       (
-         id     : as_jvm_jasmin;
-         idtxt  : 'Jasmin';
-         asmbin : 'java';
-         asmcmd : '-jar $JASMINJAR $ASM $EXTRAOPT -d $OBJDIR';
-         supported_targets : [system_jvm_java32,system_jvm_android32];
-         flags : [];
-         labelprefix : 'L';
-         comment : ' ; ';
-         dollarsign : '$';
-       );
-
-
-begin
-  RegisterAssembler(as_jvm_jasmin_info,TJasminAssembler);
-end.

+ 0 - 268
compiler/alpha/aasmcpu.pas

@@ -1,268 +0,0 @@
-{
-    Copyright (c) 1998-2000 by Florian Klaempfl
-
-    Implements the assembler classes specific for the Alpha
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-{
-  Implements the assembler classes specific for the Alpha.
-}
-unit aasmcpu;
-
-{$i fpcdefs.inc}
-
-  interface
-
-    uses
-       aasmbase,globals,verbose,
-       cpubase,aasmtai,aasmdata,aasmsym;
-
-    type
-      tai_frame = class(tai)
-         G,R : TRegister;
-         LS,LU : longint;
-        Constructor Create (GP : Tregister; Localsize : Longint; RA : TRegister; L : longint);
-        end;
-
-
-      taicpu = class(tai_cpu_abstract_sym)
-         constructor op_none(op : tasmop);
-
-         constructor op_reg(op : tasmop;_op1 : tregister);
-         constructor op_const(op : tasmop;_op1 : longint);
-         constructor op_ref(op : tasmop;_op1 : preference);
-
-         constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
-         constructor op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
-         constructor op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
-
-         constructor op_const_reg(op : tasmop;_op1 : longint;_op2 : tregister);
-         constructor op_const_const(op : tasmop;_op1,_op2 : longint);
-         constructor op_const_ref(op : tasmop;_op1 : longint;_op2 : preference);
-
-         constructor op_ref_reg(op : tasmop;_op1 : preference;_op2 : tregister);
-         { this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
-         constructor op_ref_ref(op : tasmop;_op1,_op2 : preference);
-
-         constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
-         constructor op_reg_const_reg(op : tasmop;_op1 : tregister;_op2 : longint;_op3 : tregister);
-         constructor op_const_ref_reg(op : tasmop;_op1 : longint;_op2 : preference;_op3 : tregister);
-         constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; _op3 : preference);
-         constructor op_const_reg_ref(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : preference);
-         constructor op_reg_ref_const(op : tasmop;_op1 : tregister;_op2 : preference;_op3 : longint);
-
-         { this is for Jmp instructions }
-         constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
-
-         constructor op_sym(op : tasmop;_op1 : tasmsymbol);
-         constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
-         constructor op_sym_ofs_reg(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;_op2 : tregister);
-         constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;_op2 : preference);
-      end;
-
-      tai_align = class(tai_align_abstract)
-        { nothing to add }
-      end;
-
-    procedure InitAsm;
-    procedure DoneAsm;
-
-implementation
-
-
-{*****************************************************************************
-                                 taicpu Constructors
-*****************************************************************************}
-
-
-    constructor taicpu.op_none(op : tasmop);
-      begin
-         inherited create(op);
-      end;
-
-
-    constructor taicpu.op_reg(op : tasmop;_op1 : tregister);
-      begin
-         inherited create(op);
-         ops:=1;
-      end;
-
-
-    constructor taicpu.op_const(op : tasmop;_op1 : longint);
-      begin
-         inherited create(op);
-         ops:=1;
-      end;
-
-
-    constructor taicpu.op_ref(op : tasmop;_op1 : preference);
-      begin
-         inherited create(op);
-         ops:=1;
-      end;
-
-
-    constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-
-    constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-
-    constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-
-    constructor taicpu.op_const_reg(op : tasmop;_op1 : longint;_op2 : tregister);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-
-    constructor taicpu.op_const_const(op : tasmop;_op1,_op2 : longint);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-
-    constructor taicpu.op_const_ref(op : tasmop;_op1 : longint;_op2 : preference);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-    constructor taicpu.op_ref_reg(op : tasmop;_op1 : preference;_op2 : tregister);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-
-    constructor taicpu.op_ref_ref(op : tasmop;_op1,_op2 : preference);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-
-    constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
-      begin
-         inherited create(op);
-         ops:=3;
-      end;
-
-    constructor taicpu.op_reg_const_reg(op : tasmop;_op1 : tregister;_op2 : longint;_op3 : tregister);
-      begin
-         inherited create(op);
-         ops:=3;
-      end;
-
-     constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister;_op3 : preference);
-      begin
-         inherited create(op);
-         ops:=3;
-      end;
-
-     constructor taicpu.op_const_ref_reg(op : tasmop;_op1 : longint;_op2 : preference;_op3 : tregister);
-      begin
-         inherited create(op);
-         ops:=3;
-      end;
-
-     constructor taicpu.op_const_reg_ref(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : preference);
-      begin
-         inherited create(op);
-         ops:=3;
-      end;
-
-     constructor taicpu.op_reg_ref_const(op : tasmop;_op1 : tregister;_op2 : preference;_op3 : longint);
-      begin
-         inherited create(op);
-         ops:=3;
-      end;
-
-
-    constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
-      begin
-         inherited create(op);
-         condition:=cond;
-         ops:=1;
-      end;
-
-
-    constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
-      begin
-         inherited create(op);
-         ops:=1;
-      end;
-
-
-    constructor taicpu.op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
-      begin
-         inherited create(op);
-         ops:=1;
-      end;
-
-
-    constructor taicpu.op_sym_ofs_reg(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;_op2 : tregister);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-
-    constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;_op2 : preference);
-      begin
-         inherited create(op);
-         ops:=2;
-      end;
-
-    Constructor tai_frame.create (GP : Tregister; Localsize : Longint; RA : TRegister; L : longint);
-
-    begin
-      Inherited Create;
-      typ:=ait_frame;
-      G:=GP;
-      R:=RA;
-      LS:=LocalSize;
-      LU:=L;
-    end;
-
-    procedure InitAsm;
-      begin
-      end;
-
-
-    procedure DoneAsm;
-      begin
-      end;
-
-
-    end.

+ 0 - 126
compiler/alpha/agaxpgas.pas

@@ -1,126 +0,0 @@
-{
-    Copyright (c) 1998-2000 by Florian Klaempfl
-
-    This unit implements an asm for the DEC Alpha
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit agaxpgas;
-
-  {$i fpcdefs.inc}
-
-  interface
-
-    uses
-       globals,systems,aasmbase,aasmtai,aasmdata,
-       aggas,cpubase;
-
-    type
-      TAXPGNUAssembler=class(TGNUAssembler)
-        procedure WriteInstruction(hp : tai);override;
-      end;
-
-    const
-       gas_reg2str : array[tregister] of string[4] = (
-         '',
-         '','','','','','','','','','',
-         '','','','','','','','','','',
-         '','','','','','','','','','',
-         '','',
-         '','','','','','','','','','',
-         '','','','','','','','','','',
-         '','','','','','','','','','',
-         '',''
-       );
-
-  implementation
-
-    const
-       op2str : array[tasmop] of string[14] = (
-          'addf','addg','addl','addq',
-          'adds','addt','amask','and','beq','bge',
-          'bgt','bic','bis','blbc','blbs','ble',
-          'blt','bne','br','bsr','call_pal','cmoveq',
-          'cmovge','cmovgt','cmovlbc','cmovlbs','cmovle','cmovlt',
-          'cmovne','cmpbge','cmpeq','cmpgeq','cmpgle','cmpglt',
-          'cmple','cmplt','cmpteq','cmptle','cmptlt','cmptun',
-          'cmpule','cmpult','cpys','cpyse','cpysn','ctlz',
-          'ctpop','cttz','cvtdg','cvtgd','cvtgf','cvtgq',
-          'cvtlq','cvtqf','cvtqg','cvtql','cvtqs','cvtqt',
-          'cvtst','cvttq','cvtts','divf','divg','divs',
-          'divt','ecb','eqv','excb','extbl','extlh',
-          'extll','extqh','extql','extwh','extwl','fbeq',
-          'fbge','fbgt','fble','fblt','fbne','fcmoveq',
-          'fcmovge','fcmovgt','fcmovle','fcmovlt','fcmovne','fetch',
-          'fetch_m','ftois','ftoit','implver','insbl','inslh',
-          'insll','insqh','insql','inswh','inswl','itoff',
-          'itofs','itoft','jmp','jsr','jsr_coroutine','lda',
-          'ldah','ldbu','ldwu','ldf','ldg','ldl',
-          'ldl_l','ldq','ldq_l','ldq_u','lds','ldt',
-          'maxsb8','maxsw4','maxub8','maxuw4','mb','mf_fpcr',
-          'minsb8','minsw4','minub8','minuw4','mskbl','msklh',
-          'mskll','mskqh','mskql','mskwh','mskwl','mt_fpcr',
-          'mulf','mulg','mull','mulq',
-          'muls','mult','ornot','perr','pklb','pkwb',
-          'rc','ret','rpcc','rs','s4addl','s4addq',
-          's4subl','s4subq','s8addl','s8addq','s8subl','s8subq',
-          'sextb','sextw','sll','sqrtf','sqrtg','sqrts',
-          'sqrtt','sra','srl','stb','stf','stg',
-          'sts','stl','stl_c','stq','stq_c','stq_u',
-          'stt','stw','subf','subg','subl',
-          'subq','subs','subt','trapb','umulh','unpkbl',
-          'unpkbw','wh64','wmb','xor','zap','zapnot',
-          'ldgp');
-
-      procedure TAXPGNUAssembler.WriteInstruction (hp : tai);
-        begin
-(*
-               op:=paicpu(hp)^.opcode;
-               calljmp:=is_calljmp(op);
-             { call maybe not translated to calll }
-               s:=#9+att_op2str[op]+cond2str[paicpu(hp)^.condition];
-               if (not calljmp) and
-                  (not att_nosuffix[op]) and
-                  not(
-                   (paicpu(hp)^.oper[0].typ=top_reg) and
-                   (paicpu(hp)^.oper[0].reg in [R_ST..R_ST7])
-                  ) then
-                s:=s+att_opsize2str[paicpu(hp)^.opsize];
-             { process operands }
-               if paicpu(hp)^.ops<>0 then
-                begin
-                { call and jmp need an extra handling                          }
-                { this code is only called if jmp isn't a labeled instruction }
-                  if calljmp then
-                   s:=s+#9+getopstr_jmp(paicpu(hp)^.oper[0])
-                  else
-                   begin
-                     for i:=0to paicpu(hp)^.ops-1 do
-                      begin
-                        if i=0 then
-                         sep:=#9
-                        else
-                         sep:=',';
-                        s:=s+sep+getopstr(paicpu(hp)^.oper[i])
-                      end;
-                   end;
-                end;
-               AsmWriteLn(s);
-*)
-             end;
-
-end.

+ 0 - 38
compiler/alpha/aoptcpu.pas

@@ -1,38 +0,0 @@
-{
-    Copyright (c) 1998-2000 by Jonas Maebe, member of the Free Pascal
-    Development Team
-
-    This unit implements the Alpha optimizer object
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-
-
-Unit aoptcpu;
-
-Interface
-
-uses cpubase, aoptobj, aoptcpub;
-
-Type
-  TAOptCpu = Object(TAoptObj)
-    { uses the same constructor as TAopObj }
-  End;
-
-Implementation
-
-End.

+ 0 - 112
compiler/alpha/aoptcpub.pas

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

+ 0 - 38
compiler/alpha/aoptcpuc.pas

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

+ 0 - 39
compiler/alpha/aoptcpud.pas

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

+ 0 - 168
compiler/alpha/cgcpu.pas

@@ -1,168 +0,0 @@
-{
-    Copyright (c) 1998-2000 by Florian Klaempfl
-
-    This unit implements the code generator for the Alpha
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-{
-  This unit implements the code generator for the Alpha.
-}
-unit cgcpu;
-
-{$i fpcdefs.inc}
-
-interface
-
-uses
-   cgbase,cgobj,aasmbase,aasmtai,aasmdata,aasmcpu,cginfo,cpubase,cpuinfo;
-
-type
-pcgalpha = ^tcgalpha;
-tcgalpha = class(tcg)
-  procedure a_call_name(list : TAsmList;const s : string);override;
-  procedure a_load_const_reg(list : TAsmList;size : tcgsize;a : aword;register : tregister);override;
-  procedure a_load_reg_ref(list : TAsmList;size : tcgsize;register : tregister;const ref : treference);override;
-  procedure a_load_ref_reg(list : TAsmList;size : tcgsize;const ref : treference;register : tregister);override;
-  procedure a_load_reg_reg(list : TAsmList;fromsize, tosize : tcgsize;reg1,reg2 : tregister);override;
-  procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aword;
-    reg : tregister;  l : tasmlabel);override;
-  procedure a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel);
-  procedure a_cmp_reg_ref_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg : tregister;l : tasmlabel);
-  procedure a_cmp_ref_const_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aword;
-    reg : tregister; l : tasmlabel);
-  procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override;
-  procedure g_stackframe_entry(list : TAsmList;localsize : longint);override;
-  procedure g_maybe_loadself(list : TAsmList);override;
-  procedure g_restore_frame_pointer(list : TAsmList);override;
-end;
-
-procedure create_codegen;
-
-implementation
-
-uses
-   globtype,globals;
-
-procedure tcgalpha.g_stackframe_entry(list : TAsmList;localsize : longint);
-
-begin
-   list.concat(taicpu.op_reg_ref(A_LDGP,Global_pointer,new_reference(R_27,0)));
-   list.concat(taicpu.op_reg_ref(A_LDA,stack_pointer_reg,new_reference(stack_pointer_reg,-LocalSize)));
-   If LocalSize<>0 then
-     list.concat(tai_frame.create(Global_pointer,LocalSize,R_27,0));
-   { Always generate a frame pointer. }
-   list.concat(taicpu.op_reg_reg_reg(A_BIS,stack_pointer_reg,stack_pointer_reg,frame_pointer_reg));
-end;
-
-procedure g_exitcode(list : TAsmList;parasize : longint; nostackframe,inlined : boolean);
-
-begin
-   { Restore stack pointer from frame pointer }
-   list.Concat (taicpu.op_reg_reg_reg(A_BIS,frame_pointer_reg,frame_pointer_reg,stack_pointer_reg));
-   { Restore previous stack position}
-   list.Concat (taicpu.op_reg_const_reg(A_ADDQ,stack_pointer_reg,Parasize,stack_pointer_reg));
-   { return... }
-   list.Concat(taicpu.op_reg_ref_const(A_RET,stack_pointer_reg,new_reference(Return_pointer,0),1));
-    { end directive
-    Concat (paiend,init(''));
-    }
-end;
-
-procedure tcgalpha.a_call_name(list : TAsmList;const s : string);
-
-  begin
-     { list^.concat(taicpu,op_sym(A_CALL,S_NO,newasmsymbol(s,AB_EXTERNAL,AT_FUNCTION)))); }
-     {!!!!!!!!!1 offset is ignored }
-     abstract;
-  end;
-
-procedure tcgalpha.a_load_const_reg(list : TAsmList;size : tcgsize;a : aword;register : tregister);
-
-begin
-end;
-
-
-procedure tcgalpha.a_load_reg_ref(list : TAsmList;size : tcgsize;register : tregister;const ref : treference);
-
-begin
-end;
-
-
-procedure tcgalpha.a_load_ref_reg(list : TAsmList;size : tcgsize;const ref : treference;register : tregister);
-
-begin
-end;
-
-
-procedure tcgalpha.a_load_reg_reg(list : TAsmList;fromsize, tosize : tcgsize;reg1,reg2 : tregister);
-
-begin
-end;
-
-
-procedure tcgalpha.a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
-  l : tasmlabel);
-
-begin
-end;
-
-
-procedure tcgalpha.a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel);
-
-begin
-end;
-
-
-procedure tcgalpha.a_cmp_reg_ref_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg : tregister;l : tasmlabel);
-
-begin
-end;
-
-
-procedure tcgalpha.a_cmp_ref_const_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aword;
-  reg : tregister; l : tasmlabel);
-
-begin
-end;
-
-
-procedure tcgalpha.a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);
-
-begin
-end;
-
-
-procedure tcgalpha.g_maybe_loadself(list : TAsmList);
-
-begin
-end;
-
-
-procedure tcgalpha.g_restore_frame_pointer(list : TAsmList);
-
-begin
-end;
-
-
-procedure create_codegen;
-  begin
-    cg:=tcgalpha.create;
-    cg128:=tcg128.create;
-  end;
-
-end.

+ 0 - 431
compiler/alpha/cpubase.pas

@@ -1,431 +0,0 @@
-{
-    Copyright (C) 1998-2000 by Florian Klaempfl
-
-    This unit implements an asmlistitem class for the Alpha architecture.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-{
-  This unit implements an asmlistitem class for the Alpha architecture.
-}
-unit cpubase;
-
-{$i fpcdefs.inc}
-
-  interface
-
-    uses
-       cutils,cclasses,globals,aasmbase,cpuinfo,cginfo;
-
-    type
-       { all registers }
-       TRegister = (R_NO,  { R_NO is Mandatory, signifies no register }
-                    R_0,R_1,R_2,R_3,R_4,R_5,R_6,R_7,R_8,R_9,
-                    R_10,R_11,R_12,R_13,R_14,R_15,R_16,R_17,R_18,R_19,
-                    R_20,R_21,R_22,R_23,R_24,R_25,R_26,R_27,R_28,R_29,
-                    R_30,R_31,
-                    R_F0,R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,
-                    R_F10,R_F11,R_F12,R_F13,R_F14,R_F15,R_F16,R_F17,R_F18,R_F19,
-                    R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,
-                    R_F30,R_F31);
-
-       tasmop = (A_ADDF,A_ADDG,A_ADDL,A_ADDQ,
-                 A_ADDS,A_ADDT,A_AMASK,A_AND,A_BEQ,A_BGE,
-                 A_BGT,A_BIC,A_BIS,A_BLBC,A_BLBS,A_BLE,
-                 A_BLT,A_BNE,A_BR,A_BSR,A_CALL_PAL,A_CMOVEQ,
-                 A_CMOVGE,A_CMOVGT,A_CMOVLBC,A_CMOVLBS,A_CMOVLE,A_CMOVLT,
-                 A_CMOVNE,A_CMPBGE,A_CMPEQ,A_CMPGEQ,A_CMPGLE,A_CMPGLT,
-                 A_CMPLE,A_CMPLT,A_CMPTEQ,A_CMPTLE,A_CMPTLT,A_CMPTUN,
-                 A_CMPULE,A_CMPULT,A_CPYS,A_CPYSE,A_CPYSN,A_CTLZ,
-                 A_CTPOP,A_CTTZ,A_CVTDG,A_CVTGD,A_CVTGF,A_CVTGQ,
-                 A_CVTLQ,A_CVTQF,A_CVTQG,A_CVTQL,A_CVTQS,A_CVTQT,
-                 A_CVTST,A_CVTTQ,A_CVTTS,A_DIVF,A_DIVG,A_DIVS,
-                 A_DIVT,A_ECB,A_EQV,A_EXCB,A_EXTBL,A_EXTLH,
-                 A_EXTLL,A_EXTQH,A_EXTQL,A_EXTWH,A_EXTWL,A_FBEQ,
-                 A_FBGE,A_FBGT,A_FBLE,A_FBLT,A_FBNE,A_FCMOVEQ,
-                 A_FCMOVGE,A_FCMOVGT,A_FCMOVLE,A_FCMOVLT,A_FCMOVNE,A_FETCH,
-                 A_FETCH_M,A_FTOIS,A_FTOIT,A_IMPLVER,A_INSBL,A_INSLH,
-                 A_INSLL,A_INSQH,A_INSQL,A_INSWH,A_INSWL,A_ITOFF,
-                 A_ITOFS,A_ITOFT,A_JMP,A_JSR,A_JSR_COROUTINE,A_LDA,
-                 A_LDAH,A_LDBU,A_LDWU,A_LDF,A_LDG,A_LDL,
-                 A_LDL_L,A_LDQ,A_LDQ_L,A_LDQ_U,A_LDS,A_LDT,
-                 A_MAXSB8,A_MAXSW4,A_MAXUB8,A_MAXUW4,A_MB,A_MF_FPCR,
-                 A_MINSB8,A_MINSW4,A_MINUB8,A_MINUW4,A_MSKBL,A_MSKLH,
-                 A_MSKLL,A_MSKQH,A_MSKQL,A_MSKWH,A_MSKWL,A_MT_FPCR,
-                 A_MULF,A_MULG,A_MULL,A_MULQ,
-                 A_MULS,A_MULT,A_ORNOT,A_PERR,A_PKLB,A_PKWB,
-                 A_RC,A_RET,A_RPCC,A_RS,A_S4ADDL,A_S4ADDQ,
-                 A_S4SUBL,A_S4SUBQ,A_S8ADDL,A_S8ADDQ,A_S8SUBL,A_S8SUBQ,
-                 A_SEXTB,A_SEXTW,A_SLL,A_SQRTF,A_SQRTG,A_SQRTS,
-                 A_SQRTT,A_SRA,A_SRL,A_STB,A_STF,A_STG,
-                 A_STS,A_STL,A_STL_C,A_STQ,A_STQ_C,A_STQ_U,
-                 A_STT,A_STW,A_SUBF,A_SUBG,A_SUBL,
-                 A_SUBQ,A_SUBS,A_SUBT,A_TRAPB,A_UMULH,
-                 A_UNPKBL,A_UNPKBW,A_WH64,A_WMB,A_XOR,A_ZAP,
-                 A_ZAPNOT
-                 { Psuedo code understood by the gnu assembler }
-                 ,A_LDGP);
-
-    const
-       firstop = low(tasmop);
-       lastop  = high(tasmop);
-
-       std_reg2str : array[tregister] of string[4] = (
-         '',
-         '','','','','','','','','','',
-         '','','','','','','','','','',
-         '','','','','','','','','','',
-         '','',
-         '','','','','','','','','','',
-         '','','','','','','','','','',
-         '','','','','','','','','','',
-         '',''
-       );
-
-
-    type
-       TAsmCond =
-        (
-         C_None,C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
-         C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,C_NS,C_NZ,C_O,C_P,
-         C_PE,C_PO,C_S,C_Z
-        );
-
-        TRegisterset = Set of TRegister;
-
-        tregister64 = tregister;
-
-    Const
-       Firstreg = R_0;
-       LastReg = R_F31;
-
-
-{*****************************************************************************
-                          Default generic sizes
-*****************************************************************************}
-
-       { Defines the default address size for a processor, }
-       OS_ADDR = OS_64;
-       { the natural int size for a processor,
-         has to match osuinttype/ossinttype as initialized in psystem }
-       OS_INT = OS_64;
-       { the maximum float size for a processor,           }
-       OS_FLOAT = OS_F80;
-       { the size of a vector register for a processor     }
-       OS_VECTOR = OS_M64;
-
-       stack_pointer_reg = R_30;
-       frame_pointer_reg = R_15;
-       self_pointer_reg = R_16;
-       accumulator   = R_0;
-  {the return_result_reg, is used inside the called function to store its return
-  value when that is a scalar value otherwise a pointer to the address of the
-  result is placed inside it}
-        return_result_reg               =       accumulator;
-
-  {the function_result_reg contains the function result after a call to a scalar
-  function othewise it contains a pointer to the returned result}
-        function_result_reg     =       accumulator;
-       fpu_result_reg = R_F0;
-       global_pointer = R_29;
-       return_pointer = R_26;
-       { it is used to pass the offset to the destructor helper routine }
-       vmt_offset_reg = R_1;
-
-     { low and high of the available maximum width integer general purpose }
-     { registers                                                           }
-       LoGPReg = R_0;
-       HiGPReg = R_31;
-
-       { low and high of every possible width general purpose register (same as
-         above on most architctures apart from the 80x86)                       }
-       LoReg = R_0;
-       HiReg = R_31;
-
-       maxfpuregs = 32;
-
-       max_operands = 4;
-
-       registers_saved_on_cdecl = [R_9..R_14,R_F2..R_F9];
-
-       maxvarregs = 6;
-       varregs : Array [1..maxvarregs] of Tregister =
-                 (R_9,R_10,R_11,R_12,R_13,R_14);
-
-       maxfpuvarregs = 8;
-
-       { Registers which are defined as scratch and no need to save across
-         routine calls or in assembler blocks.
-       }
-       max_scratch_regs = 2;
-       scratch_regs : array[1..max_scratch_regs] of tregister = (R_1,R_2);
-
-{*****************************************************************************
-                               GDB Information
-*****************************************************************************}
-
-       {  Register indexes for stabs information, when some
-         parameters or variables are stored in registers.
-       }
-       stab_regindex : array[tregister] of shortint =
-          (0,
-           0,0,0,0,0,0,0,0,0,0,
-           0,0,0,0,0,0,0,0,0,0,
-           0,0,0,0,0,0,0,0,0,0,
-           0,0,
-           0,0,0,0,0,0,0,0,0,0,
-           0,0,0,0,0,0,0,0,0,0,
-           0,0,0,0,0,0,0,0,0,0,
-           0,0
-          );
-
-{*****************************************************************************
-                                   Flags
-*****************************************************************************}
-       type
-       { The Alpha doesn't have flags but some generic code depends on this type. }
-       TResFlags = (F_NO);
-
-
-       { reference record }
-       pparareference = ^tparareference;
-       tparareference = packed record
-          index       : tregister;
-          offset      : longint;
-       end;
-
-       trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
-
-       TReference = record
-         offset : aword;
-         symbol : tasmsymbol;
-         base : tregister;
-         { The index isn't used by the alpha port, but some generic code depends on it }
-         index : tregister;
-         is_immediate : boolean;
-         offsetfixup : word; {needed for inline}
-         options     : trefoptions;
-         { the boundary to which the reference is surely aligned }
-         alignment : byte;
-       end;
-       PReference = ^TReference;
-
-       TLoc=(
-              LOC_INVALID,      { added for tracking problems}
-              LOC_CONSTANT,     { constant value }
-              LOC_JUMP,         { boolean results only, jump to false or true label }
-              LOC_FLAGS,        { boolean results only, flags are set }
-              LOC_CREFERENCE,   { in memory constant value reference (cannot change) }
-              LOC_REFERENCE,    { in memory value }
-              LOC_REGISTER,     { in a processor register }
-              LOC_CREGISTER,    { Constant register which shouldn't be modified }
-              LOC_FPUREGISTER,  { FPU stack }
-              LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack }
-              LOC_SSEREGISTER,
-              LOC_CSSEREGISTER,
-              LOC_CMMREGISTER,
-              LOC_MMREGISTER
-            );
-
-      { tparamlocation describes where a parameter for a procedure is stored.
-        References are given from the caller's point of view. The usual
-        TLocation isn't used, because contains a lot of unnessary fields.
-      }
-      tparalocation = packed record
-         size : TCGSize;
-         loc  : TLoc;
-         sp_fixup : longint;
-         case TLoc of
-            LOC_REFERENCE : (reference : tparareference);
-            { segment in reference at the same place as in loc_register }
-            LOC_REGISTER,LOC_CREGISTER : (
-              case longint of
-                1 : (register,register64.reghi : tregister);
-                { overlay a register64.reglo }
-                2 : (register64.reglo : tregister);
-                { overlay a 64 Bit register type }
-                3 : (reg64 : tregister64);
-                4 : (register64 : tregister64);
-              );
-      end;
-
-      tlocation = packed record
-         loc  : TLoc;
-         size : TCGSize;
-         case TLoc of
-            LOC_CONSTANT : (
-              case longint of
-                1 : (value : AWord);
-                { can't do this, this layout depends on the host cpu. Use }
-                { lo(valueqword)/hi(valueqword) instead (JM)              }
-                { 2 : (valuelow, valuehigh:AWord);                        }
-                { overlay a complete 64 Bit value }
-                3 : (valueqword : qword);
-              );
-            LOC_CREFERENCE,
-            LOC_REFERENCE : (reference : treference);
-            { segment in reference at the same place as in loc_register }
-            LOC_REGISTER,LOC_CREGISTER : (
-              case longint of
-                1 : (register,register64.reghi,segment : tregister);
-                { overlay a register64.reglo }
-                2 : (register64.reglo : tregister);
-                { overlay a 64 Bit register type }
-                3 : (reg64 : tregister64);
-                4 : (register64 : tregister64);
-              );
-      end;
-
-{*****************************************************************************
-                                Operands
-*****************************************************************************}
-
-
-        { Types of operand }
-        toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
-
-        toper=record
-          ot  : longint;
-          case typ : toptype of
-           top_none   : ();
-           top_reg    : (reg:tregister);
-           top_ref    : (ref:preference);
-           top_const  : (val:longint);
-           top_symbol : (sym:tasmsymbol;symofs:longint);
-        end;
-
-   const
-      { Registers which must be saved when calling a routine declared as
-        cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
-        saved should be the ones as defined in the target ABI and / or GCC.
-
-        This value can be deduced from the CALLED_USED_REGISTERS array in the
-        GCC source.
-      }
-      std_saved_registers = [];
-      { Required parameter alignment when calling a routine declared as
-        stdcall and cdecl. The alignment value should be the one defined
-        by GCC or the target ABI.
-
-        The value of this constant is equal to the constant
-        PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
-      }
-      std_param_align = 8;
-
-      { offsets for the integer and floating point registers }
-      INT_REG = 0;
-      FLOAT_REG = 32;
-
-      { operator qualifiers }
-      OQ_CHOPPED_ROUNDING            = $01;  { /C }
-      OQ_ROUNDING_MODE_DYNAMIC       = $02;  { /D }
-      OQ_ROUND_TOWARD_MINUS_INFINITY = $04;  { /M }
-      OQ_INEXACT_RESULT_ENABLE        = $08; { /I }
-      OQ_SOFTWARE_COMPLETION_ENABLE  = $10;  { /S }
-      OQ_FLOATING_UNDERFLOW_ENABLE   = $20;  { /U }
-      OQ_INTEGER_OVERFLOW_ENABLE     = $40;  { /V }
-
-
-{*****************************************************************************
-                   Opcode propeties (needed for optimizer)
-*****************************************************************************}
-
-{$ifndef NOOPT}
-Type
-{What an instruction can change}
-  TInsChange = (Ch_None);
-{$endif}
-
-
-{ resets all values of ref to defaults }
-procedure reset_reference(var ref : treference);
-{ set mostly used values of a new reference }
-function new_reference(base : tregister;offset : longint) : preference;
-function newreference(const r : treference) : preference;
-procedure disposereference(var r : preference);
-
-function reg2str(r : tregister) : string;
-
-{*****************************************************************************
-                                  Init/Done
-*****************************************************************************}
-
-  procedure InitCpu;
-  procedure DoneCpu;
-
-implementation
-
-uses
-   verbose;
-
-function reg2str(r : tregister) : string;
-
-  begin
-     if r in [R_0..R_31] then
-       reg2str:='R'+tostr(longint(r)-longint(R_0))
-     else if r in [R_F0..R_F31] then
-       reg2str:='F'+tostr(longint(r)-longint(R_F0))
-     else internalerror(38991);
-  end;
-
-procedure reset_reference(var ref : treference);
-begin
-  FillChar(ref,sizeof(treference),0);
-end;
-
-
-function new_reference(base : tregister;offset : longint) : preference;
-var
-  r : preference;
-begin
-  new(r);
-  FillChar(r^,sizeof(treference),0);
-  r^.offset:=offset;
-  r^.alignment:=8;
-  new_reference:=r;
-end;
-
-function newreference(const r : treference) : preference;
-
-var
-   p : preference;
-begin
-   new(p);
-   p^:=r;
-   newreference:=p;
-end;
-
-procedure disposereference(var r : preference);
-
-begin
-  dispose(r);
-  r:=Nil;
-end;
-
-{*****************************************************************************
-                                  Init/Done
-*****************************************************************************}
-
-  procedure InitCpu;
-    begin
-    end;
-
-  procedure DoneCpu;
-    begin
-    end;
-
-end.

+ 0 - 91
compiler/alpha/cpuinfo.pas

@@ -1,91 +0,0 @@
-{
-    This file is part of the Free Pascal run time library.
-    Copyright (c) 1998-2000 by the Free Pascal development team
-
-    Basic Processor information about the Alpha
-
-    See the file COPYING.FPC, included in this distribution,
-    for details about the copyright.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- **********************************************************************}
-{
-  Basic Processor information about the Alpha
-}
-Unit CPUInfo;
-
-{$i fpcdefs.inc}
-
-Interface
-
-uses
- globtype;
-
-Type
-   { Natural integer register type and size for the target machine }
-{$ifdef FPC}
-   AWord = Qword;
-{$else FPC}
-   AWord = Longint;
-{$endif FPC}
-   PAWord = ^AWord;
-
-   { This must be an ordinal type with the same size as a pointer
-     Note: Must be unsigned! Otherwise, ugly code like
-     pointer(-1) will result in a pointer with the value
-     $fffffffffffffff on a 32bit machine if the compiler uses
-     int64 constants internally (JM)                              }
-   TConstPtrUInt = qword;
-
-   bestreal = extended;
-{$if FPC_FULLVERSION>20700}
-   bestrealrec = TExtended80Rec;
-{$endif FPC_FULLVERSION>20700}
-   ts32real = single;
-   ts64real = double;
-   ts80real = extended;
-   ts64comp = extended;
-
-   pbestreal=^bestreal;
-
-   { possible supported processors for this target }
-   tcputype =
-      (cpu_none,
-       ClassEV7,
-       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                           }
-   aint_size  = 8;
-   {# 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';
-
-Implementation
-
-end.

+ 0 - 56
compiler/alpha/cpunode.pas

@@ -1,56 +0,0 @@
-{
-    Copyright (c) 2000-2002 by Florian Klaempfl
-
-    Imports the Alpha code generator
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-{
-  This unit imports the Alpha code generator.
-}
-unit cpunode;
-
-{$i fpcdefs.inc}
-
-  interface
-
-  implementation
-
-    uses
-       { generic nodes }
-       ncgbas,ncgld,ncgflw,ncgcnv,ncgmem,ncgcon,ncgcal,ncgset,ncginl,
-       { to be able to only parts of the generic code,
-         the processor specific nodes must be included
-         after the generic one (FK)
-       }
-//       naxpadd,
-//       naxpcal,
-//       naxpcon,
-//       naxpflw,
-//       naxpmem,
-//       naxpset,
-//       naxpinl,
-//       nppcopt,
-       { this not really a node }
-//       naxpobj,
-//       naxpmat,
-//       naxpcnv,
-         { symtable }
-         symcpu
-       ;
-
-end.

+ 0 - 270
compiler/alpha/cpupara.pas

@@ -1,270 +0,0 @@
-{
-    Copyright (c) 2002 by Florian Klaempfl
-
-    Alpha specific calling conventions
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
-}
-{ Alpha specific calling conventions are handled by this unit
-}
-unit cpupara;
-
-{$i fpcdefs.inc}
-
-  interface
-
-    uses
-       cpubase,
-       symconst,symbase,symtype,symdef,paramgr;
-
-    type
-       tcpuparamanager = class(tparamanager)
-          procedure create_param_loc_info(p : tabstractprocdef);override;
-          function getfuncretparaloc(p : tabstractprocdef) : tparalocation;override;
-       end;
-
-  implementation
-
-    uses
-       verbose,
-       globtype,
-       cpuinfo,cginfo,cgbase,
-       defbase;
-
-    function getparaloc(p : tdef) : tloc;
-
-      begin
-         { Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER
-           if push_addr_param for the def is true
-         }
-         case p.typ of
-            orddef:
-              getparaloc:=LOC_REGISTER;
-            floatdef:
-              getparaloc:=LOC_FPUREGISTER;
-            enumdef:
-              getparaloc:=LOC_REGISTER;
-            pointerdef:
-              getparaloc:=LOC_REGISTER;
-            formaldef:
-              getparaloc:=LOC_REGISTER;
-            classrefdef:
-              getparaloc:=LOC_REGISTER;
-            recorddef:
-              getparaloc:=LOC_REFERENCE;
-            objectdef:
-              if is_object(p) then
-                getparaloc:=LOC_REFERENCE
-              else
-                getparaloc:=LOC_REGISTER;
-            stringdef:
-              if is_shortstring(p) or is_longstring(p) then
-                getparaloc:=LOC_REFERENCE
-              else
-                getparaloc:=LOC_REGISTER;
-            procvardef:
-              if (po_methodpointer in tprocvardef(p).procoptions) then
-                getparaloc:=LOC_REFERENCE
-              else
-                getparaloc:=LOC_REGISTER;
-            filedef:
-              getparaloc:=LOC_REGISTER;
-            arraydef:
-              getparaloc:=LOC_REFERENCE;
-            setdef:
-              if is_smallset(p) then
-                getparaloc:=LOC_REGISTER
-              else
-                getparaloc:=LOC_REFERENCE;
-            variantdef:
-              getparaloc:=LOC_REFERENCE;
-            { avoid problems with errornous definitions }
-            errordef:
-              getparaloc:=LOC_REGISTER;
-            else
-              internalerror(2002071001);
-         end;
-      end;
-
-    procedure tcpuparamanager.create_param_loc_info(p : tabstractprocdef);
-
-      var
-         nextintreg,nextfloatreg,nextmmreg : tregister;
-         stack_offset : aword;
-         hp : tparaitem;
-         loc : tloc;
-         is_64bit: boolean;
-
-      begin
-         nextintreg:=R_3;
-         nextfloatreg:=R_F1;
-         // nextmmreg:=R_M1;
-         stack_offset:=0;
-         { pointer for structured results ? }
-         if not is_void(p.returndef) then
-           begin
-              if not(ret_in_reg(p.returndef)) then
-                inc(nextintreg);
-           end;
-
-         { frame pointer for nested procedures? }
-         { inc(nextintreg);                     }
-         { constructor? }
-         { destructor? }
-         hp:=tparaitem(p.para.last);
-         while assigned(hp) do
-           begin
-              loc:=getparaloc(hp.paratype.def);
-              hp.paraloc.sp_fixup:=0;
-              case loc of
-                 LOC_REGISTER:
-                   begin
-                      hp.paraloc.size := def_cgsize(hp.paratype.def);
-                      { for things like formaldef }
-                      if hp.paraloc.size = OS_NO then
-                        hp.paraloc.size := OS_ADDR;
-                      is_64bit := hp.paraloc.size in [OS_64,OS_S64];
-                      if nextintreg<=tregister(ord(R_10)-ord(is_64bit))  then
-                        begin
-                           hp.paraloc.loc:=LOC_REGISTER;
-                           hp.paraloc.register64.reglo:=nextintreg;
-                           inc(nextintreg);
-                           if is_64bit then
-                             begin
-                               hp.paraloc.register64.reghi:=nextintreg;
-                               inc(nextintreg);
-                             end;
-                        end
-                      else
-                         begin
-                            nextintreg := R_11;
-                            hp.paraloc.loc:=LOC_REFERENCE;
-                            hp.paraloc.reference.index:=stack_pointer_reg;
-                            hp.paraloc.reference.offset:=stack_offset;
-                            if not is_64bit then
-                              inc(stack_offset,4)
-                            else
-                              inc(stack_offset,8);
-                        end;
-                   end;
-                 LOC_FPUREGISTER:
-                   begin
-                      if hp.paratyp in [vs_var,vs_out] then
-                        begin
-                            if nextintreg<=R_10 then
-                             begin
-                                hp.paraloc.size:=OS_ADDR;
-                                hp.paraloc.loc:=LOC_REGISTER;
-                                hp.paraloc.register:=nextintreg;
-                                inc(nextintreg);
-                             end
-                           else
-                              begin
-                                 {!!!!!!!}
-                                 hp.paraloc.size:=def_cgsize(hp.paratype.def);
-                                 internalerror(2002071006);
-                             end;
-                        end
-                      else if nextfloatreg<=R_F10 then
-                        begin
-                           hp.paraloc.size:=def_cgsize(hp.paratype.def);
-                           hp.paraloc.loc:=LOC_FPUREGISTER;
-                           hp.paraloc.register:=nextfloatreg;
-                           inc(nextfloatreg);
-                        end
-                      else
-                         begin
-                            {!!!!!!!}
-                             hp.paraloc.size:=def_cgsize(hp.paratype.def);
-                            internalerror(2002071004);
-                        end;
-                   end;
-                 LOC_REFERENCE:
-                   begin
-                      hp.paraloc.size:=OS_ADDR;
-                      if push_addr_param(hp.paratype.def,p.proccalloption in [pocall_cdecl,pocall_cppdecl]) or (hp.paratyp in [vs_var,vs_out]) then
-                        begin
-                           if nextintreg<=R_10 then
-                             begin
-                                hp.paraloc.loc:=LOC_REGISTER;
-                                hp.paraloc.register:=nextintreg;
-                                inc(nextintreg);
-                             end
-                           else
-                              begin
-                                 hp.paraloc.loc:=LOC_REFERENCE;
-                                 hp.paraloc.reference.index:=stack_pointer_reg;
-                                 hp.paraloc.reference.offset:=stack_offset;
-                                 inc(stack_offset,4);
-                             end;
-                        end
-                      else
-                        begin
-                           hp.paraloc.loc:=LOC_REFERENCE;
-                           hp.paraloc.reference.index:=stack_pointer_reg;
-                           hp.paraloc.reference.offset:=stack_offset;
-                           inc(stack_offset,hp.paratype.def.size);
-                        end;
-                   end;
-                 else
-                   internalerror(2002071002);
-              end;
-              hp:=tparaitem(hp.previous);
-           end;
-      end;
-
-    function tcpuparamanager.getfuncretparaloc(p : tabstractprocdef) : tparalocation;
-      begin
-         case p.returndef.typ of
-            orddef,
-            enumdef:
-              begin
-                getfuncretparaloc.loc:=LOC_REGISTER;
-                getfuncretparaloc.register:=R_3;
-                getfuncretparaloc.size:=def_cgsize(p.returndef);
-                if getfuncretparaloc.size in [OS_S64,OS_64] then
-                  getfuncretparaloc.register64.reghi:=R_4;
-              end;
-            floatdef:
-              begin
-                getfuncretparaloc.loc:=LOC_FPUREGISTER;
-                getfuncretparaloc.register:=R_F1;
-                getfuncretparaloc.size:=def_cgsize(p.returndef);
-              end;
-            pointerdef,
-            formaldef,
-            classrefdef,
-            recorddef,
-            objectdef,
-            stringdef,
-            procvardef,
-            filedef,
-            arraydef,
-            errordef:
-              begin
-                getfuncretparaloc.loc:=LOC_REGISTER;
-                getfuncretparaloc.register:=R_3;
-                getfuncretparaloc.size:=OS_ADDR;
-              end;
-            else
-              internalerror(2002090903);
-        end;
-      end;
-
-
-begin
-   paramanager:=tcpuparamanager.create;
-end.

+ 0 - 43
compiler/alpha/cpupi.pas

@@ -1,43 +0,0 @@
-{
-    Copyright (c) 2002 by Florian Klaempfl
-
-    This unit contains the CPU specific part of tprocinfo
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-{
-  This unit contains the CPU specific part of tprocinfo.
-}
-unit cpupi;
-
-{$i fpcdefs.inc}
-
-  interface
-
-    uses
-       cgbase;
-
-    type
-       talphaprocinfo = class(tprocinfo)
-       end;
-
-
-  implementation
-
-begin
-   cprocinfo:=talphaprocinfo;
-end.

+ 0 - 51
compiler/alpha/cputarg.pas

@@ -1,51 +0,0 @@
-{
-    Copyright (c) 2001-2002 by Peter Vreman
-
-    Includes the powerpc dependent target units
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit cputarg;
-
-{$i fpcdefs.inc}
-
-interface
-
-
-implementation
-
-    uses
-      systems { prevent a syntax error when nothing is included }
-
-{**************************************
-             Targets
-**************************************}
-
-    {$ifndef NOTARGETLINUX}
-      ,t_linux
-    {$endif}
-
-{**************************************
-             Assemblers
-**************************************}
-
-    {$ifndef NOAGAXPGAS}
-      ,agaxpgas
-    {$endif}
-      ;
-
-end.

+ 0 - 0
compiler/alpha/radirect.pas


+ 0 - 65
compiler/alpha/rasm.pas

@@ -1,65 +0,0 @@
-{
-    Copyright (c) 1998-2002 by The Free Pascal Team
-
-    This unit does the parsing process for the inline assembler
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-{
-  This unit does the parsing process for the inline assembler.
-}
-Unit Rasm;
-
-{$i fpcdefs.inc}
-
-Interface
-
-uses
-  node;
-
-   {
-     This routine is called to parse the instructions in assembler
-     blocks. It returns a complete list of directive and instructions
-   }
-   function assemble: tnode;
-
-
-Implementation
-
-    uses
-       { common }
-       cutils,cclasses,
-       { global }
-       globtype,globals,verbose,
-       systems,
-       { aasm }
-       cpubase,aasmbase,aasmtai,aasmdata,aasmcpu,
-       { symtable }
-       symconst,symbase,symtype,symsym,symtable,
-       { pass 1 }
-       nbas,
-       { parser }
-       scanner
-       // ,rautils
-       ;
-
-    function assemble : tnode;
-     begin
-     end;
-
-Begin
-end.

+ 0 - 69
compiler/alpha/rgcpu.pas

@@ -1,69 +0,0 @@
-{
-    Copyright (c) 1998-2002 by Florian Klaempfl
-
-    This unit implements the powerpc specific class for the register
-    allocator
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-
-unit rgcpu;
-
-{$i fpcdefs.inc}
-
-  interface
-
-     uses
-       aasmbase,aasmtai,aasmdata,
-       cpubase,
-       rgobj;
-
-     type
-       trgcpu = class(trgobj)
-         function getcpuregisterint(list: TAsmList; reg: tregister): tregister; override;
-         procedure ungetregisterint(list: TAsmList; reg: tregister); override;
-       end;
-
-  implementation
-
-    uses
-      cgobj;
-
-    function trgcpu.getcpuregisterint(list: TAsmList; reg: tregister): tregister;
-
-      begin
-        if reg = R_0 then
-          begin
-            cg.a_reg_alloc(list,reg);
-            result := reg;
-          end
-        else result := inherited getcpuregisterint(list,reg);
-      end;
-
-
-    procedure trgcpu.ungetregisterint(list: TAsmList; reg: tregister);
-
-      begin
-        if reg = R_0 then
-          cg.a_reg_dealloc(list,reg)
-        else
-          inherited ungetregisterint(list,reg);
-      end;
-
-initialization
-  rg := trgcpu.create;
-end.

+ 0 - 211
compiler/alpha/symcpu.pas

@@ -1,211 +0,0 @@
-{
-    Copyright (c) 2014 by Florian Klaempfl
-
-    Symbol table overrides for Alpha
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit symcpu;
-
-{$i fpcdefs.inc}
-
-interface
-
-uses
-  symtype,symdef,symsym;
-
-type
-  { defs }
-  tcpufiledef = class(tfiledef)
-  end;
-  tcpufiledefclass = class of tcpufiledef;
-
-  tcpuvariantdef = class(tvariantdef)
-  end;
-  tcpuvariantdefclass = class of tcpuvariantdef;
-
-  tcpuformaldef = class(tformaldef)
-  end;
-  tcpuformaldefclass = class of tcpuformaldef;
-
-  tcpuforwarddef = class(tforwarddef)
-  end;
-  tcpuforwarddefclass = class of tcpuforwarddef;
-
-  tcpuundefineddef = class(tundefineddef)
-  end;
-  tcpuundefineddefclass = class of tcpuundefineddef;
-
-  tcpuerrordef = class(terrordef)
-  end;
-  tcpuerrordefclass = class of tcpuerrordef;
-
-  tcpupointerdef = class(tpointerdef)
-  end;
-  tcpupointerdefclass = class of tcpupointerdef;
-
-  tcpurecorddef = class(trecorddef)
-  end;
-  tcpurecorddefclass = class of tcpurecorddef;
-
-  tcpuimplementedinterface = class(timplementedinterface)
-  end;
-  tcpuimplementedinterfaceclass = class of tcpuimplementedinterface;
-
-  tcpuobjectdef = class(tobjectdef)
-  end;
-  tcpuobjectdefclass = class of tcpuobjectdef;
-
-  tcpuclassrefdef = class(tclassrefdef)
-  end;
-  tcpuclassrefdefclass = class of tcpuclassrefdef;
-
-  tcpuarraydef = class(tarraydef)
-  end;
-  tcpuarraydefclass = class of tcpuarraydef;
-
-  tcpuorddef = class(torddef)
-  end;
-  tcpuorddefclass = class of tcpuorddef;
-
-  tcpufloatdef = class(tfloatdef)
-  end;
-  tcpufloatdefclass = class of tcpufloatdef;
-
-  tcpuprocvardef = class(tprocvardef)
-  end;
-  tcpuprocvardefclass = class of tcpuprocvardef;
-
-  tcpuprocdef = class(tprocdef)
-  end;
-  tcpuprocdefclass = class of tcpuprocdef;
-
-  tcpustringdef = class(tstringdef)
-  end;
-  tcpustringdefclass = class of tcpustringdef;
-
-  tcpuenumdef = class(tenumdef)
-  end;
-  tcpuenumdefclass = class of tcpuenumdef;
-
-  tcpusetdef = class(tsetdef)
-  end;
-  tcpusetdefclass = class of tcpusetdef;
-
-  { syms }
-  tcpulabelsym = class(tlabelsym)
-  end;
-  tcpulabelsymclass = class of tcpulabelsym;
-
-  tcpuunitsym = class(tunitsym)
-  end;
-  tcpuunitsymclass = class of tcpuunitsym;
-
-  tcpunamespacesym = class(tnamespacesym)
-  end;
-  tcpunamespacesymclass = class of tcpunamespacesym;
-
-  tcpuprocsym = class(tprocsym)
-  end;
-  tcpuprocsymclass = class of tcpuprocsym;
-
-  tcputypesym = class(ttypesym)
-  end;
-  tcpuypesymclass = class of tcputypesym;
-
-  tcpufieldvarsym = class(tfieldvarsym)
-  end;
-  tcpufieldvarsymclass = class of tcpufieldvarsym;
-
-  tcpulocalvarsym = class(tlocalvarsym)
-  end;
-  tcpulocalvarsymclass = class of tcpulocalvarsym;
-
-  tcpuparavarsym = class(tparavarsym)
-  end;
-  tcpuparavarsymclass = class of tcpuparavarsym;
-
-  tcpustaticvarsym = class(tstaticvarsym)
-  end;
-  tcpustaticvarsymclass = class of tcpustaticvarsym;
-
-  tcpuabsolutevarsym = class(tabsolutevarsym)
-  end;
-  tcpuabsolutevarsymclass = class of tcpuabsolutevarsym;
-
-  tcpupropertysym = class(tpropertysym)
-  end;
-  tcpupropertysymclass = class of tcpupropertysym;
-
-  tcpuconstsym = class(tconstsym)
-  end;
-  tcpuconstsymclass = class of tcpuconstsym;
-
-  tcpuenumsym = class(tenumsym)
-  end;
-  tcpuenumsymclass = class of tcpuenumsym;
-
-  tcpusyssym = class(tsyssym)
-  end;
-  tcpusyssymclass = class of tcpusyssym;
-
-
-const
-  pbestrealtype : ^tdef = @s64floattype;
-
-
-implementation
-
-begin
-  { used tdef classes }
-  cfiledef:=tcpufiledef;
-  cvariantdef:=tcpuvariantdef;
-  cformaldef:=tcpuformaldef;
-  cforwarddef:=tcpuforwarddef;
-  cundefineddef:=tcpuundefineddef;
-  cerrordef:=tcpuerrordef;
-  cpointerdef:=tcpupointerdef;
-  crecorddef:=tcpurecorddef;
-  cimplementedinterface:=tcpuimplementedinterface;
-  cobjectdef:=tcpuobjectdef;
-  cclassrefdef:=tcpuclassrefdef;
-  carraydef:=tcpuarraydef;
-  corddef:=tcpuorddef;
-  cfloatdef:=tcpufloatdef;
-  cprocvardef:=tcpuprocvardef;
-  cprocdef:=tcpuprocdef;
-  cstringdef:=tcpustringdef;
-  cenumdef:=tcpuenumdef;
-  csetdef:=tcpusetdef;
-
-  { used tsym classes }
-  clabelsym:=tcpulabelsym;
-  cunitsym:=tcpuunitsym;
-  cnamespacesym:=tcpunamespacesym;
-  cprocsym:=tcpuprocsym;
-  ctypesym:=tcputypesym;
-  cfieldvarsym:=tcpufieldvarsym;
-  clocalvarsym:=tcpulocalvarsym;
-  cparavarsym:=tcpuparavarsym;
-  cstaticvarsym:=tcpustaticvarsym;
-  cabsolutevarsym:=tcpuabsolutevarsym;
-  cpropertysym:=tcpupropertysym;
-  cconstsym:=tcpuconstsym;
-  cenumsym:=tcpuenumsym;
-  csyssym:=tcpusyssym;
-end.
-

+ 0 - 42
compiler/alpha/tgcpu.pas

@@ -1,42 +0,0 @@
-{
-    Copyright (C) 1998-2000 by Florian Klaempfl
-
-    This unit handles the temporary variables stuff for Alpha
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-{
-  This unit handles the temporary variables stuff for Alpha.
-}
-unit tgcpu;
-
-{$i fpcdefs.inc}
-
-  interface
-
-    uses
-       tgobj;
-
-    type
-       ttgalpha = class(ttgobj)
-       end;
-
-implementation
-
-begin
-  tg:=ttgalpha.create;
-end.

+ 0 - 8
compiler/aopt.pas

@@ -279,14 +279,6 @@ Unit aopt;
                 if pass = 0 then
                 if pass = 0 then
                   PeepHoleOptPass1;
                   PeepHoleOptPass1;
               end;
               end;
-            If (cs_opt_asmcse in current_settings.optimizerswitches) Then
-              Begin
-//                DFA:=TAOptDFACpu.Create(AsmL,BlockStart,BlockEnd,LabelInfo);
-                { data flow analyzer }
-//                DFA.DoDFA;
-                { common subexpression elimination }
-      {          CSE;}
-              End;
             { more peephole optimizations }
             { more peephole optimizations }
             if (cs_opt_peephole in current_settings.optimizerswitches) then
             if (cs_opt_peephole in current_settings.optimizerswitches) then
               begin
               begin

+ 4 - 0
compiler/aoptobj.pas

@@ -1178,7 +1178,11 @@ Unit AoptObj;
 
 
     function IsJumpToLabel(hp: taicpu): boolean;
     function IsJumpToLabel(hp: taicpu): boolean;
       begin
       begin
+{$if defined(avr)}
+        result:=(hp.opcode in aopt_uncondjmp) and
+{$else avr}
         result:=(hp.opcode=aopt_uncondjmp) and
         result:=(hp.opcode=aopt_uncondjmp) and
+{$endif avr}
 {$if defined(arm) or defined(aarch64)}
 {$if defined(arm) or defined(aarch64)}
           (hp.condition=c_None) and
           (hp.condition=c_None) and
 {$endif arm or aarch64}
 {$endif arm or aarch64}

+ 8 - 2
compiler/arm/aasmcpu.pas

@@ -744,7 +744,8 @@ implementation
           A_SXTB16,A_UXTB16,
           A_SXTB16,A_UXTB16,
           A_UXTB,A_UXTH,A_SXTB,A_SXTH,
           A_UXTB,A_UXTH,A_SXTB,A_SXTH,
           A_NEG,
           A_NEG,
-          A_VABS,A_VADD,A_VCVT,A_VDIV,A_VLDR,A_VMOV,A_VMUL,A_VNEG,A_VSQRT,A_VSUB:
+          A_VABS,A_VADD,A_VCVT,A_VDIV,A_VLDR,A_VMOV,A_VMUL,A_VNEG,A_VSQRT,A_VSUB,
+          A_MRS,A_MSR:
             if opnr=0 then
             if opnr=0 then
               result:=operand_write
               result:=operand_write
             else
             else
@@ -2684,8 +2685,13 @@ implementation
         end;
         end;
 
 
       function getcoprocreg(reg: tregister): byte;
       function getcoprocreg(reg: tregister): byte;
+        var
+          tmpr: tregister;
         begin
         begin
-          result:=getsupreg(reg)-getsupreg(NR_CR0);
+          { FIXME: temp variable r is needed here to avoid Internal error 20060521 }
+          {        while compiling the compiler. }
+          tmpr:=NR_CR0;
+          result:=getsupreg(reg)-getsupreg(tmpr);
         end;
         end;
 
 
       function getmmreg(reg: tregister): byte;
       function getmmreg(reg: tregister): byte;

+ 32 - 0
compiler/arm/cpuinfo.pas

@@ -250,6 +250,17 @@ Type
       ct_stm32f107rc,
       ct_stm32f107rc,
       ct_stm32f107vb,
       ct_stm32f107vb,
       ct_stm32f107vc,
       ct_stm32f107vc,
+      
+      ct_stm32f429xe, // 512K flash
+      ct_stm32f429xg, // 1M flash
+      ct_stm32f429xi, // 2M flash
+
+      ct_stm32f745xe,
+      ct_stm32f745xg,
+      ct_stm32f746xe,
+      ct_stm32f746xg,
+      ct_stm32f756xe,
+      ct_stm32f756xg,
 
 
       { TI - Fury Class - 64 K Flash, 16 K SRAM Devices }
       { TI - Fury Class - 64 K Flash, 16 K SRAM Devices }
       ct_lm3s1110,
       ct_lm3s1110,
@@ -341,6 +352,11 @@ Type
       { Allwinner }
       { Allwinner }
       ct_allwinner_a20,
       ct_allwinner_a20,
 
 
+      { Freescale }
+      ct_mk20dx128xxx7,
+      ct_mk20dx256xxx7,
+      ct_mk20dx64xxx7,
+
       // generic Thumb2 target
       // generic Thumb2 target
       ct_thumb2bare
       ct_thumb2bare
      );
      );
@@ -621,6 +637,17 @@ Const
       (controllertypestr:'STM32F107RC';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
       (controllertypestr:'STM32F107RC';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
       (controllertypestr:'STM32F107VB';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
       (controllertypestr:'STM32F107VB';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
       (controllertypestr:'STM32F107VC';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
       (controllertypestr:'STM32F107VC';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      
+      (controllertypestr:'STM32F429XE';     controllerunitstr:'STM32F429';        flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429XG';     controllerunitstr:'STM32F429';        flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429XI';     controllerunitstr:'STM32F429';        flashbase:$08000000; flashsize:$00200000; srambase:$20000000; sramsize:$00030000),
+
+      (controllertypestr:'STM32F745XE';     controllerunitstr:'STM32F745';        flashbase:$08000000; flashsize:$00080000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F745XG';     controllerunitstr:'STM32F745';        flashbase:$08000000; flashsize:$00100000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F746XE';     controllerunitstr:'STM32F746';        flashbase:$08000000; flashsize:$00080000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F746XG';     controllerunitstr:'STM32F746';        flashbase:$08000000; flashsize:$00100000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F756XE';     controllerunitstr:'STM32F756';        flashbase:$08000000; flashsize:$00080000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F756XG';     controllerunitstr:'STM32F756';        flashbase:$08000000; flashsize:$00100000; srambase:$20010000; sramsize:$00040000),
 
 
       (controllertypestr:'LM3S1110';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
       (controllertypestr:'LM3S1110';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
       (controllertypestr:'LM3S1133';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
       (controllertypestr:'LM3S1133';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
@@ -710,6 +737,11 @@ Const
       { Allwinner }
       { Allwinner }
       (controllertypestr:'ALLWINNER_A20'; controllerunitstr:'ALLWINNER_A20';     flashbase:$00000000; flashsize:$00000000;  srambase:$40000000; sramsize:$80000000),
       (controllertypestr:'ALLWINNER_A20'; controllerunitstr:'ALLWINNER_A20';     flashbase:$00000000; flashsize:$00000000;  srambase:$40000000; sramsize:$80000000),
 
 
+      { Freescale }
+      (controllertypestr:'MK20DX128XXX7'; controllerunitstr:'MK20D7'; flashbase:$00000000; flashsize:$00020000; srambase:$20000000; sramsize:$00004000),
+      (controllertypestr:'MK20DX256XXX7'; controllerunitstr:'MK20D7'; flashbase:$00000000; flashsize:$00040000; srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'MK20DX64XXX7';  controllerunitstr:'MK20D7'; flashbase:$00000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
+
       { Bare bones }
       { Bare bones }
       (controllertypestr:'THUMB2_BARE';	controllerunitstr:'THUMB2_BARE';	flashbase:$00000000;	flashsize:$00002000;	srambase:$20000000;	sramsize:$00000400)
       (controllertypestr:'THUMB2_BARE';	controllerunitstr:'THUMB2_BARE';	flashbase:$00000000;	flashsize:$00002000;	srambase:$20000000;	sramsize:$00000400)
     );
     );

+ 9 - 6
compiler/arm/cpupara.pas

@@ -131,7 +131,7 @@ unit cpupara;
         psym:=tparavarsym(pd.paras[nr-1]);
         psym:=tparavarsym(pd.paras[nr-1]);
         pdef:=psym.vardef;
         pdef:=psym.vardef;
         if push_addr_param(psym.varspez,pdef,pd.proccalloption) then
         if push_addr_param(psym.varspez,pdef,pd.proccalloption) then
-          pdef:=getpointerdef(pdef);
+          pdef:=cpointerdef.getreusable(pdef);
         cgpara.reset;
         cgpara.reset;
         cgpara.size:=def_cgsize(pdef);
         cgpara.size:=def_cgsize(pdef);
         cgpara.intsize:=tcgsize2size[cgpara.size];
         cgpara.intsize:=tcgsize2size[cgpara.size];
@@ -202,7 +202,10 @@ unit cpupara;
             filedef:
             filedef:
               getparaloc:=LOC_REGISTER;
               getparaloc:=LOC_REGISTER;
             arraydef:
             arraydef:
-              getparaloc:=LOC_REFERENCE;
+              if is_dynamic_array(p) then
+                getparaloc:=LOC_REGISTER
+              else
+                getparaloc:=LOC_REFERENCE;
             setdef:
             setdef:
               if is_smallset(p) then
               if is_smallset(p) then
                 getparaloc:=LOC_REGISTER
                 getparaloc:=LOC_REGISTER
@@ -415,7 +418,7 @@ unit cpupara;
 
 
             if push_addr_param(hp.varspez,paradef,p.proccalloption) then
             if push_addr_param(hp.varspez,paradef,p.proccalloption) then
               begin
               begin
-                paradef:=getpointerdef(paradef);
+                paradef:=cpointerdef.getreusable(paradef);
                 loc:=LOC_REGISTER;
                 loc:=LOC_REGISTER;
                 paracgsize := OS_ADDR;
                 paracgsize := OS_ADDR;
                 paralen := tcgsize2size[OS_ADDR];
                 paralen := tcgsize2size[OS_ADDR];
@@ -509,7 +512,7 @@ unit cpupara;
                             { LOC_REFERENCE always contains everything that's left }
                             { LOC_REFERENCE always contains everything that's left }
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.size:=int_cgsize(paralen);
                             paraloc^.size:=int_cgsize(paralen);
-                            paraloc^.def:=getarraydef(u8inttype,paralen);
+                            paraloc^.def:=carraydef.getreusable(u8inttype,paralen);
                             if (side=callerside) then
                             if (side=callerside) then
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                             paraloc^.reference.offset:=stack_offset;
                             paraloc^.reference.offset:=stack_offset;
@@ -583,7 +586,7 @@ unit cpupara;
                             { LOC_REFERENCE always contains everything that's left }
                             { LOC_REFERENCE always contains everything that's left }
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.size:=int_cgsize(paralen);
                             paraloc^.size:=int_cgsize(paralen);
-                            paraloc^.def:=getarraydef(u8inttype,paralen);
+                            paraloc^.def:=carraydef.getreusable(u8inttype,paralen);
                             if (side=callerside) then
                             if (side=callerside) then
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                             paraloc^.reference.offset:=stack_offset;
                             paraloc^.reference.offset:=stack_offset;
@@ -596,7 +599,7 @@ unit cpupara;
                         if push_addr_param(hp.varspez,paradef,p.proccalloption) then
                         if push_addr_param(hp.varspez,paradef,p.proccalloption) then
                           begin
                           begin
                             paraloc^.size:=OS_ADDR;
                             paraloc^.size:=OS_ADDR;
-                            paraloc^.def:=getpointerdef(paradef);
+                            paraloc^.def:=cpointerdef.getreusable(paradef);
                             assignintreg
                             assignintreg
                           end
                           end
                         else
                         else

+ 4 - 0
compiler/arm/narmcnv.pas

@@ -314,6 +314,10 @@ implementation
 
 
          { Load left node into flag F_NE/F_E }
          { Load left node into flag F_NE/F_E }
          resflags:=F_NE;
          resflags:=F_NE;
+
+         if (left.location.loc in [LOC_SUBSETREG,LOC_CSUBSETREG,LOC_SUBSETREF,LOC_CSUBSETREF]) then
+           hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
+
          case left.location.loc of
          case left.location.loc of
             LOC_CREFERENCE,
             LOC_CREFERENCE,
             LOC_REFERENCE :
             LOC_REFERENCE :

+ 1 - 0
compiler/arm/narmset.pas

@@ -242,6 +242,7 @@ implementation
             { do not use BX here to avoid switching into arm mode }
             { do not use BX here to avoid switching into arm mode }
             current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_MOV, NR_PC, tmpreg));
             current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_MOV, NR_PC, tmpreg));
 
 
+            current_asmdata.CurrAsmList.Concat(tai_align.Create(4));                
             cg.a_label(current_asmdata.CurrAsmList,tablelabel);
             cg.a_label(current_asmdata.CurrAsmList,tablelabel);
             { generate jump table }
             { generate jump table }
             last:=min_;
             last:=min_;

+ 5 - 0
compiler/arm/symcpu.pas

@@ -119,6 +119,10 @@ type
   end;
   end;
   tcpuunitsymclass = class of tcpuunitsym;
   tcpuunitsymclass = class of tcpuunitsym;
 
 
+  tcpuprogramparasym = class(tprogramparasym)
+  end;
+  tcpuprogramparasymclass = class(tprogramparasym);
+
   tcpunamespacesym = class(tnamespacesym)
   tcpunamespacesym = class(tnamespacesym)
   end;
   end;
   tcpunamespacesymclass = class of tcpunamespacesym;
   tcpunamespacesymclass = class of tcpunamespacesym;
@@ -199,6 +203,7 @@ begin
   { used tsym classes }
   { used tsym classes }
   clabelsym:=tcpulabelsym;
   clabelsym:=tcpulabelsym;
   cunitsym:=tcpuunitsym;
   cunitsym:=tcpuunitsym;
+  cprogramparasym:=tcpuprogramparasym;
   cnamespacesym:=tcpunamespacesym;
   cnamespacesym:=tcpunamespacesym;
   cprocsym:=tcpuprocsym;
   cprocsym:=tcpuprocsym;
   ctypesym:=tcputypesym;
   ctypesym:=tcputypesym;

+ 24 - 9
compiler/assemble.pas

@@ -33,7 +33,7 @@ interface
 
 
     uses
     uses
       SysUtils,
       SysUtils,
-      systems,globtype,globals,aasmbase,aasmtai,aasmdata,ogbase,finput;
+      systems,globtype,globals,aasmbase,aasmtai,aasmdata,ogbase,owbase,finput;
 
 
     const
     const
        { maximum of aasmoutput lists there will be }
        { maximum of aasmoutput lists there will be }
@@ -147,6 +147,7 @@ interface
       TInternalAssembler=class(TAssembler)
       TInternalAssembler=class(TAssembler)
       private
       private
         FCObjOutput : TObjOutputclass;
         FCObjOutput : TObjOutputclass;
+        FCInternalAr : TObjectWriterClass;
         { the aasmoutput lists that need to be processed }
         { the aasmoutput lists that need to be processed }
         lists        : byte;
         lists        : byte;
         list         : array[1..maxoutputlists] of TAsmList;
         list         : array[1..maxoutputlists] of TAsmList;
@@ -165,6 +166,7 @@ interface
         ObjData   : TObjData;
         ObjData   : TObjData;
         ObjOutput : tObjOutput;
         ObjOutput : tObjOutput;
         property CObjOutput:TObjOutputclass read FCObjOutput write FCObjOutput;
         property CObjOutput:TObjOutputclass read FCObjOutput write FCObjOutput;
+        property CInternalAr : TObjectWriterClass read FCInternalAr write FCInternalAr;
       public
       public
         constructor create(smart:boolean);override;
         constructor create(smart:boolean);override;
         destructor  destroy;override;
         destructor  destroy;override;
@@ -194,7 +196,7 @@ Implementation
       cpuinfo,
       cpuinfo,
 {$endif m68k or arm}
 {$endif m68k or arm}
       aasmcpu,
       aasmcpu,
-      owbase,owar
+      owar,owomflib
       ;
       ;
 
 
     var
     var
@@ -1819,16 +1821,20 @@ Implementation
         startsectype : TAsmSectiontype;
         startsectype : TAsmSectiontype;
         place: tcutplace;
         place: tcutplace;
         ObjWriter : TObjectWriter;
         ObjWriter : TObjectWriter;
+        startsecname: String;
+        startsecorder: TAsmSectionOrder;
       begin
       begin
         if not(cs_asm_leave in current_settings.globalswitches) and
         if not(cs_asm_leave in current_settings.globalswitches) and
            not(af_needar in target_asm.flags) then
            not(af_needar in target_asm.flags) then
-          ObjWriter:=TARObjectWriter.create(current_module.staticlibfilename)
+          ObjWriter:=CInternalAr.CreateAr(current_module.staticlibfilename)
         else
         else
           ObjWriter:=TObjectwriter.create;
           ObjWriter:=TObjectwriter.create;
 
 
         NextSmartName(cut_normal);
         NextSmartName(cut_normal);
         ObjOutput:=CObjOutput.Create(ObjWriter);
         ObjOutput:=CObjOutput.Create(ObjWriter);
-        startsectype:=sec_code;
+        startsectype:=sec_none;
+        startsecname:='';
+        startsecorder:=secorder_default;
 
 
         { start with list 1 }
         { start with list 1 }
         currlistidx:=1;
         currlistidx:=1;
@@ -1842,7 +1848,8 @@ Implementation
            ObjData.currpass:=0;
            ObjData.currpass:=0;
            ObjData.resetsections;
            ObjData.resetsections;
            ObjData.beforealloc;
            ObjData.beforealloc;
-           ObjData.createsection(startsectype);
+           if startsectype<>sec_none then
+             ObjData.CreateSection(startsectype,startsecname,startsecorder);
            TreePass0(hp);
            TreePass0(hp);
            ObjData.afteralloc;
            ObjData.afteralloc;
            { leave if errors have occured }
            { leave if errors have occured }
@@ -1853,7 +1860,8 @@ Implementation
            ObjData.currpass:=1;
            ObjData.currpass:=1;
            ObjData.resetsections;
            ObjData.resetsections;
            ObjData.beforealloc;
            ObjData.beforealloc;
-           ObjData.createsection(startsectype);
+           if startsectype<>sec_none then
+             ObjData.CreateSection(startsectype,startsecname,startsecorder);
            TreePass1(hp);
            TreePass1(hp);
            ObjData.afteralloc;
            ObjData.afteralloc;
 
 
@@ -1866,7 +1874,8 @@ Implementation
            ObjOutput.startobjectfile(ObjFileName);
            ObjOutput.startobjectfile(ObjFileName);
            ObjData.resetsections;
            ObjData.resetsections;
            ObjData.beforewrite;
            ObjData.beforewrite;
-           ObjData.createsection(startsectype);
+           if startsectype<>sec_none then
+             ObjData.CreateSection(startsectype,startsecname,startsecorder);
            hp:=TreePass2(hp);
            hp:=TreePass2(hp);
            ObjData.afterwrite;
            ObjData.afterwrite;
 
 
@@ -1892,12 +1901,18 @@ Implementation
              place := cut_normal;
              place := cut_normal;
 
 
            { avoid empty files }
            { avoid empty files }
-           startsectype:=sec_code;
+           startsectype:=sec_none;
+           startsecname:='';
+           startsecorder:=secorder_default;
            while assigned(hp) and
            while assigned(hp) and
                  (Tai(hp).typ in [ait_marker,ait_comment,ait_section,ait_cutobject]) do
                  (Tai(hp).typ in [ait_marker,ait_comment,ait_section,ait_cutobject]) do
             begin
             begin
               if Tai(hp).typ=ait_section then
               if Tai(hp).typ=ait_section then
-                startsectype:=Tai_section(hp).sectype;
+                begin
+                  startsectype:=Tai_section(hp).sectype;
+                  startsecname:=Tai_section(hp).name^;
+                  startsecorder:=Tai_section(hp).secorder;
+                end;
               if (Tai(hp).typ=ait_cutobject) then
               if (Tai(hp).typ=ait_cutobject) then
                 place:=Tai_cutobject(hp).place;
                 place:=Tai_cutobject(hp).place;
               hp:=Tai(hp.next);
               hp:=Tai(hp.next);

+ 36 - 14
compiler/avr/aasmcpu.pas

@@ -250,7 +250,8 @@ implementation
           A_MOV,A_MOVW,A_POP:
           A_MOV,A_MOVW,A_POP:
             if opnr=0 then
             if opnr=0 then
               result:=operand_write;
               result:=operand_write;
-          A_CP,A_CPC,A_CPI,A_PUSH,A_SBRC,A_SBRS,A_ST,A_STD,A_STS:
+          A_CP,A_CPC,A_CPI,A_PUSH,A_SBRC,A_SBRS,A_ST,A_STD,A_STS,
+          A_MUL,A_MULS,A_MULSU,A_FMUL,A_FMULS,A_FMULSU:
             ;
             ;
           else
           else
             begin
             begin
@@ -401,6 +402,7 @@ implementation
         curtai : tai;
         curtai : tai;
         again : boolean;
         again : boolean;
         l : tasmlabel;
         l : tasmlabel;
+        inasmblock : Boolean;
       begin
       begin
         again:=true;
         again:=true;
         while again do
         while again do
@@ -435,21 +437,41 @@ implementation
               end;
               end;
 
 
             curtai:=tai(list.first);
             curtai:=tai(list.first);
+            inasmblock:=false;
             while assigned(curtai) do
             while assigned(curtai) do
               begin
               begin
-                if (curtai.typ=ait_instruction) and
-                  (taicpu(curtai).opcode in [A_BRxx]) and
-                  ((taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset>64) or
-                   (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset<-63)
-                  ) then
-                  begin
-                    current_asmdata.getjumplabel(l);
-                    list.insertafter(tai_label.create(l),curtai);
-                    list.insertafter(taicpu.op_sym(A_JMP,taicpu(curtai).oper[0]^.ref^.symbol),curtai);
-                    taicpu(curtai).oper[0]^.ref^.symbol:=l;
-                    taicpu(curtai).condition:=inverse_cond(taicpu(curtai).condition);
-                    again:=true;
-                  end;
+                case curtai.typ of
+                  ait_instruction:
+                    case taicpu(curtai).opcode of
+                      A_BRxx:
+                        if (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset>64) or
+                          (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset<-63) then
+                          begin
+                            current_asmdata.getjumplabel(l);
+                            list.insertafter(tai_label.create(l),curtai);
+                            list.insertafter(taicpu.op_sym(A_JMP,taicpu(curtai).oper[0]^.ref^.symbol),curtai);
+                            taicpu(curtai).oper[0]^.ref^.symbol:=l;
+                            taicpu(curtai).condition:=inverse_cond(taicpu(curtai).condition);
+                            again:=true;
+                          end;
+                      A_JMP:
+                        { replace JMP by RJMP? ...
+                          ... but do not mess with asm block }
+                        if not(inasmblock) and (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset<=2048) and
+                        (taicpu(curtai).InsOffset-taicpu(curtai).oper[0]^.ref^.symbol.offset>=-2047) then
+                        begin
+                          taicpu(curtai).opcode:=A_RJMP;
+                          again:=true;
+                        end;
+                    end;
+                  ait_marker:
+                    case tai_marker(curtai).Kind of
+                      mark_AsmBlockStart:
+                        inasmblock:=true;
+                      mark_AsmBlockEnd:
+                        inasmblock:=false;
+                    end;
+                end;
                 curtai:=tai(curtai.next);
                 curtai:=tai(curtai.next);
               end;
               end;
           end;
           end;

+ 4 - 0
compiler/avr/agavrgas.pas

@@ -128,8 +128,12 @@ unit agavrgas;
                   case refaddr of
                   case refaddr of
                     addr_hi8:
                     addr_hi8:
                       s:='hi8('+s+')';
                       s:='hi8('+s+')';
+                    addr_hi8_gs:
+                      s:='hi8(gs('+s+'))';
                     addr_lo8:
                     addr_lo8:
                       s:='lo8('+s+')';
                       s:='lo8('+s+')';
+                    addr_lo8_gs:
+                      s:='lo8(gs('+s+'))';
                     else
                     else
                       s:='('+s+')';
                       s:='('+s+')';
                   end;
                   end;

+ 822 - 242
compiler/avr/aoptcpu.pas

@@ -26,13 +26,19 @@ Unit aoptcpu;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
+{$define DEBUG_AOPTCPU}
+
 Interface
 Interface
 
 
 uses cpubase, cgbase, aasmtai, aopt, aoptcpub;
 uses cpubase, cgbase, aasmtai, aopt, aoptcpub;
 
 
 Type
 Type
   TCpuAsmOptimizer = class(TAsmOptimizer)
   TCpuAsmOptimizer = class(TAsmOptimizer)
+    { outputs a debug message into the assembler file }
+    procedure DebugMsg(const s: string; p: tai);
+
     Function GetNextInstructionUsingReg(Current: tai; Var Next: tai;reg : TRegister): Boolean;
     Function GetNextInstructionUsingReg(Current: tai; Var Next: tai;reg : TRegister): Boolean;
+    function RegInInstruction(Reg: TRegister; p1: tai): Boolean; override;
 
 
     { uses the same constructor as TAopObj }
     { uses the same constructor as TAopObj }
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
@@ -42,9 +48,14 @@ Type
 Implementation
 Implementation
 
 
   uses
   uses
+    cutils,
     cpuinfo,
     cpuinfo,
-    aasmbase,aasmcpu,
-    globals,globtype;
+    aasmbase,aasmcpu,aasmdata,
+    globals,globtype,
+    cgutils;
+
+  type
+    TAsmOpSet = set of TAsmOp;
 
 
   function CanBeCond(p : tai) : boolean;
   function CanBeCond(p : tai) : boolean;
     begin
     begin
@@ -52,6 +63,79 @@ Implementation
     end;
     end;
 
 
 
 
+  function RefsEqual(const r1, r2: treference): boolean;
+    begin
+      refsequal :=
+        (r1.offset = r2.offset) and
+        (r1.base = r2.base) and
+        (r1.index = r2.index) and (r1.scalefactor = r2.scalefactor) and
+        (r1.symbol=r2.symbol) and (r1.refaddr = r2.refaddr) and
+        (r1.relsymbol = r2.relsymbol) and
+        (r1.addressmode = r2.addressmode);
+    end;
+
+
+  function MatchOperand(const oper1: TOper; const oper2: TOper): boolean; inline;
+    begin
+      result:=oper1.typ=oper2.typ;
+
+      if result then
+        case oper1.typ of
+          top_const:
+            Result:=oper1.val = oper2.val;
+          top_reg:
+            Result:=oper1.reg = oper2.reg;
+          top_ref:
+            Result:=RefsEqual(oper1.ref^, oper2.ref^);
+          else Result:=false;
+        end
+    end;
+
+
+  function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
+    begin
+      result := (oper.typ = top_reg) and (oper.reg = reg);
+    end;
+
+
+  function MatchInstruction(const instr: tai; const op: TAsmOp): boolean;
+    begin
+      result :=
+        (instr.typ = ait_instruction) and
+        (taicpu(instr).opcode = op);
+    end;
+
+
+  function MatchInstruction(const instr: tai; const ops: TAsmOpSet): boolean;
+    begin
+      result :=
+        (instr.typ = ait_instruction) and
+        (taicpu(instr).opcode in ops);
+    end;
+
+
+{$ifdef DEBUG_AOPTCPU}
+  procedure TCpuAsmOptimizer.DebugMsg(const s: string;p : tai);
+    begin
+      asml.insertbefore(tai_comment.Create(strpnew(s)), p);
+    end;
+{$else DEBUG_AOPTCPU}
+  procedure TCpuAsmOptimizer.DebugMsg(const s: string;p : tai);inline;
+    begin
+    end;
+{$endif DEBUG_AOPTCPU}
+
+
+  function TCpuAsmOptimizer.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
+    begin
+      If (p1.typ = ait_instruction) and (taicpu(p1).opcode in [A_MUL,A_MULS,A_FMUL,A_FMULS,A_FMULSU]) and
+              ((getsupreg(reg)=RS_R0) or (getsupreg(reg)=RS_R1)) then
+        Result:=true
+      else
+        Result:=inherited RegInInstruction(Reg, p1);
+    end;
+
+
   function TCpuAsmOptimizer.GetNextInstructionUsingReg(Current: tai;
   function TCpuAsmOptimizer.GetNextInstructionUsingReg(Current: tai;
     var Next: tai; reg: TRegister): Boolean;
     var Next: tai; reg: TRegister): Boolean;
     begin
     begin
@@ -65,261 +149,757 @@ Implementation
 
 
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
     var
     var
-      hp1,hp2,hp3: tai;
+      hp1,hp2,hp3,hp4,hp5: tai;
       alloc, dealloc: tai_regalloc;
       alloc, dealloc: tai_regalloc;
       i: integer;
       i: integer;
+      l: TAsmLabel;
     begin
     begin
       result := false;
       result := false;
       case p.typ of
       case p.typ of
         ait_instruction:
         ait_instruction:
           begin
           begin
-            case taicpu(p).opcode of
-              A_LDI:
-                begin
-                  { turn
-                    ldi reg0, imm
-                    cp reg1, reg0
-                    dealloc reg0
-                    into
-                    cpi reg1, imm
-                  }
-                  if (taicpu(p).ops=2) and
-                     (taicpu(p).oper[0]^.typ=top_reg) and
-                     (taicpu(p).oper[1]^.typ=top_const) and
-                     GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
-                     (hp1.typ=ait_instruction) and
-                     (not RegModifiedBetween(taicpu(p).oper[0]^.reg, p, hp1)) and
-                     (taicpu(hp1).opcode=A_CP) and
-                     (taicpu(hp1).ops=2) and
-                     (taicpu(hp1).oper[1]^.typ=top_reg) and
-                     (getsupreg(taicpu(hp1).oper[0]^.reg) in [16..31]) and
-                     (taicpu(hp1).oper[1]^.reg=taicpu(p).oper[0]^.reg) and
-                     assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) then
+            {
+              change
+              <op> reg,x,y
+              cp reg,r1
+              into
+              <op>s reg,x,y
+            }
+            { this optimization can applied only to the currently enabled operations because
+              the other operations do not update all flags and FPC does not track flag usage }
+            if MatchInstruction(p, [A_ADC,A_ADD,A_AND,A_ANDI,A_ASR,A_COM,A_DEC,A_EOR,
+                                    A_INC,A_LSL,A_LSR,
+                                    A_OR,A_ORI,A_ROL,A_ROR,A_SBC,A_SBCI,A_SUB,A_SUBI]) and
+              GetNextInstruction(p, hp1) and
+              MatchInstruction(hp1, A_CP) and
+              (((taicpu(p).oper[0]^.reg = taicpu(hp1).oper[0]^.reg) and
+                (taicpu(hp1).oper[1]^.reg = NR_R1)) or
+               ((taicpu(p).oper[0]^.reg = taicpu(hp1).oper[1]^.reg) and
+                (taicpu(hp1).oper[0]^.reg = NR_R1) and
+                (taicpu(p).opcode in [A_ADC,A_ADD,A_AND,A_ANDI,A_ASR,A_COM,A_EOR,
+                                      A_LSL,A_LSR,
+                                      A_OR,A_ORI,A_ROL,A_ROR]))) and
+              GetNextInstruction(hp1, hp2) and
+              { be careful here, following instructions could use other flags
+                however after a jump fpc never depends on the value of flags }
+              { All above instructions set Z and N according to the following
+                Z := result = 0;
+                N := result[31];
+                EQ = Z=1; NE = Z=0;
+                MI = N=1; PL = N=0; }
+              MatchInstruction(hp2, A_BRxx) and
+              (taicpu(hp2).condition in [C_EQ,C_NE,C_MI,C_PL]) { and
+              no flag allocation tracking implemented yet on avr
+              assigned(FindRegDealloc(NR_DEFAULTFLAGS,tai(hp2.Next)))} then
+              begin
+                { move flag allocation if possible }
+                { no flag allocation tracking implemented yet on avr
+                GetLastInstruction(hp1, hp2);
+                hp2:=FindRegAlloc(NR_DEFAULTFLAGS,tai(hp2.Next));
+                if assigned(hp2) then
+                  begin
+                    asml.Remove(hp2);
+                    asml.insertbefore(hp2, p);
+                  end;
+                }
+
+                DebugMsg('Peephole OpCp2Op performed', p);
+
+                asml.remove(hp1);
+                hp1.free;
+                Result:=true;
+              end
+            else
+              case taicpu(p).opcode of
+                A_LDI:
+                  begin
+                    { turn
+                      ldi reg0, imm
+                      cp reg1, reg0
+                      dealloc reg0
+                      into
+                      cpi reg1, imm
+                    }
+                    if (taicpu(p).ops=2) and
+                       (taicpu(p).oper[0]^.typ=top_reg) and
+                       (taicpu(p).oper[1]^.typ=top_const) and
+                       GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
+                       (hp1.typ=ait_instruction) and
+                       (not RegModifiedBetween(taicpu(p).oper[0]^.reg, p, hp1)) and
+                       (taicpu(hp1).opcode=A_CP) and
+                       (taicpu(hp1).ops=2) and
+                       (taicpu(hp1).oper[1]^.typ=top_reg) and
+                       (getsupreg(taicpu(hp1).oper[0]^.reg) in [16..31]) and
+                       (taicpu(hp1).oper[1]^.reg=taicpu(p).oper[0]^.reg) and
+                       assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) then
+                      begin
+                        taicpu(hp1).opcode:=A_CPI;
+                        taicpu(hp1).loadconst(1, taicpu(p).oper[1]^.val);
+
+                        alloc:=FindRegAllocBackward(taicpu(p).oper[0]^.reg,tai(p.Previous));
+                        dealloc:=FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next));
+
+                        if assigned(alloc) and assigned(dealloc) then
+                          begin
+                            asml.Remove(alloc);
+                            alloc.Free;
+                            asml.Remove(dealloc);
+                            dealloc.Free;
+                          end;
+
+                        DebugMsg('Peephole LdiCp2Cpi performed', p);
+
+                        GetNextInstruction(p,hp1);
+                        asml.Remove(p);
+                        p.Free;
+                        p:=hp1;
+
+                        result:=true;
+                      end;
+                  end;
+                A_STS:
+                  if (taicpu(p).oper[0]^.ref^.symbol=nil) and
+                    (taicpu(p).oper[0]^.ref^.relsymbol=nil) and
+                    (getsupreg(taicpu(p).oper[0]^.ref^.base)=RS_NO) and
+                    (getsupreg(taicpu(p).oper[0]^.ref^.index)=RS_NO) and
+                    (taicpu(p).oper[0]^.ref^.addressmode=AM_UNCHANGED) and
+                    (taicpu(p).oper[0]^.ref^.offset>=32) and
+                    (taicpu(p).oper[0]^.ref^.offset<=95) then
                     begin
                     begin
-                      taicpu(hp1).opcode:=A_CPI;
-                      taicpu(hp1).loadconst(1, taicpu(p).oper[1]^.val);
-
-                      alloc:=FindRegAllocBackward(taicpu(p).oper[0]^.reg,tai(p.Previous));
-                      dealloc:=FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next));
-
-                      if assigned(alloc) and assigned(dealloc) then
-                        begin
-                          asml.Remove(alloc);
-                          alloc.Free;
-                          asml.Remove(dealloc);
-                          dealloc.Free;
-                        end;
-
-                      GetNextInstruction(p,hp1);
-                      asml.Remove(p);
-                      p.Free;
-                      p:=hp1;
+                      DebugMsg('Peephole Sts2Out performed', p);
 
 
-                      result:=true;
+                      taicpu(p).opcode:=A_OUT;
+                      taicpu(p).loadconst(0,taicpu(p).oper[0]^.ref^.offset-32);
                     end;
                     end;
-                end;
-              A_CLR:
-                begin
-                  { turn the common
-                    clr rX
-                    mov/ld rX, rY
-                    into
-                    mov/ld rX, rY
-                  }
-                  if (taicpu(p).ops=1) and
-                     (taicpu(p).oper[0]^.typ=top_reg) and
-                     GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
-                     (not RegModifiedBetween(taicpu(p).oper[0]^.reg, p, hp1)) and
-                     (hp1.typ=ait_instruction) and
-                     (taicpu(hp1).opcode in [A_MOV,A_LD]) and
-                     (taicpu(hp1).ops>0) and
-                     (taicpu(hp1).oper[0]^.typ=top_reg) and
-                     (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) then
+                A_LDS:
+                  if (taicpu(p).oper[1]^.ref^.symbol=nil) and
+                    (taicpu(p).oper[1]^.ref^.relsymbol=nil) and
+                    (getsupreg(taicpu(p).oper[1]^.ref^.base)=RS_NO) and
+                    (getsupreg(taicpu(p).oper[1]^.ref^.index)=RS_NO) and
+                    (taicpu(p).oper[1]^.ref^.addressmode=AM_UNCHANGED) and
+                    (taicpu(p).oper[1]^.ref^.offset>=32) and
+                    (taicpu(p).oper[1]^.ref^.offset<=95) then
                     begin
                     begin
-                      asml.Remove(p);
-                      p.Free;
-                      p:=hp1;
-                      result:=true;
-                    end
-                  { turn
-                    clr rX
-                    ...
-                    adc rY, rX
-                    into
-                    ...
-                    adc rY, r1
-                  }
-                  else if (taicpu(p).ops=1) and
-                     (taicpu(p).oper[0]^.typ=top_reg) and
-                     GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
-                     (not RegModifiedBetween(taicpu(p).oper[0]^.reg, p, hp1)) and
-                     (hp1.typ=ait_instruction) and
-                     (taicpu(hp1).opcode in [A_ADC,A_SBC]) and
-                     (taicpu(hp1).ops=2) and
-                     (taicpu(hp1).oper[1]^.typ=top_reg) and
-                     (taicpu(hp1).oper[1]^.reg=taicpu(p).oper[0]^.reg) and
-                     (taicpu(hp1).oper[0]^.reg<>taicpu(p).oper[0]^.reg) and
-                     assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) then
-                    begin
-                      taicpu(hp1).oper[1]^.reg:=NR_R1;
-
-                      alloc:=FindRegAllocBackward(taicpu(p).oper[0]^.reg,tai(p.Previous));
-                      dealloc:=FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next));
+                      DebugMsg('Peephole Lds2In performed', p);
 
 
-                      if assigned(alloc) and assigned(dealloc) then
-                        begin
-                          asml.Remove(alloc);
-                          alloc.Free;
-                          asml.Remove(dealloc);
-                          dealloc.Free;
-                        end;
-
-                      GetNextInstruction(p,hp1);
-                      asml.Remove(p);
-                      p.free;
-                      p:=hp1;
-
-                      result:=true;
+                      taicpu(p).opcode:=A_IN;
+                      taicpu(p).loadconst(1,taicpu(p).oper[1]^.ref^.offset-32);
                     end;
                     end;
-                end;
-              A_PUSH:
-                begin
-                  { turn
-                    push reg0
-                    push reg1
-                    pop reg3
-                    pop reg2
-                    into
-                    movw reg2,reg0
-                  }
-                  if (taicpu(p).ops=1) and
-                     (taicpu(p).oper[0]^.typ=top_reg) and
-                     GetNextInstruction(p,hp1) and
-                     (hp1.typ=ait_instruction) and
-                     (taicpu(hp1).opcode=A_PUSH) and
-                     (getsupreg(taicpu(hp1).oper[0]^.reg)=getsupreg(taicpu(p).oper[0]^.reg)+1) and
-                     ((getsupreg(taicpu(p).oper[0]^.reg) mod 2)=0) and
-
-                     GetNextInstruction(hp1,hp2) and
-                     (hp2.typ=ait_instruction) and
-                     (taicpu(hp2).opcode=A_POP) and
-
-                     GetNextInstruction(hp2,hp3) and
-                     (hp3.typ=ait_instruction) and
-                     (taicpu(hp3).opcode=A_POP) and
-                     (getsupreg(taicpu(hp2).oper[0]^.reg)=getsupreg(taicpu(hp3).oper[0]^.reg)+1) and
-                     ((getsupreg(taicpu(hp3).oper[0]^.reg) mod 2)=0) then
-                    begin
-                      taicpu(p).ops:=2;
-                      taicpu(p).opcode:=A_MOVW;
-
-                      taicpu(p).loadreg(1, taicpu(p).oper[0]^.reg);
-                      taicpu(p).loadreg(0, taicpu(hp3).oper[0]^.reg);
-
-                      asml.Remove(hp1);
-                      hp1.Free;
-                      asml.Remove(hp2);
-                      hp2.Free;
-                      asml.Remove(hp3);
-                      hp3.Free;
-
-                      result:=true;
-                    end;
-                end;
-              A_MOV:
-                begin
-                  { turn
-                    mov reg0, reg1
-                    push reg0
-                    dealloc reg0
-                    into
-                    push reg1
-                  }
-                  if (taicpu(p).ops=2) and
-                     (taicpu(p).oper[0]^.typ = top_reg) and
-                     (taicpu(p).oper[1]^.typ = top_reg) and
-                     GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
-                     (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p, hp1)) and
-                     (hp1.typ = ait_instruction) and
-                     (taicpu(hp1).opcode in [A_PUSH,A_MOV,A_CP,A_CPC,A_ADD,A_SUB,A_EOR,A_AND,A_OR]) and
-                     RegInInstruction(taicpu(p).oper[0]^.reg, hp1) and
-                     (not RegModifiedByInstruction(taicpu(p).oper[0]^.reg, hp1)) and
-                     {(taicpu(hp1).ops=1) and
-                     (taicpu(hp1).oper[0]^.typ = top_reg) and
-                     (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and  }
-                     assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) then
-                    begin
-                      for i := 0 to taicpu(hp1).ops-1 do
-                        if taicpu(hp1).oper[i]^.typ=top_reg then
-                          if taicpu(hp1).oper[i]^.reg=taicpu(p).oper[0]^.reg then
-                            taicpu(hp1).oper[i]^.reg:=taicpu(p).oper[1]^.reg;
-
-                      alloc:=FindRegAllocBackward(taicpu(p).oper[0]^.reg,tai(p.Previous));
-                      dealloc:=FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next));
-
-                      if assigned(alloc) and assigned(dealloc) then
+                A_IN:
+                    if GetNextInstruction(p,hp1) then
+                      begin
+                        {
+                          in rX,Y
+                          ori rX,n
+                          out Y,rX
+
+                          into
+                          sbi rX,lg(n)
+                        }
+                        if (taicpu(p).oper[1]^.val<=31) and
+                          MatchInstruction(hp1,A_ORI) and
+                          (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
+                          (PopCnt(byte(taicpu(hp1).oper[1]^.val))=1) and
+                          GetNextInstruction(hp1,hp2) and
+                          MatchInstruction(hp2,A_OUT) and
+                          MatchOperand(taicpu(hp2).oper[1]^,taicpu(p).oper[0]^) and
+                          MatchOperand(taicpu(hp2).oper[0]^,taicpu(p).oper[1]^) then
+                          begin
+                            DebugMsg('Peephole InOriOut2Sbi performed', p);
+
+                            taicpu(p).opcode:=A_SBI;
+                            taicpu(p).loadconst(0,taicpu(p).oper[1]^.val);
+                            taicpu(p).loadconst(1,BsrByte(taicpu(hp1).oper[1]^.val));
+                            asml.Remove(hp1);
+                            hp1.Free;
+                            asml.Remove(hp2);
+                            hp2.Free;
+                            result:=true;
+                          end
+                         {
+                          in rX,Y
+                          andi rX,not(n)
+                          out Y,rX
+
+                          into
+                          cbi rX,lg(n)
+                        }
+                        else if (taicpu(p).oper[1]^.val<=31) and
+                           MatchInstruction(hp1,A_ANDI) and
+                           (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
+                           (PopCnt(byte(not(taicpu(hp1).oper[1]^.val)))=1) and
+                           GetNextInstruction(hp1,hp2) and
+                           MatchInstruction(hp2,A_OUT) and
+                           MatchOperand(taicpu(hp2).oper[1]^,taicpu(p).oper[0]^) and
+                           MatchOperand(taicpu(hp2).oper[0]^,taicpu(p).oper[1]^) then
+                          begin
+                            DebugMsg('Peephole InAndiOut2Cbi performed', p);
+
+                            taicpu(p).opcode:=A_CBI;
+                            taicpu(p).loadconst(0,taicpu(p).oper[1]^.val);
+                            taicpu(p).loadconst(1,BsrByte(not(taicpu(hp1).oper[1]^.val)));
+                            asml.Remove(hp1);
+                            hp1.Free;
+                            asml.Remove(hp2);
+                            hp2.Free;
+                            result:=true;
+                          end
+                         {
+                              in rX,Y
+                              andi rX,n
+                              breq/brne L1
+
+                          into
+                              sbis/sbic Y,lg(n)
+                              jmp L1
+                            .Ltemp:
+                        }
+                        else if (taicpu(p).oper[1]^.val<=31) and
+                           MatchInstruction(hp1,A_ANDI) and
+                           (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
+                           (PopCnt(byte(taicpu(hp1).oper[1]^.val))=1) and
+                           GetNextInstruction(hp1,hp2) and
+                           MatchInstruction(hp2,A_BRxx) and
+                           (taicpu(hp2).condition in [C_EQ,C_NE]) then
+                          begin
+                            if taicpu(hp2).condition=C_EQ then
+                              taicpu(p).opcode:=A_SBIS
+                            else
+                              taicpu(p).opcode:=A_SBIC;
+
+                            DebugMsg('Peephole InAndiBrx2SbixJmp performed', p);
+
+                            taicpu(p).loadconst(0,taicpu(p).oper[1]^.val);
+                            taicpu(p).loadconst(1,BsrByte(taicpu(hp1).oper[1]^.val));
+                            asml.Remove(hp1);
+                            hp1.Free;
+
+                            taicpu(hp2).condition:=C_None;
+                            if CPUAVR_HAS_JMP_CALL in cpu_capabilities[current_settings.cputype] then
+                              taicpu(hp2).opcode:=A_JMP
+                            else
+                              taicpu(hp2).opcode:=A_RJMP;
+
+                            current_asmdata.getjumplabel(l);
+                            l.increfs;
+                            asml.InsertAfter(tai_label.create(l), hp2);
+
+                            result:=true;
+                          end;
+                      end;
+                A_ANDI:
+                  begin
+                    {
+                      Turn
+                          andi rx, #pow2
+                          brne l
+                          <op>
+                        l:
+                      Into
+                          sbrs rx, #(1 shl imm)
+                          <op>
+                        l:
+                    }
+                    if (taicpu(p).ops=2) and
+                       (taicpu(p).oper[1]^.typ=top_const) and
+                       ispowerof2(taicpu(p).oper[1]^.val,i) and
+                       assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(p.next))) and
+                       GetNextInstruction(p,hp1) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).opcode=A_BRxx) and
+                       (taicpu(hp1).condition in [C_EQ,C_NE]) and
+                       (taicpu(hp1).ops>0) and
+                       (taicpu(hp1).oper[0]^.typ = top_ref) and
+                       (taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) and
+                       GetNextInstruction(hp1,hp2) and
+                       (hp2.typ=ait_instruction) and
+                       GetNextInstruction(hp2,hp3) and
+                       (hp3.typ=ait_label) and
+                       (taicpu(hp1).oper[0]^.ref^.symbol=tai_label(hp3).labsym) then
+                      begin
+                        DebugMsg('Peephole AndiBr2Sbr performed', p);
+
+                        taicpu(p).oper[1]^.val:=i;
+
+                        if taicpu(hp1).condition=C_NE then
+                          taicpu(p).opcode:=A_SBRS
+                        else
+                          taicpu(p).opcode:=A_SBRC;
+
+                        asml.Remove(hp1);
+                        hp1.free;
+
+                        result:=true;
+                      end
+                    {
+                      Remove
+                        andi rx, #y
+                        dealloc rx
+                    }
+                    else if (taicpu(p).ops=2) and
+                       (taicpu(p).oper[0]^.typ=top_reg) and
+                       assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(p.next))) and
+                       (assigned(FindRegDeAlloc(NR_DEFAULTFLAGS,tai(p.Next))) or
+                        (not RegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs))) then
+                      begin
+                        DebugMsg('Redundant Andi removed', p);
+
+                        GetNextInstruction(p,hp1);
+
+                        AsmL.Remove(p);
+                        p.free;
+
+                        p:=hp1;
+
+                        result:=true;
+                      end;
+                  end;
+                A_CLR:
+                  begin
+                    { turn the common
+                      clr rX
+                      mov/ld rX, rY
+                      into
+                      mov/ld rX, rY
+                    }
+                    if (taicpu(p).ops=1) and
+                       (taicpu(p).oper[0]^.typ=top_reg) and
+                       GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
+                       (not RegModifiedBetween(taicpu(p).oper[0]^.reg, p, hp1)) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).opcode in [A_MOV,A_LD]) and
+                       (taicpu(hp1).ops>0) and
+                       (taicpu(hp1).oper[0]^.typ=top_reg) and
+                       (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) then
+                      begin
+                        DebugMsg('Peephole ClrMov2Mov performed', p);
+
+                        asml.Remove(p);
+                        p.Free;
+                        p:=hp1;
+                        result:=true;
+                      end
+                    { turn
+                      clr rX
+                      ...
+                      adc rY, rX
+                      into
+                      ...
+                      adc rY, r1
+                    }
+                    else if (taicpu(p).ops=1) and
+                       (taicpu(p).oper[0]^.typ=top_reg) and
+                       GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
+                       (not RegModifiedBetween(taicpu(p).oper[0]^.reg, p, hp1)) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).opcode in [A_ADC,A_SBC]) and
+                       (taicpu(hp1).ops=2) and
+                       (taicpu(hp1).oper[1]^.typ=top_reg) and
+                       (taicpu(hp1).oper[1]^.reg=taicpu(p).oper[0]^.reg) and
+                       (taicpu(hp1).oper[0]^.reg<>taicpu(p).oper[0]^.reg) and
+                       assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) then
+                      begin
+                        DebugMsg('Peephole ClrAdc2Adc performed', p);
+
+                        taicpu(hp1).oper[1]^.reg:=NR_R1;
+
+                        alloc:=FindRegAllocBackward(taicpu(p).oper[0]^.reg,tai(p.Previous));
+                        dealloc:=FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next));
+
+                        if assigned(alloc) and assigned(dealloc) then
+                          begin
+                            asml.Remove(alloc);
+                            alloc.Free;
+                            asml.Remove(dealloc);
+                            dealloc.Free;
+                          end;
+
+                        GetNextInstruction(p,hp1);
+                        asml.Remove(p);
+                        p.free;
+                        p:=hp1;
+
+                        result:=true;
+                      end;
+                  end;
+                A_PUSH:
+                  begin
+                    { turn
+                      push reg0
+                      push reg1
+                      pop reg3
+                      pop reg2
+                      into
+                      movw reg2,reg0
+                    }
+                    if (taicpu(p).ops=1) and
+                       (taicpu(p).oper[0]^.typ=top_reg) and
+                       GetNextInstruction(p,hp1) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).opcode=A_PUSH) and
+                       (getsupreg(taicpu(hp1).oper[0]^.reg)=getsupreg(taicpu(p).oper[0]^.reg)+1) and
+                       ((getsupreg(taicpu(p).oper[0]^.reg) mod 2)=0) and
+
+                       GetNextInstruction(hp1,hp2) and
+                       (hp2.typ=ait_instruction) and
+                       (taicpu(hp2).opcode=A_POP) and
+
+                       GetNextInstruction(hp2,hp3) and
+                       (hp3.typ=ait_instruction) and
+                       (taicpu(hp3).opcode=A_POP) and
+                       (getsupreg(taicpu(hp2).oper[0]^.reg)=getsupreg(taicpu(hp3).oper[0]^.reg)+1) and
+                       ((getsupreg(taicpu(hp3).oper[0]^.reg) mod 2)=0) then
+                      begin
+                        DebugMsg('Peephole PushPushPopPop2Movw performed', p);
+
+                        taicpu(p).ops:=2;
+                        taicpu(p).opcode:=A_MOVW;
+
+                        taicpu(p).loadreg(1, taicpu(p).oper[0]^.reg);
+                        taicpu(p).loadreg(0, taicpu(hp3).oper[0]^.reg);
+
+                        asml.Remove(hp1);
+                        hp1.Free;
+                        asml.Remove(hp2);
+                        hp2.Free;
+                        asml.Remove(hp3);
+                        hp3.Free;
+
+                        result:=true;
+                      end;
+                  end;
+                A_MOV:
+                  begin
+                    { turn
+                      mov reg0, reg1
+                      push reg0
+                      dealloc reg0
+                      into
+                      push reg1
+                    }
+                    if (taicpu(p).ops=2) and
+                       (taicpu(p).oper[0]^.typ = top_reg) and
+                       (taicpu(p).oper[1]^.typ = top_reg) and
+                       GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                       (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p, hp1)) and
+                       (hp1.typ = ait_instruction) and
+                       (taicpu(hp1).opcode in [A_PUSH,A_MOV,A_CP,A_CPC,A_ADD,A_SUB,A_ADC,A_SBC,A_EOR,A_AND,A_OR,
+                                               A_OUT,A_IN]) and
+                       RegInInstruction(taicpu(p).oper[0]^.reg, hp1) and
+                       (not RegModifiedByInstruction(taicpu(p).oper[0]^.reg, hp1)) and
+                       {(taicpu(hp1).ops=1) and
+                       (taicpu(hp1).oper[0]^.typ = top_reg) and
+                       (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and  }
+                       assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) then
+                      begin
+                        DebugMsg('Peephole MovPush2Push performed', p);
+
+                        for i := 0 to taicpu(hp1).ops-1 do
+                          if taicpu(hp1).oper[i]^.typ=top_reg then
+                            if taicpu(hp1).oper[i]^.reg=taicpu(p).oper[0]^.reg then
+                              taicpu(hp1).oper[i]^.reg:=taicpu(p).oper[1]^.reg;
+
+                        alloc:=FindRegAllocBackward(taicpu(p).oper[0]^.reg,tai(p.Previous));
+                        dealloc:=FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next));
+
+                        if assigned(alloc) and assigned(dealloc) then
+                          begin
+                            asml.Remove(alloc);
+                            alloc.Free;
+                            asml.Remove(dealloc);
+                            dealloc.Free;
+                          end;
+
+                        GetNextInstruction(p,hp1);
+                        asml.Remove(p);
+                        p.free;
+                        p:=hp1;
+                        result:=true;
+                      end
+                    { remove
+                      mov reg0,reg0
+                    }
+                    else if (taicpu(p).ops=2) and
+                       (taicpu(p).oper[0]^.typ = top_reg) and
+                       (taicpu(p).oper[1]^.typ = top_reg) and
+                       (taicpu(p).oper[0]^.reg = taicpu(p).oper[1]^.reg) then
+                      begin
+                        DebugMsg('Peephole RedundantMov performed', p);
+
+                        GetNextInstruction(p,hp1);
+                        asml.remove(p);
+                        p.free;
+                        p:=hp1;
+                        result:=true;
+                      end
+                    {
+                      Turn
+                        mov rx,ry
+                        op rx,rz
+                        mov ry, rx
+                      Into
+                        op ry,rz
+                    }
+                    else if (taicpu(p).ops=2) and
+                       (taicpu(p).oper[0]^.typ = top_reg) and
+                       (taicpu(p).oper[1]^.typ = top_reg) and
+                       GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).ops >= 1) and
+                       (taicpu(hp1).oper[0]^.typ = top_reg) and
+                       GetNextInstructionUsingReg(hp1,hp2,taicpu(hp1).oper[0]^.reg) and
+                       (hp2.typ=ait_instruction) and
+                       (taicpu(hp2).opcode=A_MOV) and
+                       (taicpu(hp2).oper[0]^.typ = top_reg) and
+                       (taicpu(hp2).oper[1]^.typ = top_reg) and
+                       (taicpu(hp2).oper[0]^.reg = taicpu(p).oper[1]^.reg) and
+                       (taicpu(hp2).oper[1]^.reg = taicpu(hp1).oper[0]^.reg) and
+                       (taicpu(hp2).oper[1]^.reg = taicpu(p).oper[0]^.reg) and
+                       (not RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp2)) and
+                       (taicpu(hp1).opcode in [A_ADD,A_ADC,A_SUB,A_SBC,A_AND,A_OR,A_EOR,
+                                               A_LSL,A_LSR,A_ASR,A_ROR,A_ROL]) and
+                       assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg, tai(hp2.Next))) then
+                      begin
+                        DebugMsg('Peephole MovOpMov2Op performed', p);
+
+                        if (taicpu(hp1).ops=2) and
+                           (taicpu(hp1).oper[1]^.typ=top_reg) and
+                           (taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) then
+                          taicpu(hp1).oper[1]^.reg:=taicpu(p).oper[1]^.reg;
+
+                        taicpu(hp1).oper[0]^.reg:=taicpu(p).oper[1]^.reg;
+
+                        alloc:=FindRegAllocBackward(taicpu(p).oper[0]^.reg,tai(p.Previous));
+                        dealloc:=FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp2.Next));
+
+                        if assigned(alloc) and assigned(dealloc) then
+                          begin
+                            asml.Remove(alloc);
+                            alloc.Free;
+                            asml.Remove(dealloc);
+                            dealloc.Free;
+                          end;
+
+                        GetNextInstruction(p,hp1);
+
+                        asml.remove(p);
+                        p.free;
+                        asml.remove(hp2);
+                        hp2.free;
+
+                        p:=hp1;
+
+                        result:=true;
+                      end
+                    {
+                      Turn
+                        mov rx,ry
+                        op  rx,rw
+                        mov rw,rx
+                      Into
+                        op rw,ry
+                    }
+                    else if (taicpu(p).ops=2) and
+                       (taicpu(p).oper[0]^.typ = top_reg) and
+                       (taicpu(p).oper[1]^.typ = top_reg) and
+                       GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).ops = 2) and
+                       (taicpu(hp1).oper[0]^.typ = top_reg) and
+                       (taicpu(hp1).oper[1]^.typ = top_reg) and
+                       GetNextInstructionUsingReg(hp1,hp2,taicpu(hp1).oper[0]^.reg) and
+                       (hp2.typ=ait_instruction) and
+                       (taicpu(hp2).opcode=A_MOV) and
+                       (taicpu(hp2).oper[0]^.typ = top_reg) and
+                       (taicpu(hp2).oper[1]^.typ = top_reg) and
+                       (taicpu(hp2).oper[0]^.reg = taicpu(hp1).oper[1]^.reg) and
+                       (taicpu(hp2).oper[1]^.reg = taicpu(hp1).oper[0]^.reg) and
+                       (taicpu(hp2).oper[1]^.reg = taicpu(p).oper[0]^.reg) and
+                       (not RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) and
+                       (taicpu(hp1).opcode in [A_ADD,A_ADC,A_AND,A_OR,A_EOR]) and
+                       assigned(FindRegDeAlloc(taicpu(p).oper[0]^.reg, tai(hp2.Next))) then
+                      begin
+                        DebugMsg('Peephole MovOpMov2Op2 performed', p);
+
+                        taicpu(hp1).oper[0]^.reg:=taicpu(hp2).oper[0]^.reg;
+                        taicpu(hp1).oper[1]^.reg:=taicpu(p).oper[1]^.reg;
+
+                        alloc:=FindRegAllocBackward(taicpu(p).oper[0]^.reg,tai(p.Previous));
+                        dealloc:=FindRegDeAlloc(taicpu(p).oper[0]^.reg,tai(hp2.Next));
+
+                        if assigned(alloc) and assigned(dealloc) then
+                          begin
+                            asml.Remove(alloc);
+                            alloc.Free;
+                            asml.Remove(dealloc);
+                            dealloc.Free;
+                          end;
+
+                        GetNextInstruction(p,hp1);
+
+                        asml.remove(p);
+                        p.free;
+                        asml.remove(hp2);
+                        hp2.free;
+
+                        p:=hp1;
+
+                        result:=true;
+                      end
+                    { fold
+                      mov reg2,reg0
+                      mov reg3,reg1
+                      to
+                      movw reg2,reg0
+                    }
+                    else if (CPUAVR_HAS_MOVW in cpu_capabilities[current_settings.cputype]) and
+                       (taicpu(p).ops=2) and
+                       (taicpu(p).oper[0]^.typ = top_reg) and
+                       (taicpu(p).oper[1]^.typ = top_reg) and
+                       getnextinstruction(p,hp1) and
+                       (hp1.typ = ait_instruction) and
+                       (taicpu(hp1).opcode = A_MOV) and
+                       (taicpu(hp1).ops=2) and
+                       (taicpu(hp1).oper[0]^.typ = top_reg) and
+                       (taicpu(hp1).oper[1]^.typ = top_reg) and
+                       (getsupreg(taicpu(hp1).oper[0]^.reg)=getsupreg(taicpu(p).oper[0]^.reg)+1) and
+                       ((getsupreg(taicpu(p).oper[0]^.reg) mod 2)=0) and
+                       ((getsupreg(taicpu(p).oper[1]^.reg) mod 2)=0) and
+                       (getsupreg(taicpu(hp1).oper[1]^.reg)=getsupreg(taicpu(p).oper[1]^.reg)+1) then
+                      begin
+                        DebugMsg('Peephole MovMov2Movw performed', p);
+
+                        alloc:=FindRegAllocBackward(taicpu(hp1).oper[0]^.reg,tai(hp1.Previous));
+                        if assigned(alloc) then
+                          begin
+                            asml.Remove(alloc);
+                            asml.InsertBefore(alloc,p);
+                          end;
+
+                        taicpu(p).opcode:=A_MOVW;
+                        asml.remove(hp1);
+                        hp1.free;
+                        result:=true;
+                      end
+                    {
+                      This removes the first mov from
+                      mov rX,...
+                      mov rX,...
+                    }
+                    else if taicpu(hp1).opcode=A_MOV then
+                      while (hp1.typ=ait_instruction) and (taicpu(hp1).opcode=A_MOV) and
+                            MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^) and
+                            { don't remove the first mov if the second is a mov rX,rX }
+                            not(MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^)) do
                         begin
                         begin
-                          asml.Remove(alloc);
-                          alloc.Free;
-                          asml.Remove(dealloc);
-                          dealloc.Free;
+                          DebugMsg('Peephole MovMov2Mov performed', p);
+
+                          asml.remove(p);
+                          p.free;
+                          p:=hp1;
+                          GetNextInstruction(hp1,hp1);
+                          result:=true;
+                          if not assigned(hp1) then
+                            break;
                         end;
                         end;
-
-                      GetNextInstruction(p,hp1);
-                      asml.Remove(p);
-                      p.free;
-                      p:=hp1;
-                      result:=true;
-                    end
-                  { remove
-                    mov reg0,reg0
-                  }
-                  else if (taicpu(p).ops=2) and
-                     (taicpu(p).oper[0]^.typ = top_reg) and
-                     (taicpu(p).oper[1]^.typ = top_reg) and
-                     (taicpu(p).oper[0]^.reg = taicpu(p).oper[1]^.reg) then
-                    begin
-                      GetNextInstruction(p,hp1);
-                      asml.remove(p);
-                      p.free;
-                      p:=hp1;
-                      result:=true;
-                    end
-                  { fold
-                    mov reg2,reg0
-                    mov reg3,reg1
-                    to
-                    movw reg2,reg0
-                  }
-                  else if (CPUAVR_HAS_MOVW in cpu_capabilities[current_settings.cputype]) and
-                     (taicpu(p).ops=2) and
-                     (taicpu(p).oper[0]^.typ = top_reg) and
-                     (taicpu(p).oper[1]^.typ = top_reg) and
-                     getnextinstruction(p,hp1) and
-                     (hp1.typ = ait_instruction) and
-                     (taicpu(hp1).opcode = A_MOV) and
-                     (taicpu(hp1).ops=2) and
-                     (taicpu(hp1).oper[0]^.typ = top_reg) and
-                     (taicpu(hp1).oper[1]^.typ = top_reg) and
-                     (getsupreg(taicpu(hp1).oper[0]^.reg)=getsupreg(taicpu(p).oper[0]^.reg)+1) and
-                     ((getsupreg(taicpu(p).oper[0]^.reg) mod 2)=0) and
-                     ((getsupreg(taicpu(p).oper[1]^.reg) mod 2)=0) and
-                     (getsupreg(taicpu(hp1).oper[1]^.reg)=getsupreg(taicpu(p).oper[1]^.reg)+1) then
-                    begin
-                      alloc:=FindRegAllocBackward(taicpu(hp1).oper[0]^.reg,tai(hp1.Previous));
-                      if assigned(alloc) then
-                        begin
-                          asml.Remove(alloc);
-                          asml.InsertBefore(alloc,p);
-                        end;
-
-                      taicpu(p).opcode:=A_MOVW;
-                      asml.remove(hp1);
-                      hp1.free;
-                      result:=true;
-                    end;
-                end;
-            end;
+                  end;
+                A_SBIC,
+                A_SBIS:
+                  begin
+                    {
+                      Turn
+                          sbic/sbis X, y
+                          jmp .L1
+                          op
+                        .L1:
+
+                      into
+                          sbis/sbic X,y
+                          op
+                        .L1:
+                    }
+                    if GetNextInstruction(p, hp1) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).opcode in [A_JMP,A_RJMP]) and
+                       (taicpu(hp1).ops>0) and
+                       (taicpu(hp1).oper[0]^.typ = top_ref) and
+                       (taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) and
+                       GetNextInstruction(hp1, hp2) and
+                       (hp2.typ=ait_instruction) and
+                       (not taicpu(hp2).is_jmp) and
+                       GetNextInstruction(hp2, hp3) and
+                       (hp3.typ=ait_label) and
+                       (taicpu(hp1).oper[0]^.ref^.symbol=tai_label(hp3).labsym) then
+                      begin
+                        DebugMsg('Peephole SbiJmp2Sbi performed',p);
+
+                        if taicpu(p).opcode=A_SBIC then
+                          taicpu(p).opcode:=A_SBIS
+                        else
+                          taicpu(p).opcode:=A_SBIC;
+
+                        tai_label(hp3).labsym.decrefs;
+
+                        AsmL.remove(hp1);
+                        taicpu(hp1).Free;
+
+                        result:=true;
+                      end
+                    {
+                      Turn
+                          sbiX X, y
+                          jmp .L1
+                          jmp .L2
+                        .L1:
+                          op
+                        .L2:
+
+                      into
+                          sbiX X,y
+                        .L1:
+                          op
+                        .L2:
+                    }
+                    else if GetNextInstruction(p, hp1) and
+                       (hp1.typ=ait_instruction) and
+                       (taicpu(hp1).opcode in [A_JMP,A_RJMP]) and
+                       (taicpu(hp1).ops>0) and
+                       (taicpu(hp1).oper[0]^.typ = top_ref) and
+                       (taicpu(hp1).oper[0]^.ref^.symbol is TAsmLabel) and
+
+                       GetNextInstruction(hp1, hp2) and
+                       (hp2.typ=ait_instruction) and
+                       (taicpu(hp2).opcode in [A_JMP,A_RJMP]) and
+                       (taicpu(hp2).ops>0) and
+                       (taicpu(hp2).oper[0]^.typ = top_ref) and
+                       (taicpu(hp2).oper[0]^.ref^.symbol is TAsmLabel) and
+
+                       GetNextInstruction(hp2, hp3) and
+                       (hp3.typ=ait_label) and
+                       (taicpu(hp1).oper[0]^.ref^.symbol=tai_label(hp3).labsym) and
+
+                       GetNextInstruction(hp3, hp4) and
+                       (hp4.typ=ait_instruction) and
+
+                       GetNextInstruction(hp4, hp5) and
+                       (hp3.typ=ait_label) and
+                       (taicpu(hp2).oper[0]^.ref^.symbol=tai_label(hp5).labsym) then
+                      begin
+                        DebugMsg('Peephole SbiJmpJmp2Sbi performed',p);
+
+                        tai_label(hp3).labsym.decrefs;
+                        tai_label(hp5).labsym.decrefs;
+
+                        AsmL.remove(hp1);
+                        taicpu(hp1).Free;
+
+                        AsmL.remove(hp2);
+                        taicpu(hp2).Free;
+
+                        result:=true;
+                      end;
+                  end;
+              end;
           end;
           end;
       end;
       end;
     end;
     end;

+ 8 - 1
compiler/avr/aoptcpub.pas

@@ -99,7 +99,7 @@ Const
 
 
   StoreDst = 0;
   StoreDst = 0;
 
 
-  aopt_uncondjmp = A_JMP;
+  aopt_uncondjmp = [A_RJMP,A_JMP];
   aopt_condjmp = A_BRxx;
   aopt_condjmp = A_BRxx;
 
 
 Implementation
 Implementation
@@ -121,6 +121,13 @@ Implementation
       i : Longint;
       i : Longint;
     begin
     begin
       result:=false;
       result:=false;
+      If (p1.typ = ait_instruction) and (taicpu(p1).opcode in [A_MUL,A_MULS,A_FMUL,A_FMULS,A_FMULSU]) and
+              ((getsupreg(reg)=RS_R0) or (getsupreg(reg)=RS_R1)) then
+        begin
+          Result:=true;
+          exit;
+        end;
+
       for i:=0 to taicpu(p1).ops-1 do
       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
         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
           begin

+ 394 - 102
compiler/avr/cgcpu.pas

@@ -57,6 +57,8 @@ unit cgcpu;
 
 
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
         procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst : TRegister); override;
         procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst : TRegister); override;
+        procedure a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); override;
+        procedure a_op_const_reg_reg(list : TAsmList;op : TOpCg;size : tcgsize; a : tcgint;src,dst : tregister); override;
 
 
         { move instructions }
         { move instructions }
         procedure a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);override;
         procedure a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);override;
@@ -107,6 +109,7 @@ unit cgcpu;
       protected
       protected
         procedure a_op_reg_reg_internal(list: TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
         procedure a_op_reg_reg_internal(list: TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
         procedure a_op_const_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg, reghi: TRegister);
         procedure a_op_const_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg, reghi: TRegister);
+        procedure maybegetcpuregister(list : tasmlist; reg : tregister);
       end;
       end;
 
 
       tcg64favr = class(tcg64f32)
       tcg64favr = class(tcg64f32)
@@ -399,12 +402,12 @@ unit cgcpu;
     procedure tcgavr.a_call_reg(list : TAsmList;reg: tregister);
     procedure tcgavr.a_call_reg(list : TAsmList;reg: tregister);
       begin
       begin
         a_reg_alloc(list,NR_ZLO);
         a_reg_alloc(list,NR_ZLO);
+        emit_mov(list,NR_ZLO,reg);
         a_reg_alloc(list,NR_ZHI);
         a_reg_alloc(list,NR_ZHI);
-        list.concat(taicpu.op_reg_reg(A_MOV,NR_ZLO,reg));
-        list.concat(taicpu.op_reg_reg(A_MOV,NR_ZHI,GetHigh(reg)));
+        emit_mov(list,NR_ZHI,GetHigh(reg));
         list.concat(taicpu.op_none(A_ICALL));
         list.concat(taicpu.op_none(A_ICALL));
-        a_reg_dealloc(list,NR_ZLO);
         a_reg_dealloc(list,NR_ZHI);
         a_reg_dealloc(list,NR_ZHI);
+        a_reg_dealloc(list,NR_ZLO);
 
 
         include(current_procinfo.flags,pi_do_call);
         include(current_procinfo.flags,pi_do_call);
       end;
       end;
@@ -426,6 +429,48 @@ unit cgcpu;
        end;
        end;
 
 
 
 
+     procedure tcgavr.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
+       begin
+         if (op in [OP_MUL,OP_IMUL]) and (size in [OS_16,OS_S16]) and
+            (CPUAVR_HAS_MUL in cpu_capabilities[current_settings.cputype]) then
+           begin
+             getcpuregister(list,NR_R0);
+             getcpuregister(list,NR_R1);
+             list.concat(taicpu.op_reg_reg(A_MUL,src1,src2));
+             emit_mov(list,dst,NR_R0);
+             emit_mov(list,GetNextReg(dst),NR_R1);
+             list.concat(taicpu.op_reg_reg(A_MUL,GetNextReg(src1),src2));
+             list.concat(taicpu.op_reg_reg(A_ADD,GetNextReg(dst),NR_R0));
+             list.concat(taicpu.op_reg_reg(A_MUL,src1,GetNextReg(src2)));
+             list.concat(taicpu.op_reg_reg(A_ADD,GetNextReg(dst),NR_R0));
+             ungetcpuregister(list,NR_R0);
+             list.concat(taicpu.op_reg(A_CLR,NR_R1));
+             ungetcpuregister(list,NR_R1);
+           end
+         else
+          inherited a_op_reg_reg_reg(list,op,size,src1,src2,dst);
+       end;
+
+
+     procedure tcgavr.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
+       begin
+         if (op in [OP_MUL,OP_IMUL]) and (size in [OS_16,OS_S16]) and (a in [2,4,8]) then
+           begin
+             emit_mov(list,dst,src);
+             emit_mov(list,GetNextReg(dst),GetNextReg(src));
+             a:=a shr 1;
+             while a>0 do
+               begin
+                 list.concat(taicpu.op_reg(A_LSL,dst));
+                 list.concat(taicpu.op_reg(A_ROL,GetNextReg(dst)));
+                 a:=a shr 1;
+               end;
+           end
+         else
+           inherited a_op_const_reg_reg(list,op,size,a,src,dst);
+       end;
+
+
      procedure tcgavr.a_op_reg_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
      procedure tcgavr.a_op_reg_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
        var
        var
          countreg,
          countreg,
@@ -533,40 +578,64 @@ unit cgcpu;
              begin
              begin
                if size in [OS_8,OS_S8] then
                if size in [OS_8,OS_S8] then
                  begin
                  begin
-                   cg.a_reg_alloc(list,NR_R0);
-                   cg.a_reg_alloc(list,NR_R1);
-                   list.concat(taicpu.op_reg_reg(topcg2asmop[op],dst,src));
-                   cg.a_reg_dealloc(list,NR_R1);
-                   list.concat(taicpu.op_reg_reg(A_MOV,dst,NR_R0));
-                   cg.a_reg_dealloc(list,NR_R0);
+                   if CPUAVR_HAS_MUL in cpu_capabilities[current_settings.cputype] then
+                     begin
+                       cg.a_reg_alloc(list,NR_R0);
+                       cg.a_reg_alloc(list,NR_R1);
+                       list.concat(taicpu.op_reg_reg(topcg2asmop[op],dst,src));
+                       list.concat(taicpu.op_reg(A_CLR,NR_R1));
+                       cg.a_reg_dealloc(list,NR_R1);
+                       list.concat(taicpu.op_reg_reg(A_MOV,dst,NR_R0));
+                       cg.a_reg_dealloc(list,NR_R0);
+                     end
+                   else
+                     internalerror(2015061001);
                  end
                  end
                else if size=OS_16 then
                else if size=OS_16 then
                  begin
                  begin
-                   pd:=search_system_proc('fpc_mul_word');
-                   paraloc1.init;
-                   paraloc2.init;
-                   paraloc3.init;
-                   paramanager.getintparaloc(list,pd,1,paraloc1);
-                   paramanager.getintparaloc(list,pd,2,paraloc2);
-                   paramanager.getintparaloc(list,pd,3,paraloc3);
-                   a_load_const_cgpara(list,OS_8,0,paraloc3);
-                   a_load_reg_cgpara(list,OS_16,src,paraloc2);
-                   a_load_reg_cgpara(list,OS_16,dst,paraloc1);
-                   paramanager.freecgpara(list,paraloc3);
-                   paramanager.freecgpara(list,paraloc2);
-                   paramanager.freecgpara(list,paraloc1);
-                   alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-                   a_call_name(list,'FPC_MUL_WORD',false);
-                   dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-                   cg.a_reg_alloc(list,NR_R23);
-                   cg.a_reg_alloc(list,NR_R24);
-                   cg.a_load_reg_reg(list,OS_8,OS_8,NR_R23,dst);
-                   cg.a_reg_dealloc(list,NR_R23);
-                   cg.a_load_reg_reg(list,OS_8,OS_8,NR_R24,GetNextReg(dst));
-                   cg.a_reg_dealloc(list,NR_R24);
-                   paraloc3.done;
-                   paraloc2.done;
-                   paraloc1.done;
+                   if CPUAVR_HAS_MUL in cpu_capabilities[current_settings.cputype] then
+                     begin
+                       tmpreg:=getintregister(list,OS_16);
+                       emit_mov(list,tmpreg,dst);
+                       emit_mov(list,GetNextReg(tmpreg),GetNextReg(dst));
+                       list.concat(taicpu.op_reg_reg(A_MUL,tmpreg,src));
+                       emit_mov(list,dst,NR_R0);
+                       emit_mov(list,GetNextReg(dst),NR_R1);
+                       list.concat(taicpu.op_reg_reg(A_MUL,GetNextReg(tmpreg),src));
+                       list.concat(taicpu.op_reg_reg(A_ADD,GetNextReg(dst),NR_R0));
+                       list.concat(taicpu.op_reg_reg(A_MUL,tmpreg,GetNextReg(src)));
+                       list.concat(taicpu.op_reg_reg(A_ADD,GetNextReg(dst),NR_R0));
+                       list.concat(taicpu.op_reg(A_CLR,NR_R1));
+                     end
+                   else
+                     begin
+                       { keep code for muls with overflow checking }
+                       pd:=search_system_proc('fpc_mul_word');
+                       paraloc1.init;
+                       paraloc2.init;
+                       paraloc3.init;
+                       paramanager.getintparaloc(list,pd,1,paraloc1);
+                       paramanager.getintparaloc(list,pd,2,paraloc2);
+                       paramanager.getintparaloc(list,pd,3,paraloc3);
+                       a_load_const_cgpara(list,OS_8,0,paraloc3);
+                       a_load_reg_cgpara(list,OS_16,src,paraloc2);
+                       a_load_reg_cgpara(list,OS_16,dst,paraloc1);
+                       paramanager.freecgpara(list,paraloc3);
+                       paramanager.freecgpara(list,paraloc2);
+                       paramanager.freecgpara(list,paraloc1);
+                       alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+                       a_call_name(list,'FPC_MUL_WORD',false);
+                       dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+                       cg.a_reg_alloc(list,NR_R24);
+                       cg.a_reg_alloc(list,NR_R25);
+                       cg.a_load_reg_reg(list,OS_8,OS_8,NR_R24,dst);
+                       cg.a_reg_dealloc(list,NR_R24);
+                       cg.a_load_reg_reg(list,OS_8,OS_8,NR_R25,GetNextReg(dst));
+                       cg.a_reg_dealloc(list,NR_R25);
+                       paraloc3.done;
+                       paraloc2.done;
+                       paraloc1.done;
+                     end;
                  end
                  end
                else
                else
                  internalerror(2011022002);
                  internalerror(2011022002);
@@ -663,7 +732,7 @@ unit cgcpu;
        var
        var
          mask : qword;
          mask : qword;
          shift : byte;
          shift : byte;
-         i : byte;
+         i,j : byte;
          tmpreg : tregister;
          tmpreg : tregister;
          tmpreg64 : tregister64;
          tmpreg64 : tregister64;
 
 
@@ -679,9 +748,19 @@ unit cgcpu;
         curvalue : byte;
         curvalue : byte;
 
 
        begin
        begin
+         optimize_op_const(size,op,a);
          mask:=$ff;
          mask:=$ff;
          shift:=0;
          shift:=0;
          case op of
          case op of
+           OP_NONE:
+             begin
+               { Opcode is optimized away }
+             end;
+           OP_MOVE:
+             begin
+               { Optimized, replaced with a simple load }
+               a_load_const_reg(list,size,a,reg);
+             end;
            OP_OR:
            OP_OR:
              begin
              begin
                for i:=1 to tcgsize2size[size] do
                for i:=1 to tcgsize2size[size] do
@@ -722,6 +801,71 @@ unit cgcpu;
                      end;
                      end;
                  end;
                  end;
              end;
              end;
+           OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
+             begin
+               if a*tcgsize2size[size]<=8 then
+                 begin
+                   for j:=1 to a do
+                     begin
+                       case op of
+                         OP_SHR:
+                           list.concat(taicpu.op_reg(A_LSR,GetOffsetReg64(reg,reghi,tcgsize2size[size]-1)));
+                         OP_SHL:
+                           list.concat(taicpu.op_reg(A_LSL,reg));
+                         OP_SAR:
+                           list.concat(taicpu.op_reg(A_ASR,GetOffsetReg64(reg,reghi,tcgsize2size[size]-1)));
+                         OP_ROR:
+                           begin
+                             { load carry? }
+                             if not(size in [OS_8,OS_S8]) then
+                               begin
+                                 list.concat(taicpu.op_none(A_CLC));
+                                 list.concat(taicpu.op_reg_const(A_SBRC,reg,0));
+                                 list.concat(taicpu.op_none(A_SEC));
+                               end;
+                             list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(reg,reghi,tcgsize2size[size]-1)));
+                           end;
+                         OP_ROL:
+                           begin
+                             { load carry? }
+                             if not(size in [OS_8,OS_S8]) then
+                               begin
+                                 list.concat(taicpu.op_none(A_CLC));
+                                 list.concat(taicpu.op_reg_const(A_SBRC,GetOffsetReg64(reg,reghi,tcgsize2size[size]-1),7));
+                                 list.concat(taicpu.op_none(A_SEC));
+                               end;
+                             list.concat(taicpu.op_reg(A_ROL,reg))
+                           end;
+                         else
+                           internalerror(2011030901);
+                       end;
+                       if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
+                         begin
+                           for i:=2 to tcgsize2size[size] do
+                             begin
+                               case op of
+                                 OP_ROR,
+                                 OP_SHR:
+                                   list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(reg,reghi,tcgsize2size[size]-i)));
+                                 OP_ROL,
+                                 OP_SHL:
+                                   list.concat(taicpu.op_reg(A_ROL,GetOffsetReg64(reg,reghi,i-1)));
+                                 OP_SAR:
+                                   list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(reg,reghi,tcgsize2size[size]-i)));
+                                 else
+                                   internalerror(2011030902);
+                               end;
+                           end;
+                         end;
+                   end;
+                 end
+               else
+                 begin
+                   tmpreg:=getintregister(list,size);
+                   a_load_const_reg(list,size,a,tmpreg);
+                   a_op_reg_reg(list,op,size,tmpreg,reg);
+                 end;
+             end;
            OP_ADD:
            OP_ADD:
              begin
              begin
                curvalue:=a and mask;
                curvalue:=a and mask;
@@ -765,9 +909,10 @@ unit cgcpu;
                end
                end
              else
              else
                begin
                begin
-                 { if (op=OP_SAR) and (a=31) and (size in [OS_32,OS_S32]) then
+{$if 0}
+                 { code not working yet }
+                 if (op=OP_SAR) and (a=31) and (size in [OS_32,OS_S32]) then
                    begin
                    begin
-                     { code not working yet }
                      tmpreg:=reg;
                      tmpreg:=reg;
                      for i:=1 to 4 do
                      for i:=1 to 4 do
                        begin
                        begin
@@ -776,7 +921,7 @@ unit cgcpu;
                        end;
                        end;
                    end
                    end
                  else
                  else
-                 }
+{$endif}
                    begin
                    begin
                      tmpreg:=getintregister(list,size);
                      tmpreg:=getintregister(list,size);
                      a_load_const_reg(list,size,a,tmpreg);
                      a_load_const_reg(list,size,a,tmpreg);
@@ -810,14 +955,15 @@ unit cgcpu;
        end;
        end;
 
 
 
 
-    function tcgavr.normalize_ref(list:TAsmList;ref: treference;tmpreg : tregister) : treference;
+    procedure tcgavr.maybegetcpuregister(list:tasmlist;reg : tregister);
+      begin
+        { allocate the register only, if a cpu register is passed }
+        if getsupreg(reg)<first_int_imreg then
+          getcpuregister(list,reg);
+      end;
 
 
-      procedure maybegetcpuregister(list:tasmlist;reg : tregister);
-        begin
-          { allocate the register only, if a cpu register is passed }
-          if getsupreg(reg)<first_int_imreg then
-            getcpuregister(list,reg);
-        end;
+
+    function tcgavr.normalize_ref(list:TAsmList;ref: treference;tmpreg : tregister) : treference;
 
 
       var
       var
         tmpref : treference;
         tmpref : treference;
@@ -837,17 +983,47 @@ unit cgcpu;
             ref.base:=ref.index;
             ref.base:=ref.index;
             ref.index:=NR_NO;
             ref.index:=NR_NO;
           end;
           end;
-        if assigned(ref.symbol) or (ref.offset<>0) then
+
+        { can we take advantage of adiw/sbiw? }
+        if (current_settings.cputype>=cpu_avr2) and not(assigned(ref.symbol)) and (ref.offset<>0) and (ref.offset>=-63) and (ref.offset<=63) and
+          ((tmpreg=NR_R24) or (tmpreg=NR_R26) or (tmpreg=NR_R28) or (tmpreg=NR_R30)) and (ref.base<>NR_NO) then
+          begin
+            maybegetcpuregister(list,tmpreg);
+            emit_mov(list,tmpreg,ref.base);
+            maybegetcpuregister(list,GetNextReg(tmpreg));
+            emit_mov(list,GetNextReg(tmpreg),GetNextReg(ref.base));
+            if ref.index<>NR_NO then
+              begin
+                list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.index));
+                list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.index)));
+              end;
+            if ref.offset>0 then
+              list.concat(taicpu.op_reg_const(A_ADIW,tmpreg,ref.offset))
+            else
+              list.concat(taicpu.op_reg_const(A_SBIW,tmpreg,-ref.offset));
+            ref.offset:=0;
+            ref.base:=tmpreg;
+            ref.index:=NR_NO;
+          end
+        else if assigned(ref.symbol) or (ref.offset<>0) then
           begin
           begin
             reference_reset(tmpref,0);
             reference_reset(tmpref,0);
             tmpref.symbol:=ref.symbol;
             tmpref.symbol:=ref.symbol;
             tmpref.offset:=ref.offset;
             tmpref.offset:=ref.offset;
-            tmpref.refaddr:=addr_lo8;
+            if assigned(ref.symbol) and (ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) then
+              tmpref.refaddr:=addr_lo8_gs
+            else
+              tmpref.refaddr:=addr_lo8;
             maybegetcpuregister(list,tmpreg);
             maybegetcpuregister(list,tmpreg);
             list.concat(taicpu.op_reg_ref(A_LDI,tmpreg,tmpref));
             list.concat(taicpu.op_reg_ref(A_LDI,tmpreg,tmpref));
-            tmpref.refaddr:=addr_hi8;
+
+            if assigned(ref.symbol) and (ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) then
+              tmpref.refaddr:=addr_hi8_gs
+            else
+              tmpref.refaddr:=addr_hi8;
             maybegetcpuregister(list,GetNextReg(tmpreg));
             maybegetcpuregister(list,GetNextReg(tmpreg));
             list.concat(taicpu.op_reg_ref(A_LDI,GetNextReg(tmpreg),tmpref));
             list.concat(taicpu.op_reg_ref(A_LDI,GetNextReg(tmpreg),tmpref));
+
             if (ref.base<>NR_NO) then
             if (ref.base<>NR_NO) then
               begin
               begin
                 list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.base));
                 list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.base));
@@ -905,20 +1081,39 @@ unit cgcpu;
          QuickRef : Boolean;
          QuickRef : Boolean;
        begin
        begin
          QuickRef:=false;
          QuickRef:=false;
-         if not((Ref.addressmode=AM_UNCHANGED) and
-                (Ref.symbol=nil) and
-                ((Ref.base=NR_R28) or
-                 (Ref.base=NR_R29)) and
-                 (Ref.Index=NR_No) and
-                 (Ref.Offset in [0..64-tcgsize2size[tosize]])) and
-           not((Ref.Base=NR_NO) and (Ref.Index=NR_NO)) then
-           href:=normalize_ref(list,Ref,NR_R30)
-         else
+
+         href:=Ref;
+         { ensure, href.base contains a valid register if there is any register used }
+         if href.base=NR_NO then
            begin
            begin
-             QuickRef:=true;
-             href:=Ref;
+             href.base:=href.index;
+             href.index:=NR_NO;
            end;
            end;
 
 
+         { try to use std/sts }
+         if not((href.Base=NR_NO) and (href.Index=NR_NO)) then
+           begin
+             if not((href.addressmode=AM_UNCHANGED) and
+                    (href.symbol=nil) and
+                     (href.Index=NR_NO) and
+                     (href.Offset in [0..64-tcgsize2size[fromsize]])) then
+               href:=normalize_ref(list,href,NR_R30)
+             else
+               begin
+                 if (href.base<>NR_R28) and (href.base<>NR_R30) then
+                   begin
+                     maybegetcpuregister(list,NR_R30);
+                     emit_mov(list,NR_R30,href.base);
+                     maybegetcpuregister(list,NR_R31);
+                     emit_mov(list,NR_R31,GetNextReg(href.base));
+                     href.base:=NR_R30;
+                   end;
+                 QuickRef:=true;
+               end;
+           end
+         else
+           QuickRef:=true;
+
          if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
          if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
            internalerror(2011021307);
            internalerror(2011021307);
 
 
@@ -1077,20 +1272,39 @@ unit cgcpu;
          QuickRef : boolean;
          QuickRef : boolean;
        begin
        begin
          QuickRef:=false;
          QuickRef:=false;
-         if not((Ref.addressmode=AM_UNCHANGED) and
-                (Ref.symbol=nil) and
-                ((Ref.base=NR_R28) or
-                 (Ref.base=NR_R29)) and
-                 (Ref.Index=NR_No) and
-                 (Ref.Offset in [0..64-tcgsize2size[fromsize]])) and
-           not((Ref.Base=NR_NO) and (Ref.Index=NR_NO)) then
-           href:=normalize_ref(list,Ref,NR_R30)
-         else
+
+         href:=Ref;
+         { ensure, href.base contains a valid register if there is any register used }
+         if href.base=NR_NO then
            begin
            begin
-             QuickRef:=true;
-             href:=Ref;
+             href.base:=href.index;
+             href.index:=NR_NO;
            end;
            end;
 
 
+         { try to use ldd/lds }
+         if not((href.Base=NR_NO) and (href.Index=NR_NO)) then
+           begin
+             if not((href.addressmode=AM_UNCHANGED) and
+                    (href.symbol=nil) and
+                     (href.Index=NR_NO) and
+                     (href.Offset in [0..64-tcgsize2size[fromsize]])) then
+               href:=normalize_ref(list,href,NR_R30)
+             else
+               begin
+                 if (href.base<>NR_R28) and (href.base<>NR_R30) then
+                   begin
+                     maybegetcpuregister(list,NR_R30);
+                     emit_mov(list,NR_R30,href.base);
+                     maybegetcpuregister(list,NR_R31);
+                     emit_mov(list,NR_R31,GetNextReg(href.base));
+                     href.base:=NR_R30;
+                   end;
+                 QuickRef:=true;
+               end;
+           end
+         else
+           QuickRef:=true;
+
          if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
          if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
            internalerror(2011021307);
            internalerror(2011021307);
 
 
@@ -1552,29 +1766,77 @@ unit cgcpu;
          regs : tcpuregisterset;
          regs : tcpuregisterset;
          reg : tsuperregister;
          reg : tsuperregister;
       begin
       begin
-        if not(nostackframe) then
+        if po_interrupt in current_procinfo.procdef.procoptions then
           begin
           begin
-            { save int registers }
-            regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
-            if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+            { check if the framepointer is actually used, this is done here because
+              we have to know the size of the locals (must be 0), avr does not know
+              an sp based stack }
+
+            if not(current_procinfo.procdef.stack_tainting_parameter(calleeside)) and
+              (localsize=0) then
+              current_procinfo.framepointer:=NR_NO;
+
+            { save int registers,
+              but only if the procedure returns }
+            if not(po_noreturn in current_procinfo.procdef.procoptions) then
+              regs:=rg[R_INTREGISTER].used_in_proc
+            else
+              regs:=[];
+            { if the framepointer is potentially used, save it always because we need a proper stack frame,
+              even if the procedure never returns, the procedure could be e.g. a nested one accessing
+              an outer stackframe }
+            if current_procinfo.framepointer<>NR_NO then
               regs:=regs+[RS_R28,RS_R29];
               regs:=regs+[RS_R28,RS_R29];
 
 
+            regs:=regs+[RS_R0];
+
             for reg:=RS_R31 downto RS_R0 do
             for reg:=RS_R31 downto RS_R0 do
               if reg in regs then
               if reg in regs then
                 list.concat(taicpu.op_reg(A_PUSH,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
                 list.concat(taicpu.op_reg(A_PUSH,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
 
 
-            if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+            { Save SREG }
+            list.concat(taicpu.op_reg_const(A_IN, NR_R0, $3F));
+            list.concat(taicpu.op_reg(A_PUSH, NR_R0));
+
+            if current_procinfo.framepointer<>NR_NO then
               begin
               begin
                 list.concat(taicpu.op_reg_const(A_IN,NR_R28,NIO_SP_LO));
                 list.concat(taicpu.op_reg_const(A_IN,NR_R28,NIO_SP_LO));
                 list.concat(taicpu.op_reg_const(A_IN,NR_R29,NIO_SP_HI));
                 list.concat(taicpu.op_reg_const(A_IN,NR_R29,NIO_SP_HI));
-              end
+                a_adjust_sp(list,-localsize);
+              end;
+          end
+        else if not(nostackframe) then
+          begin
+            { check if the framepointer is actually used, this is done here because
+              we have to know the size of the locals (must be 0), avr does not know
+              an sp based stack }
+
+            if not(current_procinfo.procdef.stack_tainting_parameter(calleeside)) and
+              (localsize=0) then
+              current_procinfo.framepointer:=NR_NO;
+
+            { save int registers,
+              but only if the procedure returns }
+            if not(po_noreturn in current_procinfo.procdef.procoptions) then
+              regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall)
             else
             else
-              { the framepointer cannot be omitted on avr because sp
-                is not a register but part of the i/o map
-              }
-              internalerror(2011021901);
+              regs:=[];
+            { if the framepointer is potentially used, save it always because we need a proper stack frame,
+              even if the procedure never returns, the procedure could be e.g. a nested one accessing
+              an outer stackframe }
+            if current_procinfo.framepointer<>NR_NO then
+              regs:=regs+[RS_R28,RS_R29];
 
 
-            a_adjust_sp(list,-localsize);
+            for reg:=RS_R31 downto RS_R0 do
+              if reg in regs then
+                list.concat(taicpu.op_reg(A_PUSH,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
+
+            if current_procinfo.framepointer<>NR_NO then
+              begin
+                list.concat(taicpu.op_reg_const(A_IN,NR_R28,NIO_SP_LO));
+                list.concat(taicpu.op_reg_const(A_IN,NR_R29,NIO_SP_HI));
+                a_adjust_sp(list,-localsize);
+              end;
           end;
           end;
       end;
       end;
 
 
@@ -1585,28 +1847,49 @@ unit cgcpu;
         reg : TSuperRegister;
         reg : TSuperRegister;
         LocalSize : longint;
         LocalSize : longint;
       begin
       begin
-        if not(nostackframe) then
+        { every byte counts for avr, so if a subroutine is marked as non-returning, we do
+          not generate any exit code, so we really trust the noreturn directive
+        }
+        if po_noreturn in current_procinfo.procdef.procoptions then
+          exit;
+        if po_interrupt in current_procinfo.procdef.procoptions then
           begin
           begin
-            if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+            regs:=rg[R_INTREGISTER].used_in_proc;
+            if current_procinfo.framepointer<>NR_NO then
               begin
               begin
+                regs:=regs+[RS_R28,RS_R29];
                 LocalSize:=current_procinfo.calc_stackframe_size;
                 LocalSize:=current_procinfo.calc_stackframe_size;
                 a_adjust_sp(list,LocalSize);
                 a_adjust_sp(list,LocalSize);
-                regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
-                if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
-                  regs:=regs+[RS_R28,RS_R29];
+              end;
 
 
-                for reg:=RS_R0 to RS_R31 do
-                  if reg in regs then
-                    list.concat(taicpu.op_reg(A_POP,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
+            { Reload SREG }
+            regs:=regs+[RS_R0];
 
 
-              end
-            else
-              { the framepointer cannot be omitted on avr because sp
-                is not a register but part of the i/o map
-              }
-              internalerror(2011021902);
-          end;
-        list.concat(taicpu.op_none(A_RET));
+            list.concat(taicpu.op_reg(A_POP, NR_R0));
+            list.concat(taicpu.op_const_reg(A_OUT, $3F, NR_R0));
+
+            for reg:=RS_R0 to RS_R31 do
+              if reg in regs then
+                list.concat(taicpu.op_reg(A_POP,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
+
+            list.concat(taicpu.op_none(A_RETI));
+          end
+        else if not(nostackframe) then
+          begin
+            regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
+            if current_procinfo.framepointer<>NR_NO then
+              begin
+                regs:=regs+[RS_R28,RS_R29];
+                LocalSize:=current_procinfo.calc_stackframe_size;
+                a_adjust_sp(list,LocalSize);
+              end;
+            for reg:=RS_R0 to RS_R31 do
+              if reg in regs then
+                list.concat(taicpu.op_reg(A_POP,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
+            list.concat(taicpu.op_none(A_RET));
+          end
+        else
+          list.concat(taicpu.op_none(A_RET));
       end;
       end;
 
 
 
 
@@ -1622,10 +1905,19 @@ unit cgcpu;
             reference_reset(tmpref,0);
             reference_reset(tmpref,0);
             tmpref.symbol:=ref.symbol;
             tmpref.symbol:=ref.symbol;
             tmpref.offset:=ref.offset;
             tmpref.offset:=ref.offset;
-            tmpref.refaddr:=addr_lo8;
+
+            if assigned(ref.symbol) and (ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) then
+              tmpref.refaddr:=addr_lo8_gs
+            else
+              tmpref.refaddr:=addr_lo8;
             list.concat(taicpu.op_reg_ref(A_LDI,r,tmpref));
             list.concat(taicpu.op_reg_ref(A_LDI,r,tmpref));
-            tmpref.refaddr:=addr_hi8;
+
+            if assigned(ref.symbol) and (ref.symbol.typ in [AT_FUNCTION,AT_LABEL]) then
+              tmpref.refaddr:=addr_hi8_gs
+            else
+              tmpref.refaddr:=addr_hi8;
             list.concat(taicpu.op_reg_ref(A_LDI,GetNextReg(r),tmpref));
             list.concat(taicpu.op_reg_ref(A_LDI,GetNextReg(r),tmpref));
+
             if (ref.base<>NR_NO) then
             if (ref.base<>NR_NO) then
               begin
               begin
                 list.concat(taicpu.op_reg_reg(A_ADD,r,ref.base));
                 list.concat(taicpu.op_reg_reg(A_ADD,r,ref.base));
@@ -1732,7 +2024,7 @@ unit cgcpu;
             cg.a_label(list,l);
             cg.a_label(list,l);
             list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
             list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
             list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
             list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
-            a_op_const_reg(list,OP_SUB,countregsize,1,countreg);
+            list.concat(taicpu.op_reg(A_DEC,countreg));
             a_jmp_flags(list,F_NE,l);
             a_jmp_flags(list,F_NE,l);
             // keep registers alive
             // keep registers alive
             list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
             list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
@@ -1744,7 +2036,7 @@ unit cgcpu;
             if not((source.addressmode=AM_UNCHANGED) and
             if not((source.addressmode=AM_UNCHANGED) and
                    (source.symbol=nil) and
                    (source.symbol=nil) and
                    ((source.base=NR_R28) or
                    ((source.base=NR_R28) or
-                    (source.base=NR_R29)) and
+                    (source.base=NR_R30)) and
                     (source.Index=NR_NO) and
                     (source.Index=NR_NO) and
                     (source.Offset in [0..64-len])) and
                     (source.Offset in [0..64-len])) and
               not((source.Base=NR_NO) and (source.Index=NR_NO)) then
               not((source.Base=NR_NO) and (source.Index=NR_NO)) then
@@ -1758,7 +2050,7 @@ unit cgcpu;
             if not((dest.addressmode=AM_UNCHANGED) and
             if not((dest.addressmode=AM_UNCHANGED) and
                    (dest.symbol=nil) and
                    (dest.symbol=nil) and
                    ((dest.base=NR_R28) or
                    ((dest.base=NR_R28) or
-                    (dest.base=NR_R29)) and
+                    (dest.base=NR_R30)) and
                     (dest.Index=NR_No) and
                     (dest.Index=NR_No) and
                     (dest.Offset in [0..64-len])) and
                     (dest.Offset in [0..64-len])) and
               not((dest.Base=NR_NO) and (dest.Index=NR_NO)) then
               not((dest.Base=NR_NO) and (dest.Index=NR_NO)) then

+ 15 - 8
compiler/avr/cpubase.pas

@@ -44,14 +44,16 @@ unit cpubase;
 
 
     type
     type
       TAsmOp=(A_None,
       TAsmOp=(A_None,
-        A_ADD,A_ADC,A_ADIW,A_SUB,A_SUBI,A_SBC,A_SBCI,A_SBRC,A_SBRS,A_CLC,A_SEC,A_SBIW,A_AND,A_ANDI,
-        A_OR,A_ORI,A_EOR,A_COM,A_NEG,A_SBR,A_CBR,A_INC,A_DEC,A_TST,A_CLR,
-        A_SER,A_MUL,A_MULS,A_FMUL,A_FMULS,A_FMULSU,A_RJMP,A_IJMP,
+        A_ADD,A_ADC,A_ADIW,A_SUB,A_SUBI,A_SBC,A_SBCI,A_SBRC,A_SBRS,A_SBIW,A_AND,A_ANDI,
+        A_OR,A_ORI,A_EOR,A_COM,A_NEG,A_SBR,A_CBR,A_INC,A_DEC,A_TST,
+        A_MUL,A_MULS,A_MULSU,A_FMUL,A_FMULS,A_FMULSU,A_RJMP,A_IJMP,
         A_EIJMP,A_JMP,A_RCALL,A_ICALL,R_EICALL,A_CALL,A_RET,A_RETI,A_CPSE,
         A_EIJMP,A_JMP,A_RCALL,A_ICALL,R_EICALL,A_CALL,A_RET,A_RETI,A_CPSE,
         A_CP,A_CPC,A_CPI,A_SBIC,A_SBIS,A_BRxx,A_MOV,A_MOVW,A_LDI,A_LDS,A_LD,A_LDD,
         A_CP,A_CPC,A_CPI,A_SBIC,A_SBIS,A_BRxx,A_MOV,A_MOVW,A_LDI,A_LDS,A_LD,A_LDD,
         A_STS,A_ST,A_STD,A_LPM,A_ELPM,A_SPM,A_IN,A_OUT,A_PUSH,A_POP,
         A_STS,A_ST,A_STD,A_LPM,A_ELPM,A_SPM,A_IN,A_OUT,A_PUSH,A_POP,
         A_LSL,A_LSR,A_ROL,A_ROR,A_ASR,A_SWAP,A_BSET,A_BCLR,A_SBI,A_CBI,
         A_LSL,A_LSR,A_ROL,A_ROR,A_ASR,A_SWAP,A_BSET,A_BCLR,A_SBI,A_CBI,
-        A_BST,A_BLD,A_Sxx,A_CLI,A_BRAK,A_NOP,A_SLEEP,A_WDR);
+        A_SEC,A_SEH,A_SEI,A_SEN,A_SER,A_SES,A_SET,A_SEV,A_SEZ,
+        A_CLC,A_CLH,A_CLI,A_CLN,A_CLR,A_CLS,A_CLT,A_CLV,A_CLZ,
+        A_BST,A_BLD,A_BREAK,A_NOP,A_SLEEP,A_WDR);
 
 
 
 
       { This should define the array of instructions as string }
       { This should define the array of instructions as string }
@@ -66,6 +68,7 @@ unit cpubase;
       { call/reg instructions (A_RCALL,A_ICALL,A_CALL,A_RET,A_RETI) are not considered as jmp instructions for the usage cases of
       { call/reg instructions (A_RCALL,A_ICALL,A_CALL,A_RET,A_RETI) are not considered as jmp instructions for the usage cases of
         this set }
         this set }
       jmp_instructions = [A_BRxx,A_SBIC,A_SBIS,A_JMP,A_EIJMP,A_RJMP,A_CPSE,A_IJMP];
       jmp_instructions = [A_BRxx,A_SBIC,A_SBIS,A_JMP,A_EIJMP,A_RJMP,A_CPSE,A_IJMP];
+      call_jmp_instructions = [A_ICALL,A_RCALL,A_CALL,A_RET,A_RETI]+jmp_instructions;
 
 
 {*****************************************************************************
 {*****************************************************************************
                                   Registers
                                   Registers
@@ -212,9 +215,13 @@ unit cpubase;
       { Defines the default address size for a processor, }
       { Defines the default address size for a processor, }
       OS_ADDR = OS_16;
       OS_ADDR = OS_16;
       { the natural int size for a processor,
       { the natural int size for a processor,
-        has to match osuinttype/ossinttype as initialized in psystem }
-      OS_INT = OS_16;
-      OS_SINT = OS_S16;
+        has to match osuinttype/ossinttype as initialized in psystem,
+        initially, this was OS_16/OS_S16 on avr, but experience has
+        proven that it is better to make it 8 Bit thus having the same
+        size as a register.
+      }
+      OS_INT = OS_8;
+      OS_SINT = OS_S8;
       { the maximum float size for a processor,           }
       { the maximum float size for a processor,           }
       OS_FLOAT = OS_F64;
       OS_FLOAT = OS_F64;
       { the size of a vector register for a processor     }
       { the size of a vector register for a processor     }
@@ -481,7 +488,7 @@ unit cpubase;
 
 
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
       begin
-        is_calljmp:= o in jmp_instructions;
+        is_calljmp:= o in call_jmp_instructions;
       end;
       end;
 
 
 
 

+ 295 - 62
compiler/avr/cpuinfo.pas

@@ -58,11 +58,150 @@ Type
 
 
       ct_avrsim,
       ct_avrsim,
 
 
+      ct_atmega645,
+      ct_atmega165a,
+      ct_attiny44a,
+      ct_atmega649a,
+      ct_atmega32u4,
+      ct_attiny26,
+      ct_at90usb1287,
+      ct_at90pwm161,
+      ct_attiny48,
+      ct_atmega168p,
+      ct_attiny10,
+      ct_attiny84a,
+      ct_at90usb82,
+      ct_attiny2313,
+      ct_attiny461,
+      ct_atmega3250pa,
+      ct_atmega3290a,
+      ct_atmega165p,
+      ct_attiny43u,
+      ct_at90usb162,
+      ct_atmega16u4,
+      ct_attiny24a,
+      ct_atmega88p,
+      ct_attiny88,
+      ct_atmega6490p,
+      ct_attiny40,
+      ct_atmega324p,
+      ct_attiny167,
+      ct_atmega328,
+      ct_attiny861,
+      ct_attiny85,
+      ct_atmega64m1,
+      ct_atmega645p,
+      ct_atmega8u2,
+      ct_atmega329a,
+      ct_atmega8a,
+      ct_atmega324pa,
+      ct_atmega32hvb,
+      ct_at90pwm316,
+      ct_at90pwm3b,
+      ct_at90usb646,
+      ct_attiny20,
       ct_atmega16,
       ct_atmega16,
-      ct_atmega32,
+      ct_atmega48a,
+      ct_attiny24,
+      ct_atmega644,
+      ct_atmega1284,
+      ct_ata6285,
+      ct_at90can64,
       ct_atmega48,
       ct_atmega48,
+      ct_at90can32,
+      ct_attiny9,
+      ct_attiny87,
+      ct_atmega1281,
+      ct_at90pwm216,
+      ct_atmega3250a,
+      ct_atmega88a,
+      ct_atmega128rfa1,
+      ct_atmega3290pa,
+      ct_at90pwm81,
+      ct_atmega325p,
+      ct_attiny84,
+      ct_atmega328p,
+      ct_attiny13a,
+      ct_atmega8,
+      ct_atmega1284p,
+      ct_atmega16u2,
+      ct_attiny45,
+      ct_atmega3250,
+      ct_atmega329,
+      ct_atmega32a,
+      ct_attiny5,
+      ct_at90can128,
+      ct_atmega6490,
+      ct_atmega8515,
+      ct_atmega88pa,
+      ct_atmega168a,
+      ct_atmega128,
+      ct_at90usb1286,
+      ct_atmega164pa,
+      ct_attiny828,
+      ct_atmega88,
+      ct_atmega645a,
+      ct_atmega3290p,
+      ct_atmega644p,
+      ct_atmega164a,
+      ct_attiny4313,
+      ct_atmega162,
+      ct_atmega32c1,
+      ct_atmega128a,
+      ct_atmega324a,
+      ct_attiny13,
+      ct_atmega2561,
+      ct_atmega169a,
+      ct_attiny261,
+      ct_atmega644a,
+      ct_atmega3290,
+      ct_atmega64a,
+      ct_atmega169p,
+      ct_atmega2560,
+      ct_atmega32,
+      ct_attiny861a,
+      ct_attiny28,
+      ct_atmega48p,
+      ct_atmega8535,
+      ct_atmega168pa,
+      ct_atmega16m1,
+      ct_atmega16hvb,
+      ct_atmega164p,
+      ct_atmega325a,
+      ct_atmega640,
+      ct_atmega6450,
+      ct_atmega329p,
+      ct_ata6286,
+      ct_at90usb647,
+      ct_atmega168,
+      ct_atmega6490a,
+      ct_atmega32m1,
+      ct_atmega64c1,
+      ct_atmega32u2,
+      ct_attiny4,
+      ct_atmega644pa,
+      ct_at90pwm1,
+      ct_attiny44,
+      ct_atmega325pa,
+      ct_atmega6450a,
+      ct_attiny2313a,
+      ct_atmega329pa,
+      ct_attiny461a,
+      ct_atmega6450p,
       ct_atmega64,
       ct_atmega64,
-      ct_atmega128
+      ct_atmega165pa,
+      ct_atmega16a,
+      ct_atmega649,
+      ct_atmega1280,
+      ct_at90pwm2b,
+      ct_atmega649p,
+      ct_atmega3250p,
+      ct_atmega48pa,
+      ct_attiny1634,
+      ct_atmega325,
+      ct_atmega169pa,
+      ct_attiny261a,
+      ct_attiny25
      );
      );
 
 
 Const
 Const
@@ -113,7 +252,7 @@ Const
    {$WARN 3177 OFF}
    {$WARN 3177 OFF}
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    ((
    ((
-   	controllertypestr:'';
+        controllertypestr:'';
         controllerunitstr:'';
         controllerunitstr:'';
         flashbase:0;
         flashbase:0;
         flashsize:0;
         flashsize:0;
@@ -121,60 +260,10 @@ Const
         sramsize:0;
         sramsize:0;
         eeprombase:0;
         eeprombase:0;
         eepromsize:0
         eepromsize:0
-   	),
-   	(
-        controllertypestr:'AVRSIM';
-        controllerunitstr:'AVRSIM';
-        flashbase:0;
-        flashsize:$20000;
-        srambase:0;
-        sramsize:4096;
-        eeprombase:0;
-        eepromsize:4096;
-        ),
-        (
-   	controllertypestr:'ATMEGA16';
-        controllerunitstr:'ATMEGA16';
-        flashbase:0;
-        flashsize:$4000;
-        srambase:0;
-        sramsize:1024;
-        eeprombase:0;
-        eepromsize:512
         ),
         ),
         (
         (
-   	controllertypestr:'ATMEGA32';
-        controllerunitstr:'ATMEGA32';
-        flashbase:0;
-        flashsize:$8000;
-        srambase:0;
-        sramsize:1024;
-        eeprombase:0;
-        eepromsize:512
-        ),
-   	(
-        controllertypestr:'ATMEGA48';
-        controllerunitstr:'ATMEGA48';
-        flashbase:0;
-        flashsize:$1000;
-        srambase:0;
-        sramsize:512;
-        eeprombase:0;
-        eepromsize:256;
-        ),
-   	(
-        controllertypestr:'ATMEGA64';
-        controllerunitstr:'ATMEGA64';
-        flashbase:0;
-        flashsize:$10000;
-        srambase:0;
-        sramsize:4096;
-        eeprombase:0;
-        eepromsize:2048;
-        ),
-   	(
-        controllertypestr:'ATMEGA128';
-        controllerunitstr:'ATMEGA128';
+        controllertypestr:'AVRSIM';
+        controllerunitstr:'AVRSIM';
         flashbase:0;
         flashbase:0;
         flashsize:$20000;
         flashsize:$20000;
         srambase:0;
         srambase:0;
@@ -182,6 +271,150 @@ Const
         eeprombase:0;
         eeprombase:0;
         eepromsize:4096;
         eepromsize:4096;
         )
         )
+        ,(controllertypestr:'ATMEGA645'; controllerunitstr:'ATMEGA645'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA165A'; controllerunitstr:'ATMEGA165A'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY44A'; controllerunitstr:'ATTINY44A'; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA649A'; controllerunitstr:'ATMEGA649A'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA32U4'; controllerunitstr:'ATMEGA32U4'; flashbase:0; flashsize:32768; srambase:256; sramsize:2560; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY26'; controllerunitstr:'ATTINY26'; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'AT90USB1287'; controllerunitstr:'AT90USB1287'; flashbase:0; flashsize:131072; srambase:256; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'AT90PWM161'; controllerunitstr:'AT90PWM161'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY48'; controllerunitstr:'ATTINY48'; flashbase:0; flashsize:4096; srambase:256; sramsize:256; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'ATMEGA168P'; controllerunitstr:'ATMEGA168P'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY10'; controllerunitstr:'ATTINY10'; flashbase:0; flashsize:1024; srambase:64; sramsize:32; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATTINY84A'; controllerunitstr:'ATTINY84A'; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'AT90USB82'; controllerunitstr:'AT90USB82'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY2313'; controllerunitstr:'ATTINY2313'; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATTINY461'; controllerunitstr:'ATTINY461'; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA3250PA'; controllerunitstr:'ATMEGA3250PA'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA3290A'; controllerunitstr:'ATMEGA3290A'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA165P'; controllerunitstr:'ATMEGA165P'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY43U'; controllerunitstr:'ATTINY43U'; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'AT90USB162'; controllerunitstr:'AT90USB162'; flashbase:0; flashsize:16384; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA16U4'; controllerunitstr:'ATMEGA16U4'; flashbase:0; flashsize:16384; srambase:256; sramsize:1280; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY24A'; controllerunitstr:'ATTINY24A'; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATMEGA88P'; controllerunitstr:'ATMEGA88P'; flashbase:0; flashsize:8192; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY88'; controllerunitstr:'ATTINY88'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'ATMEGA6490P'; controllerunitstr:'ATMEGA6490P'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATTINY40'; controllerunitstr:'ATTINY40'; flashbase:0; flashsize:4096; srambase:64; sramsize:256; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATMEGA324P'; controllerunitstr:'ATMEGA324P'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY167'; controllerunitstr:'ATTINY167'; flashbase:0; flashsize:16384; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA328'; controllerunitstr:'ATMEGA328'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY861'; controllerunitstr:'ATTINY861'; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY85'; controllerunitstr:'ATTINY85'; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA64M1'; controllerunitstr:'ATMEGA64M1'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA645P'; controllerunitstr:'ATMEGA645P'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA8U2'; controllerunitstr:'ATMEGA8U2'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA329A'; controllerunitstr:'ATMEGA329A'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA8A'; controllerunitstr:'ATMEGA8A'; flashbase:0; flashsize:8192; srambase:96; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA324PA'; controllerunitstr:'ATMEGA324PA'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA32HVB'; controllerunitstr:'ATMEGA32HVB'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'AT90PWM316'; controllerunitstr:'AT90PWM316'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'AT90PWM3B'; controllerunitstr:'AT90PWM3B'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'AT90USB646'; controllerunitstr:'AT90USB646'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATTINY20'; controllerunitstr:'ATTINY20'; flashbase:0; flashsize:2048; srambase:64; sramsize:128; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATMEGA16'; controllerunitstr:'ATMEGA16'; flashbase:0; flashsize:16384; srambase:96; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA48A'; controllerunitstr:'ATMEGA48A'; flashbase:0; flashsize:4096; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATTINY24'; controllerunitstr:'ATTINY24'; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATMEGA644'; controllerunitstr:'ATMEGA644'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA1284'; controllerunitstr:'ATMEGA1284'; flashbase:0; flashsize:131072; srambase:256; sramsize:16384; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATA6285'; controllerunitstr:'ATA6285'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:320)
+        ,(controllertypestr:'AT90CAN64'; controllerunitstr:'AT90CAN64'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA48'; controllerunitstr:'ATMEGA48'; flashbase:0; flashsize:4096; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'AT90CAN32'; controllerunitstr:'AT90CAN32'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY9'; controllerunitstr:'ATTINY9'; flashbase:0; flashsize:1024; srambase:64; sramsize:32; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATTINY87'; controllerunitstr:'ATTINY87'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA1281'; controllerunitstr:'ATMEGA1281'; flashbase:0; flashsize:131072; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'AT90PWM216'; controllerunitstr:'AT90PWM216'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA3250A'; controllerunitstr:'ATMEGA3250A'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA88A'; controllerunitstr:'ATMEGA88A'; flashbase:0; flashsize:8192; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA128RFA1'; controllerunitstr:'ATMEGA128RFA1'; flashbase:0; flashsize:131072; srambase:512; sramsize:16384; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA3290PA'; controllerunitstr:'ATMEGA3290PA'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'AT90PWM81'; controllerunitstr:'AT90PWM81'; flashbase:0; flashsize:8192; srambase:256; sramsize:256; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA325P'; controllerunitstr:'ATMEGA325P'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY84'; controllerunitstr:'ATTINY84'; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA328P'; controllerunitstr:'ATMEGA328P'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY13A'; controllerunitstr:'ATTINY13A'; flashbase:0; flashsize:1024; srambase:96; sramsize:64; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'ATMEGA8'; controllerunitstr:'ATMEGA8'; flashbase:0; flashsize:8192; srambase:96; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA1284P'; controllerunitstr:'ATMEGA1284P'; flashbase:0; flashsize:131072; srambase:256; sramsize:16384; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA16U2'; controllerunitstr:'ATMEGA16U2'; flashbase:0; flashsize:16384; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY45'; controllerunitstr:'ATTINY45'; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA3250'; controllerunitstr:'ATMEGA3250'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA329'; controllerunitstr:'ATMEGA329'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA32A'; controllerunitstr:'ATMEGA32A'; flashbase:0; flashsize:32768; srambase:96; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY5'; controllerunitstr:'ATTINY5'; flashbase:0; flashsize:512; srambase:64; sramsize:32; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'AT90CAN128'; controllerunitstr:'AT90CAN128'; flashbase:0; flashsize:131072; srambase:256; sramsize:4096; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA6490'; controllerunitstr:'ATMEGA6490'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA8515'; controllerunitstr:'ATMEGA8515'; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA88PA'; controllerunitstr:'ATMEGA88PA'; flashbase:0; flashsize:8192; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA168A'; controllerunitstr:'ATMEGA168A'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA128'; controllerunitstr:'ATMEGA128'; flashbase:0; flashsize:131072; srambase:256; sramsize:4096; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'AT90USB1286'; controllerunitstr:'AT90USB1286'; flashbase:0; flashsize:131072; srambase:256; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA164PA'; controllerunitstr:'ATMEGA164PA'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY828'; controllerunitstr:'ATTINY828'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA88'; controllerunitstr:'ATMEGA88'; flashbase:0; flashsize:8192; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA645A'; controllerunitstr:'ATMEGA645A'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA3290P'; controllerunitstr:'ATMEGA3290P'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA644P'; controllerunitstr:'ATMEGA644P'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA164A'; controllerunitstr:'ATMEGA164A'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY4313'; controllerunitstr:'ATTINY4313'; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA162'; controllerunitstr:'ATMEGA162'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA32C1'; controllerunitstr:'ATMEGA32C1'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA128A'; controllerunitstr:'ATMEGA128A'; flashbase:0; flashsize:131072; srambase:256; sramsize:4096; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA324A'; controllerunitstr:'ATMEGA324A'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY13'; controllerunitstr:'ATTINY13'; flashbase:0; flashsize:1024; srambase:96; sramsize:64; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'ATMEGA2561'; controllerunitstr:'ATMEGA2561'; flashbase:0; flashsize:262144; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA169A'; controllerunitstr:'ATMEGA169A'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY261'; controllerunitstr:'ATTINY261'; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATMEGA644A'; controllerunitstr:'ATMEGA644A'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA3290'; controllerunitstr:'ATMEGA3290'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA64A'; controllerunitstr:'ATMEGA64A'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA169P'; controllerunitstr:'ATMEGA169P'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA2560'; controllerunitstr:'ATMEGA2560'; flashbase:0; flashsize:262144; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA32'; controllerunitstr:'ATMEGA32'; flashbase:0; flashsize:32768; srambase:96; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY861A'; controllerunitstr:'ATTINY861A'; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY28'; controllerunitstr:'ATTINY28'; flashbase:0; flashsize:2048; srambase:0; sramsize:0; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATMEGA48P'; controllerunitstr:'ATMEGA48P'; flashbase:0; flashsize:4096; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA8535'; controllerunitstr:'ATMEGA8535'; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA168PA'; controllerunitstr:'ATMEGA168PA'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA16M1'; controllerunitstr:'ATMEGA16M1'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA16HVB'; controllerunitstr:'ATMEGA16HVB'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA164P'; controllerunitstr:'ATMEGA164P'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA325A'; controllerunitstr:'ATMEGA325A'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA640'; controllerunitstr:'ATMEGA640'; flashbase:0; flashsize:65536; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA6450'; controllerunitstr:'ATMEGA6450'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA329P'; controllerunitstr:'ATMEGA329P'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATA6286'; controllerunitstr:'ATA6286'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:320)
+        ,(controllertypestr:'AT90USB647'; controllerunitstr:'AT90USB647'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA168'; controllerunitstr:'ATMEGA168'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA6490A'; controllerunitstr:'ATMEGA6490A'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA32M1'; controllerunitstr:'ATMEGA32M1'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA64C1'; controllerunitstr:'ATMEGA64C1'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA32U2'; controllerunitstr:'ATMEGA32U2'; flashbase:0; flashsize:32768; srambase:256; sramsize:1024; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY4'; controllerunitstr:'ATTINY4'; flashbase:0; flashsize:512; srambase:64; sramsize:32; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATMEGA644PA'; controllerunitstr:'ATMEGA644PA'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'AT90PWM1'; controllerunitstr:'AT90PWM1'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY44'; controllerunitstr:'ATTINY44'; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA325PA'; controllerunitstr:'ATMEGA325PA'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA6450A'; controllerunitstr:'ATMEGA6450A'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATTINY2313A'; controllerunitstr:'ATTINY2313A'; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATMEGA329PA'; controllerunitstr:'ATMEGA329PA'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY461A'; controllerunitstr:'ATTINY461A'; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA6450P'; controllerunitstr:'ATMEGA6450P'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA64'; controllerunitstr:'ATMEGA64'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA165PA'; controllerunitstr:'ATMEGA165PA'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA16A'; controllerunitstr:'ATMEGA16A'; flashbase:0; flashsize:16384; srambase:96; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA649'; controllerunitstr:'ATMEGA649'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA1280'; controllerunitstr:'ATMEGA1280'; flashbase:0; flashsize:131072; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'AT90PWM2B'; controllerunitstr:'AT90PWM2B'; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA649P'; controllerunitstr:'ATMEGA649P'; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA3250P'; controllerunitstr:'ATMEGA3250P'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA48PA'; controllerunitstr:'ATMEGA48PA'; flashbase:0; flashsize:4096; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATTINY1634'; controllerunitstr:'ATTINY1634'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA325'; controllerunitstr:'ATMEGA325'; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA169PA'; controllerunitstr:'ATMEGA169PA'; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY261A'; controllerunitstr:'ATTINY261A'; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATTINY25'; controllerunitstr:'ATTINY25'; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
    );
    );
 
 
    { Supported optimizations, only used for information }
    { Supported optimizations, only used for information }
@@ -214,17 +447,17 @@ Const
 
 
  const
  const
    cpu_capabilities : array[tcputype] of set of tcpuflags =
    cpu_capabilities : array[tcputype] of set of tcpuflags =
-     ( { cpu_none } [],
-       { cpu_avr1 } [CPUAVR_2_BYTE_PC],
-       { cpu_avr2 } [CPUAVR_2_BYTE_PC],
+     ( { cpu_none  } [],
+       { cpu_avr1  } [CPUAVR_2_BYTE_PC],
+       { cpu_avr2  } [CPUAVR_2_BYTE_PC],
        { cpu_avr25 } [CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_2_BYTE_PC],
        { cpu_avr25 } [CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_2_BYTE_PC],
-       { cpu_avr3 } [CPUAVR_HAS_JMP_CALL,CPUAVR_2_BYTE_PC],
+       { cpu_avr3  } [CPUAVR_HAS_JMP_CALL,CPUAVR_2_BYTE_PC],
        { cpu_avr31 } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_RAMPZ,CPUAVR_HAS_ELPM,CPUAVR_2_BYTE_PC],
        { cpu_avr31 } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_RAMPZ,CPUAVR_HAS_ELPM,CPUAVR_2_BYTE_PC],
        { cpu_avr35 } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_2_BYTE_PC],
        { cpu_avr35 } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_2_BYTE_PC],
-       { cpu_avr4 } [CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_HAS_MUL,CPUAVR_2_BYTE_PC],
-       { cpu_avr5 } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_HAS_MUL,CPUAVR_2_BYTE_PC],
+       { cpu_avr4  } [CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_HAS_MUL,CPUAVR_2_BYTE_PC],
+       { cpu_avr5  } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_HAS_MUL,CPUAVR_2_BYTE_PC],
        { cpu_avr51 } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_HAS_MUL,CPUAVR_HAS_RAMPZ,CPUAVR_HAS_ELPM,CPUAVR_HAS_ELPMX,CPUAVR_2_BYTE_PC],
        { cpu_avr51 } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_HAS_MUL,CPUAVR_HAS_RAMPZ,CPUAVR_HAS_ELPM,CPUAVR_HAS_ELPMX,CPUAVR_2_BYTE_PC],
-       { cpu_avr6 } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_HAS_MUL,CPUAVR_HAS_RAMPZ,CPUAVR_HAS_ELPM,CPUAVR_HAS_ELPMX,CPUAVR_3_BYTE_PC]
+       { cpu_avr6  } [CPUAVR_HAS_JMP_CALL,CPUAVR_HAS_MOVW,CPUAVR_HAS_LPMX,CPUAVR_HAS_MUL,CPUAVR_HAS_RAMPZ,CPUAVR_HAS_ELPM,CPUAVR_HAS_ELPMX,CPUAVR_3_BYTE_PC]
      );
      );
 
 
 Implementation
 Implementation

+ 8 - 4
compiler/avr/cpupara.pas

@@ -99,7 +99,10 @@ unit cpupara;
             filedef:
             filedef:
               getparaloc:=LOC_REGISTER;
               getparaloc:=LOC_REGISTER;
             arraydef:
             arraydef:
-              getparaloc:=LOC_REFERENCE;
+              if is_dynamic_array(p) then
+                getparaloc:=LOC_REGISTER
+              else
+                getparaloc:=LOC_REFERENCE;
             setdef:
             setdef:
               if is_smallset(p) then
               if is_smallset(p) then
                 getparaloc:=LOC_REGISTER
                 getparaloc:=LOC_REGISTER
@@ -252,7 +255,7 @@ unit cpupara;
 
 
             if push_addr_param(hp.varspez,paradef,p.proccalloption) then
             if push_addr_param(hp.varspez,paradef,p.proccalloption) then
               begin
               begin
-                paradef:=getpointerdef(paradef);
+                paradef:=cpointerdef.getreusable(paradef);
                 loc:=LOC_REGISTER;
                 loc:=LOC_REGISTER;
                 paracgsize:=OS_ADDR;
                 paracgsize:=OS_ADDR;
                 paralen:=tcgsize2size[OS_ADDR];
                 paralen:=tcgsize2size[OS_ADDR];
@@ -343,13 +346,14 @@ unit cpupara;
                         else
                         else
                           { parameters are always passed completely in registers or in memory on avr }
                           { parameters are always passed completely in registers or in memory on avr }
                           internalerror(2015041002);
                           internalerror(2015041002);
+                        dec(paralen,tcgsize2size[paraloc^.size]);
                       end;
                       end;
                     LOC_REFERENCE:
                     LOC_REFERENCE:
                       begin
                       begin
                         if push_addr_param(hp.varspez,paradef,p.proccalloption) then
                         if push_addr_param(hp.varspez,paradef,p.proccalloption) then
                           begin
                           begin
                             paraloc^.size:=OS_ADDR;
                             paraloc^.size:=OS_ADDR;
-                            paraloc^.def:=getpointerdef(paradef);
+                            paraloc^.def:=cpointerdef.getreusable(paradef);
                             assignintreg
                             assignintreg
                           end
                           end
                         else
                         else
@@ -360,6 +364,7 @@ unit cpupara;
                              paraloc^.reference.offset:=stack_offset;
                              paraloc^.reference.offset:=stack_offset;
                              inc(stack_offset,hp.vardef.size);
                              inc(stack_offset,hp.vardef.size);
                           end;
                           end;
+                        dec(paralen,hp.vardef.size);
                       end;
                       end;
                     else
                     else
                       internalerror(2002071002);
                       internalerror(2002071002);
@@ -372,7 +377,6 @@ unit cpupara;
                          inc(paraloc^.reference.offset,2);
                          inc(paraloc^.reference.offset,2);
                        end;
                        end;
                    end;
                    end;
-                 dec(paralen,tcgsize2size[paraloc^.size]);
                  firstparaloc:=false;
                  firstparaloc:=false;
                end;
                end;
           end;
           end;

+ 10 - 3
compiler/avr/cpupi.pas

@@ -56,7 +56,9 @@ unit cpupi;
     procedure tavrprocinfo.set_first_temp_offset;
     procedure tavrprocinfo.set_first_temp_offset;
       begin
       begin
         if tg.direction = -1 then
         if tg.direction = -1 then
-          tg.setfirsttemp(0)
+          tg.setfirsttemp(-1)
+        else if not (po_nostackframe in procdef.procoptions) then
+          tg.setfirsttemp(maxpushedparasize+1)
         else
         else
           tg.setfirsttemp(maxpushedparasize);
           tg.setfirsttemp(maxpushedparasize);
       end;
       end;
@@ -64,8 +66,13 @@ unit cpupi;
 
 
     function tavrprocinfo.calc_stackframe_size:longint;
     function tavrprocinfo.calc_stackframe_size:longint;
       begin
       begin
-        maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
-        result:=Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+maxpushedparasize;
+        if tg.lasttemp=2 then
+          { correct that lasttemp is 2 in case of an empty stack due to the post-decrement pushing and an additional correction
+            in tgobj.setfirsttemp.
+          }
+          result:=maxpushedparasize
+        else
+          result:=tg.direction*tg.lasttemp+maxpushedparasize;
       end;
       end;
 
 
 
 

+ 6 - 4
compiler/avr/itcpugas.pas

@@ -35,14 +35,16 @@ interface
       processor manufacturer.
       processor manufacturer.
     }
     }
     gas_op2str : op2strtable = ('',
     gas_op2str : op2strtable = ('',
-        'add','adc','adiw','sub','subi','sbc','sbci','sbrc','sbrs','clc','sec','sbiw','and','andi',
-        'or','ori','eor','com','neg','sbr','cbr','inc','dec','tst','clr',
-        'ser','mul','muls','fmul','fmuls','fmulsu','rjmp','ijmp',
+        'add','adc','adiw','sub','subi','sbc','sbci','sbrc','sbrs','sbiw','and','andi',
+        'or','ori','eor','com','neg','sbr','cbr','inc','dec','tst',
+        'mul','muls','mulsu','fmul','fmuls','fmulsu','rjmp','ijmp',
         'eijmp','jmp','rcall','icall','eicall','call','ret','reti','cpse',
         'eijmp','jmp','rcall','icall','eicall','call','ret','reti','cpse',
         'cp','cpc','cpi','sbic','sbis','br','mov','movw','ldi','lds','ld','ldd',
         'cp','cpc','cpi','sbic','sbis','br','mov','movw','ldi','lds','ld','ldd',
         'sts','st','std','lpm','elpm','spm','in','out','push','pop',
         'sts','st','std','lpm','elpm','spm','in','out','push','pop',
         'lsl','lsr','rol','ror','asr','swap','bset','bclr','sbi','cbi',
         'lsl','lsr','rol','ror','asr','swap','bset','bclr','sbi','cbi',
-        'bst','bld','s','cli','brak','nop','sleep','wdr');
+        'sec','seh','sei','sen','ser','ses','set','sev','sez',
+        'clc','clh','cli','cln','clr','cls','clt','clv','clz',
+        'bst','bld','break','nop','sleep','wdr');
 
 
     function gas_regnum_search(const s:string):Tregister;
     function gas_regnum_search(const s:string):Tregister;
     function gas_regname(r:Tregister):string;
     function gas_regname(r:Tregister):string;

+ 23 - 10
compiler/avr/navradd.pas

@@ -198,7 +198,7 @@ interface
             swapleftright;
             swapleftright;
             { if we have to swap back and left is a constant, force it to a register because we cannot generate
             { if we have to swap back and left is a constant, force it to a register because we cannot generate
               the needed code using a constant }
               the needed code using a constant }
-            if left.location.loc=LOC_CONSTANT then
+            if (left.location.loc=LOC_CONSTANT) and (left.location.value<>0) then
               hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
               hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
           end;
           end;
 
 
@@ -206,12 +206,16 @@ interface
           begin
           begin
             { decrease register pressure on registers >= r16 }
             { decrease register pressure on registers >= r16 }
             if (right.location.value and $ff)=0 then
             if (right.location.value and $ff)=0 then
-              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,left.location.register,NR_R1))
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,NR_R1))
             else
             else
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CPI,left.location.register,right.location.value and $ff))
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CPI,left.location.register,right.location.value and $ff))
           end
           end
+        { on the left side, we allow only a constant if it is 0 }
+        else if (left.location.loc=LOC_CONSTANT) and (left.location.value=0) then
+          current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,NR_R1,right.location.register))
         else
         else
           current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,right.location.register));
           current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,left.location.register,right.location.register));
+
         tmpreg1:=left.location.register;
         tmpreg1:=left.location.register;
         tmpreg2:=right.location.register;
         tmpreg2:=right.location.register;
 
 
@@ -219,26 +223,35 @@ interface
           begin
           begin
             if i=5 then
             if i=5 then
               begin
               begin
-                tmpreg1:=left.location.registerhi;
+                if left.location.loc<>LOC_CONSTANT then
+                  tmpreg1:=left.location.registerhi;
                 if right.location.loc<>LOC_CONSTANT then
                 if right.location.loc<>LOC_CONSTANT then
                   tmpreg2:=right.location.registerhi;
                   tmpreg2:=right.location.registerhi;
               end
               end
             else
             else
               begin
               begin
-                tmpreg1:=GetNextReg(tmpreg1);
+                if left.location.loc<>LOC_CONSTANT then
+                  tmpreg1:=GetNextReg(tmpreg1);
                 if right.location.loc<>LOC_CONSTANT then
                 if right.location.loc<>LOC_CONSTANT then
                   tmpreg2:=GetNextReg(tmpreg2);
                   tmpreg2:=GetNextReg(tmpreg2);
               end;
               end;
             if right.location.loc=LOC_CONSTANT then
             if right.location.loc=LOC_CONSTANT then
               begin
               begin
-                tmpreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
-                cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_8,(right.location.value64 shr (i*8)) and $ff,tmpreg2);
-                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
+                { just use R1? }
+                if ((right.location.value64 shr ((i-1)*8)) and $ff)=0 then
+                  current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,NR_R1))
+                else
+                  begin
+                    tmpreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_8);
+                    cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_8,(right.location.value64 shr ((i-1)*8)) and $ff,tmpreg2);
+                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
+                  end;
               end
               end
+            { above it is checked, if left=0, then a constant is allowed }
+            else if (left.location.loc=LOC_CONSTANT) and (left.location.value=0) then
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,NR_R1,tmpreg2))
             else
             else
-              begin
-                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
-              end;
+              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
           end;
           end;
 
 
         location_reset(location,LOC_FLAGS,OS_NO);
         location_reset(location,LOC_FLAGS,OS_NO);

+ 64 - 159
compiler/avr/navrmat.pas

@@ -29,20 +29,20 @@ interface
       node,nmat,ncgmat;
       node,nmat,ncgmat;
 
 
     type
     type
-      tavrmoddivnode = class(tmoddivnode)
-        function first_moddivint: tnode;override;
-        procedure pass_generate_code;override;
-      end;
-
       tavrnotnode = class(tcgnotnode)
       tavrnotnode = class(tcgnotnode)
         procedure second_boolean;override;
         procedure second_boolean;override;
       end;
       end;
 
 
+      tavrshlshrnode = class(tcgshlshrnode)
+        procedure second_integer;override;
+      end;
+
 implementation
 implementation
 
 
     uses
     uses
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,constexp,
       cutils,verbose,globals,constexp,
+      symtype,symdef,
       aasmbase,aasmcpu,aasmtai,aasmdata,
       aasmbase,aasmcpu,aasmtai,aasmdata,
       defutil,
       defutil,
       cgbase,cgobj,hlcgobj,cgutils,
       cgbase,cgobj,hlcgobj,cgutils,
@@ -51,159 +51,6 @@ implementation
       cpubase,
       cpubase,
       ncgutil,cgcpu;
       ncgutil,cgcpu;
 
 
-{*****************************************************************************
-                             TAVRMODDIVNODE
-*****************************************************************************}
-
-    function tavrmoddivnode.first_moddivint: tnode;
-      var
-        power  : longint;
-      begin
-        if (right.nodetype=ordconstn) and
-          (nodetype=divn) and
-          (ispowerof2(tordconstnode(right).value,power) or
-           (tordconstnode(right).value=1) or
-           (tordconstnode(right).value=int64(-1))
-          ) and
-          not(is_64bitint(resultdef)) then
-          result:=nil
-        else
-          result:=inherited first_moddivint;
-      end;
-
-
-    procedure tavrmoddivnode.pass_generate_code;
-      var
-        power  : longint;
-        numerator,
-        helper1,
-        helper2,
-        resultreg  : tregister;
-        size       : Tcgsize;
-       procedure genOrdConstNodeDiv;
-         begin
-{
-           if tordconstnode(right).value=0 then
-             internalerror(2005061701)
-           else if tordconstnode(right).value=1 then
-             cg.a_load_reg_reg(current_asmdata.CurrAsmList, OS_INT, OS_INT, numerator, resultreg)
-           else if (tordconstnode(right).value = int64(-1)) then
-             begin
-               // note: only in the signed case possible..., may overflow
-               current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_MVN,
-                 resultreg,numerator),toppostfix(ord(cs_check_overflow in current_settings.localswitches)*ord(PF_S))));
-             end
-           else if ispowerof2(tordconstnode(right).value,power) then
-             begin
-               if (is_signed(right.resultdef)) then
-                 begin
-                    helper1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                    helper2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_ASR;
-                    so.shiftimm:=31;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_MOV,helper1,numerator,so));
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_LSR;
-                    so.shiftimm:=32-power;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,helper2,numerator,helper1,so));
-                    shifterop_reset(so);
-                    so.shiftmode:=SM_ASR;
-                    so.shiftimm:=power;
-                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_MOV,resultreg,helper2,so));
-                  end
-               else
-                 cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,power,numerator,resultreg)
-             end;
-}
-         end;
-
-
-       procedure genOrdConstNodeMod;
-         var
-             modreg, maskreg, tempreg : tregister;
-         begin
-{
-             if (tordconstnode(right).value = 0) then begin
-                 internalerror(2005061702);
-             end
-             else if (abs(tordconstnode(right).value.svalue) = 1) then
-             begin
-                // x mod +/-1 is always zero
-                cg.a_load_const_reg(current_asmdata.CurrAsmList, OS_INT, 0, resultreg);
-             end
-             else if (ispowerof2(tordconstnode(right).value, power)) then
-             begin
-                 if (is_signed(right.resultdef)) then begin
-
-                     tempreg := cg.getintregister(current_asmdata.CurrAsmList, OS_INT);
-                     maskreg := cg.getintregister(current_asmdata.CurrAsmList, OS_INT);
-                     modreg := cg.getintregister(current_asmdata.CurrAsmList, OS_INT);
-
-                     cg.a_load_const_reg(current_asmdata.CurrAsmList, OS_INT, abs(tordconstnode(right).value.svalue)-1, modreg);
-                     cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_SAR, OS_INT, 31, numerator, maskreg);
-                     cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_AND, OS_INT, numerator, modreg, tempreg);
-
-                     current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ANDC, maskreg, maskreg, modreg));
-                     current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_SUBFIC, modreg, tempreg, 0));
-                     current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SUBFE, modreg, modreg, modreg));
-                     cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_AND, OS_INT, modreg, maskreg, maskreg);
-                     cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_INT, maskreg, tempreg, resultreg);
-                 end else begin
-                     cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_AND, OS_INT, tordconstnode(right).value.svalue-1, numerator, resultreg);
-                 end;
-             end else begin
-                 genOrdConstNodeDiv();
-                 cg.a_op_const_reg_reg(current_asmdata.CurrAsmList, OP_MUL, OS_INT, tordconstnode(right).value.svalue, resultreg, resultreg);
-                 cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_SUB, OS_INT, resultreg, numerator, resultreg);
-             end;
-}
-         end;
-
-      begin
-        secondpass(left);
-        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,
-          left.resultdef,left.resultdef,true);
-        location_copy(location,left.location);
-        numerator:=location.register;
-        resultreg:=location.register;
-        if location.loc=LOC_CREGISTER then
-          begin
-            location.loc := LOC_REGISTER;
-            location.register := cg.getintregister(current_asmdata.CurrAsmList,size);
-            resultreg:=location.register;
-          end
-        else if (nodetype=modn) or (right.nodetype=ordconstn) then
-          begin
-            // for a modulus op, and for const nodes we need the result register
-            // to be an extra register
-            resultreg:=cg.getintregister(current_asmdata.CurrAsmList,size);
-          end;
-
-        if right.nodetype=ordconstn then
-          begin
-            if nodetype=divn then
-              genOrdConstNodeDiv
-            else
-              genOrdConstNodeMod;
-          end;
-
-        location.register:=resultreg;
-
-        { unsigned division/module can only overflow in case of division by zero }
-        { (but checking this overflow flag is more convoluted than performing a  }
-        {  simple comparison with 0)                                             }
-        if is_signed(right.resultdef) then
-          cg.g_overflowcheck(current_asmdata.CurrAsmList,location,resultdef);
-{$endif dummy}
-      end;
-
 {*****************************************************************************
 {*****************************************************************************
                                TAVRNOTNODE
                                TAVRNOTNODE
 *****************************************************************************}
 *****************************************************************************}
@@ -263,7 +110,65 @@ implementation
           end;
           end;
       end;
       end;
 
 
+
+    procedure tavrshlshrnode.second_integer;
+      var
+         op : topcg;
+         opdef: tdef;
+         hcountreg : tregister;
+         opsize : tcgsize;
+         shiftval : longint;
+      begin
+        { determine operator }
+        case nodetype of
+          shln: op:=OP_SHL;
+          shrn: op:=OP_SHR;
+          else
+            internalerror(2013120102);
+        end;
+        opsize:=left.location.size;
+        opdef:=left.resultdef;
+
+        if not(left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) or
+          { location_force_reg can be also used to change the size of a register }
+          (left.location.size<>opsize) then
+          hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,opdef,true);
+        location_reset(location,LOC_REGISTER,opsize);
+        location.register:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
+
+        { shifting by a constant directly coded: }
+        if (right.nodetype=ordconstn) then
+          begin
+             { shl/shr must "wrap around", so use ... and 31 }
+             { In TP, "byte/word shl 16 = 0", so no "and 15" in case of
+               a 16 bit ALU }
+             if tcgsize2size[opsize]<=4 then
+               shiftval:=tordconstnode(right).value.uvalue and 31
+             else
+               shiftval:=tordconstnode(right).value.uvalue and 63;
+             hlcg.a_op_const_reg_reg(current_asmdata.CurrAsmList,op,opdef,
+               shiftval,left.location.register,location.register);
+          end
+        else
+          begin
+             { load right operators in a register - this
+               is done since most target cpu which will use this
+               node do not support a shift count in a mem. location (cec)
+             }
+             hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,sinttype,true);
+             hlcg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,op,opdef,right.location.register,left.location.register,location.register);
+          end;
+        { shl/shr nodes return the same type as left, which can be different
+          from opdef }
+        if opdef<>resultdef then
+          begin
+            hcountreg:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
+            hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,opdef,resultdef,location.register,hcountreg);
+            location.register:=hcountreg;
+          end;
+      end;
+
 begin
 begin
-  cmoddivnode:=tavrmoddivnode;
   cnotnode:=tavrnotnode;
   cnotnode:=tavrnotnode;
+  cshlshrnode:=tavrshlshrnode;
 end.
 end.

+ 33 - 10
compiler/avr/raavrgas.pas

@@ -344,19 +344,42 @@ Unit raavrgas;
           AS_MINUS,
           AS_MINUS,
           AS_PLUS:
           AS_PLUS:
             Begin
             Begin
-              { Constant memory offset }
-              { This must absolutely be followed by (  }
-              oper.InitRef;
-              oper.opr.ref.offset:=BuildConstExpression(True,False);
+              if (actasmtoken=AS_MINUS) and
+                 (actopcode in [A_LD,A_ST]) then
+                begin
+                  { Special handling of predecrement addressing }
+                  oper.InitRef;
+                  oper.opr.ref.addressmode:=AM_PREDRECEMENT;
+
+                  consume(AS_MINUS);
 
 
-              { absolute memory addresss? }
-              if actopcode in [A_LDS,A_STS] then
-                BuildReference(oper)
+                  if actasmtoken=AS_REGISTER then
+                    begin
+                      oper.opr.ref.base:=actasmregister;
+                      consume(AS_REGISTER);
+                    end
+                  else
+                    begin
+                      Message(asmr_e_invalid_reference_syntax);
+                      RecoverConsume(false);
+                    end;
+                end
               else
               else
                 begin
                 begin
-                  ofs:=oper.opr.ref.offset;
-                  BuildConstantOperand(oper);
-                  inc(oper.opr.val,ofs);
+                  { Constant memory offset }
+                  { This must absolutely be followed by (  }
+                  oper.InitRef;
+                  oper.opr.ref.offset:=BuildConstExpression(True,False);
+
+                  { absolute memory addresss? }
+                  if actopcode in [A_LDS,A_STS] then
+                    BuildReference(oper)
+                  else
+                    begin
+                      ofs:=oper.opr.ref.offset;
+                      BuildConstantOperand(oper);
+                      inc(oper.opr.val,ofs);
+                    end;
                 end;
                 end;
             end;
             end;
 
 

+ 1 - 1
compiler/avr/rgcpu.pas

@@ -137,7 +137,7 @@ unit rgcpu;
           end
           end
         else
         else
           inherited;
           inherited;
-    end;
+      end;
 
 
 
 
     procedure trgintcpu.add_cpu_interferences(p : tai);
     procedure trgintcpu.add_cpu_interferences(p : tai);

+ 5 - 0
compiler/avr/symcpu.pas

@@ -115,6 +115,10 @@ type
   end;
   end;
   tcpuunitsymclass = class of tcpuunitsym;
   tcpuunitsymclass = class of tcpuunitsym;
 
 
+  tcpuprogramparasym = class(tprogramparasym)
+  end;
+  tcpuprogramparasymclass = class(tprogramparasym);
+
   tcpunamespacesym = class(tnamespacesym)
   tcpunamespacesym = class(tnamespacesym)
   end;
   end;
   tcpunamespacesymclass = class of tcpunamespacesym;
   tcpunamespacesymclass = class of tcpunamespacesym;
@@ -195,6 +199,7 @@ begin
   { used tsym classes }
   { used tsym classes }
   clabelsym:=tcpulabelsym;
   clabelsym:=tcpulabelsym;
   cunitsym:=tcpuunitsym;
   cunitsym:=tcpuunitsym;
+  cprogramparasym:=tcpuprogramparasym;
   cnamespacesym:=tcpunamespacesym;
   cnamespacesym:=tcpunamespacesym;
   cprocsym:=tcpuprocsym;
   cprocsym:=tcpuprocsym;
   ctypesym:=tcputypesym;
   ctypesym:=tcputypesym;

+ 0 - 3
compiler/bsdcompile

@@ -1,3 +0,0 @@
-#!/bin/sh
-ppc386 -OG3p3 -Ch8000000 -dI386 -dGDB -dBROWSERLOG -Sg pp.pas -a -s -g %1 %2 %3 %4 %5 %6 %7 %8 %9
-

+ 2 - 0
compiler/cgbase.pas

@@ -95,7 +95,9 @@ interface
          {$ENDIF}
          {$ENDIF}
          {$IFDEF AVR}
          {$IFDEF AVR}
          ,addr_lo8
          ,addr_lo8
+         ,addr_lo8_gs
          ,addr_hi8
          ,addr_hi8
+         ,addr_hi8_gs
          {$ENDIF}
          {$ENDIF}
          {$IFDEF i8086}
          {$IFDEF i8086}
          ,addr_dgroup      // the data segment group
          ,addr_dgroup      // the data segment group

+ 14 - 47
compiler/cgobj.pas

@@ -348,7 +348,6 @@ unit cgobj;
           procedure optimize_op_const(size: TCGSize; var op: topcg; var a : tcgint);virtual;
           procedure optimize_op_const(size: TCGSize; var op: topcg; var a : tcgint);virtual;
 
 
 
 
-          procedure g_maybe_testvmt(list : TAsmList;reg:tregister;objdef:tobjectdef);
           {# This should emit the opcode to copy len bytes from the source
           {# This should emit the opcode to copy len bytes from the source
              to destination.
              to destination.
 
 
@@ -1761,6 +1760,20 @@ implementation
     procedure Tcg.a_op_const_reg_reg(list:TAsmList;op:Topcg;size:Tcgsize;
     procedure Tcg.a_op_const_reg_reg(list:TAsmList;op:Topcg;size:Tcgsize;
                                      a:tcgint;src,dst:Tregister);
                                      a:tcgint;src,dst:Tregister);
     begin
     begin
+      optimize_op_const(size, op, a);
+      case op of
+        OP_NONE:
+          begin
+            if src <> dst then
+              a_load_reg_reg(list, size, size, src, dst);
+            exit;
+          end;
+        OP_MOVE:
+          begin
+            a_load_const_reg(list, size, a, dst);
+            exit;
+          end;
+      end;
       a_load_reg_reg(list,size,size,src,dst);
       a_load_reg_reg(list,size,size,src,dst);
       a_op_const_reg(list,op,size,a,dst);
       a_op_const_reg(list,op,size,a,dst);
     end;
     end;
@@ -2171,52 +2184,6 @@ implementation
 {$endif cpuflags}
 {$endif cpuflags}
 
 
 
 
-    procedure tcg.g_maybe_testvmt(list : TAsmList;reg:tregister;objdef:tobjectdef);
-      var
-        hrefvmt : treference;
-        cgpara1,cgpara2 : TCGPara;
-        pd: tprocdef;
-      begin
-        cgpara1.init;
-        cgpara2.init;
-        if (cs_check_object in current_settings.localswitches) then
-         begin
-           pd:=search_system_proc('fpc_check_object_ext');
-           paramanager.getintparaloc(list,pd,1,cgpara1);
-           paramanager.getintparaloc(list,pd,2,cgpara2);
-           reference_reset_symbol(hrefvmt,current_asmdata.RefAsmSymbol(objdef.vmt_mangledname,AT_DATA),0,sizeof(pint));
-           if pd.is_pushleftright then
-             begin
-               a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
-               a_loadaddr_ref_cgpara(list,hrefvmt,cgpara2);
-             end
-           else
-             begin
-               a_loadaddr_ref_cgpara(list,hrefvmt,cgpara2);
-               a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
-             end;
-           paramanager.freecgpara(list,cgpara1);
-           paramanager.freecgpara(list,cgpara2);
-           allocallcpuregisters(list);
-           a_call_name(list,'fpc_check_object_ext',false);
-           deallocallcpuregisters(list);
-         end
-        else
-         if (cs_check_range in current_settings.localswitches) then
-          begin
-            pd:=search_system_proc('fpc_check_object');
-            paramanager.getintparaloc(list,pd,1,cgpara1);
-            a_load_reg_cgpara(list,OS_ADDR,reg,cgpara1);
-            paramanager.freecgpara(list,cgpara1);
-            allocallcpuregisters(list);
-            a_call_name(list,'fpc_check_object',false);
-            deallocallcpuregisters(list);
-          end;
-        cgpara1.done;
-        cgpara2.done;
-      end;
-
-
 {*****************************************************************************
 {*****************************************************************************
                             Entry/Exit Code Functions
                             Entry/Exit Code Functions
 *****************************************************************************}
 *****************************************************************************}

+ 6 - 0
compiler/dbgdwarf.pas

@@ -3347,6 +3347,12 @@ implementation
       begin
       begin
         { this function will always terminate the lineinfo block }
         { this function will always terminate the lineinfo block }
         generated_lineinfo := true;
         generated_lineinfo := true;
+        { if this unit only contains code without debug info (implicit init
+          or final etc), make sure the file table contains at least one entry
+          (the main source of the unit), because normally this table gets
+          populated via calls to get_file_index and that won't happen in this
+          case }
+        get_file_index(current_module.sourcefiles.get_file(1));
         FillChar(lastfileinfo,sizeof(lastfileinfo),0);
         FillChar(lastfileinfo,sizeof(lastfileinfo),0);
         currfuncname:=nil;
         currfuncname:=nil;
         currsectype:=sec_code;
         currsectype:=sec_code;

+ 9 - 6
compiler/defcmp.pas

@@ -247,12 +247,12 @@ implementation
 
 
          if cdo_strict_undefined_check in cdoptions then
          if cdo_strict_undefined_check in cdoptions then
            begin
            begin
-             { undefined defs are considered equal if both are undefined defs }
+             { two different undefined defs are not considered equal }
              if (def_from.typ=undefineddef) and
              if (def_from.typ=undefineddef) and
                 (def_to.typ=undefineddef) then
                 (def_to.typ=undefineddef) then
               begin
               begin
-                doconv:=tc_equal;
-                compare_defs_ext:=te_exact;
+                doconv:=tc_not_possible;
+                compare_defs_ext:=te_incompatible;
                 exit;
                 exit;
               end;
               end;
 
 
@@ -2010,15 +2010,18 @@ implementation
                 if (vo_is_hidden_para in currpara1.varoptions)<>(vo_is_hidden_para in currpara2.varoptions) then
                 if (vo_is_hidden_para in currpara1.varoptions)<>(vo_is_hidden_para in currpara2.varoptions) then
                   exit;
                   exit;
                 eq:=te_exact;
                 eq:=te_exact;
-                if not(vo_is_self in currpara1.varoptions) and
-                   not(vo_is_self in currpara2.varoptions) then
+                if (([vo_is_self,vo_is_vmt]*currpara1.varoptions)=[]) and
+                   (([vo_is_self,vo_is_vmt]*currpara2.varoptions)=[]) then
                  begin
                  begin
                    if not(cpo_ignorevarspez in cpoptions) and
                    if not(cpo_ignorevarspez in cpoptions) and
                       (currpara1.varspez<>currpara2.varspez) then
                       (currpara1.varspez<>currpara2.varspez) then
                     exit;
                     exit;
                    eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
                    eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
                                         convtype,hpd,cdoptions);
                                         convtype,hpd,cdoptions);
-                 end;
+                 end
+                else if ([vo_is_self,vo_is_vmt]*currpara1.varoptions)<>
+                         ([vo_is_self,vo_is_vmt]*currpara2.varoptions) then
+                   eq:=te_incompatible;
               end
               end
              else
              else
               begin
               begin

+ 5 - 16
compiler/defutil.pas

@@ -337,7 +337,7 @@ interface
 implementation
 implementation
 
 
     uses
     uses
-       verbose,cutils,symcpu;
+       verbose,cutils;
 
 
     { returns true, if def uses FPU }
     { returns true, if def uses FPU }
     function is_fpu(def : tdef) : boolean;
     function is_fpu(def : tdef) : boolean;
@@ -1208,21 +1208,10 @@ implementation
           classrefdef,
           classrefdef,
           pointerdef:
           pointerdef:
             begin
             begin
-{$ifdef x86}
-              if (def.typ=pointerdef) and
-                 (tcpupointerdef(def).x86pointertyp in [x86pt_far,x86pt_huge]) then
-                begin
-                  {$if defined(i8086)}
-                    result := OS_32;
-                  {$elseif defined(i386)}
-                    internalerror(2013052201);  { there's no OS_48 }
-                  {$elseif defined(x86_64)}
-                    internalerror(2013052202);  { there's no OS_80 }
-                  {$endif}
-                end
-              else
-{$endif x86}
-                result := int_cgsize(def.size);
+              result:=int_cgsize(def.size);
+              { can happen for far/huge pointers on non-i8086 }
+              if result=OS_NO then
+                internalerror(2013052201);
             end;
             end;
           formaldef:
           formaldef:
             result := int_cgsize(voidpointertype.size);
             result := int_cgsize(voidpointertype.size);

+ 9 - 4
compiler/fmodule.pas

@@ -44,7 +44,7 @@ interface
     uses
     uses
        cutils,cclasses,cfileutl,
        cutils,cclasses,cfileutl,
        globtype,finput,ogbase,
        globtype,finput,ogbase,
-       symbase,symconst,symsym,symcpu,
+       symbase,symconst,symsym,
        wpobase,
        wpobase,
        aasmbase,aasmtai,aasmdata;
        aasmbase,aasmtai,aasmdata;
 
 
@@ -142,8 +142,9 @@ interface
         checkforwarddefs,
         checkforwarddefs,
         deflist,
         deflist,
         symlist       : TFPObjectList;
         symlist       : TFPObjectList;
-        ptrdefs       : tPtrDefHashSet; { list of pointerdefs created in this module so we can reuse them (not saved/restored) }
+        ptrdefs       : THashSet; { 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) }
         arraydefs     : THashSet; { list of single-element-arraydefs created in this module so we can reuse them (not saved/restored) }
+        procaddrdefs  : THashSet; { list of procvardefs created when getting the address of a procdef (not saved/restored) }
 {$ifdef llvm}
 {$ifdef llvm}
         llvmdefs      : THashSet; { defs added for llvm-specific reasons (not saved/restored) }
         llvmdefs      : THashSet; { defs added for llvm-specific reasons (not saved/restored) }
 {$endif llvm}
 {$endif llvm}
@@ -570,8 +571,9 @@ implementation
         derefdataintflen:=0;
         derefdataintflen:=0;
         deflist:=TFPObjectList.Create(false);
         deflist:=TFPObjectList.Create(false);
         symlist:=TFPObjectList.Create(false);
         symlist:=TFPObjectList.Create(false);
-        ptrdefs:=cPtrDefHashSet.Create;
+        ptrdefs:=THashSet.Create(64,true,false);
         arraydefs:=THashSet.Create(64,true,false);
         arraydefs:=THashSet.Create(64,true,false);
+        procaddrdefs:=THashSet.Create(64,true,false);
 {$ifdef llvm}
 {$ifdef llvm}
         llvmdefs:=THashSet.Create(64,true,false);
         llvmdefs:=THashSet.Create(64,true,false);
 {$endif llvm}
 {$endif llvm}
@@ -689,6 +691,7 @@ implementation
         symlist.free;
         symlist.free;
         ptrdefs.free;
         ptrdefs.free;
         arraydefs.free;
         arraydefs.free;
+        procaddrdefs.free;
 {$ifdef llvm}
 {$ifdef llvm}
         llvmdefs.free;
         llvmdefs.free;
 {$endif llvm}
 {$endif llvm}
@@ -753,9 +756,11 @@ implementation
         symlist.free;
         symlist.free;
         symlist:=TFPObjectList.Create(false);
         symlist:=TFPObjectList.Create(false);
         ptrdefs.free;
         ptrdefs.free;
-        ptrdefs:=cPtrDefHashSet.Create;
+        ptrdefs:=THashSet.Create(64,true,false);
         arraydefs.free;
         arraydefs.free;
         arraydefs:=THashSet.Create(64,true,false);
         arraydefs:=THashSet.Create(64,true,false);
+        procaddrdefs.free;
+        procaddrdefs:=THashSet.Create(64,true,false);
 {$ifdef llvm}
 {$ifdef llvm}
         llvmdefs.free;
         llvmdefs.free;
         llvmdefs:=THashSet.Create(64,true,false);
         llvmdefs:=THashSet.Create(64,true,false);

+ 5 - 4
compiler/fpcdefs.inc

@@ -56,7 +56,7 @@
   {$define SUPPORT_SAFECALL}
   {$define SUPPORT_SAFECALL}
   {$define cpuneedsmulhelper}
   {$define cpuneedsmulhelper}
   { TODO: add another define in order to disable the div helper for 16-bit divs? }
   { TODO: add another define in order to disable the div helper for 16-bit divs? }
-  {$define cpuneedsdiv32helper}
+  {$define cpuneedsdivhelper}
   {$define VOLATILE_ES}
   {$define VOLATILE_ES}
   {$define SUPPORT_GET_FRAME}
   {$define SUPPORT_GET_FRAME}
 {$endif i8086}
 {$endif i8086}
@@ -145,7 +145,7 @@
   {$define cpu32bitalu}
   {$define cpu32bitalu}
   {$define cpuflags}
   {$define cpuflags}
   {$define cpufpemu}
   {$define cpufpemu}
-  {$define cpuneedsdiv32helper}
+  {$define cpuneedsdivhelper}
   {$define cpurox}
   {$define cpurox}
   {$define cputargethasfixedstack}
   {$define cputargethasfixedstack}
   {$define cpurefshaveindexreg}
   {$define cpurefshaveindexreg}
@@ -178,7 +178,7 @@
   {$define cpufpemu}
   {$define cpufpemu}
   {$define cpurefshaveindexreg}
   {$define cpurefshaveindexreg}
   {$define cpucapabilities}
   {$define cpucapabilities}
-  {$define cpuneedsdiv32helper}
+  {$define cpuneedsdivhelper}
 {$endif m68k}
 {$endif m68k}
 
 
 {$ifdef avr}
 {$ifdef avr}
@@ -188,7 +188,7 @@
   {$define cpuflags}
   {$define cpuflags}
   {$define cpunofpu}
   {$define cpunofpu}
   {$define cpunodefaultint}
   {$define cpunodefaultint}
-  {$define cpuneedsdiv32helper}
+  {$define cpuneedsdivhelper}
   {$define cpuneedsmulhelper}
   {$define cpuneedsmulhelper}
   {$define cpurefshaveindexreg}
   {$define cpurefshaveindexreg}
   {$define cpucapabilities}
   {$define cpucapabilities}
@@ -269,4 +269,5 @@
   {$undef cpu32bitalu}
   {$undef cpu32bitalu}
   {$define cpu64bitalu}
   {$define cpu64bitalu}
   {$define cpuhighleveltarget}
   {$define cpuhighleveltarget}
+  {$define symansistr}
 {$endif}
 {$endif}

+ 5 - 0
compiler/generic/symcpu.pas

@@ -115,6 +115,10 @@ type
   end;
   end;
   tcpuunitsymclass = class of tcpuunitsym;
   tcpuunitsymclass = class of tcpuunitsym;
 
 
+  tcpuprogramparasym = class(tprogramparasym)
+  end;
+  tcpuprogramparasymclass = class(tprogramparasym);
+
   tcpunamespacesym = class(tnamespacesym)
   tcpunamespacesym = class(tnamespacesym)
   end;
   end;
   tcpunamespacesymclass = class of tcpunamespacesym;
   tcpunamespacesymclass = class of tcpunamespacesym;
@@ -195,6 +199,7 @@ begin
   { used tsym classes }
   { used tsym classes }
   clabelsym:=tcpulabelsym;
   clabelsym:=tcpulabelsym;
   cunitsym:=tcpuunitsym;
   cunitsym:=tcpuunitsym;
+  cprogramparasym:=tcpuprogramparasym;
   cnamespacesym:=tcpunamespacesym;
   cnamespacesym:=tcpunamespacesym;
   cprocsym:=tcpuprocsym;
   cprocsym:=tcpuprocsym;
   ctypesym:=tcputypesym;
   ctypesym:=tcputypesym;

+ 1 - 1
compiler/globals.pas

@@ -398,7 +398,7 @@ interface
         optimizerswitches : [];
         optimizerswitches : [];
         genwpoptimizerswitches : [];
         genwpoptimizerswitches : [];
         dowpoptimizerswitches : [];
         dowpoptimizerswitches : [];
-        debugswitches : [];
+        debugswitches : [ds_dwarf_sets];
 
 
         setalloc : 0;
         setalloc : 0;
         packenum : 4;
         packenum : 4;

+ 2 - 2
compiler/globtype.pas

@@ -269,7 +269,7 @@ interface
        toptimizerswitch = (cs_opt_none,
        toptimizerswitch = (cs_opt_none,
          cs_opt_level1,cs_opt_level2,cs_opt_level3,cs_opt_level4,
          cs_opt_level1,cs_opt_level2,cs_opt_level3,cs_opt_level4,
          cs_opt_regvar,cs_opt_uncertain,cs_opt_size,cs_opt_stackframe,
          cs_opt_regvar,cs_opt_uncertain,cs_opt_size,cs_opt_stackframe,
-         cs_opt_peephole,cs_opt_asmcse,cs_opt_loopunroll,cs_opt_tailrecursion,cs_opt_nodecse,
+         cs_opt_peephole,cs_opt_loopunroll,cs_opt_tailrecursion,cs_opt_nodecse,
          cs_opt_nodedfa,cs_opt_loopstrength,cs_opt_scheduler,cs_opt_autoinline,cs_useebp,cs_userbp,
          cs_opt_nodedfa,cs_opt_loopstrength,cs_opt_scheduler,cs_opt_autoinline,cs_useebp,cs_userbp,
          cs_opt_reorder_fields,cs_opt_fastmath,
          cs_opt_reorder_fields,cs_opt_fastmath,
          { Allow removing expressions whose result is not used, even when this
          { Allow removing expressions whose result is not used, even when this
@@ -315,7 +315,7 @@ interface
        OptimizerSwitchStr : array[toptimizerswitch] of string[17] = ('',
        OptimizerSwitchStr : array[toptimizerswitch] of string[17] = ('',
          'LEVEL1','LEVEL2','LEVEL3','LEVEL4',
          'LEVEL1','LEVEL2','LEVEL3','LEVEL4',
          'REGVAR','UNCERTAIN','SIZE','STACKFRAME',
          'REGVAR','UNCERTAIN','SIZE','STACKFRAME',
-         'PEEPHOLE','ASMCSE','LOOPUNROLL','TAILREC','CSE',
+         'PEEPHOLE','LOOPUNROLL','TAILREC','CSE',
          'DFA','STRENGTH','SCHEDULE','AUTOINLINE','USEEBP','USERBP',
          'DFA','STRENGTH','SCHEDULE','AUTOINLINE','USEEBP','USERBP',
          'ORDERFIELDS','FASTMATH','DEADVALUES','REMOVEEMPTYPROCS',
          'ORDERFIELDS','FASTMATH','DEADVALUES','REMOVEEMPTYPROCS',
          'CONSTPROP',
          'CONSTPROP',

+ 69 - 12
compiler/hlcgobj.pas

@@ -563,6 +563,7 @@ unit hlcgobj;
 
 
           procedure gen_proc_symbol(list:TAsmList);virtual;
           procedure gen_proc_symbol(list:TAsmList);virtual;
           procedure gen_proc_symbol_end(list:TAsmList);virtual;
           procedure gen_proc_symbol_end(list:TAsmList);virtual;
+          procedure handle_external_proc(list: TAsmList; pd: tprocdef; const importname: TSymStr); virtual;
 
 
           procedure gen_initialize_code(list:TAsmList);virtual;
           procedure gen_initialize_code(list:TAsmList);virtual;
           procedure gen_finalize_code(list:TAsmList);virtual;
           procedure gen_finalize_code(list:TAsmList);virtual;
@@ -1596,8 +1597,12 @@ implementation
     end;
     end;
 
 
   procedure thlcgobj.a_bit_test_const_ref_reg(list: TAsmList; fromsize, destsize: tdef; bitnumber: aint; const ref: treference; destreg: tregister);
   procedure thlcgobj.a_bit_test_const_ref_reg(list: TAsmList; fromsize, destsize: tdef; bitnumber: aint; const ref: treference; destreg: tregister);
+    var
+      href: treference;
     begin
     begin
-      a_load_subsetref_reg(list,u8inttype,destsize,get_bit_const_ref_sref(bitnumber,fromsize,ref),destreg);
+      href:=ref;
+      g_ptrtypecast_ref(list,cpointerdef.getreusable(fromsize),cpointerdef.getreusable(u8inttype),href);
+      a_load_subsetref_reg(list,u8inttype,destsize,get_bit_const_ref_sref(bitnumber,fromsize,href),destreg);
     end;
     end;
 
 
   procedure thlcgobj.a_bit_test_const_reg_reg(list: TAsmList; setregsize, destsize: tdef; bitnumber: aint; setreg, destreg: tregister);
   procedure thlcgobj.a_bit_test_const_reg_reg(list: TAsmList; setregsize, destsize: tdef; bitnumber: aint; setreg, destreg: tregister);
@@ -1621,8 +1626,12 @@ implementation
     end;
     end;
 
 
   procedure thlcgobj.a_bit_test_reg_ref_reg(list: TAsmList; bitnumbersize, refsize, destsize: tdef; bitnumber: tregister; const ref: treference; destreg: tregister);
   procedure thlcgobj.a_bit_test_reg_ref_reg(list: TAsmList; bitnumbersize, refsize, destsize: tdef; bitnumber: tregister; const ref: treference; destreg: tregister);
+    var
+      href: treference;
     begin
     begin
-      a_load_subsetref_reg(list,u8inttype,destsize,get_bit_reg_ref_sref(list,bitnumbersize,refsize,bitnumber,ref),destreg);
+      href:=ref;
+      g_ptrtypecast_ref(list,cpointerdef.getreusable(refsize),cpointerdef.getreusable(u8inttype),href);
+      a_load_subsetref_reg(list,u8inttype,destsize,get_bit_reg_ref_sref(list,bitnumbersize,refsize,bitnumber,href),destreg);
     end;
     end;
 
 
   procedure thlcgobj.a_bit_test_reg_loc_reg(list: TAsmList; bitnumbersize, locsize, destsize: tdef; bitnumber: tregister; const loc: tlocation; destreg: tregister);
   procedure thlcgobj.a_bit_test_reg_loc_reg(list: TAsmList; bitnumbersize, locsize, destsize: tdef; bitnumber: tregister; const loc: tlocation; destreg: tregister);
@@ -1705,12 +1714,17 @@ implementation
     end;
     end;
 
 
   procedure thlcgobj.a_bit_set_const_ref(list: TAsmList; doset: boolean; destsize: tdef; bitnumber: tcgint; const ref: treference);
   procedure thlcgobj.a_bit_set_const_ref(list: TAsmList; doset: boolean; destsize: tdef; bitnumber: tcgint; const ref: treference);
+    var
+      href: treference;
     begin
     begin
-      a_load_const_subsetref(list,u8inttype,ord(doset),get_bit_const_ref_sref(bitnumber,destsize,ref));
+      href:=ref;
+      g_ptrtypecast_ref(list,cpointerdef.getreusable(destsize),cpointerdef.getreusable(u8inttype),href);
+      a_load_const_subsetref(list,u8inttype,ord(doset),get_bit_const_ref_sref(bitnumber,destsize,href));
     end;
     end;
 
 
   procedure thlcgobj.a_bit_set_const_reg(list: TAsmList; doset: boolean; destsize: tdef; bitnumber: tcgint; destreg: tregister);
   procedure thlcgobj.a_bit_set_const_reg(list: TAsmList; doset: boolean; destsize: tdef; bitnumber: tcgint; destreg: tregister);
     begin
     begin
+      g_ptrtypecast_reg(list,cpointerdef.getreusable(destsize),cpointerdef.getreusable(u8inttype),destreg);
       a_load_const_subsetreg(list,u8inttype,ord(doset),get_bit_const_reg_sreg(destsize,bitnumber,destreg));
       a_load_const_subsetreg(list,u8inttype,ord(doset),get_bit_const_reg_sreg(destsize,bitnumber,destreg));
     end;
     end;
 
 
@@ -1730,7 +1744,11 @@ implementation
     end;
     end;
 
 
   procedure thlcgobj.a_bit_set_reg_ref(list: TAsmList; doset: boolean; fromsize, tosize: tdef; bitnumber: tregister; const ref: treference);
   procedure thlcgobj.a_bit_set_reg_ref(list: TAsmList; doset: boolean; fromsize, tosize: tdef; bitnumber: tregister; const ref: treference);
+    var
+      href: treference;
     begin
     begin
+      href:=ref;
+      g_ptrtypecast_ref(list,cpointerdef.getreusable(tosize),cpointerdef.getreusable(u8inttype),href);
       a_load_const_subsetref(list,u8inttype,ord(doset),get_bit_reg_ref_sref(list,fromsize,tosize,bitnumber,ref));
       a_load_const_subsetref(list,u8inttype,ord(doset),get_bit_reg_ref_sref(list,fromsize,tosize,bitnumber,ref));
     end;
     end;
 
 
@@ -2401,7 +2419,7 @@ implementation
       if result.ref.index<>NR_NO then
       if result.ref.index<>NR_NO then
         begin
         begin
           { don't just add to ref.index, as it may be scaled }
           { don't just add to ref.index, as it may be scaled }
-          refptrdef:=getpointerdef(refsize);
+          refptrdef:=cpointerdef.getreusable(refsize);
           newbase:=getaddressregister(list,refptrdef);
           newbase:=getaddressregister(list,refptrdef);
           a_loadaddr_ref_reg(list,refsize,refptrdef,ref,newbase);
           a_loadaddr_ref_reg(list,refsize,refptrdef,ref,newbase);
           reference_reset_base(result.ref,refptrdef,newbase,0,result.ref.alignment);
           reference_reset_base(result.ref,refptrdef,newbase,0,result.ref.alignment);
@@ -2528,7 +2546,7 @@ implementation
               internalerror(2014080603);
               internalerror(2014080603);
             { convert the reference from a floating point location to an
             { convert the reference from a floating point location to an
               integer location, and load that }
               integer location, and load that }
-            intptrdef:=getpointerdef(cgpara.location^.def);
+            intptrdef:=cpointerdef.getreusable(cgpara.location^.def);
             hreg:=getaddressregister(list,intptrdef);
             hreg:=getaddressregister(list,intptrdef);
             a_loadaddr_ref_reg(list,fromsize,intptrdef,ref,hreg);
             a_loadaddr_ref_reg(list,fromsize,intptrdef,ref,hreg);
             reference_reset_base(href,intptrdef,hreg,0,ref.alignment);
             reference_reset_base(href,intptrdef,hreg,0,ref.alignment);
@@ -3659,7 +3677,7 @@ implementation
       a_op_const_reg_reg(list,OP_ADD,sinttype,1,lenreg,sizereg);
       a_op_const_reg_reg(list,OP_ADD,sinttype,1,lenreg,sizereg);
       a_op_const_reg(list,OP_IMUL,sinttype,arrdef.elesize,sizereg);
       a_op_const_reg(list,OP_IMUL,sinttype,arrdef.elesize,sizereg);
       { load source }
       { load source }
-      ptrarrdef:=getpointerdef(arrdef);
+      ptrarrdef:=cpointerdef.getreusable(arrdef);
       sourcereg:=getaddressregister(list,ptrarrdef);
       sourcereg:=getaddressregister(list,ptrarrdef);
       a_loadaddr_ref_reg(list,arrdef,ptrarrdef,ref,sourcereg);
       a_loadaddr_ref_reg(list,arrdef,ptrarrdef,ref,sourcereg);
 
 
@@ -3722,7 +3740,7 @@ implementation
       cgpara1.init;
       cgpara1.init;
       paramanager.getintparaloc(list,pd,1,cgpara1);
       paramanager.getintparaloc(list,pd,1,cgpara1);
       { load source }
       { load source }
-      a_load_loc_cgpara(list,getpointerdef(arrdef),l,cgpara1);
+      a_load_loc_cgpara(list,cpointerdef.getreusable(arrdef),l,cgpara1);
       paramanager.freecgpara(list,cgpara1);
       paramanager.freecgpara(list,cgpara1);
       g_call_system_proc(list,pd,[@cgpara1],nil);
       g_call_system_proc(list,pd,[@cgpara1],nil);
       cgpara1.done;
       cgpara1.done;
@@ -3988,6 +4006,8 @@ implementation
     end;
     end;
 
 
     procedure thlcgobj.location_get_data_ref(list: TAsmList; def: tdef; const l: tlocation; var ref: treference; loadref: boolean; alignment: longint);
     procedure thlcgobj.location_get_data_ref(list: TAsmList; def: tdef; const l: tlocation; var ref: treference; loadref: boolean; alignment: longint);
+      var
+        pdef: tdef;
       begin
       begin
         case l.loc of
         case l.loc of
           LOC_REGISTER,
           LOC_REGISTER,
@@ -3995,16 +4015,17 @@ implementation
             begin
             begin
               if not loadref then
               if not loadref then
                 internalerror(200410231);
                 internalerror(200410231);
-              reference_reset_base(ref,voidpointertype,l.register,0,alignment);
+              reference_reset_base(ref,cpointerdef.getreusable(def),l.register,0,alignment);
             end;
             end;
           LOC_REFERENCE,
           LOC_REFERENCE,
           LOC_CREFERENCE :
           LOC_CREFERENCE :
             begin
             begin
               if loadref then
               if loadref then
                 begin
                 begin
-                  reference_reset_base(ref,voidpointertype,getaddressregister(list,voidpointertype),0,alignment);
+                  pdef:=cpointerdef.getreusable(def);
+                  reference_reset_base(ref,pdef,getaddressregister(list,voidpointertype),0,alignment);
                   { it's a pointer to def }
                   { it's a pointer to def }
-                  a_load_ref_reg(list,voidpointertype,voidpointertype,l.reference,ref.base);
+                  a_load_ref_reg(list,pdef,pdef,l.reference,ref.base);
                 end
                 end
               else
               else
                 ref:=l.reference;
                 ref:=l.reference;
@@ -4357,6 +4378,40 @@ implementation
         end;
         end;
     end;
     end;
 
 
+
+  procedure thlcgobj.handle_external_proc(list: TAsmList; pd: tprocdef; const importname: TSymStr);
+    begin
+      { External declared in implementation, and there was already a
+        forward (or interface) declaration then we need to generate
+        a stub that calls the external routine }
+      if (not pd.forwarddef) and
+         (pd.hasforward) then
+        begin
+          if importname<>'' then
+            begin
+             { add the procedure to the al_procedures }
+             maybe_new_object_file(list);
+             new_section(list,sec_code,lower(pd.mangledname),current_settings.alignment.procalign);
+             if (po_global in pd.procoptions) then
+               list.concat(Tai_symbol.createname_global(pd.mangledname,AT_FUNCTION,0))
+             else
+               list.concat(Tai_symbol.createname(pd.mangledname,AT_FUNCTION,0));
+
+             g_external_wrapper(list,pd,importname);
+            end;
+          { remove the external stuff, so that the interface crc
+            doesn't change. This makes the function calls less
+            efficient, but it means that the interface doesn't
+            change if the function is ever redirected to another
+            function or implemented in the unit. }
+          pd.procoptions:=pd.procoptions-[po_external,po_has_importname,po_has_importdll];
+          stringdispose(pd.import_name);
+          stringdispose(pd.import_dll);
+          pd.import_nr:=0;
+        end;
+    end;
+
+
   procedure thlcgobj.gen_initialize_code(list: TAsmList);
   procedure thlcgobj.gen_initialize_code(list: TAsmList);
     begin
     begin
       { initialize local data like ansistrings }
       { initialize local data like ansistrings }
@@ -4843,7 +4898,9 @@ implementation
       for i:=0 to current_procinfo.procdef.paras.count-1 do
       for i:=0 to current_procinfo.procdef.paras.count-1 do
         begin
         begin
           currpara:=tparavarsym(current_procinfo.procdef.paras[i]);
           currpara:=tparavarsym(current_procinfo.procdef.paras[i]);
-          gen_load_cgpara_loc(list,currpara.vardef,currpara.paraloc[calleeside],currpara.initialloc,paramanager.param_use_paraloc(currpara.paraloc[calleeside]));
+          { don't use currpara.vardef, as this will be wrong in case of
+            call-by-reference parameters (it won't contain the pointer) }
+          gen_load_cgpara_loc(list,currpara.paraloc[calleeside].def,currpara.paraloc[calleeside],currpara.initialloc,paramanager.param_use_paraloc(currpara.paraloc[calleeside]));
         end;
         end;
 
 
       { generate copies of call by value parameters, must be done before
       { generate copies of call by value parameters, must be done before
@@ -5123,7 +5180,7 @@ implementation
           retdef:=ressym.vardef;
           retdef:=ressym.vardef;
           { and TP-style constructors return a pointer to self }
           { and TP-style constructors return a pointer to self }
           if is_object(ressym.vardef) then
           if is_object(ressym.vardef) then
-            retdef:=getpointerdef(retdef);
+            retdef:=cpointerdef.getreusable(retdef);
         end
         end
       else
       else
         begin
         begin

+ 17 - 9
compiler/htypechk.pas

@@ -1500,17 +1500,25 @@ implementation
                         is_open_array(fromdef) or
                         is_open_array(fromdef) or
                         is_open_array(todef) or
                         is_open_array(todef) or
                         ((fromdef.typ=pointerdef) and (todef.typ=arraydef)) or
                         ((fromdef.typ=pointerdef) and (todef.typ=arraydef)) or
-                        (def_is_related(fromdef,todef))) and
-                    (fromdef.size<>todef.size) then
+                        (def_is_related(fromdef,todef))) then
                   begin
                   begin
-                    { in TP it is allowed to typecast to smaller types. But the variable can't
-                      be in a register }
-                    if (m_tp7 in current_settings.modeswitches) or
-                       (todef.size<fromdef.size) then
-                      make_not_regable(hp,[ra_addr_regable])
+                    if (fromdef.size<>todef.size) then
+                      begin
+                        { in TP it is allowed to typecast to smaller types. But the variable can't
+                          be in a register }
+                        if (m_tp7 in current_settings.modeswitches) or
+                           (todef.size<fromdef.size) then
+                          make_not_regable(hp,[ra_addr_regable])
+                        else
+                          if report_errors then
+                            CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
+                      end
+{$ifdef llvm}
+                    { we can never typecast a non-memory value on the assignment
+                      side in llvm }
                     else
                     else
-                      if report_errors then
-                        CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
+                      make_not_regable(hp,[ra_addr_regable])
+{$endif llvm}
                   end;
                   end;
 
 
                  { don't allow assignments to typeconvs that need special code }
                  { don't allow assignments to typeconvs that need special code }

+ 1 - 8
compiler/i386/aopt386.pas

@@ -37,7 +37,7 @@ Implementation
 Uses
 Uses
   globtype,
   globtype,
   globals,
   globals,
-  DAOpt386,POpt386,CSOpt386;
+  DAOpt386,POpt386;
 
 
 
 
 Procedure Optimize(AsmL: TAsmList);
 Procedure Optimize(AsmL: TAsmList);
@@ -74,13 +74,6 @@ Begin
                if pass = 0 then
                if pass = 0 then
                  PeepHoleOptPass1(AsmL, BlockStart, BlockEnd);
                  PeepHoleOptPass1(AsmL, BlockStart, BlockEnd);
            end;
            end;
-        { Data flow analyzer }
-         If (cs_opt_asmcse in current_settings.optimizerswitches) Then
-           begin
-             if dfa.pass_generate_code then
-              { common subexpression elimination }
-               changed := CSE(asmL, blockStart, blockEnd, pass) or changed;
-           end;
         { More peephole optimizations }
         { More peephole optimizations }
          if (cs_opt_peephole in current_settings.optimizerswitches) then
          if (cs_opt_peephole in current_settings.optimizerswitches) then
            begin
            begin

+ 1 - 1
compiler/i386/cpuinfo.pas

@@ -139,7 +139,7 @@ Const
                                  { no need to write info about those }
                                  { no need to write info about those }
                                  [cs_opt_level1,cs_opt_level2,cs_opt_level3]+
                                  [cs_opt_level1,cs_opt_level2,cs_opt_level3]+
                                  [cs_opt_peephole,cs_opt_regvar,cs_opt_stackframe,
                                  [cs_opt_peephole,cs_opt_regvar,cs_opt_stackframe,
-                                  cs_opt_asmcse,cs_opt_loopunroll,cs_opt_uncertain,
+                                  cs_opt_loopunroll,cs_opt_uncertain,
                                   cs_opt_tailrecursion,cs_opt_nodecse,cs_useebp,
                                   cs_opt_tailrecursion,cs_opt_nodecse,cs_useebp,
 				  cs_opt_reorder_fields,cs_opt_fastmath];
 				  cs_opt_reorder_fields,cs_opt_fastmath];
 
 

+ 4 - 3
compiler/i386/cpupara.pas

@@ -446,7 +446,7 @@ unit cpupara;
               begin
               begin
                 paralen:=sizeof(aint);
                 paralen:=sizeof(aint);
                 paracgsize:=OS_ADDR;
                 paracgsize:=OS_ADDR;
-                paradef:=getpointerdef(paradef);
+                paradef:=cpointerdef.getreusable(paradef);
               end
               end
             else
             else
               begin
               begin
@@ -598,7 +598,7 @@ unit cpupara;
                       begin
                       begin
                         paralen:=sizeof(aint);
                         paralen:=sizeof(aint);
                         paracgsize:=OS_ADDR;
                         paracgsize:=OS_ADDR;
-                        paradef:=getpointerdef(paradef);
+                        paradef:=cpointerdef.getreusable(paradef);
                       end
                       end
                     else
                     else
                       begin
                       begin
@@ -625,7 +625,8 @@ unit cpupara;
                     if (parareg<=high(parasupregs)) and
                     if (parareg<=high(parasupregs)) and
                        (paralen<=sizeof(aint)) and
                        (paralen<=sizeof(aint)) and
                        (not(hp.vardef.typ in [floatdef,recorddef,arraydef]) or
                        (not(hp.vardef.typ in [floatdef,recorddef,arraydef]) or
-                        pushaddr) and
+                        pushaddr or
+                        is_dynamic_array(hp.vardef)) and
                        (not(vo_is_parentfp in hp.varoptions) or
                        (not(vo_is_parentfp in hp.varoptions) or
                         not(po_delphi_nested_cc in p.procoptions)) then
                         not(po_delphi_nested_cc in p.procoptions)) then
                       begin
                       begin

+ 0 - 2265
compiler/i386/csopt386.pas

@@ -1,2265 +0,0 @@
-{
-    Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
-      development team
-
-    This unit contains the common subexpression elimination procedure.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit CSOpt386;
-
-{$i fpcdefs.inc}
-
-interface
-
-uses aasmbase,aasmtai,aasmdata,aasmcpu, cpuinfo, cpubase, cgbase;
-
-function CSE(asml: TAsmList; first, last: tai; pass: longint): boolean;
-
-function doReplaceReg(hp: taicpu; newReg, orgReg: tsuperregister): boolean;
-function changeOp(var o: toper; newReg, orgReg: tsuperregister): boolean;
-function storeBack(start, current: tai; orgReg, newReg: tsuperregister): boolean;
-function NoHardCodedRegs(p: taicpu; orgReg, newReg: tsuperregister): boolean;
-function RegSizesOK(oldReg,newReg: tsuperregister; p: taicpu): boolean;
-
-implementation
-
-uses
-{$ifdef csdebug}
-  cutils,
-{$else}
-  {$ifdef replaceregdebug}cutils,{$endif}
-{$endif}
-  globtype, verbose, procinfo, globals, daopt386, rgobj, rropt386,cgutils;
-
-{
-function TaiInSequence(P: tai; Const Seq: TContent): Boolean;
-var P1: tai;
-    Counter: Byte;
-    TmpResult: Boolean;
-begin
-  TmpResult := False;
-  P1 := Seq.StartMod;
-  Counter := 1;
-  while not(TmpResult) and
-        (Counter <= Seq.NrofMods) do
-    begin
-      if (P = P1) then TmpResult := True;
-      inc(Counter);
-      p1 := tai(p1.Next);
-    end;
-  TaiInSequence := TmpResult;
-end;
-}
-
-function modifiesConflictingMemLocation(p1: tai; supreg: tsuperregister; c: tregContent;
-   var regsStillValid: tregset; onlymem: boolean; var invalsmemwrite: boolean): boolean;
-var
-  p: taicpu;
-  tmpRef: treference;
-  regCounter: tsuperregister;
-  opCount: longint;
-  dummy: boolean;
-begin
-  modifiesConflictingMemLocation := false;
-  invalsmemwrite := false;
-  if p1.typ <> ait_instruction then
-    exit;
-  p := taicpu(p1);
-  case p.opcode of
-    A_MOV,A_MOVSX,A_MOVZX:
-      if p.oper[1]^.typ = top_ref then
-        for regCounter := RS_EAX to RS_EDI do
-          begin
-            if (p.oper[0]^.typ<>top_reg) or
-               (getregtype(p.oper[0]^.reg) <> R_INTREGISTER) then
-               break;
-            if writeToMemDestroysContents(getsupreg(p.oper[0]^.reg),p.oper[1]^.ref^,
-                 regCounter,topsize2tcgsize[p.opsize],c[regCounter],dummy) then
-              begin
-                exclude(regsStillValid,regCounter);
-                modifiesConflictingMemLocation := not(supreg in regsStillValid);
-              end;
-            if (regcounter = supreg) then
-              invalsmemwrite := invalsmemwrite or dummy;
-          end
-      else
-{         if is_reg_var[getsupreg(p.oper[1]^.reg)] then }
-        if not onlymem  then
-          for regCounter := RS_EAX to RS_EDI do
-            begin
-              if writeDestroysContents(p.oper[1]^,regCounter,topsize2tcgsize[p.opsize],c[regCounter],dummy) then
-                begin
-                  exclude(regsStillValid,regCounter);
-                  modifiesConflictingMemLocation := not(supreg in regsStillValid);
-                end
-            end;
-    A_DIV, A_IDIV, A_MUL, A_IMUL:
-      begin
-        if not onlymem then
-          if (p.ops = 1) then
-            begin
-              for regCounter := RS_EAX to RS_EDI do
-                begin
-                  if writeToRegDestroysContents(RS_EDX,regCounter,c[regCounter]) then
-                    begin
-                      exclude(regsStillValid,RS_EDX);
-                      modifiesConflictingMemLocation := not(supreg in regsStillValid);
-                    end;
-                  if writeToRegDestroysContents(RS_EAX,regCounter,c[regCounter]) then
-                    begin
-                      exclude(regsStillValid,RS_EAX);
-                      modifiesConflictingMemLocation := not(supreg in regsStillValid);
-                    end;
-                end
-            end
-          else
-            { only possible for imul }
-            { last operand is always destination }
-            for regCounter := RS_EAX to RS_EDI do
-              begin
-                if writeDestroysContents(p.oper[p.ops-1]^,regCounter,topsize2tcgsize[p.opsize],c[regCounter],dummy) then
-                  begin
-                    exclude(regsStillValid,regCounter);
-                    modifiesConflictingMemLocation := not(supreg in regsStillValid);
-                  end
-              end
-      end;
-    else
-      for opCount := 1 to maxinschanges do
-        case InsProp[p.opcode].Ch[opCount] of
-          Ch_MOp1,CH_WOp1,CH_RWOp1:
-              if not(onlymem) or
-                 (p.oper[0]^.typ = top_ref) then
-{                or ((p.oper[0]^.typ = top_reg) and }
-{                 is_reg_var[getsupreg(p.oper[0]^.reg)]) then }
-                for regCounter := RS_EAX to RS_EDI do
-                  begin
-                    if writeDestroysContents(p.oper[0]^,regCounter,topsize2tcgsize[p.opsize],c[regCounter],dummy) then
-                      begin
-                        exclude(regsStillValid,regCounter);
-                        modifiesConflictingMemLocation := not(supreg in regsStillValid);
-                      end;
-                    if (regcounter = supreg) then
-                      invalsmemwrite := invalsmemwrite or dummy;
-                  end;
-          Ch_MOp2,CH_WOp2,CH_RWOp2:
-              if not(onlymem) or
-                 (p.oper[1]^.typ = top_ref) then
-{                or ((p.oper[1]^.typ = top_reg) and }
-{                 is_reg_var[getsupreg(p.oper[1]^.reg)]) then }
-                for regCounter := RS_EAX to RS_EDI do
-                  begin
-                    if writeDestroysContents(p.oper[1]^,regCounter,topsize2tcgsize[p.opsize],c[regCounter],dummy) then
-                      begin
-                        exclude(regsStillValid,regCounter);
-                        modifiesConflictingMemLocation := not(supreg in regsStillValid);
-                      end;
-                    if (regcounter = supreg) then
-                      invalsmemwrite := invalsmemwrite or dummy;
-                  end;
-          Ch_MOp3,CH_WOp3,CH_RWOp3:
-              if not(onlymem) or
-                 (p.oper[2]^.typ = top_ref) then
-{                or ((p.oper[2]^.typ = top_reg) and }
-{                 is_reg_var[getsupreg(p.oper[2]^.reg)]) then }
-                for regCounter := RS_EAX to RS_EDI do
-                  begin
-                    if writeDestroysContents(p.oper[2]^,regCounter,topsize2tcgsize[p.opsize],c[regCounter],dummy) then
-                      begin
-                        exclude(regsStillValid,regCounter);
-                        modifiesConflictingMemLocation := not(supreg in regsStillValid);
-                      end;
-                    if (regcounter = supreg) then
-                      invalsmemwrite := invalsmemwrite or dummy;
-                  end;
-          Ch_WMemEDI:
-            begin
-              fillchar(tmpref,sizeof(tmpref),0);
-              tmpRef.base := NR_EDI;
-              tmpRef.index := NR_EDI;
-              for regCounter := RS_EAX to RS_EDI do
-                begin
-                  if writeToMemDestroysContents(RS_INVALID,tmpRef,regCounter,OS_32,c[regCounter],dummy) then
-                    begin
-                      exclude(regsStillValid,regCounter);
-                      modifiesConflictingMemLocation := not(supreg in regsStillValid);
-                   end;
-                  if (regcounter = supreg) then
-                    invalsmemwrite := invalsmemwrite or dummy;
-                end;
-            end;
-        end;
-  end;
-end;
-
-
-function isSimpleMemLoc(const ref: treference): boolean;
-begin
-{  isSimpleMemLoc :=
-    (ref.index = RS_NO) and
-    not(ref.base in (rg.usableregsint+[RS_EDI]));}
-  isSimpleMemLoc :=
-    (ref.index = NR_NO) and
-    ((ref.base = NR_NO) or
-     not(getsupreg(ref.base) in [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESI,RS_EDI]));
-end;
-
-
-{checks whether the current instruction sequence (starting with p) and the
- one between StartMod and EndMod of Reg are the same. if so, the number of
- instructions that match is stored in Found and true is returned, otherwise
- Found holds the number of instructions between StartMod and EndMod and false
- is returned}
-function CheckSequence(p: tai; var prev: tai; supreg: tsuperregister; var Found: Longint;
-           var reginfo: toptreginfo; findPrevSeqs: boolean): Boolean;
-
-var
-  regsNotRead, regsStillValid : tregset;
-  checkingPrevSequences,
-  passedFlagsModifyingInstr   : boolean;
-
-  function getPrevSequence(p: tai; supreg: tsuperregister; currentPrev: tai; var newPrev: tai): tsuperregister;
-
-  const
-    current_reg: tsuperregister = RS_INVALID;
-
-    function stillValid(p: tai): boolean;
-      var
-        hp: tai;
-      begin
-        { only regvars are still used at jump instructions }
-        if (cs_opt_regvar in current_settings.optimizerswitches) and
-           (p.typ = ait_instruction) and
-           taicpu(p).is_jmp then
-         regsstillvalid := regsstillvalid - ptaiprop(p.optinfo)^.usedregs;
-
-        stillValid :=
-          (p.typ = ait_instruction) and
-          (taicpu(p).opcode <> a_jmp) and
-          (ptaiprop(p.optinfo)^.regs[supreg].wstate =
-            ptaiprop(currentPrev.optinfo)^.regs[supreg].wstate) and
-        { in case destroyreg is called with doIncState = false }
-          (ptaiprop(p.optinfo)^.regs[supreg].typ =
-            ptaiprop(currentPrev.optinfo)^.regs[supreg].typ) and
-          (supreg in (regsNotRead * regsStillValid));
-        { stop if the register was still used right before a (conditional) }
-        { jump, since in that case its current contents could still be     }
-        { used in the other path of the jump)                              }
-        if (p.typ = ait_instruction) and
-           (taicpu(p).is_jmp) and
-           getlastinstruction(p,hp) then
-          stillValid := stillValid and
-           not(supreg in ptaiprop(hp.optinfo)^.usedregs);
-        passedFlagsModifyingInstr := passedFlagsModifyingInstr or
-          instrWritesFlags(currentPrev);
-      end;
-
-
-    function findChangedRegister(p: tai): tsuperregister;
-    var
-      regCounter, loopstart: tsuperregister;
-    begin
-      if (current_reg <> RS_INVALID) then
-        loopstart := succ(current_reg)
-      else
-        loopstart := RS_EAX;
-      for regCounter := loopstart to RS_EDI do
-        with ptaiprop(p.optinfo)^.regs[regCounter] do
-        if ((startmod <>
-             ptaiprop(currentPrev.optinfo)^.regs[regCounter].startmod)  or
-            (nrofMods <>
-             ptaiprop(currentPrev.optinfo)^.regs[regCounter].nrofMods)) and
-           (ptaiprop(p.optinfo)^.regs[regCounter].typ in [con_ref,con_noRemoveRef]) then
-          begin
-            findChangedRegister := regCounter;
-            current_reg := regCounter;
-            exit;
-          end;
-      current_reg := RS_INVALID;
-      findChangedRegister := RS_INVALID;
-    end;
-
-
-  var
-    hp, prevFound: tai;
-    tmpResult, regCounter: tsuperregister;
-    invalsmemwrite: boolean;
-  begin
-    if (current_reg <> RS_EDI) and
-       (current_reg <> RS_INVALID) then
-      begin
-        tmpResult := findChangedRegister(currentPrev);
-        if tmpResult <> RS_INVALID then
-          begin
-            getPrevSequence := tmpResult;
-            exit;
-          end;
-      end;
-
-    getPrevSequence := RS_INVALID;
-    passedFlagsModifyingInstr := passedFlagsModifyingInstr or
-      instrWritesFlags(currentPrev);
-    if (cs_opt_regvar in current_settings.optimizerswitches) and
-       (currentprev.typ = ait_instruction) and
-       taicpu(currentprev).is_jmp then
-      regsstillvalid := regsstillvalid - ptaiprop(currentprev.optinfo)^.usedregs;
-
-    if not getLastInstruction(currentPrev,hp) then
-      exit;
-
-    prevFound := currentPrev;
-    tmpResult := RS_INVALID;
-
-    while (tmpResult = RS_INVALID) and
-          stillValid(hp) and
-          (ptaiprop(prevFound.optinfo)^.canBeRemoved or
-           not(modifiesConflictingMemLocation(prevFound,supreg,
-             ptaiprop(p.optinfo)^.regs,regsStillValid,false, invalsmemwrite))) do
-      begin
-        { only update the regsread for the instructions we already passed }
-        if not(ptaiprop(prevFound.optinfo)^.canBeRemoved) then
-          for regCounter := RS_EAX to RS_EDI do
-            if regReadByInstruction(regCounter,prevFound) then
-              exclude(regsNotRead,regCounter);
-
-        { in case getPreviousInstruction fails and sets hp to nil in the }
-        { next iteration                                                 }
-        prevFound := hp;
-        if not(ptaiprop(hp.optinfo)^.canBeRemoved) then
-          tmpResult := findChangedRegister(hp);
-        if not getLastInstruction(hp,hp) then
-          break;
-      end;
-    getPrevSequence := tmpResult;
-    if tmpResult <> RS_INVALID then
-      newPrev := prevFound;
-  end;
-
-
-  function getNextRegToTest(var prev: tai; currentReg: tsuperregister): tsuperregister;
-  begin
-    getNextRegToTest := RS_INVALID;
-    if not checkingPrevSequences then
-      begin
-        if (currentreg = RS_INVALID) then
-          currentreg := RS_EAX
-        else
-          inc(currentreg);
-        while (currentReg <= RS_EDI) and
-              not(ptaiprop(prev.optinfo)^.regs[currentReg].typ in [con_ref,con_noRemoveRef]) do
-          inc(currentReg);
-        if currentReg > RS_EDI then
-          begin
-            if (taicpu(p).oper[0]^.typ <> top_ref) or
-               isSimpleMemLoc(taicpu(p).oper[0]^.ref^) then
-              begin
-                checkingPrevSequences := true;
-              end
-            else
-              getNextRegToTest := RS_INVALID;
-          end
-        else
-          getNextRegToTest := currentReg;
-      end;
-    if checkingPrevSequences then
-      if findPrevSeqs then
-        getNextRegToTest :=
-          getPrevSequence(p,supreg,prev,prev)
-      else
-        getNextRegToTest := RS_INVALID;
-  end;
-
-
-  function changedreginvalidatedbetween(const oldreginfo: toptreginfo; var newreginfo: toptreginfo; startp,endp,current: tai): boolean;
-    var
-      orgdiffregs,diffregs: tregset;
-      runner: tai;
-      invalsmemwrite: boolean;
-    begin
-      diffregs := newreginfo.newregsencountered - oldreginfo.newregsencountered;
-      orgdiffregs := diffregs;
-      if diffregs <> [] then
-        begin
-          runner := startp;
-          repeat
-            modifiesConflictingMemLocation(runner,RS_EAX { dummy },ptaiprop(current.optinfo)^.regs,diffregs,true,invalsmemwrite);
-            if orgdiffregs <> diffregs then
-              begin
-                changedreginvalidatedbetween := true;
-                newreginfo := oldreginfo;
-                exit;
-              end;
-            getnextinstruction(runner,runner);
-          until (runner = endp);
-        end;
-      changedreginvalidatedbetween := false;
-    end;
-
-var
-  prevreginfo: toptreginfo;
-  hp2, hp3{, EndMod}, prevhp3, highPrev, orgPrev, pprev: tai;
-  {Cnt,} OldNrofMods: Longint;
-  startRegInfo, OrgRegInfo, HighRegInfo: toptreginfo;
-  regModified, lastregloadremoved: array[RS_EAX..RS_ESP] of boolean;
-  HighFound, OrgRegFound: longint;
-  regcounter, regCounter2, tmpreg, base, index: tsuperregister;
-  OrgRegResult: Boolean;
-  TmpResult, flagResultsNeeded: Boolean;
-begin {CheckSequence}
-  TmpResult := False;
-  FillChar(OrgRegInfo, Sizeof(OrgRegInfo), 0);
-  FillChar(startRegInfo, sizeof(startRegInfo), 0);
-  FillChar(HighRegInfo, sizeof(HighRegInfo), 0);
-  FillChar(prevreginfo, sizeof(prevreginfo), 0);
-  OrgRegFound := 0;
-  HighFound := 0;
-  OrgRegResult := False;
-  highPrev := nil;
-  orgPrev := nil;
-  with startRegInfo do
-    begin
-      newRegsEncountered := [RS_EBP, RS_ESP];
-      fillword(new2oldreg,sizeof(new2oldreg),RS_INVALID);
-      new2OldReg[RS_EBP] := RS_EBP;
-      new2OldReg[RS_ESP] := RS_ESP;
-      oldRegsEncountered := newRegsEncountered;
-    end;
-
-  checkingPrevSequences := false;
-  passedFlagsModifyingInstr := false;
-  flagResultsNeeded := false;
-  regsNotRead := [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESP,RS_EBP,RS_EDI,RS_ESI];
-  regsStillValid := regsNotRead;
-  GetLastInstruction(p, prev);
-  pprev := prev;
-  tmpreg:=RS_INVALID;
-  regCounter := getNextRegToTest(prev,tmpreg);
-  while (regcounter <> RS_INVALID) do
-    begin
-      fillchar(regModified,sizeof(regModified),0);
-      fillchar(lastregloadremoved,sizeof(lastregloadremoved),0);
-      reginfo := startRegInfo;
-      Found := 0;
-      hp2 := ptaiprop(prev.optinfo)^.Regs[regcounter].StartMod;
-      if (prev <> ptaiprop(prev.optinfo)^.Regs[regcounter].StartMod) then
-        OldNrofMods := ptaiprop(prev.optinfo)^.Regs[regcounter].NrofMods
-      else
-        OldNrofMods := 1;
-      hp3 := p;
-      if checkingprevsequences then
-        prevreginfo := reginfo;
-      while (Found <> OldNrofMods) and
-                                  { old  new }
-             InstructionsEquivalent(hp2, hp3, reginfo) and
-             (not(checkingprevsequences) or
-              not(changedreginvalidatedbetween(prevreginfo,reginfo,prev,p,hp3))) do
-        begin
-          if checkingprevsequences then
-            begin
-              prevreginfo := reginfo;
-            end;
-          if (hp3.typ = ait_instruction) and
-             ((taicpu(hp3).opcode = A_MOV) or
-              (taicpu(hp3).opcode = A_MOVZX) or
-              (taicpu(hp3).opcode = A_LEA) or
-             (taicpu(hp3).opcode = A_MOVSX)) and
-             (taicpu(hp3).oper[1]^.typ = top_reg) and
-             not(regInOp(getsupreg(taicpu(hp3).oper[1]^.reg),taicpu(hp3).oper[0]^)) then
-            begin
-              tmpreg := getsupreg(taicpu(hp3).oper[1]^.reg);
-              lastregloadremoved[tmpreg] := ptaiprop(hp2.optinfo)^.canberemoved;
-              reginfo.lastReload[tmpreg] := hp3;
-              case taicpu(hp3).oper[0]^.typ of
-                top_ref:
-                  begin
-                    base := getsupreg(taicpu(hp3).oper[0]^.ref^.base);
-                    index := getsupreg(taicpu(hp3).oper[0]^.ref^.index);
-                    if (found <> 0) and
-                       ((taicpu(hp3).oper[0]^.ref^.base = NR_NO) or
-                        regModified[base] or
-                        (base = getsupreg(current_procinfo.framepointer))) and
-                       ((taicpu(hp3).oper[0]^.ref^.index = NR_NO) or
-                        regModified[index]) and
-                       not(regInRef(tmpReg,taicpu(hp3).oper[0]^.ref^)) then
-                      begin
-                        with ptaiprop(hp3.optinfo)^.regs[tmpreg] do
-                          if nrofMods > (oldNrofMods - found) then
-                            oldNrofMods := found + nrofMods;
-                        { next is safe because instructions are equivalent }
-                        with ptaiprop(hp2.optinfo)^.regs[getsupreg(taicpu(hp2).oper[1]^.reg)] do
-                          if nrofMods > (oldNrofMods - found) then
-                            oldNrofMods := found + nrofMods;
-                      end;
-                  end;
-                top_reg:
-                  if regModified[getsupreg(taicpu(hp3).oper[0]^.reg)] then
-                    begin
-                      with ptaiprop(hp3.optinfo)^.regs[tmpreg] do
-                        if nrofMods > (oldNrofMods - found) then
-                          oldNrofMods := found + nrofMods;
-                      with ptaiprop(hp2.optinfo)^.regs[getsupreg(taicpu(hp2).oper[1]^.reg)] do
-                        if nrofMods > (oldNrofMods - found) then
-                          oldNrofMods := found + nrofMods;
-                    end;
-              end;
-            end;
-          for regCounter2 := RS_EAX to RS_EDI do
-            regModified[regCounter2] := regModified[regCounter2] or
-              regModifiedByInstruction(regCounter2,hp3);
-          if flagResultsNeeded then
-            flagResultsNeeded := not instrReadsFlags(hp3);
-          if not flagResultsNeeded then
-            flagResultsNeeded := ptaiprop(hp3.optinfo)^.FlagsUsed;
-          inc(Found);
-          prevhp3 := hp3;
-          if (Found <> OldNrofMods) then
-            if not GetNextInstruction(hp2, hp2) or
-               not GetNextInstruction(hp3, hp3) then
-              break;
-        end;
-
-      if assigned(hp3) then
-        begin
-          prevhp3 := hp3;
-          getnextinstruction(hp3,hp3);
-        end;
-      if not assigned(hp3) or
-         { a marker has no optinfo, which is used below }
-         (hp3.typ = ait_marker) then
-        hp3 := prevhp3;
-{
-a) movl  -4(%ebp),%edx
-   movl -12(%ebp),%ecx
-   ...
-   movl  -8(%ebp),%eax
-   movl -12(%ebp),%edx (marked as removable)
-   movl  (%eax,%edx),%eax (replaced by "movl (%eax,%ecx),%eax")
-   ...
-   movl  -8(%ebp),%eax
-   movl -12(%ebp),%edx
-   movl  (%eax,%edx),%eax
-   movl  (%edx),%edx
-
--> the "movl -12(ebp),%edx" can't be removed in the last sequence, because
-   edx has not been replaced with ecx there, and edx is still used after the
-   sequence
-
-b) tests/webtbs/tw4266.pp
-}
-
-      { hp2 = instruction after previous sequence, pprev = instruction before }
-      { current sequence, prev = instruction where the loads of the registers }
-      { will be inserted                                                      }
-      for regCounter2 := RS_EAX to RS_EDI do
-        if (reginfo.new2OldReg[regCounter2] <> RS_INVALID) and
-           { case a) above }
-           (((regCounter2 in ptaiprop(hp3.optinfo)^.usedRegs) and
-             (not regLoadedWithNewValue(regCounter2,false,hp3) and
-              lastregloadremoved[regcounter2])) or
-           { case b) above }
-            ((ptaiprop(hp2.optinfo)^.regs[regCounter2].wstate <>
-              ptaiprop(pprev.optinfo)^.regs[regcounter2].wstate)) or
-            ((ptaiprop(hp2.optinfo)^.regs[reginfo.new2OldReg[regCounter2]].wstate <>
-              ptaiprop(prev.optinfo)^.regs[reginfo.new2OldReg[regCounter2]].wstate))) then
-          begin
-            found := 0;
-            break;
-          end;
-
-      if checkingPrevSequences then
-        begin
-          for regCounter2 := RS_EAX to RS_EDI do
-            if (reginfo.new2OldReg[regCounter2] <> RS_INVALID) and
-               (reginfo.new2OldReg[regCounter2] <> regCounter2) and
-               (not(regCounter2 in (regsNotRead * regsStillValid)) or
-               not(reginfo.new2OldReg[regCounter2] in regsStillValid)) then
-              begin
-                found := 0;
-                break;
-              end;
-           if passedFlagsModifyingInstr and flagResultsNeeded then
-              found := 0;
-        end;
-
-      TmpResult := true;
-      if (found <> OldNrofMods) then
-        TmpResult := false
-      else if assigned(hp3) then
-        for regcounter2 := RS_EAX to RS_EDI do
-          if (regcounter2 in reginfo.regsLoadedforRef) and
-             regModified[regcounter2] and
-             (regcounter2 in ptaiprop(hp3.optinfo)^.usedRegs) and
-             not regLoadedWithNewValue(regcounter2,false,hp3) then
-            begin
-              TmpResult := False;
-              if (found > 0) then
-    {this is correct because we only need to turn off the CanBeRemoved flag
-    when an instruction has already been processed by CheckSequence
-    (otherwise CanBeRemoved can't be true and thus can't have to be turned off).
-    if it has already been processed by CheckSequence and flagged to be
-    removed, it means that it has been checked against a previous sequence
-    and that it was equal (otherwise CheckSequence would have returned false
-    and the instruction wouldn't have been removed). if this "if found > 0"
-    check is left out, incorrect optimizations are performed.}
-                Found := ptaiprop(tai(p).optinfo)^.Regs[supreg].NrofMods;
-              break;
-            end;
-
-      if TmpResult and
-         (Found > HighFound) then
-        begin
-          highPrev := prev;
-          HighFound := Found;
-          HighRegInfo := reginfo;
-        end;
-      if (regcounter = supreg) then
-        begin
-          orgPrev := prev;
-          OrgRegFound := Found;
-          OrgRegResult := TmpResult;
-          OrgRegInfo := reginfo
-        end;
-      regCounter := getNextRegToTest(prev,regCounter);
-    end;
-  if (HighFound > 0) and
-     (not(OrgRegResult) Or
-      (HighFound > OrgRegFound))
-    then
-      begin
-        CheckSequence := True;
-        prev := highPrev;
-        reginfo := HighRegInfo;
-        Found := HighFound
-      end
-    else
-      begin
-        CheckSequence := OrgRegResult;
-        prev := orgPrev;
-        Found := OrgRegFound;
-        reginfo := OrgRegInfo;
-      end;
-end; {CheckSequence}
-
-
-procedure SetAlignReg(p: tai);
-Const alignSearch = 12;
-var regsUsable: TRegSet;
-    prevInstrCount, nextInstrCount: Longint;
-    prevState, nextWState,nextRState: Array[RS_EAX..RS_EDI] of byte;
-    regCounter, lastRemoved: tsuperregister;
-    prev, next: tai;
-{$ifdef alignregdebug}
-    temp: tai;
-{$endif alignregdebug}
-begin
-  regsUsable := [RS_EAX,RS_ECX,RS_EDX,RS_EBX,{R_ESP,RS_EBP,}RS_ESI,RS_EDI];
-  for regCounter := RS_EAX to RS_EDI do
-    begin
-      prevState[regCounter] := ptaiprop(p.optinfo)^.Regs[regCounter].wState;
-      nextWState[regCounter] := ptaiprop(p.optinfo)^.Regs[regCounter].wState;
-      nextRState[regCounter] := ptaiprop(p.optinfo)^.Regs[regCounter].rState;
-    end;
-  getLastInstruction(p,prev);
-  getNextInstruction(p,next);
-  lastRemoved := getsupreg(tai_align(p).reg);
-  nextInstrCount := 0;
-  prevInstrCount := 0;
-  while ((assigned(prev) and
-          assigned(prev.optinfo) and
-          (prevInstrCount < alignSearch)) or
-         (assigned(next) and
-          assigned(next.optinfo) and
-          (nextInstrCount < alignSearch))) and
-        (regsUsable <> []) do
-    begin
-{$ifdef alignregdebug}
-      if assigned(prev) then
-        begin
-          temp := tai_comment.Create(strpnew('got here'));
-          temp.next := prev.next;
-          temp.previous := prev;
-          prev.next := temp;
-          if assigned(temp.next) then
-            temp.next.previous := temp;
-        end;
-{$endif alignregdebug}
-      if assigned(prev) and assigned(prev.optinfo) and
-         (prevInstrCount < alignSearch) then
-        begin
-          if (prev.typ = ait_instruction) and
-             (insProp[taicpu(prev).opcode].ch[1] <> Ch_ALL) and
-             (taicpu(prev).opcode <> A_JMP) then
-            begin
-              inc(prevInstrCount);
-              for regCounter := RS_EAX to RS_EDI do
-                begin
-                  if (regCounter in regsUsable) and
-                     (ptaiprop(prev.optinfo)^.Regs[regCounter].wState <>
-                       prevState[regCounter]) then
-                    begin
-                      lastRemoved := regCounter;
-                      exclude(regsUsable,regCounter);
-{$ifdef alignregdebug}
-                      temp := tai_comment.Create(strpnew(
-                                std_regname(newreg(R_INTREGISTER,regCounter,R_SUBWHOLE))+' removed')));
-                      temp.next := prev.next;
-                      temp.previous := prev;
-                      prev.next := temp;
-                      if assigned(temp.next) then
-                        temp.next.previous := temp;
-                      if regsUsable = [] then
-                        begin
-                          temp := tai_comment.Create(strpnew(
-                                    'regsUsable empty here')));
-                          temp.next := prev.next;
-                          temp.previous := prev;
-                          prev.next := temp;
-                          if assigned(temp.next) then
-                            temp.next.previous := temp;
-                        end;
-{$endif alignregdebug}
-                    end;
-                  prevState[regCounter] :=
-                    ptaiprop(prev.optinfo)^.Regs[regCounter].wState;
-                end;
-              getLastInstruction(prev,prev);
-            end
-          else
-            if GetLastInstruction(prev,prev) and
-               assigned(prev.optinfo) then
-              for regCounter := RS_EAX to RS_EDI do
-                prevState[regCounter] :=
-                  ptaiprop(prev.optinfo)^.Regs[regCounter].wState
-        end;
-      if assigned(next) and assigned(next.optinfo) and
-         (nextInstrCount < alignSearch) then
-        begin
-          if (next.typ = ait_instruction) and
-             (insProp[taicpu(next).opcode].ch[1] <> Ch_ALL) and
-             (taicpu(next).opcode <> A_JMP) then
-            begin
-              inc(nextInstrCount);
-              for regCounter := RS_EAX to RS_EDI do
-                begin
-                  if (regCounter in regsUsable) and
-                     ((ptaiprop(next.optinfo)^.Regs[regCounter].wState <>
-                       nextWState[regCounter]) or
-                      (ptaiprop(next.optinfo)^.Regs[regCounter].rState <>
-                       nextRState[regCounter])) then
-                    begin
-                      lastRemoved := regCounter;
-                      exclude(regsUsable,regCounter);
-{$ifdef alignregdebug}
-                      temp := tai_comment.Create(strpnew(
-                                std_regname(newreg(R_INTREGISTER,regCounter,R_SUBWHOLE))+' removed')));
-                      temp.next := next.next;
-                      temp.previous := next;
-                      next.next := temp;
-                      if assigned(temp.next) then
-                        temp.next.previous := temp;
-                      if regsUsable = [] then
-                        begin
-                          temp := tai_comment.Create(strpnew(
-                                    'regsUsable empty here')));
-                          temp.next := next.next;
-                          temp.previous := next;
-                          next.next := temp;
-                          if assigned(temp.next) then
-                            temp.next.previous := temp;
-                        end;
-{$endif alignregdebug}
-                    end;
-                  nextWState[regCounter] :=
-                    ptaiprop(next.optinfo)^.Regs[regCounter].wState;
-                  nextRState[regCounter] :=
-                    ptaiprop(next.optinfo)^.Regs[regCounter].rState;
-                end
-            end
-          else
-            for regCounter := RS_EAX to RS_EDI do
-              begin
-                nextWState[regCounter] :=
-                  ptaiprop(next.optinfo)^.Regs[regCounter].wState;
-                nextRState[regCounter] :=
-                  ptaiprop(next.optinfo)^.Regs[regCounter].rState;
-              end;
-          getNextInstruction(next,next);
-        end;
-    end;
-  if regsUsable <> [] then
-    for regCounter := RS_EAX to RS_EDI do
-      if regCounter in regsUsable then
-        begin
-          lastRemoved := regCounter;
-          break
-        end;
-{$ifdef alignregdebug}
-  next := tai_comment.Create(strpnew(std_regname(newreg(R_INTREGISTER,lastremoved,R_SUBWHOLE))+
-               ' chosen as alignment register')));
-  next.next := p.next;
-  next.previous := p;
-  p.next := next;
-  if assigned(next.next) then
-    next.next.previous := next;
-{$endif alignregdebug}
-  tai_align(p).reg := newreg(R_INTREGISTER,lastRemoved,R_SUBWHOLE);
-end;
-
-
-procedure clearmemwrites(p: tai; supreg: tsuperregister);
-var
-  beginmemwrite: tai;
-begin
-  beginmemwrite := ptaiprop(p.optinfo)^.regs[supreg].memwrite;
-  repeat
-    ptaiprop(p.optinfo)^.regs[supreg].memwrite := nil;
-  until not getnextinstruction(p,p) or
-        (ptaiprop(p.optinfo)^.regs[supreg].memwrite <> beginmemwrite);
-end;
-
-
-procedure ClearRegContentsFrom(asml: TAsmList; supreg: tsuperregister; p, endP: tai);
-{ first clears the contents of reg from p till endP. then the contents are }
-{ cleared until the first instruction that changes reg                     }
-var
-{$ifdef replaceregdebug}
-    hp: tai;
-    l: longint;
-{$endif replaceregdebug}
-    regcounter: tsuperregister;
-    oldStartmod: tai;
-    regstoclear: tregset;
-begin
-{$ifdef replaceregdebug}
-  l := random(1000);
-  hp := tai_comment.Create(strpnew(
-          'cleared '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+' from here... '+tostr(l)));
-  insertllitem(asml,p.previous,p,hp);
-{$endif replaceregdebug}
-  ptaiprop(p.optinfo)^.Regs[supreg].typ := con_unknown;
-  regstoclear := [supreg];
-  while (p <> endP) do
-    begin
-      for regcounter := RS_EAX to RS_EDI do
-        begin
-          if (regcounter <> supreg) and
-             assigned(ptaiprop(p.optinfo)^.regs[supreg].memwrite) and
-             reginref(regcounter,ptaiprop(p.optinfo)^.regs[supreg].memwrite.oper[1]^.ref^) then
-            clearmemwrites(p,regcounter);
-          { needs double loop to cheack for each dependency combination? }
-          if assigned(ptaiprop(p.optinfo)^.regs[regcounter].startmod) and
-             sequencedependsonreg(ptaiprop(p.optinfo)^.regs[regcounter],regcounter,supreg) then
-            include(regstoclear,regcounter);
-
-          if regcounter in regstoclear then
-            with ptaiprop(p.optinfo)^.Regs[regcounter] do
-              begin
-                typ := con_unknown;
-                memwrite := nil;
-                startmod := nil;
-                nrofmods := 0;
-              end;
-        end;
-      getNextInstruction(p,p);
-    end;
-  oldStartmod := ptaiprop(p.optinfo)^.Regs[supreg].startmod;
-  repeat
-    for regcounter := RS_EAX to RS_EDI do
-      begin
-        { needs double loop to cheack for each dependency combination? }
-        if assigned(ptaiprop(p.optinfo)^.regs[regcounter].startmod) and
-           sequencedependsonreg(ptaiprop(p.optinfo)^.regs[regcounter],regcounter,supreg) then
-          include(regstoclear,regcounter);
-        with ptaiprop(p.optinfo)^.Regs[supreg] do
-          if regcounter in regstoclear then
-            begin
-              typ := con_unknown;
-              memwrite := nil;
-            end;
-      end;
-  until not getNextInstruction(p,p) or
-        (ptaiprop(p.optinfo)^.Regs[supreg].startmod <> oldStartmod);
-{$ifdef replaceregdebug}
-  if assigned(p) then
-    begin
-      hp := tai_comment.Create(strpnew(
-        'cleared '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+' till here... '+tostr(l)));
-      insertllitem(asml,p.previous,p,hp);
-    end;
-{$endif replaceregdebug}
-end;
-
-procedure RestoreRegContentsTo(asml: TAsmList; supreg: tsuperregister; const c: TContent; p, endP: tai);
-var
-{$ifdef replaceregdebug}
-  l: longint;
-{$endif replaceregdebug}
-  hp: tai;
-  validregs, prevvalidregs: tregset;
-  regcounter: tsuperregister;
-  tmpState, newrstate: byte;
-  prevcontenttyp: byte;
-  memconflict: boolean;
-  invalsmemwrite: boolean;
-begin
-{$ifdef replaceregdebug}
-  l := random(1000);
-  hp := tai_comment.Create(strpnew(
-          'restored '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+' with data from here... '+tostr(l)));
-  insertllitem(asml,p.previous,p,hp);
-{$endif replaceregdebug}
-{  ptaiprop(p.optinfo)^.Regs[reg] := c;}
-  newrstate := c.rstate;
-  incstate(newrstate,$7f);
-  memconflict := false;
-  invalsmemwrite := false;
-  validregs := [RS_EAX..RS_EDI];
-  prevvalidregs := validregs;
-  while (p <> endP) and
-        not(memconflict) and
-        not(invalsmemwrite) do
-    begin
-      if not(ptaiprop(p.optinfo)^.canberemoved) and
-         regreadbyinstruction(supreg,p) then
-        incstate(newrstate,1);
-      // is this a write to memory that destroys the contents we are restoring?
-      memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,validregs,false,invalsmemwrite);
-      if (validregs <> prevvalidregs) then
-        begin
-          prevvalidregs := validregs >< prevvalidregs;
-          for regcounter := RS_EAX to RS_EDI do
-            if regcounter in prevvalidregs then
-              clearRegContentsFrom(asml,regcounter,p,endP);
-        end;
-      prevvalidregs := validregs;
-      if (not memconflict and not invalsmemwrite) then
-        begin
-          ptaiprop(p.optinfo)^.Regs[supreg] := c;
-          ptaiprop(p.optinfo)^.Regs[supreg].rstate := newrstate;
-        end
-      else
-        begin
-          clearRegContentsFrom(asml,supreg,p,endP);
-{$ifdef replaceregdebug}
-           if assigned(p) then
-             begin
-               hp := tai_comment.Create(strpnew(
-                 'stopping restoring of '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+'because memory conflict... '+tostr(l)));
-               insertllitem(asml,p,p.next,hp);
-             end;
-{$endif replaceregdebug}
-          exit
-        end;
-
-      getNextInstruction(p,p);
-    end;
-
-  tmpState := ptaiprop(p.optinfo)^.Regs[supreg].wState;
-  if (newrstate = ptaiprop(p.optinfo)^.Regs[supreg].rState) then
-    begin
-      incstate(ptaiprop(p.optinfo)^.regs[supreg].rstate,63);
-      if not getnextinstruction(p,hp) then
-        exit;
-      if (ptaiprop(hp.optinfo)^.regs[supreg].rstate = ptaiprop(p.optinfo)^.regs[supreg].rstate) then
-        internalerror(2004122710);
-     end;
-  repeat
-    newrstate := ptaiprop(p.optinfo)^.Regs[supreg].rState;
-    prevcontenttyp := ptaiprop(p.optinfo)^.Regs[supreg].typ;
-    // is this a write to memory that destroys the contents we are restoring?
-    memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,validregs,false,invalsmemwrite);
-    if (validregs <> prevvalidregs) then
-      begin
-        prevvalidregs := validregs >< prevvalidregs;
-        for regcounter := RS_EAX to RS_EDI do
-          if regcounter in prevvalidregs then
-            clearRegContentsFrom(asml,regcounter,p,p);
-      end;
-    prevvalidregs := validregs;
-    if (not memconflict and not invalsmemwrite) then
-      begin
-        ptaiprop(p.optinfo)^.Regs[supreg] := c;
-        ptaiprop(p.optinfo)^.Regs[supreg].rstate := newrstate;
-      end;
-  until invalsmemwrite or
-        memconflict or
-        not getNextInstruction(p,p) or
-        (ptaiprop(p.optinfo)^.Regs[supreg].wState <> tmpState) or
-        (p.typ = ait_label) or
-        ((prevcontenttyp <> con_invalid) and
-         (ptaiprop(p.optinfo)^.Regs[supreg].typ = con_invalid));
-  if assigned(p) and
-     (p.typ <> ait_marker) then
-    if ((p.typ = ait_label) or
-       memconflict or
-       invalsmemwrite) then
-      clearRegContentsFrom(asml,supreg,p,p)
-    else if (ptaiprop(p.optinfo)^.Regs[supreg].rstate = newrstate) then
-      incstate(ptaiprop(p.optinfo)^.Regs[supreg].rstate,20);
-{$ifdef replaceregdebug}
-  if assigned(p) then
-    begin
-      hp := tai_comment.Create(strpnew(
-        'restored '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+' till here... '+tostr(l)));
-     insertllitem(asml,p,p.next,hp);
-    end;
-{$endif replaceregdebug}
-end;
-
-function NoHardCodedRegs(p: taicpu; orgReg, newReg: tsuperregister): boolean;
-var
-  chCount: byte;
-begin
-  case p.opcode of
-    A_IMUL: noHardCodedRegs := p.ops <> 1;
-    A_SHL,A_SHR,A_ROR,A_ROL,A_SAR,A_SHLD,A_SHRD: noHardCodedRegs :=
-      (p.oper[0]^.typ <> top_reg) or
-      ((orgReg <> RS_ECX) and (newReg <> RS_ECX));
-    else
-      begin
-        NoHardCodedRegs := true;
-        with InsProp[p.opcode] do
-          for chCount := 1 to maxinschanges do
-            if Ch[chCount] in ([Ch_REAX..Ch_MEDI,Ch_WMemEDI,Ch_All]-[Ch_RESP,Ch_WESP,Ch_RWESP]) then
-              begin
-                NoHardCodedRegs := false;
-                break
-              end;
-      end;
-  end;
-end;
-
-
-function ChangeReg(var Reg: TRegister; newReg, orgReg: tsuperregister): boolean;
-begin
-  changereg := false;
-  if (reg <> NR_NO) and
-     (getregtype(reg) = R_INTREGISTER) and
-     (getsupreg(reg) = newreg) then
-    begin
-      changereg := true;
-      setsupreg(reg,orgreg);
-    end;
-end;
-
-
-function changeOp(var o: toper; newReg, orgReg: tsuperregister): boolean;
-var
-  tmpresult: boolean;
-begin
-  changeOp := false;
-  case o.typ of
-    top_reg: changeOp := changeReg(o.reg,newReg,orgReg);
-    top_ref:
-      begin
-        tmpresult := changeReg(o.ref^.base,newReg,orgReg);
-        changeop := changeReg(o.ref^.index,newReg,orgReg) or tmpresult;
-      end;
-  end;
-end;
-
-
-procedure updateStates(orgReg,newReg: tsuperregister; hp: tai; writeStateToo: boolean);
-var
-  prev: tai;
-  newOrgRegRState, newOrgRegWState: byte;
-begin
-  newOrgRegwState := 0;
-  if getLastInstruction(hp,prev) then
-    with ptaiprop(prev.optinfo)^ do
-      begin
-        newOrgRegRState := byte(longint(regs[orgReg].rState) +
-          longint(ptaiprop(hp.optinfo)^.regs[newReg].rState) - regs[newReg].rstate);
-        if writeStateToo then
-          newOrgRegWState := byte(longint(regs[orgReg].wState) +
-            longint(ptaiprop(hp.optinfo)^.regs[newReg].wState) - regs[newReg].wstate);
-      end
-  else
-    with ptaiprop(hp.optinfo)^.regs[newReg] do
-      begin
-        newOrgRegRState := rState;
-        if writeStateToo then
-          newOrgRegWState := wState;
-      end;
-  with ptaiprop(hp.optinfo)^.regs[orgReg] do
-    begin
-      rState := newOrgRegRState;
-      if writeStateToo then
-        wState := newOrgRegwState;
-    end;
-end;
-
-
-function doReplaceReg(hp: taicpu; newReg, orgReg: tsuperregister): boolean;
-var
-  opCount: longint;
-  tmpResult: boolean;
-begin
-  tmpresult := false;
-  for opCount := 0 to hp.ops-1 do
-    tmpResult :=
-      changeOp(hp.oper[opCount]^,newReg,orgReg) or tmpResult;
-  doReplaceReg := tmpResult;
-end;
-
-
-function RegSizesOK(oldReg,newReg: tsuperregister; p: taicpu): boolean;
-{ oldreg and newreg must be 32bit components }
-var
-  opCount: longint;
-  tmpreg: tsuperregister;
-begin
-  RegSizesOK := true;
-  { if only one of them is a general purpose register ... }
-  if (IsGP32reg(oldReg) xor IsGP32Reg(newReg)) then
-    begin
-      for opCount := 0 to p.ops-1 do
-        if (p.oper[opCount]^.typ = top_reg) and
-           (getsubreg(p.oper[opCount]^.reg) in [R_SUBL,R_SUBH]) then
-          begin
-            tmpreg := getsupreg(p.oper[opCount]^.reg);
-            if (tmpreg = oldreg) or
-               (tmpreg = newreg) then
-              begin
-                RegSizesOK := false;
-                break
-              end
-          end;
-    end;
-end;
-
-
-function doReplaceReadReg(p: taicpu; newReg,orgReg: tsuperregister): boolean;
-var
-  opCount: longint;
-begin
-  doReplaceReadReg := false;
-  { handle special case }
-  case p.opcode of
-    A_IMUL:
-      begin
-        case p.ops of
-          1: internalerror(1301001);
-          2,3:
-            begin
-              if changeOp(p.oper[0]^,newReg,orgReg) then
-                begin
-{                  updateStates(orgReg,newReg,p,false);}
-                  doReplaceReadReg := true;
-                end;
-             if p.ops = 3 then
-                if changeOp(p.oper[1]^,newReg,orgReg) then
-                  begin
-{                    updateStates(orgReg,newReg,p,false);}
-                    doReplaceReadReg := true;
-                  end;
-            end;
-        end;
-      end;
-    A_DIV,A_IDIV,A_MUL: internalerror(1301002);
-    else
-      begin
-        for opCount := 0 to p.ops-1 do
-          if p.oper[opCount]^.typ = top_ref then
-            if changeOp(p.oper[opCount]^,newReg,orgReg) then
-              begin
-{                updateStates(orgReg,newReg,p,false);}
-                doReplaceReadReg := true;
-              end;
-        for opCount := 1 to maxinschanges do
-          case InsProp[p.opcode].Ch[opCount] of
-            Ch_ROp1:
-              if p.oper[0]^.typ = top_reg then
-                if changeReg(p.oper[0]^.reg,newReg,orgReg) then
-                  begin
-{                    updateStates(orgReg,newReg,p,false);}
-                    doReplaceReadReg := true;
-                  end;
-            Ch_ROp2:
-              if p.oper[1]^.typ = top_reg then
-                if changeReg(p.oper[1]^.reg,newReg,orgReg) then
-                  begin
-{                    updateStates(orgReg,newReg,p,false);}
-                    doReplaceReadReg := true;
-                  end;
-            Ch_ROp3:
-              if p.oper[2]^.typ = top_reg then
-                if changeReg(p.oper[2]^.reg,newReg,orgReg) then
-                  begin
-{                    updateStates(orgReg,newReg,p,false);}
-                    doReplaceReadReg := true;
-                  end;
-          end;
-      end;
-  end;
-end;
-
-
-procedure updateState(supreg: tsuperregister; p: tai);
-{ this procedure updates the read and write states of the instructions }
-{ coming after p. It's called when the read/write state of p has been  }
-{ changed and this change has to be propagated to the following        }
-{ instructions as well                                                 }
-var
-  newRState, newWState: byte;
-  prevRState, prevWState: byte;
-  doRState, doWState: boolean;
-begin
-  { get the new read/write states from p }
-  with ptaiprop(p.optinfo)^.regs[supreg] do
-    begin
-      newRState := rState;
-      newWState := wState;
-    end;
-  if not GetNextInstruction(p,p) then
-    exit;
-  { get the old read/write states from the next instruction, to know }
-  { when we can stop updating                                        }
-  with ptaiprop(p.optinfo)^.regs[supreg] do
-    begin
-      prevRState := rState;
-      prevWState := wState;
-    end;
-  { adjust the states if this next instruction reads/writes the register }
-  if regReadByInstruction(supreg,p) then
-    incState(newRState,1);
-  if regModifiedByInstruction(supreg,p) then
-    incState(newWState,1);
-  { do we still have to update the read and/or write states? }
-  doRState := true;
-  doWState := true;
-  repeat
-    { update the states }
-    with ptaiprop(p.optinfo)^.regs[supreg] do
-      begin
-        if doRState then
-          rState := newRState;
-        if doWState then
-          wState := newWState;
-      end;
-    if not getNextInstruction(p,p) then
-      break;
-    with ptaiprop(p.optinfo)^.regs[supreg] do
-      begin
-        { stop updating the read state if it changes }
-        doRState :=
-          doRState and (rState = prevRState);
-        { if, by accident, this changed state is the same as the one }
-        { we've been using, change it to a value that's definitely   }
-        { different from the previous and next state                 }
-        if not doRState and
-           (rState = newRState) then
-          begin
-            incState(newRState,1);
-            prevRState := rState;
-            doRState := true;
-          end;
-        { ditto for the write state }
-        doWState :=
-          doWState and (WState = prevWState);
-        if not doWState and
-           (wState = newWState) then
-          begin
-            incState(newWState,1);
-            prevWState := wState;
-            doWState := true;
-          end;
-      end;
-  { stop when we don't have to update either state anymore }
-  until not(doRState or doWState);
-end;
-
-
-function storeBack(start, current: tai; orgReg, newReg: tsuperregister): boolean;
-{ returns true if p1 contains an instruction that stores the contents }
-{ of newReg back to orgReg                                            }
-begin
-  storeback := false;
-  if (current.typ = ait_instruction) and
-     (taicpu(current).opcode = A_MOV) and
-     (taicpu(current).oper[0]^.typ = top_reg) and
-     (getsupreg(taicpu(current).oper[0]^.reg) = newReg) and
-     (taicpu(current).oper[1]^.typ = top_reg) and
-     (getsupreg(taicpu(current).oper[1]^.reg) = orgReg) then
-    case taicpu(current).opsize of
-      S_B:
-        storeback := true;
-      S_W:
-        storeback := taicpu(start).opsize <> S_B;
-      S_L:
-        storeback := taicpu(start).opsize = S_L;
-      else
-        internalerror(2003121501);
-    end;
-end;
-
-
-function canreplacereg(orgsupreg, newsupreg: tsuperregister; p: tai;
-  orgRegCanBeModified: boolean; var resnewregmodified, resorgregread, resremovelast: boolean; var returnendp: tai): boolean;
-var
-  endP, hp: tai;
-  removeLast, sequenceEnd, tmpResult, newRegModified, orgRegRead: boolean;
-begin
-  canreplacereg := false;
-  tmpResult := true;
-  sequenceEnd := false;
-  newRegModified := false;
-  orgRegRead := false;
-  removeLast := false;
-  endP := p;
-  while tmpResult and not sequenceEnd do
-    begin
-      tmpResult :=
-        getNextInstruction(endP,endP) and
-        (endp.typ = ait_instruction) and
-        not(taicpu(endp).is_jmp);
-      if tmpresult and not assigned(endp.optinfo) then
-        begin
-{          hp := tai_comment.Create(strpnew('next no optinfo'));
-          hp.next := endp;
-          hp.previous := endp.previous;
-          endp.previous := hp;
-          if assigned(hp.previous) then
-            hp.previous.next := hp;}
-          exit;
-        end;
-      if tmpResult and
-         { don't take into account instructions that will be removed }
-         not (ptaiprop(endp.optinfo)^.canBeRemoved) then
-        begin
-          { if the newsupreg gets stored back to the oldReg, we can change }
-          { "mov %oldReg,%newReg; <operations on %newReg>; mov %newReg, }
-          { %oldReg" to "<operations on %oldReg>"                       }
-          removeLast := storeBack(p,endP, orgsupreg, newsupreg);
-          sequenceEnd :=
-            { no support for (i)div, mul and imul with hardcoded operands }
-            noHardCodedRegs(taicpu(endP),orgsupreg,newsupreg) and
-            { if newsupreg gets loaded with a new value, we can stop   }
-            { replacing newsupreg with oldReg here (possibly keeping   }
-            { the original contents of oldReg so we still know them }
-            { afterwards)                                           }
-             (RegLoadedWithNewValue(newsupreg,true,taicpu(endP)) or
-            { we can also stop if we reached the end of the use of }
-            { newReg's current contents                            }
-              (GetNextInstruction(endp,hp) and
-               FindRegDealloc(newsupreg,hp)));
-          { to be able to remove the first and last instruction of  }
-          {   movl %reg1, %reg2                                     }
-          {   <operations on %reg2> (replacing reg2 with reg1 here) }
-          {   movl %reg2, %reg1                                     }
-          { %reg2 must not be use afterwards (it can be as the      }
-          { result of a peepholeoptimization)                       }
-          removeLast := removeLast and sequenceEnd;
-          newRegModified :=
-            newRegModified or
-            (not(regLoadedWithNewValue(newsupreg,true,taicpu(endP))) and
-             RegModifiedByInstruction(newsupreg,endP));
-          orgRegRead := newRegModified and RegReadByInstruction(orgsupreg,endP);
-          sequenceEnd := SequenceEnd and
-                         (removeLast or
-    { since newsupreg will be replaced by orgsupreg, we can't allow that newsupreg }
-    { gets modified if orgsupreg is still read afterwards (since after       }
-    { replacing, this would mean that orgsupreg first gets modified and then }
-    { gets read in the assumption it still contains the unmodified value) }
-                         not(newRegModified and orgRegRead)) (* and
-    { since newsupreg will be replaced by orgsupreg, we can't allow that newsupreg }
-    { gets modified if orgRegCanBeModified = false                        }
-
-    { this now gets checked after the loop (JM) }
-                         (orgRegCanBeModified or not(newRegModified)) *);
-          tmpResult :=
-            not(removeLast) and
-            not(newRegModified and orgRegRead) and
-(*            (orgRegCanBeModified or not(newRegModified)) and *)
-(*          already checked at the top
-            (endp.typ = ait_instruction) and  *)
-            NoHardCodedRegs(taicpu(endP),orgsupreg,newsupreg) and
-            RegSizesOk(orgsupreg,newsupreg,taicpu(endP)) and
-            not RegModifiedByInstruction(orgsupreg,endP);
-        end;
-    end;
-  canreplacereg := sequenceEnd and
-     (removeLast  or
-      (orgRegCanBeModified or not(newRegModified))) and
-     (not(assigned(endp)) or
-      not(endp.typ = ait_instruction) or
-      (noHardCodedRegs(taicpu(endP),orgsupreg,newsupreg) and
-       RegSizesOk(orgsupreg,newsupreg,taicpu(endP)) and
-       not(newRegModified and
-           (orgsupreg in ptaiprop(endp.optinfo)^.usedRegs) and
-           not(RegLoadedWithNewValue(orgsupreg,true,taicpu(endP))))));
-  if canreplacereg then
-    begin
-      resnewregmodified := newregmodified;
-      resorgregread := orgregread;
-      resremovelast := removelast;
-    end;
-  { needed for replaceregdebug code }
-  returnendp := endp;
-end;
-
-
-
-function ReplaceReg(asml: TAsmList; orgsupreg, newsupreg: tsuperregister; p,
-          seqstart: tai; const c: TContent; orgRegCanBeModified: Boolean;
-          var returnEndP: tai): Boolean;
-{ Tries to replace orgsupreg with newsupreg in all instructions coming after p }
-{ until orgsupreg gets loaded with a new value. Returns true if successful, }
-{ false otherwise. if successful, the contents of newsupreg are set to c,   }
-{ which should hold the contents of newsupreg before the current sequence   }
-{ started                                                                }
-{ if the function returns true, returnEndP holds the last instruction    }
-{ where newsupreg was replaced by orgsupreg                                    }
-var
-  endP, hp: tai;
-  removeLast, newRegModified, orgRegRead,
-    stateChanged, readStateChanged: Boolean;
-{$ifdef replaceregdebug}
-  l: longint;
-{$endif replaceregdebug}
-
-begin
-  replacereg := false;
-  readStateChanged := false;
-  if canreplacereg(orgsupreg,newsupreg,p,orgregcanbemodified,newregmodified, orgregread, removelast,endp) then
-    begin
-{$ifdef replaceregdebug}
-      l := random(1000);
-      hp := tai_comment.Create(strpnew(
-        'replacing '+std_regname(newreg(R_INTREGISTER,newsupreg,R_SUBWHOLE))+' with '+std_regname(newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE))+
-        ' from here... '+tostr(l)));
-      insertllitem(asml,p.previous,p,hp);
-      hp := tai_comment.Create(strpnew(
-        'replaced '+std_regname(newreg(R_INTREGISTER,newsupreg,R_SUBWHOLE))+' with '+std_regname(newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE))+
-        ' till here ' + tostr(l)));
-      insertllitem(asml,endp,endp.next,hp);
-{$endif replaceregdebug}
-      replaceReg := true;
-      returnEndP := endP;
-
-      if not getNextInstruction(p,hp) then
-        exit;
-      stateChanged := false;
-      while hp <> endP do
-        begin
-          if {not(ptaiprop(hp.optinfo)^.canBeRemoved) and }
-             (hp.typ = ait_instruction) then
-            stateChanged :=
-              doReplaceReg(taicpu(hp),newsupreg,orgsupreg) or stateChanged;
-            if stateChanged then
-              updateStates(orgsupreg,newsupreg,hp,true);
-          getNextInstruction(hp,hp)
-        end;
-      if assigned(endp) and (endp.typ = ait_instruction) then
-        readStateChanged :=
-          doReplaceReadReg(taicpu(endP),newsupreg,orgsupreg);
-      if stateChanged or readStateChanged then
-        updateStates(orgsupreg,newsupreg,endP,stateChanged);
-
-      if stateChanged or readStateChanged then
-        updateState(orgsupreg,endP);
-
-{ We replaced newreg with oldreg between p and endp, so restore the contents }
-{ of newreg there with its contents from before the sequence.                }
-      if removeLast or
-         RegLoadedWithNewValue(newsupreg,true,endP) then
-        GetLastInstruction(endP,hp)
-      else hp := endP;
-      RestoreRegContentsTo(asml,newsupreg,c,seqstart,hp);
-
-{ Ot is possible that the new register was modified (e.g. an add/sub), so if  }
-{ it was replaced by oldreg in that instruction, oldreg's contents have been  }
-{ changed. To take this into account, we simply set the contents of orgsupreg }
-{ to "unknown" after this sequence                                            }
-      if newRegModified then
-        ClearRegContentsFrom(asml,orgsupreg,p,hp);
-      if removeLast then
-        ptaiprop(endp.optinfo)^.canBeRemoved := true;
-      allocRegBetween(asml,newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE),p,endP,ptaiprop(p.optinfo)^.usedregs);
-
-    end
-{$ifdef replaceregdebug}
-     else
-       begin
-         l := random(1000);
-         hp := tai_comment.Create(strpnew(
-           'replacing '+std_regname(newreg(R_INTREGISTER,newsupreg,R_SUBWHOLE))+' with '+std_regname(newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE))+
-           ' from here... '+ tostr(l)));
-         insertllitem(asml,p.previous,p,hp);
-        hp := tai_comment.Create(strpnew(
-          'replacing '+std_regname(newreg(R_INTREGISTER,newsupreg,R_SUBWHOLE))+' with '+std_regname(newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE))+
-          ' failed here ' + tostr(l)));
-        insertllitem(asml,endp,endp.next,hp);
-      end;
-{$endif replaceregdebug}
-end;
-
-
-function FindRegWithConst(p: tai; size: topsize; l: aint; var Res: TRegister): Boolean;
-{Finds a register which contains the constant l}
-var
-  Counter: tsuperregister;
-{$ifdef testing}
-    hp: tai;
-{$endif testing}
-begin
-  Result:=false;
-  Counter := RS_EAX;
-  repeat
-{$ifdef testing}
-     if (ptaiprop(p.optinfo)^.regs[counter].typ in [con_const,con_noRemoveConst]) then
-       begin
-         hp := tai_comment.Create(strpnew(
-           'checking const load of '+tostr(l)+' here...'));
-         hp.next := ptaiprop(p.optinfo)^.Regs[Counter].StartMod;
-         hp.previous := ptaiprop(p.optinfo)^.Regs[Counter].StartMod^.previous;
-         ptaiprop(p.optinfo)^.Regs[Counter].StartMod^.previous := hp;
-         if assigned(hp.previous) then
-           hp.previous.next := hp;
-       end;
-{$endif testing}
-     if (ptaiprop(p.optinfo)^.regs[counter].typ in [con_const,con_noRemoveConst]) and
-        (taicpu(ptaiprop(p.optinfo)^.Regs[Counter].StartMod).opsize = size) and
-        (taicpu(ptaiprop(p.optinfo)^.Regs[Counter].StartMod).oper[0]^.typ = top_const) and
-        (taicpu(ptaiprop(p.optinfo)^.Regs[Counter].StartMod).oper[0]^.val = l) then
-       begin
-         res:=taicpu(ptaiprop(p.optinfo)^.Regs[Counter].StartMod).oper[1]^.reg;
-         result:=true;
-         exit;
-       end;
-     inc(counter);
-  until (Counter > RS_EDI);
-end;
-
-
-procedure removePrevNotUsedLoad(asml: TAsmList; p: tai; supreg: tsuperregister; check: boolean);
-{ if check = true, it means the procedure has to check whether it isn't  }
-{ possible that the contents are still used after p (used when removing  }
-{ instructions because of a "call"), otherwise this is not necessary     }
-{ (e.g. when you have a "mov 8(%ebp),%eax", you can be sure the previous }
-{ value of %eax isn't used anymore later on)                             }
-var
-  hp1, next, beforestartmod: tai;
-begin
-  if getLastInstruction(p,hp1) then
-    with ptaiprop(hp1.optinfo)^.regs[supreg] do
-      if (typ in [con_ref,con_invalid,con_const]) and
-         (nrofMods = 1) and
-         (rState = ptaiprop(startmod.optinfo)^.regs[supreg].rState) and
-         (not(check) or
-          (not(regInInstruction(supreg,p)) and
-           (not(supreg in ptaiprop(hp1.optinfo)^.usedRegs) or
-            findRegDealloc(supreg,p)))) then
-        begin
-          ptaiprop(startMod.optinfo)^.canBeRemoved := true;
-          getnextinstruction(p,next);
-          { give the register that was modified by this instruction again }
-          { the contents it had before this instruction                   }
-          if getlastinstruction(startmod,beforestartmod) then
-            RestoreRegContentsTo(asml,supreg,ptaiprop(beforestartmod.optinfo)^.regs[supreg],
-             startmod,hp1)
-          else
-            ClearRegContentsFrom(asml,supreg,startmod,hp1);
-        end;
-end;
-
-
-{$ifdef notused}
-function is_mov_for_div(p: taicpu): boolean;
-begin
-  is_mov_for_div :=
-    (p.opcode = A_MOV) and
-    (p.oper[0]^.typ = top_const) and
-    (p.oper[1]^.typ = top_reg) and
-    (p.oper[1]^.reg = RS_EDX) and
-    getNextInstruction(p,p) and
-    (p.typ = ait_instruction) and
-    ((p.opcode = A_DIV) or
-     (p.opcode = A_IDIV));
-end;
-{$endif notused}
-
-
-function memtoreg(t: taicpu; const ref: treference; var startp: tai): tregister;
-var
-  hp: tai;
-  p: ptaiprop;
-  regcounter: tsuperregister;
-  optimizable: boolean;
-begin
-  memtoreg := NR_NO;
-
-  if not getlastinstruction(t,hp) or
-     not issimplememloc(ref) then
-    exit;
-
-  p := ptaiprop(hp.optinfo);
-  optimizable := false;
-  for regcounter := RS_EAX to RS_EDI do
-    begin
-      if (assigned(p^.regs[regcounter].memwrite) and
-         refsequal(ref,p^.regs[regcounter].memwrite.oper[1]^.ref^)) then
-        begin
-          optimizable := true;
-          hp := p^.regs[regcounter].memwrite;
-        end
-      else if ((p^.regs[regcounter].typ in [CON_REF,CON_NOREMOVEREF]) and
-             (p^.regs[regcounter].nrofmods = 1) and
-             ((taicpu(p^.regs[regcounter].startmod).opcode = A_MOV) or
-              (taicpu(p^.regs[regcounter].startmod).opcode = A_MOVZX) or
-              (taicpu(p^.regs[regcounter].startmod).opcode = A_MOVSX)) and
-             (taicpu(p^.regs[regcounter].startmod).oper[0]^.typ = top_ref) and
-             refsequal(ref,taicpu(p^.regs[regcounter].startmod).oper[0]^.ref^)) then
-        begin
-          optimizable := true;
-          hp := p^.regs[regcounter].startmod;
-        end;
-      if optimizable then
-        if ((t.opsize <> S_B) or
-            not(regcounter in [RS_ESI,RS_EDI])) and
-            sizescompatible(taicpu(hp).opsize,t.opsize) then
-          begin
-            case t.opsize of
-              S_B:
-                begin
-                  memtoreg := newreg(R_INTREGISTER,regcounter,R_SUBL)
-                end;
-              S_W,S_BW:
-                begin
-                  memtoreg := newreg(R_INTREGISTER,regcounter,R_SUBW);
-                  if (t.opsize = S_BW) then
-                      begin
-                        t.opcode := A_MOV;
-                        t.opsize := S_W;
-                      end;
-                end;
-              S_L,S_BL,S_WL:
-                begin
-                  memtoreg := newreg(R_INTREGISTER,regcounter,R_SUBWHOLE);
-                  if (t.opsize <> S_L) then
-                    begin
-                      t.opcode := A_MOV;
-                      t.opsize := S_L;
-                    end;
-                end;
-            end;
-            startp := hp;
-            exit;
-          end;
-    end;
-  memtoreg := NR_NO;
-end;
-
-
-procedure removeLocalStores(const t1: tai);
-{var
-  p: tai;
-  regcount: tregister; }
-begin
-{
-  for regcount := LoGPReg to HiGPReg do
-    if assigned(pTaiProp(t1.optinfo)^.regs[regcount].memwrite) and
-       (taicpu(pTaiProp(t1.optinfo)^.regs[regcount].memwrite).oper[1]^.ref^.base
-         = current_procinfo.framepointer) then
-      begin
-        pTaiProp(pTaiProp(t1.optinfo)^.regs[regcount].memwrite.optinfo)^.canberemoved := true;
-        clearmemwrites(pTaiProp(t1.optinfo)^.regs[regcount].memwrite,regcount);
-      end;
-}
-end;
-
-
-procedure loadcseregs(asml: TAsmList; const reginfo: toptreginfo; curseqend, prevseqstart, curseqstart, curprev: tai; cnt: longint);
-var
-  regsloaded: tregset;
-  regloads, reguses: array[RS_EAX..RS_EDI] of tai;
-  regcounter: tsuperregister;
-  hp, hp2: tai;
-  insertpos, insertoptinfo, prevseq_next: tai;
-  i: longint;
-  opc: tasmop;
-begin
-  regsloaded := [];
-  fillchar(regloads,sizeof(regloads),0);
-  fillchar(reguses,sizeof(reguses),0);
-  getnextinstruction(prevseqstart,prevseq_next);
-  for regcounter := RS_EAX To RS_EDI do
-    if (reginfo.new2oldreg[regcounter] <> RS_INVALID) Then
-      begin
-        include(regsloaded,regcounter);
-        if assigned(ptaiprop(prevseqstart.optinfo)^.Regs[reginfo.new2oldreg[regcounter]].StartMod) then
-          AllocRegBetween(asml,newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBWHOLE),
-            ptaiprop(prevseqstart.optinfo)^.Regs[reginfo.new2oldreg[regcounter]].StartMod,curseqstart,
-            ptaiprop(ptaiprop(prevseqstart.optinfo)^.Regs[reginfo.new2oldreg[regcounter]].StartMod.optinfo)^.usedregs)
-        else
-          AllocRegBetween(asml,newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBWHOLE),
-            prevseqstart,curseqstart,ptaiprop(prevseqstart.optinfo)^.usedregs);
-
-        if curprev <> prevseqstart then
-          begin
-            if assigned(reginfo.lastReload[regCounter]) then
-              getLastInstruction(reginfo.lastReload[regCounter],hp)
-            else if assigned(reginfo.lastReload[reginfo.new2oldreg[regCounter]]) then
-              getLastInstruction(reginfo.lastReload[reginfo.new2OldReg[regCounter]],hp)
-            else
-              hp := curprev;
-            clearRegContentsFrom(asml,regCounter,prevSeq_next,hp);
-            getnextInstruction(hp,hp);
-            allocRegBetween(asml,newreg(R_INTREGISTER,regCounter,R_SUBWHOLE),prevseqstart,hp,
-              ptaiprop(prevseqstart.optinfo)^.usedregs);
-          end;
-        if not(regcounter in reginfo.RegsLoadedforRef) and
-                      {old reg                new reg}
-            (reginfo.new2oldreg[regcounter] <> regcounter) then
-          begin
-            getLastInstruction(curseqend,hp);
-            opc := A_MOV;
-            insertpos := prevseq_next;
-            insertoptinfo := prevseqstart;
-            if assigned(reguses[regcounter]) then
-              if assigned(regloads[reginfo.new2oldreg[regcounter]]) then
-                opc := A_XCHG
-              else
-                begin
-                  insertoptinfo := reguses[regcounter];
-                  insertpos := tai(insertoptinfo.next)
-                end
-            else
-              if assigned(regloads[reginfo.new2oldreg[regcounter]]) then
-                 begin
-                   insertpos := regloads[reginfo.new2oldreg[regcounter]];
-                   if not getlastinstruction(insertpos,insertoptinfo) then
-                     internalerror(2006060701);
-                 end;
-            hp := Tai_Marker.Create(mark_NoPropInfoStart);
-            InsertLLItem(asml, insertpos.previous,insertpos, hp);
-            hp2 := taicpu.Op_Reg_Reg(opc, S_L,
-                                            {old reg                                        new reg}
-                     newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBWHOLE), newreg(R_INTREGISTER,regcounter,R_SUBWHOLE));
-            if (opc = A_XCHG) and
-               (taicpu(regloads[reginfo.new2oldreg[regcounter]]).opcode <> A_XCHG) then
-              begin
-                asml.remove(regloads[reginfo.new2oldreg[regcounter]]);
-                regloads[reginfo.new2oldreg[regcounter]].free;
-                regloads[reginfo.new2oldreg[regcounter]] := hp2;
-                reguses[regcounter] := hp2;
-              end;
-            regloads[regcounter] := hp2;
-            reguses[reginfo.new2oldreg[regcounter]] := hp2;
-            new(ptaiprop(hp2.optinfo));
-            ptaiprop(hp2.optinfo)^ := ptaiprop(insertoptinfo.optinfo)^;
-            ptaiprop(hp2.optinfo)^.canBeRemoved := false;
-            InsertLLItem(asml, insertpos.previous, insertpos, hp2);
-            hp := Tai_Marker.Create(mark_NoPropInfoEnd);
-            InsertLLItem(asml, insertpos.previous, insertpos, hp);
-            { adjusts states in previous instruction so that it will  }
-            { definitely be different from the previous or next state }
-            incstate(ptaiprop(hp2.optinfo)^.
-              regs[reginfo.new2oldreg[regcounter]].rstate,20);
-            incstate(ptaiprop(hp2.optinfo)^.
-              regs[regCounter].wstate,20);
-            updateState(reginfo.new2oldreg[regcounter],hp2);
-            updateState(regcounter,hp2);
-          end
-        else
-  {   imagine the following code:                                            }
-  {        normal                    wrong optimized                         }
-  {    movl 8(%ebp), %eax           movl 8(%ebp), %eax                       }
-  {    movl (%eax), %eax            movl (%eax), %eax                        }
-  {    cmpl 8(%ebp), %eax           cmpl 8(%ebp), %eax                       }
-  {    jne l1                       jne l1                                   }
-  {    movl 8(%ebp), %eax                                                    }
-  {    movl (%eax), %edi            movl %eax, %edi                          }
-  {    movl %edi, -4(%ebp)          movl %edi, -4(%ebp)                      }
-  {    movl 8(%ebp), %eax                                                    }
-  {    pushl 70(%eax)               pushl 70(%eax)                           }
-  {                                                                          }
-  {   The error is that at the moment that the last instruction is executed, }
-  {   %eax doesn't contain 8(%ebp) anymore. Solution: the contents of        }
-  {   registers that are completely removed from a sequence (= registers in  }
-  {   RegLoadedforRef), have to be changed to their contents from before the }
-  {   sequence.                                                              }
-        { if regcounter in reginfo.RegsLoadedforRef then }
-          begin
-            hp := curseqstart;
-            { cnt still holds the number of instructions }
-            { of the sequence, so go to the end of it    }
-            for i := 1 to pred(cnt) do
-              getNextInstruction(hp,hp);
-            { curprev = instruction prior to start of sequence }
-            restoreRegContentsTo(asml,regCounter,
-              ptaiprop(curprev.optinfo)^.Regs[regcounter],
-              curseqstart,hp);
-          end;
-      end;
-end;
-
-
-procedure replaceoperandwithreg(asml: TAsmList; p: tai; opnr: byte; reg: tregister);
-var
-  hp: tai;
-begin
-  { new instruction -> it's info block is not in the big one allocated at the start }
-  hp := Tai_Marker.Create(mark_NoPropInfoStart);
-  InsertLLItem(asml, p.previous,p, hp);
-  { duplicate the original instruction and replace it's designated operant with the register }
-  hp := tai(p.getcopy);
-  taicpu(hp).loadreg(opnr,reg);
-  { add optimizer state info }
-  new(ptaiprop(hp.optinfo));
-  ptaiprop(hp.optinfo)^ := ptaiprop(p.optinfo)^;
-  { new instruction can not be removed }
-  ptaiprop(hp.optinfo)^.canBeRemoved := false;
-  { but the old one can }
-  ptaiprop(p.optinfo)^.canBeRemoved := true;
-  { insert end marker }
-  InsertLLItem(asml, p.previous, p, hp);
-  hp := Tai_Marker.Create(mark_NoPropInfoEnd);
-  InsertLLItem(asml, p.previous, p, hp);
-end;
-
-
-procedure doCSE(asml: TAsmList; First, Last: tai; findPrevSeqs, doSubOpts: boolean);
-{marks the instructions that can be removed by RemoveInstructs. They're not
- removed immediately because sometimes an instruction needs to be checked in
- two different sequences}
-var cnt, cnt2, {cnt3,} orgNrofMods: longint;
-    p, hp1, hp2, hp4, hp5, prevSeq: tai;
-    reginfo: toptreginfo;
-    memreg: tregister;
-    regcounter: tsuperregister;
-begin
-  p := First;
-  SkipHead(p);
-  hp1 := nil;
-  hp2 := nil;
-  hp4 := nil;
-  hp5 := nil;
-  cnt := 0;
-  while (p <> Last) do
-    begin
-      case p.typ of
-        ait_align:
-          if not(tai_align(p).use_op) then
-            SetAlignReg(p);
-        ait_instruction:
-          begin
-            case taicpu(p).opcode of
-{
-     Does not work anymore with register calling because the registers are
-     released before the call
-              A_CALL:
-                for regCounter := RS_EAX to RS_EBX do
-                  removePrevNotUsedLoad(asml,p,regCounter,true);
-}
-              A_CLD: if GetLastInstruction(p, hp1) and
-                        (ptaiprop(hp1.optinfo)^.DirFlag = F_NotSet) then
-                       ptaiprop(tai(p).optinfo)^.CanBeRemoved := True;
-              A_LEA, A_MOV, A_MOVZX, A_MOVSX:
-                begin
-                  hp2 := p;
-                  case taicpu(p).oper[0]^.typ of
-                    top_ref, top_reg:
-                     if (taicpu(p).oper[1]^.typ = top_reg) then
-                       begin
-                        With ptaiprop(p.optinfo)^.Regs[getsupreg(taicpu(p).oper[1]^.reg)] do
-                          begin
-                            if (startmod = p) then
-                              orgNrofMods := nrofMods
-                            else
-                              orgNrofMods := 0;
-                            if (p = StartMod) and
-                               GetLastInstruction (p, hp1) and
-                               not(hp1.typ in [ait_marker,ait_label]) then
-{so we don't try to check a sequence when p is the first instruction of the block}
-                              begin
-{$ifdef csdebug}
-                               hp5 := tai_comment.Create(strpnew(
-                                 'cse checking '+std_regname(taicpu(p).oper[1]^.reg)));
-                               insertLLItem(asml,p,p.next,hp5);
-{$endif csdebug}
-                               if CheckSequence(p,prevSeq,getsupreg(taicpu(p).oper[1]^.reg), Cnt, reginfo, findPrevSeqs) and
-                                  (Cnt > 0) then
-                                 begin
-(*
-                                   hp1 := nil;
-{ although it's perfectly ok to remove an instruction which doesn't contain }
-{ the register that we've just checked (CheckSequence takes care of that),  }
-{ the sequence containing this other register should also be completely     }
-{ checked and removed, otherwise we may get situations like this:           }
-{                                                                           }
-{   movl 12(%ebp), %edx                       movl 12(%ebp), %edx           }
-{   movl 16(%ebp), %eax                       movl 16(%ebp), %eax           }
-{   movl 8(%edx), %edx                        movl 8(%edx), %edx            }
-{   movl (%eax), eax                          movl (%eax), eax              }
-{   cmpl %eax, %edx                           cmpl %eax, %edx               }
-{   jnz  l123           getting converted to  jnz  l123                     }
-{   movl 12(%ebp), %edx                       movl 4(%eax), eax             }
-{   movl 16(%ebp), %eax                                                     }
-{   movl 8(%edx), %edx                                                      }
-{   movl 4(%eax), eax                                                       }
-*)
-
-{ not anymore: if the start of a new sequence is found while checking (e.g. }
-{ above that of eax while checking edx, this new sequence is automatically  }
-{ also checked                                                              }
-                                   Cnt2 := 1;
-                                   while Cnt2 <= Cnt do
-                                     begin
-{$ifndef noremove}
-                                         ptaiprop(p.optinfo)^.CanBeRemoved := True
-{$endif noremove}
-                                       ; inc(Cnt2);
-                                       GetNextInstruction(p, p);
-                                     end;
- {hp4 is used to get the contents of the registers before the sequence}
-                                   GetLastInstruction(hp2, hp4);
-
-{$IfDef CSDebug}
-                                   for regcounter := RS_EAX To RS_EDI do
-                                     if (regcounter in reginfo.RegsLoadedforRef) then
-                                       begin
-                                         hp5 := tai_comment.Create(strpnew('New: '+std_regname(newreg(R_INTREGISTER,regcounter,R_SUBNONE))+', Old: '+
-                                           std_regname(newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBNONE))));
-                                         InsertLLItem(asml, tai(hp2.previous), hp2, hp5);
-                                       end;
-{$EndIf CSDebug}
- { if some registers were different in the old and the new sequence, move }
- { the contents of those old registers to the new ones                    }
-                                   loadcseregs(asml,reginfo,p,prevseq,hp2,hp4,cnt);
-                                   continue;
-                                 end
-                              end;
-                          end;
-                      { try to replace the new reg with the old reg }
-                      if not(ptaiprop(p.optinfo)^.canBeRemoved) then
-                        if (taicpu(p).oper[0]^.typ = top_reg) and
-                           (taicpu(p).oper[1]^.typ = top_reg) and
-                           { only remove if we're not storing something in a regvar }
-                           (getsupreg(taicpu(p).oper[1]^.reg) in [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESI,RS_EDI]) and
-{                           (taicpu(p).oper[1]^.reg in (rg.usableregsint+[RS_EDI])) and}
-                           (taicpu(p).opcode = A_MOV) and
-                           getLastInstruction(p,hp4) and
-                          { we only have to start replacing from the instruction after the mov, }
-                          { but replacereg only starts with getnextinstruction(p,p)             }
-                            replaceReg(asml,getsupreg(taicpu(p).oper[0]^.reg),
-                              getsupreg(taicpu(p).oper[1]^.reg),p,p,
-                              ptaiprop(hp4.optinfo)^.regs[getsupreg(taicpu(p).oper[1]^.reg)],false,hp1) then
-                          begin
-                            ptaiprop(p.optinfo)^.canBeRemoved := true;
-                            { this is just a regular move that was here, so the source register should be }
-                            { allocated already at this point -> only allocate from here onwards          }
-                            if not(getsupreg(taicpu(p).oper[0]^.reg) in pTaiProp(p.optinfo)^.usedregs) then
-                              internalerror(2004101011);
-                            allocRegBetween(asml,taicpu(p).oper[0]^.reg,
-                              p,hp1,pTaiProp(p.optinfo)^.usedregs)
-                          end
-                        else
-                          begin
-                             if (taicpu(p).oper[1]^.typ = top_reg) and
-                                not regInOp(getsupreg(taicpu(p).oper[1]^.reg),taicpu(p).oper[0]^) then
-                               removePrevNotUsedLoad(asml,p,getsupreg(taicpu(p).oper[1]^.reg),false);
-                             if doSubOpts and
-                                (taicpu(p).opcode <> A_LEA) and
-                                (taicpu(p).oper[0]^.typ = top_ref) then
-                              begin
-                                memreg :=
-                                  memtoreg(taicpu(p),
-                                  taicpu(p).oper[0]^.ref^,hp5);
-                                if memreg <> NR_NO then
-                                  if (taicpu(p).opcode = A_MOV) and
-                                     (taicpu(p).oper[1]^.typ = top_reg) and
-                                     (taicpu(p).oper[1]^.reg = memreg) then
-                                    begin
-                                      pTaiProp(p.optinfo)^.canberemoved := true;
-                                      allocregbetween(asml,memreg,hp5,p,ptaiprop(hp5.optinfo)^.usedregs);
-                                    end
-                                  else
-                                    begin
-                                      replaceoperandwithreg(asml,p,0,memreg);
-                                      allocregbetween(asml,memreg,hp5,p,ptaiprop(hp5.optinfo)^.usedregs);
-                                      regcounter := getsupreg(memreg);
-                                      incstate(pTaiProp(p.optinfo)^.regs[regcounter].rstate,1);
-                                      updatestate(regcounter,p);
-                                    end;
-                              end;
-                          end;
-                        { at first, only try optimizations of large blocks, because doing }
-                        { doing smaller ones may prevent bigger ones from completing in   }
-                        { in the next pass                                                }
-                        if not doSubOpts and (orgNrofMods <> 0) then
-                          begin
-                            p := hp2;
-                            for cnt := 1 to pred(orgNrofMods) do
-                              getNextInstruction(p,p);
-                          end;
-                      end;
-                    top_Const:
-                      begin
-                        case taicpu(p).oper[1]^.typ of
-                          Top_Reg:
-                            begin
-                              regCounter := getsupreg(taicpu(p).oper[1]^.reg);
-                              if GetLastInstruction(p, hp1) then
-                                With ptaiprop(hp1.optinfo)^.Regs[regCounter] do
-                                  if (typ in [con_const,con_noRemoveConst]) and
-                                     (taicpu(startMod).opsize >= taicpu(p).opsize) and
-                                     opsequal(taicpu(StartMod).oper[0]^,taicpu(p).oper[0]^) then
-                                    begin
-                                      ptaiprop(p.optinfo)^.CanBeRemoved := True;
-                                      allocRegBetween(asml,taicpu(p).oper[1]^.reg,startmod,p,
-                                        ptaiprop(startmod.optinfo)^.usedregs);
-                                    end
-                                  else
-                                    removePrevNotUsedLoad(asml,p,getsupreg(taicpu(p).oper[1]^.reg),false);
-
-                            end;
-                          Top_Ref:
-                            if (taicpu(p).oper[0]^.typ = top_const) and
-                               getLastInstruction(p,hp1) and
-                               findRegWithConst(hp1,taicpu(p).opsize,taicpu(p).oper[0]^.val,memreg) then
-                              begin
-                                taicpu(p).loadreg(0,memreg);
-                                { mark the used register as read }
-                                incstate(ptaiprop(p.optinfo)^.
-                                   regs[getsupreg(memreg)].rstate,20);
-                                updateState(getsupreg(memreg),p);
-                                allocRegBetween(asml,memreg,
-                                  ptaiprop(hp1.optinfo)^.regs[getsupreg(memreg)].startMod,p,
-                                  ptaiprop(ptaiprop(hp1.optinfo)^.regs[getsupreg(memreg)].startMod.optinfo)^.usedregs);
-                              end;
-                        end;
-                      end;
-                  end;
-
-                end;
-              A_LEAVE:
-                begin
-                  if getlastinstruction(p,hp1) then
-                    removeLocalStores(hp1);
-                end;
-              A_STD: if GetLastInstruction(p, hp1) and
-                        (ptaiprop(hp1.optinfo)^.DirFlag = F_Set) then
-                        ptaiprop(tai(p).optinfo)^.CanBeRemoved := True;
-              else
-                begin
-                  for cnt := 1 to maxinschanges do
-                    begin
-                      case InsProp[taicpu(p).opcode].Ch[cnt] of
-                        Ch_ROp1:
-                          if (taicpu(p).oper[0]^.typ = top_ref) and
-                             ((taicpu(p).opcode < A_F2XM1) or
-                              ((taicpu(p).opcode > A_IN) and
-                               (taicpu(p).opcode < A_OUT)) or
-                              (taicpu(p).opcode = A_PUSH) or
-                              ((taicpu(p).opcode >= A_RCL) and
-                               (taicpu(p).opcode <= A_XOR))) then
-                            begin
-                              memreg :=
-                                memtoreg(taicpu(p),
-                                taicpu(p).oper[0]^.ref^,hp5);
-                              if memreg <> NR_NO then
-                                begin
-                                  replaceoperandwithreg(asml,p,0,memreg);
-                                  allocregbetween(asml,memreg,hp5,p,ptaiprop(hp5.optinfo)^.usedregs);
-                                  regcounter := getsupreg(memreg);
-                                  incstate(pTaiProp(p.optinfo)^.regs[regcounter].rstate,1);
-                                  updatestate(regcounter,p);
-                                end;
-                            end;
-                        Ch_MOp1:
-                          if not(cs_opt_size in current_settings.optimizerswitches) and
-                             (taicpu(p).oper[0]^.typ = top_ref) then
-                            begin
-                              memreg :=
-                                memtoreg(taicpu(p),
-                                taicpu(p).oper[0]^.ref^,hp5);
-                              if (memreg <> NR_NO) and
-                                 (not getNextInstruction(p,hp1) or
-                                  (RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
-                                   FindRegDealloc(getsupreg(memreg),hp1))) then
-                                begin
-                                  hp1 := Tai_Marker.Create(mark_NoPropInfoEnd);
-                                  insertllitem(asml,p,p.next,hp1);
-                                  hp1 := taicpu.op_reg_ref(A_MOV,reg2opsize(memreg),
-                                     memreg,taicpu(p).oper[0]^.ref^);
-                                  new(ptaiprop(hp1.optinfo));
-                                  pTaiProp(hp1.optinfo)^ := pTaiProp(p.optinfo)^;
-                                  insertllitem(asml,p,p.next,hp1);
-                                  regcounter := getsupreg(memreg);
-                                  incstate(pTaiProp(hp1.optinfo)^.regs[regcounter].rstate,1);
-                                  updatestate(regcounter,hp1);
-                                  hp1 := Tai_Marker.Create(mark_NoPropInfoStart);
-                                  insertllitem(asml,p,p.next,hp1);
-                                  replaceoperandwithreg(asml,p,0,memreg);
-                                  allocregbetween(asml,memreg,hp5,
-                                    tai(p.next.next),ptaiprop(hp5.optinfo)^.usedregs);
-                                  ClearRegContentsFrom(asml,regcounter,hp5,p);
-                                end;
-                            end;
-                        Ch_ROp2:
-                          if ((taicpu(p).opcode = A_CMP) or
-                              (taicpu(p).opcode = A_TEST)) and
-                             (taicpu(p).oper[1]^.typ = top_ref) then
-                            begin
-                              memreg :=
-                                memtoreg(taicpu(p),
-                                taicpu(p).oper[1]^.ref^,hp5);
-                              if memreg <> NR_NO then
-                                begin
-                                  replaceoperandwithreg(asml,p,1,memreg);
-                                  allocregbetween(asml,memreg,hp5,p,ptaiprop(hp5.optinfo)^.usedregs);
-                                  regcounter := getsupreg(memreg);
-                                  incstate(pTaiProp(p.optinfo)^.regs[regcounter].rstate,1);
-                                  updatestate(regcounter,p);
-                                end;
-                            end;
-                        Ch_MOp2:
-                          if not(cs_opt_size in current_settings.optimizerswitches) and
-                             (taicpu(p).oper[1]^.typ = top_ref) and
-                             ((taicpu(p).opcode < A_BT) or
-                              ((taicpu(p).opcode > A_IN) and
-                               (taicpu(p).opcode < A_OUT)) or
-                              (taicpu(p).opcode = A_PUSH) or
-                              ((taicpu(p).opcode >= A_RCL) and
-                               (taicpu(p).opcode <= A_XOR))) then
-                            begin
-                              memreg :=
-                                memtoreg(taicpu(p),
-                                taicpu(p).oper[1]^.ref^,hp5);
-                              if (memreg <> NR_NO) and
-                                 (not getNextInstruction(p,hp1) or
-                                  (RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
-                                   FindRegDealloc(getsupreg(memreg),hp1))) then
-                                begin
-                                  hp1 := Tai_Marker.Create(mark_NoPropInfoEnd);
-                                  insertllitem(asml,p,p.next,hp1);
-                                  hp1 := taicpu.op_reg_ref(A_MOV,reg2opsize(memreg),
-                                    memreg,taicpu(p).oper[1]^.ref^);
-                                  new(ptaiprop(hp1.optinfo));
-                                  pTaiProp(hp1.optinfo)^ := pTaiProp(p.optinfo)^;
-                                  insertllitem(asml,p,p.next,hp1);
-                                  regcounter := getsupreg(memreg);
-                                  incstate(pTaiProp(hp1.optinfo)^.regs[regcounter].rstate,1);
-                                  updatestate(regcounter,hp1);
-                                  hp1 := Tai_Marker.Create(mark_NoPropInfoStart);
-                                  insertllitem(asml,p,p.next,hp1);
-                                  replaceoperandwithreg(asml,p,1,memreg);
-                                  allocregbetween(asml,memreg,hp5,
-                                    tai(p.next.next),ptaiprop(hp5.optinfo)^.usedregs);
-                                  ClearRegContentsFrom(asml,regcounter,hp5,p);
-                                end;
-                            end;
-                      end;
-                    end;
-                end;
-            end
-          end;
-      end;
-      GetNextInstruction(p, p);
-    end;
-end;
-
-function removeInstructs(asml: TAsmList; first, last: tai): boolean;
-{ Removes the marked instructions and disposes the PTaiProps of the other }
-{ instructions                                                            }
-var
-  p, hp1: tai;
-  nopropinfolevel: longint;
-begin
-  removeInstructs := false;
-  p := First;
-  nopropinfolevel := 0;
-  while (p <> Last) do
-    begin
-      if (p.typ = ait_marker) and
-         (Tai_marker(p).kind = mark_NoPropInfoStart) then
-        begin
-          hp1 := tai(p.next);
-          asml.remove(p);
-          p.free;
-          nopropinfolevel := 1;
-          while (nopropinfolevel <> 0) do
-            begin
-              p := tai(hp1.next);
-{$ifndef noinstremove}
-              { allocregbetween can insert new ait_regalloc objects }
-              { without optinfo                                     }
-              if (hp1.typ = ait_marker) then
-                begin
-                  case Tai_marker(hp1).kind of
-                    { they can be nested! }
-                    mark_NoPropInfoStart: inc(nopropinfolevel);
-                    mark_NoPropInfoEnd: dec(nopropinfolevel);
-                    else
-                      begin
-                        hp1 := p;
-                        continue;
-                      end;
-                  end;
-                  asml.remove(hp1);
-                  hp1.free;
-                end
-              else if assigned(hp1.optinfo) then
-                if ptaiprop(hp1.optinfo)^.canBeRemoved then
-                  begin
-                    dispose(ptaiprop(hp1.optinfo));
-                    hp1.optinfo := nil;
-                    asml.remove(hp1);
-                    hp1.free;
-                  end
-                else
-{$endif noinstremove}
-                  begin
-                    dispose(ptaiprop(hp1.optinfo));
-                    hp1.optinfo := nil;
-                  end;
-              hp1 := p;
-            end;
-        end
-      else
-{$ifndef noinstremove}
-        if assigned(p.optinfo) and
-              ptaiprop(p.optinfo)^.canBeRemoved then
-          begin
-            hp1 := tai(p.next);
-            asml.Remove(p);
-            p.free;
-            p := hp1;
-            removeInstructs := true;
-          end
-        else
-{$endif noinstremove}
-          begin
-            p.optinfo := nil;
-            p := tai(p.next);
-          end;
-    end;
-end;
-
-function CSE(asml: TAsmList; First, Last: tai; pass: longint): boolean;
-begin
-  doCSE(asml, First, Last, not(cs_opt_level3 in current_settings.optimizerswitches) or (pass >= 2),
-        not(cs_opt_level3 in current_settings.optimizerswitches) or (pass >= 1));
- { register renaming }
-  if not(cs_opt_level3 in current_settings.optimizerswitches) or (pass > 0) then
-    doRenaming(asml, first, last);
-  cse := removeInstructs(asml, first, last);
-end;
-
-end.

+ 2 - 2
compiler/i386/popt386.pas

@@ -58,7 +58,7 @@ begin
           (taicpu(hp1).oper[0]^.reg <> reg))) and
           (taicpu(hp1).oper[0]^.reg <> reg))) and
         (taicpu(hp1).oper[1]^.typ = top_reg) and
         (taicpu(hp1).oper[1]^.typ = top_reg) and
         (taicpu(hp1).oper[1]^.reg = reg);
         (taicpu(hp1).oper[1]^.reg = reg);
-    A_INC,A_DEC:
+    A_INC,A_DEC,A_NEG,A_NOT:
       isFoldableArithOp :=
       isFoldableArithOp :=
         (taicpu(hp1).oper[0]^.typ = top_reg) and
         (taicpu(hp1).oper[0]^.typ = top_reg) and
         (taicpu(hp1).oper[0]^.reg = reg);
         (taicpu(hp1).oper[0]^.reg = reg);
@@ -2282,7 +2282,7 @@ begin
   { to       add/sub/or/... reg2/$const, (ref)    }
   { to       add/sub/or/... reg2/$const, (ref)    }
                         begin
                         begin
                           case taicpu(hp1).opcode of
                           case taicpu(hp1).opcode of
-                            A_INC,A_DEC:
+                            A_INC,A_DEC,A_NOT,A_NEG:
                               taicpu(hp1).loadRef(0,taicpu(p).oper[0]^.ref^);
                               taicpu(hp1).loadRef(0,taicpu(p).oper[0]^.ref^);
                             A_LEA:
                             A_LEA:
                               begin
                               begin

+ 0 - 372
compiler/i386/rropt386.pas

@@ -1,372 +0,0 @@
-{
-    Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
-      development team
-
-    This unit contains register renaming functionality
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit rropt386;
-
-{$i fpcdefs.inc}
-
-interface
-
-uses aasmbase,aasmtai,aasmdata,aasmcpu;
-
-procedure doRenaming(asml: TAsmList; first, last: tai);
-
-implementation
-
-uses
-  {$ifdef replaceregdebug}cutils,{$endif}
-  verbose,globals,cpubase,daopt386,csopt386,rgobj,
-  cgbase,cgutils,cgobj;
-
-function canBeFirstSwitch(p: taicpu; supreg: tsuperregister): boolean;
-{ checks whether an operation on reg can be switched to another reg without an }
-{ additional mov, e.g. "addl $4,%reg1" can be changed to "leal 4(%reg1),%reg2" }
-begin
-  canBeFirstSwitch := false;
-  case p.opcode of
-    A_MOV,A_MOVZX,A_MOVSX,A_LEA:
-      canBeFirstSwitch :=
-        (p.oper[1]^.typ = top_reg) and
-        (getsupreg(p.oper[1]^.reg) = supreg);
-    A_IMUL:
-      canBeFirstSwitch :=
-        (p.ops >= 2) and
-        (p.oper[0]^.typ = top_const) and
-        (getsupreg(p.oper[p.ops-1]^.reg) = supreg) and
-        (not pTaiprop(p.optinfo)^.FlagsUsed);
-    A_INC,A_DEC:
-      canBeFirstSwitch :=
-        (p.oper[0]^.typ = top_reg) and
-        (p.opsize = S_L) and
-        (not pTaiprop(p.optinfo)^.FlagsUsed);
-    A_SUB,A_ADD:
-      canBeFirstSwitch :=
-        (p.oper[1]^.typ = top_reg) and
-        (p.opsize = S_L) and
-        (getsupreg(p.oper[1]^.reg) = supreg) and
-        (p.oper[0]^.typ <> top_ref) and
-        ((p.opcode <> A_SUB) or
-         (p.oper[0]^.typ = top_const)) and
-        (not pTaiprop(p.optinfo)^.FlagsUsed);
-    A_SHL:
-      canBeFirstSwitch :=
-        (p.opsize = S_L) and
-        (p.oper[1]^.typ = top_reg) and
-        (getsupreg(p.oper[1]^.reg) = supreg) and
-        (p.oper[0]^.typ = top_const) and
-        (p.oper[0]^.val in [1,2,3]) and
-        (not pTaiprop(p.optinfo)^.FlagsUsed);
-  end;
-end;
-
-
-procedure switchReg(var reg: tregister; reg1, reg2: tsuperregister);
-var
-  supreg: tsuperregister;
-begin
-  if (reg = NR_NO) or
-     (getregtype(reg) <> R_INTREGISTER) then
-    exit;
-  supreg := getsupreg(reg);
-  if (supreg = reg1) then
-    setsupreg(reg,reg2)
-  else if (supreg = reg2) then
-    setsupreg(reg,reg1);
-end;
-
-
-procedure switchOp(var op: toper; reg1, reg2: tsuperregister);
-begin
-  case op.typ of
-    top_reg:
-      switchReg(op.reg,reg1,reg2);
-    top_ref:
-      begin
-        switchReg(op.ref^.base,reg1,reg2);
-        switchReg(op.ref^.index,reg1,reg2);
-      end;
-  end;
-end;
-
-
-procedure doSwitchReg(hp: taicpu; reg1,reg2: tsuperregister);
-var
-  opCount: longint;
-begin
-  for opCount := 0 to hp.ops-1 do
-    switchOp(hp.oper[opCount]^,reg1,reg2);
-end;
-
-
-procedure doFirstSwitch(p: taicpu; reg1, reg2: tsuperregister);
-var
-  tmpRef: treference;
-begin
-  case p.opcode of
-    A_MOV,A_MOVZX,A_MOVSX,A_LEA:
-       begin
-         changeOp(p.oper[1]^,reg1,reg2);
-         changeOp(p.oper[0]^,reg2,reg1);
-       end;
-    A_IMUL:
-      begin
-        p.ops := 3;
-        p.loadreg(2,newreg(R_INTREGISTER,reg2,R_SUBWHOLE));
-        changeOp(p.oper[1]^,reg2,reg1);
-      end;
-    A_INC,A_DEC:
-      begin
-        reference_reset(tmpref,1);
-        tmpref.base := newreg(R_INTREGISTER,reg1,R_SUBWHOLE);
-        case p.opcode of
-          A_INC:
-            tmpref.offset := 1;
-          A_DEC:
-            tmpref.offset := -1;
-        end;
-        p.ops := 2;
-        p.opcode := A_LEA;
-        p.loadreg(1,newreg(R_INTREGISTER,reg2,R_SUBWHOLE));
-        p.loadref(0,tmpref);
-      end;
-    A_SUB,A_ADD:
-      begin
-        reference_reset(tmpref,1);
-        tmpref.base := newreg(R_INTREGISTER,reg1,R_SUBWHOLE);
-        case p.oper[0]^.typ of
-          top_const:
-            begin
-              tmpref.offset := longint(p.oper[0]^.val);
-              if p.opcode = A_SUB then
-                tmpref.offset := - tmpRef.offset;
-            end;
-          top_ref:
-            if (p.oper[0]^.ref^.refaddr=addr_full) then
-              tmpref.symbol := p.oper[0]^.ref^.symbol
-            else
-              internalerror(200402263);
-          top_reg:
-            begin
-              { "addl %reg2,%reg1" must become "leal (%reg1,%reg1),%reg2" }
-              { since at this point reg1 holds the value that reg2 would  }
-              { otherwise contain                                         }
-              tmpref.index := p.oper[0]^.reg;
-              if (getsupreg(tmpref.index)=reg2) then
-                setsupreg(tmpref.index,reg1);
-              tmpref.scalefactor := 1;
-            end;
-          else internalerror(200010031);
-        end;
-        p.opcode := A_LEA;
-        p.loadref(0,tmpref);
-        p.loadreg(1,newreg(R_INTREGISTER,reg2,R_SUBWHOLE));
-      end;
-    A_SHL:
-      begin
-        reference_reset(tmpref,2);
-        tmpref.index := newreg(R_INTREGISTER,reg1,R_SUBWHOLE);
-        tmpref.scalefactor := 1 shl p.oper[0]^.val;
-        p.opcode := A_LEA;
-        p.loadref(0,tmpref);
-        p.loadreg(1,newreg(R_INTREGISTER,reg2,R_SUBWHOLE));
-      end;
-    else internalerror(200010032);
-  end;
-end;
-
-
-function switchRegs(asml: TAsmList; reg1, reg2: tsuperregister; start: tai): Boolean;
-{ change movl  %reg1,%reg2 ... bla ... to ... bla with reg1 and reg2 switched }
-var
-  endP, hp, lastreg1,lastreg2: tai;
-  switchDone, switchLast, tmpResult, sequenceEnd, reg1Modified, reg2Modified: boolean;
-  reg1StillUsed, reg2StillUsed, isInstruction: boolean;
-begin
-  switchRegs := false;
-  tmpResult := true;
-  sequenceEnd := false;
-  reg1Modified := false;
-  reg2Modified := false;
-  switchLast := false;
-  endP := start;
-  while tmpResult and not sequenceEnd do
-    begin
-      tmpResult :=
-        getNextInstruction(endP,endP);
-      If tmpResult and
-         not pTaiprop(endp.optinfo)^.canBeRemoved then
-        begin
-          { if the newReg gets stored back to the oldReg, we can change }
-          { "mov %oldReg,%newReg; <operations on %newReg>; mov %newReg, }
-          { %oldReg" to "<operations on %oldReg>"                       }
-          switchLast := storeBack(start,endP,reg1,reg2);
-          reg1StillUsed := reg1 in pTaiprop(endp.optinfo)^.usedregs;
-          reg2StillUsed := reg2 in pTaiprop(endp.optinfo)^.usedregs;
-          isInstruction := endp.typ = ait_instruction;
-          sequenceEnd :=
-            switchLast or
-            { if both registers are released right before an instruction }
-            { that contains hardcoded regs, it's ok too                  }
-            (not reg1StillUsed and not reg2StillUsed) or
-            { no support for (i)div, mul and imul with hardcoded operands }
-            (((not isInstruction) or
-              noHardCodedRegs(taicpu(endP),reg1,reg2)) and
-             (not reg1StillUsed or
-              (isInstruction and findRegDealloc(reg1,endP) and
-               regLoadedWithNewValue(reg1,false,taicpu(endP)))) and
-             (not reg2StillUsed or
-              (isInstruction and findRegDealloc(reg2,endP) and
-               regLoadedWithNewValue(reg2,false,taicpu(endP)))));
-
-          { we can't switch reg1 and reg2 in something like }
-          {   movl  %reg1,%reg2                             }
-          {   movl  (%reg2),%reg2                           }
-          {   movl  4(%reg1),%reg1                          }
-          if reg2Modified and not(reg1Modified) and
-             regReadByInstruction(reg1,endP) then
-            begin
-              tmpResult := false;
-              break
-            end;
-
-          if not reg1Modified then
-            begin
-              reg1Modified := regModifiedByInstruction(reg1,endP);
-              if reg1Modified and not canBeFirstSwitch(taicpu(endP),reg1) then
-                begin
-                  tmpResult := false;
-                  break;
-                end;
-            end;
-          if not reg2Modified then
-            reg2Modified := regModifiedByInstruction(reg2,endP);
-
-          tmpResult :=
-            ((not isInstruction) or
-             (NoHardCodedRegs(taicpu(endP),reg1,reg2) and
-              RegSizesOk(reg1,reg2,taicpu(endP))));
-
-          if sequenceEnd then
-            break;
-
-          tmpResult :=
-            tmpresult and
-            (endp.typ <> ait_label) and
-            ((not isInstruction) or
-             (not taicpu(endp).is_jmp));
-        end;
-    end;
-
-  if tmpResult and sequenceEnd then
-    begin
-      switchRegs := true;
-      reg1Modified := false;
-      reg2Modified := false;
-      lastreg1 := start;
-      lastreg2 := start;
-      getNextInstruction(start,hp);
-      while hp <> endP do
-        begin
-          if (not pTaiprop(hp.optinfo)^.canberemoved) and
-             (hp.typ = ait_instruction) then
-            begin
-              switchDone := false;
-              if not reg1Modified then
-                begin
-                  reg1Modified := regModifiedByInstruction(reg1,hp);
-                  if reg1Modified then
-                    begin
-                      doFirstSwitch(taicpu(hp),reg1,reg2);
-                      switchDone := true;
-                    end;
-                end;
-              if not switchDone then
-                if reg1Modified then
-                  doSwitchReg(taicpu(hp),reg1,reg2)
-                else
-                  doReplaceReg(taicpu(hp),reg2,reg1);
-            end;
-          if regininstruction(reg1,hp) then
-             lastreg1 := hp;
-          if regininstruction(reg2,hp) then
-             lastreg2 := hp;
-          getNextInstruction(hp,hp);
-        end;
-      if switchLast then
-        begin
-          lastreg1 := hp;
-          lastreg2 := hp;
-          { this is in case of a storeback, make sure the same size of register }
-          { contents as the initial move is transfered                          }
-          doSwitchReg(taicpu(hp),reg1,reg2);
-          if taicpu(hp).opsize <> taicpu(start).opsize then
-            begin
-              taicpu(hp).opsize := taicpu(start).opsize;
-              taicpu(hp).oper[0]^.reg := taicpu(start).oper[0]^.reg;
-              taicpu(hp).oper[1]^.reg := taicpu(start).oper[1]^.reg;
-            end;
-        end
-      else
-        getLastInstruction(hp,hp);
-      allocRegBetween(asmL,newreg(R_INTREGISTER,reg1,R_SUBWHOLE),start,lastreg1,
-        ptaiprop(start.optinfo)^.usedregs);
-      allocRegBetween(asmL,newreg(R_INTREGISTER,reg2,R_SUBWHOLE),start,lastreg2,
-        ptaiprop(start.optinfo)^.usedregs);
-    end;
-end;
-
-
-procedure doRenaming(asml: TAsmList; first, last: tai);
-var
-  p: tai;
-begin
-  p := First;
-  SkipHead(p);
-  while p <> last do
-    begin
-      case p.typ of
-        ait_instruction:
-          begin
-            case taicpu(p).opcode of
-              A_MOV:
-                begin
-                  if not(pTaiprop(p.optinfo)^.canBeRemoved) and
-                     (taicpu(p).oper[0]^.typ = top_reg) and
-                     (taicpu(p).oper[1]^.typ = top_reg) and
-                     (taicpu(p).opsize = S_L) and
-                     (getsupreg(taicpu(p).oper[0]^.reg) in ([RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESI,RS_EDI])) and
-                     (getsupreg(taicpu(p).oper[1]^.reg) in ([RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESI,RS_EDI])) then
-                    if switchRegs(asml,getsupreg(taicpu(p).oper[0]^.reg),
-                         getsupreg(taicpu(p).oper[1]^.reg),p) then
-                      begin
-                        pTaiprop(p.optinfo)^.canBeRemoved := true;
-                      end;
-                end;
-            end;
-          end;
-      end;
-      getNextInstruction(p,p);
-    end;
-end;
-
-
-End.

+ 5 - 2
compiler/i386/symcpu.pas

@@ -124,6 +124,10 @@ type
   end;
   end;
   tcpuunitsymclass = class of tcpuunitsym;
   tcpuunitsymclass = class of tcpuunitsym;
 
 
+  tcpuprogramparasym = class(tprogramparasym)
+  end;
+  tcpuprogramparasymclass = class(tprogramparasym);
+
   tcpunamespacesym = class(tnamespacesym)
   tcpunamespacesym = class(tnamespacesym)
   end;
   end;
   tcpunamespacesymclass = class of tcpunamespacesym;
   tcpunamespacesymclass = class of tcpunamespacesym;
@@ -250,6 +254,7 @@ begin
   { used tsym classes }
   { used tsym classes }
   clabelsym:=tcpulabelsym;
   clabelsym:=tcpulabelsym;
   cunitsym:=tcpuunitsym;
   cunitsym:=tcpuunitsym;
+  cprogramparasym:=tcpuprogramparasym;
   cnamespacesym:=tcpunamespacesym;
   cnamespacesym:=tcpunamespacesym;
   cprocsym:=tcpuprocsym;
   cprocsym:=tcpuprocsym;
   ctypesym:=tcputypesym;
   ctypesym:=tcputypesym;
@@ -262,7 +267,5 @@ begin
   cconstsym:=tcpuconstsym;
   cconstsym:=tcpuconstsym;
   cenumsym:=tcpuenumsym;
   cenumsym:=tcpuenumsym;
   csyssym:=tcpusyssym;
   csyssym:=tcpusyssym;
-
-  cPtrDefHashSet:=tx86PtrDefHashSet;
 end.
 end.
 
 

+ 1 - 1
compiler/i8086/cpuinfo.pas

@@ -139,7 +139,7 @@ Const
                                  { no need to write info about those }
                                  { no need to write info about those }
                                  [cs_opt_level1,cs_opt_level2,cs_opt_level3]+
                                  [cs_opt_level1,cs_opt_level2,cs_opt_level3]+
                                  [cs_opt_peephole,cs_opt_regvar,cs_opt_stackframe,
                                  [cs_opt_peephole,cs_opt_regvar,cs_opt_stackframe,
-                                  cs_opt_asmcse,cs_opt_loopunroll,cs_opt_uncertain,
+                                  cs_opt_loopunroll,cs_opt_uncertain,
                                   cs_opt_tailrecursion,cs_opt_nodecse,cs_useebp,
                                   cs_opt_tailrecursion,cs_opt_nodecse,cs_useebp,
 				  cs_opt_reorder_fields,cs_opt_fastmath];
 				  cs_opt_reorder_fields,cs_opt_fastmath];
 
 

+ 5 - 4
compiler/i8086/cpupara.pas

@@ -236,7 +236,7 @@ unit cpupara;
         psym:=tparavarsym(pd.paras[nr-1]);
         psym:=tparavarsym(pd.paras[nr-1]);
         pdef:=psym.vardef;
         pdef:=psym.vardef;
         if push_addr_param(psym.varspez,pdef,pd.proccalloption) then
         if push_addr_param(psym.varspez,pdef,pd.proccalloption) then
-          pdef:=getpointerdef(pdef);
+          pdef:=cpointerdef.getreusable(pdef);
         cgpara.reset;
         cgpara.reset;
         cgpara.size:=def_cgsize(pdef);
         cgpara.size:=def_cgsize(pdef);
         cgpara.intsize:=tcgsize2size[cgpara.size];
         cgpara.intsize:=tcgsize2size[cgpara.size];
@@ -442,7 +442,7 @@ unit cpupara;
               begin
               begin
                 paralen:=voidpointertype.size;
                 paralen:=voidpointertype.size;
                 paracgsize:=int_cgsize(voidpointertype.size);
                 paracgsize:=int_cgsize(voidpointertype.size);
-                paradef:=getpointerdef(paradef);
+                paradef:=cpointerdef.getreusable(paradef);
               end
               end
             else
             else
               begin
               begin
@@ -602,7 +602,7 @@ unit cpupara;
                       begin
                       begin
                         paralen:=voidpointertype.size;
                         paralen:=voidpointertype.size;
                         paracgsize:=int_cgsize(voidpointertype.size);
                         paracgsize:=int_cgsize(voidpointertype.size);
-                        paradef:=getpointerdef(paradef);
+                        paradef:=cpointerdef.getreusable(paradef);
                       end
                       end
                     else
                     else
                       begin
                       begin
@@ -629,7 +629,8 @@ unit cpupara;
                     if (parareg<=high(parasupregs)) and
                     if (parareg<=high(parasupregs)) and
                        (paralen<=sizeof(aint)) and
                        (paralen<=sizeof(aint)) and
                        (not(hp.vardef.typ in [floatdef,recorddef,arraydef]) or
                        (not(hp.vardef.typ in [floatdef,recorddef,arraydef]) or
-                        pushaddr) and
+                        pushaddr or
+                        is_dynamic_array(hp.vardef)) and
                        (not(vo_is_parentfp in hp.varoptions) or
                        (not(vo_is_parentfp in hp.varoptions) or
                         not(po_delphi_nested_cc in p.procoptions)) then
                         not(po_delphi_nested_cc in p.procoptions)) then
                       begin
                       begin

+ 31 - 1
compiler/i8086/cpupi.pas

@@ -32,10 +32,14 @@ unit cpupi;
 
 
     type
     type
        ti8086procinfo = class(tcgprocinfo)
        ti8086procinfo = class(tcgprocinfo)
+       private
+         procedure insert_8087_fwaits(list : TAsmList);
+       public
          constructor create(aparent:tprocinfo);override;
          constructor create(aparent:tprocinfo);override;
          procedure set_first_temp_offset;override;
          procedure set_first_temp_offset;override;
          function calc_stackframe_size:longint;override;
          function calc_stackframe_size:longint;override;
          procedure generate_parameter_info;override;
          procedure generate_parameter_info;override;
+         procedure postprocess_code;override;
        end;
        end;
 
 
 
 
@@ -44,8 +48,9 @@ unit cpupi;
     uses
     uses
       cutils,
       cutils,
       systems,globals,globtype,
       systems,globals,globtype,
+      aasmtai,aasmcpu,
       cgobj,tgobj,paramgr,
       cgobj,tgobj,paramgr,
-      cpubase,
+      cpubase,cpuinfo,
       cgutils,
       cgutils,
       symconst;
       symconst;
 
 
@@ -95,6 +100,31 @@ unit cpupi;
           para_stack_size := 0;
           para_stack_size := 0;
       end;
       end;
 
 
+
+    procedure ti8086procinfo.insert_8087_fwaits(list : TAsmList);
+      var
+        curtai: tai;
+      begin
+        curtai:=tai(list.First);
+        while assigned(curtai) do
+          begin
+            if (curtai.typ=ait_instruction)
+               and requires_fwait_on_8087(taicpu(curtai).opcode) then
+              list.InsertBefore(taicpu.op_none(A_FWAIT),curtai);
+
+            curtai:=tai(curtai.Next);
+          end;
+      end;
+
+
+    procedure ti8086procinfo.postprocess_code;
+      begin
+        { nickysn note: I don't know if the 187 requires FWAIT before
+          every instruction like the 8087, so I'm including it just in case }
+        if current_settings.cputype<=cpu_186 then
+          insert_8087_fwaits(aktproccode);
+      end;
+
 begin
 begin
    cprocinfo:=ti8086procinfo;
    cprocinfo:=ti8086procinfo;
 end.
 end.

+ 2 - 1
compiler/i8086/hlcgcpu.pas

@@ -353,7 +353,8 @@ implementation
       cg.a_loadaddr_ref_reg(list, tmpref, r);
       cg.a_loadaddr_ref_reg(list, tmpref, r);
 
 
       { step 2: if destination is a far pointer, we have to pass a segment as well }
       { step 2: if destination is a far pointer, we have to pass a segment as well }
-      if is_farpointer(tosize) or is_hugepointer(tosize) or is_farprocvar(tosize) then
+      if is_farpointer(tosize) or is_hugepointer(tosize) or is_farprocvar(tosize) or
+         ((tosize.typ=classrefdef) and (tosize.size=4)) then
         begin
         begin
           { if a segment register is specified in ref, we use that }
           { if a segment register is specified in ref, we use that }
           if ref.segment<>NR_NO then
           if ref.segment<>NR_NO then

+ 1 - 1
compiler/i8086/i8086nop.inc

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

+ 14 - 0
compiler/i8086/i8086tab.inc

@@ -5950,6 +5950,13 @@
     code    : #208#1#15#11#128#52;
     code    : #208#1#15#11#128#52;
     flags   : if_386 or if_pass2
     flags   : if_386 or if_pass2
   ),
   ),
+  (
+    opcode  : A_Jcc;
+    ops     : 1;
+    optypes : (ot_immediate or ot_bits16,ot_none,ot_none,ot_none);
+    code    : #19#112#1#3#1#233#48;
+    flags   : if_8086 or if_pass2 or if_16bitonly
+  ),
   (
   (
     opcode  : A_Jcc;
     opcode  : A_Jcc;
     ops     : 1;
     ops     : 1;
@@ -5964,6 +5971,13 @@
     code    : #208#1#15#11#128#52;
     code    : #208#1#15#11#128#52;
     flags   : if_386 or if_pass2
     flags   : if_386 or if_pass2
   ),
   ),
+  (
+    opcode  : A_Jcc;
+    ops     : 1;
+    optypes : (ot_immediate or ot_bits16 or ot_near,ot_none,ot_none,ot_none);
+    code    : #19#112#1#3#1#233#48;
+    flags   : if_8086 or if_pass2 or if_16bitonly
+  ),
   (
   (
     opcode  : A_SETcc;
     opcode  : A_SETcc;
     ops     : 1;
     ops     : 1;

+ 1 - 1
compiler/i8086/n8086mem.pas

@@ -199,7 +199,7 @@ implementation
             result:=ccallnode.createintern(procname,
             result:=ccallnode.createintern(procname,
               ccallparanode.create(right,
               ccallparanode.create(right,
               ccallparanode.create(ttypeconvnode(left).left,nil)));
               ccallparanode.create(ttypeconvnode(left).left,nil)));
-            inserttypeconv_internal(result,getx86pointerdef(arraydef.elementdef,x86pt_huge));
+            inserttypeconv_internal(result,tx86pointerdef(cpointerdef).getreusablex86(arraydef.elementdef,x86pt_huge));
             result:=cderefnode.create(result);
             result:=cderefnode.create(result);
 
 
             ttypeconvnode(left).left:=nil;
             ttypeconvnode(left).left:=nil;

+ 24 - 2
compiler/i8086/symcpu.pas

@@ -57,6 +57,7 @@ type
 
 
   tcpupointerdef = class(tx86pointerdef)
   tcpupointerdef = class(tx86pointerdef)
     class function default_x86_data_pointer_type: tx86pointertyp; override;
     class function default_x86_data_pointer_type: tx86pointertyp; override;
+    function alignment:shortint;override;
     function pointer_arithmetic_int_type:tdef; override;
     function pointer_arithmetic_int_type:tdef; override;
     function pointer_subtraction_result_type:tdef; override;
     function pointer_subtraction_result_type:tdef; override;
   end;
   end;
@@ -75,6 +76,7 @@ type
   tcpuobjectdefclass = class of tcpuobjectdef;
   tcpuobjectdefclass = class of tcpuobjectdef;
 
 
   tcpuclassrefdef = class(tclassrefdef)
   tcpuclassrefdef = class(tclassrefdef)
+    function alignment:shortint;override;
   end;
   end;
   tcpuclassrefdefclass = class of tcpuclassrefdef;
   tcpuclassrefdefclass = class of tcpuclassrefdef;
 
 
@@ -151,6 +153,10 @@ type
   end;
   end;
   tcpuunitsymclass = class of tcpuunitsym;
   tcpuunitsymclass = class of tcpuunitsym;
 
 
+  tcpuprogramparasym = class(tprogramparasym)
+  end;
+  tcpuprogramparasymclass = class(tprogramparasym);
+
   tcpunamespacesym = class(tnamespacesym)
   tcpunamespacesym = class(tnamespacesym)
   end;
   end;
   tcpunamespacesymclass = class of tcpunamespacesym;
   tcpunamespacesymclass = class of tcpunamespacesym;
@@ -254,6 +260,15 @@ implementation
       result:=(p.typ=pointerdef) and (tcpupointerdef(p).x86pointertyp=x86pt_huge);
       result:=(p.typ=pointerdef) and (tcpupointerdef(p).x86pointertyp=x86pt_huge);
     end;
     end;
 
 
+{****************************************************************************
+                               tcpuclassrefdef
+****************************************************************************}
+
+  function tcpuclassrefdef.alignment:shortint;
+    begin
+      Result:=2;
+    end;
+
 {****************************************************************************
 {****************************************************************************
                                tcpuarraydef
                                tcpuarraydef
 ****************************************************************************}
 ****************************************************************************}
@@ -408,6 +423,14 @@ implementation
       end;
       end;
 
 
 
 
+    function tcpupointerdef.alignment:shortint;
+      begin
+        { on i8086, we use 16-bit alignment for all pointer types, even far and
+          huge (which are 4 bytes long) }
+        result:=2;
+      end;
+
+
     function tcpupointerdef.pointer_arithmetic_int_type:tdef;
     function tcpupointerdef.pointer_arithmetic_int_type:tdef;
       begin
       begin
         if x86pointertyp=x86pt_huge then
         if x86pointertyp=x86pt_huge then
@@ -474,6 +497,7 @@ begin
   { used tsym classes }
   { used tsym classes }
   clabelsym:=tcpulabelsym;
   clabelsym:=tcpulabelsym;
   cunitsym:=tcpuunitsym;
   cunitsym:=tcpuunitsym;
+  cprogramparasym:=tcpuprogramparasym;
   cnamespacesym:=tcpunamespacesym;
   cnamespacesym:=tcpunamespacesym;
   cprocsym:=tcpuprocsym;
   cprocsym:=tcpuprocsym;
   ctypesym:=tcputypesym;
   ctypesym:=tcputypesym;
@@ -486,7 +510,5 @@ begin
   cconstsym:=tcpuconstsym;
   cconstsym:=tcpuconstsym;
   cenumsym:=tcpuenumsym;
   cenumsym:=tcpuenumsym;
   csyssym:=tcpusyssym;
   csyssym:=tcpusyssym;
-
-  cPtrDefHashSet:=tx86PtrDefHashSet;
 end.
 end.
 
 

+ 0 - 287
compiler/ia64/aasmcpu.pas

@@ -1,287 +0,0 @@
-{
-    Copyright (c) 2000-2006 by Florian Klaempfl
-
-    Contains the assembler object for the ia64
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit aasmcpu;
-
-{$i fpcdefs.inc}
-
-interface
-
-uses
-  globals,verbose,
-  aasmbase,aasmtai,
-  cpubase,
-  cgutils;
-
-
-type
-  pairegalloc = ^tairegalloc;
-  tairegalloc = class(tai)
-     allocation : boolean;
-     reg        : tregister;
-     constructor alloc(r : tregister);
-     constructor dealloc(r : tregister);
-  end;
-
-  { Types of operand }
-  toptype=(top_none,top_reg,top_ref,top_const,top_symbol,top_qp);
-
-  paicpu = ^taicpu;
-  taicpu = class(tai)
-     is_jmp    : boolean; { is this instruction a jump? (needed for optimizer) }
-     opcode    : tasmop;
-     ops       : array[0..4] of longint;
-     oper      : longint;
-     qp        : tqp;
-     ldsttype  : tldsttype;
-     hint      : thint;
-     { ALU instructions }
-     { A1,A9: integer ALU }
-     constructor op_reg_reg_reg(op : tasmop;const r1,r2,r3 : tregister);
-     { A2,A10: shift left and add }
-     constructor op_reg_reg_const_reg(_qp : tqp;op : tasmop;
-       const r1,r2 : tregister;i : byte;const r3 : tregister);
-     { A3,A4,A5: integer ALU - imm.,register }
-     constructor op_reg_const_reg(_qp : tqp;op : tasmop;
-       const r1 : tregister;i : longint;const r3 : tregister);
-     { A6,A7: integer compare - register,register }
-     constructor op_preg_preg_reg_reg(_qp : tqp;op : tasmop;
-       cond : tasmcond;p1,p2 : tqp;const r2,r3 : tregister);
-     { A8: integer compare - imm.,register }
-     constructor op_preg_preg_const_reg(_qp : tqp;op : tasmop;
-       cond : tasmcond;p1,p2 : tqp;i : longint;const r3 : tregister);
-(*!!!!!!!
-     { multimedia shift and multiply }
-     constructor op_reg_reg_reg_const(_qp : tqp;
-     { multimedia mux }
-     constructor op_reg_reg_mbtype(_qp : tqp;
-     { multimedia shift fixed }
-     constructor op_reg_reg_const(_qp : tqp;
-     { div. }
-     constructor op_reg_reg(_qp : tqp;
-     { mm extract }
-     constructor op_reg_reg_const_const(_qp : tqp;
-     { zero and deposit imm }
-     constructor op_reg_const_const_const(_qp : tqp;
-     { deposit imm }
-     constructor op_reg_const_reg_const_const(_qp : tqp;
-     { deposit }
-     constructor op_reg_reg_reg_const_const(_qp : tqp;
-     { test bit }
-     { !!!! here we need also to take care of the postfix }
-     constructor op_preg_preg_reg_const(_qp : tqp;
-     { test NaT }
-     { !!!! here we need also to take care of the postfix }
-     constructor op_preg_preg_reg(_qp : tqp;
-
-     { -------- here are some missed ----------- }
- *)
-
-     { M1: integer load }
-     { M4: integer store }
-     { M6: floating-point load }
-     { M9: floating-point store }
-     constructor op_reg_ref(_qp : tqp;op : tasmop;postfix : tldsttype;
-       _hint : thint;const r1 : tregister;ref : treference);
-
-     { M2: integer load incremented by register }
-     { M7: floating-point load incremented by register }
-     constructor op_reg_ref_reg(_qp : tqp;op : tasmop;postfix : tldsttype;
-       _hint : thint;const r1 : tregister;const ref : treference;
-       const r2 : tregister);
-
-     { M3: integer load increment by imm. }
-     { M5: integer store increment by imm. }
-     { M8: floating-point load increment by imm. }
-     { M10: floating-point store increment by imm. }
-     constructor op_reg_ref_const(_qp : tqp;op : tasmop;postfix : tldsttype;
-       _hint : thint;const r1 : tregister;ref : treference;i : longint);
-
-     { M11: floating-point load pair}
-     constructor op_reg_ref(_qp : tqp;op : tasmop;postfix : tldsttype;
-       _hint : thint;const r1,r2 : tregister;ref : treference);
-
-     { M12: floating-point load pair increment by imm. }
-     constructor op_reg_ref(_qp : tqp;op : tasmop;postfix : tldsttype;
-       _hint : thint;const r1,r2 : tregister;ref : treference;i : longint);
-
-     { X1: break/nop }
-     constructor op_const62(_qp : tqp;op : tasmop;i : int64);
-     { X2: move imm64 }
-     constructor op_reg_const64(_qp : tqp;op : tasmop;const r1 : tregister;
-       i : int64);
-  end;
-
-  { the following objects are special for the ia64 }
-  { they decribe a stop and the bundles            }
-  paistop = ^taistop;
-  taistop = class(tai)
-    constructor init;
-  end;
-
-  { a second underscro indicates a stop }
-  tbundletemplate = (but_none,but_mii,but_mii_,
-    but_mi_i,but_mi_i_,but_mlx,but_mlx_,
-    but_mmi,but_mmi_,but_m_mi,but_m_mi_,
-    but_mfi,but_mfi_,but_mmf,but_mmf_,
-    but_mif,but_mib_,but_mbb,but_mbb_,
-    but_bbb,but_bbb_,but_mmb,but_mmb_,
-    but_mfb,but_mfb_);
-
-  paibundle = ^taibundle;
-  taibundle = class(tai)
-     template : tbundletemplate;
-     instructions : array[0..1] of paicpu;
-  end;
-
-implementation
-
-
-{*****************************************************************************
-                                 TaiStop
-*****************************************************************************}
-
-    constructor taistop.init;
-
-      begin
-         inherited create;
-         typ:=ait_stop;
-      end;
-
-
-{*****************************************************************************
-                                 TaiRegAlloc
-*****************************************************************************}
-
-    constructor tairegalloc.alloc(r : tregister);
-      begin
-        inherited create;
-        typ:=ait_regalloc;
-        allocation:=true;
-        reg:=r;
-      end;
-
-
-    constructor tairegalloc.dealloc(r : tregister);
-      begin
-        inherited create;
-        typ:=ait_regalloc;
-        allocation:=false;
-        reg:=r;
-      end;
-
-
-{*****************************************************************************
-                                 Taicpu
-*****************************************************************************}
-
-    { ALU instructions }
-    { A1,A9: integer ALU }
-    constructor taicpu.op_reg_reg_reg(op : tasmop;const r1,r2,r3 : tregister);
-
-      begin
-      end;
-
-    { A2,A10: shift left and add }
-    constructor taicpu.op_reg_reg_const_reg(_qp : tqp;op : tasmop;
-      const r1,r2 : tregister;i : byte;const r3 : tregister);
-
-      begin
-      end;
-
-    { A3,A4,A5: integer ALU - imm.,register }
-    constructor taicpu.op_reg_const_reg(_qp : tqp;op : tasmop;
-      const r1 : tregister;i : longint;const r3 : tregister);
-
-      begin
-      end;
-
-    { A6,A7: integer compare - register,register }
-    constructor taicpu.op_preg_preg_reg_reg(_qp : tqp;op : tasmop;
-      cond : tasmcond;p1,p2 : tqp;const r2,r3 : tregister);
-
-      begin
-      end;
-
-    { A8: integer compare - imm.,register }
-    constructor taicpu.op_preg_preg_const_reg(_qp : tqp;op : tasmop;
-      cond : tasmcond;p1,p2 : tqp;i : longint;const r3 : tregister);
-
-      begin
-      end;
-
-    { M1: integer load }
-    { M4: integer store }
-    { M6: floating-point load }
-    { M9: floating-point store }
-    constructor taicpu.op_reg_ref(_qp : tqp;op : tasmop;postfix : tldsttype;
-      _hint : thint;const r1 : tregister;ref : treference);
-
-      begin
-      end;
-
-    { M2: integer load incremented by register }
-    { M7: floating-point load incremented by register }
-    constructor taicpu.op_reg_ref_reg(_qp : tqp;op : tasmop;postfix : tldsttype;
-      _hint : thint;const r1 : tregister;const ref : treference;
-      const r2 : tregister);
-
-      begin
-      end;
-
-    { M3: integer load increment by imm. }
-    { M5: integer store increment by imm. }
-    { M8: floating-point load increment by imm. }
-    { M10: floating-point store increment by imm. }
-    constructor taicpu.op_reg_ref_const(_qp : tqp;op : tasmop;postfix : tldsttype;
-      _hint : thint;const r1 : tregister;ref : treference;i : longint);
-
-      begin
-      end;
-
-    { M11: floating-point load pair}
-    constructor taicpu.op_reg_ref(_qp : tqp;op : tasmop;postfix : tldsttype;
-      _hint : thint;const r1,r2 : tregister;ref : treference);
-
-      begin
-      end;
-
-    { M12: floating-point load pair increment by imm. }
-    constructor taicpu.op_reg_ref(_qp : tqp;op : tasmop;postfix : tldsttype;
-      _hint : thint;const r1,r2 : tregister;ref : treference;i : longint);
-
-      begin
-      end;
-
-    { X1: break/nop }
-    constructor taicpu.op_const62(_qp : tqp;op : tasmop;i : int64);
-    { X2: move imm64 }
-
-      begin
-      end;
-
-    constructor taicpu.op_reg_const64(_qp : tqp;op : tasmop;const r1 : tregister;
-      i : int64);
-
-      begin
-      end;
-
-end.

+ 0 - 150
compiler/ia64/cpubase.pas

@@ -1,150 +0,0 @@
-{
-    Copyright (C) 2000-2006 by Florian Klaempfl
-
-    this unit implements the base types for the iA-64 architecture
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit cpubase;
-
-  interface
-
-    uses
-       cutils,
-       globals,
-       systems,
-       cpuinfo,
-       cgbase;
-
-type
-  tasmop = (A_ADD,A_SUB,A_ADDP4,A_AND,A_ANDCM,A_OR,A_XOR,A_SHLADD,
-            A_SHLADDP4,A_ADDS,A_ADDL,A_CMP,A_CMP4,A_PADD1,A_PADD2,
-            A_PADD4,A_PSUB1,A_PSUB2,A_PSUB4,A_PAVG1,A_PAVG2,A_PAVGSUB1,
-            A_PAVGSUB2,A_PCMP1,A_PCMP2,A_PCMP4,A_PSHLADD2,A_PSHRADD2,
-            A_PMPY2,A_MIX1,A_MIX2,A_MIX4,A_PACK2,A_PACK4,A_UNPACK2,
-            A_UNPACK4,A_PMIN1,A_PMAX1,A_PMIN2,A_PMAX2,A_PSAD1,A_MUX1,
-            A_MUX2,A_PSHR2,A_PSHR4,A_SHR,A_PSHL2,A_SHL4,A_SHL,
-            A_POPCNT,A_SHRP,A_EXTR,A_DEP,A_TBIT,A_TNAT,A_BREAK,
-            A_NOP,A_CHK,A_MOV,A_ZX1,A_ZX2,A_ZXT4,A_SXT1,A_SXT2,A_SXT4,
-            A_CXZ1,A_CZX2,A_LD1,A_LD2,A_LD4,A_LD8,A_ST1,A_ST2,A_ST4,
-            A_ST8,A_LDFS,A_LDFD,A_LDF8,A_LDFE,A_LDF,A_STFS,A_STFD,A_STF8,
-            A_STFE,A_STF,A_LDFPS,A_LDFPD,A_LDFP8,A_LFETCH,A_CMPXCHG1,
-            A_CMPXCHG2,A_CMPXHG4,A_CMPXCHG8,A_XCHG1,A_XCHG2,A_XCHG4,
-            A_XCHG8,A_FETCHADD4,A_FETCHADD8,A_SETF,A_GETF,
-            A_INVALA,A_MF,A_SRLZ,A_SYNC,A_FLUSHRS,A_FC,A_ALLOC,A_SUM,
-            A_RUM,A_BR,A_CLRRRB,A_FMA,A_FPMA,A_FMS,A_FPMS,A_FNMA,A_FPNMA,
-            A_XMA,A_FSELECT,A_FCLASS,A_FRCPA,A_FPRCPA,A_FRSQRTA,
-            A_FPRSQRTA,A_FMIN,A_FMAX,A_FAMIN,A_FAMAX,A_FPMIN,A_FPMAX,
-            A_FPAMIN,A_FPAMAX,A_FPCMP,A_FMERGE,A_FMIX,A_FSXT,A_FPACK,
-            A_FSWAP,A_FAND,A_FANDCM,A_FOR,A_FXOR,A_FPMERGE,A_FCVT,
-            A_FPCVT,A_FSETC,A_FCLRT,A_FCHKF,A_MOVL);
-
-Const
-  firstop = low(tasmop);
-  lastop  = high(tasmop);
-
-type
-  TAsmCond = (C_NONE,C_LT,C_LTU,C_EQ,C_LT_UNC,C_LTU_UNC,C_EQ_UNC,
-              C_EQ_AND,C_EQ_OR,C_EQ_OR_ANDCM,C_NE_AND,C_NE_OR);
-
-  THint = (H_NONE,H_NT1,H_NT2,H_NTA);
-  TLdStType = (LST_NONE,LST_S,LST_A,LSR_SA,LST_BIAS,LST_ACQ,LST_C_CLR,
-               LST_FILL,LST_C_NC,LST_C_CLR_ACQ,LST_REL,
-               LST_SPILL);
-
-{*****************************************************************************
-                                   Flags
-*****************************************************************************}
-
-    type
-      TResFlags = (F_NONE,F_LT,F_LTU,F_EQ,F_LT_UNC,F_LTU_UNC,F_EQ_UNC,
-              F_EQ_AND,F_EQ_OR,F_EQ_OR_ANDCM,F_NE_AND,F_NE_OR);
-
-Type
- TRegister = (R_NO,  { R_NO is Mandatory, signifies no register }
-              R_0,R_1,R_2,R_3,R_4,R_5,R_6,R_7,R_8,R_9,
-              R_10,R_11,R_12,R_13,R_14,R_15,R_16,R_17,R_18,R_19,
-              R_20,R_21,R_22,R_23,R_24,R_25,R_26,R_27,R_28,R_29,
-              R_30,R_31,
-              R_F0,R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,
-              R_F10,R_F11,R_F12,R_F13,R_F14,R_F15,R_F16,R_F17,R_F18,R_F19,
-              R_F20,R_F21,R_F22,R_F23,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,
-              R_F30,R_F31);
-
-  TRegisterset = Set of TRegister;
-
-  { -1 indicates no qualifying prediction }
-  tqp = -1..63;
-
-const
-  qp_none : tqp = -1;
-
-{ Constants describing the registers }
-
-Const
-  intregs = [R_0..R_31];
-  fpuregs = [R_F0..R_F31];
-  mmregs = [];
-
-  maxvarregs = 128;
-  maxfpuvarregs = 128;
-
-  max_operands = 4;
-
-{*****************************************************************************
-                          Default generic sizes
-*****************************************************************************}
-
-      { Defines the default address size for a processor, }
-      OS_ADDR = OS_64;
-      { the natural int size for a processor,
-        has to match osuinttype/ossinttype as initialized in psystem }
-      OS_INT = OS_64;
-      OS_SINT = OS_S64;
-      { the maximum float size for a processor,           }
-      OS_FLOAT = OS_F80;
-      { the size of a vector register for a processor     }
-      OS_VECTOR = OS_M128;
-      
-{*****************************************************************************
-                       GCC /ABI linking information
-*****************************************************************************}
-
-  {# Registers which must be saved when calling a routine declared as
-     cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
-     saved should be the ones as defined in the target ABI and / or GCC.
-
-     This value can be deduced from CALLED_USED_REGISTERS array in the
-     GCC source.
-  }
-  std_saved_registers = [R_9..R_14,R_F2..R_F9];
-  {# Required parameter alignment when calling a routine declared as
-     stdcall and cdecl. The alignment value should be the one defined
-     by GCC or the target ABI.
-
-     The value of this constant is equal to the constant
-     PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
-  }
-  std_param_align = 8;
-
-{*****************************************************************************
-                   Opcode propeties (needed for optimizer)
-*****************************************************************************}
-
-implementation
-
-end.

+ 0 - 105
compiler/ia64/cpuinfo.pas

@@ -1,105 +0,0 @@
-{
-    Copyright (c) 1998-2006 by Florian Klaempfl
-
-    Basic Processor information
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-Unit cpuinfo;
-
-{$i fpcdefs.inc}
-
-Interface
-
-uses
-  globtype;
-
-Type
-   bestreal = extended;
-{$if FPC_FULLVERSION>20700}
-   bestrealrec = TExtended80Rec;
-{$endif FPC_FULLVERSION>20700}
-   ts32real = single;
-   ts64real = double;
-   ts80real = extended;
-   ts128real = type extended;
-   ts64comp = type extended;
-
-   pbestreal=^bestreal;
-
-   { possible supported processors for this target }
-   tcputype =
-      (cpu_none,
-       cpu_itanium
-      );
-
-   tfputype =
-     (fpu_none,
-      fpu_itanium
-     );
-     
-   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,
-     pocall_stdcall,
-     pocall_cdecl,
-     pocall_cppdecl
-   ];
-
-
-   cputypestr : array[tcputype] of string[10] = ('',
-     'ITANIUM'
-   );
-
-   fputypestr : array[tfputype] of string[6] = ('',
-     'ITANIUM'
-   );
-
-   { Supported optimizations, only used for information }
-   supported_optimizerswitches = [cs_opt_peephole,cs_opt_regvar,cs_opt_stackframe,
-								  cs_opt_asmcse,cs_opt_loopunroll,cs_opt_uncertain,
-								  cs_opt_nodecse];
-
-   level1optimizerswitches = [cs_opt_level1,cs_opt_peephole];
-   level2optimizerswitches = level1optimizerswitches + 
-     [cs_opt_level2,cs_opt_regvar,cs_opt_stackframe,cs_opt_asmcse,cs_opt_nodecse];
-   level3optimizerswitches = level2optimizerswitches + [cs_opt_level3{,cs_opt_loopunroll}];
-   level4optimizerswitches = genericlevel4optimizerswitches + level3optimizerswitches + [];
-
-Implementation
-
-end.
-

+ 0 - 268
compiler/ia64/ia64reg.dat

@@ -1,268 +0,0 @@
-;
-; iA-64 registers
-; This file is generate with help of fpc/compiler/utils/gia64reg,
-; please try to use this generator before you do error prone and tedious
-; editing by hand
-;
-; layout
-; <name>,<type>,<value>,<stdname>,<gasname>
-;
-NO,$00,$00,INVALID,INVALID
-
-R0,$01,0,r0,r0
-R1,$01,1,r1,r1
-R2,$01,2,r2,r2
-R3,$01,3,r3,r3
-R4,$01,4,r4,r4
-R5,$01,5,r5,r5
-R6,$01,6,r6,r6
-R7,$01,7,r7,r7
-R8,$01,8,r8,r8
-R9,$01,9,r9,r9
-R10,$01,10,r10,r10
-R11,$01,11,r11,r11
-R12,$01,12,r12,r12
-R13,$01,13,r13,r13
-R14,$01,14,r14,r14
-R15,$01,15,r15,r15
-R16,$01,16,r16,r16
-R17,$01,17,r17,r17
-R18,$01,18,r18,r18
-R19,$01,19,r19,r19
-R20,$01,20,r20,r20
-R21,$01,21,r21,r21
-R22,$01,22,r22,r22
-R23,$01,23,r23,r23
-R24,$01,24,r24,r24
-R25,$01,25,r25,r25
-R26,$01,26,r26,r26
-R27,$01,27,r27,r27
-R28,$01,28,r28,r28
-R29,$01,29,r29,r29
-R30,$01,30,r30,r30
-R31,$01,31,r31,r31
-R32,$01,32,r32,r32
-R33,$01,33,r33,r33
-R34,$01,34,r34,r34
-R35,$01,35,r35,r35
-R36,$01,36,r36,r36
-R37,$01,37,r37,r37
-R38,$01,38,r38,r38
-R39,$01,39,r39,r39
-R40,$01,40,r40,r40
-R41,$01,41,r41,r41
-R42,$01,42,r42,r42
-R43,$01,43,r43,r43
-R44,$01,44,r44,r44
-R45,$01,45,r45,r45
-R46,$01,46,r46,r46
-R47,$01,47,r47,r47
-R48,$01,48,r48,r48
-R49,$01,49,r49,r49
-R50,$01,50,r50,r50
-R51,$01,51,r51,r51
-R52,$01,52,r52,r52
-R53,$01,53,r53,r53
-R54,$01,54,r54,r54
-R55,$01,55,r55,r55
-R56,$01,56,r56,r56
-R57,$01,57,r57,r57
-R58,$01,58,r58,r58
-R59,$01,59,r59,r59
-R60,$01,60,r60,r60
-R61,$01,61,r61,r61
-R62,$01,62,r62,r62
-R63,$01,63,r63,r63
-R64,$01,64,r64,r64
-R65,$01,65,r65,r65
-R66,$01,66,r66,r66
-R67,$01,67,r67,r67
-R68,$01,68,r68,r68
-R69,$01,69,r69,r69
-R70,$01,70,r70,r70
-R71,$01,71,r71,r71
-R72,$01,72,r72,r72
-R73,$01,73,r73,r73
-R74,$01,74,r74,r74
-R75,$01,75,r75,r75
-R76,$01,76,r76,r76
-R77,$01,77,r77,r77
-R78,$01,78,r78,r78
-R79,$01,79,r79,r79
-R80,$01,80,r80,r80
-R81,$01,81,r81,r81
-R82,$01,82,r82,r82
-R83,$01,83,r83,r83
-R84,$01,84,r84,r84
-R85,$01,85,r85,r85
-R86,$01,86,r86,r86
-R87,$01,87,r87,r87
-R88,$01,88,r88,r88
-R89,$01,89,r89,r89
-R90,$01,90,r90,r90
-R91,$01,91,r91,r91
-R92,$01,92,r92,r92
-R93,$01,93,r93,r93
-R94,$01,94,r94,r94
-R95,$01,95,r95,r95
-R96,$01,96,r96,r96
-R97,$01,97,r97,r97
-R98,$01,98,r98,r98
-R99,$01,99,r99,r99
-R100,$01,100,r100,r100
-R101,$01,101,r101,r101
-R102,$01,102,r102,r102
-R103,$01,103,r103,r103
-R104,$01,104,r104,r104
-R105,$01,105,r105,r105
-R106,$01,106,r106,r106
-R107,$01,107,r107,r107
-R108,$01,108,r108,r108
-R109,$01,109,r109,r109
-R110,$01,110,r110,r110
-R111,$01,111,r111,r111
-R112,$01,112,r112,r112
-R113,$01,113,r113,r113
-R114,$01,114,r114,r114
-R115,$01,115,r115,r115
-R116,$01,116,r116,r116
-R117,$01,117,r117,r117
-R118,$01,118,r118,r118
-R119,$01,119,r119,r119
-R120,$01,120,r120,r120
-R121,$01,121,r121,r121
-R122,$01,122,r122,r122
-R123,$01,123,r123,r123
-R124,$01,124,r124,r124
-R125,$01,125,r125,r125
-R126,$01,126,r126,r126
-R127,$01,127,r127,r127
-
-F0,$02,0,r0,r0
-F1,$02,1,r1,r1
-F2,$02,2,r2,r2
-F3,$02,3,r3,r3
-F4,$02,4,r4,r4
-F5,$02,5,r5,r5
-F6,$02,6,r6,r6
-F7,$02,7,r7,r7
-F8,$02,8,r8,r8
-F9,$02,9,r9,r9
-F10,$02,10,r10,r10
-F11,$02,11,r11,r11
-F12,$02,12,r12,r12
-F13,$02,13,r13,r13
-F14,$02,14,r14,r14
-F15,$02,15,r15,r15
-F16,$02,16,r16,r16
-F17,$02,17,r17,r17
-F18,$02,18,r18,r18
-F19,$02,19,r19,r19
-F20,$02,20,r20,r20
-F21,$02,21,r21,r21
-F22,$02,22,r22,r22
-F23,$02,23,r23,r23
-F24,$02,24,r24,r24
-F25,$02,25,r25,r25
-F26,$02,26,r26,r26
-F27,$02,27,r27,r27
-F28,$02,28,r28,r28
-F29,$02,29,r29,r29
-F30,$02,30,r30,r30
-F31,$02,31,r31,r31
-F32,$02,32,r32,r32
-F33,$02,33,r33,r33
-F34,$02,34,r34,r34
-F35,$02,35,r35,r35
-F36,$02,36,r36,r36
-F37,$02,37,r37,r37
-F38,$02,38,r38,r38
-F39,$02,39,r39,r39
-F40,$02,40,r40,r40
-F41,$02,41,r41,r41
-F42,$02,42,r42,r42
-F43,$02,43,r43,r43
-F44,$02,44,r44,r44
-F45,$02,45,r45,r45
-F46,$02,46,r46,r46
-F47,$02,47,r47,r47
-F48,$02,48,r48,r48
-F49,$02,49,r49,r49
-F50,$02,50,r50,r50
-F51,$02,51,r51,r51
-F52,$02,52,r52,r52
-F53,$02,53,r53,r53
-F54,$02,54,r54,r54
-F55,$02,55,r55,r55
-F56,$02,56,r56,r56
-F57,$02,57,r57,r57
-F58,$02,58,r58,r58
-F59,$02,59,r59,r59
-F60,$02,60,r60,r60
-F61,$02,61,r61,r61
-F62,$02,62,r62,r62
-F63,$02,63,r63,r63
-F64,$02,64,r64,r64
-F65,$02,65,r65,r65
-F66,$02,66,r66,r66
-F67,$02,67,r67,r67
-F68,$02,68,r68,r68
-F69,$02,69,r69,r69
-F70,$02,70,r70,r70
-F71,$02,71,r71,r71
-F72,$02,72,r72,r72
-F73,$02,73,r73,r73
-F74,$02,74,r74,r74
-F75,$02,75,r75,r75
-F76,$02,76,r76,r76
-F77,$02,77,r77,r77
-F78,$02,78,r78,r78
-F79,$02,79,r79,r79
-F80,$02,80,r80,r80
-F81,$02,81,r81,r81
-F82,$02,82,r82,r82
-F83,$02,83,r83,r83
-F84,$02,84,r84,r84
-F85,$02,85,r85,r85
-F86,$02,86,r86,r86
-F87,$02,87,r87,r87
-F88,$02,88,r88,r88
-F89,$02,89,r89,r89
-F90,$02,90,r90,r90
-F91,$02,91,r91,r91
-F92,$02,92,r92,r92
-F93,$02,93,r93,r93
-F94,$02,94,r94,r94
-F95,$02,95,r95,r95
-F96,$02,96,r96,r96
-F97,$02,97,r97,r97
-F98,$02,98,r98,r98
-F99,$02,99,r99,r99
-F100,$02,100,r100,r100
-F101,$02,101,r101,r101
-F102,$02,102,r102,r102
-F103,$02,103,r103,r103
-F104,$02,104,r104,r104
-F105,$02,105,r105,r105
-F106,$02,106,r106,r106
-F107,$02,107,r107,r107
-F108,$02,108,r108,r108
-F109,$02,109,r109,r109
-F110,$02,110,r110,r110
-F111,$02,111,r111,r111
-F112,$02,112,r112,r112
-F113,$02,113,r113,r113
-F114,$02,114,r114,r114
-F115,$02,115,r115,r115
-F116,$02,116,r116,r116
-F117,$02,117,r117,r117
-F118,$02,118,r118,r118
-F119,$02,119,r119,r119
-F120,$02,120,r120,r120
-F121,$02,121,r121,r121
-F122,$02,122,r122,r122
-F123,$02,123,r123,r123
-F124,$02,124,r124,r124
-F125,$02,125,r125,r125
-F126,$02,126,r126,r126
-F127,$02,127,r127,r127

+ 0 - 211
compiler/ia64/symcpu.pas

@@ -1,211 +0,0 @@
-{
-    Copyright (c) 2014 by Florian Klaempfl
-
-    Symbol table overrides for IA64
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit symcpu;
-
-{$i fpcdefs.inc}
-
-interface
-
-uses
-  symtype,symdef,symsym;
-
-type
-  { defs }
-  tcpufiledef = class(tfiledef)
-  end;
-  tcpufiledefclass = class of tcpufiledef;
-
-  tcpuvariantdef = class(tvariantdef)
-  end;
-  tcpuvariantdefclass = class of tcpuvariantdef;
-
-  tcpuformaldef = class(tformaldef)
-  end;
-  tcpuformaldefclass = class of tcpuformaldef;
-
-  tcpuforwarddef = class(tforwarddef)
-  end;
-  tcpuforwarddefclass = class of tcpuforwarddef;
-
-  tcpuundefineddef = class(tundefineddef)
-  end;
-  tcpuundefineddefclass = class of tcpuundefineddef;
-
-  tcpuerrordef = class(terrordef)
-  end;
-  tcpuerrordefclass = class of tcpuerrordef;
-
-  tcpupointerdef = class(tpointerdef)
-  end;
-  tcpupointerdefclass = class of tcpupointerdef;
-
-  tcpurecorddef = class(trecorddef)
-  end;
-  tcpurecorddefclass = class of tcpurecorddef;
-
-  tcpuimplementedinterface = class(timplementedinterface)
-  end;
-  tcpuimplementedinterfaceclass = class of tcpuimplementedinterface;
-
-  tcpuobjectdef = class(tobjectdef)
-  end;
-  tcpuobjectdefclass = class of tcpuobjectdef;
-
-  tcpuclassrefdef = class(tclassrefdef)
-  end;
-  tcpuclassrefdefclass = class of tcpuclassrefdef;
-
-  tcpuarraydef = class(tarraydef)
-  end;
-  tcpuarraydefclass = class of tcpuarraydef;
-
-  tcpuorddef = class(torddef)
-  end;
-  tcpuorddefclass = class of tcpuorddef;
-
-  tcpufloatdef = class(tfloatdef)
-  end;
-  tcpufloatdefclass = class of tcpufloatdef;
-
-  tcpuprocvardef = class(tprocvardef)
-  end;
-  tcpuprocvardefclass = class of tcpuprocvardef;
-
-  tcpuprocdef = class(tprocdef)
-  end;
-  tcpuprocdefclass = class of tcpuprocdef;
-
-  tcpustringdef = class(tstringdef)
-  end;
-  tcpustringdefclass = class of tcpustringdef;
-
-  tcpuenumdef = class(tenumdef)
-  end;
-  tcpuenumdefclass = class of tcpuenumdef;
-
-  tcpusetdef = class(tsetdef)
-  end;
-  tcpusetdefclass = class of tcpusetdef;
-
-  { syms }
-  tcpulabelsym = class(tlabelsym)
-  end;
-  tcpulabelsymclass = class of tcpulabelsym;
-
-  tcpuunitsym = class(tunitsym)
-  end;
-  tcpuunitsymclass = class of tcpuunitsym;
-
-  tcpunamespacesym = class(tnamespacesym)
-  end;
-  tcpunamespacesymclass = class of tcpunamespacesym;
-
-  tcpuprocsym = class(tprocsym)
-  end;
-  tcpuprocsymclass = class of tcpuprocsym;
-
-  tcputypesym = class(ttypesym)
-  end;
-  tcpuypesymclass = class of tcputypesym;
-
-  tcpufieldvarsym = class(tfieldvarsym)
-  end;
-  tcpufieldvarsymclass = class of tcpufieldvarsym;
-
-  tcpulocalvarsym = class(tlocalvarsym)
-  end;
-  tcpulocalvarsymclass = class of tcpulocalvarsym;
-
-  tcpuparavarsym = class(tparavarsym)
-  end;
-  tcpuparavarsymclass = class of tcpuparavarsym;
-
-  tcpustaticvarsym = class(tstaticvarsym)
-  end;
-  tcpustaticvarsymclass = class of tcpustaticvarsym;
-
-  tcpuabsolutevarsym = class(tabsolutevarsym)
-  end;
-  tcpuabsolutevarsymclass = class of tcpuabsolutevarsym;
-
-  tcpupropertysym = class(tpropertysym)
-  end;
-  tcpupropertysymclass = class of tcpupropertysym;
-
-  tcpuconstsym = class(tconstsym)
-  end;
-  tcpuconstsymclass = class of tcpuconstsym;
-
-  tcpuenumsym = class(tenumsym)
-  end;
-  tcpuenumsymclass = class of tcpuenumsym;
-
-  tcpusyssym = class(tsyssym)
-  end;
-  tcpusyssymclass = class of tcpusyssym;
-
-
-const
-  pbestrealtype : ^tdef = @s64floattype;
-
-
-implementation
-
-begin
-  { used tdef classes }
-  cfiledef:=tcpufiledef;
-  cvariantdef:=tcpuvariantdef;
-  cformaldef:=tcpuformaldef;
-  cforwarddef:=tcpuforwarddef;
-  cundefineddef:=tcpuundefineddef;
-  cerrordef:=tcpuerrordef;
-  cpointerdef:=tcpupointerdef;
-  crecorddef:=tcpurecorddef;
-  cimplementedinterface:=tcpuimplementedinterface;
-  cobjectdef:=tcpuobjectdef;
-  cclassrefdef:=tcpuclassrefdef;
-  carraydef:=tcpuarraydef;
-  corddef:=tcpuorddef;
-  cfloatdef:=tcpufloatdef;
-  cprocvardef:=tcpuprocvardef;
-  cprocdef:=tcpuprocdef;
-  cstringdef:=tcpustringdef;
-  cenumdef:=tcpuenumdef;
-  csetdef:=tcpusetdef;
-
-  { used tsym classes }
-  clabelsym:=tcpulabelsym;
-  cunitsym:=tcpuunitsym;
-  cnamespacesym:=tcpunamespacesym;
-  cprocsym:=tcpuprocsym;
-  ctypesym:=tcputypesym;
-  cfieldvarsym:=tcpufieldvarsym;
-  clocalvarsym:=tcpulocalvarsym;
-  cparavarsym:=tcpuparavarsym;
-  cstaticvarsym:=tcpustaticvarsym;
-  cabsolutevarsym:=tcpuabsolutevarsym;
-  cpropertysym:=tcpupropertysym;
-  cconstsym:=tcpuconstsym;
-  cenumsym:=tcpuenumsym;
-  csyssym:=tcpusyssym;
-end.
-

+ 2 - 2
compiler/jvm/cpupara.pas

@@ -160,7 +160,7 @@ implementation
         else if jvmimplicitpointertype(result.def) then
         else if jvmimplicitpointertype(result.def) then
           begin
           begin
             retcgsize:=OS_ADDR;
             retcgsize:=OS_ADDR;
-            result.def:=getpointerdef(result.def);
+            result.def:=cpointerdef.getreusable(result.def);
           end
           end
         else
         else
           begin
           begin
@@ -237,7 +237,7 @@ implementation
             else if jvmimplicitpointertype(hp.vardef) then
             else if jvmimplicitpointertype(hp.vardef) then
               begin
               begin
                 paracgsize:=OS_ADDR;
                 paracgsize:=OS_ADDR;
-                paradef:=getpointerdef(hp.vardef);
+                paradef:=cpointerdef.getreusable(hp.vardef);
               end
               end
             else
             else
               begin
               begin

+ 1 - 0
compiler/jvm/hlcgcpu.pas

@@ -2401,6 +2401,7 @@ implementation
         begin
         begin
           sym:=tsym(obj.symtable.symlist[i]);
           sym:=tsym(obj.symtable.symlist[i]);
           if (sym.typ=fieldvarsym) and
           if (sym.typ=fieldvarsym) and
+             not(sp_static in sym.symoptions) and
              (jvmimplicitpointertype(tfieldvarsym(sym).vardef) or
              (jvmimplicitpointertype(tfieldvarsym(sym).vardef) or
               ((tfieldvarsym(sym).vardef.typ=enumdef) and
               ((tfieldvarsym(sym).vardef.typ=enumdef) and
                get_enum_init_val_ref(tfieldvarsym(sym).vardef,ref))) then
                get_enum_init_val_ref(tfieldvarsym(sym).vardef,ref))) then

+ 1 - 1
compiler/jvm/njvmadd.pas

@@ -324,7 +324,7 @@ interface
           evaluation }
           evaluation }
         if not is_boolean(resultdef) then
         if not is_boolean(resultdef) then
           begin
           begin
-            inserttypeconv_explicit(result,getpointerdef(resultdef));
+            inserttypeconv_explicit(result,cpointerdef.getreusable(resultdef));
             result:=cderefnode.create(result);
             result:=cderefnode.create(result);
           end;
           end;
         { left and right are reused as parameters }
         { left and right are reused as parameters }

+ 13 - 3
compiler/jvm/njvmcal.pas

@@ -50,6 +50,7 @@ interface
          procedure extra_post_call_code; override;
          procedure extra_post_call_code; override;
          function dispatch_procvar: tnode;
          function dispatch_procvar: tnode;
          procedure remove_hidden_paras;
          procedure remove_hidden_paras;
+         procedure gen_vmt_entry_load; override;
         public
         public
          function pass_typecheck: tnode; override;
          function pass_typecheck: tnode; override;
          function pass_1: tnode; override;
          function pass_1: tnode; override;
@@ -170,6 +171,9 @@ implementation
         implicitptrpara,
         implicitptrpara,
         verifyout: boolean;
         verifyout: boolean;
       begin
       begin
+        { the original version doesn't do anything for garbage collected
+          platforms, but who knows in the future }
+        inherited;
         { implicit pointer types are already pointers -> no need to stuff them
         { implicit pointer types are already pointers -> no need to stuff them
           in an array to pass them by reference (except in case of a formal
           in an array to pass them by reference (except in case of a formal
           parameter, in which case everything is passed in an array since the
           parameter, in which case everything is passed in an array since the
@@ -224,10 +228,10 @@ implementation
         if parasym.vardef.typ=formaldef then
         if parasym.vardef.typ=formaldef then
           arreledef:=java_jlobject
           arreledef:=java_jlobject
         else if implicitptrpara then
         else if implicitptrpara then
-          arreledef:=getpointerdef(orgparadef)
+          arreledef:=cpointerdef.getreusable(orgparadef)
         else
         else
           arreledef:=parasym.vardef;
           arreledef:=parasym.vardef;
-        arrdef:=getarraydef(arreledef,1+ord(cs_check_var_copyout in current_settings.localswitches));
+        arrdef:=carraydef.getreusable(arreledef,1+ord(cs_check_var_copyout in current_settings.localswitches));
         { the -1 means "use the array's element count to determine the number
         { the -1 means "use the array's element count to determine the number
           of elements" in the JVM temp generator }
           of elements" in the JVM temp generator }
         arraytemp:=ctempcreatenode.create(arrdef,-1,tt_persistent,true);
         arraytemp:=ctempcreatenode.create(arrdef,-1,tt_persistent,true);
@@ -308,7 +312,7 @@ implementation
                   tempn:=cinlinenode.create(in_unbox_x_y,false,ccallparanode.create(
                   tempn:=cinlinenode.create(in_unbox_x_y,false,ccallparanode.create(
                     ctypenode.create(orgparadef),ccallparanode.create(tempn,nil)))
                     ctypenode.create(orgparadef),ccallparanode.create(tempn,nil)))
                 else if implicitptrpara then
                 else if implicitptrpara then
-                  tempn:=ctypeconvnode.create_explicit(tempn,getpointerdef(orgparadef))
+                  tempn:=ctypeconvnode.create_explicit(tempn,cpointerdef.getreusable(orgparadef))
               end;
               end;
             if implicitptrpara then
             if implicitptrpara then
               tempn:=cderefnode.create(tempn)
               tempn:=cderefnode.create(tempn)
@@ -492,6 +496,12 @@ implementation
     end;
     end;
 
 
 
 
+  procedure tjvmcallnode.gen_vmt_entry_load;
+    begin
+      { nothing to do }
+    end;
+
+
   function tjvmcallnode.pass_typecheck: tnode;
   function tjvmcallnode.pass_typecheck: tnode;
     begin
     begin
       result:=inherited pass_typecheck;
       result:=inherited pass_typecheck;

+ 5 - 5
compiler/jvm/njvmcnv.pas

@@ -368,7 +368,7 @@ implementation
                       genintconstnode(tsetdef(left.resultdef).setbase),
                       genintconstnode(tsetdef(left.resultdef).setbase),
                         ccallparanode.create(left,nil))));
                         ccallparanode.create(left,nil))));
               end;
               end;
-            inserttypeconv_explicit(result,getpointerdef(resultdef));
+            inserttypeconv_explicit(result,cpointerdef.getreusable(resultdef));
             result:=cderefnode.create(result);
             result:=cderefnode.create(result);
             { reused }
             { reused }
             left:=nil;
             left:=nil;
@@ -387,7 +387,7 @@ implementation
         result:=ccallnode.createinternmethod(
         result:=ccallnode.createinternmethod(
           cloadvmtaddrnode.create(ctypenode.create(tcpuprocvardef(resultdef).classdef)),'CREATE',nil);
           cloadvmtaddrnode.create(ctypenode.create(tcpuprocvardef(resultdef).classdef)),'CREATE',nil);
         { method pointer is an implicit pointer type }
         { method pointer is an implicit pointer type }
-        result:=ctypeconvnode.create_explicit(result,getpointerdef(resultdef));
+        result:=ctypeconvnode.create_explicit(result,cpointerdef.getreusable(resultdef));
         result:=cderefnode.create(result);
         result:=cderefnode.create(result);
       end;
       end;
 
 
@@ -494,7 +494,7 @@ implementation
           result:=ctypeconvnode.create_explicit(result,resultdef)
           result:=ctypeconvnode.create_explicit(result,resultdef)
         else
         else
           begin
           begin
-            result:=ctypeconvnode.create_explicit(result,getpointerdef(resultdef));
+            result:=ctypeconvnode.create_explicit(result,cpointerdef.getreusable(resultdef));
             result:=cderefnode.create(result)
             result:=cderefnode.create(result)
           end;
           end;
         { reused }
         { reused }
@@ -1263,7 +1263,7 @@ implementation
                   a proper checkcast is inserted }
                   a proper checkcast is inserted }
                 if not check_only then
                 if not check_only then
                   begin
                   begin
-                    resnode:=ctypeconvnode.create_explicit(left,getpointerdef(resultdef));
+                    resnode:=ctypeconvnode.create_explicit(left,cpointerdef.getreusable(resultdef));
                     resnode:=cderefnode.create(resnode);
                     resnode:=cderefnode.create(resnode);
                     left:=nil;
                     left:=nil;
                   end;
                   end;
@@ -1385,7 +1385,7 @@ implementation
                   begin
                   begin
                     resnode:=to_set_explicit_typecast;
                     resnode:=to_set_explicit_typecast;
                     { convert to desired result }
                     { convert to desired result }
-                    inserttypeconv_explicit(resnode,getpointerdef(resultdef));
+                    inserttypeconv_explicit(resnode,cpointerdef.getreusable(resultdef));
                     resnode:=cderefnode.create(resnode);
                     resnode:=cderefnode.create(resnode);
                   end;
                   end;
                 result:=true;
                 result:=true;

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません