Browse Source

merge of r31476 through r32427

git-svn-id: branches/interfacertti@32429 -
steve 10 years ago
parent
commit
d356e65415
100 changed files with 4507 additions and 2052 deletions
  1. 153 6
      .gitattributes
  2. 21 4
      Makefile
  3. 1 1
      Makefile.fpc
  4. 36 3
      compiler/Makefile
  5. 3 0
      compiler/Makefile.fpc
  6. 21 35
      compiler/aarch64/agcpugas.pas
  7. 7 1
      compiler/aarch64/cpuinfo.pas
  8. 2 2
      compiler/aarch64/cpupara.pas
  9. 263 9
      compiler/aasmcnst.pas
  10. 3 0
      compiler/aasmdata.pas
  11. 29 0
      compiler/aasmtai.pas
  12. 232 229
      compiler/aggas.pas
  13. 1 3
      compiler/aopt.pas
  14. 30 10
      compiler/aoptobj.pas
  15. 171 85
      compiler/arm/aasmcpu.pas
  16. 44 14
      compiler/arm/agarmgas.pas
  17. 9 9
      compiler/arm/aoptcpu.pas
  18. 128 51
      compiler/arm/cgcpu.pas
  19. 511 291
      compiler/arm/cpuinfo.pas
  20. 5 6
      compiler/arm/cpupara.pas
  21. 0 1
      compiler/arm/hlcgcpu.pas
  22. 2 2
      compiler/arm/narmadd.pas
  23. 0 1
      compiler/arm/narminl.pas
  24. 2 2
      compiler/arm/narmmat.pas
  25. 1 5
      compiler/arm/rgcpu.pas
  26. 511 317
      compiler/assemble.pas
  27. 5 6
      compiler/avr/agavrgas.pas
  28. 18 8
      compiler/avr/aoptcpu.pas
  29. 33 6
      compiler/avr/cgcpu.pas
  30. 155 144
      compiler/avr/cpuinfo.pas
  31. 2 2
      compiler/avr/cpupara.pas
  32. 7 7
      compiler/blockutl.pas
  33. 6 6
      compiler/cclasses.pas
  34. 4 4
      compiler/cg64f32.pas
  35. 1 0
      compiler/cgbase.pas
  36. 2 2
      compiler/cgutils.pas
  37. 7 1
      compiler/compiler.pas
  38. 51 49
      compiler/cresstr.pas
  39. 0 2
      compiler/cutils.pas
  40. 69 31
      compiler/dbgdwarf.pas
  41. 53 9
      compiler/defcmp.pas
  42. 2 0
      compiler/finput.pas
  43. 32 0
      compiler/fmodule.pas
  44. 2 2
      compiler/fpcdefs.inc
  45. 13 11
      compiler/fppu.pas
  46. 7 1
      compiler/generic/cpuinfo.pas
  47. 8 1
      compiler/globals.pas
  48. 34 17
      compiler/globtype.pas
  49. 89 28
      compiler/hlcgobj.pas
  50. 91 24
      compiler/htypechk.pas
  51. 39 43
      compiler/i386/cgcpu.pas
  52. 7 1
      compiler/i386/cpuinfo.pas
  53. 2 2
      compiler/i386/cpupara.pas
  54. 1 2
      compiler/i386/cpupi.pas
  55. 2 14
      compiler/i386/daopt386.pas
  56. 27 0
      compiler/i386/hlcgcpu.pas
  57. 2 2
      compiler/i386/n386flw.pas
  58. 2 2
      compiler/i386/n386ld.pas
  59. 4 78
      compiler/i386/popt386.pas
  60. 65 1
      compiler/i8086/aoptcpu.pas
  61. 129 42
      compiler/i8086/cgcpu.pas
  62. 1 0
      compiler/i8086/cpubase.inc
  63. 7 1
      compiler/i8086/cpuinfo.pas
  64. 3 3
      compiler/i8086/cpupara.pas
  65. 3 0
      compiler/i8086/cputarg.pas
  66. 18 0
      compiler/i8086/hlcgcpu.pas
  67. 29 4
      compiler/i8086/n8086add.pas
  68. 13 1
      compiler/i8086/n8086cnv.pas
  69. 12 1
      compiler/i8086/n8086con.pas
  70. 174 6
      compiler/i8086/n8086ld.pas
  71. 52 5
      compiler/i8086/n8086mat.pas
  72. 20 0
      compiler/i8086/n8086mem.pas
  73. 96 2
      compiler/i8086/n8086tcon.pas
  74. 5 5
      compiler/i8086/symcpu.pas
  75. 139 121
      compiler/jvm/agjasmin.pas
  76. 1 0
      compiler/jvm/aoptcpu.pas
  77. 7 1
      compiler/jvm/cpuinfo.pas
  78. 2 2
      compiler/jvm/cpupara.pas
  79. 2 1
      compiler/jvm/hlcgcpu.pas
  80. 14 3
      compiler/jvm/jvmdef.pas
  81. 1 1
      compiler/jvm/njvmcal.pas
  82. 32 5
      compiler/jvm/njvmcnv.pas
  83. 2 2
      compiler/jvm/njvminl.pas
  84. 1 1
      compiler/jvm/njvmld.pas
  85. 2 2
      compiler/jvm/njvmmem.pas
  86. 15 1
      compiler/jvm/njvmutil.pas
  87. 21 21
      compiler/jvm/pjvm.pas
  88. 5 5
      compiler/jvm/symcpu.pas
  89. 13 1
      compiler/jvm/tgcpu.pas
  90. 2 2
      compiler/link.pas
  91. 80 15
      compiler/llvm/aasmllvm.pas
  92. 241 143
      compiler/llvm/agllvm.pas
  93. 134 38
      compiler/llvm/hlcgllvm.pas
  94. 1 0
      compiler/llvm/itllvm.pas
  95. 1 0
      compiler/llvm/llvmbase.pas
  96. 25 3
      compiler/llvm/llvmdef.pas
  97. 1 1
      compiler/llvm/llvmpara.pas
  98. 24 12
      compiler/llvm/llvmtype.pas
  99. 56 6
      compiler/llvm/nllvmcnv.pas
  100. 95 2
      compiler/llvm/nllvminl.pas

+ 153 - 6
.gitattributes

@@ -524,6 +524,7 @@ compiler/pdecsub.pas svneol=native#text/plain
 compiler/pdecvar.pas svneol=native#text/plain
 compiler/pdecvar.pas svneol=native#text/plain
 compiler/pexports.pas svneol=native#text/plain
 compiler/pexports.pas svneol=native#text/plain
 compiler/pexpr.pas svneol=native#text/plain
 compiler/pexpr.pas svneol=native#text/plain
+compiler/pgentype.pas svneol=native#text/pascal
 compiler/pgenutil.pas svneol=native#text/pascal
 compiler/pgenutil.pas svneol=native#text/pascal
 compiler/pinline.pas svneol=native#text/plain
 compiler/pinline.pas svneol=native#text/plain
 compiler/pmodules.pas svneol=native#text/plain
 compiler/pmodules.pas svneol=native#text/plain
@@ -687,7 +688,6 @@ compiler/symbase.pas svneol=native#text/plain
 compiler/symconst.pas svneol=native#text/plain
 compiler/symconst.pas svneol=native#text/plain
 compiler/symcreat.pas svneol=native#text/plain
 compiler/symcreat.pas svneol=native#text/plain
 compiler/symdef.pas svneol=native#text/plain
 compiler/symdef.pas svneol=native#text/plain
-compiler/symnot.pas svneol=native#text/plain
 compiler/symsym.pas svneol=native#text/plain
 compiler/symsym.pas svneol=native#text/plain
 compiler/symtable.pas svneol=native#text/plain
 compiler/symtable.pas svneol=native#text/plain
 compiler/symtype.pas svneol=native#text/plain
 compiler/symtype.pas svneol=native#text/plain
@@ -723,6 +723,7 @@ compiler/systems/i_watcom.pas svneol=native#text/plain
 compiler/systems/i_wdosx.pas svneol=native#text/plain
 compiler/systems/i_wdosx.pas svneol=native#text/plain
 compiler/systems/i_wii.pas svneol=native#text/plain
 compiler/systems/i_wii.pas svneol=native#text/plain
 compiler/systems/i_win.pas svneol=native#text/plain
 compiler/systems/i_win.pas svneol=native#text/plain
+compiler/systems/i_win16.pas svneol=native#text/plain
 compiler/systems/mac_crea.txt svneol=native#text/plain
 compiler/systems/mac_crea.txt svneol=native#text/plain
 compiler/systems/t_aix.pas svneol=native#text/plain
 compiler/systems/t_aix.pas svneol=native#text/plain
 compiler/systems/t_amiga.pas svneol=native#text/plain
 compiler/systems/t_amiga.pas svneol=native#text/plain
@@ -753,6 +754,7 @@ compiler/systems/t_watcom.pas svneol=native#text/plain
 compiler/systems/t_wdosx.pas svneol=native#text/plain
 compiler/systems/t_wdosx.pas svneol=native#text/plain
 compiler/systems/t_wii.pas svneol=native#text/plain
 compiler/systems/t_wii.pas svneol=native#text/plain
 compiler/systems/t_win.pas svneol=native#text/plain
 compiler/systems/t_win.pas svneol=native#text/plain
+compiler/systems/t_win16.pas svneol=native#text/plain
 compiler/tgobj.pas svneol=native#text/plain
 compiler/tgobj.pas svneol=native#text/plain
 compiler/tokens.pas svneol=native#text/plain
 compiler/tokens.pas svneol=native#text/plain
 compiler/utils/Makefile svneol=native#text/plain
 compiler/utils/Makefile svneol=native#text/plain
@@ -801,6 +803,7 @@ compiler/x86/aasmcpu.pas svneol=native#text/plain
 compiler/x86/agx86att.pas svneol=native#text/plain
 compiler/x86/agx86att.pas svneol=native#text/plain
 compiler/x86/agx86int.pas svneol=native#text/plain
 compiler/x86/agx86int.pas svneol=native#text/plain
 compiler/x86/agx86nsm.pas svneol=native#text/plain
 compiler/x86/agx86nsm.pas svneol=native#text/plain
+compiler/x86/aoptx86.pas svneol=native#text/pascal
 compiler/x86/cga.pas svneol=native#text/plain
 compiler/x86/cga.pas svneol=native#text/plain
 compiler/x86/cgx86.pas svneol=native#text/plain
 compiler/x86/cgx86.pas svneol=native#text/plain
 compiler/x86/cpubase.pas svneol=native#text/plain
 compiler/x86/cpubase.pas svneol=native#text/plain
@@ -813,6 +816,7 @@ compiler/x86/nx86cal.pas svneol=native#text/plain
 compiler/x86/nx86cnv.pas svneol=native#text/plain
 compiler/x86/nx86cnv.pas svneol=native#text/plain
 compiler/x86/nx86con.pas svneol=native#text/plain
 compiler/x86/nx86con.pas svneol=native#text/plain
 compiler/x86/nx86inl.pas svneol=native#text/plain
 compiler/x86/nx86inl.pas svneol=native#text/plain
+compiler/x86/nx86ld.pas svneol=native#text/plain
 compiler/x86/nx86mat.pas svneol=native#text/plain
 compiler/x86/nx86mat.pas svneol=native#text/plain
 compiler/x86/nx86mem.pas svneol=native#text/plain
 compiler/x86/nx86mem.pas svneol=native#text/plain
 compiler/x86/nx86set.pas svneol=native#text/plain
 compiler/x86/nx86set.pas svneol=native#text/plain
@@ -1962,6 +1966,7 @@ packages/fcl-base/examples/showver.pp svneol=native#text/plain
 packages/fcl-base/examples/showver.rc -text
 packages/fcl-base/examples/showver.rc -text
 packages/fcl-base/examples/showver.res -text
 packages/fcl-base/examples/showver.res -text
 packages/fcl-base/examples/simple.xml -text
 packages/fcl-base/examples/simple.xml -text
+packages/fcl-base/examples/sitest.pp svneol=native#text/plain
 packages/fcl-base/examples/sockcli.pp svneol=native#text/plain
 packages/fcl-base/examples/sockcli.pp svneol=native#text/plain
 packages/fcl-base/examples/socksvr.pp svneol=native#text/plain
 packages/fcl-base/examples/socksvr.pp svneol=native#text/plain
 packages/fcl-base/examples/sstream.pp svneol=native#text/plain
 packages/fcl-base/examples/sstream.pp svneol=native#text/plain
@@ -1977,6 +1982,8 @@ packages/fcl-base/examples/testcont.pp svneol=native#text/plain
 packages/fcl-base/examples/testexprpars.pp svneol=native#text/plain
 packages/fcl-base/examples/testexprpars.pp svneol=native#text/plain
 packages/fcl-base/examples/testez.pp svneol=native#text/plain
 packages/fcl-base/examples/testez.pp svneol=native#text/plain
 packages/fcl-base/examples/testhres.pp svneol=native#text/plain
 packages/fcl-base/examples/testhres.pp svneol=native#text/plain
+packages/fcl-base/examples/testipc_client.pp svneol=native#text/plain
+packages/fcl-base/examples/testipc_server.pp svneol=native#text/plain
 packages/fcl-base/examples/testmime.pp svneol=native#text/plain
 packages/fcl-base/examples/testmime.pp svneol=native#text/plain
 packages/fcl-base/examples/testnres.pp svneol=native#text/plain
 packages/fcl-base/examples/testnres.pp svneol=native#text/plain
 packages/fcl-base/examples/testol.pp svneol=native#text/plain
 packages/fcl-base/examples/testol.pp svneol=native#text/plain
@@ -2004,6 +2011,7 @@ packages/fcl-base/examples/tstelgtk.pp svneol=native#text/plain
 packages/fcl-base/examples/txmlreg.pp svneol=native#text/plain
 packages/fcl-base/examples/txmlreg.pp svneol=native#text/plain
 packages/fcl-base/examples/xmldump.pp svneol=native#text/plain
 packages/fcl-base/examples/xmldump.pp svneol=native#text/plain
 packages/fcl-base/fpmake.pp svneol=native#text/plain
 packages/fcl-base/fpmake.pp svneol=native#text/plain
+packages/fcl-base/src/advancedipc.pp svneol=native#text/plain
 packages/fcl-base/src/ascii85.pp svneol=native#text/plain
 packages/fcl-base/src/ascii85.pp svneol=native#text/plain
 packages/fcl-base/src/avl_tree.pp svneol=native#text/plain
 packages/fcl-base/src/avl_tree.pp svneol=native#text/plain
 packages/fcl-base/src/base64.pp svneol=native#text/plain
 packages/fcl-base/src/base64.pp svneol=native#text/plain
@@ -2038,6 +2046,7 @@ packages/fcl-base/src/pooledmm.pp svneol=native#text/plain
 packages/fcl-base/src/rtfdata.inc svneol=native#text/plain
 packages/fcl-base/src/rtfdata.inc svneol=native#text/plain
 packages/fcl-base/src/rtfpars.pp svneol=native#text/plain
 packages/fcl-base/src/rtfpars.pp svneol=native#text/plain
 packages/fcl-base/src/rttiutils.pp svneol=native#text/plain
 packages/fcl-base/src/rttiutils.pp svneol=native#text/plain
+packages/fcl-base/src/singleinstance.pp svneol=native#text/plain
 packages/fcl-base/src/streamcoll.pp svneol=native#text/plain
 packages/fcl-base/src/streamcoll.pp svneol=native#text/plain
 packages/fcl-base/src/streamex.pp svneol=native#text/plain
 packages/fcl-base/src/streamex.pp svneol=native#text/plain
 packages/fcl-base/src/streamio.pp svneol=native#text/plain
 packages/fcl-base/src/streamio.pp svneol=native#text/plain
@@ -2246,6 +2255,7 @@ packages/fcl-db/src/sqldb/mysql/mysql50conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysql51conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysql51conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysql55conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysql55conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysql56conn.pas svneol=native#text/pascal
 packages/fcl-db/src/sqldb/mysql/mysql56conn.pas svneol=native#text/pascal
+packages/fcl-db/src/sqldb/mysql/mysql57conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysqlconn.inc svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysqlconn.inc svneol=native#text/plain
 packages/fcl-db/src/sqldb/odbc/Makefile svneol=native#text/plain
 packages/fcl-db/src/sqldb/odbc/Makefile svneol=native#text/plain
 packages/fcl-db/src/sqldb/odbc/Makefile.fpc svneol=native#text/plain
 packages/fcl-db/src/sqldb/odbc/Makefile.fpc svneol=native#text/plain
@@ -4947,6 +4957,36 @@ packages/libgd/examples/gdtest.pp svneol=native#text/plain
 packages/libgd/examples/gdtestcgi.pp svneol=native#text/plain
 packages/libgd/examples/gdtestcgi.pp svneol=native#text/plain
 packages/libgd/fpmake.pp svneol=native#text/plain
 packages/libgd/fpmake.pp svneol=native#text/plain
 packages/libgd/src/gd.pas svneol=native#text/plain
 packages/libgd/src/gd.pas svneol=native#text/plain
+packages/libmicrohttpd/Makefile svneol=native#text/plain
+packages/libmicrohttpd/Makefile.fpc svneol=native#text/plain
+packages/libmicrohttpd/examples/basicauthentication.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/benchmark.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/benchmark_https.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/chunked_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/cutils.pas svneol=native#text/plain
+packages/libmicrohttpd/examples/demo.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/demo_https.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/digest_auth_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/dual_stack_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/fileserver_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/fileserver_example_dirs.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/fileserver_example_external_select.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/hellobrowser.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/https_fileserver_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/largepost.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/logging.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/magic.inc svneol=native#text/plain
+packages/libmicrohttpd/examples/minimal_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/minimal_example_comet.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/post_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/querystring_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/refuse_post_example.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/responseheaders.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/sessions.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/simplepost.pp svneol=native#text/plain
+packages/libmicrohttpd/examples/tlsauthentication.pp svneol=native#text/plain
+packages/libmicrohttpd/fpmake.pp svneol=native#text/plain
+packages/libmicrohttpd/src/libmicrohttpd.pp svneol=native#text/plain
 packages/libndsfpc/Makefile svneol=native#text/plain
 packages/libndsfpc/Makefile svneol=native#text/plain
 packages/libndsfpc/Makefile.fpc svneol=native#text/plain
 packages/libndsfpc/Makefile.fpc svneol=native#text/plain
 packages/libndsfpc/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/libndsfpc/Makefile.fpc.fpcmake svneol=native#text/plain
@@ -5763,8 +5803,11 @@ packages/morphunits/src/ahi.pas svneol=native#text/plain
 packages/morphunits/src/amigados.pas svneol=native#text/plain
 packages/morphunits/src/amigados.pas svneol=native#text/plain
 packages/morphunits/src/amigalib.pas svneol=native#text/plain
 packages/morphunits/src/amigalib.pas svneol=native#text/plain
 packages/morphunits/src/asl.pas svneol=native#text/plain
 packages/morphunits/src/asl.pas svneol=native#text/plain
+packages/morphunits/src/cgxvideo.pas svneol=native#text/plain
 packages/morphunits/src/clipboard.pas svneol=native#text/plain
 packages/morphunits/src/clipboard.pas svneol=native#text/plain
+packages/morphunits/src/cybergraphics.pas svneol=native#text/plain
 packages/morphunits/src/datatypes.pas svneol=native#text/plain
 packages/morphunits/src/datatypes.pas svneol=native#text/plain
+packages/morphunits/src/diskfont.pas svneol=native#text/plain
 packages/morphunits/src/exec.pas svneol=native#text/plain
 packages/morphunits/src/exec.pas svneol=native#text/plain
 packages/morphunits/src/get9.pas svneol=native#text/plain
 packages/morphunits/src/get9.pas svneol=native#text/plain
 packages/morphunits/src/hardware.pas svneol=native#text/plain
 packages/morphunits/src/hardware.pas svneol=native#text/plain
@@ -6801,6 +6844,10 @@ packages/rtl-console/src/win/keyboard.pp svneol=native#text/plain
 packages/rtl-console/src/win/mouse.pp svneol=native#text/plain
 packages/rtl-console/src/win/mouse.pp svneol=native#text/plain
 packages/rtl-console/src/win/video.pp svneol=native#text/plain
 packages/rtl-console/src/win/video.pp svneol=native#text/plain
 packages/rtl-console/src/win/winevent.pp svneol=native#text/plain
 packages/rtl-console/src/win/winevent.pp svneol=native#text/plain
+packages/rtl-console/src/win16/crt.pp svneol=native#text/plain
+packages/rtl-console/src/win16/keyboard.pp svneol=native#text/plain
+packages/rtl-console/src/win16/mouse.pp svneol=native#text/plain
+packages/rtl-console/src/win16/video.pp svneol=native#text/plain
 packages/rtl-extra/Makefile svneol=native#text/plain
 packages/rtl-extra/Makefile svneol=native#text/plain
 packages/rtl-extra/Makefile.fpc svneol=native#text/plain
 packages/rtl-extra/Makefile.fpc svneol=native#text/plain
 packages/rtl-extra/Makefile.fpc.fpcmake svneol=native#text/plain
 packages/rtl-extra/Makefile.fpc.fpcmake svneol=native#text/plain
@@ -8101,6 +8148,7 @@ rtl/android/jvm/java_sysh_android.inc svneol=native#text/plain
 rtl/android/jvm/rtl.cfg svneol=native#text/plain
 rtl/android/jvm/rtl.cfg svneol=native#text/plain
 rtl/android/mipsel/dllprt0.as svneol=native#text/plain
 rtl/android/mipsel/dllprt0.as svneol=native#text/plain
 rtl/android/mipsel/prt0.as svneol=native#text/plain
 rtl/android/mipsel/prt0.as svneol=native#text/plain
+rtl/android/sysandroid.inc svneol=native#text/plain
 rtl/arm/arm.inc svneol=native#text/plain
 rtl/arm/arm.inc svneol=native#text/plain
 rtl/arm/armdefines.inc svneol=native#text/plain
 rtl/arm/armdefines.inc svneol=native#text/plain
 rtl/arm/divide.inc svneol=native#text/plain
 rtl/arm/divide.inc svneol=native#text/plain
@@ -8306,7 +8354,11 @@ rtl/embedded/arm/lpc13xx.pp svneol=native#text/pascal
 rtl/embedded/arm/lpc1768.pp svneol=native#text/pascal
 rtl/embedded/arm/lpc1768.pp svneol=native#text/pascal
 rtl/embedded/arm/lpc21x4.pp svneol=native#text/plain
 rtl/embedded/arm/lpc21x4.pp svneol=native#text/plain
 rtl/embedded/arm/lpc8xx.pp svneol=native#text/pascal
 rtl/embedded/arm/lpc8xx.pp svneol=native#text/pascal
+rtl/embedded/arm/mk20d5.pp svneol=native#text/pascal
 rtl/embedded/arm/mk20d7.pp svneol=native#text/plain
 rtl/embedded/arm/mk20d7.pp svneol=native#text/plain
+rtl/embedded/arm/mk22f51212.pp svneol=native#text/pascal
+rtl/embedded/arm/mk64f12.pp svneol=native#text/pascal
+rtl/embedded/arm/sam3x8e.pp svneol=native#text/pascal
 rtl/embedded/arm/sc32442b.pp svneol=native#text/pascal
 rtl/embedded/arm/sc32442b.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f0xx.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f0xx.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f10x_cl.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f10x_cl.pp svneol=native#text/plain
@@ -8315,7 +8367,12 @@ rtl/embedded/arm/stm32f10x_hd.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f10x_ld.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f10x_ld.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f10x_md.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f10x_md.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f10x_xl.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f10x_xl.pp svneol=native#text/pascal
+rtl/embedded/arm/stm32f401xx.pp svneol=native#text/pascal
+rtl/embedded/arm/stm32f407xx.pp svneol=native#text/pascal
+rtl/embedded/arm/stm32f411xe.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f429.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f429.pp svneol=native#text/pascal
+rtl/embedded/arm/stm32f429xx.pp svneol=native#text/pascal
+rtl/embedded/arm/stm32f446xx.pp svneol=native#text/pascal
 rtl/embedded/arm/stm32f745.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f745.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f746.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f746.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f756.pp svneol=native#text/plain
 rtl/embedded/arm/stm32f756.pp svneol=native#text/plain
@@ -8685,6 +8742,7 @@ rtl/inc/dynlibs.pas svneol=native#text/plain
 rtl/inc/except.inc svneol=native#text/plain
 rtl/inc/except.inc svneol=native#text/plain
 rtl/inc/excepth.inc svneol=native#text/plain
 rtl/inc/excepth.inc svneol=native#text/plain
 rtl/inc/exeinfo.pp svneol=native#text/plain
 rtl/inc/exeinfo.pp svneol=native#text/plain
+rtl/inc/extpas.pp svneol=native#text/pascal
 rtl/inc/extres.inc svneol=native#text/plain
 rtl/inc/extres.inc svneol=native#text/plain
 rtl/inc/fexpand.inc svneol=native#text/plain
 rtl/inc/fexpand.inc svneol=native#text/plain
 rtl/inc/file.inc svneol=native#text/plain
 rtl/inc/file.inc svneol=native#text/plain
@@ -8745,6 +8803,8 @@ rtl/inc/threadvr.inc svneol=native#text/plain
 rtl/inc/tinyheap.inc svneol=native#text/plain
 rtl/inc/tinyheap.inc svneol=native#text/plain
 rtl/inc/tnyheaph.inc svneol=native#text/plain
 rtl/inc/tnyheaph.inc svneol=native#text/plain
 rtl/inc/typefile.inc svneol=native#text/plain
 rtl/inc/typefile.inc svneol=native#text/plain
+rtl/inc/typshrd.inc svneol=native#text/plain
+rtl/inc/typshrdh.inc svneol=native#text/plain
 rtl/inc/ufloat128.pp svneol=native#text/plain
 rtl/inc/ufloat128.pp svneol=native#text/plain
 rtl/inc/ustringh.inc svneol=native#text/plain
 rtl/inc/ustringh.inc svneol=native#text/plain
 rtl/inc/ustrings.inc svneol=native#text/plain
 rtl/inc/ustrings.inc svneol=native#text/plain
@@ -9306,6 +9366,11 @@ rtl/objpas/sysutils/syscodepagesh.inc svneol=native#text/pascal
 rtl/objpas/sysutils/sysencoding.inc svneol=native#text/pascal
 rtl/objpas/sysutils/sysencoding.inc svneol=native#text/pascal
 rtl/objpas/sysutils/sysencodingh.inc svneol=native#text/pascal
 rtl/objpas/sysutils/sysencodingh.inc svneol=native#text/pascal
 rtl/objpas/sysutils/sysformt.inc svneol=native#text/plain
 rtl/objpas/sysutils/sysformt.inc svneol=native#text/plain
+rtl/objpas/sysutils/syshelp.inc svneol=native#text/plain
+rtl/objpas/sysutils/syshelpb.inc svneol=native#text/plain
+rtl/objpas/sysutils/syshelpf.inc svneol=native#text/plain
+rtl/objpas/sysutils/syshelph.inc svneol=native#text/plain
+rtl/objpas/sysutils/syshelpo.inc svneol=native#text/plain
 rtl/objpas/sysutils/sysint.inc svneol=native#text/plain
 rtl/objpas/sysutils/sysint.inc svneol=native#text/plain
 rtl/objpas/sysutils/sysinth.inc svneol=native#text/plain
 rtl/objpas/sysutils/sysinth.inc svneol=native#text/plain
 rtl/objpas/sysutils/syspch.inc svneol=native#text/plain
 rtl/objpas/sysutils/syspch.inc svneol=native#text/plain
@@ -9692,6 +9757,36 @@ rtl/win/wininc/unidef.inc svneol=native#text/plain
 rtl/win/wininc/unidef.sed -text
 rtl/win/wininc/unidef.sed -text
 rtl/win/wininc/unifun.inc svneol=native#text/plain
 rtl/win/wininc/unifun.inc svneol=native#text/plain
 rtl/win/winres.inc svneol=native#text/plain
 rtl/win/winres.inc svneol=native#text/plain
+rtl/win16/Makefile svneol=native#text/plain
+rtl/win16/Makefile.fpc svneol=native#text/plain
+rtl/win16/dos.pp svneol=native#text/plain
+rtl/win16/dynlibs.inc svneol=native#text/plain
+rtl/win16/glbheap.inc svneol=native#text/plain
+rtl/win16/glbheaph.inc svneol=native#text/plain
+rtl/win16/locheap.inc svneol=native#text/plain
+rtl/win16/locheaph.inc svneol=native#text/plain
+rtl/win16/prt0c.asm svneol=native#text/plain
+rtl/win16/prt0comn.asm svneol=native#text/plain
+rtl/win16/prt0h.asm svneol=native#text/plain
+rtl/win16/prt0l.asm svneol=native#text/plain
+rtl/win16/prt0m.asm svneol=native#text/plain
+rtl/win16/prt0s.asm svneol=native#text/plain
+rtl/win16/registers.inc svneol=native#text/plain
+rtl/win16/rtldefs.inc svneol=native#text/plain
+rtl/win16/sysdir.inc svneol=native#text/plain
+rtl/win16/sysdl.inc svneol=native#text/plain
+rtl/win16/sysdlh.inc svneol=native#text/plain
+rtl/win16/sysfile.inc svneol=native#text/plain
+rtl/win16/sysheap.inc svneol=native#text/plain
+rtl/win16/sysos.inc svneol=native#text/plain
+rtl/win16/sysosh.inc svneol=native#text/plain
+rtl/win16/system.pp svneol=native#text/plain
+rtl/win16/win31.pp svneol=native#text/plain
+rtl/win16/winprocs.inc svneol=native#text/plain
+rtl/win16/winprocs.pp svneol=native#text/plain
+rtl/win16/winprocsh.inc svneol=native#text/plain
+rtl/win16/wintypes.inc svneol=native#text/plain
+rtl/win16/wintypes.pp svneol=native#text/plain
 rtl/win32/Makefile svneol=native#text/plain
 rtl/win32/Makefile svneol=native#text/plain
 rtl/win32/Makefile.fpc svneol=native#text/plain
 rtl/win32/Makefile.fpc svneol=native#text/plain
 rtl/win32/buildrtl.lpi svneol=native#text/plain
 rtl/win32/buildrtl.lpi svneol=native#text/plain
@@ -10724,8 +10819,10 @@ tests/tbs/tb0609.pp svneol=native#text/plain
 tests/tbs/tb0610.pp svneol=native#text/pascal
 tests/tbs/tb0610.pp svneol=native#text/pascal
 tests/tbs/tb0611.pp svneol=native#text/pascal
 tests/tbs/tb0611.pp svneol=native#text/pascal
 tests/tbs/tb0612.pp svneol=native#text/pascal
 tests/tbs/tb0612.pp svneol=native#text/pascal
+tests/tbs/tb0613.pp svneol=native#text/pascal
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb610.pp svneol=native#text/pascal
 tests/tbs/tb610.pp svneol=native#text/pascal
+tests/tbs/tb613.pp svneol=native#text/plain
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain
@@ -10903,6 +11000,13 @@ tests/test/cg/obj/haiku/i386/tcext3.o -text
 tests/test/cg/obj/haiku/i386/tcext4.o -text
 tests/test/cg/obj/haiku/i386/tcext4.o -text
 tests/test/cg/obj/haiku/i386/tcext5.o -text
 tests/test/cg/obj/haiku/i386/tcext5.o -text
 tests/test/cg/obj/haiku/i386/tcext6.o -text
 tests/test/cg/obj/haiku/i386/tcext6.o -text
+tests/test/cg/obj/linux/aarch64/cpptcl1.o -text
+tests/test/cg/obj/linux/aarch64/cpptcl2.o -text
+tests/test/cg/obj/linux/aarch64/ctest.o -text
+tests/test/cg/obj/linux/aarch64/tcext3.o -text
+tests/test/cg/obj/linux/aarch64/tcext4.o -text
+tests/test/cg/obj/linux/aarch64/tcext5.o -text
+tests/test/cg/obj/linux/aarch64/tcext6.o -text
 tests/test/cg/obj/linux/arm-eabi/cpptcl1.o -text
 tests/test/cg/obj/linux/arm-eabi/cpptcl1.o -text
 tests/test/cg/obj/linux/arm-eabi/cpptcl2.o -text
 tests/test/cg/obj/linux/arm-eabi/cpptcl2.o -text
 tests/test/cg/obj/linux/arm-eabi/ctest.o -text
 tests/test/cg/obj/linux/arm-eabi/ctest.o -text
@@ -10979,6 +11083,7 @@ tests/test/cg/obj/linux/x86_64/tcext4.o -text
 tests/test/cg/obj/linux/x86_64/tcext5.o -text
 tests/test/cg/obj/linux/x86_64/tcext5.o -text
 tests/test/cg/obj/linux/x86_64/tcext6.o -text
 tests/test/cg/obj/linux/x86_64/tcext6.o -text
 tests/test/cg/obj/macos/powerpc/ctest.o -text
 tests/test/cg/obj/macos/powerpc/ctest.o -text
+tests/test/cg/obj/msdos/i8086/ttasm1.obj -text
 tests/test/cg/obj/netbsd/i386/cpptcl1.o -text
 tests/test/cg/obj/netbsd/i386/cpptcl1.o -text
 tests/test/cg/obj/netbsd/i386/cpptcl2.o -text
 tests/test/cg/obj/netbsd/i386/cpptcl2.o -text
 tests/test/cg/obj/netbsd/i386/ctest.o -text
 tests/test/cg/obj/netbsd/i386/ctest.o -text
@@ -11042,6 +11147,7 @@ tests/test/cg/obj/tcext3.c -text
 tests/test/cg/obj/tcext4.c -text
 tests/test/cg/obj/tcext4.c -text
 tests/test/cg/obj/tcext5.c -text
 tests/test/cg/obj/tcext5.c -text
 tests/test/cg/obj/tcext6.c svneol=native#text/plain
 tests/test/cg/obj/tcext6.c svneol=native#text/plain
+tests/test/cg/obj/ttasm1.asm svneol=native#text/plain
 tests/test/cg/obj/win32/i386/cpptcl1.o -text
 tests/test/cg/obj/win32/i386/cpptcl1.o -text
 tests/test/cg/obj/win32/i386/cpptcl2.o -text
 tests/test/cg/obj/win32/i386/cpptcl2.o -text
 tests/test/cg/obj/win32/i386/ctest.o -text
 tests/test/cg/obj/win32/i386/ctest.o -text
@@ -11068,6 +11174,7 @@ tests/test/cg/taddint.pp svneol=native#text/plain
 tests/test/cg/taddlong.pp svneol=native#text/plain
 tests/test/cg/taddlong.pp svneol=native#text/plain
 tests/test/cg/taddr1.pp svneol=native#text/plain
 tests/test/cg/taddr1.pp svneol=native#text/plain
 tests/test/cg/taddr2.pp svneol=native#text/plain
 tests/test/cg/taddr2.pp svneol=native#text/plain
+tests/test/cg/taddr3.pp svneol=native#text/plain
 tests/test/cg/taddreal1.pp svneol=native#text/plain
 tests/test/cg/taddreal1.pp svneol=native#text/plain
 tests/test/cg/taddreal2.pp svneol=native#text/plain
 tests/test/cg/taddreal2.pp svneol=native#text/plain
 tests/test/cg/taddreal3.pp svneol=native#text/plain
 tests/test/cg/taddreal3.pp svneol=native#text/plain
@@ -11374,7 +11481,12 @@ tests/test/cg/variants/tvarol9.pp svneol=native#text/plain
 tests/test/cg/variants/tvarol91.pp svneol=native#text/plain
 tests/test/cg/variants/tvarol91.pp svneol=native#text/plain
 tests/test/cg/variants/tvarol94.pp svneol=native#text/plain
 tests/test/cg/variants/tvarol94.pp svneol=native#text/plain
 tests/test/cg/variants/tvarol96.pp svneol=native#text/plain
 tests/test/cg/variants/tvarol96.pp svneol=native#text/plain
+tests/test/cpu16/i8086/tasmseg1.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tfarcal1.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tfarcal1.pp svneol=native#text/pascal
+tests/test/cpu16/i8086/tfarcal2.pp svneol=native#text/pascal
+tests/test/cpu16/i8086/tfarcal3.pp svneol=native#text/plain
+tests/test/cpu16/i8086/tfarcal4.pp svneol=native#text/plain
+tests/test/cpu16/i8086/tfarjmp2.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tfarptr1.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tfarptr1.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tfarptr2.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tfarptr2.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tfarptr3.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tfarptr3.pp svneol=native#text/pascal
@@ -11389,12 +11501,18 @@ tests/test/cpu16/i8086/thugeptr5.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/thugeptr5a.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/thugeptr5a.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tintr1.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tintr1.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tintr2.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tintr2.pp svneol=native#text/pascal
+tests/test/cpu16/i8086/tlbldat1.pp svneol=native#text/plain
 tests/test/cpu16/i8086/tmmc.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmmc.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmml.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmml.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmmm.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmmm.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmms.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmms.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmmt.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tmmt.pp svneol=native#text/pascal
+tests/test/cpu16/i8086/tprcdat1.pp svneol=native#text/plain
+tests/test/cpu16/i8086/tptrcon.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tptrsize.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/tptrsize.pp svneol=native#text/pascal
+tests/test/cpu16/i8086/tretf1.pp svneol=native#text/plain
+tests/test/cpu16/i8086/tretf2.pp svneol=native#text/plain
+tests/test/cpu16/i8086/ttasm1.pp svneol=native#text/plain
 tests/test/cpu16/i8086/ttheap1.pp svneol=native#text/pascal
 tests/test/cpu16/i8086/ttheap1.pp svneol=native#text/pascal
 tests/test/cpu16/taddint1.pp svneol=native#text/pascal
 tests/test/cpu16/taddint1.pp svneol=native#text/pascal
 tests/test/dumpclass.pp svneol=native#text/plain
 tests/test/dumpclass.pp svneol=native#text/plain
@@ -11426,8 +11544,8 @@ tests/test/jvm/tdynarrnil.pp svneol=native#text/plain
 tests/test/jvm/tenum.pp svneol=native#text/plain
 tests/test/jvm/tenum.pp svneol=native#text/plain
 tests/test/jvm/tenum2.pp svneol=native#text/plain
 tests/test/jvm/tenum2.pp svneol=native#text/plain
 tests/test/jvm/test.pp svneol=native#text/plain
 tests/test/jvm/test.pp svneol=native#text/plain
-tests/test/jvm/testall.bat -text svneol=native#application/x-bat
-tests/test/jvm/testall.sh -text svneol=native#application/x-sh
+tests/test/jvm/testall.bat svneol=native#text/plain
+tests/test/jvm/testall.sh svneol=native#text/plain
 tests/test/jvm/testansi.pp svneol=native#text/plain
 tests/test/jvm/testansi.pp svneol=native#text/plain
 tests/test/jvm/testintf.pp svneol=native#text/plain
 tests/test/jvm/testintf.pp svneol=native#text/plain
 tests/test/jvm/testshort.pp svneol=native#text/plain
 tests/test/jvm/testshort.pp svneol=native#text/plain
@@ -11942,6 +12060,7 @@ tests/test/texception6.pp svneol=native#text/plain
 tests/test/texception7.pp svneol=native#text/plain
 tests/test/texception7.pp svneol=native#text/plain
 tests/test/texception8.pp svneol=native#text/plain
 tests/test/texception8.pp svneol=native#text/plain
 tests/test/texception9.pp svneol=native#text/plain
 tests/test/texception9.pp svneol=native#text/plain
+tests/test/textpas01.pp svneol=native#text/pascal
 tests/test/textthr.pp svneol=native#text/plain
 tests/test/textthr.pp svneol=native#text/plain
 tests/test/tfillchr.pp svneol=native#text/plain
 tests/test/tfillchr.pp svneol=native#text/plain
 tests/test/tfinal1.pp svneol=native#text/pascal
 tests/test/tfinal1.pp svneol=native#text/pascal
@@ -12211,6 +12330,7 @@ tests/test/tinterface3.pp svneol=native#text/plain
 tests/test/tinterface4.pp svneol=native#text/plain
 tests/test/tinterface4.pp svneol=native#text/plain
 tests/test/tinterface5.pp svneol=native#text/plain
 tests/test/tinterface5.pp svneol=native#text/plain
 tests/test/tinterface6.pp svneol=native#text/plain
 tests/test/tinterface6.pp svneol=native#text/plain
+tests/test/tinterlockedmt.pp svneol=native#text/plain
 tests/test/tinterrupt.pp svneol=native#text/plain
 tests/test/tinterrupt.pp svneol=native#text/plain
 tests/test/tintfcdecl1.pp svneol=native#text/plain
 tests/test/tintfcdecl1.pp svneol=native#text/plain
 tests/test/tintfcdecl2.pp svneol=native#text/plain
 tests/test/tintfcdecl2.pp svneol=native#text/plain
@@ -12835,6 +12955,7 @@ tests/test/units/classes/tvclcomobject.pp svneol=native#text/plain
 tests/test/units/cpu/tcpu1.pp svneol=native#text/pascal
 tests/test/units/cpu/tcpu1.pp svneol=native#text/pascal
 tests/test/units/crt/tcrt.pp svneol=native#text/plain
 tests/test/units/crt/tcrt.pp svneol=native#text/plain
 tests/test/units/crt/tctrlc.pp svneol=native#text/plain
 tests/test/units/crt/tctrlc.pp svneol=native#text/plain
+tests/test/units/dateutil/testscandatetime.pas svneol=native#text/plain
 tests/test/units/dos/hello.pp svneol=native#text/plain
 tests/test/units/dos/hello.pp svneol=native#text/plain
 tests/test/units/dos/tbreak.pp svneol=native#text/plain
 tests/test/units/dos/tbreak.pp svneol=native#text/plain
 tests/test/units/dos/tdisk.pp svneol=native#text/plain
 tests/test/units/dos/tdisk.pp svneol=native#text/plain
@@ -14648,6 +14769,7 @@ tests/webtbs/tw2736.pp svneol=native#text/plain
 tests/webtbs/tw2737.pp svneol=native#text/plain
 tests/webtbs/tw2737.pp svneol=native#text/plain
 tests/webtbs/tw2738.pp svneol=native#text/plain
 tests/webtbs/tw2738.pp svneol=native#text/plain
 tests/webtbs/tw2739.pp svneol=native#text/plain
 tests/webtbs/tw2739.pp svneol=native#text/plain
+tests/webtbs/tw27414.pp svneol=native#text/plain
 tests/webtbs/tw27424.pp svneol=native#text/pascal
 tests/webtbs/tw27424.pp svneol=native#text/pascal
 tests/webtbs/tw27515.pp svneol=native#text/pascal
 tests/webtbs/tw27515.pp svneol=native#text/pascal
 tests/webtbs/tw27517.pp svneol=native#text/pascal
 tests/webtbs/tw27517.pp svneol=native#text/pascal
@@ -14706,16 +14828,33 @@ tests/webtbs/tw2853c.pp svneol=native#text/plain
 tests/webtbs/tw2853d.pp svneol=native#text/plain
 tests/webtbs/tw2853d.pp svneol=native#text/plain
 tests/webtbs/tw2853e.pp svneol=native#text/plain
 tests/webtbs/tw2853e.pp svneol=native#text/plain
 tests/webtbs/tw2859.pp svneol=native#text/plain
 tests/webtbs/tw2859.pp svneol=native#text/plain
+tests/webtbs/tw28593.pp svneol=native#text/plain
+tests/webtbs/tw28632.pp -text svneol=native#text/plain
 tests/webtbs/tw2865.pp svneol=native#text/plain
 tests/webtbs/tw2865.pp svneol=native#text/plain
+tests/webtbs/tw28650.pp svneol=native#text/pascal
+tests/webtbs/tw28674.pp svneol=native#text/pascal
+tests/webtbs/tw28718a.pp svneol=native#text/plain
+tests/webtbs/tw28718b.pp svneol=native#text/plain
+tests/webtbs/tw28718c.pp svneol=native#text/plain
+tests/webtbs/tw28718d.pp svneol=native#text/plain
+tests/webtbs/tw28748.pp svneol=native#text/plain
 tests/webtbs/tw2876.pp svneol=native#text/plain
 tests/webtbs/tw2876.pp svneol=native#text/plain
+tests/webtbs/tw28766.pp svneol=native#text/pascal
+tests/webtbs/tw28801.pp svneol=native#text/plain
 tests/webtbs/tw2883.pp svneol=native#text/plain
 tests/webtbs/tw2883.pp svneol=native#text/plain
 tests/webtbs/tw2885.pp svneol=native#text/plain
 tests/webtbs/tw2885.pp svneol=native#text/plain
+tests/webtbs/tw28850.pp svneol=native#text/plain
 tests/webtbs/tw2886.pp svneol=native#text/plain
 tests/webtbs/tw2886.pp svneol=native#text/plain
 tests/webtbs/tw2891.pp svneol=native#text/plain
 tests/webtbs/tw2891.pp svneol=native#text/plain
 tests/webtbs/tw2892.pp svneol=native#text/plain
 tests/webtbs/tw2892.pp svneol=native#text/plain
+tests/webtbs/tw28934.pp svneol=native#text/plain
 tests/webtbs/tw2897.pp svneol=native#text/plain
 tests/webtbs/tw2897.pp svneol=native#text/plain
 tests/webtbs/tw2899.pp svneol=native#text/plain
 tests/webtbs/tw2899.pp svneol=native#text/plain
+tests/webtbs/tw29010a.pp svneol=native#text/plain
+tests/webtbs/tw29010b.pp svneol=native#text/plain
+tests/webtbs/tw29010c.pp svneol=native#text/plain
 tests/webtbs/tw2904.pp svneol=native#text/plain
 tests/webtbs/tw2904.pp svneol=native#text/plain
+tests/webtbs/tw29040.pp svneol=native#text/plain
 tests/webtbs/tw2908.pp svneol=native#text/plain
 tests/webtbs/tw2908.pp svneol=native#text/plain
 tests/webtbs/tw2911.pp svneol=native#text/plain
 tests/webtbs/tw2911.pp svneol=native#text/plain
 tests/webtbs/tw2912.pp svneol=native#text/plain
 tests/webtbs/tw2912.pp svneol=native#text/plain
@@ -15418,6 +15557,7 @@ 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/uw28442.pp svneol=native#text/pascal
+tests/webtbs/uw28766.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
@@ -15576,6 +15716,16 @@ utils/fpdoc/dw_txt.pp svneol=native#text/plain
 utils/fpdoc/dw_xml.pp svneol=native#text/plain
 utils/fpdoc/dw_xml.pp svneol=native#text/plain
 utils/fpdoc/dwlinear.pp svneol=native#text/plain
 utils/fpdoc/dwlinear.pp svneol=native#text/plain
 utils/fpdoc/dwriter.pp svneol=native#text/plain
 utils/fpdoc/dwriter.pp svneol=native#text/plain
+utils/fpdoc/examples/basedir/readme.txt svneol=native#text/plain
+utils/fpdoc/examples/basedir/sample-project.xml svneol=native#text/plain
+utils/fpdoc/examples/gentest.sh svneol=native#text/plain
+utils/fpdoc/examples/project/readme.txt svneol=native#text/plain
+utils/fpdoc/examples/project/sample-project.xml svneol=native#text/plain
+utils/fpdoc/examples/simple/html.bat svneol=native#text/plain
+utils/fpdoc/examples/simple/html.sh svneol=native#text/plain
+utils/fpdoc/examples/simple/readme.txt svneol=native#text/plain
+utils/fpdoc/examples/simple/testunit.pp svneol=native#text/plain
+utils/fpdoc/examples/simple/testunit.xml svneol=native#text/plain
 utils/fpdoc/fpclasschart.lpi svneol=native#text/plain
 utils/fpdoc/fpclasschart.lpi svneol=native#text/plain
 utils/fpdoc/fpclasschart.pp svneol=native#text/plain
 utils/fpdoc/fpclasschart.pp svneol=native#text/plain
 utils/fpdoc/fpde/Makefile svneol=native#text/plain
 utils/fpdoc/fpde/Makefile svneol=native#text/plain
@@ -15617,7 +15767,6 @@ utils/fpdoc/fpdocstripper.lpi svneol=native#text/plain
 utils/fpdoc/fpdocstripper.pp svneol=native#text/plain
 utils/fpdoc/fpdocstripper.pp svneol=native#text/plain
 utils/fpdoc/fpdocxmlopts.pas svneol=native#text/plain
 utils/fpdoc/fpdocxmlopts.pas svneol=native#text/plain
 utils/fpdoc/fpmake.pp svneol=native#text/plain
 utils/fpdoc/fpmake.pp svneol=native#text/plain
-utils/fpdoc/gentest.sh svneol=native#text/plain
 utils/fpdoc/images/minus.png -text svneol=unset#image/png
 utils/fpdoc/images/minus.png -text svneol=unset#image/png
 utils/fpdoc/images/plus.png -text svneol=unset#image/png
 utils/fpdoc/images/plus.png -text svneol=unset#image/png
 utils/fpdoc/intl/Makefile svneol=native#text/plain
 utils/fpdoc/intl/Makefile svneol=native#text/plain
@@ -15638,8 +15787,6 @@ utils/fpdoc/mkfpdocproj.pp svneol=native#text/plain
 utils/fpdoc/plusimage.inc svneol=native#text/plain
 utils/fpdoc/plusimage.inc svneol=native#text/plain
 utils/fpdoc/sample-project.xml svneol=native#text/plain
 utils/fpdoc/sample-project.xml svneol=native#text/plain
 utils/fpdoc/sh_pas.pp svneol=native#text/plain
 utils/fpdoc/sh_pas.pp svneol=native#text/plain
-utils/fpdoc/testunit.pp svneol=native#text/plain
-utils/fpdoc/testunit.xml svneol=native#text/plain
 utils/fpdoc/unitdiff.pp svneol=native#text/plain
 utils/fpdoc/unitdiff.pp svneol=native#text/plain
 utils/fpgmake/fpgmake.pp svneol=native#text/plain
 utils/fpgmake/fpgmake.pp svneol=native#text/plain
 utils/fpgmake/fpmake.cft svneol=native#text/plain
 utils/fpgmake/fpmake.cft svneol=native#text/plain

+ 21 - 4
Makefile

@@ -1,11 +1,11 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-07-28 rev 31240]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-09-05 rev 31523]
 #
 #
 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-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
+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 i8086-win16 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 win16
 OSNeedsComspecToRunBatch = go32v2 watcom
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 FORCE:
 .PHONY: FORCE
 .PHONY: FORCE
@@ -476,7 +476,7 @@ endif
 endif
 endif
 BuildOnlyBaseCPUs=jvm
 BuildOnlyBaseCPUs=jvm
 ifneq ($(wildcard utils),)
 ifneq ($(wildcard utils),)
-NOUTILSTARGETS=embedded gba nds msdos $(BuildOnlyBaseCPUs)
+NOUTILSTARGETS=embedded gba nds msdos win16 $(BuildOnlyBaseCPUs)
 ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
 ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
 ifdef BUILDFULLNATIVE
 ifdef BUILDFULLNATIVE
 UTILS=1
 UTILS=1
@@ -720,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),i8086-win16)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
 endif
@@ -1126,6 +1129,12 @@ ifeq ($(OS_TARGET),embedded)
 EXEEXT=.bin
 EXEEXT=.bin
 SHORTSUFFIX=emb
 SHORTSUFFIX=emb
 endif
 endif
+ifeq ($(OS_TARGET),win16)
+STATICLIBPREFIX=
+STATICLIBEXT=.a
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w16
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -2522,6 +2531,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),i8086-win16)
+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-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1
 TARGET_DIRS_RTL=1

+ 1 - 1
Makefile.fpc

@@ -210,7 +210,7 @@ endif
 BuildOnlyBaseCPUs=jvm
 BuildOnlyBaseCPUs=jvm
 
 
 ifneq ($(wildcard utils),)
 ifneq ($(wildcard utils),)
-NOUTILSTARGETS=embedded gba nds msdos $(BuildOnlyBaseCPUs)
+NOUTILSTARGETS=embedded gba nds msdos win16 $(BuildOnlyBaseCPUs)
 ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
 ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
 ifdef BUILDFULLNATIVE
 ifdef BUILDFULLNATIVE
 UTILS=1
 UTILS=1

+ 36 - 3
compiler/Makefile

@@ -1,11 +1,11 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-07-28 rev 31240]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-09-05 rev 31523]
 #
 #
 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-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
+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 i8086-win16 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 win16
 OSNeedsComspecToRunBatch = go32v2 watcom
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 FORCE:
 .PHONY: FORCE
 .PHONY: FORCE
@@ -556,6 +556,9 @@ endif
 ifeq ($(OS_TARGET),nds)
 ifeq ($(OS_TARGET),nds)
 NoNativeBinaries=1
 NoNativeBinaries=1
 endif
 endif
+ifeq ($(OS_TARGET),win16)
+NoNativeBinaries=1
+endif
 ifeq ($(FULL_TARGET),i386-linux)
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_DIRS+=utils
 override TARGET_DIRS+=utils
 endif
 endif
@@ -793,6 +796,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),i8086-win16)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 override TARGET_DIRS+=utils
 override TARGET_DIRS+=utils
 endif
 endif
@@ -1036,6 +1042,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),i8086-win16)
+override TARGET_PROGRAMS+=pp
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 override TARGET_PROGRAMS+=pp
 override TARGET_PROGRAMS+=pp
 endif
 endif
@@ -1280,6 +1289,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),i8086-win16)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
 endif
@@ -1523,6 +1535,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),i8086-win16)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
 endif
@@ -1766,6 +1781,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_TARGETDIR+=.
 override COMPILER_TARGETDIR+=.
 endif
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 override COMPILER_TARGETDIR+=.
 override COMPILER_TARGETDIR+=.
 endif
 endif
@@ -2009,6 +2027,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),i8086-win16)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
 endif
@@ -2414,6 +2435,12 @@ ifeq ($(OS_TARGET),embedded)
 EXEEXT=.bin
 EXEEXT=.bin
 SHORTSUFFIX=emb
 SHORTSUFFIX=emb
 endif
 endif
+ifeq ($(OS_TARGET),win16)
+STATICLIBPREFIX=
+STATICLIBEXT=.a
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w16
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -2906,6 +2933,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),i8086-win16)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_RTL=1
 endif
 endif
@@ -3790,6 +3820,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),i8086-win16)
+TARGET_DIRS_UTILS=1
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 ifeq ($(FULL_TARGET),aarch64-linux)
 TARGET_DIRS_UTILS=1
 TARGET_DIRS_UTILS=1
 endif
 endif

+ 3 - 0
compiler/Makefile.fpc

@@ -328,6 +328,9 @@ endif
 ifeq ($(OS_TARGET),nds)
 ifeq ($(OS_TARGET),nds)
 NoNativeBinaries=1
 NoNativeBinaries=1
 endif
 endif
+ifeq ($(OS_TARGET),win16)
+NoNativeBinaries=1
+endif
 
 
 [rules]
 [rules]
 #####################################################################
 #####################################################################

+ 21 - 35
compiler/aarch64/agcpugas.pas

@@ -29,7 +29,7 @@ unit agcpugas;
   interface
   interface
 
 
     uses
     uses
-       globtype,
+       globtype,systems,
        aasmtai,
        aasmtai,
        aggas,
        aggas,
        cpubase,cpuinfo;
        cpubase,cpuinfo;
@@ -40,12 +40,11 @@ unit agcpugas;
       end;
       end;
 
 
       TAArch64Assembler=class(TGNUassembler)
       TAArch64Assembler=class(TGNUassembler)
-        constructor create(smart: boolean); override;
+        constructor create(info: pasminfo; smart: boolean); override;
       end;
       end;
 
 
       TAArch64AppleAssembler=class(TAppleGNUassembler)
       TAArch64AppleAssembler=class(TAppleGNUassembler)
-        constructor create(smart: boolean); override;
-        function MakeCmdLine: TCmdStr; override;
+        constructor create(info: pasminfo; smart: boolean); override;
       end;
       end;
 
 
 
 
@@ -65,7 +64,6 @@ unit agcpugas;
 
 
     uses
     uses
        cutils,globals,verbose,
        cutils,globals,verbose,
-       systems,
        assemble,
        assemble,
        aasmcpu,
        aasmcpu,
        itcpugas,
        itcpugas,
@@ -76,9 +74,9 @@ unit agcpugas;
 {                      AArch64 Assembler writer                              }
 {                      AArch64 Assembler writer                              }
 {****************************************************************************}
 {****************************************************************************}
 
 
-    constructor TAArch64Assembler.create(smart: boolean);
+    constructor TAArch64Assembler.create(info: pasminfo; smart: boolean);
       begin
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter := TAArch64InstrWriter.create(self);
         InstrWriter := TAArch64InstrWriter.create(self);
       end;
       end;
 
 
@@ -86,30 +84,18 @@ unit agcpugas;
 {                      Apple AArch64 Assembler writer                        }
 {                      Apple AArch64 Assembler writer                        }
 {****************************************************************************}
 {****************************************************************************}
 
 
-    constructor TAArch64AppleAssembler.create(smart: boolean);
+    constructor TAArch64AppleAssembler.create(info: pasminfo; smart: boolean);
       begin
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter := TAArch64InstrWriter.create(self);
         InstrWriter := TAArch64InstrWriter.create(self);
       end;
       end;
 
 
-    function TAArch64AppleAssembler.MakeCmdLine: TCmdStr;
-      begin
-        { 'as' calls through to clang for aarch64, and that one only supports
-          reading from standard input in case "-" is specified as input file
-          (in which case you also have to specify the language via -x) }
-        result:=inherited;
-{$ifdef hasunix}
-        if DoPipe then
-          result:=result+' -x assembler -'
-{$endif}
-      end;
-
 
 
 {****************************************************************************}
 {****************************************************************************}
 {                  Helper routines for Instruction Writer                    }
 {                  Helper routines for Instruction Writer                    }
 {****************************************************************************}
 {****************************************************************************}
 
 
-    function getreferencestring(var ref : treference) : string;
+    function getreferencestring(asminfo: pasminfo; var ref : treference) : string;
       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');
@@ -130,7 +116,7 @@ unit agcpugas;
                      (ref.shiftmode<>SM_None) or
                      (ref.shiftmode<>SM_None) or
                      (ref.offset<>0) then
                      (ref.offset<>0) then
                     internalerror(2014121501);
                     internalerror(2014121501);
-                  if target_asm.id=as_darwin then
+                  if target_info.system in systems_darwin then
                     result:=ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                     result:=ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                   else
                   else
                     result:=linux_addrpage2str[ref.refaddr]+ref.symbol.name
                     result:=linux_addrpage2str[ref.refaddr]+ref.symbol.name
@@ -172,7 +158,7 @@ unit agcpugas;
                       addr_gotpageoffset,
                       addr_gotpageoffset,
                       addr_pageoffset:
                       addr_pageoffset:
                         begin
                         begin
-                          if target_asm.id=as_darwin then
+                          if target_info.system in systems_darwin then
                             result:=result+', '+ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                             result:=result+', '+ref.symbol.name+darwin_addrpage2str[ref.refaddr]
                           else
                           else
                             result:=result+', '+linux_addrpage2str[ref.refaddr]+ref.symbol.name
                             result:=result+', '+linux_addrpage2str[ref.refaddr]+ref.symbol.name
@@ -200,7 +186,7 @@ unit agcpugas;
       end;
       end;
 
 
 
 
-    function getopstr(hp: taicpu; opnr: longint; const o: toper): string;
+    function getopstr(asminfo: pasminfo; hp: taicpu; opnr: longint; const o: toper): string;
       begin
       begin
         case o.typ of
         case o.typ of
           top_reg:
           top_reg:
@@ -248,7 +234,7 @@ unit agcpugas;
                 getopstr:=o.ref^.symbol.name;
                 getopstr:=o.ref^.symbol.name;
               end
               end
             else
             else
-              getopstr:=getreferencestring(o.ref^);
+              getopstr:=getreferencestring(asminfo,o.ref^);
           else
           else
             internalerror(2014121507);
             internalerror(2014121507);
         end;
         end;
@@ -274,11 +260,11 @@ unit agcpugas;
                  // debug code
                  // debug code
                  // writeln(s);
                  // writeln(s);
                  // writeln(taicpu(hp).fileinfo.line);
                  // writeln(taicpu(hp).fileinfo.line);
-                 s:=s+sep+getopstr(taicpu(hp),i,taicpu(hp).oper[i]^);
+                 s:=s+sep+getopstr(owner.asminfo,taicpu(hp),i,taicpu(hp).oper[i]^);
                  sep:=',';
                  sep:=',';
               end;
               end;
           end;
           end;
-        owner.AsmWriteLn(s);
+        owner.writer.AsmWriteLn(s);
       end;
       end;
 
 
 
 
@@ -296,14 +282,14 @@ unit agcpugas;
             dollarsign: '$';
             dollarsign: '$';
           );
           );
 
 
-       as_aarch64_gas_darwin_info : tasminfo =
+       as_aarch64_clang_darwin_info : tasminfo =
           (
           (
-            id     : as_darwin;
-            idtxt  : 'AS-Darwin';
-            asmbin : 'as';
-            asmcmd : '-o $OBJ $EXTRAOPT $ASM -arch arm64';
+            id     : as_clang;
+            idtxt  : 'CLANG';
+            asmbin : 'clang';
+            asmcmd : '-c -o $OBJ $EXTRAOPT -arch arm64 $DARWINVERSION -x assembler $ASM';
             supported_targets : [system_aarch64_darwin];
             supported_targets : [system_aarch64_darwin];
-            flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_stabs_use_function_absolute_addresses];
+            flags : [af_needar,af_smartlink_sections,af_supports_dwarf];
             labelprefix : 'L';
             labelprefix : 'L';
             comment : '# ';
             comment : '# ';
             dollarsign: '$';
             dollarsign: '$';
@@ -312,5 +298,5 @@ unit agcpugas;
 
 
 begin
 begin
   RegisterAssembler(as_aarch64_gas_info,TAArch64Assembler);
   RegisterAssembler(as_aarch64_gas_info,TAArch64Assembler);
-  RegisterAssembler(as_aarch64_gas_darwin_info,TAArch64AppleAssembler);
+  RegisterAssembler(as_aarch64_clang_darwin_info,TAArch64AppleAssembler);
 end.
 end.

+ 7 - 1
compiler/aarch64/cpuinfo.pas

@@ -48,6 +48,12 @@ Type
      (ct_none
      (ct_none
      );
      );
 
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 
 
 Const
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { Is there support for dealing with multiple microcontrollers available }
@@ -66,7 +72,7 @@ Const
     {$WARN 3177 OFF}
     {$WARN 3177 OFF}
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    (
    (
-      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+      (controllertypestr:''; controllerunitstr:''; cputype:cpu_none; fputype:fpu_none; flashbase:0; flashsize:0; srambase:0; sramsize:0));
    {$POP}
    {$POP}
 
 
    { calling conventions supported by the code generator }
    { calling conventions supported by the code generator }

+ 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:=cpointerdef.getreusable(hp.vardef);
+                hp.paraloc[side].def:=cpointerdef.getreusable_no_free(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:=cpointerdef.getreusable(paradef);
+            paradef:=cpointerdef.getreusable_no_free(paradef);
             loc:=LOC_REGISTER;
             loc:=LOC_REGISTER;
             paracgsize:=OS_ADDR;
             paracgsize:=OS_ADDR;
             paralen:=tcgsize2size[OS_ADDR];
             paralen:=tcgsize2size[OS_ADDR];

+ 263 - 9
compiler/aasmcnst.pas

@@ -29,7 +29,7 @@ interface
 uses
 uses
   cclasses,globtype,constexp,
   cclasses,globtype,constexp,
   aasmbase,aasmdata,aasmtai,
   aasmbase,aasmdata,aasmtai,
-  symconst,symtype,symdef,symsym;
+  symconst,symbase,symtype,symdef,symsym;
 
 
 type
 type
    { typed const: integer/floating point/string/pointer/... const along with
    { typed const: integer/floating point/string/pointer/... const along with
@@ -92,6 +92,7 @@ type
      procedure addvalue(val: tai_abstracttypedconst);
      procedure addvalue(val: tai_abstracttypedconst);
      function valuecount: longint;
      function valuecount: longint;
      procedure insertvaluebeforepos(val: tai_abstracttypedconst; pos: longint);
      procedure insertvaluebeforepos(val: tai_abstracttypedconst; pos: longint);
+     function replacevalueatpos(val: tai_abstracttypedconst; pos: longint): tai_abstracttypedconst;
      procedure finish;
      procedure finish;
      destructor destroy; override;
      destructor destroy; override;
    end;
    end;
@@ -112,7 +113,17 @@ type
      { this symbol is the start of a block of data that should be
      { this symbol is the start of a block of data that should be
        dead-stripable/smartlinkable; may imply starting a new section, but
        dead-stripable/smartlinkable; may imply starting a new section, but
        not necessarily (depends on what the platform requirements are) }
        not necessarily (depends on what the platform requirements are) }
-     tcalo_make_dead_strippable
+     tcalo_make_dead_strippable,
+     { this symbol should never be removed by the linker }
+     tcalo_no_dead_strip,
+     { start of a vectorized but individually dead strippable list of elements,
+       like the resource strings of a unit: they have to stay in this order,
+       but individual elements can be removed }
+     tcalo_vectorized_dead_strip_start,
+     { item in the above list }
+     tcalo_vectorized_dead_strip_item,
+     { end of the above list }
+     tcalo_vectorized_dead_strip_end
    );
    );
    ttcasmlistoptions = set of ttcasmlistoption;
    ttcasmlistoptions = set of ttcasmlistoption;
 
 
@@ -168,6 +179,14 @@ type
    end;
    end;
    taggregateinformationclass = class of taggregateinformation;
    taggregateinformationclass = class of taggregateinformation;
 
 
+   { information about a placeholder element that has been added, and which has
+     to be replaced later with a real data element }
+   ttypedconstplaceholder = class abstract
+     def: tdef;
+     constructor create(d: tdef);
+     procedure replace(ai: tai; d: tdef); virtual; abstract;
+   end;
+
    { Warning: never directly create a ttai_typedconstbuilder instance,
    { Warning: never directly create a ttai_typedconstbuilder instance,
      instead create a cai_typedconstbuilder (this class can be overridden) }
      instead create a cai_typedconstbuilder (this class can be overridden) }
    ttai_typedconstbuilder = class abstract
    ttai_typedconstbuilder = class abstract
@@ -220,12 +239,17 @@ type
 
 
      { ensure that finalize_asmlist is called only once }
      { ensure that finalize_asmlist is called only once }
      fasmlist_finalized: boolean;
      fasmlist_finalized: boolean;
+     { ensure that if it's vectorized dead strippable data, we called
+       finalize_vectorized_dead_strip_asmlist instead of finalize_asmlist }
+     fvectorized_finalize_called: boolean;
 
 
      { returns whether def must be handled as an aggregate on the current
      { returns whether def must be handled as an aggregate on the current
        platform }
        platform }
      function aggregate_kind(def: tdef): ttypedconstkind; virtual;
      function aggregate_kind(def: tdef): ttypedconstkind; virtual;
      { finalize the asmlist: add the necessary symbols etc }
      { finalize the asmlist: add the necessary symbols etc }
      procedure finalize_asmlist(sym: tasmsymbol; def: tdef; section: TAsmSectiontype; const secname: TSymStr; alignment: shortint; const options: ttcasmlistoptions); virtual;
      procedure finalize_asmlist(sym: tasmsymbol; def: tdef; section: TAsmSectiontype; const secname: TSymStr; alignment: shortint; const options: ttcasmlistoptions); virtual;
+     { functionality of the above for vectorized dead strippable sections }
+     procedure finalize_vectorized_dead_strip_asmlist(def: tdef; const basename, itemname: TSymStr; st: tsymtable; alignment: shortint; options: ttcasmlistoptions); virtual;
 
 
      { called by the public emit_tai() routines to actually add the typed
      { called by the public emit_tai() routines to actually add the typed
        constant data; the public ones also take care of adding extra padding
        constant data; the public ones also take care of adding extra padding
@@ -284,7 +308,14 @@ type
        the anonymous record, and insert the alignment once it's finished }
        the anonymous record, and insert the alignment once it's finished }
      procedure mark_anon_aggregate_alignment; virtual; abstract;
      procedure mark_anon_aggregate_alignment; virtual; abstract;
      procedure insert_marked_aggregate_alignment(def: tdef); virtual; abstract;
      procedure insert_marked_aggregate_alignment(def: tdef); virtual; abstract;
+     class function get_vectorized_dead_strip_section_symbol(const basename: string; st: tsymtable; define, start: boolean): tasmsymbol; virtual;
     public
     public
+     class function get_vectorized_dead_strip_custom_section_name(const basename: TSymStr; st: tsymtable; out secname: TSymStr): boolean; virtual;
+     { get the start/end symbol for a dead stripable vectorized section, such
+       as the resourcestring data of a unit }
+     class function get_vectorized_dead_strip_section_symbol_start(const basename: string; st: tsymtable; define: boolean): tasmsymbol; virtual;
+     class function get_vectorized_dead_strip_section_symbol_end(const basename: string; st: tsymtable; define: boolean): tasmsymbol; virtual;
+
      class function get_dynstring_rec_name(typ: tstringtype; winlike: boolean; len: asizeint): string;
      class function get_dynstring_rec_name(typ: tstringtype; winlike: boolean; len: asizeint): string;
      { the datalist parameter specifies where the data for the string constant
      { the datalist parameter specifies where the data for the string constant
        will be emitted (via an internal data builder) }
        will be emitted (via an internal data builder) }
@@ -327,6 +358,16 @@ type
      function begin_anonymous_record(const optionalname: string; packrecords, recordalign, 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;
 
 
+     { add a placeholder element at the current position that later can be
+       filled in with the actual data (via ttypedconstplaceholder.replace)
+
+       useful in case you have table preceded by the number of elements, and
+       you cound the elements while building the table }
+     function emit_placeholder(def: tdef): ttypedconstplaceholder; virtual; abstract;
+     { common code to check whether a placeholder can be added at the current
+       position }
+     procedure check_add_placeholder(def: tdef);
+
      { The next group of routines are for constructing complex expressions.
      { The next group of routines are for constructing complex expressions.
        While parsing a typed constant these operators are encountered from
        While parsing a typed constant these operators are encountered from
        outer to inner, so that is also the order in which they should be
        outer to inner, so that is also the order in which they should be
@@ -368,6 +409,7 @@ type
        contents to another list first. This property should only be accessed
        contents to another list first. This property should only be accessed
        once all data has been added. }
        once all data has been added. }
      function get_final_asmlist(sym: tasmsymbol; def: tdef; section: TAsmSectiontype; const secname: TSymStr; alignment: longint): tasmlist;
      function get_final_asmlist(sym: tasmsymbol; def: tdef; section: TAsmSectiontype; const secname: TSymStr; alignment: longint): tasmlist;
+     function get_final_asmlist_vectorized_dead_strip(def: tdef; const basename, itemname: TSymStr; st: TSymtable; alignment: longint): tasmlist;
 
 
      { returns the offset of the string data relative to ansi/unicode/widestring
      { returns the offset of the string data relative to ansi/unicode/widestring
        constant labels. On most platforms, this is 0 (with the header at a
        constant labels. On most platforms, this is 0 (with the header at a
@@ -397,13 +439,22 @@ type
      property anonrecmarker: tai read fanonrecmarker write fanonrecmarker;
      property anonrecmarker: tai read fanonrecmarker write fanonrecmarker;
    end;
    end;
 
 
+   tlowleveltypedconstplaceholder = class(ttypedconstplaceholder)
+     list: tasmlist;
+     insertpos: tai;
+     constructor create(l: tasmlist; pos: tai; d: tdef);
+     procedure replace(ai: tai; d: tdef); override;
+   end;
+
    ttai_lowleveltypedconstbuilder = class(ttai_typedconstbuilder)
    ttai_lowleveltypedconstbuilder = class(ttai_typedconstbuilder)
     protected
     protected
      procedure mark_anon_aggregate_alignment; override;
      procedure mark_anon_aggregate_alignment; override;
      procedure insert_marked_aggregate_alignment(def: tdef); override;
      procedure insert_marked_aggregate_alignment(def: tdef); override;
+     procedure finalize_asmlist(sym: tasmsymbol; def: tdef; section: TAsmSectiontype; const secname: TSymStr; alignment: shortint; const options: ttcasmlistoptions); override;
     public
     public
      { set the default value for caggregateinformation (= tlowlevelaggregateinformation) }
      { set the default value for caggregateinformation (= tlowlevelaggregateinformation) }
      class constructor classcreate;
      class constructor classcreate;
+     function emit_placeholder(def: tdef): ttypedconstplaceholder; override;
    end;
    end;
 
 
    var
    var
@@ -414,7 +465,7 @@ implementation
    uses
    uses
      verbose,globals,systems,widestr,
      verbose,globals,systems,widestr,
      fmodule,
      fmodule,
-     symbase,symtable,defutil;
+     symtable,defutil;
 
 
 {****************************************************************************
 {****************************************************************************
                        taggregateinformation
                        taggregateinformation
@@ -508,6 +559,15 @@ implementation
       end;
       end;
 
 
 
 
+{****************************************************************************
+                             ttypedconstplaceholder
+ ****************************************************************************}
+
+    constructor ttypedconstplaceholder.create(d: tdef);
+      begin
+        def:=d;
+      end;
+
 {****************************************************************************
 {****************************************************************************
                             tai_abstracttypedconst
                             tai_abstracttypedconst
  ****************************************************************************}
  ****************************************************************************}
@@ -685,6 +745,13 @@ implementation
      end;
      end;
 
 
 
 
+   function tai_aggregatetypedconst.replacevalueatpos(val: tai_abstracttypedconst; pos: longint): tai_abstracttypedconst;
+     begin
+       result:=tai_abstracttypedconst(fvalues[pos]);
+       fvalues[pos]:=val;
+     end;
+
+
    procedure tai_aggregatetypedconst.finish;
    procedure tai_aggregatetypedconst.finish;
      begin
      begin
        if fisstring then
        if fisstring then
@@ -819,22 +886,45 @@ implementation
           { in case of syntax errors, the aggregate may not have been finished }
           { in case of syntax errors, the aggregate may not have been finished }
           (ErrorCount=0) then
           (ErrorCount=0) then
          internalerror(2015072301);
          internalerror(2015072301);
+
+       { must call finalize_vectorized_dead_strip_asmlist() instead }
+       if (([tcalo_vectorized_dead_strip_start,
+             tcalo_vectorized_dead_strip_item,
+             tcalo_vectorized_dead_strip_end]*options)<>[]) and
+          not fvectorized_finalize_called then
+         internalerror(2015110602);
+
        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 }
-       if tcalo_make_dead_strippable in options then
+
+       { both in case the data should be dead strippable and never dead
+         stripped, it should be in a separate section (so this property doesn't
+         affect other data) }
+       if ([tcalo_no_dead_strip,tcalo_make_dead_strippable]*options)<>[] then
          begin
          begin
            maybe_new_object_file(prelist);
            maybe_new_object_file(prelist);
            { we always need a new section here, since if we started a new
            { we always need a new section here, since if we started a new
              object file then we have to say what the section is, and otherwise
              object file then we have to say what the section is, and otherwise
-             we need a new section because that's how the dead stripping works
-             (except on Darwin, but that will be addressed in a future commit) }
+             we need a new section because that's how the dead stripping works }
            new_section(prelist,section,secname,const_align(alignment));
            new_section(prelist,section,secname,const_align(alignment));
          end
          end
        else if tcalo_new_section in options then
        else if tcalo_new_section in options then
          new_section(prelist,section,secname,const_align(alignment))
          new_section(prelist,section,secname,const_align(alignment))
        else
        else
          prelist.concat(cai_align.Create(const_align(alignment)));
          prelist.concat(cai_align.Create(const_align(alignment)));
+
+       { On Darwin, use .reference to ensure the data doesn't get dead stripped.
+         On other platforms, the data must be in the .fpc section (which is
+         kept via the linker script) }
+       if tcalo_no_dead_strip in options then
+         begin
+           if target_info.system in systems_darwin then
+             prelist.concat(tai_directive.Create(asd_reference,sym.name))
+           else if section<>sec_fpc then
+             internalerror(2015101402);
+         end;
+
        if not(tcalo_is_lab in options) then
        if not(tcalo_is_lab in options) then
          if sym.bind=AB_GLOBAL then
          if sym.bind=AB_GLOBAL then
            prelist.concat(tai_symbol.Create_Global(sym,0))
            prelist.concat(tai_symbol.Create_Global(sym,0))
@@ -851,6 +941,48 @@ implementation
      end;
      end;
 
 
 
 
+   procedure ttai_typedconstbuilder.finalize_vectorized_dead_strip_asmlist(def: tdef; const basename, itemname: TSymStr; st: tsymtable; alignment: shortint; options: ttcasmlistoptions);
+     var
+       sym: tasmsymbol;
+       secname: TSymStr;
+       sectype: TAsmSectiontype;
+       customsecname: boolean;
+     begin
+       fvectorized_finalize_called:=true;
+       customsecname:=get_vectorized_dead_strip_custom_section_name(basename,st,secname);
+       if customsecname then
+         sectype:=sec_user
+       else
+         sectype:=sec_data;
+       if tcalo_vectorized_dead_strip_start in options then
+         begin
+           { the start and end names are predefined }
+           if itemname<>'' then
+             internalerror(2015110801);
+           sym:=get_vectorized_dead_strip_section_symbol_start(basename,st,true);
+           if not customsecname then
+             secname:=make_mangledname(basename,st,'1_START');
+         end
+       else if tcalo_vectorized_dead_strip_end in options then
+         begin
+           { the start and end names are predefined }
+           if itemname<>'' then
+             internalerror(2015110802);
+           sym:=get_vectorized_dead_strip_section_symbol_end(basename,st,true);
+           if not customsecname then
+             make_mangledname(basename,st,'3_END');
+         end
+       else if tcalo_vectorized_dead_strip_item in options then
+         begin
+           sym:=current_asmdata.DefineAsmSymbol(make_mangledname(basename,st,itemname),AB_GLOBAL,AT_DATA);
+           if not customsecname then
+             secname:=make_mangledname(basename,st,'2_'+itemname);
+           exclude(options,tcalo_vectorized_dead_strip_item);
+         end;
+       finalize_asmlist(sym,def,sectype,secname,alignment,options);
+     end;
+
+
    procedure ttai_typedconstbuilder.do_emit_tai(p: tai; def: tdef);
    procedure ttai_typedconstbuilder.do_emit_tai(p: tai; def: tdef);
      begin
      begin
        { by default we don't care about the type }
        { by default we don't care about the type }
@@ -869,6 +1001,17 @@ implementation
      end;
      end;
 
 
 
 
+   function ttai_typedconstbuilder.get_final_asmlist_vectorized_dead_strip(def: tdef; const basename, itemname: TSymStr; st: TSymtable; alignment: longint): tasmlist;
+     begin
+       if not fasmlist_finalized then
+         begin
+           finalize_vectorized_dead_strip_asmlist(def,basename,itemname,st,alignment,foptions);
+           fasmlist_finalized:=true;
+         end;
+       result:=fasmlist;
+     end;
+
+
    class function ttai_typedconstbuilder.get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint;
    class function ttai_typedconstbuilder.get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint;
      begin
      begin
        { darwin's linker does not support negative offsets }
        { darwin's linker does not support negative offsets }
@@ -1196,6 +1339,33 @@ implementation
      end;
      end;
 
 
 
 
+   class function ttai_typedconstbuilder.get_vectorized_dead_strip_section_symbol(const basename: string; st: tsymtable; define, start: boolean): tasmsymbol;
+     begin
+       if start then
+         result:=current_asmdata.DefineAsmSymbol(make_mangledname(basename,st,'START'),AB_GLOBAL,AT_DATA)
+       else
+         result:=current_asmdata.DefineAsmSymbol(make_mangledname(basename,st,'END'),AB_GLOBAL,AT_DATA);
+     end;
+
+
+   class function ttai_typedconstbuilder.get_vectorized_dead_strip_custom_section_name(const basename: TSymStr; st: tsymtable; out secname: TSymStr): boolean;
+     begin
+       result:=false;
+     end;
+
+
+   class function ttai_typedconstbuilder.get_vectorized_dead_strip_section_symbol_start(const basename: string; st: tsymtable; define: boolean): tasmsymbol;
+     begin
+       result:=get_vectorized_dead_strip_section_symbol(basename,st,define,true);
+     end;
+
+
+   class function ttai_typedconstbuilder.get_vectorized_dead_strip_section_symbol_end(const basename: string; st: tsymtable; define: boolean): tasmsymbol;
+     begin
+       result:=get_vectorized_dead_strip_section_symbol(basename,st,define,false);
+     end;
+
+
    class function ttai_typedconstbuilder.get_dynstring_rec_name(typ: tstringtype; winlike: boolean; len: asizeint): string;
    class function ttai_typedconstbuilder.get_dynstring_rec_name(typ: tstringtype; winlike: boolean; len: asizeint): string;
      begin
      begin
        case typ of
        case typ of
@@ -1245,7 +1415,6 @@ implementation
        string_symofs: asizeint;
        string_symofs: asizeint;
        startlab: tasmlabel;
        startlab: tasmlabel;
        datadef: tdef;
        datadef: tdef;
-       uniwidestrrecdef: trecorddef;
        datatcb: ttai_typedconstbuilder;
        datatcb: ttai_typedconstbuilder;
      begin
      begin
        start_internal_data_builder(datalist,sec_rodata_norel,'',datatcb,startlab);
        start_internal_data_builder(datalist,sec_rodata_norel,'',datatcb,startlab);
@@ -1286,7 +1455,7 @@ implementation
            { ending #0 }
            { ending #0 }
            datatcb.emit_tai(Tai_const.Create_16bit(0),cwidechartype);
            datatcb.emit_tai(Tai_const.Create_16bit(0),cwidechartype);
            datatcb.maybe_end_aggregate(datadef);
            datatcb.maybe_end_aggregate(datadef);
-           uniwidestrrecdef:=datatcb.end_anonymous_record;
+           datatcb.end_anonymous_record;
          end
          end
        else
        else
          { code generation for other sizes must be written }
          { code generation for other sizes must be written }
@@ -1430,6 +1599,22 @@ implementation
      end;
      end;
 
 
 
 
+   procedure ttai_typedconstbuilder.check_add_placeholder(def: tdef);
+     begin
+       { it only makes sense to add a placeholder inside an aggregate
+         (otherwise there can be but one element)
+
+         we cannot add a placeholder in the middle of a queued expression
+         either
+
+         the placeholder cannot be an aggregate }
+       if not assigned(curagginfo) or
+          queue_is_active or
+          (aggregate_kind(def)<>tck_simple) then
+         internalerror(2015091001);
+     end;
+
+
    procedure ttai_typedconstbuilder.queue_init(todef: tdef);
    procedure ttai_typedconstbuilder.queue_init(todef: tdef);
      var
      var
        info: taggregateinformation;
        info: taggregateinformation;
@@ -1564,13 +1749,32 @@ implementation
 
 
 
 
    procedure ttai_typedconstbuilder.queue_emit_const(cs: tconstsym);
    procedure ttai_typedconstbuilder.queue_emit_const(cs: tconstsym);
+     var
+       resourcestrrec: trecorddef;
      begin
      begin
        if cs.consttyp<>constresourcestring then
        if cs.consttyp<>constresourcestring then
          internalerror(2014062102);
          internalerror(2014062102);
        if fqueue_offset<>0 then
        if fqueue_offset<>0 then
          internalerror(2014062103);
          internalerror(2014062103);
        { warning: update if/when the type of resource strings changes }
        { warning: update if/when the type of resource strings changes }
-       emit_tai(Tai_const.Createname(make_mangledname('RESSTR',cs.owner,cs.name),AT_DATA,sizeof(pint)),cansistringtype);
+       case cs.consttyp of
+         constresourcestring:
+           begin
+             resourcestrrec:=trecorddef(search_system_type('TRESOURCESTRINGRECORD').typedef);
+             queue_subscriptn_multiple_by_name(resourcestrrec,['CURRENTVALUE']);
+             queue_emit_asmsym(current_asmdata.RefAsmSymbol(
+               make_mangledname('RESSTR',cs.owner,cs.name),AT_DATA),cansistringtype
+             );
+           end;
+         { can these occur? }
+         constord,
+         conststring,constreal,
+         constset,constpointer,constnil,
+         constwstring,constguid:
+           internalerror(2015090903);
+         else
+           internalerror(2015090904);
+       end;
        fqueue_offset:=low(fqueue_offset);
        fqueue_offset:=low(fqueue_offset);
      end;
      end;
 
 
@@ -1598,6 +1802,28 @@ implementation
      end;
      end;
 
 
 
 
+   {****************************************************************************
+                         tlowleveltypedconstplaceholder
+   ****************************************************************************}
+
+   constructor tlowleveltypedconstplaceholder.create(l: tasmlist; pos: tai; d: tdef);
+     begin
+       inherited create(d);
+       list:=l;
+       insertpos:=pos;
+     end;
+
+
+   procedure tlowleveltypedconstplaceholder.replace(ai: tai; d: tdef);
+     begin
+       if d<>def then
+         internalerror(2015091001);
+       list.insertafter(ai,insertpos);
+       list.remove(insertpos);
+       insertpos.free;
+     end;
+
+
 {****************************************************************************
 {****************************************************************************
                            tai_abstracttypedconst
                            tai_abstracttypedconst
  ****************************************************************************}
  ****************************************************************************}
@@ -1608,6 +1834,17 @@ implementation
      end;
      end;
 
 
 
 
+   function ttai_lowleveltypedconstbuilder.emit_placeholder(def: tdef): ttypedconstplaceholder;
+     var
+       p: tai;
+     begin
+       check_add_placeholder(def);
+       p:=tai_marker.Create(mark_position);
+       emit_tai(p,def);
+       result:=tlowleveltypedconstplaceholder.create(fasmlist,p,def);
+     end;
+
+
    procedure ttai_lowleveltypedconstbuilder.mark_anon_aggregate_alignment;
    procedure ttai_lowleveltypedconstbuilder.mark_anon_aggregate_alignment;
      var
      var
        marker: tai_marker;
        marker: tai_marker;
@@ -1637,6 +1874,23 @@ implementation
        info.anonrecmarker:=nil;
        info.anonrecmarker:=nil;
      end;
      end;
 
 
+   procedure ttai_lowleveltypedconstbuilder.finalize_asmlist(sym: tasmsymbol; def: tdef; section: TAsmSectiontype; const secname: TSymStr; alignment: shortint; const options: ttcasmlistoptions);
+     begin
+       inherited;
+       { The darwin/ppc64 assembler or linker seems to have trouble       }
+       { if a section ends with a global label without any data after it. }
+       { So for safety, just put a dummy value here.                      }
+       { Further, the regular linker also kills this symbol when turning  }
+       { on smart linking in case no value appears after it, so put the   }
+       { dummy byte there always                                          }
+       { Update: the Mac OS X 10.6 linker orders data that needs to be    }
+       { relocated before all other data, so make this data relocatable,  }
+       { otherwise the end label won't be moved with the rest             }
+       if (tcalo_vectorized_dead_strip_end in options) and
+          (target_info.system in (systems_darwin+systems_aix)) then
+         fasmlist.concat(Tai_const.create_sym(sym));
+     end;
+
 
 
 
 
 begin
 begin

+ 3 - 0
compiler/aasmdata.pas

@@ -46,6 +46,8 @@ interface
       TAsmListType=(
       TAsmListType=(
         al_start,
         al_start,
         al_stabs,
         al_stabs,
+        { pure assembler routines }
+        al_pure_assembler,
         al_procedures,
         al_procedures,
         al_globals,
         al_globals,
         al_const,
         al_const,
@@ -97,6 +99,7 @@ interface
       AsmListTypeStr : array[TAsmListType] of string[24] =(
       AsmListTypeStr : array[TAsmListType] of string[24] =(
         'al_begin',
         'al_begin',
         'al_stabs',
         'al_stabs',
+        'al_pure_assembler',
         'al_procedures',
         'al_procedures',
         'al_globals',
         'al_globals',
         'al_const',
         'al_const',

+ 29 - 0
compiler/aasmtai.pas

@@ -135,6 +135,17 @@ interface
           aitconst_farptr,
           aitconst_farptr,
           { i8086 segment of symbol; emits: 'DW SEG symbol' }
           { i8086 segment of symbol; emits: 'DW SEG symbol' }
           aitconst_seg,
           aitconst_seg,
+          { i8086 data segment group; emits: 'DW dgroup'
+            generated by the this inline asm:
+              DW SEG @DATA
+            in all memory models, except huge }
+          aitconst_dgroup,
+          { i8086 far data segment of the current pascal module (unit or program);
+            emits: 'DW CURRENTMODULENAME_DATA'
+            generated by the this inline asm:
+              DW SEG @DATA
+            in the huge memory model }
+          aitconst_fardataseg,
           { offset of symbol's GOT slot in GOT }
           { offset of symbol's GOT slot in GOT }
           aitconst_got,
           aitconst_got,
           { offset of symbol itself from GOT }
           { offset of symbol itself from GOT }
@@ -620,6 +631,8 @@ interface
           constructor Create_int_dataptr(_value: int64);
           constructor Create_int_dataptr(_value: int64);
 {$ifdef i8086}
 {$ifdef i8086}
           constructor Create_seg_name(const name:string);
           constructor Create_seg_name(const name:string);
+          constructor Create_dgroup;
+          constructor Create_fardataseg;
 {$endif i8086}
 {$endif i8086}
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -1817,6 +1830,20 @@ implementation
         self.Createname(name,0);
         self.Createname(name,0);
         self.consttype:=aitconst_seg;
         self.consttype:=aitconst_seg;
       end;
       end;
+
+
+    constructor tai_const.Create_dgroup;
+      begin
+        self.Create_16bit(0);
+        self.consttype:=aitconst_dgroup;
+      end;
+
+
+    constructor tai_const.Create_fardataseg;
+      begin
+        self.Create_16bit(0);
+        self.consttype:=aitconst_fardataseg;
+      end;
 {$endif i8086}
 {$endif i8086}
 
 
 
 
@@ -1884,6 +1911,8 @@ implementation
             result:=2;
             result:=2;
           aitconst_farptr:
           aitconst_farptr:
             result:=4;
             result:=4;
+          aitconst_dgroup,
+          aitconst_fardataseg,
           aitconst_seg:
           aitconst_seg:
             result:=2;
             result:=2;
           aitconst_got:
           aitconst_got:

File diff suppressed because it is too large
+ 232 - 229
compiler/aggas.pas


+ 1 - 3
compiler/aopt.pas

@@ -331,7 +331,7 @@ Unit aopt;
 
 
     procedure TAsmScheduler.SchedulerPass1;
     procedure TAsmScheduler.SchedulerPass1;
       var
       var
-        p,hp1,hp2 : tai;
+        p : tai;
       begin
       begin
         p:=BlockStart;
         p:=BlockStart;
         while p<>BlockEnd Do
         while p<>BlockEnd Do
@@ -346,9 +346,7 @@ Unit aopt;
     procedure TAsmScheduler.Optimize;
     procedure TAsmScheduler.Optimize;
       Var
       Var
         HP: tai;
         HP: tai;
-        pass: longint;
       Begin
       Begin
-        pass:=0;
         BlockStart := tai(AsmL.First);
         BlockStart := tai(AsmL.First);
         While Assigned(BlockStart) Do
         While Assigned(BlockStart) Do
           Begin
           Begin

+ 30 - 10
compiler/aoptobj.pas

@@ -859,8 +859,6 @@ Unit AoptObj;
 
 
 
 
       procedure TAOptObj.UpdateUsedRegs(p : Tai);
       procedure TAOptObj.UpdateUsedRegs(p : Tai);
-        var
-          i : TRegisterType;
         begin
         begin
           { this code is based on TUsedRegs.Update to avoid multiple passes through the asmlist,
           { this code is based on TUsedRegs.Update to avoid multiple passes through the asmlist,
             the code is duplicated here }
             the code is duplicated here }
@@ -1176,7 +1174,9 @@ Unit AoptObj;
       end;
       end;
 {$pop}
 {$pop}
 
 
-    function IsJumpToLabel(hp: taicpu): boolean;
+
+    { Returns True if hp is an unconditional jump to a label }
+    function IsJumpToLabelUncond(hp: taicpu): boolean;
       begin
       begin
 {$if defined(avr)}
 {$if defined(avr)}
         result:=(hp.opcode in aopt_uncondjmp) and
         result:=(hp.opcode in aopt_uncondjmp) and
@@ -1192,6 +1192,16 @@ Unit AoptObj;
       end;
       end;
 
 
 
 
+    { Returns True if hp is any jump to a label }
+    function IsJumpToLabel(hp: taicpu): boolean;
+      begin
+        result:=hp.is_jmp and
+          (hp.ops>0) and
+          (JumpTargetOp(hp)^.typ = top_ref) and
+          (JumpTargetOp(hp)^.ref^.symbol is TAsmLabel);
+      end;
+
+
     procedure TAOptObj.RemoveDelaySlot(hp1:tai);
     procedure TAOptObj.RemoveDelaySlot(hp1:tai);
       var
       var
         hp2: tai;
         hp2: tai;
@@ -1223,8 +1233,11 @@ Unit AoptObj;
        the level parameter denotes how deeep we have already followed the jump,
        the level parameter denotes how deeep we have already followed the jump,
        to avoid endless loops with constructs such as "l5: ; jmp l5"           }
        to avoid endless loops with constructs such as "l5: ; jmp l5"           }
 
 
-      var p1, p2: tai;
+      var p1: tai;
+          {$if not defined(MIPS) and not defined(JVM)}
+          p2: tai;
           l: tasmlabel;
           l: tasmlabel;
+          {$endif}
 
 
       begin
       begin
         GetfinalDestination := false;
         GetfinalDestination := false;
@@ -1238,7 +1251,7 @@ Unit AoptObj;
                (taicpu(p1).is_jmp) then
                (taicpu(p1).is_jmp) then
               if { the next instruction after the label where the jump hp arrives}
               if { the next instruction after the label where the jump hp arrives}
                  { is unconditional or of the same type as hp, so continue       }
                  { is unconditional or of the same type as hp, so continue       }
-                 IsJumpToLabel(taicpu(p1))
+                 IsJumpToLabelUncond(taicpu(p1))
 {$if not defined(MIPS) and not defined(JVM)}
 {$if not defined(MIPS) and not defined(JVM)}
 { for MIPS, it isn't enough to check the condition; first operands must be same, too. }
 { for MIPS, it isn't enough to check the condition; first operands must be same, too. }
                  or
                  or
@@ -1253,7 +1266,7 @@ Unit AoptObj;
                   SkipLabels(p1,p2) and
                   SkipLabels(p1,p2) and
                   (p2.typ = ait_instruction) and
                   (p2.typ = ait_instruction) and
                   (taicpu(p2).is_jmp) and
                   (taicpu(p2).is_jmp) and
-                   (IsJumpToLabel(taicpu(p2)) or
+                   (IsJumpToLabelUncond(taicpu(p2)) or
                    (conditions_equal(taicpu(p2).condition,hp.condition))) and
                    (conditions_equal(taicpu(p2).condition,hp.condition))) and
                   SkipLabels(p1,p1))
                   SkipLabels(p1,p1))
 {$endif not MIPS and not JVM}
 {$endif not MIPS and not JVM}
@@ -1353,7 +1366,7 @@ Unit AoptObj;
                         { the following if-block removes all code between a jmp and the next label,
                         { the following if-block removes all code between a jmp and the next label,
                           because it can never be executed
                           because it can never be executed
                         }
                         }
-                        if IsJumpToLabel(taicpu(p)) then
+                        if IsJumpToLabelUncond(taicpu(p)) then
                           begin
                           begin
                             hp2:=p;
                             hp2:=p;
                             while GetNextInstruction(hp2, hp1) and
                             while GetNextInstruction(hp2, hp1) and
@@ -1386,11 +1399,11 @@ Unit AoptObj;
                                 end
                                 end
                               else break;
                               else break;
                             end;
                             end;
-                        { remove jumps to a label coming right after them }
                         if GetNextInstruction(p, hp1) then
                         if GetNextInstruction(p, hp1) then
                           begin
                           begin
                             SkipEntryExitMarker(hp1,hp1);
                             SkipEntryExitMarker(hp1,hp1);
-                            if IsJumpToLabel(taicpu(p)) and
+                            { remove unconditional jumps to a label coming right after them }
+                            if IsJumpToLabelUncond(taicpu(p)) and
                               FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp1) and
                               FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp1) and
           { TODO: FIXME removing the first instruction fails}
           { TODO: FIXME removing the first instruction fails}
                                 (p<>blockstart) then
                                 (p<>blockstart) then
@@ -1408,10 +1421,17 @@ Unit AoptObj;
                               end
                               end
                             else if assigned(hp1) then
                             else if assigned(hp1) then
                               begin
                               begin
+                                { change the following jumps:
+                                    jmp<cond> lab_1         jmp<cond_inverted> lab_2
+                                    jmp       lab_2  >>>    <code>
+                                  lab_1:                  lab_2:
+                                    <code>
+                                  lab_2:
+                                }
                                 if hp1.typ = ait_label then
                                 if hp1.typ = ait_label then
                                   SkipLabels(hp1,hp1);
                                   SkipLabels(hp1,hp1);
                                 if (tai(hp1).typ=ait_instruction) and
                                 if (tai(hp1).typ=ait_instruction) and
-                                  IsJumpToLabel(taicpu(hp1)) and
+                                  IsJumpToLabelUncond(taicpu(hp1)) and
                                   GetNextInstruction(hp1, hp2) and
                                   GetNextInstruction(hp1, hp2) and
                                   IsJumpToLabel(taicpu(p)) and
                                   IsJumpToLabel(taicpu(p)) and
                                   FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp2) then
                                   FindLabel(tasmlabel(JumpTargetOp(taicpu(p))^.ref^.symbol), hp2) then

+ 171 - 85
compiler/arm/aasmcpu.pas

@@ -715,91 +715,178 @@ implementation
 
 
     function taicpu.spilling_get_operation_type(opnr: longint): topertype;
     function taicpu.spilling_get_operation_type(opnr: longint): topertype;
       begin
       begin
-        case opcode of
-          A_ADC,A_ADD,A_AND,A_BIC,
-          A_EOR,A_CLZ,A_RBIT,
-          A_LDR,A_LDRB,A_LDRBT,A_LDRH,A_LDRSB,
-          A_LDRSH,A_LDRT,
-          A_MOV,A_MVN,A_MLA,A_MUL,
-          A_ORR,A_RSB,A_RSC,A_SBC,A_SUB,
-          A_SWP,A_SWPB,
-          A_LDF,A_FLT,A_FIX,
-          A_ADF,A_DVF,A_FDV,A_FML,
-          A_RFS,A_RFC,A_RDF,
-          A_RMF,A_RPW,A_RSF,A_SUF,A_ABS,A_ACS,A_ASN,A_ATN,A_COS,
-          A_EXP,A_LOG,A_LGN,A_MVF,A_MNF,A_FRD,A_MUF,A_POL,A_RND,A_SIN,A_SQT,A_TAN,
-          A_LFM,
-          A_FLDS,A_FLDD,
-          A_FMRX,A_FMXR,A_FMSTAT,
-          A_FMSR,A_FMRS,A_FMDRR,
-          A_FCPYS,A_FCPYD,A_FCVTSD,A_FCVTDS,
-          A_FABSS,A_FABSD,A_FSQRTS,A_FSQRTD,A_FMULS,A_FMULD,
-          A_FADDS,A_FADDD,A_FSUBS,A_FSUBD,A_FDIVS,A_FDIVD,
-          A_FMACS,A_FMACD,A_FMSCS,A_FMSCD,A_FNMACS,A_FNMACD,
-          A_FNMSCS,A_FNMSCD,A_FNMULS,A_FNMULD,
-          A_FMDHR,A_FMRDH,A_FMDLR,A_FMRDL,
-          A_FNEGS,A_FNEGD,
-          A_FSITOS,A_FSITOD,A_FTOSIS,A_FTOSID,
-          A_FTOUIS,A_FTOUID,A_FUITOS,A_FUITOD,
-          A_SXTB16,A_UXTB16,
-          A_UXTB,A_UXTH,A_SXTB,A_SXTH,
-          A_NEG,
-          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
-              result:=operand_write
-            else
-              result:=operand_read;
-          A_BKPT,A_B,A_BL,A_BLX,A_BX,
-          A_CMN,A_CMP,A_TEQ,A_TST,
-          A_CMF,A_CMFE,A_WFS,A_CNF,
-          A_FCMPS,A_FCMPD,A_FCMPES,A_FCMPED,A_FCMPEZS,A_FCMPEZD,
-          A_FCMPZS,A_FCMPZD,
-          A_VCMP,A_VCMPE:
-            result:=operand_read;
-          A_SMLAL,A_UMLAL:
-            if opnr in [0,1] then
-              result:=operand_readwrite
-            else
-              result:=operand_read;
-           A_SMULL,A_UMULL,
-           A_FMRRD:
-            if opnr in [0,1] then
-              result:=operand_write
-            else
-              result:=operand_read;
-          A_STR,A_STRB,A_STRBT,
-          A_STRH,A_STRT,A_STF,A_SFM,
-          A_FSTS,A_FSTD,
-          A_VSTR:
-            { important is what happens with the involved registers }
-            if opnr=0 then
-              result := operand_read
-            else
-              { check for pre/post indexed }
-              result := operand_read;
-          //Thumb2
-          A_LSL, A_LSR, A_ROR, A_ASR, A_SDIV, A_UDIV, A_MOVW, A_MOVT, A_MLS, A_BFI,
-          A_SMMLA,A_SMMLS:
-            if opnr in [0] then
-              result:=operand_write
-            else
+        if GenerateThumbCode then
+          case opcode of
+            A_ADC,A_ADD,A_AND,A_BIC,
+            A_EOR,A_CLZ,A_RBIT,
+            A_LDR,A_LDRB,A_LDRBT,A_LDRH,A_LDRSB,
+            A_LDRSH,A_LDRT,
+            A_MOV,A_MVN,A_MLA,A_MUL,
+            A_ORR,A_RSB,A_RSC,A_SBC,A_SUB,
+            A_SWP,A_SWPB,
+            A_LDF,A_FLT,A_FIX,
+            A_ADF,A_DVF,A_FDV,A_FML,
+            A_RFS,A_RFC,A_RDF,
+            A_RMF,A_RPW,A_RSF,A_SUF,A_ABS,A_ACS,A_ASN,A_ATN,A_COS,
+            A_EXP,A_LOG,A_LGN,A_MVF,A_MNF,A_FRD,A_MUF,A_POL,A_RND,A_SIN,A_SQT,A_TAN,
+            A_LFM,
+            A_FLDS,A_FLDD,
+            A_FMRX,A_FMXR,A_FMSTAT,
+            A_FMSR,A_FMRS,A_FMDRR,
+            A_FCPYS,A_FCPYD,A_FCVTSD,A_FCVTDS,
+            A_FABSS,A_FABSD,A_FSQRTS,A_FSQRTD,A_FMULS,A_FMULD,
+            A_FADDS,A_FADDD,A_FSUBS,A_FSUBD,A_FDIVS,A_FDIVD,
+            A_FMACS,A_FMACD,A_FMSCS,A_FMSCD,A_FNMACS,A_FNMACD,
+            A_FNMSCS,A_FNMSCD,A_FNMULS,A_FNMULD,
+            A_FMDHR,A_FMRDH,A_FMDLR,A_FMRDL,
+            A_FNEGS,A_FNEGD,
+            A_FSITOS,A_FSITOD,A_FTOSIS,A_FTOSID,
+            A_FTOUIS,A_FTOUID,A_FUITOS,A_FUITOD,
+            A_SXTB16,A_UXTB16,
+            A_UXTB,A_UXTH,A_SXTB,A_SXTH,
+            A_NEG,
+            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
+                result:=operand_readwrite
+              else
+                result:=operand_read;
+            A_BKPT,A_B,A_BL,A_BLX,A_BX,
+            A_CMN,A_CMP,A_TEQ,A_TST,
+            A_CMF,A_CMFE,A_WFS,A_CNF,
+            A_FCMPS,A_FCMPD,A_FCMPES,A_FCMPED,A_FCMPEZS,A_FCMPEZD,
+            A_FCMPZS,A_FCMPZD,
+            A_VCMP,A_VCMPE:
               result:=operand_read;
               result:=operand_read;
-          A_BFC:
-            if opnr in [0] then
-              result:=operand_readwrite
+            A_SMLAL,A_UMLAL:
+              if opnr in [0,1] then
+                result:=operand_readwrite
+              else
+                result:=operand_read;
+             A_SMULL,A_UMULL,
+             A_FMRRD:
+              if opnr in [0,1] then
+                result:=operand_readwrite
+              else
+                result:=operand_read;
+            A_STR,A_STRB,A_STRBT,
+            A_STRH,A_STRT,A_STF,A_SFM,
+            A_FSTS,A_FSTD,
+            A_VSTR:
+              { important is what happens with the involved registers }
+              if opnr=0 then
+                result := operand_read
+              else
+                { check for pre/post indexed }
+                result := operand_read;
+            //Thumb2
+            A_LSL, A_LSR, A_ROR, A_ASR, A_SDIV, A_UDIV, A_MOVW, A_MOVT, A_MLS, A_BFI,
+            A_SMMLA,A_SMMLS:
+              if opnr in [0] then
+                result:=operand_readwrite
+              else
+                result:=operand_read;
+            A_BFC:
+              if opnr in [0] then
+                result:=operand_readwrite
+              else
+                result:=operand_read;
+            A_LDREX:
+              if opnr in [0] then
+                result:=operand_readwrite
+              else
+                result:=operand_read;
+            A_STREX:
+              result:=operand_write;
             else
             else
+              internalerror(200403151);
+          end
+        else
+          case opcode of
+            A_ADC,A_ADD,A_AND,A_BIC,
+            A_EOR,A_CLZ,A_RBIT,
+            A_LDR,A_LDRB,A_LDRBT,A_LDRH,A_LDRSB,
+            A_LDRSH,A_LDRT,
+            A_MOV,A_MVN,A_MLA,A_MUL,
+            A_ORR,A_RSB,A_RSC,A_SBC,A_SUB,
+            A_SWP,A_SWPB,
+            A_LDF,A_FLT,A_FIX,
+            A_ADF,A_DVF,A_FDV,A_FML,
+            A_RFS,A_RFC,A_RDF,
+            A_RMF,A_RPW,A_RSF,A_SUF,A_ABS,A_ACS,A_ASN,A_ATN,A_COS,
+            A_EXP,A_LOG,A_LGN,A_MVF,A_MNF,A_FRD,A_MUF,A_POL,A_RND,A_SIN,A_SQT,A_TAN,
+            A_LFM,
+            A_FLDS,A_FLDD,
+            A_FMRX,A_FMXR,A_FMSTAT,
+            A_FMSR,A_FMRS,A_FMDRR,
+            A_FCPYS,A_FCPYD,A_FCVTSD,A_FCVTDS,
+            A_FABSS,A_FABSD,A_FSQRTS,A_FSQRTD,A_FMULS,A_FMULD,
+            A_FADDS,A_FADDD,A_FSUBS,A_FSUBD,A_FDIVS,A_FDIVD,
+            A_FMACS,A_FMACD,A_FMSCS,A_FMSCD,A_FNMACS,A_FNMACD,
+            A_FNMSCS,A_FNMSCD,A_FNMULS,A_FNMULD,
+            A_FMDHR,A_FMRDH,A_FMDLR,A_FMRDL,
+            A_FNEGS,A_FNEGD,
+            A_FSITOS,A_FSITOD,A_FTOSIS,A_FTOSID,
+            A_FTOUIS,A_FTOUID,A_FUITOS,A_FUITOD,
+            A_SXTB16,A_UXTB16,
+            A_UXTB,A_UXTH,A_SXTB,A_SXTH,
+            A_NEG,
+            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
+                result:=operand_write
+              else
+                result:=operand_read;
+            A_BKPT,A_B,A_BL,A_BLX,A_BX,
+            A_CMN,A_CMP,A_TEQ,A_TST,
+            A_CMF,A_CMFE,A_WFS,A_CNF,
+            A_FCMPS,A_FCMPD,A_FCMPES,A_FCMPED,A_FCMPEZS,A_FCMPEZD,
+            A_FCMPZS,A_FCMPZD,
+            A_VCMP,A_VCMPE:
               result:=operand_read;
               result:=operand_read;
-          A_LDREX:
-            if opnr in [0] then
-              result:=operand_write
+            A_SMLAL,A_UMLAL:
+              if opnr in [0,1] then
+                result:=operand_readwrite
+              else
+                result:=operand_read;
+             A_SMULL,A_UMULL,
+             A_FMRRD:
+              if opnr in [0,1] then
+                result:=operand_write
+              else
+                result:=operand_read;
+            A_STR,A_STRB,A_STRBT,
+            A_STRH,A_STRT,A_STF,A_SFM,
+            A_FSTS,A_FSTD,
+            A_VSTR:
+              { important is what happens with the involved registers }
+              if opnr=0 then
+                result := operand_read
+              else
+                { check for pre/post indexed }
+                result := operand_read;
+            //Thumb2
+            A_LSL, A_LSR, A_ROR, A_ASR, A_SDIV, A_UDIV, A_MOVW, A_MOVT, A_MLS, A_BFI,
+            A_SMMLA,A_SMMLS:
+              if opnr in [0] then
+                result:=operand_write
+              else
+                result:=operand_read;
+            A_BFC:
+              if opnr in [0] then
+                result:=operand_readwrite
+              else
+                result:=operand_read;
+            A_LDREX:
+              if opnr in [0] then
+                result:=operand_write
+              else
+                result:=operand_read;
+            A_STREX:
+              result:=operand_write;
             else
             else
-              result:=operand_read;
-          A_STREX:
-            result:=operand_write;
-          else
-            internalerror(200403151);
-        end;
+              internalerror(200403151);
+          end;
       end;
       end;
 
 
 
 
@@ -920,7 +1007,9 @@ implementation
                (tai(hp).typ=ait_instruction) and
                (tai(hp).typ=ait_instruction) and
                ((taicpu(hp).opcode=A_FLDS) or
                ((taicpu(hp).opcode=A_FLDS) or
                 (taicpu(hp).opcode=A_FLDD) or
                 (taicpu(hp).opcode=A_FLDD) or
-                (taicpu(hp).opcode=A_VLDR)) then
+                (taicpu(hp).opcode=A_VLDR) or
+                (taicpu(hp).opcode=A_LDF) or
+                (taicpu(hp).opcode=A_STF)) then
               limit:=254;
               limit:=254;
         end;
         end;
 
 
@@ -943,12 +1032,10 @@ implementation
         penalty,
         penalty,
         lastinspos,
         lastinspos,
         { increased for every data element > 4 bytes inserted }
         { increased for every data element > 4 bytes inserted }
-        currentsize,
         extradataoffset,
         extradataoffset,
         curop : longint;
         curop : longint;
         curtai,
         curtai,
         inserttai : tai;
         inserttai : tai;
-        ai_label : tai_label;
         curdatatai,hp,hp2 : tai;
         curdatatai,hp,hp2 : tai;
         curdata : TAsmList;
         curdata : TAsmList;
         l : tasmlabel;
         l : tasmlabel;
@@ -1320,7 +1407,6 @@ implementation
     procedure ensurethumbencodings(list: TAsmList);
     procedure ensurethumbencodings(list: TAsmList);
       var
       var
         curtai: tai;
         curtai: tai;
-        op2reg: TRegister;
       begin
       begin
         { Do Thumb 16bit transformations to form valid instruction forms }
         { Do Thumb 16bit transformations to form valid instruction forms }
         curtai:=tai(list.first);
         curtai:=tai(list.first);

+ 44 - 14
compiler/arm/agarmgas.pas

@@ -29,24 +29,27 @@ unit agarmgas;
   interface
   interface
 
 
     uses
     uses
-       globtype,
+       globtype,systems,
        aasmtai,
        aasmtai,
        aggas,
        aggas,
        cpubase,cpuinfo;
        cpubase,cpuinfo;
 
 
     type
     type
       TARMGNUAssembler=class(TGNUassembler)
       TARMGNUAssembler=class(TGNUassembler)
-        constructor create(smart: boolean); override;
+        constructor create(info: pasminfo; smart: boolean); override;
         function MakeCmdLine: TCmdStr; override;
         function MakeCmdLine: TCmdStr; override;
         procedure WriteExtraHeader; override;
         procedure WriteExtraHeader; override;
       end;
       end;
 
 
       TArmInstrWriter=class(TCPUInstrWriter)
       TArmInstrWriter=class(TCPUInstrWriter)
+        unified_syntax: boolean;
+
         procedure WriteInstruction(hp : tai);override;
         procedure WriteInstruction(hp : tai);override;
       end;
       end;
 
 
       TArmAppleGNUAssembler=class(TAppleGNUassembler)
       TArmAppleGNUAssembler=class(TAppleGNUassembler)
-        constructor create(smart: boolean); override;
+        constructor create(info: pasminfo; smart: boolean); override;
+        procedure WriteExtraHeader; override;
       end;
       end;
 
 
 
 
@@ -79,7 +82,6 @@ unit agarmgas;
 
 
     uses
     uses
        cutils,globals,verbose,
        cutils,globals,verbose,
-       systems,
        assemble,
        assemble,
        aasmcpu,
        aasmcpu,
        itcpugas,
        itcpugas,
@@ -89,10 +91,12 @@ unit agarmgas;
 {                         GNU Arm Assembler writer                           }
 {                         GNU Arm Assembler writer                           }
 {****************************************************************************}
 {****************************************************************************}
 
 
-    constructor TArmGNUAssembler.create(smart: boolean);
+    constructor TArmGNUAssembler.create(info: pasminfo; smart: boolean);
       begin
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter := TArmInstrWriter.create(self);
         InstrWriter := TArmInstrWriter.create(self);
+        if GenerateThumb2Code then
+          TArmInstrWriter(InstrWriter).unified_syntax:=true;
       end;
       end;
 
 
 
 
@@ -127,18 +131,27 @@ unit agarmgas;
     procedure TArmGNUAssembler.WriteExtraHeader;
     procedure TArmGNUAssembler.WriteExtraHeader;
       begin
       begin
         inherited WriteExtraHeader;
         inherited WriteExtraHeader;
-        if GenerateThumb2Code then
-          AsmWriteLn(#9'.syntax unified');
+        if TArmInstrWriter(InstrWriter).unified_syntax then
+          writer.AsmWriteLn(#9'.syntax unified');
       end;
       end;
 
 
 {****************************************************************************}
 {****************************************************************************}
 {                      GNU/Apple ARM Assembler writer                        }
 {                      GNU/Apple ARM Assembler writer                        }
 {****************************************************************************}
 {****************************************************************************}
 
 
-    constructor TArmAppleGNUAssembler.create(smart: boolean);
+    constructor TArmAppleGNUAssembler.create(info: pasminfo; smart: boolean);
       begin
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter := TArmInstrWriter.create(self);
         InstrWriter := TArmInstrWriter.create(self);
+        TArmInstrWriter(InstrWriter).unified_syntax:=true;
+      end;
+
+
+    procedure TArmAppleGNUAssembler.WriteExtraHeader;
+      begin
+        inherited WriteExtraHeader;
+        if TArmInstrWriter(InstrWriter).unified_syntax then
+          writer.AsmWriteLn(#9'.syntax unified');
       end;
       end;
 
 
 
 
@@ -320,12 +333,14 @@ unit agarmgas;
         sep: string[3];
         sep: string[3];
     begin
     begin
       op:=taicpu(hp).opcode;
       op:=taicpu(hp).opcode;
+      postfix:='';
       if GenerateThumb2Code then
       if GenerateThumb2Code then
         begin
         begin
-          postfix:='';
           if taicpu(hp).wideformat then
           if taicpu(hp).wideformat then
             postfix:='.w';
             postfix:='.w';
-
+        end;
+      if unified_syntax then
+        begin
           if taicpu(hp).ops = 0 then
           if taicpu(hp).ops = 0 then
             s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix]
             s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix]
           else if taicpu(hp).oppostfix in [PF_8..PF_U32F64] then
           else if taicpu(hp).oppostfix in [PF_8..PF_U32F64] then
@@ -376,7 +391,7 @@ unit agarmgas;
                sep:=',';
                sep:=',';
             end;
             end;
         end;
         end;
-      owner.AsmWriteLn(s);
+      owner.writer.AsmWriteLn(s);
     end;
     end;
 
 
 
 
@@ -399,7 +414,7 @@ unit agarmgas;
        as_arm_gas_darwin_info : tasminfo =
        as_arm_gas_darwin_info : tasminfo =
           (
           (
             id     : as_darwin;
             id     : as_darwin;
-            idtxt  : 'AS-Darwin';
+            idtxt  : 'AS-DARWIN';
             asmbin : 'as';
             asmbin : 'as';
             asmcmd : '-o $OBJ $EXTRAOPT $ASM -arch $ARCH';
             asmcmd : '-o $OBJ $EXTRAOPT $ASM -arch $ARCH';
             supported_targets : [system_arm_darwin];
             supported_targets : [system_arm_darwin];
@@ -410,7 +425,22 @@ unit agarmgas;
           );
           );
 
 
 
 
+       as_arm_clang_darwin_info : tasminfo =
+          (
+            id     : as_clang;
+            idtxt  : 'CLANG';
+            asmbin : 'clang';
+            asmcmd : '-c -o $OBJ $EXTRAOPT -arch $ARCH $DARWINVERSION -x assembler $ASM';
+            supported_targets : [system_arm_darwin];
+            flags : [af_needar,af_smartlink_sections,af_supports_dwarf];
+            labelprefix : 'L';
+            comment : '# ';
+            dollarsign: '$';
+          );
+
+
 begin
 begin
   RegisterAssembler(as_arm_gas_info,TARMGNUAssembler);
   RegisterAssembler(as_arm_gas_info,TARMGNUAssembler);
   RegisterAssembler(as_arm_gas_darwin_info,TArmAppleGNUAssembler);
   RegisterAssembler(as_arm_gas_darwin_info,TArmAppleGNUAssembler);
+  RegisterAssembler(as_arm_clang_darwin_info,TArmAppleGNUAssembler);
 end.
 end.

+ 9 - 9
compiler/arm/aoptcpu.pas

@@ -2500,13 +2500,16 @@ Implementation
               hp3:=tai(p.Previous);
               hp3:=tai(p.Previous);
               hp5:=tai(p.next);
               hp5:=tai(p.next);
               asml.Remove(p);
               asml.Remove(p);
-              { if there is a reg. dealloc instruction associated with p, move it together with p }
+              { if there is a reg. dealloc instruction or address labels (e.g. for GOT-less PIC)
+                associated with p, move it together with p }
 
 
               { before the instruction? }
               { before the instruction? }
               while assigned(hp3) and (hp3.typ<>ait_instruction) do
               while assigned(hp3) and (hp3.typ<>ait_instruction) do
                 begin
                 begin
-                  if (hp3.typ=ait_regalloc) and (tai_regalloc(hp3).ratype in [ra_dealloc]) and
-                    RegInInstruction(tai_regalloc(hp3).reg,p) then
+                  if ( (hp3.typ=ait_regalloc) and (tai_regalloc(hp3).ratype in [ra_dealloc]) and
+                    RegInInstruction(tai_regalloc(hp3).reg,p) )
+                    or ( (hp3.typ=ait_label) and (tai_label(hp3).labsym.typ=AT_ADDR) )
+                  then
                     begin
                     begin
                       hp4:=hp3;
                       hp4:=hp3;
                       hp3:=tai(hp3.Previous);
                       hp3:=tai(hp3.Previous);
@@ -2552,7 +2555,7 @@ Implementation
 {$endif DEBUG_PREREGSCHEDULER}
 {$endif DEBUG_PREREGSCHEDULER}
               asml.InsertBefore(hp1,insertpos);
               asml.InsertBefore(hp1,insertpos);
               asml.InsertListBefore(insertpos,list);
               asml.InsertListBefore(insertpos,list);
-              p:=tai(p.next)
+              p:=tai(p.next);
             end
             end
           else if p.typ=ait_instruction then
           else if p.typ=ait_instruction then
             p:=hp1
             p:=hp1
@@ -2629,8 +2632,7 @@ Implementation
   function TCpuThumb2AsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
   function TCpuThumb2AsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
     var
     var
       hp : taicpu;
       hp : taicpu;
-      hp1,hp2 : tai;
-      oldreg : TRegister;
+      //hp1,hp2 : tai;
     begin
     begin
       result:=false;
       result:=false;
       if inherited PeepHoleOptPass1Cpu(p) then
       if inherited PeepHoleOptPass1Cpu(p) then
@@ -2757,10 +2759,8 @@ Implementation
   procedure TCpuThumb2AsmOptimizer.PeepHoleOptPass2;
   procedure TCpuThumb2AsmOptimizer.PeepHoleOptPass2;
     var
     var
       p,hp1,hp2: tai;
       p,hp1,hp2: tai;
-      l,l2 : longint;
+      l : longint;
       condition : tasmcond;
       condition : tasmcond;
-      hp3: tai;
-      WasLast: boolean;
       { UsedRegs, TmpUsedRegs: TRegSet; }
       { UsedRegs, TmpUsedRegs: TRegSet; }
 
 
     begin
     begin

+ 128 - 51
compiler/arm/cgcpu.pas

@@ -378,7 +378,14 @@ unit cgcpu;
            else
            else
              InternalError(200308297);
              InternalError(200308297);
          end;
          end;
-         if (ref.alignment in [1,2]) and (ref.alignment<tcgsize2size[fromsize]) then
+
+         if (fromsize=OS_S8) and
+            (not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
+           oppostfix:=PF_B;
+
+         if ((ref.alignment in [1,2]) and (ref.alignment<tcgsize2size[fromsize])) or
+            ((not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) and
+             (oppostfix in [PF_SH,PF_H])) then
            begin
            begin
              if target_info.endian=endian_big then
              if target_info.endian=endian_big then
                dir:=-1
                dir:=-1
@@ -479,7 +486,10 @@ unit cgcpu;
          else
          else
            handle_load_store(list,A_LDR,oppostfix,reg,ref);
            handle_load_store(list,A_LDR,oppostfix,reg,ref);
 
 
-         if (fromsize=OS_S8) and (tosize = OS_16) then
+         if (fromsize=OS_S8) and
+            (not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
+           a_load_reg_reg(list,OS_S8,OS_32,reg,reg)
+         else if (fromsize=OS_S8) and (tosize = OS_16) then
            a_load_reg_reg(list,OS_16,OS_32,reg,reg);
            a_load_reg_reg(list,OS_16,OS_32,reg,reg);
        end;
        end;
 
 
@@ -651,7 +661,6 @@ unit cgcpu;
         if (tf_pic_uses_got in target_info.flags) and
         if (tf_pic_uses_got in target_info.flags) and
            (cs_create_pic in current_settings.moduleswitches) then
            (cs_create_pic in current_settings.moduleswitches) then
           begin
           begin
-            include(current_procinfo.flags,pi_needs_got);
             r.refaddr:=addr_pic
             r.refaddr:=addr_pic
           end
           end
         else
         else
@@ -1116,7 +1125,8 @@ unit cgcpu;
           OP_IMUL,
           OP_IMUL,
           OP_MUL:
           OP_MUL:
             begin
             begin
-              if cgsetflags or setflags then
+              if (cgsetflags or setflags) and
+                 (CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) then
                 begin
                 begin
                   overflowreg:=getintregister(list,size);
                   overflowreg:=getintregister(list,size);
                   if op=OP_IMUL then
                   if op=OP_IMUL then
@@ -1184,28 +1194,39 @@ unit cgcpu;
     var
     var
       asmop: tasmop;
       asmop: tasmop;
     begin
     begin
-      list.concat(tai_comment.create(strpnew('tcgarm.a_mul_reg_reg_pair called')));
-      case size of
-        OS_32:  asmop:=A_UMULL;
-        OS_S32: asmop:=A_SMULL;
-        else
-          InternalError(2014060802);
-      end;
-      { The caller might omit dstlo or dsthi, when he is not interested in it, we still
-        need valid registers everywhere. In case of dsthi = NR_NO we could fall back to
-        32x32=32 bit multiplication}
-      if (dstlo = NR_NO) then
-        dstlo:=getintregister(list,size);
-      if (dsthi = NR_NO) then
-        dsthi:=getintregister(list,size);
-      list.concat(taicpu.op_reg_reg_reg_reg(asmop, dstlo, dsthi, src1,src2));
+      if CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype] then
+        begin
+          list.concat(tai_comment.create(strpnew('tcgarm.a_mul_reg_reg_pair called')));
+          case size of
+            OS_32:  asmop:=A_UMULL;
+            OS_S32: asmop:=A_SMULL;
+            else
+              InternalError(2014060802);
+          end;
+          { The caller might omit dstlo or dsthi, when he is not interested in it, we still
+            need valid registers everywhere. In case of dsthi = NR_NO we could fall back to
+            32x32=32 bit multiplication}
+          if (dstlo = NR_NO) then
+            dstlo:=getintregister(list,size);
+          if (dsthi = NR_NO) then
+            dsthi:=getintregister(list,size);
+          list.concat(taicpu.op_reg_reg_reg_reg(asmop, dstlo, dsthi, src1,src2));
+        end
+      else if dsthi=NR_NO then
+        begin
+          if (dstlo = NR_NO) then
+            dstlo:=getintregister(list,size);
+          list.concat(taicpu.op_reg_reg_reg(A_MUL, dstlo, src1,src2));
+        end
+      else
+        begin
+          internalerror(2015083022);
+        end;
     end;
     end;
 
 
     function tbasecgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
     function tbasecgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
       var
       var
         tmpreg1,tmpreg2 : tregister;
         tmpreg1,tmpreg2 : tregister;
-        tmpref : treference;
-        l : tasmlabel;
       begin
       begin
         tmpreg1:=NR_NO;
         tmpreg1:=NR_NO;
 
 
@@ -1373,7 +1394,10 @@ unit cgcpu;
            else
            else
              InternalError(200308299);
              InternalError(200308299);
          end;
          end;
-         if (ref.alignment in [1,2]) and (ref.alignment<tcgsize2size[tosize]) then
+
+         if ((ref.alignment in [1,2]) and (ref.alignment<tcgsize2size[tosize])) or
+            ((not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) and
+             (oppostfix =PF_H)) then
            begin
            begin
              if target_info.endian=endian_big then
              if target_info.endian=endian_big then
                dir:=-1
                dir:=-1
@@ -1432,6 +1456,8 @@ unit cgcpu;
      function tbasecgarm.a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
      function tbasecgarm.a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
        var
        var
          oppostfix:toppostfix;
          oppostfix:toppostfix;
+         href: treference;
+         tmpreg: TRegister;
        begin
        begin
          case ToSize of
          case ToSize of
            { signed integer registers }
            { signed integer registers }
@@ -1447,13 +1473,31 @@ unit cgcpu;
            else
            else
              InternalError(2003082910);
              InternalError(2003082910);
          end;
          end;
-         result:=handle_load_store(list,A_STR,oppostfix,reg,ref);
+
+         if (tosize in [OS_S16,OS_16]) and
+            (not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
+           begin
+             result:=handle_load_store(list,A_STR,PF_B,reg,ref);
+
+             tmpreg:=getintregister(list,OS_INT);
+             a_op_const_reg_reg(list,OP_SHR,OS_INT,8,reg,tmpreg);
+
+             href:=result;
+             inc(href.offset);
+
+             handle_load_store(list,A_STR,PF_B,tmpreg,href);
+           end
+         else
+           result:=handle_load_store(list,A_STR,oppostfix,reg,ref);
        end;
        end;
 
 
 
 
      function tbasecgarm.a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
      function tbasecgarm.a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
        var
        var
          oppostfix:toppostfix;
          oppostfix:toppostfix;
+         so: tshifterop;
+         tmpreg: TRegister;
+         href: treference;
        begin
        begin
          case FromSize of
          case FromSize of
            { signed integer registers }
            { signed integer registers }
@@ -1471,7 +1515,33 @@ unit cgcpu;
            else
            else
              InternalError(200308291);
              InternalError(200308291);
          end;
          end;
-         result:=handle_load_store(list,A_LDR,oppostfix,reg,ref);
+
+         if (tosize=OS_S8) and
+            (not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
+           begin
+             result:=handle_load_store(list,A_LDR,PF_B,reg,ref);
+             a_load_reg_reg(list,OS_S8,OS_32,reg,reg);
+           end
+         else if (tosize in [OS_S16,OS_16]) and
+            (not (CPUARM_HAS_ALL_MEM in cpu_capabilities[current_settings.cputype])) then
+           begin
+             result:=handle_load_store(list,A_LDR,PF_B,reg,ref);
+
+             tmpreg:=getintregister(list,OS_INT);
+
+             href:=result;
+             inc(href.offset);
+
+             handle_load_store(list,A_LDR,PF_B,tmpreg,href);
+
+             shifterop_reset(so);
+             so.shiftmode:=SM_LSL;
+             so.shiftimm:=8;
+
+             list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,reg,reg,tmpreg,so));
+           end
+         else
+           result:=handle_load_store(list,A_LDR,oppostfix,reg,ref);
        end;
        end;
 
 
      procedure tbasecgarm.a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);
      procedure tbasecgarm.a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);
@@ -1818,7 +1888,6 @@ unit cgcpu;
          registerarea,
          registerarea,
          r7offset,
          r7offset,
          stackmisalignment : pint;
          stackmisalignment : pint;
-         postfix: toppostfix;
          imm1, imm2: DWord;
          imm1, imm2: DWord;
          stack_parameters : Boolean;
          stack_parameters : Boolean;
       begin
       begin
@@ -2056,7 +2125,6 @@ unit cgcpu;
          registerarea,
          registerarea,
          stackmisalignment: pint;
          stackmisalignment: pint;
          paddingreg: TSuperRegister;
          paddingreg: TSuperRegister;
-         mmpostfix: toppostfix;
          imm1, imm2: DWord;
          imm1, imm2: DWord;
       begin
       begin
         if not(nostackframe) then
         if not(nostackframe) then
@@ -2261,22 +2329,43 @@ unit cgcpu;
       var
       var
         ref : treference;
         ref : treference;
         l : TAsmLabel;
         l : TAsmLabel;
+        regs : tcpuregisterset;
+        r: byte;
       begin
       begin
         if (cs_create_pic in current_settings.moduleswitches) and
         if (cs_create_pic in current_settings.moduleswitches) and
            (pi_needs_got in current_procinfo.flags) and
            (pi_needs_got in current_procinfo.flags) and
            (tf_pic_uses_got in target_info.flags) then
            (tf_pic_uses_got in target_info.flags) then
           begin
           begin
+            { Procedure parametrs are not initialized at this stage.
+              Before GOT initialization code, allocate registers used for procedure parameters
+              to prevent usage of these registers for temp operations in later stages of code
+              generation. }
+            regs:=rg[R_INTREGISTER].used_in_proc;
+            for r:=RS_R0 to RS_R3 do
+              if r in regs then
+                a_reg_alloc(list, newreg(R_INTREGISTER,r,R_SUBWHOLE));
+            { Allocate scratch register R12 and use it for GOT calculations directly.
+              Otherwise the init code can be distorted in later stages of code generation. }
+            a_reg_alloc(list,NR_R12);
+
             reference_reset(ref,4);
             reference_reset(ref,4);
             current_asmdata.getglobaldatalabel(l);
             current_asmdata.getglobaldatalabel(l);
             cg.a_label(current_procinfo.aktlocaldata,l);
             cg.a_label(current_procinfo.aktlocaldata,l);
             ref.symbol:=l;
             ref.symbol:=l;
             ref.base:=NR_PC;
             ref.base:=NR_PC;
             ref.symboldata:=current_procinfo.aktlocaldata.last;
             ref.symboldata:=current_procinfo.aktlocaldata.last;
-            list.concat(Taicpu.op_reg_ref(A_LDR,current_procinfo.got,ref));
+            list.concat(Taicpu.op_reg_ref(A_LDR,NR_R12,ref));
             current_asmdata.getaddrlabel(l);
             current_asmdata.getaddrlabel(l);
             current_procinfo.aktlocaldata.concat(tai_const.Create_rel_sym_offset(aitconst_32bit,l,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),-8));
             current_procinfo.aktlocaldata.concat(tai_const.Create_rel_sym_offset(aitconst_32bit,l,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),-8));
             cg.a_label(list,l);
             cg.a_label(list,l);
-            list.concat(Taicpu.op_reg_reg_reg(A_ADD,current_procinfo.got,NR_PC,current_procinfo.got));
+            list.concat(Taicpu.op_reg_reg_reg(A_ADD,NR_R12,NR_PC,NR_R12));
+            list.concat(Taicpu.op_reg_reg(A_MOV,current_procinfo.got,NR_R12));
+
+            { Deallocate registers }
+            a_reg_dealloc(list,NR_R12);
+            for r:=RS_R3 downto RS_R0 do
+              if r in regs then
+                a_reg_dealloc(list, newreg(R_INTREGISTER,r,R_SUBWHOLE));
           end;
           end;
       end;
       end;
 
 
@@ -2372,12 +2461,12 @@ unit cgcpu;
               begin
               begin
                 tmpreg:=g_indirect_sym_load(list,ref.symbol.name,asmsym2indsymflags(ref.symbol));
                 tmpreg:=g_indirect_sym_load(list,ref.symbol.name,asmsym2indsymflags(ref.symbol));
                 if ref.offset<>0 then
                 if ref.offset<>0 then
-                  a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,tmpreg);
+                    a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,tmpreg);
                 indirection_done:=true;
                 indirection_done:=true;
               end
               end
             else if (cs_create_pic in current_settings.moduleswitches) then
             else if (cs_create_pic in current_settings.moduleswitches) then
               if (tf_pic_uses_got in target_info.flags) then
               if (tf_pic_uses_got in target_info.flags) then
-                current_procinfo.aktlocaldata.concat(tai_const.Create_type_sym_offset(aitconst_got,ref.symbol,ref.offset))
+                current_procinfo.aktlocaldata.concat(tai_const.Create_type_sym(aitconst_got,ref.symbol))
               else
               else
                 begin
                 begin
                   { ideally, we would want to generate
                   { ideally, we would want to generate
@@ -2401,7 +2490,7 @@ unit cgcpu;
               current_procinfo.aktlocaldata.concat(tai_const.create_sym_offset(ref.symbol,ref.offset))
               current_procinfo.aktlocaldata.concat(tai_const.create_sym_offset(ref.symbol,ref.offset))
           end
           end
         else
         else
-          current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
+            current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
 
 
         { load consts entry }
         { load consts entry }
         if not indirection_done then
         if not indirection_done then
@@ -2419,6 +2508,8 @@ unit cgcpu;
                 tmpref.base:=current_procinfo.got;
                 tmpref.base:=current_procinfo.got;
                 tmpref.index:=tmpreg;
                 tmpref.index:=tmpreg;
                 list.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
                 list.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
+                if ref.offset<>0 then
+                  a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,tmpreg);
               end;
               end;
           end;
           end;
 
 
@@ -3462,14 +3553,10 @@ unit cgcpu;
     procedure tthumbcgarm.g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);
     procedure tthumbcgarm.g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);
       var
       var
          ref : treference;
          ref : treference;
-         shift : byte;
          r : byte;
          r : byte;
-         regs, saveregs : tcpuregisterset;
-         r7offset,
+         regs : tcpuregisterset;
          stackmisalignment : pint;
          stackmisalignment : pint;
-         postfix: toppostfix;
-         registerarea,
-         imm1, imm2: DWord;
+         registerarea: DWord;
          stack_parameters: Boolean;
          stack_parameters: Boolean;
       begin
       begin
         stack_parameters:=current_procinfo.procdef.stack_tainting_parameter(calleeside);
         stack_parameters:=current_procinfo.procdef.stack_tainting_parameter(calleeside);
@@ -3575,15 +3662,11 @@ unit cgcpu;
 
 
     procedure tthumbcgarm.g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);
     procedure tthumbcgarm.g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);
       var
       var
-         ref : treference;
          LocalSize : longint;
          LocalSize : longint;
-         r,
-         shift : byte;
-         saveregs,
+         r: byte;
          regs : tcpuregisterset;
          regs : tcpuregisterset;
          registerarea : DWord;
          registerarea : DWord;
          stackmisalignment: pint;
          stackmisalignment: pint;
-         imm1, imm2: DWord;
          stack_parameters : Boolean;
          stack_parameters : Boolean;
       begin
       begin
         if not(nostackframe) then
         if not(nostackframe) then
@@ -3778,7 +3861,6 @@ unit cgcpu;
 
 
      procedure tthumbcgarm.a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);
      procedure tthumbcgarm.a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);
        var
        var
-          imm_shift : byte;
           l : tasmlabel;
           l : tasmlabel;
           hr : treference;
           hr : treference;
        begin
        begin
@@ -3940,8 +4022,7 @@ unit cgcpu;
 
 
     procedure tthumbcgarm.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
     procedure tthumbcgarm.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
       var
       var
-        tmpreg,overflowreg : tregister;
-        asmop : tasmop;
+        tmpreg : tregister;
       begin
       begin
         case op of
         case op of
           OP_NEG:
           OP_NEG:
@@ -3974,9 +4055,9 @@ unit cgcpu;
     procedure tthumbcgarm.a_op_const_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; dst: tregister);
     procedure tthumbcgarm.a_op_const_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; dst: tregister);
       var
       var
         tmpreg : tregister;
         tmpreg : tregister;
-        so : tshifterop;
+        {$ifdef DUMMY}
         l1 : longint;
         l1 : longint;
-        imm1, imm2: DWord;
+        {$endif DUMMY}
       begin
       begin
         //!!! ovloc.loc:=LOC_VOID;
         //!!! ovloc.loc:=LOC_VOID;
         if {$ifopt R+}(a<>-2147483648) and{$endif} {!!!!!! not setflags and } is_thumb_imm(-a) then
         if {$ifopt R+}(a<>-2147483648) and{$endif} {!!!!!! not setflags and } is_thumb_imm(-a) then
@@ -4177,7 +4258,6 @@ unit cgcpu;
 
 
      procedure tthumb2cgarm.a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);
      procedure tthumb2cgarm.a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);
        var
        var
-          imm_shift : byte;
           l : tasmlabel;
           l : tasmlabel;
           hr : treference;
           hr : treference;
        begin
        begin
@@ -4663,7 +4743,6 @@ unit cgcpu;
 
 
 
 
     procedure tthumb2cgarm.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
     procedure tthumb2cgarm.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
-      var item: taicpu;
       begin
       begin
         list.concat(taicpu.op_cond(A_ITE, flags_to_cond(f)));
         list.concat(taicpu.op_cond(A_ITE, flags_to_cond(f)));
         list.concat(setcondition(taicpu.op_reg_const(A_MOV,reg,1),flags_to_cond(f)));
         list.concat(setcondition(taicpu.op_reg_const(A_MOV,reg,1),flags_to_cond(f)));
@@ -4879,7 +4958,6 @@ unit cgcpu;
         tmpreg : tregister;
         tmpreg : tregister;
         tmpref : treference;
         tmpref : treference;
         l : tasmlabel;
         l : tasmlabel;
-        so: tshifterop;
       begin
       begin
         tmpreg:=NR_NO;
         tmpreg:=NR_NO;
 
 
@@ -5157,7 +5235,6 @@ unit cgcpu;
     procedure tthumbcg64farm.a_op64_const_reg(list: TAsmList; op: TOpCG; size: tcgsize; value: int64; reg: tregister64);
     procedure tthumbcg64farm.a_op64_const_reg(list: TAsmList; op: TOpCG; size: tcgsize; value: int64; reg: tregister64);
       var
       var
         tmpreg : tregister;
         tmpreg : tregister;
-        b : byte;
       begin
       begin
         case op of
         case op of
           OP_AND,OP_OR,OP_XOR:
           OP_AND,OP_OR,OP_XOR:

+ 511 - 291
compiler/arm/cpuinfo.pas

@@ -251,9 +251,60 @@ Type
       ct_stm32f107vb,
       ct_stm32f107vb,
       ct_stm32f107vc,
       ct_stm32f107vc,
       
       
-      ct_stm32f429xe, // 512K flash
-      ct_stm32f429xg, // 1M flash
-      ct_stm32f429xi, // 2M flash
+      ct_stm32f401cb,
+      ct_stm32f401rb,
+      ct_stm32f401vb,
+      ct_stm32f401cc,
+      ct_stm32f401rc,
+      ct_stm32f401vc,
+      ct_discoveryf401vc,
+      ct_stm32f401cd,
+      ct_stm32f401rd,
+      ct_stm32f401vd,
+      ct_stm32f401ce,
+      ct_stm32f401re,
+      ct_nucleof401re,
+      ct_stm32f401ve,
+      ct_stm32f407vg,
+      ct_discoveryf407vg,
+      ct_stm32f407ig,
+      ct_stm32f407zg,
+      ct_stm32f407ve,
+      ct_stm32f407ze,
+      ct_stm32f407ie,
+      ct_stm32f411cc,
+      ct_stm32f411rc,
+      ct_stm32f411vc,
+      ct_stm32f411ce,
+      ct_stm32f411re,
+      ct_nucleof411re,
+      ct_stm32f411ve,
+      ct_discoveryf411ve,
+      ct_stm32f429vg,
+      ct_stm32f429zg,
+      ct_stm32f429ig,
+      ct_stm32f429vi,
+      ct_stm32f429zi,
+      ct_discoveryf429zi,
+      ct_stm32f429ii,
+      ct_stm32f429ve,
+      ct_stm32f429ze,
+      ct_stm32f429ie,
+      ct_stm32f429bg,
+      ct_stm32f429bi,
+      ct_stm32f429be,
+      ct_stm32f429ng,
+      ct_stm32f429ni,
+      ct_stm32f429ne,
+      ct_stm32f446mc,
+      ct_stm32f446rc,
+      ct_stm32f446vc,
+      ct_stm32f446zc,
+      ct_stm32f446me,
+      ct_stm32f446re,
+      ct_nucleof446re,
+      ct_stm32f446ve,
+      ct_stm32f446ze,
 
 
       ct_stm32f745xe,
       ct_stm32f745xe,
       ct_stm32f745xg,
       ct_stm32f745xg,
@@ -353,14 +404,75 @@ Type
       ct_allwinner_a20,
       ct_allwinner_a20,
 
 
       { Freescale }
       { Freescale }
-      ct_mk20dx128xxx7,
-      ct_mk20dx256xxx7,
-      ct_mk20dx64xxx7,
+      ct_mk20dx128vfm5,
+      ct_mk20dx128vft5,
+      ct_mk20dx128vlf5,
+      ct_mk20dx128vlh5,
+      ct_teensy30,
+      ct_mk20dx128vmp5,
+
+      ct_mk20dx32vfm5,
+      ct_mk20dx32vft5,
+      ct_mk20dx32vlf5,
+      ct_mk20dx32vlh5,
+      ct_mk20dx32vmp5,
+
+      ct_mk20dx64vfm5,
+      ct_mk20dx64vft5,
+      ct_mk20dx64vlf5,
+      ct_mk20dx64vlh5,
+      ct_mk20dx64vmp5,
+
+      ct_mk20dx128vlh7,
+      ct_mk20dx128vlk7,
+      ct_mk20dx128vll7,
+      ct_mk20dx128vmc7,
+
+      ct_mk20dx256vlh7,
+      ct_mk20dx256vlk7,
+      ct_mk20dx256vll7,
+      ct_mk20dx256vmc7,
+      ct_teensy31,
+      ct_teensy32,
+
+      ct_mk20dx64vlh7,
+      ct_mk20dx64vlk7,
+      ct_mk20dx64vmc7,
+
+      ct_mk22fn512cap12,
+      ct_mk22fn512cbp12,
+      ct_mk22fn512vdc12,
+      ct_mk22fn512vlh12,
+      ct_mk22fn512vll12,
+      ct_mk22fn512vmp12,
+      ct_freedom_k22f,
+
+      ct_mk64fn1m0vdc12,
+      ct_mk64fn1m0vll12,
+      ct_freedom_k64f,
+      ct_mk64fn1m0vlq12,
+      ct_mk64fn1m0vmd12,
+
+      ct_mk64fx512vdc12,
+      ct_mk64fx512vll12,
+      ct_mk64fx512vlq12,
+      ct_mk64fx512vmd12,
+
+      { Atmel }
+      ct_sam3x8e,
+      ct_arduino_due,
+      ct_flip_n_click,
 
 
       // generic Thumb2 target
       // generic Thumb2 target
       ct_thumb2bare
       ct_thumb2bare
      );
      );
 
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 Const
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { Is there support for dealing with multiple microcontrollers available }
    { for this platform? }
    { for this platform? }
@@ -430,320 +542,427 @@ Const
 
 
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    (
    (
-      (controllertypestr:'';		controllerunitstr:'';	flashbase:0;	flashsize:0;	srambase:0;	sramsize:0),
+      (controllertypestr:'';		controllerunitstr:'';	cputype:cpu_none; fputype:fpu_none; flashbase:0;	flashsize:0;	srambase:0;	sramsize:0),
 
 
       { LPC 8xx Series}
       { LPC 8xx Series}
-      (controllertypestr:'LPC810M021FN8';	controllerunitstr:'LPC8xx';	flashbase:$00000000;	flashsize:$00001000;	srambase:$10000000;	sramsize:$00000400),
-      (controllertypestr:'LPC811M001FDH16';	controllerunitstr:'LPC8xx';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
-      (controllertypestr:'LPC812M101FDH16';	controllerunitstr:'LPC8xx';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC812M101FD20';	controllerunitstr:'LPC8xx';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC812M101FDH20';	controllerunitstr:'LPC8xx';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC810M021FN8';	  controllerunitstr:'LPC8xx';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00001000;	srambase:$10000000;	sramsize:$00000400),
+      (controllertypestr:'LPC811M001FDH16';	controllerunitstr:'LPC8xx';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
+      (controllertypestr:'LPC812M101FDH16';	controllerunitstr:'LPC8xx';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC812M101FD20';	controllerunitstr:'LPC8xx';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC812M101FDH20';	controllerunitstr:'LPC8xx';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
 
 
       { LPC 11xx Series}
       { LPC 11xx Series}
-      (controllertypestr:'LPC1110FD20';		controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00001000;	srambase:$10000000;	sramsize:$00000400),
-      (controllertypestr:'LPC1111FDH20_002';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
-      (controllertypestr:'LPC1111FHN33_101';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
-      (controllertypestr:'LPC1111FHN33_102';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
-      (controllertypestr:'LPC1111FHN33_103';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
-      (controllertypestr:'LPC1111FHN33_201';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1111FHN33_202';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1111FHN33_203';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
-
-      (controllertypestr:'LPC1112FD20_102';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1112FDH20_102';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1112FDH28_102';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1112FHN33_101';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00000800),
-      (controllertypestr:'LPC1112FHN33_102';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00000800),
-      (controllertypestr:'LPC1112FHN33_103';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00000800),
-      (controllertypestr:'LPC1112FHN33_201';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1112FHN24_202';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1112FHN33_202';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1112FHN33_203';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1112FHI33_202';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1112FHI33_203';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-
-      (controllertypestr:'LPC1113FHN33_201';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1113FHN33_202';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1113FHN33_203';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1113FHN33_301';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1113FHN33_302';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1113FHN33_303';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1113FBD48_301';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1113FBD48_302';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1113FBD48_303';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
-
-      (controllertypestr:'LPC1114FDH28_102';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1114FN28_102';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1114FHN33_201';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1114FHN33_202';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1114FHN33_203';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1114FHN33_301';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FHN33_302';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FHN33_303';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FHN33_333';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$0000E000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FHI33_302';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FHI33_303';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FBD48_301';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FBD48_302';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FBD48_303';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FBD48_323';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1114FBD48_333';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$0000E000;	srambase:$10000000;	sramsize:$00002000),
-
-      (controllertypestr:'LPC1115FBD48_303';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
-
-      (controllertypestr:'LPC11C12FBD48_301';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC11C14FBD48_301';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-
-      (controllertypestr:'LPC11C22FBD48_301';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC11C24FBD48_301';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-
-      (controllertypestr:'LPC11D14FBD100_302';	controllerunitstr:'LPC11XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1110FD20';		    controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00001000;	srambase:$10000000;	sramsize:$00000400),
+      (controllertypestr:'LPC1111FDH20_002';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
+      (controllertypestr:'LPC1111FHN33_101';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
+      (controllertypestr:'LPC1111FHN33_102';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
+      (controllertypestr:'LPC1111FHN33_103';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00000800),
+      (controllertypestr:'LPC1111FHN33_201';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1111FHN33_202';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1111FHN33_203';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
+
+      (controllertypestr:'LPC1112FD20_102';	controllerunitstr:'LPC11XX';	  cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1112FDH20_102';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1112FDH28_102';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1112FHN33_101';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00000800),
+      (controllertypestr:'LPC1112FHN33_102';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00000800),
+      (controllertypestr:'LPC1112FHN33_103';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00000800),
+      (controllertypestr:'LPC1112FHN33_201';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1112FHN24_202';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1112FHN33_202';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1112FHN33_203';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1112FHI33_202';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1112FHI33_203';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+
+      (controllertypestr:'LPC1113FHN33_201';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1113FHN33_202';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1113FHN33_203';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1113FHN33_301';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1113FHN33_302';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1113FHN33_303';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1113FBD48_301';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1113FBD48_302';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1113FBD48_303';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00006000;	srambase:$10000000;	sramsize:$00002000),
+
+      (controllertypestr:'LPC1114FDH28_102';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1114FN28_102';	  controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1114FHN33_201';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1114FHN33_202';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1114FHN33_203';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1114FHN33_301';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FHN33_302';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FHN33_303';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FHN33_333';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000E000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FHI33_302';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FHI33_303';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FBD48_301';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FBD48_302';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FBD48_303';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FBD48_323';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1114FBD48_333';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000E000;	srambase:$10000000;	sramsize:$00002000),
+
+      (controllertypestr:'LPC1115FBD48_303';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+
+      (controllertypestr:'LPC11C12FBD48_301';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC11C14FBD48_301';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+
+      (controllertypestr:'LPC11C22FBD48_301';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC11C24FBD48_301';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+
+      (controllertypestr:'LPC11D14FBD100_302';	controllerunitstr:'LPC11XX';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
 
 
       {LPC 122x Series}
       {LPC 122x Series}
-      (controllertypestr:'LPC1224FBD48_101';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1224FBD48_121';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1224FBD64_101';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1224FBD64_121';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1224FBD48_101';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1224FBD48_121';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1224FBD64_101';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1224FBD64_121';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00001000),
 
 
-      (controllertypestr:'LPC1225FBD48_301';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1225FBD48_321';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00014000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1225FBD64_301';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1225FBD64_321';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00014000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1225FBD48_301';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1225FBD48_321';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00014000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1225FBD64_301';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1225FBD64_321';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00014000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1226FBD48_301';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00018000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1226FBD64_301';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00018000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1226FBD48_301';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00018000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1226FBD64_301';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00018000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1227FBD48_301';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1227FBD64_301';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1227FBD48_301';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1227FBD64_301';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC12D27FBD100_301';	controllerunitstr:'LPC122X';	flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC12D27FBD100_301';	controllerunitstr:'LPC122X';	cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00002000),
 
 
 
 
-      (controllertypestr:'LPC1311FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1311FHN33_01';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1311FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1311FHN33_01';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$10000000;	sramsize:$00001000),
 
 
-      (controllertypestr:'LPC1313FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1313FHN33_01';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1313FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1313FBD48_01';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1313FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1313FHN33_01';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1313FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1313FBD48_01';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1315FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1315FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1315FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1315FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1316FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1316FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1316FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1316FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1317FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1317FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1317FBD64';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1317FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1317FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1317FBD64';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1342FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
-      (controllertypestr:'LPC1342FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1342FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
+      (controllertypestr:'LPC1342FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00004000;	srambase:$10000000;	sramsize:$00001000),
 
 
-      (controllertypestr:'LPC1343FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1343FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1343FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1343FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1345FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1345FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1345FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1345FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00008000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1346FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1346FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1346FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1346FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$0000C000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC1347FHN33';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1347FBD48';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
-      (controllertypestr:'LPC1347FBD64';	controllerunitstr:'LPC13XX';	flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1347FHN33';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1347FBD48';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
+      (controllertypestr:'LPC1347FBD64';	controllerunitstr:'LPC13XX';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$10000000;	sramsize:$00002000),
 
 
-      (controllertypestr:'LPC2114';	controllerunitstr:'LPC21x4';	flashbase:$00000000;	flashsize:$00040000;	srambase:$40000000;	sramsize:$00004000),
-      (controllertypestr:'LPC2124';	controllerunitstr:'LPC21x4';	flashbase:$00000000;	flashsize:$00040000;	srambase:$40000000;	sramsize:$00004000),
-      (controllertypestr:'LPC2194';	controllerunitstr:'LPC21x4';	flashbase:$00000000;	flashsize:$00040000;	srambase:$40000000;	sramsize:$00004000),
-      (controllertypestr:'LPC1754';	controllerunitstr:'LPC1754';	flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00004000),
-      (controllertypestr:'LPC1756';	controllerunitstr:'LPC1756';	flashbase:$00000000;	flashsize:$00040000;	srambase:$10000000;	sramsize:$00004000),
-      (controllertypestr:'LPC1758';	controllerunitstr:'LPC1758';	flashbase:$00000000;	flashsize:$00080000;	srambase:$10000000;	sramsize:$00008000),
-      (controllertypestr:'LPC1764';	controllerunitstr:'LPC1764';	flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00004000),
-      (controllertypestr:'LPC1766';	controllerunitstr:'LPC1766';	flashbase:$00000000;	flashsize:$00040000;	srambase:$10000000;	sramsize:$00008000),
-      (controllertypestr:'LPC1768';	controllerunitstr:'LPC1768';	flashbase:$00000000;	flashsize:$00080000;	srambase:$10000000;	sramsize:$00008000),
+      (controllertypestr:'LPC2114';	controllerunitstr:'LPC21x4';	cputype:cpu_armv4t; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$40000000;	sramsize:$00004000),
+      (controllertypestr:'LPC2124';	controllerunitstr:'LPC21x4';	cputype:cpu_armv4t; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$40000000;	sramsize:$00004000),
+      (controllertypestr:'LPC2194';	controllerunitstr:'LPC21x4';	cputype:cpu_armv4t; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$40000000;	sramsize:$00004000),
+      
+      (controllertypestr:'LPC1754';	controllerunitstr:'LPC1754';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00004000),
+      (controllertypestr:'LPC1756';	controllerunitstr:'LPC1756';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$10000000;	sramsize:$00004000),
+      (controllertypestr:'LPC1758';	controllerunitstr:'LPC1758';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00080000;	srambase:$10000000;	sramsize:$00008000),
+      (controllertypestr:'LPC1764';	controllerunitstr:'LPC1764';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$10000000;	sramsize:$00004000),
+      (controllertypestr:'LPC1766';	controllerunitstr:'LPC1766';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$10000000;	sramsize:$00008000),
+      (controllertypestr:'LPC1768';	controllerunitstr:'LPC1768';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00080000;	srambase:$10000000;	sramsize:$00008000),
 
 
       { AT91 }
       { AT91 }
-      (controllertypestr:'AT91SAM7S256';	controllerunitstr:'AT91SAM7x256';	flashbase:$00000000;	flashsize:$00040000;	srambase:$00200000;	sramsize:$00010000),
-      (controllertypestr:'AT91SAM7SE256';	controllerunitstr:'AT91SAM7x256';	flashbase:$00000000;	flashsize:$00040000;	srambase:$00200000;	sramsize:$00010000),
-      (controllertypestr:'AT91SAM7X256';	controllerunitstr:'AT91SAM7x256';	flashbase:$00000000;	flashsize:$00040000;	srambase:$00200000;	sramsize:$00010000),
-      (controllertypestr:'AT91SAM7XC256';	controllerunitstr:'AT91SAM7x256';	flashbase:$00000000;	flashsize:$00040000;	srambase:$00200000;	sramsize:$00010000),
+      (controllertypestr:'AT91SAM7S256';	controllerunitstr:'AT91SAM7x256';	cputype:cpu_armv4t; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$00200000;	sramsize:$00010000),
+      (controllertypestr:'AT91SAM7SE256';	controllerunitstr:'AT91SAM7x256';	cputype:cpu_armv4t; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$00200000;	sramsize:$00010000),
+      (controllertypestr:'AT91SAM7X256';	controllerunitstr:'AT91SAM7x256';	cputype:cpu_armv4t; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$00200000;	sramsize:$00010000),
+      (controllertypestr:'AT91SAM7XC256';	controllerunitstr:'AT91SAM7x256';	cputype:cpu_armv4t; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$00200000;	sramsize:$00010000),
 
 
       { STM32F0 series }
       { STM32F0 series }
-      (controllertypestr:'STM32F030C6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F030C8';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
-      (controllertypestr:'STM32F030F4';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F030K6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F030R8';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
-      (controllertypestr:'STM32F050C4';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F050C6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F050F4';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F050F6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F050G4';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F050G6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F050K4';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F050K6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F051C4';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F051C6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F051C8';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
-      (controllertypestr:'STM32F051K4';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F051K6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F051K8';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
-      (controllertypestr:'STM32F051R4';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F051R6';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F051R8';     controllerunitstr:'STM32F0XX';        flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'STM32F030C6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F030C8';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'STM32F030F4';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F030K6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F030R8';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'STM32F050C4';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F050C6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F050F4';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F050F6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F050G4';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F050G6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F050K4';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F050K6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F051C4';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F051C6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F051C8';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'STM32F051K4';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F051K6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F051K8';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'STM32F051R4';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F051R6';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F051R8';     controllerunitstr:'STM32F0XX';        cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
 
 
       { STM32F1 series }
       { STM32F1 series }
-      (controllertypestr:'STM32F100X4';     controllerunitstr:'STM32F10X_LD';     flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F100X6';     controllerunitstr:'STM32F10X_LD';     flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F100X8';     controllerunitstr:'STM32F10X_MD';     flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
-      (controllertypestr:'STM32F100XB';     controllerunitstr:'STM32F10X_MD';     flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00002000),
-      (controllertypestr:'STM32F100XC';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00006000),
-      (controllertypestr:'STM32F100XD';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$00008000),
-      (controllertypestr:'STM32F100XE';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00008000),
-      (controllertypestr:'STM32F101X4';     controllerunitstr:'STM32F10X_LD';     flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F101X6';     controllerunitstr:'STM32F10X_LD';     flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001800),
-      (controllertypestr:'STM32F101X8';     controllerunitstr:'STM32F10X_MD';     flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002800),
-      (controllertypestr:'STM32F101XB';     controllerunitstr:'STM32F10X_MD';     flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00004000),
-      (controllertypestr:'STM32F101XC';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00008000),
-      (controllertypestr:'STM32F101XD';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$0000C000),
-      (controllertypestr:'STM32F101XE';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$0000C000),
-      (controllertypestr:'STM32F101XF';     controllerunitstr:'STM32F10X_XL';     flashbase:$08000000; flashsize:$000C0000; srambase:$20000000; sramsize:$00014000),
-      (controllertypestr:'STM32F101XG';     controllerunitstr:'STM32F10X_XL';     flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00014000),
-      (controllertypestr:'STM32F102X4';     controllerunitstr:'STM32F10X_LD';     flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F102X6';     controllerunitstr:'STM32F10X_LD';     flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001800),
-      (controllertypestr:'STM32F102X8';     controllerunitstr:'STM32F10X_MD';     flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002800),
-      (controllertypestr:'STM32F102XB';     controllerunitstr:'STM32F10X_MD';     flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00004000),
-      (controllertypestr:'STM32F103X4';     controllerunitstr:'STM32F10X_LD';     flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
-      (controllertypestr:'STM32F103X6';     controllerunitstr:'STM32F10X_LD';     flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00002800),
-      (controllertypestr:'STM32F103X8';     controllerunitstr:'STM32F10X_MD';     flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00005000),
-      (controllertypestr:'STM32F103XB';     controllerunitstr:'STM32F10X_MD';     flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00005000),
-      (controllertypestr:'STM32F103XC';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$0000C000),
-      (controllertypestr:'STM32F103XD';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F103XE';     controllerunitstr:'STM32F10X_HD';     flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F103XF';     controllerunitstr:'STM32F10X_XL';     flashbase:$08000000; flashsize:$000C0000; srambase:$20000000; sramsize:$00018000),
-      (controllertypestr:'STM32F103XG';     controllerunitstr:'STM32F10X_XL';     flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00018000),
-      (controllertypestr:'STM32F107X8';     controllerunitstr:'STM32F10X_CONN';   flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F107XB';     controllerunitstr:'STM32F10X_CONN';   flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F107XC';     controllerunitstr:'STM32F10X_CONN';   flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
-
-      (controllertypestr:'STM32F105R8';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F105RB';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F105RC';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F105V8';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F105VB';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F105VC';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
-      (controllertypestr:'STM32F107RB';     controllerunitstr:'STM32F10X_CL';     flashbase:$08000000; flashsize:$00020000; 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:'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:'LM3S1133';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S1138';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S1150';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S1162';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S1165';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S1166';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S2110';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S2139';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S6100';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
-      (controllertypestr:'LM3S6110';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'STM32F100X4';     controllerunitstr:'STM32F10X_LD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F100X6';     controllerunitstr:'STM32F10X_LD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F100X8';     controllerunitstr:'STM32F10X_MD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'STM32F100XB';     controllerunitstr:'STM32F10X_MD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'STM32F100XC';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00006000),
+      (controllertypestr:'STM32F100XD';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'STM32F100XE';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'STM32F101X4';     controllerunitstr:'STM32F10X_LD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F101X6';     controllerunitstr:'STM32F10X_LD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001800),
+      (controllertypestr:'STM32F101X8';     controllerunitstr:'STM32F10X_MD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002800),
+      (controllertypestr:'STM32F101XB';     controllerunitstr:'STM32F10X_MD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00004000),
+      (controllertypestr:'STM32F101XC';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'STM32F101XD';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$0000C000),
+      (controllertypestr:'STM32F101XE';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$0000C000),
+      (controllertypestr:'STM32F101XF';     controllerunitstr:'STM32F10X_XL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$000C0000; srambase:$20000000; sramsize:$00014000),
+      (controllertypestr:'STM32F101XG';     controllerunitstr:'STM32F10X_XL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00014000),
+      (controllertypestr:'STM32F102X4';     controllerunitstr:'STM32F10X_LD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F102X6';     controllerunitstr:'STM32F10X_LD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00001800),
+      (controllertypestr:'STM32F102X8';     controllerunitstr:'STM32F10X_MD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00002800),
+      (controllertypestr:'STM32F102XB';     controllerunitstr:'STM32F10X_MD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00004000),
+      (controllertypestr:'STM32F103X4';     controllerunitstr:'STM32F10X_LD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'STM32F103X6';     controllerunitstr:'STM32F10X_LD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00002800),
+      (controllertypestr:'STM32F103X8';     controllerunitstr:'STM32F10X_MD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00005000),
+      (controllertypestr:'STM32F103XB';     controllerunitstr:'STM32F10X_MD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00005000),
+      (controllertypestr:'STM32F103XC';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$0000C000),
+      (controllertypestr:'STM32F103XD';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F103XE';     controllerunitstr:'STM32F10X_HD';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F103XF';     controllerunitstr:'STM32F10X_XL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$000C0000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'STM32F103XG';     controllerunitstr:'STM32F10X_XL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'STM32F107X8';     controllerunitstr:'STM32F10X_CONN';   cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F107XB';     controllerunitstr:'STM32F10X_CONN';   cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F107XC';     controllerunitstr:'STM32F10X_CONN';   cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+
+      (controllertypestr:'STM32F105R8';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F105RB';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F105RC';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F105V8';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F105VB';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F105VC';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F107RB';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F107RC';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F107VB';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F107VC';     controllerunitstr:'STM32F10X_CL';     cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+    
+      (controllertypestr:'STM32F401CB';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F401RB';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F401VB';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F401CC';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F401RC';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F401VC';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'DISCOVERYF401VC'; controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'STM32F401CD';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'STM32F401RD';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'STM32F401VD';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00060000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'STM32F401CE';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'STM32F401RE';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'NUCLEOF401RE';    controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'STM32F401VE';     controllerunitstr:'STM32F401XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00018000),
+      (controllertypestr:'STM32F407VG';     controllerunitstr:'STM32F407XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'DISCOVERYF407VG'; controllerunitstr:'STM32F407XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F407IG';     controllerunitstr:'STM32F407XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F407ZG';     controllerunitstr:'STM32F407XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F407VE';     controllerunitstr:'STM32F407XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F407ZE';     controllerunitstr:'STM32F407XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F407IE';     controllerunitstr:'STM32F407XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F411CC';     controllerunitstr:'STM32F411XE';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F411RC';     controllerunitstr:'STM32F411XE';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F411VC';     controllerunitstr:'STM32F411XE';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F411CE';     controllerunitstr:'STM32F411XE';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F411RE';     controllerunitstr:'STM32F411XE';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'NUCLEOF411RE';    controllerunitstr:'STM32F411XE';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F411VE';     controllerunitstr:'STM32F411XE';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'DISCOVERYF411VE'; controllerunitstr:'STM32F411XE';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F429VG';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429ZG';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429IG';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429VI';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00200000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429ZI';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00200000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'DISCOVERYF429ZI'; controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00200000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429II';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00200000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429VE';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429ZE';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429IE';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429BG';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429BI';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00200000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429BE';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429NG';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429NI';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00200000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F429NE';     controllerunitstr:'STM32F429XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'STM32F446MC';     controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F446RC';     controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F446VC';     controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F446ZC';     controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00040000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F446ME';     controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F446RE';     controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'NUCLEOF446RE';    controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F446VE';     controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'STM32F446ZE';     controllerunitstr:'STM32F446XX';      cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20000000; sramsize:$00020000),
+ 
+      (controllertypestr:'STM32F745XE';     controllerunitstr:'STM32F745';        cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F745XG';     controllerunitstr:'STM32F745';        cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F746XE';     controllerunitstr:'STM32F746';        cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F746XG';     controllerunitstr:'STM32F746';        cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F756XE';     controllerunitstr:'STM32F756';        cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00080000; srambase:$20010000; sramsize:$00040000),
+      (controllertypestr:'STM32F756XG';     controllerunitstr:'STM32F756';        cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000; flashsize:$00100000; srambase:$20010000; sramsize:$00040000),
+
+      (controllertypestr:'LM3S1110';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S1133';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S1138';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S1150';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S1162';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S1165';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S1166';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S2110';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S2139';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S6100';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
+      (controllertypestr:'LM3S6110';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00010000;	srambase:$20000000;	sramsize:$00004000),
 
 
       { TI - 128K Flash, 32K SRAM devices }
       { TI - 128K Flash, 32K SRAM devices }
-      (controllertypestr:'LM3S1601';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S1608';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S1620';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S1635';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S1636';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S1637';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S1651';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S2601';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S2608';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S2620';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S2637';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S2651';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S6610';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S6611';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S6618';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S6633';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S6637';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
-      (controllertypestr:'LM3S8630';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S1601';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S1608';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S1620';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S1635';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S1636';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S1637';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S1651';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S2601';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S2608';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S2620';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S2637';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S2651';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S6610';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S6611';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S6618';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S6633';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S6637';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM3S8630';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00020000;	srambase:$20000000;	sramsize:$00008000),
 
 
       { TI - 256K Flash, 64K SRAM devices }
       { TI - 256K Flash, 64K SRAM devices }
-      (controllertypestr:'LM3S1911';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S1918';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S1937';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S1958';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S1960';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S1968';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S1969';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S2911';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S2918';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S2919';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S2939';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S2948';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S2950';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S2965';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S6911';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S6918';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S6938';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S6950';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S6952';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S6965';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S8930';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S8933';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S8938';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S8962';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S8970';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S8971';	controllerunitstr:'LM3FURY';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S1911';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S1918';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S1937';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S1958';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S1960';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S1968';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S1969';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S2911';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S2918';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S2919';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S2939';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S2948';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S2950';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S2965';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S6911';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S6918';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S6938';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S6950';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S6952';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S6965';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S8930';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S8933';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S8938';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S8962';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S8970';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S8971';	controllerunitstr:'LM3FURY';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
 
 
       { TI - Tempest parts - up to 512 K Flash, 96 K SRAM }
       { TI - Tempest parts - up to 512 K Flash, 96 K SRAM }
-      (controllertypestr:'LM3S5951';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S5956';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'LM3S1B21';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
-      (controllertypestr:'LM3S2B93';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
-      (controllertypestr:'LM3S5B91';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
-      (controllertypestr:'LM3S9B81';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
-      (controllertypestr:'LM3S9B90';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
-      (controllertypestr:'LM3S9B92';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
-      (controllertypestr:'LM3S9B95';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
-      (controllertypestr:'LM3S9B96';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
-      (controllertypestr:'LM3S5D51';	controllerunitstr:'LM3TEMPEST';	flashbase:$00000000;	flashsize:$00080000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S5951';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S5956';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'LM3S1B21';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S2B93';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S5B91';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S9B81';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S9B90';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S9B92';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S9B95';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S9B96';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00018000),
+      (controllertypestr:'LM3S5D51';	controllerunitstr:'LM3TEMPEST';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00080000;	srambase:$20000000;	sramsize:$00018000),
 
 
       { TI }
       { TI }
-      (controllertypestr:'LM4F120H5';	controllerunitstr:'LM4F120';	flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00008000),
+      (controllertypestr:'LM4F120H5';	controllerunitstr:'LM4F120';	cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00040000;	srambase:$20000000;	sramsize:$00008000),
 
 
       { Samsung }
       { Samsung }
-      (controllertypestr:'SC32442B';	controllerunitstr:'SC32442b';	flashbase:$00000000;	flashsize:$00000000;	srambase:$00000000;	sramsize:$08000000),
+      (controllertypestr:'SC32442B';	controllerunitstr:'SC32442b';	cputype:cpu_armv4t; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00000000;	srambase:$00000000;	sramsize:$08000000),
       
       
       { Infinion }
       { Infinion }
-      (controllertypestr:'XMC4500X1024';  controllerunitstr:'XMC4500'; flashbase:$08000000;	flashsize:$00100000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'XMC4500X768';   controllerunitstr:'XMC4500'; flashbase:$08000000;	flashsize:$000C0000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'XMC4502X768';   controllerunitstr:'XMC4502'; flashbase:$08000000;	flashsize:$000C0000;	srambase:$20000000;	sramsize:$00010000),
-      (controllertypestr:'XMC4504X512';   controllerunitstr:'XMC4504'; flashbase:$08000000;	flashsize:$00080000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'XMC4500X1024';  controllerunitstr:'XMC4500'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000;	flashsize:$00100000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'XMC4500X768';   controllerunitstr:'XMC4500'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000;	flashsize:$000C0000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'XMC4502X768';   controllerunitstr:'XMC4502'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000;	flashsize:$000C0000;	srambase:$20000000;	sramsize:$00010000),
+      (controllertypestr:'XMC4504X512';   controllerunitstr:'XMC4504'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$08000000;	flashsize:$00080000;	srambase:$20000000;	sramsize:$00010000),
 
 
       { Allwinner }
       { Allwinner }
-      (controllertypestr:'ALLWINNER_A20'; controllerunitstr:'ALLWINNER_A20';     flashbase:$00000000; flashsize:$00000000;  srambase:$40000000; sramsize:$80000000),
+      (controllertypestr:'ALLWINNER_A20'; controllerunitstr:'ALLWINNER_A20'; cputype:cpu_armv7a; fputype:fpu_vfpv4; flashbase:$00000000; flashsize:$00000000;  srambase:$40000000; sramsize:$80000000),
 
 
       { Freescale }
       { 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),
+      (controllertypestr:'MK20DX128VFM5'; controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX128VFT5'; controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX128VLF5'; controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX128VLH5'; controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'TEENSY30'     ; controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX128VMP5'; controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00002000),
+
+      (controllertypestr:'MK20DX32VFM5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00008000;   srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'MK20DX32VFT5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00008000;   srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'MK20DX32VLF5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00008000;   srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'MK20DX32VLH5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00008000;   srambase:$20000000; sramsize:$00001000),
+      (controllertypestr:'MK20DX32VMP5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00008000;   srambase:$20000000; sramsize:$00001000),
+
+      (controllertypestr:'MK20DX64VFM5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00010000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX64VFT5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00010000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX64VLF5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00010000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX64VLH5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00010000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX64VMP5';  controllerunitstr:'MK20D5';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00010000;   srambase:$20000000; sramsize:$00002000),
+
+      (controllertypestr:'MK20DX128VLH7'; controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00004000),
+      (controllertypestr:'MK20DX128VLK7'; controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00004000),
+      (controllertypestr:'MK20DX128VLL7'; controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00004000),
+      (controllertypestr:'MK20DX128VMC7'; controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00020000;   srambase:$20000000; sramsize:$00004000),
+
+      (controllertypestr:'MK20DX256VLH7'; controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00040000;   srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'MK20DX256VLK7'; controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00040000;   srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'MK20DX256VLL7'; controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00040000;   srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'MK20DX256VMC7'; controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00040000;   srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'TEENSY31';      controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00040000;   srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'TEENSY32';      controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00040000;   srambase:$20000000; sramsize:$00008000),
+
+      (controllertypestr:'MK20DX64VLH7';  controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00010000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX64VLK7';  controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00010000;   srambase:$20000000; sramsize:$00002000),
+      (controllertypestr:'MK20DX64VMC7';  controllerunitstr:'MK20D7';  cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00010000;   srambase:$20000000; sramsize:$00002000),
+
+      (controllertypestr:'MK22FN512CAP12';controllerunitstr:'MK22F51212'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;   flashsize:$00080000;   srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'MK22FN512CBP12';controllerunitstr:'MK22F51212'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;   flashsize:$00080000;   srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'MK22FN512VDC12';controllerunitstr:'MK22F51212'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;   flashsize:$00080000;   srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'MK22FN512VLH12';controllerunitstr:'MK22F51212'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;   flashsize:$00080000;   srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'MK22FN512VLL12';controllerunitstr:'MK22F51212'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;   flashsize:$00080000;   srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'MK22FN512VMP12';controllerunitstr:'MK22F51212'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;   flashsize:$00080000;   srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'FREEDOM_K22F';  controllerunitstr:'MK22F51212'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;   flashsize:$00080000;   srambase:$20000000; sramsize:$00010000),
+
+      (controllertypestr:'MK64FN1M0VDC12';controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00100000;   srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'MK64FN1M0VLL12';controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00100000;   srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'FREEDOM_K64F';  controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00100000;   srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'MK64FN1M0VLQ12';controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00100000;   srambase:$20000000; sramsize:$00030000),
+      (controllertypestr:'MK64FN1M0VMD12';controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00100000;   srambase:$20000000; sramsize:$00030000),
+
+      (controllertypestr:'MK64FX512VDC12';controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00080000;   srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'MK64FX512VLL12';controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00080000;   srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'MK64FX512VLQ12';controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00080000;   srambase:$20000000; sramsize:$00020000),
+      (controllertypestr:'MK64FX512VMD12';controllerunitstr:'MK64F12'; cputype:cpu_armv7em; fputype:fpu_soft; flashbase:$00000000;      flashsize:$00080000;   srambase:$20000000; sramsize:$00020000),
+
+      { Atmel }
+      (controllertypestr:'ATSAM3X8E';     controllerunitstr:'SAM3X8E'; cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00080000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'ARDUINO_DUE';   controllerunitstr:'SAM3X8E'; cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00080000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
+      (controllertypestr:'FLIP_N_CLICK';  controllerunitstr:'SAM3X8E'; cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00080000; flashsize:$00040000; srambase:$20000000; sramsize:$00010000),
 
 
       { Bare bones }
       { Bare bones }
-      (controllertypestr:'THUMB2_BARE';	controllerunitstr:'THUMB2_BARE';	flashbase:$00000000;	flashsize:$00002000;	srambase:$20000000;	sramsize:$00000400)
+      (controllertypestr:'THUMB2_BARE';	controllerunitstr:'THUMB2_BARE';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$20000000;	sramsize:$00000400)
     );
     );
 
 
    vfp_scalar = [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_fpv4_s16];
    vfp_scalar = [fpu_vfpv2,fpu_vfpv3,fpu_vfpv3_d16,fpu_fpv4_s16];
@@ -765,7 +984,8 @@ Const
 
 
  type
  type
    tcpuflags =
    tcpuflags =
-      (CPUARM_HAS_BX,         { CPU supports the BX instruction                           }
+      (CPUARM_HAS_ALL_MEM,    { CPU supports LDRSB/LDRSH/LDRH/STRH instructions           }
+       CPUARM_HAS_BX,         { CPU supports the BX instruction                           }
        CPUARM_HAS_BLX,        { CPU supports the BLX rX instruction                       }
        CPUARM_HAS_BLX,        { CPU supports the BLX rX instruction                       }
        CPUARM_HAS_BLX_LABEL,  { CPU supports the BLX <label> instruction                  }
        CPUARM_HAS_BLX_LABEL,  { CPU supports the BLX <label> instruction                  }
        CPUARM_HAS_CLZ,        { CPU supports the CLZ instruction                          }
        CPUARM_HAS_CLZ,        { CPU supports the CLZ instruction                          }
@@ -784,23 +1004,23 @@ Const
    cpu_capabilities : array[tcputype] of set of tcpuflags =
    cpu_capabilities : array[tcputype] of set of tcpuflags =
      ( { cpu_none     } [],
      ( { cpu_none     } [],
        { cpu_armv3    } [],
        { cpu_armv3    } [],
-       { cpu_armv4    } [CPUARM_HAS_UMULL],
-       { cpu_armv4t   } [CPUARM_HAS_BX,CPUARM_HAS_UMULL],
-       { cpu_armv5    } [CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
-       { cpu_armv5t   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
-       { cpu_armv5te  } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
-       { cpu_armv5tej } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
-       { cpu_armv6    } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
-       { cpu_armv6k   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
-       { cpu_armv6t2  } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv6z   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
-       { cpu_armv6m   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_REV],
+       { cpu_armv4    } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_UMULL],
+       { cpu_armv4t   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_UMULL],
+       { cpu_armv5    } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
+       { cpu_armv5t   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
+       { cpu_armv5te  } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
+       { cpu_armv5tej } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
+       { cpu_armv6    } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
+       { cpu_armv6k   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
+       { cpu_armv6t2  } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv6z   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
+       { cpu_armv6m   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_REV],
        { the identifier armv7 is should not be used, it is considered being equal to armv7a }
        { the identifier armv7 is should not be used, it is considered being equal to armv7a }
-       { cpu_armv7    } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv7a   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv7r   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv7m   } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv7em  } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL]
+       { cpu_armv7    } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv7a   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv7r   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv7m   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv7em  } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL]
      );
      );
 
 
    { contains all CPU supporting any kind of thumb instruction set }
    { contains all CPU supporting any kind of thumb instruction set }

+ 5 - 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:=cpointerdef.getreusable(pdef);
+          pdef:=cpointerdef.getreusable_no_free(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];
@@ -257,7 +257,6 @@ unit cpupara;
       var
       var
         i: longint;
         i: longint;
         sym: tsym;
         sym: tsym;
-        fpufield: boolean;
       begin
       begin
         if handle_common_ret_in_param(def,pd,result) then
         if handle_common_ret_in_param(def,pd,result) then
           exit;
           exit;
@@ -418,7 +417,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:=cpointerdef.getreusable(paradef);
+                paradef:=cpointerdef.getreusable_no_free(paradef);
                 loc:=LOC_REGISTER;
                 loc:=LOC_REGISTER;
                 paracgsize := OS_ADDR;
                 paracgsize := OS_ADDR;
                 paralen := tcgsize2size[OS_ADDR];
                 paralen := tcgsize2size[OS_ADDR];
@@ -512,7 +511,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:=carraydef.getreusable(u8inttype,paralen);
+                            paraloc^.def:=carraydef.getreusable_no_free(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;
@@ -586,7 +585,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:=carraydef.getreusable(u8inttype,paralen);
+                            paraloc^.def:=carraydef.getreusable_no_free(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;
@@ -599,7 +598,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:=cpointerdef.getreusable(paradef);
+                            paraloc^.def:=cpointerdef.getreusable_no_free(paradef);
                             assignintreg
                             assignintreg
                           end
                           end
                         else
                         else

+ 0 - 1
compiler/arm/hlcgcpu.pas

@@ -63,7 +63,6 @@ implementation
       var
       var
         tmpref,
         tmpref,
         href : treference;
         href : treference;
-        extrareg : boolean;
         l : TAsmLabel;
         l : TAsmLabel;
       begin
       begin
         reference_reset_base(href,voidpointertype,NR_R0,0,sizeof(pint));
         reference_reset_base(href,voidpointertype,NR_R0,0,sizeof(pint));

+ 2 - 2
compiler/arm/narmadd.pas

@@ -330,8 +330,8 @@ interface
               else
               else
                 op:=A_VCMPE;
                 op:=A_VCMPE;
 
 
-              current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,
-                left.location.register,right.location.register));
+              current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(op,
+                left.location.register,right.location.register),PF_F32));
               cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
               cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
               current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_VMRS, NR_APSR_nzcv, NR_FPSCR));
               current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_VMRS, NR_APSR_nzcv, NR_FPSCR));
             end;
             end;

+ 0 - 1
compiler/arm/narminl.pas

@@ -380,7 +380,6 @@ implementation
     procedure tarminlinenode.second_abs_long;
     procedure tarminlinenode.second_abs_long;
       var
       var
         opsize : tcgsize;
         opsize : tcgsize;
-        hp : taicpu;
       begin
       begin
         if GenerateThumbCode then
         if GenerateThumbCode then
           begin
           begin

+ 2 - 2
compiler/arm/narmmat.pas

@@ -286,7 +286,8 @@ implementation
                 resultreg:=cg.getintregister(current_asmdata.CurrAsmList,size);
                 resultreg:=cg.getintregister(current_asmdata.CurrAsmList,size);
               end;
               end;
 
 
-            if right.nodetype=ordconstn then
+            if (right.nodetype=ordconstn) and
+               (CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) then
               begin
               begin
                 if nodetype=divn then
                 if nodetype=divn then
                   genOrdConstNodeDiv
                   genOrdConstNodeDiv
@@ -392,7 +393,6 @@ implementation
 
 
     procedure tarmunaryminusnode.second_float;
     procedure tarmunaryminusnode.second_float;
       var
       var
-        op: tasmop;
         pf: TOpPostfix;
         pf: TOpPostfix;
       begin
       begin
         secondpass(left);
         secondpass(left);

+ 1 - 5
compiler/arm/rgcpu.pas

@@ -174,7 +174,6 @@ unit rgcpu;
       var
       var
         tmpref : treference;
         tmpref : treference;
         helplist : TAsmList;
         helplist : TAsmList;
-        l : tasmlabel;
         hreg : tregister;
         hreg : tregister;
         immshift: byte;
         immshift: byte;
         a: aint;
         a: aint;
@@ -283,8 +282,6 @@ unit rgcpu;
 
 
 
 
     function trgcpu.do_spill_replace(list:TAsmList;instr:tai_cpu_abstract_sym;orgreg:tsuperregister;const spilltemp:treference):boolean;
     function trgcpu.do_spill_replace(list:TAsmList;instr:tai_cpu_abstract_sym;orgreg:tsuperregister;const spilltemp:treference):boolean;
-      var
-        b : byte;
       begin
       begin
         result:=false;
         result:=false;
         if abs(spilltemp.offset)>4095 then
         if abs(spilltemp.offset)>4095 then
@@ -611,8 +608,7 @@ unit rgcpu;
     procedure trgintcputhumb.add_cpu_interferences(p: tai);
     procedure trgintcputhumb.add_cpu_interferences(p: tai);
       var
       var
         r : tregister;
         r : tregister;
-        i,
-        hr : longint;
+        i : longint;
       begin
       begin
         if p.typ=ait_instruction then
         if p.typ=ait_instruction then
           begin
           begin

File diff suppressed because it is too large
+ 511 - 317
compiler/assemble.pas


+ 5 - 6
compiler/avr/agavrgas.pas

@@ -29,7 +29,7 @@ unit agavrgas;
   interface
   interface
 
 
     uses
     uses
-       globtype,
+       globtype,systems,
        aasmtai,aasmdata,
        aasmtai,aasmdata,
        aggas,
        aggas,
        cpubase;
        cpubase;
@@ -39,7 +39,7 @@ unit agavrgas;
       { TAVRGNUAssembler }
       { TAVRGNUAssembler }
 
 
       TAVRGNUAssembler=class(TGNUassembler)
       TAVRGNUAssembler=class(TGNUassembler)
-        constructor create(smart: boolean); override;
+        constructor create(info: pasminfo; smart: boolean); override;
        function MakeCmdLine: TCmdStr; override;
        function MakeCmdLine: TCmdStr; override;
       end;
       end;
 
 
@@ -52,7 +52,6 @@ unit agavrgas;
 
 
     uses
     uses
        cutils,globals,verbose,
        cutils,globals,verbose,
-       systems,
        assemble,
        assemble,
        aasmbase,aasmcpu,
        aasmbase,aasmcpu,
        itcpugas,
        itcpugas,
@@ -63,9 +62,9 @@ unit agavrgas;
 {                         GNU Arm Assembler writer                           }
 {                         GNU Arm Assembler writer                           }
 {****************************************************************************}
 {****************************************************************************}
 
 
-    constructor TAVRGNUAssembler.create(smart: boolean);
+    constructor TAVRGNUAssembler.create(info: pasminfo; smart: boolean);
       begin
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter := TAVRInstrWriter.create(self);
         InstrWriter := TAVRInstrWriter.create(self);
       end;
       end;
 
 
@@ -188,7 +187,7 @@ unit agavrgas;
               sep:=',';
               sep:=',';
             end;
             end;
         end;
         end;
-      owner.AsmWriteLn(s);
+      owner.writer.AsmWriteLn(s);
     end;
     end;
 
 
 
 

+ 18 - 8
compiler/avr/aoptcpu.pas

@@ -171,14 +171,19 @@ Implementation
                                     A_INC,A_LSL,A_LSR,
                                     A_INC,A_LSL,A_LSR,
                                     A_OR,A_ORI,A_ROL,A_ROR,A_SBC,A_SBCI,A_SUB,A_SUBI]) and
                                     A_OR,A_ORI,A_ROL,A_ROR,A_SBC,A_SBCI,A_SUB,A_SUBI]) and
               GetNextInstruction(p, hp1) 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
+              ((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])))) or
+               (MatchInstruction(hp1, A_CPI) and
+                (taicpu(p).opcode in [A_ANDI,A_ORI]) and
+                (taicpu(p).oper[1]^.typ=top_const) and
+                (taicpu(hp1).oper[1]^.typ=top_const) and
+                (taicpu(p).oper[1]^.val=taicpu(hp1).oper[1]^.val))) and
               GetNextInstruction(hp1, hp2) and
               GetNextInstruction(hp1, hp2) and
               { be careful here, following instructions could use other flags
               { be careful here, following instructions could use other flags
                 however after a jump fpc never depends on the value of flags }
                 however after a jump fpc never depends on the value of flags }
@@ -203,6 +208,10 @@ Implementation
                   end;
                   end;
                 }
                 }
 
 
+                asml.InsertBefore(tai_regalloc.alloc(NR_DEFAULTFLAGS,p), p);
+                asml.InsertAfter(tai_regalloc.dealloc(NR_DEFAULTFLAGS,hp2), hp2);
+                IncludeRegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs);
+
                 DebugMsg('Peephole OpCp2Op performed', p);
                 DebugMsg('Peephole OpCp2Op performed', p);
 
 
                 asml.remove(hp1);
                 asml.remove(hp1);
@@ -584,6 +593,7 @@ Implementation
                        (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p, hp1)) and
                        (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p, hp1)) and
                        (hp1.typ = ait_instruction) 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,
                        (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_STD,A_ST,
                                                A_OUT,A_IN]) and
                                                A_OUT,A_IN]) and
                        RegInInstruction(taicpu(p).oper[0]^.reg, hp1) and
                        RegInInstruction(taicpu(p).oper[0]^.reg, hp1) and
                        (not RegModifiedByInstruction(taicpu(p).oper[0]^.reg, hp1)) and
                        (not RegModifiedByInstruction(taicpu(p).oper[0]^.reg, hp1)) and

+ 33 - 6
compiler/avr/cgcpu.pas

@@ -308,16 +308,19 @@ unit cgcpu;
       var
       var
         i : longint;
         i : longint;
         hp : PCGParaLocation;
         hp : PCGParaLocation;
+        ref: treference;
       begin
       begin
         if not(tcgsize2size[paraloc.Size] in [1..4]) then
         if not(tcgsize2size[paraloc.Size] in [1..4]) then
           internalerror(2014011101);
           internalerror(2014011101);
 
 
         hp:=paraloc.location;
         hp:=paraloc.location;
 
 
-        for i:=1 to tcgsize2size[paraloc.Size] do
+        i:=1;
+        while i<=tcgsize2size[paraloc.Size] do
           begin
           begin
             if not(assigned(hp)) then
             if not(assigned(hp)) then
               internalerror(2014011105);
               internalerror(2014011105);
+             //paramanager.allocparaloc(list,hp);
              case hp^.loc of
              case hp^.loc of
                LOC_REGISTER,LOC_CREGISTER:
                LOC_REGISTER,LOC_CREGISTER:
                  begin
                  begin
@@ -325,10 +328,20 @@ unit cgcpu;
                      (hp^.shiftval<>0) then
                      (hp^.shiftval<>0) then
                      internalerror(2015041101);
                      internalerror(2015041101);
                    a_load_const_reg(list,hp^.size,(a shr (8*(i-1))) and $ff,hp^.register);
                    a_load_const_reg(list,hp^.size,(a shr (8*(i-1))) and $ff,hp^.register);
+
+                   inc(i,tcgsize2size[hp^.size]);
                    hp:=hp^.Next;
                    hp:=hp^.Next;
                  end;
                  end;
                LOC_REFERENCE,LOC_CREFERENCE:
                LOC_REFERENCE,LOC_CREFERENCE:
-                 list.concat(taicpu.op_const(A_PUSH,(a shr (8*(i-1))) and $ff));
+                 begin
+                   reference_reset(ref,paraloc.alignment);
+                   ref.base:=hp^.reference.index;
+                   ref.offset:=hp^.reference.offset;
+                   a_load_const_ref(list,hp^.size,a shr (8*(i-1)),ref);
+
+                   inc(i,tcgsize2size[hp^.size]);
+                   hp:=hp^.Next;
+                 end;
                else
                else
                  internalerror(2002071004);
                  internalerror(2002071004);
             end;
             end;
@@ -765,7 +778,8 @@ unit cgcpu;
              begin
              begin
                for i:=1 to tcgsize2size[size] do
                for i:=1 to tcgsize2size[size] do
                  begin
                  begin
-                   list.concat(taicpu.op_reg_const(A_ORI,reg,(qword(a) and mask) shr shift));
+                   if ((qword(a) and mask) shr shift)<>0 then
+                     list.concat(taicpu.op_reg_const(A_ORI,reg,(qword(a) and mask) shr shift));
                    NextReg;
                    NextReg;
                    mask:=mask shl 8;
                    mask:=mask shl 8;
                    inc(shift,8);
                    inc(shift,8);
@@ -775,7 +789,10 @@ unit cgcpu;
              begin
              begin
                for i:=1 to tcgsize2size[size] do
                for i:=1 to tcgsize2size[size] do
                  begin
                  begin
-                   list.concat(taicpu.op_reg_const(A_ANDI,reg,(qword(a) and mask) shr shift));
+                   if ((qword(a) and mask) shr shift)=0 then
+                     list.concat(taicpu.op_reg_reg(A_MOV,reg,NR_R1))
+                   else
+                     list.concat(taicpu.op_reg_const(A_ANDI,reg,(qword(a) and mask) shr shift));
                    NextReg;
                    NextReg;
                    mask:=mask shl 8;
                    mask:=mask shl 8;
                    inc(shift,8);
                    inc(shift,8);
@@ -783,7 +800,10 @@ unit cgcpu;
              end;
              end;
            OP_SUB:
            OP_SUB:
              begin
              begin
-               list.concat(taicpu.op_reg_const(A_SUBI,reg,a and mask));
+               if ((a and mask)=1) and (tcgsize2size[size]=1) then
+                 list.concat(taicpu.op_reg(A_DEC,reg))
+               else
+                 list.concat(taicpu.op_reg_const(A_SUBI,reg,a and mask));
                if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
                if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
                  begin
                  begin
                    for i:=2 to tcgsize2size[size] do
                    for i:=2 to tcgsize2size[size] do
@@ -871,6 +891,8 @@ unit cgcpu;
                curvalue:=a and mask;
                curvalue:=a and mask;
                if curvalue=0 then
                if curvalue=0 then
                  list.concat(taicpu.op_reg_reg(A_ADD,reg,NR_R1))
                  list.concat(taicpu.op_reg_reg(A_ADD,reg,NR_R1))
+               else if (curvalue=1) and (tcgsize2size[size]=1) then
+                 list.concat(taicpu.op_reg(A_INC,reg))
                else
                else
                  begin
                  begin
                    tmpreg:=getintregister(list,OS_8);
                    tmpreg:=getintregister(list,OS_8);
@@ -946,7 +968,12 @@ unit cgcpu;
              if ((qword(a) and mask) shr shift)=0 then
              if ((qword(a) and mask) shr shift)=0 then
                emit_mov(list,reg,NR_R1)
                emit_mov(list,reg,NR_R1)
              else
              else
-               list.concat(taicpu.op_reg_const(A_LDI,reg,(qword(a) and mask) shr shift));
+               begin
+                 getcpuregister(list,NR_R26);
+                 list.concat(taicpu.op_reg_const(A_LDI,NR_R26,(qword(a) and mask) shr shift));
+                 a_load_reg_reg(list,OS_8,OS_8,NR_R26,reg);
+                 ungetcpuregister(list,NR_R26);
+               end;
 
 
              mask:=mask shl 8;
              mask:=mask shl 8;
              inc(shift,8);
              inc(shift,8);

+ 155 - 144
compiler/avr/cpuinfo.pas

@@ -204,6 +204,12 @@ Type
       ct_attiny25
       ct_attiny25
      );
      );
 
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 Const
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { Is there support for dealing with multiple microcontrollers available }
    { for this platform? }
    { for this platform? }
@@ -254,6 +260,8 @@ Const
    ((
    ((
         controllertypestr:'';
         controllertypestr:'';
         controllerunitstr:'';
         controllerunitstr:'';
+        cputype: cpu_none;
+        fputype: fpu_soft;
         flashbase:0;
         flashbase:0;
         flashsize:0;
         flashsize:0;
         srambase:0;
         srambase:0;
@@ -264,6 +272,9 @@ Const
         (
         (
         controllertypestr:'AVRSIM';
         controllertypestr:'AVRSIM';
         controllerunitstr:'AVRSIM';
         controllerunitstr:'AVRSIM';
+        
+        cputype: cpu_avr5;
+        fputype: fpu_soft;
         flashbase:0;
         flashbase:0;
         flashsize:$20000;
         flashsize:$20000;
         srambase:0;
         srambase:0;
@@ -271,150 +282,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)
+        ,(controllertypestr:'ATMEGA645'; controllerunitstr:'ATMEGA645'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA165A'; controllerunitstr:'ATMEGA165A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY44A'; controllerunitstr:'ATTINY44A'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA649A'; controllerunitstr:'ATMEGA649A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA32U4'; controllerunitstr:'ATMEGA32U4'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2560; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY26'; controllerunitstr:'ATTINY26'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'AT90USB1287'; controllerunitstr:'AT90USB1287'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:256; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'AT90PWM161'; controllerunitstr:'AT90PWM161'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY48'; controllerunitstr:'ATTINY48'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:256; sramsize:256; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'ATMEGA168P'; controllerunitstr:'ATMEGA168P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY10'; controllerunitstr:'ATTINY10'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:1024; srambase:64; sramsize:32; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATTINY84A'; controllerunitstr:'ATTINY84A'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'AT90USB82'; controllerunitstr:'AT90USB82'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY2313'; controllerunitstr:'ATTINY2313'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATTINY461'; controllerunitstr:'ATTINY461'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA3250PA'; controllerunitstr:'ATMEGA3250PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA3290A'; controllerunitstr:'ATMEGA3290A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA165P'; controllerunitstr:'ATMEGA165P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY43U'; controllerunitstr:'ATTINY43U'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'AT90USB162'; controllerunitstr:'AT90USB162'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA16U4'; controllerunitstr:'ATMEGA16U4'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1280; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY24A'; controllerunitstr:'ATTINY24A'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATMEGA88P'; controllerunitstr:'ATMEGA88P'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY88'; controllerunitstr:'ATTINY88'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'ATMEGA6490P'; controllerunitstr:'ATMEGA6490P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATTINY40'; controllerunitstr:'ATTINY40'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:64; sramsize:256; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATMEGA324P'; controllerunitstr:'ATMEGA324P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY167'; controllerunitstr:'ATTINY167'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA328'; controllerunitstr:'ATMEGA328'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY861'; controllerunitstr:'ATTINY861'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY85'; controllerunitstr:'ATTINY85'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA64M1'; controllerunitstr:'ATMEGA64M1'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA645P'; controllerunitstr:'ATMEGA645P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA8U2'; controllerunitstr:'ATMEGA8U2'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA329A'; controllerunitstr:'ATMEGA329A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA8A'; controllerunitstr:'ATMEGA8A'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA324PA'; controllerunitstr:'ATMEGA324PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA32HVB'; controllerunitstr:'ATMEGA32HVB'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'AT90PWM316'; controllerunitstr:'AT90PWM316'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'AT90PWM3B'; controllerunitstr:'AT90PWM3B'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'AT90USB646'; controllerunitstr:'AT90USB646'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATTINY20'; controllerunitstr:'ATTINY20'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:64; sramsize:128; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATMEGA16'; controllerunitstr:'ATMEGA16'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:96; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA48A'; controllerunitstr:'ATMEGA48A'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATTINY24'; controllerunitstr:'ATTINY24'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATMEGA644'; controllerunitstr:'ATMEGA644'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA1284'; controllerunitstr:'ATMEGA1284'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:256; sramsize:16384; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATA6285'; controllerunitstr:'ATA6285'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:320)
+        ,(controllertypestr:'AT90CAN64'; controllerunitstr:'AT90CAN64'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA48'; controllerunitstr:'ATMEGA48'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'AT90CAN32'; controllerunitstr:'AT90CAN32'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY9'; controllerunitstr:'ATTINY9'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:1024; srambase:64; sramsize:32; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATTINY87'; controllerunitstr:'ATTINY87'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA1281'; controllerunitstr:'ATMEGA1281'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'AT90PWM216'; controllerunitstr:'AT90PWM216'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA3250A'; controllerunitstr:'ATMEGA3250A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA88A'; controllerunitstr:'ATMEGA88A'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA128RFA1'; controllerunitstr:'ATMEGA128RFA1'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:512; sramsize:16384; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA3290PA'; controllerunitstr:'ATMEGA3290PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'AT90PWM81'; controllerunitstr:'AT90PWM81'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:256; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA325P'; controllerunitstr:'ATMEGA325P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY84'; controllerunitstr:'ATTINY84'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA328P'; controllerunitstr:'ATMEGA328P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY13A'; controllerunitstr:'ATTINY13A'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:1024; srambase:96; sramsize:64; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'ATMEGA8'; controllerunitstr:'ATMEGA8'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA1284P'; controllerunitstr:'ATMEGA1284P'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:256; sramsize:16384; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA16U2'; controllerunitstr:'ATMEGA16U2'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY45'; controllerunitstr:'ATTINY45'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA3250'; controllerunitstr:'ATMEGA3250'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA329'; controllerunitstr:'ATMEGA329'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA32A'; controllerunitstr:'ATMEGA32A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:96; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY5'; controllerunitstr:'ATTINY5'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:512; srambase:64; sramsize:32; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'AT90CAN128'; controllerunitstr:'AT90CAN128'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:256; sramsize:4096; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA6490'; controllerunitstr:'ATMEGA6490'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA8515'; controllerunitstr:'ATMEGA8515'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA88PA'; controllerunitstr:'ATMEGA88PA'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA168A'; controllerunitstr:'ATMEGA168A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA128'; controllerunitstr:'ATMEGA128'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:256; sramsize:4096; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'AT90USB1286'; controllerunitstr:'AT90USB1286'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:256; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA164PA'; controllerunitstr:'ATMEGA164PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY828'; controllerunitstr:'ATTINY828'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA88'; controllerunitstr:'ATMEGA88'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA645A'; controllerunitstr:'ATMEGA645A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA3290P'; controllerunitstr:'ATMEGA3290P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA644P'; controllerunitstr:'ATMEGA644P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA164A'; controllerunitstr:'ATMEGA164A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY4313'; controllerunitstr:'ATTINY4313'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA162'; controllerunitstr:'ATMEGA162'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA32C1'; controllerunitstr:'ATMEGA32C1'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA128A'; controllerunitstr:'ATMEGA128A'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:256; sramsize:4096; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA324A'; controllerunitstr:'ATMEGA324A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY13'; controllerunitstr:'ATTINY13'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:1024; srambase:96; sramsize:64; eeprombase:0; eepromsize:64)
+        ,(controllertypestr:'ATMEGA2561'; controllerunitstr:'ATMEGA2561'; cputype: cpu_avr6; fputype:fpu_soft; flashbase:0; flashsize:262144; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA169A'; controllerunitstr:'ATMEGA169A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY261'; controllerunitstr:'ATTINY261'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATMEGA644A'; controllerunitstr:'ATMEGA644A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA3290'; controllerunitstr:'ATMEGA3290'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA64A'; controllerunitstr:'ATMEGA64A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA169P'; controllerunitstr:'ATMEGA169P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA2560'; controllerunitstr:'ATMEGA2560'; cputype: cpu_avr6; fputype:fpu_soft; flashbase:0; flashsize:262144; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA32'; controllerunitstr:'ATMEGA32'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:96; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY861A'; controllerunitstr:'ATTINY861A'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY28'; controllerunitstr:'ATTINY28'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:0; sramsize:0; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATMEGA48P'; controllerunitstr:'ATMEGA48P'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA8535'; controllerunitstr:'ATMEGA8535'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:96; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA168PA'; controllerunitstr:'ATMEGA168PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA16M1'; controllerunitstr:'ATMEGA16M1'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA16HVB'; controllerunitstr:'ATMEGA16HVB'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA164P'; controllerunitstr:'ATMEGA164P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA325A'; controllerunitstr:'ATMEGA325A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA640'; controllerunitstr:'ATMEGA640'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'ATMEGA6450'; controllerunitstr:'ATMEGA6450'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA329P'; controllerunitstr:'ATMEGA329P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATA6286'; controllerunitstr:'ATA6286'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:320)
+        ,(controllertypestr:'AT90USB647'; controllerunitstr:'AT90USB647'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA168'; controllerunitstr:'ATMEGA168'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA6490A'; controllerunitstr:'ATMEGA6490A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA32M1'; controllerunitstr:'ATMEGA32M1'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA64C1'; controllerunitstr:'ATMEGA64C1'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA32U2'; controllerunitstr:'ATMEGA32U2'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:1024; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY4'; controllerunitstr:'ATTINY4'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:512; srambase:64; sramsize:32; eeprombase:0; eepromsize:0)
+        ,(controllertypestr:'ATMEGA644PA'; controllerunitstr:'ATMEGA644PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'AT90PWM1'; controllerunitstr:'AT90PWM1'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY44'; controllerunitstr:'ATTINY44'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA325PA'; controllerunitstr:'ATMEGA325PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA6450A'; controllerunitstr:'ATMEGA6450A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATTINY2313A'; controllerunitstr:'ATTINY2313A'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATMEGA329PA'; controllerunitstr:'ATMEGA329PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATTINY461A'; controllerunitstr:'ATTINY461A'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:96; sramsize:256; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA6450P'; controllerunitstr:'ATMEGA6450P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA64'; controllerunitstr:'ATMEGA64'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA165PA'; controllerunitstr:'ATMEGA165PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA16A'; controllerunitstr:'ATMEGA16A'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:96; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA649'; controllerunitstr:'ATMEGA649'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA1280'; controllerunitstr:'ATMEGA1280'; cputype: cpu_avr51; fputype:fpu_soft; flashbase:0; flashsize:131072; srambase:512; sramsize:8192; eeprombase:0; eepromsize:4096)
+        ,(controllertypestr:'AT90PWM2B'; controllerunitstr:'AT90PWM2B'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:8192; srambase:256; sramsize:512; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATMEGA649P'; controllerunitstr:'ATMEGA649P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:65536; srambase:256; sramsize:4096; eeprombase:0; eepromsize:2048)
+        ,(controllertypestr:'ATMEGA3250P'; controllerunitstr:'ATMEGA3250P'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA48PA'; controllerunitstr:'ATMEGA48PA'; cputype: cpu_avr4; fputype:fpu_soft; flashbase:0; flashsize:4096; srambase:256; sramsize:512; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATTINY1634'; controllerunitstr:'ATTINY1634'; cputype: cpu_avr35; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:256)
+        ,(controllertypestr:'ATMEGA325'; controllerunitstr:'ATMEGA325'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:32768; srambase:256; sramsize:2048; eeprombase:0; eepromsize:1024)
+        ,(controllertypestr:'ATMEGA169PA'; controllerunitstr:'ATMEGA169PA'; cputype: cpu_avr5; fputype:fpu_soft; flashbase:0; flashsize:16384; srambase:256; sramsize:1024; eeprombase:0; eepromsize:512)
+        ,(controllertypestr:'ATTINY261A'; controllerunitstr:'ATTINY261A'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
+        ,(controllertypestr:'ATTINY25'; controllerunitstr:'ATTINY25'; cputype: cpu_avr25; fputype:fpu_soft; flashbase:0; flashsize:2048; srambase:96; sramsize:128; eeprombase:0; eepromsize:128)
    );
    );
 
 
    { Supported optimizations, only used for information }
    { Supported optimizations, only used for information }

+ 2 - 2
compiler/avr/cpupara.pas

@@ -255,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:=cpointerdef.getreusable(paradef);
+                paradef:=cpointerdef.getreusable_no_free(paradef);
                 loc:=LOC_REGISTER;
                 loc:=LOC_REGISTER;
                 paracgsize:=OS_ADDR;
                 paracgsize:=OS_ADDR;
                 paralen:=tcgsize2size[OS_ADDR];
                 paralen:=tcgsize2size[OS_ADDR];
@@ -353,7 +353,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:=cpointerdef.getreusable(paradef);
+                            paraloc^.def:=cpointerdef.getreusable_no_free(paradef);
                             assignintreg
                             assignintreg
                           end
                           end
                         else
                         else

+ 7 - 7
compiler/blockutl.pas

@@ -160,9 +160,9 @@ implementation
       { must be a valid Pascal identifier, because we will reference it when
       { must be a valid Pascal identifier, because we will reference it when
         constructing the block initialiser }
         constructing the block initialiser }
       { we don't have to include the moduleid in this mangledname, because
       { we don't have to include the moduleid in this mangledname, because
-        the invokepd is a local procedure in the current unit -> defid by
-        itself is unique }
-      name:='__FPC_BLOCK_DESCRIPTOR_SIMPLE_'+tostr(invokepd.defid);
+        the invokepd is a local procedure in the current unit -> unique_id_str
+        by itself is unique }
+      name:='__FPC_BLOCK_DESCRIPTOR_SIMPLE_'+invokepd.unique_id_str;
       { already exists -> return }
       { already exists -> return }
       if searchsym(name,srsym,srsymtable) then
       if searchsym(name,srsym,srsymtable) then
         begin
         begin
@@ -174,7 +174,7 @@ implementation
       { find the type of the descriptor structure }
       { find the type of the descriptor structure }
       descriptordef:=search_named_unit_globaltype('BLOCKRTL','FPC_BLOCK_DESCRIPTOR_SIMPLE',true).typedef;
       descriptordef:=search_named_unit_globaltype('BLOCKRTL','FPC_BLOCK_DESCRIPTOR_SIMPLE',true).typedef;
       { create new static variable }
       { create new static variable }
-      descriptor:=cstaticvarsym.create(name,vs_value,descriptordef,[]);
+      descriptor:=cstaticvarsym.create(name,vs_value,descriptordef,[],true);
       symtablestack.top.insert(descriptor);
       symtablestack.top.insert(descriptor);
       include(descriptor.symoptions,sp_internal);
       include(descriptor.symoptions,sp_internal);
       { create typed constant for the descriptor }
       { create typed constant for the descriptor }
@@ -196,7 +196,7 @@ implementation
     begin
     begin
       { the copy() is to ensure we don't overflow the maximum identifier length;
       { the copy() is to ensure we don't overflow the maximum identifier length;
         the combination of owner.moduleid and defid will make the name unique }
         the combination of owner.moduleid and defid will make the name unique }
-      wrappername:='__FPC_BLOCK_INVOKE_'+upper(copy(orgpd.procsym.realname,1,60))+'_'+tostr(orgpd.owner.moduleid)+'_'+tostr(orgpd.defid);
+      wrappername:='__FPC_BLOCK_INVOKE_'+upper(copy(orgpd.procsym.realname,1,60))+'_'+tostr(orgpd.owner.moduleid)+'_'+orgpd.unique_id_str;
       { already an invoke wrapper for this procsym -> reuse }
       { already an invoke wrapper for this procsym -> reuse }
       if searchsym(wrappername,srsym,srsymtable) then
       if searchsym(wrappername,srsym,srsymtable) then
         begin
         begin
@@ -227,7 +227,7 @@ implementation
         begin
         begin
           { alias for the type to invoke the procvar, used in the symcreat
           { alias for the type to invoke the procvar, used in the symcreat
             handling of tsk_block_invoke_procvar }
             handling of tsk_block_invoke_procvar }
-          result.localst.insert(ctypesym.create('__FPC_BLOCK_INVOKE_PV_TYPE',orgpv));
+          result.localst.insert(ctypesym.create('__FPC_BLOCK_INVOKE_PV_TYPE',orgpv,true));
           result.synthetickind:=tsk_block_invoke_procvar;
           result.synthetickind:=tsk_block_invoke_procvar;
         end;
         end;
     end;
     end;
@@ -253,7 +253,7 @@ implementation
       result:=cstaticvarsym.create(
       result:=cstaticvarsym.create(
         '$'+literalname,
         '$'+literalname,
         vs_value,
         vs_value,
-        blockliteraldef,[]);
+        blockliteraldef,[],true);
       include(result.symoptions,sp_internal);
       include(result.symoptions,sp_internal);
       symtablestack.top.insert(result);
       symtablestack.top.insert(result);
       { initialise it }
       { initialise it }

+ 6 - 6
compiler/cclasses.pas

@@ -2881,7 +2881,7 @@ end;
         h: LongWord;
         h: LongWord;
       begin
       begin
         h := FPHash(Key, KeyLen);
         h := FPHash(Key, KeyLen);
-        Entry := @FBucket[h mod FBucketCount];
+        Entry := @FBucket[h and (FBucketCount-1)];
         while Assigned(Entry^) and
         while Assigned(Entry^) and
           not ((Entry^^.HashValue = h) and (Entry^^.KeyLength = KeyLen) and
           not ((Entry^^.HashValue = h) and (Entry^^.KeyLength = KeyLen) and
             (CompareByte(Entry^^.Key^, Key^, KeyLen) = 0)) do
             (CompareByte(Entry^^.Key^, Key^, KeyLen) = 0)) do
@@ -2900,7 +2900,7 @@ end;
           end
           end
         else
         else
           begin
           begin
-            New(Result);
+            GetMem(Result,SizeOfItem);
             if FOwnsKeys then
             if FOwnsKeys then
             begin
             begin
               GetMem(Result^.Key, KeyLen);
               GetMem(Result^.Key, KeyLen);
@@ -2924,13 +2924,13 @@ end;
         i: Integer;
         i: Integer;
         e, n: PHashSetItem;
         e, n: PHashSetItem;
       begin
       begin
-        p := AllocMem(NewCapacity * SizeOfItem);
+        p := AllocMem(NewCapacity * SizeOf(PHashSetItem));
         for i := 0 to FBucketCount-1 do
         for i := 0 to FBucketCount-1 do
           begin
           begin
             e := FBucket[i];
             e := FBucket[i];
             while Assigned(e) do
             while Assigned(e) do
             begin
             begin
-              chain := @p[e^.HashValue mod NewCapacity];
+              chain := @p[e^.HashValue and (NewCapacity-1)];
               n := e^.Next;
               n := e^.Next;
               e^.Next := chain^;
               e^.Next := chain^;
               chain^ := e;
               chain^ := e;
@@ -2988,7 +2988,7 @@ end;
         h: LongWord;
         h: LongWord;
       begin
       begin
         h := FPHash(Key, KeyLen, Tag);
         h := FPHash(Key, KeyLen, Tag);
-        Entry := @PPTagHashSetItem(FBucket)[h mod FBucketCount];
+        Entry := @PPTagHashSetItem(FBucket)[h and (FBucketCount-1)];
         while Assigned(Entry^) and
         while Assigned(Entry^) and
           not ((Entry^^.HashValue = h) and (Entry^^.KeyLength = KeyLen) and
           not ((Entry^^.HashValue = h) and (Entry^^.KeyLength = KeyLen) and
             (Entry^^.Tag = Tag) and (CompareByte(Entry^^.Key^, Key^, KeyLen) = 0)) do
             (Entry^^.Tag = Tag) and (CompareByte(Entry^^.Key^, Key^, KeyLen) = 0)) do
@@ -3007,7 +3007,7 @@ end;
           end
           end
         else
         else
           begin
           begin
-            New(Result);
+            Getmem(Result,SizeOfItem);
             if FOwnsKeys then
             if FOwnsKeys then
             begin
             begin
               GetMem(Result^.Key, KeyLen);
               GetMem(Result^.Key, KeyLen);

+ 4 - 4
compiler/cg64f32.pas

@@ -931,7 +931,7 @@ unit cg64f32;
              { if the high dword = 0, the low dword can be considered a }
              { if the high dword = 0, the low dword can be considered a }
              { simple cardinal                                          }
              { simple cardinal                                          }
              cg.a_label(list,poslabel);
              cg.a_label(list,poslabel);
-             hdef:=corddef.create(u32bit,0,$ffffffff);
+             hdef:=corddef.create(u32bit,0,$ffffffff,false);
 
 
              location_copy(temploc,l);
              location_copy(temploc,l);
              temploc.size:=OS_32;
              temploc.size:=OS_32;
@@ -944,7 +944,7 @@ unit cg64f32;
                end;
                end;
 
 
              hlcg.g_rangecheck(list,temploc,hdef,todef);
              hlcg.g_rangecheck(list,temploc,hdef,todef);
-             hdef.owner.deletedef(hdef);
+             hdef.free;
 
 
              if from_signed and to_signed then
              if from_signed and to_signed then
                begin
                begin
@@ -971,11 +971,11 @@ unit cg64f32;
                  { if we get here, the 64bit value lies between }
                  { if we get here, the 64bit value lies between }
                  { longint($80000000) and -1 (JM)               }
                  { longint($80000000) and -1 (JM)               }
                  cg.a_label(list,neglabel);
                  cg.a_label(list,neglabel);
-                 hdef:=corddef.create(s32bit,int64(longint($80000000)),int64(-1));
+                 hdef:=corddef.create(s32bit,int64(longint($80000000)),int64(-1),false);
                  location_copy(temploc,l);
                  location_copy(temploc,l);
                  temploc.size:=OS_32;
                  temploc.size:=OS_32;
                  hlcg.g_rangecheck(list,temploc,hdef,todef);
                  hlcg.g_rangecheck(list,temploc,hdef,todef);
-                 hdef.owner.deletedef(hdef);
+                 hdef.free;
                  cg.a_label(list,endlabel);
                  cg.a_label(list,endlabel);
                end;
                end;
            end
            end

+ 1 - 0
compiler/cgbase.pas

@@ -101,6 +101,7 @@ interface
          {$ENDIF}
          {$ENDIF}
          {$IFDEF i8086}
          {$IFDEF i8086}
          ,addr_dgroup      // the data segment group
          ,addr_dgroup      // the data segment group
+         ,addr_fardataseg  // the far data segment of the current pascal module (unit or program)
          ,addr_seg         // used for getting the segment of an object, e.g. 'mov ax, SEG symbol'
          ,addr_seg         // used for getting the segment of an object, e.g. 'mov ax, SEG symbol'
          {$ENDIF}
          {$ENDIF}
          {$IFDEF AARCH64}
          {$IFDEF AARCH64}

+ 2 - 2
compiler/cgutils.pas

@@ -141,9 +141,9 @@ unit cgutils;
                 { overlay a 64 Bit register type }
                 { overlay a 64 Bit register type }
                 2 : (register64 : tregister64);
                 2 : (register64 : tregister64);
 {$endif cpu64bitalu}
 {$endif cpu64bitalu}
-{$ifdef avr}
+{$ifdef cpu8bitalu}
                 3 : (registers : array[0..3] of tregister);
                 3 : (registers : array[0..3] of tregister);
-{$endif avr}
+{$endif cpu8bitalu}
               );
               );
             LOC_SUBSETREG,
             LOC_SUBSETREG,
             LOC_CSUBSETREG : (
             LOC_CSUBSETREG : (

+ 7 - 1
compiler/compiler.pas

@@ -370,7 +370,13 @@ begin
           { in case of 50 errors, this could cause another exception,
           { in case of 50 errors, this could cause another exception,
             suppress this exception
             suppress this exception
           }
           }
-          Message(general_f_compilation_aborted);
+          if not exception_raised then
+            begin
+              exception_raised:=true;
+              Message(general_e_exception_raised);
+            end
+          else
+            Message(general_f_compilation_aborted);
         except
         except
           on ECompilerAbort do
           on ECompilerAbort do
             ;
             ;

+ 51 - 49
compiler/cresstr.pas

@@ -37,7 +37,7 @@ uses
 {$endif}
 {$endif}
    cclasses,widestr,
    cclasses,widestr,
    cutils,globtype,globals,systems,
    cutils,globtype,globals,systems,
-   symbase,symconst,symtype,symdef,symsym,
+   symbase,symconst,symtype,symdef,symsym,symtable,
    verbose,fmodule,ppu,
    verbose,fmodule,ppu,
    aasmbase,aasmtai,aasmdata,aasmcnst,
    aasmbase,aasmtai,aasmdata,aasmcnst,
    aasmcpu;
    aasmcpu;
@@ -134,38 +134,36 @@ uses
         namelab,
         namelab,
         valuelab : tasmlabofs;
         valuelab : tasmlabofs;
         resstrlab : tasmsymbol;
         resstrlab : tasmsymbol;
-        endsymlab : tasmsymbol;
         R : TResourceStringItem;
         R : TResourceStringItem;
+        resstrdef: tdef;
         tcb : ttai_typedconstbuilder;
         tcb : ttai_typedconstbuilder;
       begin
       begin
+        resstrdef:=search_system_type('TRESOURCESTRINGRECORD').typedef;
+
         { Put resourcestrings in a new objectfile. Putting it in multiple files
         { Put resourcestrings in a new objectfile. Putting it in multiple files
           makes the linking too dependent on the linker script requiring a SORT(*) for
           makes the linking too dependent on the linker script requiring a SORT(*) for
           the data sections }
           the data sections }
-        tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable,tcalo_new_section]);
-        maybe_new_object_file(current_asmdata.asmlists[al_const]);
-        new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTRTABLE',current_module.localsymtable,''),sizeof(pint));
-
-        maybe_new_object_file(current_asmdata.asmlists[al_resourcestrings]);
-        new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'1_START'),sizeof(pint));
-        current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.createname_global(
-          make_mangledname('RESSTR',current_module.localsymtable,'START'),AT_DATA,0));
-
+        tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable,tcalo_new_section,tcalo_vectorized_dead_strip_start]);
         { Write unitname entry }
         { Write unitname entry }
+        tcb.maybe_begin_aggregate(resstrdef);
         namelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^),getansistringcodepage);
         namelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^),getansistringcodepage);
-        current_asmdata.asmlists[al_resourcestrings].concat(tai_const.Create_sym_offset(namelab.lab,namelab.ofs));
-        current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
-        current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
-        current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_32bit(0));
-{$ifdef cpu64bitaddr}
-        current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_32bit(0));
-{$endif cpu64bitaddr}
+        tcb.emit_string_offset(namelab,length(current_module.localsymtable.name^),st_ansistring,false,charpointertype);
+        tcb.emit_tai(tai_const.create_nil_dataptr,voidpointertype);
+        tcb.emit_tai(tai_const.create_nil_dataptr,voidpointertype);
+        tcb.emit_ord_const(0,u32inttype);
+        tcb.maybe_end_aggregate(resstrdef);
+        current_asmdata.asmlists[al_resourcestrings].concatList(
+          tcb.get_final_asmlist_vectorized_dead_strip(
+            resstrdef,'RESSTR','',current_module.localsymtable,sizeof(pint)
+          )
+        );
+        tcb.free;
 
 
         { Add entries }
         { Add entries }
         R:=TResourceStringItem(List.First);
         R:=TResourceStringItem(List.First);
         while assigned(R) do
         while assigned(R) do
           begin
           begin
-            new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint));
-            { Write default value }
+            tcb:=ctai_typedconstbuilder.create([tcalo_new_section,tcalo_vectorized_dead_strip_item]);
             if assigned(R.value) and (R.len<>0) then
             if assigned(R.value) and (R.len<>0) then
               valuelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,getansistringcodepage)
               valuelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,getansistringcodepage)
             else
             else
@@ -173,10 +171,8 @@ uses
                 valuelab.lab:=nil;
                 valuelab.lab:=nil;
                 valuelab.ofs:=0;
                 valuelab.ofs:=0;
               end;
               end;
-            { Append the name as a ansistring. }
             current_asmdata.asmlists[al_const].concat(cai_align.Create(const_align(sizeof(pint))));
             current_asmdata.asmlists[al_const].concat(cai_align.Create(const_align(sizeof(pint))));
             namelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],@R.Name[1],length(R.name),getansistringcodepage);
             namelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],@R.Name[1],length(R.name),getansistringcodepage);
-
             {
             {
               Resourcestring index:
               Resourcestring index:
                   TResourceStringRecord = Packed Record
                   TResourceStringRecord = Packed Record
@@ -186,35 +182,30 @@ uses
                      HashValue    : LongWord;
                      HashValue    : LongWord;
                    end;
                    end;
             }
             }
-            new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'2_'+r.name),sizeof(pint));
-            resstrlab:=current_asmdata.DefineAsmSymbol(make_mangledname('RESSTR',R.Sym.owner,R.Sym.name),AB_GLOBAL,AT_DATA);
-            current_asmdata.asmlists[al_resourcestrings].concat(tai_symbol.Create_global(resstrlab,0));
-            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.Create_sym_offset(namelab.lab,namelab.ofs));
-            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.Create_sym_offset(valuelab.lab,valuelab.ofs));
-            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.Create_sym_offset(valuelab.lab,valuelab.ofs));
-            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_32bit(longint(R.Hash)));
-{$ifdef cpu64bitaddr}
-            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_32bit(0));
-{$endif cpu64bitaddr}
-            current_asmdata.asmlists[al_resourcestrings].concat(tai_symbol_end.create(resstrlab));
+            tcb.maybe_begin_aggregate(resstrdef);
+            tcb.emit_string_offset(namelab,length(current_module.localsymtable.name^),st_ansistring,false,charpointertype);
+            tcb.emit_string_offset(valuelab,R.Len,st_ansistring,false,charpointertype);
+            tcb.emit_string_offset(valuelab,R.Len,st_ansistring,false,charpointertype);
+            tcb.emit_ord_const(R.hash,u32inttype);
+            tcb.maybe_end_aggregate(resstrdef);
+            current_asmdata.asmlists[al_resourcestrings].concatList(
+              tcb.get_final_asmlist_vectorized_dead_strip(
+                resstrdef,'RESSTR',R.Sym.Name,R.Sym.Owner,sizeof(pint))
+            );
             R:=TResourceStringItem(R.Next);
             R:=TResourceStringItem(R.Next);
+            tcb.free;
           end;
           end;
-        { nothing has been emited to the tcb itself }
+        tcb:=ctai_typedconstbuilder.create([tcalo_new_section,tcalo_vectorized_dead_strip_end]);
+        tcb.begin_anonymous_record(internaltypeprefixName[itp_emptyrec],
+          default_settings.packrecords,sizeof(pint),
+          targetinfos[target_info.system]^.alignment.recordalignmin,
+          targetinfos[target_info.system]^.alignment.maxCrecordalign);
+        current_asmdata.AsmLists[al_resourcestrings].concatList(
+          tcb.get_final_asmlist_vectorized_dead_strip(
+            tcb.end_anonymous_record,'RESSTR','',current_module.localsymtable,sizeof(pint)
+          )
+        );
         tcb.free;
         tcb.free;
-        new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'3_END'),sizeof(pint));
-        endsymlab:=current_asmdata.DefineAsmSymbol(make_mangledname('RESSTR',current_module.localsymtable,'END'),AB_GLOBAL,AT_DATA);
-        current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.create_global(endsymlab,0));
-        { The darwin/ppc64 assembler or linker seems to have trouble       }
-        { if a section ends with a global label without any data after it. }
-        { So for safety, just put a dummy value here.                      }
-        { Further, the regular linker also kills this symbol when turning  }
-        { on smart linking in case no value appears after it, so put the   }
-        { dummy byte there always                                          }
-        { Update: the Mac OS X 10.6 linker orders data that needs to be    }
-        { relocated before all other data, so make this data relocatable,  }
-        { otherwise the end label won't be moved with the rest             }
-        if (target_info.system in (systems_darwin+systems_aix)) then
-          current_asmdata.asmlists[al_resourcestrings].concat(Tai_const.create_sym(endsymlab));
       end;
       end;
 
 
     procedure Tresourcestrings.WriteRSJFile;
     procedure Tresourcestrings.WriteRSJFile;
@@ -237,11 +228,22 @@ uses
             message1(general_e_errorwritingresourcefile,ResFileName);
             message1(general_e_errorwritingresourcefile,ResFileName);
             exit;
             exit;
           end;
           end;
+        { write the data in two formats:
+           a) backward compatible: the plain bytes from the source file
+           b) portable: converted to utf-16
+        }
         writeln(f,'{"version":1,"strings":[');
         writeln(f,'{"version":1,"strings":[');
         R:=TResourceStringItem(List.First);
         R:=TResourceStringItem(List.First);
         while assigned(R) do
         while assigned(R) do
           begin
           begin
-            write(f, '{"hash":',R.Hash,',"name":"',R.Name,'","value":"');
+            write(f, '{"hash":',R.Hash,',"name":"',R.Name,'","sourcebytes":[');
+            for i:=0 to R.Len-1 do
+              begin
+                write(f,ord(R.Value[i]));
+                if i<>R.Len-1 then
+                  write(f,',');
+              end;
+            write(f,'],"value":"');
             initwidestring(W);
             initwidestring(W);
             ascii2unicode(R.Value,R.Len,current_settings.sourcecodepage,W);
             ascii2unicode(R.Value,R.Len,current_settings.sourcecodepage,W);
             for I := 0 to W^.len - 1 do
             for I := 0 to W^.len - 1 do

+ 0 - 2
compiler/cutils.pas

@@ -895,8 +895,6 @@ implementation
       PopCntData : array[0..15] of byte = (0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4);
       PopCntData : array[0..15] of byte = (0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4);
 
 
     function PopCnt(AValue : Byte): Byte;
     function PopCnt(AValue : Byte): Byte;
-      var
-        i : SizeInt;
       begin
       begin
         Result:=PopCntData[AValue and $f]+PopCntData[(AValue shr 4) and $f];
         Result:=PopCntData[AValue and $f]+PopCntData[(AValue shr 4) and $f];
       end;
       end;

+ 69 - 31
compiler/dbgdwarf.pas

@@ -276,6 +276,17 @@ interface
         bit8: boolean;
         bit8: boolean;
       end;
       end;
 
 
+      TDwarfHashSetItem = record
+        HashSetItem: THashSetItem;
+        lab, ref_lab: tasmsymbol;
+        struct_lab: tasmsymbol;
+      end;
+      PDwarfHashSetItem = ^TDwarfHashSetItem;
+
+      TDwarfLabHashSet = class(THashSet)
+        class function SizeOfItem: Integer; override;
+      end;
+
       { TDebugInfoDwarf }
       { TDebugInfoDwarf }
 
 
       TDebugInfoDwarf = class(TDebugInfo)
       TDebugInfoDwarf = class(TDebugInfo)
@@ -293,6 +304,9 @@ interface
         loclist: tdynamicarray;
         loclist: tdynamicarray;
         asmline: TAsmList;
         asmline: TAsmList;
 
 
+        { lookup table for def -> DWARF-labels }
+        dwarflabels: TDwarfLabHashSet;
+
         // The current entry in dwarf_info with the link to the abbrev-section
         // The current entry in dwarf_info with the link to the abbrev-section
         dwarf_info_abbref_tai: tai_const;
         dwarf_info_abbref_tai: tai_const;
         // Empty start-item of the abbrev-searchtree
         // Empty start-item of the abbrev-searchtree
@@ -328,7 +342,7 @@ interface
         procedure set_use_64bit_headers(state: boolean);
         procedure set_use_64bit_headers(state: boolean);
         property use_64bit_headers: Boolean read _use_64bit_headers write set_use_64bit_headers;
         property use_64bit_headers: Boolean read _use_64bit_headers write set_use_64bit_headers;
 
 
-        procedure set_def_dwarf_labs(def:tdef);
+        function get_def_dwarf_labs(def:tdef): PDwarfHashSetItem;
 
 
         { Convenience version of the method below, so the compiler creates the
         { Convenience version of the method below, so the compiler creates the
           tvarrec for us (must only pass one element in the last parameter).  }
           tvarrec for us (must only pass one element in the last parameter).  }
@@ -719,6 +733,16 @@ implementation
         Dispose(SI);
         Dispose(SI);
       end;
       end;
 
 
+
+{****************************************************************************
+                              TDwarfLabHashSet
+****************************************************************************}
+
+    class function TDwarfLabHashSet.SizeOfItem: Integer;
+      begin
+        Result:=sizeof(TDwarfHashSetItem);
+      end;
+
 {****************************************************************************
 {****************************************************************************
                               TDirIndexItem
                               TDirIndexItem
 ****************************************************************************}
 ****************************************************************************}
@@ -915,7 +939,9 @@ implementation
       end;
       end;
 
 
 
 
-    procedure TDebugInfoDwarf.set_def_dwarf_labs(def:tdef);
+    function TDebugInfoDwarf.get_def_dwarf_labs(def:tdef): PDwarfHashSetItem;
+      var
+        needstructdeflab: boolean;
       begin
       begin
         { Keep track of used dwarf entries, this info is only useful for dwarf entries
         { Keep track of used dwarf entries, this info is only useful for dwarf entries
           referenced by the symbols. Definitions will always include all
           referenced by the symbols. Definitions will always include all
@@ -923,18 +949,23 @@ implementation
         if def.dbg_state=dbg_state_unused then
         if def.dbg_state=dbg_state_unused then
           def.dbg_state:=dbg_state_used;
           def.dbg_state:=dbg_state_used;
         { Need a new label? }
         { Need a new label? }
-        if not assigned(def.dwarf_lab) then
+        result:=PDwarfHashSetItem(dwarflabels.FindOrAdd(@def,sizeof(def)));
+        { the other fields besides  Data are not initialised }
+        if not assigned(result^.HashSetItem.Data) then
           begin
           begin
+            { Mark as initialised }
+            result^.HashSetItem.Data:=self;
+            needstructdeflab:=is_implicit_pointer_object_type(def);
             if not(tf_dwarf_only_local_labels in target_info.flags) then
             if not(tf_dwarf_only_local_labels in target_info.flags) then
               begin
               begin
                 if (ds_dwarf_dbg_info_written in def.defstates) then
                 if (ds_dwarf_dbg_info_written in def.defstates) then
                   begin
                   begin
                     if not assigned(def.typesym) then
                     if not assigned(def.typesym) then
                       internalerror(200610011);
                       internalerror(200610011);
-                    def.dwarf_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AT_DATA);
-                    def.dwarf_ref_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AT_DATA);
-                    if is_class_or_interface_or_dispinterface(def) or is_objectpascal_helper(def) then
-                      tobjectdef(def).dwarf_struct_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AT_DATA);
+                    result^.lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AT_DATA);
+                    result^.ref_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AT_DATA);
+                    if needstructdeflab then
+                      result^.struct_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AT_DATA);
                     def.dbg_state:=dbg_state_written;
                     def.dbg_state:=dbg_state_written;
                   end
                   end
                 else
                 else
@@ -945,20 +976,20 @@ implementation
                        (def.owner.symtabletype=globalsymtable) and
                        (def.owner.symtabletype=globalsymtable) and
                        (def.owner.iscurrentunit) then
                        (def.owner.iscurrentunit) then
                       begin
                       begin
-                        def.dwarf_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
-                        def.dwarf_ref_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
-                        if is_class_or_interface_or_dispinterface(def) or is_objectpascal_helper(def) then
-                          tobjectdef(def).dwarf_struct_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
+                        result^.lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
+                        result^.ref_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBGREF',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
+                        if needstructdeflab then
+                          result^.struct_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG2',def.owner,symname(def.typesym, true)),AB_GLOBAL,AT_DATA);
                         include(def.defstates,ds_dwarf_dbg_info_written);
                         include(def.defstates,ds_dwarf_dbg_info_written);
                       end
                       end
                     else
                     else
                       begin
                       begin
                         { The pointer typecast is needed to prevent a problem with range checking
                         { The pointer typecast is needed to prevent a problem with range checking
                           on when the typecast is changed to 'as' }
                           on when the typecast is changed to 'as' }
-                        current_asmdata.getglobaldatalabel(TAsmLabel(pointer(def.dwarf_lab)));
-                        current_asmdata.getglobaldatalabel(TAsmLabel(pointer(def.dwarf_ref_lab)));
-                        if is_implicit_pointer_object_type(def) then
-                          current_asmdata.getglobaldatalabel(TAsmLabel(pointer(tobjectdef(def).dwarf_struct_lab)));
+                        current_asmdata.getglobaldatalabel(TAsmLabel(pointer(result^.lab)));
+                        current_asmdata.getglobaldatalabel(TAsmLabel(pointer(result^.ref_lab)));
+                        if needstructdeflab then
+                          current_asmdata.getglobaldatalabel(TAsmLabel(pointer(result^.struct_lab)));
                       end;
                       end;
                   end;
                   end;
               end
               end
@@ -967,10 +998,10 @@ implementation
                 { The pointer typecast is needed to prevent a problem with range checking
                 { The pointer typecast is needed to prevent a problem with range checking
                   on when the typecast is changed to 'as' }
                   on when the typecast is changed to 'as' }
                 { addrlabel instead of datalabel because it must be a local one }
                 { addrlabel instead of datalabel because it must be a local one }
-                current_asmdata.getaddrlabel(TAsmLabel(pointer(def.dwarf_lab)));
-                current_asmdata.getaddrlabel(TAsmLabel(pointer(def.dwarf_ref_lab)));
-                if is_implicit_pointer_object_type(def) then
-                  current_asmdata.getaddrlabel(TAsmLabel(pointer(tobjectdef(def).dwarf_struct_lab)));
+                current_asmdata.getaddrlabel(TAsmLabel(pointer(result^.lab)));
+                current_asmdata.getaddrlabel(TAsmLabel(pointer(result^.ref_lab)));
+                if needstructdeflab then
+                  current_asmdata.getaddrlabel(TAsmLabel(pointer(result^.struct_lab)));
               end;
               end;
             if def.dbg_state=dbg_state_used then
             if def.dbg_state=dbg_state_used then
               deftowritelist.Add(def);
               deftowritelist.Add(def);
@@ -980,20 +1011,17 @@ implementation
 
 
     function TDebugInfoDwarf.def_dwarf_lab(def: tdef): tasmsymbol;
     function TDebugInfoDwarf.def_dwarf_lab(def: tdef): tasmsymbol;
       begin
       begin
-        set_def_dwarf_labs(def);
-        result:=def.dwarf_lab;
+        result:=get_def_dwarf_labs(def)^.lab;
       end;
       end;
 
 
     function TDebugInfoDwarf.def_dwarf_class_struct_lab(def: tobjectdef): tasmsymbol;
     function TDebugInfoDwarf.def_dwarf_class_struct_lab(def: tobjectdef): tasmsymbol;
       begin
       begin
-        set_def_dwarf_labs(def);
-        result:=def.dwarf_struct_lab;
+        result:=get_def_dwarf_labs(def)^.struct_lab;
       end;
       end;
 
 
     function TDebugInfoDwarf.def_dwarf_ref_lab(def: tdef): tasmsymbol;
     function TDebugInfoDwarf.def_dwarf_ref_lab(def: tdef): tasmsymbol;
       begin
       begin
-        set_def_dwarf_labs(def);
-        result:=def.dwarf_ref_lab;
+        result:=get_def_dwarf_labs(def)^.ref_lab;
       end;
       end;
 
 
     constructor TDebugInfoDwarf.Create;
     constructor TDebugInfoDwarf.Create;
@@ -3117,6 +3145,15 @@ implementation
         storefilepos:=current_filepos;
         storefilepos:=current_filepos;
         current_filepos:=current_module.mainfilepos;
         current_filepos:=current_module.mainfilepos;
 
 
+        if assigned(dwarflabels) then
+          internalerror(2015100301);
+        { one item per def, plus some extra space in case of nested types,
+          externally used types etc (it will grow further if necessary) }
+        i:=current_module.localsymtable.DefList.count*4;
+        if assigned(current_module.globalsymtable) then
+          inc(i,current_module.globalsymtable.DefList.count*2);
+        dwarflabels:=TDwarfLabHashSet.Create(i,true,false);
+
         currabbrevnumber:=0;
         currabbrevnumber:=0;
 
 
         defnumberlist:=TFPObjectList.create(false);
         defnumberlist:=TFPObjectList.create(false);
@@ -3231,16 +3268,15 @@ implementation
         { end of abbrev table }
         { end of abbrev table }
         current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
         current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
 
 
-        { reset all def labels }
+        { reset all def debug states }
         for i:=0 to defnumberlist.count-1 do
         for i:=0 to defnumberlist.count-1 do
           begin
           begin
             def := tdef(defnumberlist[i]);
             def := tdef(defnumberlist[i]);
             if assigned(def) then
             if assigned(def) then
-              begin
-                def.dwarf_lab:=nil;
-                def.dbg_state:=dbg_state_unused;
-              end;
+              def.dbg_state:=dbg_state_unused;
           end;
           end;
+        dwarflabels.free;
+        dwarflabels:=nil;
 
 
         defnumberlist.free;
         defnumberlist.free;
         defnumberlist:=nil;
         defnumberlist:=nil;
@@ -3436,7 +3472,9 @@ implementation
                     if (prevlabel = nil) or
                     if (prevlabel = nil) or
                        { darwin's assembler cannot create an uleb128 of the difference }
                        { darwin's assembler cannot create an uleb128 of the difference }
                        { between to symbols                                            }
                        { between to symbols                                            }
-                       (target_info.system in systems_darwin) then
+                       { same goes for Solaris native assembler                        }
+                       (target_info.system in systems_darwin) or
+                       (target_asm.id=as_solaris_as) then
                       begin
                       begin
                         asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
                         asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
                         asmline.concat(tai_const.create_uleb128bit(1+sizeof(pint)));
                         asmline.concat(tai_const.create_uleb128bit(1+sizeof(pint)));

+ 53 - 9
compiler/defcmp.pas

@@ -45,7 +45,9 @@ interface
           cpo_ignorevarspez,          // ignore parameter access type
           cpo_ignorevarspez,          // ignore parameter access type
           cpo_ignoreframepointer,     // ignore frame pointer parameter (for assignment-compatibility of global procedures to nested procvars)
           cpo_ignoreframepointer,     // ignore frame pointer parameter (for assignment-compatibility of global procedures to nested procvars)
           cpo_compilerproc,
           cpo_compilerproc,
-          cpo_rtlproc
+          cpo_rtlproc,
+          cpo_generic                 // two different undefined defs (or a constraint in the forward) alone or in open arrays are
+                                      // treated as exactly equal (also in open arrays) if they are owned by their respective procdefs
        );
        );
 
 
        tcompare_paras_options = set of tcompare_paras_option;
        tcompare_paras_options = set of tcompare_paras_option;
@@ -1337,18 +1339,16 @@ implementation
                    end;
                    end;
                  pointerdef :
                  pointerdef :
                    begin
                    begin
-{$ifdef x86}
                      { check for far pointers }
                      { check for far pointers }
-                     if (tcpupointerdef(def_from).x86pointertyp<>tcpupointerdef(def_to).x86pointertyp) then
+                     if not tpointerdef(def_from).compatible_with_pointerdef_size(tpointerdef(def_to)) then
                        begin
                        begin
                          if fromtreetype=niln then
                          if fromtreetype=niln then
                            eq:=te_equal
                            eq:=te_equal
                          else
                          else
                            eq:=te_incompatible;
                            eq:=te_incompatible;
                        end
                        end
+                     { the types can be forward type, handle before normal type check !! }
                      else
                      else
-{$endif x86}
-                      { the types can be forward type, handle before normal type check !! }
                       if assigned(def_to.typesym) and
                       if assigned(def_to.typesym) and
                          ((tpointerdef(def_to).pointeddef.typ=forwarddef) or
                          ((tpointerdef(def_to).pointeddef.typ=forwarddef) or
                           (tpointerdef(def_from).pointeddef.typ=forwarddef)) then
                           (tpointerdef(def_from).pointeddef.typ=forwarddef)) then
@@ -1420,7 +1420,7 @@ implementation
                        this is not allowed for complex procvars }
                        this is not allowed for complex procvars }
                      if (is_void(tpointerdef(def_to).pointeddef) or
                      if (is_void(tpointerdef(def_to).pointeddef) or
                          (m_mac_procvar in current_settings.modeswitches)) and
                          (m_mac_procvar in current_settings.modeswitches)) and
-                        tprocvardef(def_from).is_addressonly then
+                        tprocvardef(def_from).compatible_with_pointerdef_size(tpointerdef(def_to)) then
                       begin
                       begin
                         doconv:=tc_equal;
                         doconv:=tc_equal;
                         eq:=te_convert_l1;
                         eq:=te_convert_l1;
@@ -1431,7 +1431,7 @@ implementation
                      { procedure variable can be assigned to an void pointer,
                      { procedure variable can be assigned to an void pointer,
                        this not allowed for methodpointers }
                        this not allowed for methodpointers }
                      if (m_mac_procvar in current_settings.modeswitches) and
                      if (m_mac_procvar in current_settings.modeswitches) and
-                        tprocdef(def_from).is_addressonly then
+                        tprocdef(def_from).compatible_with_pointerdef_size(tpointerdef(def_to)) then
                       begin
                       begin
                         doconv:=tc_proc_2_procvar;
                         doconv:=tc_proc_2_procvar;
                         eq:=te_convert_l2;
                         eq:=te_convert_l2;
@@ -1955,9 +1955,27 @@ implementation
 
 
 
 
     function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
     function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
+
       var
       var
         currpara1,
         currpara1,
         currpara2 : tparavarsym;
         currpara2 : tparavarsym;
+
+        function equal_genfunc_paradefs(def1,def2:tdef):boolean;
+          begin
+            result:=false;
+            if (sp_generic_para in def1.typesym.symoptions) and
+                (sp_generic_para in def2.typesym.symoptions) and
+                (def1.owner=currpara1.owner) and
+                (def2.owner=currpara2.owner) then
+              begin
+                { the forward declaration may have constraints }
+                if not (df_genconstraint in def2.defoptions) and (def2.typ=undefineddef) and
+                    ((def1.typ=undefineddef) or (df_genconstraint in def1.defoptions)) then
+                  result:=true;
+              end
+          end;
+
+      var
         eq,lowesteq : tequaltype;
         eq,lowesteq : tequaltype;
         hpd       : tprocdef;
         hpd       : tprocdef;
         convtype  : tconverttype;
         convtype  : tconverttype;
@@ -2096,9 +2114,32 @@ implementation
                             Message2(type_w_procvar_univ_conflicting_para,currpara1.vardef.typename,currpara2.vardef.typename)
                             Message2(type_w_procvar_univ_conflicting_para,currpara1.vardef.typename,currpara2.vardef.typename)
                         end;
                         end;
                     end
                     end
+                  else if (cpo_generic in cpoptions) then
+                    begin
+                      if equal_genfunc_paradefs(currpara1.vardef,currpara2.vardef) then
+                        eq:=te_exact
+                      else
+                        exit;
+                    end
                   else
                   else
                     exit;
                     exit;
                 end;
                 end;
+              if (eq=te_equal) and
+                  (cpo_generic in cpoptions) then
+                begin
+                  if is_open_array(currpara1.vardef) and
+                      is_open_array(currpara2.vardef) then
+                    begin
+                      if equal_genfunc_paradefs(tarraydef(currpara1.vardef).elementdef,tarraydef(currpara2.vardef).elementdef) then
+                        eq:=te_exact;
+                    end
+                  else
+                    { for the purpose of forward declarations two equal specializations
+                      are considered as exactly equal }
+                    if tstoreddef(currpara1.vardef).is_specialization and
+                        tstoreddef(currpara2.vardef).is_specialization then
+                      eq:=te_exact;
+                end;
               { open strings can never match exactly, since you cannot define }
               { open strings can never match exactly, since you cannot define }
               { a separate "open string" type -> we have to be able to        }
               { a separate "open string" type -> we have to be able to        }
               { consider those as exact when resolving forward definitions.   }
               { consider those as exact when resolving forward definitions.   }
@@ -2185,6 +2226,7 @@ implementation
          { check for method pointer and local procedure pointer:
          { check for method pointer and local procedure pointer:
              a) anything but procvars can be assigned to blocks
              a) anything but procvars can be assigned to blocks
              b) if one is a procedure of object, the other also has to be one
              b) if one is a procedure of object, the other also has to be one
+                ("object static procedure" is equal to procedure as well)
                 (except for block)
                 (except for block)
              c) if one is a pure address, the other also has to be one
              c) if one is a pure address, the other also has to be one
                 except if def1 is a global proc and def2 is a nested procdef
                 except if def1 is a global proc and def2 is a nested procdef
@@ -2201,7 +2243,9 @@ implementation
            { can't explicitly check against procvars here, because
            { can't explicitly check against procvars here, because
              def1 may already be a procvar due to a proc_to_procvar;
              def1 may already be a procvar due to a proc_to_procvar;
              this is checked in the type conversion node itself -> ok }
              this is checked in the type conversion node itself -> ok }
-         else if (def1.is_methodpointer<>def2.is_methodpointer) or  { b) }
+         else if
+            ((def1.is_methodpointer and not (po_staticmethod in def1.procoptions))<> { b) }
+             (def2.is_methodpointer and not (po_staticmethod in def2.procoptions))) or
             ((def1.is_addressonly<>def2.is_addressonly) and         { c) }
             ((def1.is_addressonly<>def2.is_addressonly) and         { c) }
              (is_nested_pd(def1) or
              (is_nested_pd(def1) or
               not is_nested_pd(def2))) or
               not is_nested_pd(def2))) or
@@ -2220,7 +2264,7 @@ implementation
          { check return value and options, methodpointer is already checked }
          { check return value and options, methodpointer is already checked }
          po_comp:=[po_interrupt,po_iocheck,po_varargs];
          po_comp:=[po_interrupt,po_iocheck,po_varargs];
          { check static only if we compare method pointers }
          { check static only if we compare method pointers }
-         if def1.is_methodpointer then
+         if def1.is_methodpointer and def2.is_methodpointer then
            include(po_comp,po_staticmethod);
            include(po_comp,po_staticmethod);
          if (m_delphi in current_settings.modeswitches) then
          if (m_delphi in current_settings.modeswitches) then
            exclude(po_comp,po_varargs);
            exclude(po_comp,po_varargs);

+ 2 - 0
compiler/finput.pas

@@ -148,6 +148,7 @@ interface
           importlibfilename,        { fullname of the import libraryfile }
           importlibfilename,        { fullname of the import libraryfile }
           staticlibfilename,        { fullname of the static libraryfile }
           staticlibfilename,        { fullname of the static libraryfile }
           sharedlibfilename,        { fullname of the shared libraryfile }
           sharedlibfilename,        { fullname of the shared libraryfile }
+          exportfilename,           { fullname of the export file }
           mapfilename,              { fullname of the mapfile }
           mapfilename,              { fullname of the mapfile }
           exefilename,              { fullname of the exefile }
           exefilename,              { fullname of the exefile }
           dbgfilename,              { fullname of the debug info file }
           dbgfilename,              { fullname of the debug info file }
@@ -626,6 +627,7 @@ uses
          ppufilename:=p+n+target_info.unitext;
          ppufilename:=p+n+target_info.unitext;
          importlibfilename:=p+target_info.importlibprefix+n+target_info.importlibext;
          importlibfilename:=p+target_info.importlibprefix+n+target_info.importlibext;
          staticlibfilename:=p+target_info.staticlibprefix+n+target_info.staticlibext;
          staticlibfilename:=p+target_info.staticlibprefix+n+target_info.staticlibext;
+         exportfilename:=p+'exp'+n+target_info.objext;
 
 
          { output dir of exe can be specified separatly }
          { output dir of exe can be specified separatly }
          if AllowOutput and (OutputExeDir<>'') then
          if AllowOutput and (OutputExeDir<>'') then

+ 32 - 0
compiler/fmodule.pas

@@ -1038,6 +1038,38 @@ implementation
             macrosymtablestack.free;
             macrosymtablestack.free;
             macrosymtablestack:=nil;
             macrosymtablestack:=nil;
           end;
           end;
+        extendeddefs.free;
+        extendeddefs:=nil;
+        genericdummysyms.free;
+        genericdummysyms:=nil;
+        waitingforunit.free;
+        waitingforunit:=nil;
+        localmacrosymtable.free;
+        localmacrosymtable:=nil;
+        ptrdefs.free;
+        ptrdefs:=nil;
+        arraydefs.free;
+        arraydefs:=nil;
+        procaddrdefs.free;
+        procaddrdefs:=nil;
+{$ifdef llvm}
+        llvmdefs.free;
+        llvmdefs:=nil;
+{$endif llvm}
+        checkforwarddefs.free;
+        checkforwarddefs:=nil;
+        tcinitcode.free;
+        tcinitcode:=nil;
+        localunitsearchpath.free;
+        localunitsearchpath:=nil;
+        localobjectsearchpath.free;
+        localobjectsearchpath:=nil;
+        localincludesearchpath.free;
+        localincludesearchpath:=nil;
+        locallibrarysearchpath.free;
+        locallibrarysearchpath:=nil;
+        localframeworksearchpath.free;
+        localframeworksearchpath:=nil;
       end;
       end;
 
 
 
 

+ 2 - 2
compiler/fpcdefs.inc

@@ -7,11 +7,9 @@
 
 
 { This reduces the memory requirements a lot }
 { This reduces the memory requirements a lot }
 {$PACKENUM 1}
 {$PACKENUM 1}
-{$ifdef FPC_HAS_VARSETS}
 {$ifndef FPC_BIG_ENDIAN}
 {$ifndef FPC_BIG_ENDIAN}
 { $define USE_PACKSET1}
 { $define USE_PACKSET1}
 {$endif}
 {$endif}
-{$endif FPC_HAS_VARSETS}
 
 
 {$ifdef USE_PACKSET1}
 {$ifdef USE_PACKSET1}
 {$PACKSET 1}
 {$PACKSET 1}
@@ -239,8 +237,10 @@
   (but there we don't support it)
   (but there we don't support it)
 }
 }
 {$ifdef cpu64bitaddr}
 {$ifdef cpu64bitaddr}
+{$ifndef USE_STABS_64}
 {$define NoDbgStabs}
 {$define NoDbgStabs}
 {$endif}
 {$endif}
+{$endif}
 
 
 {$if not defined(FPC_HAS_TYPE_EXTENDED) and defined(i386)}
 {$if not defined(FPC_HAS_TYPE_EXTENDED) and defined(i386)}
 {$error Cross-compiling from systems without support for an 80 bit extended floating point type to i386 is not yet supported at this time }
 {$error Cross-compiling from systems without support for an 80 bit extended floating point type to i386 is not yet supported at this time }

+ 13 - 11
compiler/fppu.pas

@@ -1197,13 +1197,10 @@ var
              position in derefdata is not necessarily at the end }
              position in derefdata is not necessarily at the end }
             derefdata.seek(derefdata.size);
             derefdata.seek(derefdata.size);
          tstoredsymtable(globalsymtable).buildderefimpl;
          tstoredsymtable(globalsymtable).buildderefimpl;
-         if (flags and uf_local_symtable)<>0 then
-           begin
-             tstoredsymtable(localsymtable).buildderef;
-             tstoredsymtable(localsymtable).buildderefimpl;
-           end;
          tunitwpoinfo(wpoinfo).buildderef;
          tunitwpoinfo(wpoinfo).buildderef;
          tunitwpoinfo(wpoinfo).buildderefimpl;
          tunitwpoinfo(wpoinfo).buildderefimpl;
+         if (flags and uf_local_symtable)<>0 then
+           tstoredsymtable(localsymtable).buildderef_registered;
          writederefmap;
          writederefmap;
          writederefdata;
          writederefdata;
 
 
@@ -1477,9 +1474,12 @@ var
           end;
           end;
 
 
         { we can now derefence all pointers to the implementation parts }
         { we can now derefence all pointers to the implementation parts }
-        tstoredsymtable(globalsymtable).derefimpl;
+        tstoredsymtable(globalsymtable).derefimpl(false);
+        { we've just loaded the localsymtable from the ppu file, so everything
+          in it was registered by definition (otherwise it wouldn't have been in
+          there) }
         if assigned(localsymtable) then
         if assigned(localsymtable) then
-            tstoredsymtable(localsymtable).derefimpl;
+          tstoredsymtable(localsymtable).derefimpl(false);
 
 
          { read whole program optimisation-related information }
          { read whole program optimisation-related information }
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
@@ -1608,12 +1608,14 @@ var
                if interface_compiled then
                if interface_compiled then
                  begin
                  begin
                    Message1(unit_u_reresolving_unit,modulename^);
                    Message1(unit_u_reresolving_unit,modulename^);
-                   tstoredsymtable(globalsymtable).deref;
-                   tstoredsymtable(globalsymtable).derefimpl;
+                   tstoredsymtable(globalsymtable).deref(false);
+                   tstoredsymtable(globalsymtable).derefimpl(false);
                    if assigned(localsymtable) then
                    if assigned(localsymtable) then
                     begin
                     begin
-                      tstoredsymtable(localsymtable).deref;
-                      tstoredsymtable(localsymtable).derefimpl;
+                      { we have only builderef(impl)'d the registered symbols of
+                        the localsymtable -> also only deref those again }
+                      tstoredsymtable(localsymtable).deref(true);
+                      tstoredsymtable(localsymtable).derefimpl(true);
                     end;
                     end;
                    if assigned(wpoinfo) then
                    if assigned(wpoinfo) then
                      begin
                      begin

+ 7 - 1
compiler/generic/cpuinfo.pas

@@ -53,6 +53,12 @@ Type
      (ct_none
      (ct_none
      );
      );
 
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 Const
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { Is there support for dealing with multiple microcontrollers available }
    { for this platform? }
    { for this platform? }
@@ -64,7 +70,7 @@ Const
     {$WARN 3177 OFF}
     {$WARN 3177 OFF}
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    (
    (
-      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+      (controllertypestr:''; controllerunitstr:''; cputype:cpu_none; fputype:fpu_none; flashbase:0; flashsize:0; srambase:0; sramsize:0));
    {$POP}
    {$POP}
 
 
    cputypestr : array[tcputype] of string[8] = ('none');
    cputypestr : array[tcputype] of string[8] = ('none');

+ 8 - 1
compiler/globals.pas

@@ -70,7 +70,13 @@ interface
        macmodeswitches =
        macmodeswitches =
          [m_mac,m_cvar_support,m_mac_procvar,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_default_inline];
          [m_mac,m_cvar_support,m_mac_procvar,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_default_inline];
        isomodeswitches =
        isomodeswitches =
-         [m_iso,m_tp_procvar,m_duplicate_names,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus];
+         [m_iso,m_tp_procvar,m_duplicate_names,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_isolike_io,
+          m_isolike_program_para,
+          m_isolike_mod];
+       extpasmodeswitches =
+         [m_extpas,m_tp_procvar,m_duplicate_names,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_isolike_io,
+          m_isolike_program_para,
+          m_isolike_mod];
 
 
        { maximum nesting of routines }
        { maximum nesting of routines }
        maxnesting = 32;
        maxnesting = 32;
@@ -303,6 +309,7 @@ interface
        nwcopyright  : string;
        nwcopyright  : string;
 
 
        codegenerror : boolean;           { true if there is an error reported }
        codegenerror : boolean;           { true if there is an error reported }
+       exception_raised : boolean;           { true if there is an exception reported }
 
 
        block_type : tblock_type;         { type of currently parsed block }
        block_type : tblock_type;         { type of currently parsed block }
 
 

+ 34 - 17
compiler/globtype.pas

@@ -160,7 +160,8 @@ interface
          cs_support_c_operators,
          cs_support_c_operators,
          { generation }
          { generation }
          cs_profile,cs_debuginfo,cs_compilesystem,
          cs_profile,cs_debuginfo,cs_compilesystem,
-         cs_lineinfo,cs_implicit_exceptions,cs_explicit_codepage,
+         cs_lineinfo,cs_implicit_exceptions,
+         cs_explicit_codepage,cs_system_codepage,
          { linking }
          { linking }
          cs_create_smart,cs_create_dynamic,cs_create_pic,
          cs_create_smart,cs_create_dynamic,cs_create_pic,
          { browser switches are back }
          { browser switches are back }
@@ -168,7 +169,8 @@ interface
          { target specific }
          { target specific }
          cs_executable_stack,
          cs_executable_stack,
          { i8086 specific }
          { i8086 specific }
-         cs_huge_code
+         cs_huge_code,
+         cs_win16_smartcallbacks
        );
        );
        tmoduleswitches = set of tmoduleswitch;
        tmoduleswitches = set of tmoduleswitch;
 
 
@@ -194,7 +196,9 @@ interface
          cs_link_strip,cs_link_staticflag,cs_link_on_target,cs_link_extern,cs_link_opt_vtable,
          cs_link_strip,cs_link_staticflag,cs_link_on_target,cs_link_extern,cs_link_opt_vtable,
          cs_link_opt_used_sections,cs_link_separate_dbg_file,
          cs_link_opt_used_sections,cs_link_separate_dbg_file,
          cs_link_map,cs_link_pthread,cs_link_no_default_lib_order,
          cs_link_map,cs_link_pthread,cs_link_no_default_lib_order,
-	 cs_link_native
+         cs_link_native,
+         cs_link_pre_binutils_2_19,
+         cs_link_vlink
        );
        );
        tglobalswitches = set of tglobalswitch;
        tglobalswitches = set of tglobalswitch;
 
 
@@ -247,7 +251,18 @@ interface
            accidental uses of uninitialised values }
            accidental uses of uninitialised values }
          ts_init_locals,
          ts_init_locals,
          { emit a CLD instruction before using the x86 string instructions }
          { emit a CLD instruction before using the x86 string instructions }
-         ts_cld
+         ts_cld,
+         { increment BP before pushing it in the function prologue and decrement
+           it after popping it in the function epilogue, iff the function is
+           going to terminate with a far ret. Thus, the BP value pushed on the
+           stack becomes odd if the function is far and even if the function is
+           near. This allows walking the BP chain on the stack and e.g.
+           obtaining a stack trace even if the program uses a mixture of near
+           and far calls. This is also required for Win16 real mode, because it
+           allows Windows to move code segments around (in order to defragment
+           memory) and then walk through the stacks of all running programs and
+           update the segment values of the segment that has moved. }
+         ts_x86_far_procs_push_odd_bp
        );
        );
        ttargetswitches = set of ttargetswitch;
        ttargetswitches = set of ttargetswitch;
 
 
@@ -296,19 +311,13 @@ interface
        twpoptimizerswitches = set of twpoptimizerswitch;
        twpoptimizerswitches = set of twpoptimizerswitch;
 
 
     type
     type
-       { Used by ARM / AVR / MIPSEL to differentiate between specific microcontrollers }
-       tcontrollerdatatype = record
-          controllertypestr, controllerunitstr: string[20];
-          flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
-       end;
-
        ttargetswitchinfo = record
        ttargetswitchinfo = record
           name: string[22];
           name: string[22];
           { target switch can have an arbitratry value, not only on/off }
           { target switch can have an arbitratry value, not only on/off }
           hasvalue: boolean;
           hasvalue: boolean;
           { target switch can be used only globally }
           { target switch can be used only globally }
           isglobal: boolean;
           isglobal: boolean;
-          define: string[15];
+          define: string[25];
        end;
        end;
 
 
     const
     const
@@ -338,7 +347,8 @@ interface
          (name: 'THUMBINTERWORKING';   hasvalue: false; isglobal: true ; define: ''),
          (name: 'THUMBINTERWORKING';   hasvalue: false; isglobal: true ; define: ''),
          (name: 'LOWERCASEPROCSTART';  hasvalue: false; isglobal: true ; define: ''),
          (name: 'LOWERCASEPROCSTART';  hasvalue: false; isglobal: true ; define: ''),
          (name: 'INITLOCALS';          hasvalue: false; isglobal: true ; define: ''),
          (name: 'INITLOCALS';          hasvalue: false; isglobal: true ; define: ''),
-         (name: 'CLD';                 hasvalue: false; isglobal: true ; define: 'FPC_ENABLED_CLD')
+         (name: 'CLD';                 hasvalue: false; isglobal: true ; define: 'FPC_ENABLED_CLD'),
+         (name: 'FARPROCSPUSHODDBP';   hasvalue: false; isglobal: false; define: 'FPC_FAR_PROCS_PUSH_ODD_BP')
        );
        );
 
 
        { switches being applied to all CPUs at the given level }
        { switches being applied to all CPUs at the given level }
@@ -364,7 +374,7 @@ interface
        { Switches which can be changed by a mode (fpc,tp7,delphi) }
        { Switches which can be changed by a mode (fpc,tp7,delphi) }
        tmodeswitch = (m_none,
        tmodeswitch = (m_none,
          { generic }
          { generic }
-         m_fpc,m_objfpc,m_delphi,m_tp7,m_mac,m_iso,
+         m_fpc,m_objfpc,m_delphi,m_tp7,m_mac,m_iso,m_extpas,
          {$ifdef fpc_mode}m_gpc,{$endif}
          {$ifdef fpc_mode}m_gpc,{$endif}
          { more specific }
          { more specific }
          m_class,               { delphi class model }
          m_class,               { delphi class model }
@@ -402,12 +412,15 @@ interface
                                     ansistring; similarly, char becomes unicodechar rather than ansichar }
                                     ansistring; similarly, char becomes unicodechar rather than ansichar }
          m_type_helpers,        { allows the declaration of "type helper" (non-Delphi) or "record helper"
          m_type_helpers,        { allows the declaration of "type helper" (non-Delphi) or "record helper"
                                   (Delphi) for primitive types }
                                   (Delphi) for primitive types }
-         m_blocks               { support for http://en.wikipedia.org/wiki/Blocks_(C_language_extension) }
+         m_blocks,              { support for http://en.wikipedia.org/wiki/Blocks_(C_language_extension) }
+         m_isolike_io,          { I/O as it required by an ISO compatible compiler }
+         m_isolike_program_para, { program parameters as it required by an ISO compatible compiler }
+         m_isolike_mod          { mod operation as it is required by an iso compatible compiler }
        );
        );
        tmodeswitches = set of tmodeswitch;
        tmodeswitches = set of tmodeswitch;
 
 
     const
     const
-       alllanguagemodes = [m_fpc,m_objfpc,m_delphi,m_tp7,m_mac,m_iso];
+       alllanguagemodes = [m_fpc,m_objfpc,m_delphi,m_tp7,m_mac,m_iso,m_extpas];
 
 
     type
     type
        { Application types (platform specific) }
        { Application types (platform specific) }
@@ -535,7 +548,7 @@ interface
        cstylearrayofconst = [pocall_cdecl,pocall_cppdecl,pocall_mwpascal];
        cstylearrayofconst = [pocall_cdecl,pocall_cppdecl,pocall_mwpascal];
 
 
        modeswitchstr : array[tmodeswitch] of string[18] = ('',
        modeswitchstr : array[tmodeswitch] of string[18] = ('',
-         '','','','','','',
+         '','','','','','','',
          {$ifdef fpc_mode}'',{$endif}
          {$ifdef fpc_mode}'',{$endif}
          { more specific }
          { more specific }
          'CLASS',
          'CLASS',
@@ -568,7 +581,11 @@ interface
          'FINALFIELDS',
          'FINALFIELDS',
          'UNICODESTRINGS',
          'UNICODESTRINGS',
          'TYPEHELPERS',
          'TYPEHELPERS',
-         'CBLOCKS');
+         'CBLOCKS',
+         'ISOIO',
+         'ISOPROGRAMPARAS',
+         'ISOMOD'
+         );
 
 
 
 
      type
      type

+ 89 - 28
compiler/hlcgobj.pas

@@ -532,13 +532,27 @@ unit hlcgobj;
           procedure g_reference_loc(list: TAsmList; def: tdef; const fromloc: tlocation; out toloc: tlocation); virtual;
           procedure g_reference_loc(list: TAsmList; def: tdef; const fromloc: tlocation; out toloc: tlocation); virtual;
 
 
           { typecasts the pointer in reg to a new pointer. By default it does
           { typecasts the pointer in reg to a new pointer. By default it does
-            nothing, only required for type-aware platforms like LLVM }
-          procedure g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tpointerdef; reg: tregister); virtual;
+            nothing, only required for type-aware platforms like LLVM.
+            fromdef/todef are not typed as pointerdef, because they may also be
+            a procvardef or classrefdef. Replaces reg with a new register if
+            necessary }
+          procedure g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tdef; var reg: tregister); virtual;
           { same but for a treference (considers the reference itself, not the
           { same but for a treference (considers the reference itself, not the
             value stored at that place in memory). Replaces ref with a new
             value stored at that place in memory). Replaces ref with a new
-            reference if necessary }
-          procedure g_ptrtypecast_ref(list: TAsmList; fromdef, todef: tpointerdef; var ref: treference); virtual;
-
+            reference if necessary. fromdef needs to be a pointerdef because
+            it may have to be passed as fromdef to a_loadaddr_ref_reg, which
+            needs the "pointeddef" of fromdef }
+          procedure g_ptrtypecast_ref(list: TAsmList; fromdef: tpointerdef; todef: tdef; var ref: treference); virtual;
+
+          { update a reference pointing to the start address of a record/object/
+            class (contents) so it refers to the indicated field }
+          procedure g_set_addr_nonbitpacked_field_ref(list: TAsmList; recdef: tabstractrecorddef; field: tfieldvarsym; var recref: treference); virtual;
+          { load a register/constant into a record field by name }
+         protected
+          procedure g_setup_load_field_by_name(list: TAsmList; recdef: trecorddef; const name: TIDString; const recref: treference; out fref: treference; out fielddef: tdef);
+         public
+          procedure g_load_reg_field_by_name(list: TAsmList; regsize: tdef; recdef: trecorddef; reg: tregister; const name: TIDString; const recref: treference);
+          procedure g_load_const_field_by_name(list: TAsmList; recdef: trecorddef; const name: TIDString; a: tcgint; const recref: treference);
 
 
           { routines migrated from ncgutil }
           { routines migrated from ncgutil }
 
 
@@ -3825,16 +3839,59 @@ implementation
       end;
       end;
     end;
     end;
 
 
-  procedure thlcgobj.g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tpointerdef; reg: tregister);
+  procedure thlcgobj.g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tdef; var reg: tregister);
     begin
     begin
       { nothing to do }
       { nothing to do }
     end;
     end;
 
 
-  procedure thlcgobj.g_ptrtypecast_ref(list: TAsmList; fromdef, todef: tpointerdef; var ref: treference);
+  procedure thlcgobj.g_ptrtypecast_ref(list: TAsmList; fromdef: tpointerdef; todef: tdef; var ref: treference);
     begin
     begin
       { nothing to do }
       { nothing to do }
     end;
     end;
 
 
+  procedure thlcgobj.g_set_addr_nonbitpacked_field_ref(list: TAsmList; recdef: tabstractrecorddef; field: tfieldvarsym; var recref: treference);
+    begin
+      inc(recref.offset,field.fieldoffset);
+      recref.alignment:=newalignment(recref.alignment,field.fieldoffset);
+    end;
+
+
+  procedure thlcgobj.g_setup_load_field_by_name(list: TAsmList; recdef: trecorddef; const name: TIDString; const recref: treference; out fref: treference; out fielddef: tdef);
+    var
+      sym: tsym;
+      field: tfieldvarsym;
+    begin
+      sym:=search_struct_member(recdef,name);
+      if not assigned(sym) or
+         (sym.typ<>fieldvarsym) then
+        internalerror(2015111901);
+      field:=tfieldvarsym(sym);
+      fref:=recref;
+      fielddef:=field.vardef;
+      g_set_addr_nonbitpacked_field_ref(list,recdef,field,fref);
+    end;
+
+
+  procedure thlcgobj.g_load_reg_field_by_name(list: TAsmList; regsize: tdef; recdef: trecorddef; reg: tregister; const name: TIDString; const recref: treference);
+    var
+      fref: treference;
+      fielddef: tdef;
+    begin
+      g_setup_load_field_by_name(list,recdef,name,recref,fref,fielddef);
+      a_load_reg_ref(list,regsize,fielddef,reg,fref);
+    end;
+
+
+  procedure thlcgobj.g_load_const_field_by_name(list: TAsmList; recdef: trecorddef; const name: TIDString; a: tcgint; const recref: treference);
+    var
+      fref: treference;
+      fielddef: tdef;
+    begin
+      g_setup_load_field_by_name(list,recdef,name,recref,fref,fielddef);
+      a_load_const_ref(list,fielddef,a,fref);
+    end;
+
+
   procedure thlcgobj.location_force_reg(list: TAsmList; var l: tlocation; src_size, dst_size: tdef; maybeconst: boolean);
   procedure thlcgobj.location_force_reg(list: TAsmList; var l: tlocation; src_size, dst_size: tdef; maybeconst: boolean);
     var
     var
       hregister,
       hregister,
@@ -4389,22 +4446,6 @@ implementation
           { setinitname may generate a new section -> don't add to the
           { setinitname may generate a new section -> don't add to the
             current list, because we assume this remains a text section }
             current list, because we assume this remains a text section }
           exportlib.setinitname(current_asmdata.AsmLists[al_exports],current_procinfo.procdef.mangledname);
           exportlib.setinitname(current_asmdata.AsmLists[al_exports],current_procinfo.procdef.mangledname);
-
-      if (current_procinfo.procdef.proctypeoption=potype_proginit) then
-        begin
-         if (target_info.system in (systems_darwin+[system_powerpc_macos]+systems_aix)) and
-            not(current_module.islibrary) then
-           begin
-            new_section(list,sec_code,'',4);
-            list.concat(tai_symbol.createname_global(
-              target_info.cprefix+mainaliasname,AT_FUNCTION,0));
-            { keep argc, argv and envp properly on the stack }
-            if not(target_info.system in systems_aix) then
-              cg.a_jmp_name(list,target_info.cprefix+'FPC_SYSTEMMAIN')
-            else
-              cg.a_call_name(list,target_info.cprefix+'FPC_SYSTEMMAIN',false)
-           end;
-        end;
     end;
     end;
 
 
 
 
@@ -4991,7 +5032,7 @@ implementation
                   else
                   else
                     internalerror(2011020507);
                     internalerror(2011020507);
 //                      cg.g_copyvaluepara_packedopenarray(list,href,hsym.intialloc,tarraydef(tparavarsym(p).vardef).elepackedbitsize,hreg);
 //                      cg.g_copyvaluepara_packedopenarray(list,href,hsym.intialloc,tarraydef(tparavarsym(p).vardef).elepackedbitsize,hreg);
-                  a_load_reg_loc(list,tparavarsym(p).vardef,tparavarsym(p).vardef,hreg,tparavarsym(p).initialloc);
+                  a_load_reg_loc(list,cpointerdef.getreusable(tparavarsym(p).vardef),cpointerdef.getreusable(tparavarsym(p).vardef),hreg,tparavarsym(p).initialloc);
                 end;
                 end;
             end
             end
           else
           else
@@ -5114,6 +5155,8 @@ implementation
     end;
     end;
 
 
   procedure thlcgobj.gen_load_loc_cgpara(list: TAsmList; vardef: tdef; const l: tlocation; const cgpara: tcgpara);
   procedure thlcgobj.gen_load_loc_cgpara(list: TAsmList; vardef: tdef; const l: tlocation; const cgpara: tcgpara);
+    var
+      tmploc: tlocation;
     begin
     begin
       { Handle Floating point types differently
       { Handle Floating point types differently
 
 
@@ -5129,6 +5172,18 @@ implementation
           exit;
           exit;
         end;
         end;
 
 
+      { in case of multiple locations, force the source to memory as only
+        a_load_ref_cgpara supports multiple locations }
+      if assigned(cgpara.location^.next) and
+         not(l.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+        begin
+          tmploc:=l;
+          location_force_mem(list,tmploc,vardef);
+          a_load_loc_cgpara(list,vardef,tmploc,cgpara);
+          location_freetemp(list,tmploc);
+          exit;
+        end;
+
       case l.loc of
       case l.loc of
         LOC_CONSTANT,
         LOC_CONSTANT,
         LOC_REGISTER,
         LOC_REGISTER,
@@ -5228,15 +5283,21 @@ implementation
     end;
     end;
 
 
   procedure thlcgobj.record_generated_code_for_procdef(pd: tprocdef; code, data: TAsmList);
   procedure thlcgobj.record_generated_code_for_procdef(pd: tprocdef; code, data: TAsmList);
+    var
+      alt: TAsmListType;
     begin
     begin
+      if not(po_assembler in pd.procoptions) then
+        alt:=al_procedures
+      else
+        alt:=al_pure_assembler;
       { add the procedure to the al_procedures }
       { add the procedure to the al_procedures }
-      maybe_new_object_file(current_asmdata.asmlists[al_procedures]);
-      new_section(current_asmdata.asmlists[al_procedures],sec_code,lower(pd.mangledname),getprocalign);
-      current_asmdata.asmlists[al_procedures].concatlist(code);
+      maybe_new_object_file(current_asmdata.asmlists[alt]);
+      new_section(current_asmdata.asmlists[alt],sec_code,lower(pd.mangledname),getprocalign);
+      current_asmdata.asmlists[alt].concatlist(code);
       { save local data (casetable) also in the same file }
       { save local data (casetable) also in the same file }
       if assigned(data) and
       if assigned(data) and
          (not data.empty) then
          (not data.empty) then
-        current_asmdata.asmlists[al_procedures].concatlist(data);
+        current_asmdata.asmlists[alt].concatlist(data);
     end;
     end;
 
 
   function thlcgobj.g_call_system_proc(list: TAsmList; const procname: string; const paras: array of pcgpara; forceresdef: tdef): tcgpara;
   function thlcgobj.g_call_system_proc(list: TAsmList; const procname: string; const paras: array of pcgpara; forceresdef: tdef): tcgpara;

+ 91 - 24
compiler/htypechk.pas

@@ -28,7 +28,8 @@ interface
     uses
     uses
       cclasses,cmsgs,tokens,cpuinfo,
       cclasses,cmsgs,tokens,cpuinfo,
       node,globtype,
       node,globtype,
-      symconst,symtype,symdef,symsym,symbase;
+      symconst,symtype,symdef,symsym,symbase,
+      pgentype;
 
 
     type
     type
       Ttok2nodeRec=record
       Ttok2nodeRec=record
@@ -69,12 +70,13 @@ interface
         FParaNode   : tnode;
         FParaNode   : tnode;
         FParaLength : smallint;
         FParaLength : smallint;
         FAllowVariant : boolean;
         FAllowVariant : boolean;
-        procedure collect_overloads_in_struct(structdef:tabstractrecorddef;ProcdefOverloadList:TFPObjectList;searchhelpers,anoninherited:boolean);
-        procedure collect_overloads_in_units(ProcdefOverloadList:TFPObjectList; objcidcall,explicitunit: boolean);
-        procedure create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean);
+        procedure collect_overloads_in_struct(structdef:tabstractrecorddef;ProcdefOverloadList:TFPObjectList;searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
+        procedure collect_overloads_in_units(ProcdefOverloadList:TFPObjectList; objcidcall,explicitunit: boolean;spezcontext:tspecializationcontext);
+        procedure create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
         function  proc_add(st:tsymtable;pd:tprocdef;objcidcall: boolean):pcandidate;
         function  proc_add(st:tsymtable;pd:tprocdef;objcidcall: boolean):pcandidate;
+        function  maybe_specialize(var pd:tprocdef;spezcontext:tspecializationcontext):boolean;
       public
       public
-        constructor create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean);
+        constructor create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
         constructor create_operator(op:ttoken;ppn:tnode);
         constructor create_operator(op:ttoken;ppn:tnode);
         destructor destroy;override;
         destructor destroy;override;
         procedure list(all:boolean);
         procedure list(all:boolean);
@@ -187,7 +189,8 @@ implementation
        cutils,verbose,
        cutils,verbose,
        symtable,
        symtable,
        defutil,defcmp,
        defutil,defcmp,
-       nbas,ncnv,nld,nmem,ncal,nmat,ninl,nutils,procinfo
+       nbas,ncnv,nld,nmem,ncal,nmat,ninl,nutils,procinfo,
+       pgenutil
        ;
        ;
 
 
     type
     type
@@ -776,7 +779,7 @@ implementation
 
 
         { the nil as symtable signs firstcalln that this is
         { the nil as symtable signs firstcalln that this is
           an overloaded operator }
           an overloaded operator }
-        t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[]);
+        t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[],nil);
 
 
         { we already know the procdef to use, so it can
         { we already know the procdef to use, so it can
           skip the overload choosing in callnode.pass_typecheck }
           skip the overload choosing in callnode.pass_typecheck }
@@ -955,7 +958,7 @@ implementation
 
 
         { the nil as symtable signs firstcalln that this is
         { the nil as symtable signs firstcalln that this is
           an overloaded operator }
           an overloaded operator }
-        ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[]);
+        ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[],nil);
 
 
         { we already know the procdef to use, so it can
         { we already know the procdef to use, so it can
           skip the overload choosing in callnode.pass_typecheck }
           skip the overload choosing in callnode.pass_typecheck }
@@ -2110,7 +2113,7 @@ implementation
                            TCallCandidates
                            TCallCandidates
 ****************************************************************************}
 ****************************************************************************}
 
 
-    constructor tcallcandidates.create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean);
+    constructor tcallcandidates.create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
       begin
       begin
         if not assigned(sym) then
         if not assigned(sym) then
           internalerror(200411015);
           internalerror(200411015);
@@ -2119,7 +2122,7 @@ implementation
         FProcsymtable:=st;
         FProcsymtable:=st;
         FParanode:=ppn;
         FParanode:=ppn;
         FIgnoredCandidateProcs:=tfpobjectlist.create(false);
         FIgnoredCandidateProcs:=tfpobjectlist.create(false);
-        create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited);
+        create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited,spezcontext);
       end;
       end;
 
 
 
 
@@ -2130,7 +2133,7 @@ implementation
         FProcsymtable:=nil;
         FProcsymtable:=nil;
         FParanode:=ppn;
         FParanode:=ppn;
         FIgnoredCandidateProcs:=tfpobjectlist.create(false);
         FIgnoredCandidateProcs:=tfpobjectlist.create(false);
-        create_candidate_list(false,false,false,false,false,false);
+        create_candidate_list(false,false,false,false,false,false,nil);
       end;
       end;
 
 
 
 
@@ -2144,13 +2147,16 @@ implementation
         while assigned(hp) do
         while assigned(hp) do
          begin
          begin
            hpnext:=hp^.next;
            hpnext:=hp^.next;
+           { free those procdef specializations that are not owned (thus were discarded) }
+           if hp^.data.is_specialization and not hp^.data.is_registered then
+             hp^.data.free;
            dispose(hp);
            dispose(hp);
            hp:=hpnext;
            hp:=hpnext;
          end;
          end;
       end;
       end;
 
 
 
 
-    procedure tcallcandidates.collect_overloads_in_struct(structdef:tabstractrecorddef;ProcdefOverloadList:TFPObjectList;searchhelpers,anoninherited:boolean);
+    procedure tcallcandidates.collect_overloads_in_struct(structdef:tabstractrecorddef;ProcdefOverloadList:TFPObjectList;searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
 
 
       function processprocsym(srsym:tprocsym; out foundanything: boolean):boolean;
       function processprocsym(srsym:tprocsym; out foundanything: boolean):boolean;
         var
         var
@@ -2163,6 +2169,8 @@ implementation
           for j:=0 to srsym.ProcdefList.Count-1 do
           for j:=0 to srsym.ProcdefList.Count-1 do
             begin
             begin
               pd:=tprocdef(srsym.ProcdefList[j]);
               pd:=tprocdef(srsym.ProcdefList[j]);
+              if not maybe_specialize(pd,spezcontext) then
+                continue;
               if (po_ignore_for_overload_resolution in pd.procoptions) then
               if (po_ignore_for_overload_resolution in pd.procoptions) then
                 begin
                 begin
                   FIgnoredCandidateProcs.add(pd);
                   FIgnoredCandidateProcs.add(pd);
@@ -2194,7 +2202,7 @@ implementation
                 FProcsym:=tprocsym(srsym);
                 FProcsym:=tprocsym(srsym);
               if po_overload in pd.procoptions then
               if po_overload in pd.procoptions then
                 result:=true;
                 result:=true;
-              ProcdefOverloadList.Add(srsym.ProcdefList[j]);
+              ProcdefOverloadList.Add(pd);
             end;
             end;
         end;
         end;
 
 
@@ -2275,7 +2283,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcallcandidates.collect_overloads_in_units(ProcdefOverloadList:TFPObjectList; objcidcall,explicitunit: boolean);
+    procedure tcallcandidates.collect_overloads_in_units(ProcdefOverloadList:TFPObjectList; objcidcall,explicitunit: boolean;spezcontext:tspecializationcontext);
       var
       var
         j          : integer;
         j          : integer;
         pd         : tprocdef;
         pd         : tprocdef;
@@ -2332,6 +2340,8 @@ implementation
                     for j:=0 to tprocsym(srsym).ProcdefList.Count-1 do
                     for j:=0 to tprocsym(srsym).ProcdefList.Count-1 do
                       begin
                       begin
                         pd:=tprocdef(tprocsym(srsym).ProcdefList[j]);
                         pd:=tprocdef(tprocsym(srsym).ProcdefList[j]);
+                        if not maybe_specialize(pd,spezcontext) then
+                          continue;
                         if (po_ignore_for_overload_resolution in pd.procoptions) then
                         if (po_ignore_for_overload_resolution in pd.procoptions) then
                           begin
                           begin
                             FIgnoredCandidateProcs.add(pd);
                             FIgnoredCandidateProcs.add(pd);
@@ -2342,7 +2352,7 @@ implementation
                           FProcsym:=tprocsym(srsym);
                           FProcsym:=tprocsym(srsym);
                         if po_overload in pd.procoptions then
                         if po_overload in pd.procoptions then
                           hasoverload:=true;
                           hasoverload:=true;
-                        ProcdefOverloadList.Add(tprocsym(srsym).ProcdefList[j]);
+                        ProcdefOverloadList.Add(pd);
                       end;
                       end;
                     { when there is no explicit overload we stop searching,
                     { when there is no explicit overload we stop searching,
                       except for Objective-C methods called via id }
                       except for Objective-C methods called via id }
@@ -2356,13 +2366,14 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcallcandidates.create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean);
+    procedure tcallcandidates.create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
       var
       var
         j     : integer;
         j     : integer;
         pd    : tprocdef;
         pd    : tprocdef;
         hp    : pcandidate;
         hp    : pcandidate;
         pt    : tcallparanode;
         pt    : tcallparanode;
-        found : boolean;
+        found,
+        added : boolean;
         st    : TSymtable;
         st    : TSymtable;
         contextstructdef : tabstractrecorddef;
         contextstructdef : tabstractrecorddef;
         ProcdefOverloadList : TFPObjectList;
         ProcdefOverloadList : TFPObjectList;
@@ -2375,7 +2386,7 @@ implementation
         if not objcidcall and
         if not objcidcall and
            (FOperator=NOTOKEN) and
            (FOperator=NOTOKEN) and
            (FProcsym.owner.symtabletype in [objectsymtable,recordsymtable]) then
            (FProcsym.owner.symtabletype in [objectsymtable,recordsymtable]) then
-          collect_overloads_in_struct(tabstractrecorddef(FProcsym.owner.defowner),ProcdefOverloadList,searchhelpers,anoninherited)
+          collect_overloads_in_struct(tabstractrecorddef(FProcsym.owner.defowner),ProcdefOverloadList,searchhelpers,anoninherited,spezcontext)
         else
         else
         if (FOperator<>NOTOKEN) then
         if (FOperator<>NOTOKEN) then
           begin
           begin
@@ -2386,13 +2397,13 @@ implementation
               begin
               begin
                 if (pt.resultdef.typ=recorddef) and
                 if (pt.resultdef.typ=recorddef) and
                     (sto_has_operator in tabstractrecorddef(pt.resultdef).owner.tableoptions) then
                     (sto_has_operator in tabstractrecorddef(pt.resultdef).owner.tableoptions) then
-                  collect_overloads_in_struct(tabstractrecorddef(pt.resultdef),ProcdefOverloadList,searchhelpers,anoninherited);
+                  collect_overloads_in_struct(tabstractrecorddef(pt.resultdef),ProcdefOverloadList,searchhelpers,anoninherited,spezcontext);
                 pt:=tcallparanode(pt.right);
                 pt:=tcallparanode(pt.right);
               end;
               end;
-            collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit);
+            collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit,spezcontext);
           end
           end
         else
         else
-          collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit);
+          collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit,spezcontext);
 
 
         { determine length of parameter list.
         { determine length of parameter list.
           for operators also enable the variant-operators if
           for operators also enable the variant-operators if
@@ -2433,6 +2444,7 @@ implementation
         for j:=0 to ProcdefOverloadList.Count-1 do
         for j:=0 to ProcdefOverloadList.Count-1 do
           begin
           begin
             pd:=tprocdef(ProcdefOverloadList[j]);
             pd:=tprocdef(ProcdefOverloadList[j]);
+            added:=false;
 
 
             { only when the # of parameter are supported by the procedure and
             { only when the # of parameter are supported by the procedure and
               it is visible }
               it is visible }
@@ -2452,8 +2464,23 @@ implementation
                ) and
                ) and
                (
                (
                 ignorevisibility or
                 ignorevisibility or
-                not (pd.owner.symtabletype in [objectsymtable,recordsymtable]) or
-                is_visible_for_object(pd,contextstructdef)
+                (
+                  pd.is_specialization and not assigned(pd.owner) and
+                  (
+                    not (pd.genericdef.owner.symtabletype in [objectsymtable,recordsymtable]) or
+                    is_visible_for_object(tprocdef(pd.genericdef),contextstructdef)
+                  )
+                ) or
+                (
+                  (
+                    not pd.is_specialization or
+                    assigned(pd.owner)
+                  ) and
+                  (
+                    not (pd.owner.symtabletype in [objectsymtable,recordsymtable]) or
+                    is_visible_for_object(pd,contextstructdef)
+                  )
+                )
                ) then
                ) then
               begin
               begin
                 { don't add duplicates, only compare visible parameters for the user }
                 { don't add duplicates, only compare visible parameters for the user }
@@ -2476,7 +2503,20 @@ implementation
                     hp:=hp^.next;
                     hp:=hp^.next;
                   end;
                   end;
                 if not found then
                 if not found then
-                  proc_add(st,pd,objcidcall);
+                  begin
+                    proc_add(st,pd,objcidcall);
+                    added:=true;
+                  end;
+              end;
+
+            { we need to remove all specializations that were not used from their
+              procsyms as no code must be generated for them (if they are used
+              later on they'll be added like the ones that were used now) }
+            if not added and assigned(spezcontext) and not pd.is_registered then
+              begin
+                if tprocsym(pd.procsym).procdeflist.extract(pd)<>pd then
+                  internalerror(20150828);
+                pd.free;
               end;
               end;
           end;
           end;
 
 
@@ -2525,6 +2565,33 @@ implementation
       end;
       end;
 
 
 
 
+    function tcallcandidates.maybe_specialize(var pd:tprocdef;spezcontext:tspecializationcontext):boolean;
+      var
+        def : tdef;
+      begin
+        result:=false;
+        if assigned(spezcontext) then
+          begin
+            if not (df_generic in pd.defoptions) then
+              internalerror(2015060301);
+            { check whether the given parameters are compatible
+              to the def's constraints }
+            if not check_generic_constraints(pd,spezcontext.genericdeflist,spezcontext.poslist) then
+              exit;
+            def:=generate_specialization_phase2(spezcontext,pd,false,'');
+            case def.typ of
+              errordef:
+                { do nothing }
+                ;
+              procdef:
+                pd:=tprocdef(def);
+              else
+                internalerror(2015070303);
+            end;
+          end;
+        result:=true;
+      end;
+
     procedure tcallcandidates.list(all:boolean);
     procedure tcallcandidates.list(all:boolean);
       var
       var
         hp : pcandidate;
         hp : pcandidate;

+ 39 - 43
compiler/i386/cgcpu.pas

@@ -36,7 +36,6 @@ unit cgcpu;
     type
     type
       tcg386 = class(tcgx86)
       tcg386 = class(tcgx86)
         procedure init_register_allocators;override;
         procedure init_register_allocators;override;
-        procedure do_register_allocation(list:TAsmList;headertai:tai);override;
 
 
         { passing parameter using push instead of mov }
         { passing parameter using push instead of mov }
         procedure a_load_reg_cgpara(list : TAsmList;size : tcgsize;r : tregister;const cgpara : tcgpara);override;
         procedure a_load_reg_cgpara(list : TAsmList;size : tcgsize;r : tregister;const cgpara : tcgpara);override;
@@ -81,29 +80,15 @@ unit cgcpu;
     procedure tcg386.init_register_allocators;
     procedure tcg386.init_register_allocators;
       begin
       begin
         inherited init_register_allocators;
         inherited init_register_allocators;
-        if not(target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
-           (cs_create_pic in current_settings.moduleswitches) then
-          rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP])
+        if (cs_useebp in current_settings.optimizerswitches) and assigned(current_procinfo) and (current_procinfo.framepointer<>NR_EBP) then
+          rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI,RS_EBP],first_int_imreg,[])
         else
         else
-          if (cs_useebp in current_settings.optimizerswitches) and assigned(current_procinfo) and (current_procinfo.framepointer<>NR_EBP) then
-            rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI,RS_EBP],first_int_imreg,[])
-          else
-            rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
+          rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
         rg[R_MMXREGISTER]:=trgcpu.create(R_MMXREGISTER,R_SUBNONE,[RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7],first_mm_imreg,[]);
         rg[R_MMXREGISTER]:=trgcpu.create(R_MMXREGISTER,R_SUBNONE,[RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7],first_mm_imreg,[]);
         rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBWHOLE,[RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7],first_mm_imreg,[]);
         rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBWHOLE,[RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7],first_mm_imreg,[]);
         rgfpu:=Trgx86fpu.create;
         rgfpu:=Trgx86fpu.create;
       end;
       end;
 
 
-    procedure tcg386.do_register_allocation(list:TAsmList;headertai:tai);
-      begin
-        if (pi_needs_got in current_procinfo.flags) then
-          begin
-            if getsupreg(current_procinfo.got) < first_int_imreg then
-              include(rg[R_INTREGISTER].used_in_proc,getsupreg(current_procinfo.got));
-          end;
-        inherited do_register_allocation(list,headertai);
-      end;
-
 
 
     procedure tcg386.a_load_reg_cgpara(list : TAsmList;size : tcgsize;r : tregister;const cgpara : tcgpara);
     procedure tcg386.a_load_reg_cgpara(list : TAsmList;size : tcgsize;r : tregister;const cgpara : tcgpara);
       var
       var
@@ -310,13 +295,6 @@ unit cgcpu;
         end;
         end;
 
 
       begin
       begin
-        { Release PIC register }
-        if (cs_create_pic in current_settings.moduleswitches) and
-           (tf_pic_uses_got in target_info.flags) and
-           (pi_needs_got in current_procinfo.flags) and
-           not(target_info.system in systems_darwin) then
-          list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil));
-
         { MMX needs to call EMMS }
         { MMX needs to call EMMS }
         if assigned(rg[R_MMXREGISTER]) and
         if assigned(rg[R_MMXREGISTER]) and
            (rg[R_MMXREGISTER].uses_registers) then
            (rg[R_MMXREGISTER].uses_registers) then
@@ -548,26 +526,49 @@ unit cgcpu;
 
 
     procedure tcg386.g_maybe_got_init(list: TAsmList);
     procedure tcg386.g_maybe_got_init(list: TAsmList);
       var
       var
-        notdarwin: boolean;
+        i: longint;
+        tmpreg: TRegister;
       begin
       begin
         { allocate PIC register }
         { allocate PIC register }
         if (cs_create_pic in current_settings.moduleswitches) and
         if (cs_create_pic in current_settings.moduleswitches) and
            (tf_pic_uses_got in target_info.flags) and
            (tf_pic_uses_got in target_info.flags) and
            (pi_needs_got in current_procinfo.flags) then
            (pi_needs_got in current_procinfo.flags) then
           begin
           begin
-            notdarwin:=not(target_info.system in [system_i386_darwin,system_i386_iphonesim]);
-            { on darwin, the got register is virtual (and allocated earlier
-              already) }
-            if notdarwin then
-              { ecx could be used in leaf procedures that don't use ecx to pass
-                aparameter }
-              current_procinfo.got:=NR_EBX;
-            if notdarwin { needs testing before it can be enabled for non-darwin platforms
-                and
-               (current_settings.optimizecputype in [cpu_Pentium2,cpu_Pentium3,cpu_Pentium4]) } then
+            if not (target_info.system in [system_i386_darwin,system_i386_iphonesim]) then
               begin
               begin
-                current_module.requires_ebx_pic_helper:=true;
-                a_call_name_static(list,'fpc_geteipasebx');
+                { Use ECX as a temp register by default }
+                tmpreg:=NR_ECX;
+                { Allocate registers used for parameters to make sure they
+                  never allocated during this PIC init code }
+                for i:=0 to current_procinfo.procdef.paras.Count - 1 do
+                  with tparavarsym(current_procinfo.procdef.paras[i]).paraloc[calleeside].Location^ do
+                    if Loc in [LOC_REGISTER, LOC_CREGISTER] then begin
+                      a_reg_alloc(list, register);
+                      { If ECX is used for a parameter, use EBX as temp }
+                      if getsupreg(register) = RS_ECX then
+                        tmpreg:=NR_EBX;
+                    end;
+
+                if tmpreg = NR_EBX then
+                  begin
+                    { Mark EBX as used in the proc }
+                    include(rg[R_INTREGISTER].used_in_proc,RS_EBX);
+                    current_module.requires_ebx_pic_helper:=true;
+                    a_call_name_static(list,'fpc_geteipasebx');
+                  end
+                else
+                  begin
+                    current_module.requires_ecx_pic_helper:=true;
+                    a_call_name_static(list,'fpc_geteipasecx');
+                  end;
+                list.concat(taicpu.op_sym_ofs_reg(A_ADD,S_L,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),0,tmpreg));
+                list.concat(taicpu.op_reg_reg(A_MOV,S_L,tmpreg,current_procinfo.got));
+
+                { Deallocate parameter registers }
+                for i:=0 to current_procinfo.procdef.paras.Count - 1 do
+                  with tparavarsym(current_procinfo.procdef.paras[i]).paraloc[calleeside].Location^ do
+                    if Loc in [LOC_REGISTER, LOC_CREGISTER] then
+                      a_reg_dealloc(list, register);
               end
               end
             else
             else
               begin
               begin
@@ -579,11 +580,6 @@ unit cgcpu;
                 a_label(list,current_procinfo.CurrGotLabel);
                 a_label(list,current_procinfo.CurrGotLabel);
                 list.concat(taicpu.op_reg(A_POP,S_L,current_procinfo.got))
                 list.concat(taicpu.op_reg(A_POP,S_L,current_procinfo.got))
               end;
               end;
-            if notdarwin then
-              begin
-                list.concat(taicpu.op_sym_ofs_reg(A_ADD,S_L,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),0,NR_PIC_OFFSET_REG));
-                list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
-              end;
           end;
           end;
       end;
       end;
 
 

+ 7 - 1
compiler/i386/cpuinfo.pas

@@ -73,6 +73,12 @@ Type
      (ct_none
      (ct_none
      );
      );
 
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 
 
 Const
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { Is there support for dealing with multiple microcontrollers available }
@@ -85,7 +91,7 @@ Const
     {$WARN 3177 OFF}
     {$WARN 3177 OFF}
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    (
    (
-      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+      (controllertypestr:''; controllerunitstr:''; cputype:cpu_none; fputype:fpu_none; flashbase:0; flashsize:0; srambase:0; sramsize:0));
    {$POP}
    {$POP}
 
 
    { calling conventions supported by the code generator }
    { calling conventions supported by the code generator }

+ 2 - 2
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:=cpointerdef.getreusable(paradef);
+                paradef:=cpointerdef.getreusable_no_free(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:=cpointerdef.getreusable(paradef);
+                        paradef:=cpointerdef.getreusable_no_free(paradef);
                       end
                       end
                     else
                     else
                       begin
                       begin

+ 1 - 2
compiler/i386/cpupi.pas

@@ -97,8 +97,7 @@ unit cpupi;
 
 
     procedure ti386procinfo.allocate_got_register(list: tasmlist);
     procedure ti386procinfo.allocate_got_register(list: tasmlist);
       begin
       begin
-        if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and
-           (cs_create_pic in current_settings.moduleswitches) then
+        if (cs_create_pic in current_settings.moduleswitches) then
           begin
           begin
             got := cg.getaddressregister(list);
             got := cg.getaddressregister(list);
           end;
           end;

+ 2 - 14
compiler/i386/daopt386.pas

@@ -171,8 +171,6 @@ type
 
 
 procedure InsertLLItem(AsmL: TAsmList; prev, foll, new_one: TLinkedListItem);
 procedure InsertLLItem(AsmL: TAsmList; prev, foll, new_one: TLinkedListItem);
 
 
-
-function RefsEqual(const R1, R2: TReference): Boolean;
 function isgp32reg(supreg: tsuperregister): Boolean;
 function isgp32reg(supreg: tsuperregister): Boolean;
 function reginref(supreg: tsuperregister; const ref: treference): boolean;
 function reginref(supreg: tsuperregister; const ref: treference): boolean;
 function RegReadByInstruction(supreg: tsuperregister; hp: tai): boolean;
 function RegReadByInstruction(supreg: tsuperregister; hp: tai): boolean;
@@ -270,7 +268,8 @@ Uses
     {$endif}
     {$endif}
   {$endif}
   {$endif}
 {$endif}
 {$endif}
-  globals, systems, verbose, symconst, cgobj,procinfo;
+  globals, systems, verbose, symconst, cgobj, procinfo,
+  aoptx86;
 
 
 Type
 Type
   TRefCompare = function(const r1, r2: treference; size1, size2: tcgsize): boolean;
   TRefCompare = function(const r1, r2: treference; size1, size2: tcgsize): boolean;
@@ -679,17 +678,6 @@ begin
 end;
 end;
 
 
 
 
-function refsequal(const r1, r2: treference): boolean;
-begin
-  refsequal :=
-    (r1.offset = r2.offset) and
-    (r1.segment = r2.segment) 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);
-end;
-
-
 {$push}
 {$push}
 {$q-}
 {$q-}
 
 

+ 27 - 0
compiler/i386/hlcgcpu.pas

@@ -41,6 +41,7 @@ interface
      protected
      protected
       procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
       procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
      public
      public
+      function a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara; override;
       procedure g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); override;
       procedure g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); override;
       procedure g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); override;
       procedure g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); override;
       procedure g_exception_reason_save(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const href: treference); override;
       procedure g_exception_reason_save(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const href: treference); override;
@@ -56,6 +57,7 @@ interface
 implementation
 implementation
 
 
   uses
   uses
+    globals, procinfo,
     verbose,
     verbose,
     fmodule,systems,
     fmodule,systems,
     aasmbase,aasmtai,
     aasmbase,aasmtai,
@@ -180,6 +182,31 @@ implementation
     end;
     end;
 
 
 
 
+  function thlcgcpu.a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;
+  var
+    need_got_load: boolean;
+  begin
+    { Load GOT address to EBX before calling an external function.
+      It is needed because GOT stubs for external function calls
+      generated by a linker expect EBX as a GOT register. }
+    need_got_load:=not (target_info.system in systems_darwin) and
+                   (cs_create_pic in current_settings.moduleswitches) and
+                   (tf_pic_uses_got in target_info.flags) and
+                   (pi_needs_got in current_procinfo.flags) and
+                   (po_external in pd.procoptions);
+    if need_got_load then
+      begin
+        { Alloc EBX }
+        getcpuregister(list, NR_PIC_OFFSET_REG);
+        list.concat(taicpu.op_reg_reg(A_MOV,S_L,current_procinfo.got,NR_PIC_OFFSET_REG));
+      end;
+    Result:=inherited a_call_name(list, pd, s, paras, forceresdef, weak);
+    { Free EBX }
+    if need_got_load then
+      ungetcpuregister(list, NR_PIC_OFFSET_REG);
+  end;
+
+
   procedure thlcgcpu.g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister);
   procedure thlcgcpu.g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister);
     begin
     begin
       if paramanager.use_fixed_stack then
       if paramanager.use_fixed_stack then

+ 2 - 2
compiler/i386/n386flw.pas

@@ -100,7 +100,7 @@ procedure ti386onnode.pass_generate_code;
     location_reset(location,LOC_VOID,OS_NO);
     location_reset(location,LOC_VOID,OS_NO);
 
 
     oldflowcontrol:=flowcontrol;
     oldflowcontrol:=flowcontrol;
-    flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
+    flowcontrol:=[fc_inflowcontrol];
 
 
     { RTL will put exceptobject into EAX when jumping here }
     { RTL will put exceptobject into EAX when jumping here }
     cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
     cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
@@ -241,7 +241,7 @@ function ti386tryfinallynode.simplify(forinline: boolean): tnode;
       begin
       begin
         finalizepi.code:=right;
         finalizepi.code:=right;
         foreachnodestatic(right,@copy_parasize,finalizepi);
         foreachnodestatic(right,@copy_parasize,finalizepi);
-        right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[]);
+        right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
         firstpass(right);
         firstpass(right);
         { For implicit frames, no actual code is available at this time,
         { For implicit frames, no actual code is available at this time,
           it is added later in assembler form. So store the nested procinfo
           it is added later in assembler form. So store the nested procinfo

+ 2 - 2
compiler/i386/n386ld.pas

@@ -28,10 +28,10 @@ interface
     uses
     uses
       globtype,
       globtype,
       symsym,
       symsym,
-      node,ncgld,pass_1;
+      node,ncgld,nx86ld,pass_1;
 
 
     type
     type
-      ti386loadnode = class(tcgloadnode)
+      ti386loadnode = class(tx86loadnode)
          procedure generate_absaddr_access(vs: tabsolutevarsym); override;
          procedure generate_absaddr_access(vs: tabsolutevarsym); override;
       end;
       end;
 
 

+ 4 - 78
compiler/i386/popt386.pas

@@ -44,7 +44,8 @@ uses
   cobjects,
   cobjects,
 {$endif finaldestdebug}
 {$endif finaldestdebug}
   cpuinfo,cpubase,cgutils,daopt386,
   cpuinfo,cpubase,cgutils,daopt386,
-  cgx86;
+  cgx86,
+  aoptx86;
 
 
 
 
 function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
 function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
@@ -122,7 +123,7 @@ begin
        (taicpu(hp1).opcode = A_FILD))) and
        (taicpu(hp1).opcode = A_FILD))) and
      (taicpu(hp1).oper[0]^.typ = top_ref) and
      (taicpu(hp1).oper[0]^.typ = top_ref) and
      (taicpu(hp1).opsize = taicpu(p).opsize) and
      (taicpu(hp1).opsize = taicpu(p).opsize) and
-     refsEqual(taicpu(p).oper[0]^.ref^, taicpu(hp1).oper[0]^.ref^) then
+     RefsEqual(taicpu(p).oper[0]^.ref^, taicpu(hp1).oper[0]^.ref^) then
     begin
     begin
       { replacing fstp f;fld f by fst f is only valid for extended because of rounding }
       { replacing fstp f;fld f by fst f is only valid for extended because of rounding }
       if (taicpu(p).opsize=S_FX) and
       if (taicpu(p).opsize=S_FX) and
@@ -470,81 +471,6 @@ begin
 end;
 end;
 
 
 
 
-function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
-  begin
-    result :=
-      (instr.typ = ait_instruction) and
-      (taicpu(instr).opcode = op) and
-      ((opsize = []) or (taicpu(instr).opsize in opsize));
-  end;
-
-
-function MatchInstruction(const instr: tai; const op1,op2: TAsmOp; const opsize: topsizes): boolean;
-  begin
-    result :=
-      (instr.typ = ait_instruction) and
-      ((taicpu(instr).opcode = op1) or
-       (taicpu(instr).opcode = op2)
-      ) and
-      ((opsize = []) or (taicpu(instr).opsize in opsize));
-  end;
-
-
-function MatchInstruction(const instr: tai; const op1,op2,op3: TAsmOp; const opsize: topsizes): boolean;
-  begin
-    result :=
-      (instr.typ = ait_instruction) and
-      ((taicpu(instr).opcode = op1) or
-       (taicpu(instr).opcode = op2) or
-       (taicpu(instr).opcode = op3)
-      ) and
-      ((opsize = []) or (taicpu(instr).opsize in opsize));
-  end;
-
-
-function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
-  begin
-    result := (oper.typ = top_reg) and (oper.reg = reg);
-  end;
-
-
-function MatchOperand(const oper: TOper; const a: tcgint): boolean; inline;
-  begin
-    result := (oper.typ = top_const) and (oper.val = a);
-  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
-          internalerror(2013102801);
-      end
-  end;
-
-
-function MatchReference(const ref : treference;base,index : TRegister) : Boolean;
-  begin
-   Result:=(ref.offset=0) and
-     (ref.scalefactor in [0,1]) and
-     (ref.segment=NR_NO) and
-     (ref.symbol=nil) and
-     (ref.relsymbol=nil) and
-     ((base=NR_INVALID) or
-      (ref.base=base)) and
-     ((index=NR_INVALID) or
-      (ref.index=index));
-  end;
-
 { First pass of peephole optimizations }
 { First pass of peephole optimizations }
 procedure PeepHoleOptPass1(Asml: TAsmList; BlockStart, BlockEnd: tai);
 procedure PeepHoleOptPass1(Asml: TAsmList; BlockStart, BlockEnd: tai);
 
 
@@ -2140,7 +2066,7 @@ begin
                                   (taicpu(hp2).condition=C_None) and
                                   (taicpu(hp2).condition=C_None) and
                                   { real label and jump, no further references to the
                                   { real label and jump, no further references to the
                                     label are allowed }
                                     label are allowed }
-                                  (tasmlabel(taicpu(p).oper[0]^.ref^.symbol).getrefs=2) and
+                                  (tasmlabel(taicpu(p).oper[0]^.ref^.symbol).getrefs=1) and
                                   FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol),hp1) then
                                   FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol),hp1) then
                                    begin
                                    begin
                                      l:=0;
                                      l:=0;

+ 65 - 1
compiler/i8086/aoptcpu.pas

@@ -28,14 +28,78 @@ unit aoptcpu;
   Interface
   Interface
 
 
     uses
     uses
-      cpubase, aoptobj, aoptcpub, aopt;
+      cpubase, aoptobj, aoptcpub, aopt,
+      aasmtai;
 
 
     Type
     Type
       TCpuAsmOptimizer = class(TAsmOptimizer)
       TCpuAsmOptimizer = class(TAsmOptimizer)
+        function PeepHoleOptPass1Cpu(var p : tai) : boolean; override;
       End;
       End;
 
 
   Implementation
   Implementation
 
 
+    uses
+      verbose,
+      aoptx86,
+      aasmcpu;
+
+    function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p : tai) : boolean;
+      var
+        hp1 : tai;
+        hp2 : tai;
+      begin
+        result:=false;
+        case p.typ of
+          ait_instruction:
+            begin
+              case taicpu(p).opcode of
+                A_MOV:
+                  begin
+                    if MatchInstruction(p,A_MOV,[S_W]) and
+                      MatchOpType(p,top_ref,top_reg) and
+
+                      GetNextInstruction(p, hp1) and
+                      MatchInstruction(hp1,A_MOV,[S_W]) and
+                      MatchOpType(hp1,top_ref,top_reg) and
+
+                      GetNextInstruction(hp1, hp2) and
+                      MatchInstruction(hp2,A_MOV,[S_W]) and
+                      MatchOpType(hp2,top_reg,top_reg) and
+
+                      not(OpsEqual(taicpu(p).oper[1]^,taicpu(hp1).oper[1]^)) and
+
+                      OpsEqual(taicpu(hp1).oper[1]^,taicpu(hp2).oper[0]^) and
+
+                      (MatchOperand(taicpu(hp2).oper[1]^,NR_ES) or MatchOperand(taicpu(hp2).oper[1]^,NR_DS)) and
+
+                      (taicpu(p).oper[0]^.ref^.base=taicpu(hp1).oper[0]^.ref^.base) and
+                      (taicpu(p).oper[0]^.ref^.index=taicpu(hp1).oper[0]^.ref^.index) and
+                      (taicpu(p).oper[0]^.ref^.segment=taicpu(hp1).oper[0]^.ref^.segment) and
+                      (taicpu(p).oper[0]^.ref^.symbol=taicpu(hp1).oper[0]^.ref^.symbol) and
+                      (taicpu(p).oper[0]^.ref^.relsymbol=taicpu(hp1).oper[0]^.ref^.relsymbol) and
+                      (taicpu(p).oper[0]^.ref^.offset+2=taicpu(hp1).oper[0]^.ref^.offset) and
+                      assigned(FindRegDealloc(taicpu(hp2).oper[0]^.reg,tai(hp2.Next)))  then
+                      begin
+                        case taicpu(hp2).oper[1]^.reg of
+                          NR_DS:
+                            taicpu(p).opcode:=A_LDS;
+                          NR_ES:
+                            taicpu(p).opcode:=A_LES;
+                          else
+                            internalerror(2015092601);
+                        end;
+                        asml.remove(hp1);
+                        hp1.free;
+                        asml.remove(hp2);
+                        hp2.free;
+                        result:=true;
+                      end;
+                  end;
+              end
+            end
+        end;
+      end;
+
 begin
 begin
   casmoptimizer:=TCpuAsmOptimizer;
   casmoptimizer:=TCpuAsmOptimizer;
 end.
 end.

+ 129 - 42
compiler/i8086/cgcpu.pas

@@ -1660,55 +1660,124 @@ unit cgcpu;
         hl_skip: TAsmLabel;
         hl_skip: TAsmLabel;
         invf: TResFlags;
         invf: TResFlags;
         tmpsize: TCgSize;
         tmpsize: TCgSize;
+        tmpopsize: topsize;
       begin
       begin
-        invf := f;
-        inverse_flags(invf);
-
-        case size of
-          OS_8,OS_S8:
-            begin
-              tmpsize:=OS_8;
-              list.concat(Taicpu.op_const_reg(A_MOV, S_B, 0, reg));
+        { optimized case for the carry flag, using ADC/RCL }
+        if f in [F_C,F_B,F_FB] then
+          begin
+            case size of
+              OS_8,OS_S8:
+                begin
+                  tmpsize:=OS_8;
+                  tmpopsize:=S_B;
+                end;
+              OS_16,OS_S16,OS_32,OS_S32:
+                begin
+                  tmpsize:=OS_16;
+                  tmpopsize:=S_W;
+                end;
+              else
+                internalerror(2013123101);
             end;
             end;
-          OS_16,OS_S16,OS_32,OS_S32:
-            begin
-              tmpsize:=OS_16;
-              list.concat(Taicpu.op_const_reg(A_MOV, S_W, 0, reg));
+            list.concat(Taicpu.op_const_reg(A_MOV, tmpopsize, 0, reg));
+            hl_skip:=nil;
+            if f=F_FB then
+              begin
+                current_asmdata.getjumplabel(hl_skip);
+                ai:=Taicpu.op_sym(A_Jcc,S_NO,hl_skip);
+                ai.SetCondition(C_P);
+                ai.is_jmp:=true;
+                list.concat(ai);
+              end;
+            { RCL is faster than ADC on 8086/8088. On the 80286, it is
+              equally fast and it also has the same size. In these cases,
+              we still prefer it over ADC, because it's a better choice in
+              case the register is spilled. }
+            if (cs_opt_size in current_settings.optimizerswitches) or
+               (current_settings.optimizecputype<=cpu_286) then
+              list.concat(Taicpu.op_const_reg(A_RCL, tmpopsize, 1, reg))
+            else
+              { ADC is much faster on the 386. }
+              list.concat(Taicpu.op_reg_reg(A_ADC, tmpopsize, reg, reg));
+            if f=F_FB then
+              a_label(list,hl_skip);
+            a_load_reg_reg(list,tmpsize,size,reg,reg);
+          end
+        { optimized case for the inverted carry flag, using SBB }
+        else if f in [F_NC,F_AE,F_FAE] then
+          begin
+            case size of
+              OS_8,OS_S8:
+                begin
+                  tmpsize:=OS_8;
+                  list.concat(Taicpu.op_const_reg(A_MOV, S_B, 1, reg));
+                  list.concat(Taicpu.op_const_reg(A_SBB, S_B, 0, reg));
+                end;
+              OS_16,OS_S16,OS_32,OS_S32:
+                begin
+                  tmpsize:=OS_16;
+                  list.concat(Taicpu.op_const_reg(A_MOV, S_W, 1, reg));
+                  list.concat(Taicpu.op_const_reg(A_SBB, S_W, 0, reg));
+                end;
+              else
+                internalerror(2013123101);
             end;
             end;
-          else
-            internalerror(2013123101);
-        end;
+            a_load_reg_reg(list,tmpsize,size,reg,reg);
+          end
+        else
+          begin
+            invf := f;
+            inverse_flags(invf);
 
 
-        current_asmdata.getjumplabel(hl_skip);
-        { we can't just forward invf to a_jmp_flags for FA,FAE,FB and FBE, because
-          in the case of NaNs:
-           not(F_FA )<>F_FBE
-           not(F_FAE)<>F_FB
-           not(F_FB )<>F_FAE
-           not(F_FBE)<>F_FA
-        }
-        case f of
-          F_FA,F_FAE:
-            invf:=FPUFlags2Flags[invf];
-          F_FB,F_FBE:
-            begin
-              ai:=Taicpu.op_sym(A_Jcc,S_NO,hl_skip);
-              ai.SetCondition(C_P);
-              ai.is_jmp:=true;
-              list.concat(ai);
-              invf:=FPUFlags2Flags[invf];
+            case size of
+              OS_8,OS_S8:
+                begin
+                  tmpsize:=OS_8;
+                  list.concat(Taicpu.op_const_reg(A_MOV, S_B, 0, reg));
+                end;
+              OS_16,OS_S16,OS_32,OS_S32:
+                begin
+                  tmpsize:=OS_16;
+                  list.concat(Taicpu.op_const_reg(A_MOV, S_W, 0, reg));
+                end;
+              else
+                internalerror(2013123101);
             end;
             end;
-        end;
-        a_jmp_flags(list,invf,hl_skip);
 
 
-        { 16-bit INC is shorter than 8-bit }
-        hreg16:=makeregsize(list,reg,OS_16);
-        list.concat(Taicpu.op_reg(A_INC, S_W, hreg16));
-        makeregsize(list,hreg16,tmpsize);
+            current_asmdata.getjumplabel(hl_skip);
+            { we can't just forward invf to a_jmp_flags for FA,FAE,FB and FBE, because
+              in the case of NaNs:
+               not(F_FA )<>F_FBE
+               not(F_FAE)<>F_FB
+               not(F_FB )<>F_FAE
+               not(F_FBE)<>F_FA
+            }
+            case f of
+              F_FA:
+                invf:=FPUFlags2Flags[invf];
+              F_FAE,F_FB:
+                { F_FAE and F_FB are handled above, using ADC/RCL/SBB }
+                internalerror(2015102101);
+              F_FBE:
+                begin
+                  ai:=Taicpu.op_sym(A_Jcc,S_NO,hl_skip);
+                  ai.SetCondition(C_P);
+                  ai.is_jmp:=true;
+                  list.concat(ai);
+                  invf:=FPUFlags2Flags[invf];
+                end;
+            end;
+            a_jmp_flags(list,invf,hl_skip);
+
+            { 16-bit INC is shorter than 8-bit }
+            hreg16:=makeregsize(list,reg,OS_16);
+            list.concat(Taicpu.op_reg(A_INC, S_W, hreg16));
+            makeregsize(list,hreg16,tmpsize);
 
 
-        a_label(list,hl_skip);
+            a_label(list,hl_skip);
 
 
-        a_load_reg_reg(list,tmpsize,size,reg,reg);
+            a_load_reg_reg(list,tmpsize,size,reg,reg);
+          end;
       end;
       end;
 
 
 
 
@@ -1762,6 +1831,17 @@ unit cgcpu;
         { remove stackframe }
         { remove stackframe }
         if not nostackframe then
         if not nostackframe then
           begin
           begin
+            if (po_exports in current_procinfo.procdef.procoptions) and
+               (target_info.system=system_i8086_win16) then
+              begin
+                list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DI));
+                list.concat(Taicpu.Op_reg(A_POP,S_W,NR_SI));
+              end;
+            if ((current_settings.x86memorymodel=mm_huge) and
+                not (po_interrupt in current_procinfo.procdef.procoptions)) or
+               ((po_exports in current_procinfo.procdef.procoptions) and
+                (target_info.system=system_i8086_win16)) then
+              list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DS));
             if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
             if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
               begin
               begin
                 stacksize:=current_procinfo.calc_stackframe_size;
                 stacksize:=current_procinfo.calc_stackframe_size;
@@ -1776,7 +1856,14 @@ unit cgcpu;
                   cg.a_op_const_reg(list,OP_ADD,OS_ADDR,stacksize,current_procinfo.framepointer);
                   cg.a_op_const_reg(list,OP_ADD,OS_ADDR,stacksize,current_procinfo.framepointer);
               end
               end
             else
             else
-              generate_leave(list);
+              begin
+                generate_leave(list);
+                if ((ts_x86_far_procs_push_odd_bp in current_settings.targetswitches) or
+                    ((po_exports in current_procinfo.procdef.procoptions) and
+                     (target_info.system=system_i8086_win16))) and
+                    is_proc_far(current_procinfo.procdef) then
+                  cg.a_op_const_reg(list,OP_SUB,OS_ADDR,1,current_procinfo.framepointer);
+              end;
             list.concat(tai_regalloc.dealloc(current_procinfo.framepointer,nil));
             list.concat(tai_regalloc.dealloc(current_procinfo.framepointer,nil));
           end;
           end;
 
 

+ 1 - 0
compiler/i8086/cpubase.inc

@@ -38,6 +38,7 @@
         S_YMM
         S_YMM
       );
       );
 
 
+      TOpSizes = set of topsize;
 
 
 {*****************************************************************************
 {*****************************************************************************
                                 Registers
                                 Registers

+ 7 - 1
compiler/i8086/cpuinfo.pas

@@ -73,6 +73,12 @@ Type
      (ct_none
      (ct_none
      );
      );
 
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 
 
 Const
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { Is there support for dealing with multiple microcontrollers available }
@@ -85,7 +91,7 @@ Const
     {$WARN 3177 OFF}
     {$WARN 3177 OFF}
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    (
    (
-      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+      (controllertypestr:''; controllerunitstr:''; cputype:cpu_none; fputype:fpu_none; flashbase:0; flashsize:0; srambase:0; sramsize:0));
    {$POP}
    {$POP}
 
 
    { calling conventions supported by the code generator }
    { calling conventions supported by the code generator }

+ 3 - 3
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:=cpointerdef.getreusable(pdef);
+          pdef:=cpointerdef.getreusable_no_free(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:=cpointerdef.getreusable(paradef);
+                paradef:=cpointerdef.getreusable_no_free(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:=cpointerdef.getreusable(paradef);
+                        paradef:=cpointerdef.getreusable_no_free(paradef);
                       end
                       end
                     else
                     else
                       begin
                       begin

+ 3 - 0
compiler/i8086/cputarg.pas

@@ -38,6 +38,9 @@ implementation
     {$ifndef NOTARGETMSDOS}
     {$ifndef NOTARGETMSDOS}
       ,t_msdos
       ,t_msdos
     {$endif}
     {$endif}
+    {$ifndef NOTARGETWIN}
+      ,t_win16
+    {$endif}
 
 
 {**************************************
 {**************************************
              Assemblers
              Assemblers

+ 18 - 0
compiler/i8086/hlcgcpu.pas

@@ -74,6 +74,8 @@ interface
       procedure a_load_loc_ref(list : TAsmList;fromsize, tosize: tdef; const loc: tlocation; const ref : treference);override;
       procedure a_load_loc_ref(list : TAsmList;fromsize, tosize: tdef; const loc: tlocation; const ref : treference);override;
       procedure a_loadaddr_ref_reg(list : TAsmList;fromsize, tosize : tdef;const ref : treference;r : tregister);override;
       procedure a_loadaddr_ref_reg(list : TAsmList;fromsize, tosize : tdef;const ref : treference;r : tregister);override;
 
 
+      procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: tdef; a: tcgint; reg: TRegister); override;
+
       procedure g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); override;
       procedure g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); override;
       procedure g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); override;
       procedure g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); override;
 
 
@@ -380,6 +382,22 @@ implementation
     end;
     end;
 
 
 
 
+  procedure thlcgcpu.a_op_const_reg(list: TAsmList; Op: TOpCG; size: tdef; a: tcgint; reg: TRegister);
+    begin
+      { implicit pointer types on i8086 follow the default data pointer size for
+        the current memory model }
+      if is_implicit_pointer_object_type(size) or is_implicit_array_pointer(size) then
+        size:=voidpointertype;
+
+      if is_hugepointer(size) then
+        internalerror(2015111201)
+      else if is_farpointer(size) then
+        cg.a_op_const_reg(list,Op,OS_16,a,reg)
+      else
+        inherited a_op_const_reg(list,Op,size,a,reg);
+    end;
+
+
   procedure thlcgcpu.g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister);
   procedure thlcgcpu.g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister);
     begin
     begin
       if paramanager.use_fixed_stack then
       if paramanager.use_fixed_stack then

+ 29 - 4
compiler/i8086/n8086add.pas

@@ -88,6 +88,11 @@ interface
             (rt = pointerconstn) and is_farpointer(rd) and
             (rt = pointerconstn) and is_farpointer(rd) and
             is_constintnode(left) and
             is_constintnode(left) and
             (nodetype=addn)
             (nodetype=addn)
+           ) or
+           (
+            (lt in [pointerconstn,niln]) and is_farpointer(ld) and
+            (rt in [pointerconstn,niln]) and is_farpointer(rd) and
+            (nodetype in [ltn,lten,gtn,gten,equaln,unequaln])
            ) then
            ) then
           begin
           begin
             t:=nil;
             t:=nil;
@@ -143,6 +148,18 @@ interface
                   else
                   else
                     internalerror(2014040606);
                     internalerror(2014040606);
                 end;
                 end;
+              ltn:
+                t:=cordconstnode.create(ord(word(qword(lv))<word(qword(rv))),pasbool8type,true);
+              lten:
+                t:=cordconstnode.create(ord(word(qword(lv))<=word(qword(rv))),pasbool8type,true);
+              gtn:
+                t:=cordconstnode.create(ord(word(qword(lv))>word(qword(rv))),pasbool8type,true);
+              gten:
+                t:=cordconstnode.create(ord(word(qword(lv))>=word(qword(rv))),pasbool8type,true);
+              equaln:
+                t:=cordconstnode.create(ord(lv=rv),pasbool8type,true);
+              unequaln:
+                t:=cordconstnode.create(ord(lv<>rv),pasbool8type,true);
               else
               else
                 internalerror(2014040605);
                 internalerror(2014040605);
             end;
             end;
@@ -886,10 +903,18 @@ interface
                end;
                end;
              LOC_CONSTANT :
              LOC_CONSTANT :
                begin
                begin
-                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_W,aint((right.location.value shr 16) and $FFFF),GetNextReg(left.location.register)));
-                 firstjmp32bitcmp;
-                 current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_W,aint(right.location.value and $FFFF),left.location.register));
-                 secondjmp32bitcmp;
+                 if (right.location.value=0) and (nodetype in [equaln,unequaln]) and (left.location.loc=LOC_REGISTER) then
+                   begin
+                     current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_OR,S_W,GetNextReg(left.location.register),left.location.register));
+                     secondjmp32bitcmp;
+                   end
+                 else
+                   begin
+                     current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_W,aint((right.location.value shr 16) and $FFFF),GetNextReg(left.location.register)));
+                     firstjmp32bitcmp;
+                     current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_W,aint(right.location.value and $FFFF),left.location.register));
+                     secondjmp32bitcmp;
+                   end;
                end;
                end;
              else
              else
                internalerror(200203282);
                internalerror(200203282);

+ 13 - 1
compiler/i8086/n8086cnv.pas

@@ -34,6 +34,7 @@ interface
 
 
        t8086typeconvnode = class(tx86typeconvnode)
        t8086typeconvnode = class(tx86typeconvnode)
        protected
        protected
+         function typecheck_int_to_int: tnode;override;
          function typecheck_proc_to_procvar: tnode;override;
          function typecheck_proc_to_procvar: tnode;override;
          procedure second_proc_to_procvar;override;
          procedure second_proc_to_procvar;override;
        end;
        end;
@@ -46,11 +47,22 @@ implementation
       aasmbase,aasmtai,aasmdata,aasmcpu,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       symconst,symdef,symcpu,
       symconst,symdef,symcpu,
       cgbase,cga,procinfo,pass_1,pass_2,
       cgbase,cga,procinfo,pass_1,pass_2,
-      ncon,ncal,ncnv,
+      ncon,ncal,ncnv,nmem,n8086mem,
       cpubase,cpuinfo,
       cpubase,cpuinfo,
       cgutils,cgobj,hlcgobj,cgx86,ncgutil,
       cgutils,cgobj,hlcgobj,cgx86,ncgutil,
       tgobj;
       tgobj;
 
 
+    function t8086typeconvnode.typecheck_int_to_int: tnode;
+      begin
+        Result:=inherited typecheck_int_to_int;
+        if (is_16bitint(totypedef) or is_8bitint(totypedef)) and (left.nodetype=addrn) then
+          begin
+            if left.nodetype=addrn then
+              ti8086addrnode(left).get_offset_only:=true;
+          end;
+      end;
+
+
     function t8086typeconvnode.typecheck_proc_to_procvar: tnode;
     function t8086typeconvnode.typecheck_proc_to_procvar: tnode;
       begin
       begin
         if (current_settings.x86memorymodel in x86_far_code_models) and
         if (current_settings.x86memorymodel in x86_far_code_models) and

+ 12 - 1
compiler/i8086/n8086con.pas

@@ -34,6 +34,7 @@ interface
 
 
       ti8086pointerconstnode = class(tcgpointerconstnode)
       ti8086pointerconstnode = class(tcgpointerconstnode)
         constructor create(v : TConstPtrUInt;def:tdef);override;
         constructor create(v : TConstPtrUInt;def:tdef);override;
+        procedure printnodedata(var t: text);override;
         procedure pass_generate_code;override;
         procedure pass_generate_code;override;
       end;
       end;
 
 
@@ -44,7 +45,8 @@ implementation
       symconst,symdef,symcpu,
       symconst,symdef,symcpu,
       defutil,
       defutil,
       cpubase,
       cpubase,
-      cga,cgx86,cgobj,cgbase,cgutils;
+      cga,cgx86,cgobj,cgbase,cgutils,
+      node;
 
 
     {*****************************************************************************
     {*****************************************************************************
                                T8086POINTERCONSTNODE
                                T8086POINTERCONSTNODE
@@ -60,6 +62,15 @@ implementation
       end;
       end;
 
 
 
 
+    procedure ti8086pointerconstnode.printnodedata(var t: text);
+      begin
+        if (typedef.typ=pointerdef) and (tcpupointerdef(typedef).x86pointertyp in [x86pt_far,x86pt_huge]) then
+          writeln(t,printnodeindention,'value = $',hexstr(word(value shr 16),4),':',hexstr(word(value),4))
+        else
+          inherited printnodedata(t);
+      end;
+
+
     procedure ti8086pointerconstnode.pass_generate_code;
     procedure ti8086pointerconstnode.pass_generate_code;
       begin
       begin
         { far pointer? }
         { far pointer? }

+ 174 - 6
compiler/i8086/n8086ld.pas

@@ -28,23 +28,32 @@ interface
     uses
     uses
       globtype,
       globtype,
       symsym,symtype,
       symsym,symtype,
-      node,ncgld;
+      node,ncgld,nx86ld,aasmbase;
 
 
     type
     type
-      ti8086loadnode = class(tcgloadnode)
+
+      { ti8086loadnode }
+
+      ti8086loadnode = class(tx86loadnode)
+        protected
          procedure generate_nested_access(vs: tsym); override;
          procedure generate_nested_access(vs: tsym); override;
          procedure generate_absaddr_access(vs: tabsolutevarsym); override;
          procedure generate_absaddr_access(vs: tabsolutevarsym); override;
+         procedure generate_threadvar_access(gvs: tstaticvarsym); override;
+        public
+         procedure pass_generate_code;override;
       end;
       end;
 
 
 
 
 implementation
 implementation
 
 
     uses
     uses
-      globals,aasmdata,
-      symcpu,
+      globals,verbose,aasmdata,defutil,
+      symconst,symdef,symtable,symcpu,
       nld,
       nld,
-      cgbase,cgobj,
-      cpubase,cpuinfo;
+      cgbase,cgobj,cgutils,
+      hlcgobj,
+      cpubase,cpuinfo,
+      parabase,paramgr;
 
 
 {*****************************************************************************
 {*****************************************************************************
                             TI8086LOADNODE
                             TI8086LOADNODE
@@ -85,6 +94,165 @@ implementation
         inherited;
         inherited;
       end;
       end;
 
 
+    procedure ti8086loadnode.generate_threadvar_access(gvs: tstaticvarsym);
+      var
+        segref: treference;
+        segreg: TRegister;
+        newsize: TCgSize;
+        norelocatelab: TAsmLabel;
+        endrelocatelab: TAsmLabel;
+        pvd: tdef;
+        paraloc1 : tcgpara;
+        hregister: TRegister;
+        href: treference;
+      begin
+        if current_settings.x86memorymodel=mm_huge then
+          begin
+            if (cs_compilesystem in current_settings.moduleswitches) then
+              begin
+                inherited generate_threadvar_access(gvs);
+                exit;
+              end;
+
+            { we don't know the size of all arrays }
+            newsize:=def_cgsize(resultdef);
+            { alignment is overridden per case below }
+            location_reset_ref(location,LOC_REFERENCE,newsize,resultdef.alignment);
+
+            {
+              Thread var loading is optimized to first check if
+              a relocate function is available. When the function
+              is available it is called to retrieve the address.
+              Otherwise the address is loaded with the symbol
+
+              The code needs to be in the order to first handle the
+              call and then the address load to be sure that the
+              register that is used for returning is the same (PFV)
+            }
+            current_asmdata.getjumplabel(norelocatelab);
+            current_asmdata.getjumplabel(endrelocatelab);
+            { make sure hregister can't allocate the register necessary for the parameter }
+            pvd:=search_system_type('TRELOCATETHREADVARHANDLER').typedef;
+            if pvd.typ<>procvardef then
+              internalerror(2012120901);
+            paraloc1.init;
+            paramanager.getintparaloc(current_asmdata.CurrAsmList,tprocvardef(pvd),1,paraloc1);
+            hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,pvd);
+            segreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
+            reference_reset_symbol(segref,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0,0);
+            segref.refaddr:=addr_seg;
+            cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,segreg);
+            reference_reset_symbol(href,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0,pvd.size);
+            href.segment:=segreg;
+            hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,pvd,pvd,href,hregister);
+            hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab);
+            { don't save the allocated register else the result will be destroyed later }
+            if not(vo_is_weak_external in gvs.varoptions) then
+              reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),0,sizeof(pint))
+            else
+              reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,sizeof(pint));
+            cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_16,href,paraloc1);
+            paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
+            paraloc1.done;
+            cg.allocallcpuregisters(current_asmdata.CurrAsmList);
+            cg.a_call_reg(current_asmdata.CurrAsmList,hregister);
+            cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+            cg.getcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
+            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
+            hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
+            cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_ADDR,NR_FUNCTION_RESULT_REG,hregister);
+            cg.a_jmp_always(current_asmdata.CurrAsmList,endrelocatelab);
+            cg.a_label(current_asmdata.CurrAsmList,norelocatelab);
+            { no relocation needed, load the address of the variable only, the
+              layout of a threadvar is (4 bytes pointer):
+                0 - Threadvar index
+                4 - Threadvar value in single threading }
+            if not(vo_is_weak_external in gvs.varoptions) then
+              reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),sizeof(pint),sizeof(pint))
+            else
+              reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),sizeof(pint),sizeof(pint));
+            hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,voidpointertype,href,hregister);
+            cg.a_label(current_asmdata.CurrAsmList,endrelocatelab);
+            hlcg.reference_reset_base(location.reference,voidpointertype,hregister,0,location.reference.alignment);
+          end
+        else
+          inherited generate_threadvar_access(gvs);
+      end;
+
+    procedure ti8086loadnode.pass_generate_code;
+      var
+        gvs: tstaticvarsym;
+        segref: treference;
+        refsym: TAsmSymbol;
+        segreg: TRegister;
+        newsize: TCgSize;
+      begin
+        if current_settings.x86memorymodel=mm_huge then
+          begin
+            case symtableentry.typ of
+              staticvarsym:
+                begin
+                  gvs:=tstaticvarsym(symtableentry);
+                  if (vo_is_dll_var in gvs.varoptions) then
+                  { DLL variable }
+                    begin
+                      inherited pass_generate_code;
+                      exit;
+                    end
+                  { Thread variable }
+                  else if (vo_is_thread_var in gvs.varoptions) then
+                    begin
+                      { this will be handled in ti8086loadnode.generate_threadvar_access }
+                      inherited pass_generate_code;
+                      exit;
+                    end
+                  { Normal (or external) variable }
+                  else
+                    begin
+                      if not (vo_is_external in gvs.varoptions) and gvs.Owner.iscurrentunit then
+                        begin
+                          inherited pass_generate_code;
+                          exit;
+                        end;
+
+                      { we don't know the size of all arrays }
+                      newsize:=def_cgsize(resultdef);
+                      { alignment is overridden per case below }
+                      location_reset_ref(location,LOC_REFERENCE,newsize,resultdef.alignment);
+
+                      if gvs.localloc.loc=LOC_INVALID then
+                        begin
+                          if not(vo_is_weak_external in gvs.varoptions) then
+                            refsym:=current_asmdata.RefAsmSymbol(gvs.mangledname)
+                          else
+                            refsym:=current_asmdata.WeakRefAsmSymbol(gvs.mangledname);
+
+                          segreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
+
+                          reference_reset_symbol(segref,refsym,0,0);
+                          segref.refaddr:=addr_seg;
+                          cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,segreg);
+
+                          reference_reset_symbol(location.reference,refsym,0,location.reference.alignment);
+                          location.reference.segment:=segreg;
+                        end
+                      else
+                        location:=gvs.localloc;
+                    end;
+
+                  { make const a LOC_CREFERENCE }
+                  if (gvs.varspez=vs_const) and
+                     (location.loc=LOC_REFERENCE) then
+                    location.loc:=LOC_CREFERENCE;
+                end;
+              else
+                inherited pass_generate_code;
+            end;
+          end
+        else
+          inherited pass_generate_code;
+      end;
+
 
 
 begin
 begin
    cloadnode:=ti8086loadnode;
    cloadnode:=ti8086loadnode;

+ 52 - 5
compiler/i8086/n8086mat.pas

@@ -397,6 +397,8 @@ implementation
         hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,false);
         hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,false);
         hreg64hi:=left.location.register64.reghi;
         hreg64hi:=left.location.register64.reghi;
         hreg64lo:=left.location.register64.reglo;
         hreg64lo:=left.location.register64.reglo;
+        location.register64.reglo:=hreg64lo;
+        location.register64.reghi:=hreg64hi;
 
 
         v:=0;
         v:=0;
         if right.nodetype=ordconstn then
         if right.nodetype=ordconstn then
@@ -425,6 +427,44 @@ implementation
                 emit_const_reg(A_RCR,S_W,1,hreg64lo);
                 emit_const_reg(A_RCR,S_W,1,hreg64lo);
               end;
               end;
           end
           end
+        { shifting by >=48 }
+        else if (right.nodetype=ordconstn) and (v>=48) then
+          begin
+            if nodetype=shln then
+              begin
+                cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,hreg64lo,GetNextReg(hreg64hi));
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,hreg64lo,hreg64lo);
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(hreg64lo),GetNextReg(hreg64lo));
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,hreg64hi,hreg64hi);
+                cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHL,OS_16,v-48,GetNextReg(hreg64hi));
+              end
+            else
+              begin
+                cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,GetNextReg(hreg64hi),hreg64lo);
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(hreg64hi),GetNextReg(hreg64hi));
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,hreg64hi,hreg64hi);
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(hreg64lo),GetNextReg(hreg64lo));
+                cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,v-48,hreg64lo);
+              end;
+          end
+        { shifting by 32..47 }
+        else if (right.nodetype=ordconstn) and (v>=32) and (v<=47) then
+          begin
+            if nodetype=shln then
+              begin
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,hreg64hi,hreg64hi);
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(hreg64hi),GetNextReg(hreg64hi));
+                cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHL,OS_32,v-32,hreg64lo);
+              end
+            else
+              begin
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,hreg64lo,hreg64lo);
+                cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_16,GetNextReg(hreg64lo),GetNextReg(hreg64lo));
+                cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_32,v-32,hreg64hi);
+              end;
+            location.register64.reghi:=hreg64lo;
+            location.register64.reglo:=hreg64hi;
+          end
         else
         else
           begin
           begin
             { load right operators in a register }
             { load right operators in a register }
@@ -452,14 +492,24 @@ implementation
               we've already handled them earlier as a special case }
               we've already handled them earlier as a special case }
             if right.nodetype<>ordconstn then
             if right.nodetype<>ordconstn then
               begin
               begin
+                if (cs_opt_size in current_settings.optimizerswitches) or
+                   (current_settings.optimizecputype<=cpu_386) then
+                  begin
+                    ai:=Taicpu.Op_Sym(A_JCXZ,S_W,l3);
+                    ai.is_jmp := True;
+                    current_asmdata.CurrAsmList.Concat(ai);
+                  end
+                else
+                  begin
+                    emit_reg_reg(A_TEST,S_W,NR_CX,NR_CX);
+                    cg.a_jmp_flags(current_asmdata.CurrAsmList,F_E,l3);
+                  end;
                 emit_const_reg(A_CMP,S_L,64,NR_CX);
                 emit_const_reg(A_CMP,S_L,64,NR_CX);
                 cg.a_jmp_flags(current_asmdata.CurrAsmList,F_L,l1);
                 cg.a_jmp_flags(current_asmdata.CurrAsmList,F_L,l1);
                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,hreg64lo,hreg64lo);
                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,hreg64lo,hreg64lo);
                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,hreg64hi,hreg64hi);
                 cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,hreg64hi,hreg64hi);
                 cg.a_jmp_always(current_asmdata.CurrAsmList,l3);
                 cg.a_jmp_always(current_asmdata.CurrAsmList,l3);
                 cg.a_label(current_asmdata.CurrAsmList,l1);
                 cg.a_label(current_asmdata.CurrAsmList,l1);
-                emit_reg_reg(A_TEST,S_W,NR_CX,NR_CX);
-                cg.a_jmp_flags(current_asmdata.CurrAsmList,F_E,l3);
               end;
               end;
             cg.a_label(current_asmdata.CurrAsmList,l2);
             cg.a_label(current_asmdata.CurrAsmList,l2);
             if nodetype=shln then
             if nodetype=shln then
@@ -483,9 +533,6 @@ implementation
 
 
             cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_CX);
             cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_CX);
           end;
           end;
-
-        location.register64.reglo:=hreg64lo;
-        location.register64.reghi:=hreg64hi;
       end;
       end;
 
 
 
 

+ 20 - 0
compiler/i8086/n8086mem.pas

@@ -36,6 +36,9 @@ interface
         protected
         protected
          procedure set_absvarsym_resultdef; override;
          procedure set_absvarsym_resultdef; override;
          function typecheck_non_proc(realsource: tnode; out res: tnode): boolean; override;
          function typecheck_non_proc(realsource: tnode; out res: tnode): boolean; override;
+         procedure pass_generate_code;override;
+        public
+         get_offset_only: boolean;
        end;
        end;
 
 
        ti8086derefnode = class(tx86derefnode)
        ti8086derefnode = class(tx86derefnode)
@@ -91,6 +94,23 @@ implementation
           result:=inherited;
           result:=inherited;
       end;
       end;
 
 
+
+    procedure ti8086addrnode.pass_generate_code;
+      begin
+        if get_offset_only then
+          begin
+            secondpass(left);
+
+            location_reset(location,LOC_REGISTER,OS_16);
+            location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidnearpointertype);
+            if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+              internalerror(2015103001);
+            hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.resultdef,voidnearpointertype,left.location.reference,location.register);
+          end
+        else
+          inherited;
+      end;
+
 {*****************************************************************************
 {*****************************************************************************
                              TI8086DEREFNODE
                              TI8086DEREFNODE
 *****************************************************************************}
 *****************************************************************************}

+ 96 - 2
compiler/i8086/n8086tcon.pas

@@ -35,6 +35,7 @@ interface
 
 
       ti8086typedconstbuilder = class(tasmlisttypedconstbuilder)
       ti8086typedconstbuilder = class(tasmlisttypedconstbuilder)
        protected
        protected
+        procedure tc_emit_orddef(def: torddef; var node: tnode);override;
         procedure tc_emit_pointerdef(def: tpointerdef; var node: tnode);override;
         procedure tc_emit_pointerdef(def: tpointerdef; var node: tnode);override;
       end;
       end;
 
 
@@ -42,10 +43,88 @@ interface
 implementation
 implementation
 
 
 uses
 uses
-  ncnv,defcmp,defutil,aasmtai,symcpu;
+  verbose,
+  ncon,ncnv,ninl,nld,
+  defcmp,defutil,
+  aasmtai,
+  symconst,symtype,symsym,symcpu,
+  htypechk;
 
 
     { ti8086typedconstbuilder }
     { ti8086typedconstbuilder }
 
 
+    procedure ti8086typedconstbuilder.tc_emit_orddef(def: torddef; var node: tnode);
+      var
+        hp: tnode;
+        srsym: tsym;
+        pd: tprocdef;
+        resourcestrrec: trecorddef;
+      begin
+        { support word/smallint constants, initialized with Seg() }
+        if (def.ordtype in [u16bit,s16bit]) and (node.nodetype=inlinen) and
+           (tinlinenode(node).inlinenumber=in_seg_x) then
+          begin
+            hp:=tunarynode(node).left;
+            if hp.nodetype=loadn then
+              begin
+                srsym:=tloadnode(hp).symtableentry;
+                case srsym.typ of
+                  procsym :
+                    begin
+                      pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);
+                      if Tprocsym(srsym).ProcdefList.Count>1 then
+                        Message(parser_e_no_overloaded_procvars);
+                      if po_abstractmethod in pd.procoptions then
+                        Message(type_e_cant_take_address_of_abstract_method)
+                      else
+                        ftcb.emit_tai(Tai_const.Create_seg_name(pd.mangledname),u16inttype);
+                    end;
+                  staticvarsym :
+                    ftcb.emit_tai(Tai_const.Create_seg_name(tstaticvarsym(srsym).mangledname),u16inttype);
+                  labelsym :
+                    ftcb.emit_tai(Tai_const.Create_seg_name(tlabelsym(srsym).mangledname),u16inttype);
+                  else
+                    Message(type_e_variable_id_expected);
+                end;
+              end
+            else
+              Message(parser_e_illegal_expression);
+          end
+        { support word/smallint constants, initialized with Ofs() or Word(@s) }
+        else if (def.ordtype in [u16bit,s16bit]) and (node.nodetype=typeconvn) and
+          ((Ttypeconvnode(node).left.nodetype=addrn) or
+             is_proc2procvar_load(Ttypeconvnode(node).left,pd)) then
+          begin
+            hp:=tunarynode(Ttypeconvnode(node).left).left;
+            if hp.nodetype=loadn then
+              begin
+                srsym:=tloadnode(hp).symtableentry;
+                case srsym.typ of
+                  procsym :
+                    begin
+                      pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);
+                      if Tprocsym(srsym).ProcdefList.Count>1 then
+                        Message(parser_e_no_overloaded_procvars);
+                      if po_abstractmethod in pd.procoptions then
+                        Message(type_e_cant_take_address_of_abstract_method)
+                      else
+                        ftcb.emit_tai(Tai_const.Createname(pd.mangledname,0),u16inttype);
+                    end;
+                  staticvarsym :
+                    ftcb.emit_tai(Tai_const.Createname(tstaticvarsym(srsym).mangledname,0),u16inttype);
+                  labelsym :
+                    ftcb.emit_tai(Tai_const.Createname(tlabelsym(srsym).mangledname,0),u16inttype);
+                  else
+                    Message(type_e_variable_id_expected);
+                end;
+              end
+            else
+              Message(parser_e_illegal_expression);
+          end
+        else
+          inherited;
+      end;
+
+
     procedure ti8086typedconstbuilder.tc_emit_pointerdef(def: tpointerdef; var node: tnode);
     procedure ti8086typedconstbuilder.tc_emit_pointerdef(def: tpointerdef; var node: tnode);
       var
       var
         hp: tnode;
         hp: tnode;
@@ -60,7 +139,22 @@ uses
                 node.free;
                 node.free;
                 node:=hp;
                 node:=hp;
               end;
               end;
-        if node.nodetype=niln then
+        { const pointer ? }
+        if (node.nodetype = pointerconstn) then
+          begin
+            ftcb.queue_init(def);
+            if is_farpointer(def) or is_hugepointer(def) then
+              begin
+                ftcb.queue_typeconvn(s32inttype,def);
+                ftcb.queue_emit_ordconst(longint(tpointerconstnode(node).value),s32inttype);
+              end
+            else
+              begin
+                ftcb.queue_typeconvn(s16inttype,def);
+                ftcb.queue_emit_ordconst(smallint(tpointerconstnode(node).value),s16inttype);
+              end;
+          end
+        else if node.nodetype=niln then
           begin
           begin
             if is_farpointer(def) or is_hugepointer(def) then
             if is_farpointer(def) or is_hugepointer(def) then
               ftcb.emit_tai(Tai_const.Create_32bit(0),u32inttype)
               ftcb.emit_tai(Tai_const.Create_32bit(0),u32inttype)

+ 5 - 5
compiler/i8086/symcpu.pas

@@ -123,7 +123,7 @@ type
       - it is compiled in a $F- state }
       - it is compiled in a $F- state }
     function default_far:boolean;
     function default_far:boolean;
    public
    public
-    constructor create(level:byte);override;
+    constructor create(level:byte;doregister:boolean);override;
     function address_type:tdef;override;
     function address_type:tdef;override;
     function size:asizeint;override;
     function size:asizeint;override;
     procedure declared_far;override;
     procedure declared_far;override;
@@ -324,9 +324,9 @@ implementation
                              tcpuprocdef
                              tcpuprocdef
 ****************************************************************************}
 ****************************************************************************}
 
 
-  constructor tcpuprocdef.create(level: byte);
+  constructor tcpuprocdef.create(level: byte;doregister:boolean);
     begin
     begin
-      inherited create(level);
+      inherited create(level,doregister);
       if (current_settings.x86memorymodel in x86_far_code_models) and
       if (current_settings.x86memorymodel in x86_far_code_models) and
          ((cs_huge_code in current_settings.moduleswitches) or
          ((cs_huge_code in current_settings.moduleswitches) or
           (cs_force_far_calls in current_settings.localswitches)) then
           (cs_force_far_calls in current_settings.localswitches)) then
@@ -387,8 +387,8 @@ implementation
 
 
   function tcpuprocdef.is_far: boolean;
   function tcpuprocdef.is_far: boolean;
     begin
     begin
-      result:=(current_settings.x86memorymodel in x86_far_code_models) and
-        ((po_far in procoptions) or default_far);
+      result:=(po_exports in procoptions) or
+              ((current_settings.x86memorymodel in x86_far_code_models) and ((po_far in procoptions) or default_far));
     end;
     end;
 
 
 {****************************************************************************
 {****************************************************************************

+ 139 - 121
compiler/jvm/agjasmin.pas

@@ -28,13 +28,17 @@ unit agjasmin;
 interface
 interface
 
 
     uses
     uses
-      cclasses,
+      cclasses,systems,
       globtype,globals,
       globtype,globals,
       symconst,symbase,symdef,symsym,
       symconst,symbase,symdef,symsym,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       assemble;
       assemble;
 
 
     type
     type
+      TJasminAssemblerOutputFile=class(TExternalAssemblerOutputFile)
+        procedure RemoveAsm; override;
+      end;
+
       TJasminInstrWriter = class;
       TJasminInstrWriter = class;
       {# This is a derived class which is used to write
       {# This is a derived class which is used to write
          Jasmin-styled assembler.
          Jasmin-styled assembler.
@@ -66,11 +70,10 @@ interface
         procedure WriteSymtableProcdefs(st: TSymtable);
         procedure WriteSymtableProcdefs(st: TSymtable);
         procedure WriteSymtableStructDefs(st: TSymtable);
         procedure WriteSymtableStructDefs(st: TSymtable);
        public
        public
-        constructor Create(smart: boolean); override;
+        constructor Create(info: pasminfo; smart: boolean); override;
         function MakeCmdLine: TCmdStr;override;
         function MakeCmdLine: TCmdStr;override;
         procedure WriteTree(p:TAsmList);override;
         procedure WriteTree(p:TAsmList);override;
         procedure WriteAsmList;override;
         procedure WriteAsmList;override;
-        procedure RemoveAsm; override;
         destructor destroy; override;
         destructor destroy; override;
        protected
        protected
         InstrWriter: TJasminInstrWriter;
         InstrWriter: TJasminInstrWriter;
@@ -98,7 +101,7 @@ implementation
 
 
     uses
     uses
       SysUtils,
       SysUtils,
-      cutils,cfileutl,systems,script,
+      cutils,cfileutl,script,
       fmodule,finput,verbose,
       fmodule,finput,verbose,
       symtype,symcpu,symtable,jvmdef,
       symtype,symcpu,symtable,jvmdef,
       itcpujas,cpubase,cpuinfo,cgutils,
       itcpujas,cpubase,cpuinfo,cgutils,
@@ -244,6 +247,34 @@ implementation
        result:='0dx'+result;
        result:='0dx'+result;
       end;
       end;
 
 
+
+{****************************************************************************}
+{                       Jasmin Output File                                   }
+{****************************************************************************}
+
+    procedure TJasminAssemblerOutputFile.RemoveAsm;
+      var
+        g : file;
+      begin
+        inherited;
+        if cs_asm_leave in current_settings.globalswitches then
+         exit;
+        while not TJasminAssembler(owner).asmfiles.empty do
+          begin
+            if cs_asm_extern in current_settings.globalswitches then
+             AsmRes.AddDeleteCommand(TJasminAssembler(owner).asmfiles.GetFirst)
+            else
+             begin
+               assign(g,TJasminAssembler(owner).asmfiles.GetFirst);
+               {$I-}
+                erase(g);
+               {$I+}
+               if ioresult<>0 then;
+             end;
+          end;
+      end;
+
+
 {****************************************************************************}
 {****************************************************************************}
 {                       Jasmin Assembler writer                              }
 {                       Jasmin Assembler writer                              }
 {****************************************************************************}
 {****************************************************************************}
@@ -305,7 +336,7 @@ implementation
                    begin
                    begin
                      if (infile<>lastinfile) then
                      if (infile<>lastinfile) then
                        begin
                        begin
-                         AsmWriteLn(target_asm.comment+'['+infile.name+']');
+                         writer.AsmWriteLn(asminfo^.comment+'['+infile.name+']');
                          if assigned(lastinfile) then
                          if assigned(lastinfile) then
                            lastinfile.close;
                            lastinfile.close;
                        end;
                        end;
@@ -314,7 +345,7 @@ implementation
                        begin
                        begin
                          if (hp1.fileinfo.line<>0) and
                          if (hp1.fileinfo.line<>0) and
                             ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
                             ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
-                           AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
+                           writer.AsmWriteLn(asminfo^.comment+'['+tostr(hp1.fileinfo.line)+'] '+
                              fixline(infile.GetLineStr(hp1.fileinfo.line)));
                              fixline(infile.GetLineStr(hp1.fileinfo.line)));
                          { set it to a negative value !
                          { set it to a negative value !
                          to make that is has been read already !! PM }
                          to make that is has been read already !! PM }
@@ -331,27 +362,27 @@ implementation
 
 
              ait_comment :
              ait_comment :
                Begin
                Begin
-                 AsmWrite(target_asm.comment);
-                 AsmWritePChar(tai_comment(hp).str);
-                 AsmLn;
+                 writer.AsmWrite(asminfo^.comment);
+                 writer.AsmWritePChar(tai_comment(hp).str);
+                 writer.AsmLn;
                End;
                End;
 
 
              ait_regalloc :
              ait_regalloc :
                begin
                begin
                  if (cs_asm_regalloc in current_settings.globalswitches) then
                  if (cs_asm_regalloc in current_settings.globalswitches) then
                    begin
                    begin
-                     AsmWrite(#9+target_asm.comment+'Register ');
+                     writer.AsmWrite(#9+asminfo^.comment+'Register ');
                      repeat
                      repeat
-                       AsmWrite(std_regname(Tai_regalloc(hp).reg));
+                       writer.AsmWrite(std_regname(Tai_regalloc(hp).reg));
                        if (hp.next=nil) or
                        if (hp.next=nil) or
                           (tai(hp.next).typ<>ait_regalloc) or
                           (tai(hp.next).typ<>ait_regalloc) or
                           (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
                           (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
                          break;
                          break;
                        hp:=tai(hp.next);
                        hp:=tai(hp.next);
-                       AsmWrite(',');
+                       writer.AsmWrite(',');
                      until false;
                      until false;
-                     AsmWrite(' ');
-                     AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
+                     writer.AsmWrite(' ');
+                     writer.AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
                    end;
                    end;
                end;
                end;
 
 
@@ -361,11 +392,11 @@ implementation
                    begin
                    begin
   {$ifdef EXTDEBUG}
   {$ifdef EXTDEBUG}
                      if assigned(tai_tempalloc(hp).problem) then
                      if assigned(tai_tempalloc(hp).problem) then
-                       AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
+                       writer.AsmWriteLn(asminfo^.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
                          tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
                          tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
                      else
                      else
   {$endif EXTDEBUG}
   {$endif EXTDEBUG}
-                       AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
+                       writer.AsmWriteLn(asminfo^.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
                          tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
                          tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
                    end;
                    end;
                end;
                end;
@@ -387,7 +418,7 @@ implementation
 
 
              ait_const:
              ait_const:
                begin
                begin
-                 AsmWriteln('constant');
+                 writer.AsmWriteln('constant');
 //                 internalerror(2010122702);
 //                 internalerror(2010122702);
                end;
                end;
 
 
@@ -403,7 +434,7 @@ implementation
                    begin
                    begin
                      if pos=0 then
                      if pos=0 then
                       begin
                       begin
-                        AsmWrite(#9'strconst: '#9'"');
+                        writer.AsmWrite(#9'strconst: '#9'"');
                         pos:=20;
                         pos:=20;
                       end;
                       end;
                      ch:=tai_string(hp).str[i-1];
                      ch:=tai_string(hp).str[i-1];
@@ -416,11 +447,11 @@ implementation
                      else
                      else
                       s:=ch;
                       s:=ch;
                      end;
                      end;
-                     AsmWrite(s);
+                     writer.AsmWrite(s);
                      inc(pos,length(s));
                      inc(pos,length(s));
                      if (pos>line_length) or (i=tai_string(hp).len) then
                      if (pos>line_length) or (i=tai_string(hp).len) then
                       begin
                       begin
-                        AsmWriteLn('"');
+                        writer.AsmWriteLn('"');
                         pos:=0;
                         pos:=0;
                       end;
                       end;
                    end;
                    end;
@@ -430,8 +461,8 @@ implementation
                begin
                begin
                  if (tai_label(hp).labsym.is_used) then
                  if (tai_label(hp).labsym.is_used) then
                   begin
                   begin
-                    AsmWrite(tai_label(hp).labsym.name);
-                    AsmWriteLn(':');
+                    writer.AsmWrite(tai_label(hp).labsym.name);
+                    writer.AsmWriteLn(':');
                   end;
                   end;
                end;
                end;
 
 
@@ -442,8 +473,8 @@ implementation
                     end
                     end
                   else
                   else
                    begin
                    begin
-                     AsmWrite('data symbol: ');
-                     AsmWriteln(tai_symbol(hp).sym.name);
+                     writer.AsmWrite('data symbol: ');
+                     writer.AsmWriteln(tai_symbol(hp).sym.name);
 //                     internalerror(2010122706);
 //                     internalerror(2010122706);
                    end;
                    end;
                end;
                end;
@@ -471,34 +502,34 @@ implementation
 
 
              ait_directive :
              ait_directive :
                begin
                begin
-                 AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
+                 writer.AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
                  if tai_directive(hp).name<>'' then
                  if tai_directive(hp).name<>'' then
-                   AsmWrite(tai_directive(hp).name);
-                 AsmLn;
+                   writer.AsmWrite(tai_directive(hp).name);
+                 writer.AsmLn;
                end;
                end;
 
 
              ait_jvar:
              ait_jvar:
                begin
                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);
+                 writer.AsmWrite('.var ');
+                 writer.AsmWrite(tostr(tai_jvar(hp).stackslot));
+                 writer.AsmWrite(' is ');
+                 writer.AsmWrite(tai_jvar(hp).desc^);
+                 writer.AsmWrite(' from ');
+                 writer.AsmWrite(tai_jvar(hp).startlab.name);
+                 writer.AsmWrite(' to ');
+                 writer.AsmWriteLn(tai_jvar(hp).stoplab.name);
                end;
                end;
 
 
              ait_jcatch:
              ait_jcatch:
                begin
                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);
+                 writer.AsmWrite('.catch ');
+                 writer.AsmWrite(tai_jcatch(hp).name^);
+                 writer.AsmWrite(' from ');
+                 writer.AsmWrite(tai_jcatch(hp).startlab.name);
+                 writer.AsmWrite(' to ');
+                 writer.AsmWrite(tai_jcatch(hp).stoplab.name);
+                 writer.AsmWrite(' using ');
+                 writer.AsmWriteLn(tai_jcatch(hp).handlerlab.name);
                end;
                end;
              else
              else
                internalerror(2010122707);
                internalerror(2010122707);
@@ -519,14 +550,14 @@ implementation
         superclass:=nil;
         superclass:=nil;
 
 
         { JVM 1.5+ }
         { JVM 1.5+ }
-        AsmWriteLn('.bytecode 49.0');
+        writer.AsmWriteLn('.bytecode 49.0');
         // include files are not support by Java, and the directory of the main
         // include files are not support by Java, and the directory of the main
         // source file must not be specified
         // source file must not be specified
         if current_module.mainsource<>'' then
         if current_module.mainsource<>'' then
           n:=ExtractFileName(current_module.mainsource)
           n:=ExtractFileName(current_module.mainsource)
         else
         else
           n:=InputFileName;
           n:=InputFileName;
-        AsmWriteLn('.source '+ExtractFileName(n));
+        writer.AsmWriteLn('.source '+ExtractFileName(n));
 
 
         { class/interface name }
         { class/interface name }
         if not assigned(obj) then
         if not assigned(obj) then
@@ -534,11 +565,11 @@ implementation
             { fake class type for unit -> name=unitname and
             { fake class type for unit -> name=unitname and
               superclass=java.lang.object, make final so you cannot descend
               superclass=java.lang.object, make final so you cannot descend
               from it }
               from it }
-            AsmWrite('.class final public ');
+            writer.AsmWrite('.class final public ');
             if assigned(current_module.namespace) then
             if assigned(current_module.namespace) then
-              AsmWrite(current_module.namespace^+'.');
-            AsmWriteln(current_module.realmodulename^);
-            AsmWriteLn('.super java/lang/Object');
+              writer.AsmWrite(current_module.namespace^+'.');
+            writer.AsmWriteln(current_module.realmodulename^);
+            writer.AsmWriteLn('.super java/lang/Object');
           end
           end
         else
         else
           begin
           begin
@@ -549,10 +580,10 @@ implementation
               recorddef:
               recorddef:
                 begin
                 begin
                   { can't inherit from records }
                   { can't inherit from records }
-                  AsmWrite('.class final ');
+                  writer.AsmWrite('.class final ');
                   if toplevelowner.symtabletype=globalsymtable then
                   if toplevelowner.symtabletype=globalsymtable then
-                    AsmWrite('public ');
-                  AsmWriteln(obj.jvm_full_typename(true));
+                    writer.AsmWrite('public ');
+                  writer.AsmWriteln(obj.jvm_full_typename(true));
                   superclass:=java_fpcbaserecordtype;
                   superclass:=java_fpcbaserecordtype;
                 end;
                 end;
               objectdef:
               objectdef:
@@ -560,25 +591,25 @@ implementation
                   case tobjectdef(obj).objecttype of
                   case tobjectdef(obj).objecttype of
                     odt_javaclass:
                     odt_javaclass:
                       begin
                       begin
-                        AsmWrite('.class ');
+                        writer.AsmWrite('.class ');
                         if oo_is_sealed in tobjectdef(obj).objectoptions then
                         if oo_is_sealed in tobjectdef(obj).objectoptions then
-                          AsmWrite('final ');
+                          writer.AsmWrite('final ');
                         if (oo_is_abstract in tobjectdef(obj).objectoptions) or
                         if (oo_is_abstract in tobjectdef(obj).objectoptions) or
                            (tobjectdef(obj).abstractcnt<>0) then
                            (tobjectdef(obj).abstractcnt<>0) then
-                          AsmWrite('abstract ');
+                          writer.AsmWrite('abstract ');
                         if toplevelowner.symtabletype=globalsymtable then
                         if toplevelowner.symtabletype=globalsymtable then
-                          AsmWrite('public ');
+                          writer.AsmWrite('public ');
                         if (oo_is_enum_class in tobjectdef(obj).objectoptions) then
                         if (oo_is_enum_class in tobjectdef(obj).objectoptions) then
-                          AsmWrite('enum ');
-                        AsmWriteln(obj.jvm_full_typename(true));
+                          writer.AsmWrite('enum ');
+                        writer.AsmWriteln(obj.jvm_full_typename(true));
                         superclass:=tobjectdef(obj).childof;
                         superclass:=tobjectdef(obj).childof;
                       end;
                       end;
                     odt_interfacejava:
                     odt_interfacejava:
                       begin
                       begin
-                        AsmWrite('.interface abstract ');
+                        writer.AsmWrite('.interface abstract ');
                         if toplevelowner.symtabletype=globalsymtable then
                         if toplevelowner.symtabletype=globalsymtable then
-                          AsmWrite('public ');
-                        AsmWriteLn(obj.jvm_full_typename(true));
+                          writer.AsmWrite('public ');
+                        writer.AsmWriteLn(obj.jvm_full_typename(true));
                         { interfaces must always specify Java.lang.object as
                         { interfaces must always specify Java.lang.object as
                           superclass }
                           superclass }
                         superclass:=java_jlobject;
                         superclass:=java_jlobject;
@@ -591,10 +622,10 @@ implementation
             { superclass }
             { superclass }
             if assigned(superclass) then
             if assigned(superclass) then
               begin
               begin
-                AsmWrite('.super ');
+                writer.AsmWrite('.super ');
                 if assigned(superclass.import_lib) then
                 if assigned(superclass.import_lib) then
-                  AsmWrite(superclass.import_lib^+'/');
-                AsmWriteln(superclass.objextname^);
+                  writer.AsmWrite(superclass.import_lib^+'/');
+                writer.AsmWriteln(superclass.objextname^);
               end;
               end;
             { implemented interfaces }
             { implemented interfaces }
             if (obj.typ=objectdef) and
             if (obj.typ=objectdef) and
@@ -603,26 +634,26 @@ implementation
                 for i:=0 to tobjectdef(obj).ImplementedInterfaces.count-1 do
                 for i:=0 to tobjectdef(obj).ImplementedInterfaces.count-1 do
                   begin
                   begin
                     intf:=TImplementedInterface(tobjectdef(obj).ImplementedInterfaces[i]).IntfDef;
                     intf:=TImplementedInterface(tobjectdef(obj).ImplementedInterfaces[i]).IntfDef;
-                    AsmWrite('.implements ');
-                    AsmWriteLn(intf.jvm_full_typename(true));
+                    writer.AsmWrite('.implements ');
+                    writer.AsmWriteLn(intf.jvm_full_typename(true));
                   end;
                   end;
               end;
               end;
             { signature for enum classes (must come after superclass and
             { signature for enum classes (must come after superclass and
               implemented interfaces) }
               implemented interfaces) }
             if (obj.typ=objectdef) and
             if (obj.typ=objectdef) and
                (oo_is_enum_class in tobjectdef(obj).objectoptions) then
                (oo_is_enum_class in tobjectdef(obj).objectoptions) then
-              AsmWriteln('.signature "Ljava/lang/Enum<L'+obj.jvm_full_typename(true)+';>;"');
+              writer.AsmWriteln('.signature "Ljava/lang/Enum<L'+obj.jvm_full_typename(true)+';>;"');
             { in case of nested class: relation to parent class }
             { in case of nested class: relation to parent class }
             if obj.owner.symtabletype in [objectsymtable,recordsymtable] then
             if obj.owner.symtabletype in [objectsymtable,recordsymtable] then
-              AsmWriteln(InnerStructDef(obj));
+              writer.AsmWriteln(InnerStructDef(obj));
             { add all nested classes }
             { add all nested classes }
             for i:=0 to obj.symtable.deflist.count-1 do
             for i:=0 to obj.symtable.deflist.count-1 do
               if (is_java_class_or_interface(tdef(obj.symtable.deflist[i])) or
               if (is_java_class_or_interface(tdef(obj.symtable.deflist[i])) or
                   (tdef(obj.symtable.deflist[i]).typ=recorddef)) and
                   (tdef(obj.symtable.deflist[i]).typ=recorddef)) and
                  not(df_generic in tdef(obj.symtable.deflist[i]).defoptions) then
                  not(df_generic in tdef(obj.symtable.deflist[i]).defoptions) then
-                AsmWriteln(InnerStructDef(tabstractrecorddef(obj.symtable.deflist[i])));
+                writer.AsmWriteln(InnerStructDef(tabstractrecorddef(obj.symtable.deflist[i])));
           end;
           end;
-        AsmLn;
+        writer.AsmLn;
       end;
       end;
 
 
 
 
@@ -655,7 +686,7 @@ implementation
            if jasminjarfound then
            if jasminjarfound then
              Message1(exec_t_using_assembler,jasminjar);
              Message1(exec_t_using_assembler,jasminjar);
          end;
          end;
-       result:=target_asm.asmcmd;
+       result:=asminfo^.asmcmd;
        filenames:=ScriptFixFileName(AsmFileName);
        filenames:=ScriptFixFileName(AsmFileName);
        if cs_asm_extern in current_settings.globalswitches then
        if cs_asm_extern in current_settings.globalswitches then
          filenames:=maybequoted(filenames);
          filenames:=maybequoted(filenames);
@@ -686,17 +717,15 @@ implementation
 
 
    procedure TJasminAssembler.NewAsmFileForStructDef(obj: tabstractrecorddef);
    procedure TJasminAssembler.NewAsmFileForStructDef(obj: tabstractrecorddef);
       begin
       begin
-        if AsmSize<>AsmStartSize then
+        if not writer.ClearIfEmpty then
           begin
           begin
-            AsmClose;
+            writer.AsmClose;
             asmfiles.Concat(AsmFileName);
             asmfiles.Concat(AsmFileName);
-          end
-        else
-          AsmClear;
+          end;
 
 
         AsmFileName:=obj.jvm_full_typename(false);
         AsmFileName:=obj.jvm_full_typename(false);
         AsmFileName:=Path+FixFileName(AsmFileName)+target_info.asmext;
         AsmFileName:=Path+FixFileName(AsmFileName)+target_info.asmext;
-        AsmCreate(cut_normal);
+        writer.AsmCreate(cut_normal);
       end;
       end;
 
 
 
 
@@ -912,17 +941,17 @@ implementation
            (not is_javainterface(pd.struct) or
            (not is_javainterface(pd.struct) or
             (pd.proctypeoption in [potype_unitinit,potype_unitfinalize])) then
             (pd.proctypeoption in [potype_unitinit,potype_unitfinalize])) then
           exit;
           exit;
-        AsmWrite('.method ');
-        AsmWriteln(MethodDefinition(pd));
+        writer.AsmWrite('.method ');
+        writer.AsmWriteln(MethodDefinition(pd));
         if jvmtypeneedssignature(pd) then
         if jvmtypeneedssignature(pd) then
           begin
           begin
-            AsmWrite('.signature "');
-            AsmWrite(tcpuprocdef(pd).jvmmangledbasename(true));
-            AsmWriteln('"');
+            writer.AsmWrite('.signature "');
+            writer.AsmWrite(tcpuprocdef(pd).jvmmangledbasename(true));
+            writer.AsmWriteln('"');
           end;
           end;
         WriteTree(tcpuprocdef(pd).exprasmlist);
         WriteTree(tcpuprocdef(pd).exprasmlist);
-        AsmWriteln('.end method');
-        AsmLn;
+        writer.AsmWriteln('.end method');
+        writer.AsmLn;
       end;
       end;
 
 
 
 
@@ -935,15 +964,15 @@ implementation
         { external or threadvar definition -> no definition here }
         { external or threadvar definition -> no definition here }
         if ([vo_is_external,vo_is_thread_var]*sym.varoptions)<>[] then
         if ([vo_is_external,vo_is_thread_var]*sym.varoptions)<>[] then
           exit;
           exit;
-        AsmWrite('.field ');
-        AsmWriteln(FieldDefinition(sym));
+        writer.AsmWrite('.field ');
+        writer.AsmWriteln(FieldDefinition(sym));
       end;
       end;
 
 
 
 
     procedure TJasminAssembler.WriteConstSym(sym: tconstsym);
     procedure TJasminAssembler.WriteConstSym(sym: tconstsym);
       begin
       begin
-        AsmWrite('.field ');
-        AsmWriteln(ConstDefinition(sym));
+        writer.AsmWrite('.field ');
+        writer.AsmWriteln(ConstDefinition(sym));
       end;
       end;
 
 
 
 
@@ -1042,18 +1071,29 @@ implementation
             NewAsmFileForStructDef(obj);
             NewAsmFileForStructDef(obj);
             WriteExtraHeader(obj);
             WriteExtraHeader(obj);
             WriteSymtableVarSyms(obj.symtable);
             WriteSymtableVarSyms(obj.symtable);
-            AsmLn;
+            writer.AsmLn;
             WriteSymtableProcDefs(obj.symtable);
             WriteSymtableProcDefs(obj.symtable);
             WriteSymtableStructDefs(obj.symtable);
             WriteSymtableStructDefs(obj.symtable);
           end;
           end;
         nestedstructs.free;
         nestedstructs.free;
       end;
       end;
 
 
-    constructor TJasminAssembler.Create(smart: boolean);
+
+    constructor TJasminAssembler.Create(info: pasminfo; smart: boolean);
       begin
       begin
-        inherited create(smart);
-        InstrWriter:=TJasminInstrWriter.Create(self);
-        asmfiles:=TCmdStrList.Create;
+        { this is a bit dirty: the "main" constructor is is this one, which is
+          called by TExternalAssembler.CreateWithWriter(). That means the call
+          below to CreateWithWriter will end up here again when it calls create.
+          It will first initialise fwriter though, so we can check that field,
+          and otherwise call the inherited create }
+        if not assigned(writer) then
+          begin
+            CreateWithWriter(info,TJasminAssemblerOutputFile.Create(self),true,smart);
+            InstrWriter:=TJasminInstrWriter.Create(self);
+            asmfiles:=TCmdStrList.Create;
+          end
+        else
+          inherited;
       end;
       end;
 
 
 
 
@@ -1064,20 +1104,20 @@ implementation
        Comment(V_Debug,'Start writing Jasmin-styled assembler output for '+current_module.mainsource);
        Comment(V_Debug,'Start writing Jasmin-styled assembler output for '+current_module.mainsource);
 {$endif}
 {$endif}
 
 
-      AsmStartSize:=AsmSize;
+      writer.MarkEmpty;
       WriteExtraHeader(nil);
       WriteExtraHeader(nil);
 (*
 (*
       for hal:=low(TasmlistType) to high(TasmlistType) do
       for hal:=low(TasmlistType) to high(TasmlistType) do
         begin
         begin
-          AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
+          writer.AsmWriteLn(asminfo^.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
           writetree(current_asmdata.asmlists[hal]);
           writetree(current_asmdata.asmlists[hal]);
-          AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
+          writer.AsmWriteLn(asminfo^.comment+'End asmlist '+AsmlistTypeStr[hal]);
         end;
         end;
 *)
 *)
       { print all global variables }
       { print all global variables }
       WriteSymtableVarSyms(current_module.globalsymtable);
       WriteSymtableVarSyms(current_module.globalsymtable);
       WriteSymtableVarSyms(current_module.localsymtable);
       WriteSymtableVarSyms(current_module.localsymtable);
-      AsmLn;
+      writer.AsmLn;
       { print all global procedures/functions }
       { print all global procedures/functions }
       WriteSymtableProcdefs(current_module.globalsymtable);
       WriteSymtableProcdefs(current_module.globalsymtable);
       WriteSymtableProcdefs(current_module.localsymtable);
       WriteSymtableProcdefs(current_module.localsymtable);
@@ -1085,7 +1125,7 @@ implementation
       WriteSymtableStructDefs(current_module.globalsymtable);
       WriteSymtableStructDefs(current_module.globalsymtable);
       WriteSymtableStructDefs(current_module.localsymtable);
       WriteSymtableStructDefs(current_module.localsymtable);
 
 
-      AsmLn;
+      writer.AsmLn;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
       if assigned(current_module.mainsource) then
       if assigned(current_module.mainsource) then
        Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource);
        Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource);
@@ -1093,28 +1133,6 @@ implementation
     end;
     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                          }
 {                         Jasmin Instruction Writer                          }
 {****************************************************************************}
 {****************************************************************************}
@@ -1205,7 +1223,7 @@ implementation
                  sep:=' ';
                  sep:=' ';
               end;
               end;
           end;
           end;
-        owner.AsmWriteLn(s);
+        owner.writer.AsmWriteLn(s);
       end;
       end;
 
 
 {****************************************************************************}
 {****************************************************************************}

+ 1 - 0
compiler/jvm/aoptcpu.pas

@@ -174,6 +174,7 @@ Implementation
   function TCpuAsmOptimizer.PostPeepHoleOptsCpu(var p: tai): boolean;
   function TCpuAsmOptimizer.PostPeepHoleOptsCpu(var p: tai): boolean;
     begin
     begin
       result:=
       result:=
+        (p.typ=ait_instruction) and
         RemoveLoadLoadSwap(p);
         RemoveLoadLoadSwap(p);
     end;
     end;
 
 

+ 7 - 1
compiler/jvm/cpuinfo.pas

@@ -51,6 +51,12 @@ Type
      (ct_none
      (ct_none
      );
      );
 
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 
 
 Const
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { Is there support for dealing with multiple microcontrollers available }
@@ -63,7 +69,7 @@ Const
     {$WARN 3177 OFF}
     {$WARN 3177 OFF}
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    (
    (
-      (controllertypestr:''; controllerunitstr:''; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+      (controllertypestr:''; controllerunitstr:''; cputype:cpu_none; fputype:fpu_none; flashbase:0; flashsize:0; srambase:0; sramsize:0));
    {$POP}
    {$POP}
 
 
    { calling conventions supported by the code generator }
    { calling conventions supported by the code generator }

+ 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:=cpointerdef.getreusable(result.def);
+            result.def:=cpointerdef.getreusable_no_free(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:=cpointerdef.getreusable(hp.vardef);
+                paradef:=cpointerdef.getreusable_no_free(hp.vardef);
               end
               end
             else
             else
               begin
               begin

+ 2 - 1
compiler/jvm/hlcgcpu.pas

@@ -291,8 +291,9 @@ implementation
   class function thlcgjvm.def2regtyp(def: tdef): tregistertype;
   class function thlcgjvm.def2regtyp(def: tdef): tregistertype;
     begin
     begin
       case def.typ of
       case def.typ of
-        { records and enums are implemented via classes }
+        { records (including files) and enums are implemented via classes }
         recorddef,
         recorddef,
+        filedef,
         enumdef,
         enumdef,
         setdef:
         setdef:
           result:=R_ADDRESSREGISTER;
           result:=R_ADDRESSREGISTER;

+ 14 - 3
compiler/jvm/jvmdef.pas

@@ -290,7 +290,17 @@ implementation
               encodedstr:=encodedstr+c;
               encodedstr:=encodedstr+c;
             end;
             end;
           filedef :
           filedef :
-            result:=false;
+            begin
+              case tfiledef(def).filetyp of
+                ft_text:
+                  result:=jvmaddencodedtype(search_system_type('TEXTREC').typedef,false,encodedstr,forcesignature,founderror);
+                ft_typed,
+                ft_untyped:
+                  result:=jvmaddencodedtype(search_system_type('FILEREC').typedef,false,encodedstr,forcesignature,founderror);
+                else
+                  internalerror(2015091406);
+              end;
+            end;
           recorddef :
           recorddef :
             begin
             begin
               encodedstr:=encodedstr+'L'+trecorddef(def).jvm_full_typename(true)+';'
               encodedstr:=encodedstr+'L'+trecorddef(def).jvm_full_typename(true)+';'
@@ -505,6 +515,7 @@ implementation
                 is_open_array(def) or
                 is_open_array(def) or
                 is_array_of_const(def) or
                 is_array_of_const(def) or
                 is_array_constructor(def);
                 is_array_constructor(def);
+          filedef,
           recorddef,
           recorddef,
           setdef:
           setdef:
             result:=true;
             result:=true;
@@ -919,8 +930,8 @@ implementation
                         begin
                         begin
                           if tdef(container.defowner).typ<>procdef then
                           if tdef(container.defowner).typ<>procdef then
                             internalerror(2011040303);
                             internalerror(2011040303);
-                          { defid is added to prevent problem with overloads }
-                          result:=tprocdef(container.defowner).procsym.realname+'$$'+tostr(tprocdef(container.defowner).defid)+'$'+result;
+                          { unique_id_str is added to prevent problem with overloads }
+                          result:=tprocdef(container.defowner).procsym.realname+'$$'+tprocdef(container.defowner).unique_id_str+'$'+result;
                           container:=container.defowner.owner;
                           container:=container.defowner.owner;
                         end;
                         end;
                     end;
                     end;

+ 1 - 1
compiler/jvm/njvmcal.pas

@@ -591,7 +591,7 @@ implementation
                   in theory do that, because the parameter nodes have already
                   in theory do that, because the parameter nodes have already
                   been bound to the current procdef's parasyms }
                   been bound to the current procdef's parasyms }
                 remove_hidden_paras;
                 remove_hidden_paras;
-                result:=ccallnode.create(left,tprocsym(sym),symtableproc,methodpointer,callnodeflags);
+                result:=ccallnode.create(left,tprocsym(sym),symtableproc,methodpointer,callnodeflags,nil);
                 result.flags:=flags;
                 result.flags:=flags;
                 left:=nil;
                 left:=nil;
                 methodpointer:=nil;
                 methodpointer:=nil;

+ 32 - 5
compiler/jvm/njvmcnv.pas

@@ -524,7 +524,7 @@ implementation
           with a single #0 }
           with a single #0 }
         result:=ccallnode.create(ccallparanode.create(left,nil),tprocsym(ps),
         result:=ccallnode.create(ccallparanode.create(left,nil),tprocsym(ps),
           ps.owner,
           ps.owner,
-          cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[]);
+          cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[],nil);
         include(result.flags,nf_isproperty);
         include(result.flags,nf_isproperty);
         result:=ctypeconvnode.create_explicit(result,resultdef);
         result:=ctypeconvnode.create_explicit(result,resultdef);
         { reused }
         { reused }
@@ -863,7 +863,7 @@ implementation
           { call the (static class) method to get the raw bits }
           { call the (static class) method to get the raw bits }
           result:=ccallnode.create(ccallparanode.create(left,nil),
           result:=ccallnode.create(ccallparanode.create(left,nil),
             tprocsym(psym),psym.owner,
             tprocsym(psym),psym.owner,
-            cloadvmtaddrnode.create(ctypenode.create(csym.typedef)),[]);
+            cloadvmtaddrnode.create(ctypenode.create(csym.typedef)),[],nil);
           { convert the result to the result type of this type conversion node }
           { convert the result to the result type of this type conversion node }
           inserttypeconv_explicit(result,resultdef);
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
           { left is reused }
@@ -882,7 +882,7 @@ implementation
             internalerror(2011062601);
             internalerror(2011062601);
           result:=ccallnode.create(ccallparanode.create(left,nil),
           result:=ccallnode.create(ccallparanode.create(left,nil),
             tprocsym(psym),psym.owner,
             tprocsym(psym),psym.owner,
-            cloadvmtaddrnode.create(ctypenode.create(todef.classdef)),[]);
+            cloadvmtaddrnode.create(ctypenode.create(todef.classdef)),[],nil);
           { convert the result to the result type of this type conversion node }
           { convert the result to the result type of this type conversion node }
           inserttypeconv_explicit(result,resultdef);
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
           { left is reused }
@@ -899,7 +899,7 @@ implementation
           if not assigned(psym) or
           if not assigned(psym) or
              (psym.typ<>procsym) then
              (psym.typ<>procsym) then
             internalerror(2011062602);
             internalerror(2011062602);
-          result:=ccallnode.create(nil,tprocsym(psym),psym.owner,left,[]);
+          result:=ccallnode.create(nil,tprocsym(psym),psym.owner,left,[],nil);
           { convert the result to the result type of this type conversion node }
           { convert the result to the result type of this type conversion node }
           inserttypeconv_explicit(result,resultdef);
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
           { left is reused }
@@ -1121,6 +1121,24 @@ implementation
           result:=false;
           result:=false;
         end;
         end;
 
 
+
+      function compatible_file_conversion(def1, def2: tdef): boolean;
+        begin
+          if def1.typ=filedef then
+            case tfiledef(def1).filetyp of
+              ft_text:
+                result:=def2=search_system_type('TEXTREC').typedef;
+              ft_typed,
+              ft_untyped:
+                result:=def2=search_system_type('FILEREC').typedef;
+              else
+                internalerror(2015091401);
+            end
+          else
+            result:=false;
+        end;
+
+
       var
       var
         fromclasscompatible,
         fromclasscompatible,
         toclasscompatible: boolean;
         toclasscompatible: boolean;
@@ -1380,6 +1398,15 @@ implementation
               float(intvalue) will convert rather than re-interpret the value) }
               float(intvalue) will convert rather than re-interpret the value) }
           end;
           end;
 
 
+        { files }
+        if compatible_file_conversion(left.resultdef,resultdef) or
+           compatible_file_conversion(resultdef,left.resultdef) then
+          begin
+            result:=true;
+            exit;
+          end;
+
+
         { anything not explicitly handled is a problem }
         { anything not explicitly handled is a problem }
         result:=true;
         result:=true;
         CGMessage2(type_e_illegal_type_conversion,left.resultdef.typename,resultdef.typename);
         CGMessage2(type_e_illegal_type_conversion,left.resultdef.typename,resultdef.typename);
@@ -1479,7 +1506,7 @@ implementation
               if not assigned(ps) or
               if not assigned(ps) or
                  (ps.typ<>procsym) then
                  (ps.typ<>procsym) then
                 internalerror(2011041910);
                 internalerror(2011041910);
-              call:=ccallnode.create(ccallparanode.create(node.left,nil),tprocsym(ps),ps.owner,ctypeconvnode.create_explicit(node.right,jlclass),[]);
+              call:=ccallnode.create(ccallparanode.create(node.left,nil),tprocsym(ps),ps.owner,ctypeconvnode.create_explicit(node.right,jlclass),[],nil);
               node.left:=nil;
               node.left:=nil;
               node.right:=nil;
               node.right:=nil;
               firstpass(call);
               firstpass(call);

+ 2 - 2
compiler/jvm/njvminl.pas

@@ -595,7 +595,7 @@ implementation
               internalerror(2011031403);
               internalerror(2011031403);
             stringnonnull:=cassignmentnode.create(
             stringnonnull:=cassignmentnode.create(
               ctemprefnode.create(lentemp),
               ctemprefnode.create(lentemp),
-              ccallnode.create(nil,tprocsym(psym),psym.owner,stringtemp,[]));
+              ccallnode.create(nil,tprocsym(psym),psym.owner,stringtemp,[],nil));
             { else-path: length is 0 }
             { else-path: length is 0 }
             stringnull:=cassignmentnode.create(
             stringnull:=cassignmentnode.create(
               ctemprefnode.create(lentemp),
               ctemprefnode.create(lentemp),
@@ -618,7 +618,7 @@ implementation
               internalerror(2011052402);
               internalerror(2011052402);
             result:=
             result:=
               ccallnode.create(nil,tprocsym(psym),psym.owner,
               ccallnode.create(nil,tprocsym(psym),psym.owner,
-                ctypeconvnode.create_explicit(caddrnode.create_internal(left),java_shortstring),[]);
+                ctypeconvnode.create_explicit(caddrnode.create_internal(left),java_shortstring),[],nil);
             { reused }
             { reused }
             left:=nil;
             left:=nil;
           end
           end

+ 1 - 1
compiler/jvm/njvmld.pas

@@ -142,7 +142,7 @@ function tjvmassignmentnode.pass_1: tnode;
           ccallnode.create(
           ccallnode.create(
             ccallparanode.create(right,
             ccallparanode.create(right,
               ccallparanode.create(tvecnode(target).right,nil)),
               ccallparanode.create(tvecnode(target).right,nil)),
-            tprocsym(psym),psym.owner,tvecnode(target).left,[]);
+            tprocsym(psym),psym.owner,tvecnode(target).left,[],nil);
         right:=nil;
         right:=nil;
         tvecnode(target).left:=nil;
         tvecnode(target).left:=nil;
         tvecnode(target).right:=nil;
         tvecnode(target).right:=nil;

+ 2 - 2
compiler/jvm/njvmmem.pas

@@ -332,7 +332,7 @@ implementation
             if not assigned(vs) or
             if not assigned(vs) or
                (tsym(vs).typ<>procsym) then
                (tsym(vs).typ<>procsym) then
               internalerror(2011041901);
               internalerror(2011041901);
-            result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[]);
+            result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[],nil);
             inserttypeconv_explicit(result,resultdef);
             inserttypeconv_explicit(result,resultdef);
             { reused }
             { reused }
             left:=nil;
             left:=nil;
@@ -385,7 +385,7 @@ implementation
             { Pascal strings are 1-based, Java strings 0-based }
             { Pascal strings are 1-based, Java strings 0-based }
             result:=ccallnode.create(ccallparanode.create(
             result:=ccallnode.create(ccallparanode.create(
               caddnode.create(subn,right,genintconstnode(1)),nil),tprocsym(psym),
               caddnode.create(subn,right,genintconstnode(1)),nil),tprocsym(psym),
-              psym.owner,ctypeconvnode.create_explicit(left,stringclass),[]);
+              psym.owner,ctypeconvnode.create_explicit(left,stringclass),[],nil);
             left:=nil;
             left:=nil;
             right:=nil;
             right:=nil;
             exit;
             exit;

+ 15 - 1
compiler/jvm/njvmutil.pas

@@ -50,6 +50,8 @@ interface
       class procedure InsertWideInits; override;
       class procedure InsertWideInits; override;
       class procedure InsertResourceTablesTable; override;
       class procedure InsertResourceTablesTable; override;
       class procedure InsertResourceInfo(ResourcesUsed : boolean); override;
       class procedure InsertResourceInfo(ResourcesUsed : boolean); override;
+      class procedure InsertResStrTablesTable; override;
+      class procedure InsertResStrInits; override;
       class procedure InsertMemorySizes; override;
       class procedure InsertMemorySizes; override;
      strict protected
      strict protected
        class procedure add_main_procdef_paras(pd: tdef); override;
        class procedure add_main_procdef_paras(pd: tdef); override;
@@ -202,7 +204,7 @@ implementation
         begin
         begin
           vs:=cstaticvarsym.create(sym.realname+'$threadvar',sym.varspez,
           vs:=cstaticvarsym.create(sym.realname+'$threadvar',sym.varspez,
             jvmgetthreadvardef(sym.vardef),
             jvmgetthreadvardef(sym.vardef),
-            sym.varoptions - [vo_is_thread_var]);
+            sym.varoptions - [vo_is_thread_var],true);
           sym.owner.insert(vs);
           sym.owner.insert(vs);
           { make sure that the new sym does not get allocated (we will allocate
           { make sure that the new sym does not get allocated (we will allocate
             it when encountering the original sym, because only then we know
             it when encountering the original sym, because only then we know
@@ -457,6 +459,18 @@ implementation
     end;
     end;
 
 
 
 
+  class procedure tjvmnodeutils.InsertResStrTablesTable;
+    begin
+      { not supported }
+    end;
+
+
+  class procedure tjvmnodeutils.InsertResStrInits;
+    begin
+      { not supported }
+    end;
+
+
   class procedure tjvmnodeutils.InsertMemorySizes;
   class procedure tjvmnodeutils.InsertMemorySizes;
     begin
     begin
       { not required }
       { not required }

+ 21 - 21
compiler/jvm/pjvm.pas

@@ -132,7 +132,7 @@ implementation
             while not(topowner.owner.symtabletype in [staticsymtable,globalsymtable]) do
             while not(topowner.owner.symtabletype in [staticsymtable,globalsymtable]) do
               topowner:=topowner.owner.defowner;
               topowner:=topowner.owner.defowner;
             { create procdef }
             { create procdef }
-            pd:=cprocdef.create(topowner.owner.symtablelevel+1);
+            pd:=cprocdef.create(topowner.owner.symtablelevel+1,true);
             if df_generic in obj.defoptions then
             if df_generic in obj.defoptions then
               include(pd.defoptions,df_generic);
               include(pd.defoptions,df_generic);
             { method of this objectdef }
             { method of this objectdef }
@@ -297,7 +297,7 @@ implementation
         { create new class (different internal name than enum to prevent name
         { create new class (different internal name than enum to prevent name
           clash; at unit level because we don't want its methods to be nested
           clash; at unit level because we don't want its methods to be nested
           inside a function in case its a local type) }
           inside a function in case its a local type) }
-        enumclass:=cobjectdef.create(odt_javaclass,'$'+current_module.realmodulename^+'$'+name+'$InternEnum$'+tostr(def.defid),java_jlenum);
+        enumclass:=cobjectdef.create(odt_javaclass,'$'+current_module.realmodulename^+'$'+name+'$InternEnum$'+def.unique_id_str,java_jlenum,true);
         tcpuenumdef(def).classdef:=enumclass;
         tcpuenumdef(def).classdef:=enumclass;
         include(enumclass.objectoptions,oo_is_enum_class);
         include(enumclass.objectoptions,oo_is_enum_class);
         include(enumclass.objectoptions,oo_is_sealed);
         include(enumclass.objectoptions,oo_is_sealed);
@@ -307,11 +307,11 @@ implementation
           name that can be used in generated Pascal code without risking an
           name that can be used in generated Pascal code without risking an
           identifier conflict (since it is local to this class; the global name
           identifier conflict (since it is local to this class; the global name
           is unique because it's an identifier that contains $-signs) }
           is unique because it's an identifier that contains $-signs) }
-        enumclass.symtable.insert(ctypesym.create('__FPC_TEnumClassAlias',enumclass));
+        enumclass.symtable.insert(ctypesym.create('__FPC_TEnumClassAlias',enumclass,true));
 
 
         { also create an alias for the enum type so that we can iterate over
         { also create an alias for the enum type so that we can iterate over
           all enum values when creating the body of the class constructor }
           all enum values when creating the body of the class constructor }
-        temptypesym:=ctypesym.create('__FPC_TEnumAlias',nil);
+        temptypesym:=ctypesym.create('__FPC_TEnumAlias',nil,true);
         { don't pass def to the ttypesym constructor, because then it
         { don't pass def to the ttypesym constructor, because then it
           will replace the current (real) typesym of that def with the alias }
           will replace the current (real) typesym of that def with the alias }
         temptypesym.typedef:=def;
         temptypesym.typedef:=def;
@@ -343,14 +343,14 @@ implementation
         { create static fields representing all enums }
         { create static fields representing all enums }
         for i:=0 to tenumdef(def).symtable.symlist.count-1 do
         for i:=0 to tenumdef(def).symtable.symlist.count-1 do
           begin
           begin
-            fsym:=cfieldvarsym.create(tenumsym(tenumdef(def).symtable.symlist[i]).realname,vs_final,enumclass,[]);
+            fsym:=cfieldvarsym.create(tenumsym(tenumdef(def).symtable.symlist[i]).realname,vs_final,enumclass,[],true);
             enumclass.symtable.insert(fsym);
             enumclass.symtable.insert(fsym);
             sym:=make_field_static(enumclass.symtable,fsym);
             sym:=make_field_static(enumclass.symtable,fsym);
             { add alias for the field representing ordinal(0), for use in
             { add alias for the field representing ordinal(0), for use in
               initialization code }
               initialization code }
             if tenumsym(tenumdef(def).symtable.symlist[i]).value=0 then
             if tenumsym(tenumdef(def).symtable.symlist[i]).value=0 then
               begin
               begin
-                aliassym:=cstaticvarsym.create('__FPC_Zero_Initializer',vs_final,enumclass,[vo_is_external]);
+                aliassym:=cstaticvarsym.create('__FPC_Zero_Initializer',vs_final,enumclass,[vo_is_external],true);
                 enumclass.symtable.insert(aliassym);
                 enumclass.symtable.insert(aliassym);
                 aliassym.set_raw_mangledname(sym.mangledname);
                 aliassym.set_raw_mangledname(sym.mangledname);
               end;
               end;
@@ -359,7 +359,7 @@ implementation
           (used internally by the JDK) }
           (used internally by the JDK) }
         arrdef:=carraydef.create(0,tenumdef(def).symtable.symlist.count-1,s32inttype);
         arrdef:=carraydef.create(0,tenumdef(def).symtable.symlist.count-1,s32inttype);
         arrdef.elementdef:=enumclass;
         arrdef.elementdef:=enumclass;
-        arrsym:=ctypesym.create('__FPC_TEnumValues',arrdef);
+        arrsym:=ctypesym.create('__FPC_TEnumValues',arrdef,true);
         enumclass.symtable.insert(arrsym);
         enumclass.symtable.insert(arrsym);
         { insert "public static values: array of enumclass" that returns $VALUES.clone()
         { insert "public static values: array of enumclass" that returns $VALUES.clone()
           (rather than a dynamic array and using clone --which we don't support yet for arrays--
           (rather than a dynamic array and using clone --which we don't support yet for arrays--
@@ -373,12 +373,12 @@ implementation
         if tenumdef(def).has_jumps then
         if tenumdef(def).has_jumps then
           begin
           begin
             { add field for the value }
             { add field for the value }
-            fsym:=cfieldvarsym.create('__fpc_fenumval',vs_final,s32inttype,[]);
+            fsym:=cfieldvarsym.create('__fpc_fenumval',vs_final,s32inttype,[],true);
             enumclass.symtable.insert(fsym);
             enumclass.symtable.insert(fsym);
             tobjectsymtable(enumclass.symtable).addfield(fsym,vis_strictprivate);
             tobjectsymtable(enumclass.symtable).addfield(fsym,vis_strictprivate);
             { add class field with hash table that maps from FPC-declared ordinal value -> enum instance }
             { add class field with hash table that maps from FPC-declared ordinal value -> enum instance }
             juhashmap:=search_system_type('JUHASHMAP').typedef;
             juhashmap:=search_system_type('JUHASHMAP').typedef;
-            fsym:=cfieldvarsym.create('__fpc_ord2enum',vs_final,juhashmap,[]);
+            fsym:=cfieldvarsym.create('__fpc_ord2enum',vs_final,juhashmap,[],true);
             enumclass.symtable.insert(fsym);
             enumclass.symtable.insert(fsym);
             make_field_static(enumclass.symtable,fsym);
             make_field_static(enumclass.symtable,fsym);
             { add custom constructor }
             { add custom constructor }
@@ -435,7 +435,7 @@ implementation
           "Values" instance method -- that's also the reason why we insert the
           "Values" instance method -- that's also the reason why we insert the
           field only now, because we cannot disable duplicate identifier
           field only now, because we cannot disable duplicate identifier
           checking when creating the "Values" method }
           checking when creating the "Values" method }
-        fsym:=cfieldvarsym.create('$VALUES',vs_final,arrdef,[]);
+        fsym:=cfieldvarsym.create('$VALUES',vs_final,arrdef,[],true);
         fsym.visibility:=vis_strictprivate;
         fsym.visibility:=vis_strictprivate;
         enumclass.symtable.insert(fsym,false);
         enumclass.symtable.insert(fsym,false);
         sym:=make_field_static(enumclass.symtable,fsym);
         sym:=make_field_static(enumclass.symtable,fsym);
@@ -482,13 +482,13 @@ implementation
         { create new class (different internal name than pvar to prevent name
         { create new class (different internal name than pvar to prevent name
           clash; at unit level because we don't want its methods to be nested
           clash; at unit level because we don't want its methods to be nested
           inside a function in case its a local type) }
           inside a function in case its a local type) }
-        pvclass:=cobjectdef.create(odt_javaclass,'$'+current_module.realmodulename^+'$'+name+'$InternProcvar$'+tostr(def.defid),java_procvarbase);
+        pvclass:=cobjectdef.create(odt_javaclass,'$'+current_module.realmodulename^+'$'+name+'$InternProcvar$'+def.unique_id_str,java_procvarbase,true);
         tcpuprocvardef(def).classdef:=pvclass;
         tcpuprocvardef(def).classdef:=pvclass;
         include(pvclass.objectoptions,oo_is_sealed);
         include(pvclass.objectoptions,oo_is_sealed);
         if df_generic in def.defoptions then
         if df_generic in def.defoptions then
           include(pvclass.defoptions,df_generic);
           include(pvclass.defoptions,df_generic);
         { associate typesym }
         { associate typesym }
-        pvclass.symtable.insert(ctypesym.create('__FPC_TProcVarClassAlias',pvclass));
+        pvclass.symtable.insert(ctypesym.create('__FPC_TProcVarClassAlias',pvclass,true));
         { set external name to match procvar type name }
         { set external name to match procvar type name }
         if not islocal then
         if not islocal then
           pvclass.objextname:=stringdup(name)
           pvclass.objextname:=stringdup(name)
@@ -511,7 +511,7 @@ implementation
 
 
         { add local alias for the procvartype that we can use when implementing
         { add local alias for the procvartype that we can use when implementing
           the invoke method }
           the invoke method }
-        temptypesym:=ctypesym.create('__FPC_ProcVarAlias',nil);
+        temptypesym:=ctypesym.create('__FPC_ProcVarAlias',nil,true);
         { don't pass def to the ttypesym constructor, because then it
         { don't pass def to the ttypesym constructor, because then it
           will replace the current (real) typesym of that def with the alias }
           will replace the current (real) typesym of that def with the alias }
         temptypesym.typedef:=def;
         temptypesym.typedef:=def;
@@ -527,12 +527,12 @@ implementation
            not islocal and
            not islocal and
            not force_no_callback_intf then
            not force_no_callback_intf then
           begin
           begin
-            pvintf:=cobjectdef.create(odt_interfacejava,'Callback',nil);
+            pvintf:=cobjectdef.create(odt_interfacejava,'Callback',nil,true);
             pvintf.objextname:=stringdup('Callback');
             pvintf.objextname:=stringdup('Callback');
             if df_generic in def.defoptions then
             if df_generic in def.defoptions then
               include(pvintf.defoptions,df_generic);
               include(pvintf.defoptions,df_generic);
             { associate typesym }
             { associate typesym }
-            pvclass.symtable.insert(ctypesym.create('Callback',pvintf));
+            pvclass.symtable.insert(ctypesym.create('Callback',pvintf,true));
 
 
             { add a method prototype matching the procvar (like the invoke
             { add a method prototype matching the procvar (like the invoke
               in the procvarclass itself) }
               in the procvarclass itself) }
@@ -640,10 +640,10 @@ implementation
         wrapperpv.calcparas;
         wrapperpv.calcparas;
         { no use in creating a callback wrapper here, this procvar type isn't
         { no use in creating a callback wrapper here, this procvar type isn't
           for public consumption }
           for public consumption }
-        jvm_create_procvar_class_intern('__fpc_virtualclassmethod_pv_t'+tostr(wrapperpd.defid),wrapperpv,true);
+        jvm_create_procvar_class_intern('__fpc_virtualclassmethod_pv_t'+wrapperpd.unique_id_str,wrapperpv,true);
         { create alias for the procvar type so we can use it in generated
         { create alias for the procvar type so we can use it in generated
           Pascal code }
           Pascal code }
-        typ:=ctypesym.create('__fpc_virtualclassmethod_pv_t'+tostr(wrapperpd.defid),wrapperpv);
+        typ:=ctypesym.create('__fpc_virtualclassmethod_pv_t'+wrapperpd.unique_id_str,wrapperpv,true);
         wrapperpv.classdef.typesym.visibility:=vis_strictprivate;
         wrapperpv.classdef.typesym.visibility:=vis_strictprivate;
         symtablestack.top.insert(typ);
         symtablestack.top.insert(typ);
         symtablestack.pop(pd.owner);
         symtablestack.pop(pd.owner);
@@ -737,7 +737,7 @@ implementation
             begin
             begin
               { make sure we don't emit a definition for this field (we'll do
               { make sure we don't emit a definition for this field (we'll do
                 that for the constsym already) -> mark as external }
                 that for the constsym already) -> mark as external }
-              ssym:=cstaticvarsym.create(internal_static_field_name(csym.realname),vs_final,csym.constdef,[vo_is_external]);
+              ssym:=cstaticvarsym.create(internal_static_field_name(csym.realname),vs_final,csym.constdef,[vo_is_external],true);
               csym.owner.insert(ssym);
               csym.owner.insert(ssym);
               { alias storage to the constsym }
               { alias storage to the constsym }
               ssym.set_mangledname(csym.realname);
               ssym.set_mangledname(csym.realname);
@@ -775,7 +775,7 @@ implementation
                 has been compiler -> insert a copy in the unit's staticsymtable
                 has been compiler -> insert a copy in the unit's staticsymtable
               }
               }
               symtablestack.push(current_module.localsymtable);
               symtablestack.push(current_module.localsymtable);
-              ssym:=cstaticvarsym.create(internal_static_field_name(csym.realname),vs_final,tsetdef(csym.constdef).getcopy,[vo_is_external,vo_has_local_copy]);
+              ssym:=cstaticvarsym.create(internal_static_field_name(csym.realname),vs_final,tsetdef(csym.constdef).getcopy,[vo_is_external,vo_has_local_copy],true);
               symtablestack.top.insert(ssym);
               symtablestack.top.insert(ssym);
               symtablestack.pop(current_module.localsymtable);
               symtablestack.pop(current_module.localsymtable);
               { alias storage to the constsym }
               { alias storage to the constsym }
@@ -836,8 +836,8 @@ implementation
         visname:=visibilityName[vis];
         visname:=visibilityName[vis];
         replace(visname,' ','_');
         replace(visname,' ','_');
         { create a name that is unique amongst all units (start with '$unitname$$') and
         { create a name that is unique amongst all units (start with '$unitname$$') and
-          unique in this unit (result.defid) }
-        finish_copied_procdef(result,'$'+current_module.realmodulename^+'$$'+tostr(result.defid)+pd.procsym.realname+'$'+visname,obj.symtable,obj);
+          unique in this unit (result.unique_id_str) }
+        finish_copied_procdef(result,'$'+current_module.realmodulename^+'$$'+result.unique_id_str+pd.procsym.realname+'$'+visname,obj.symtable,obj);
         { in case the referred method is from an external class }
         { in case the referred method is from an external class }
         exclude(result.procoptions,po_external);
         exclude(result.procoptions,po_external);
         { not virtual/override/abstract/... }
         { not virtual/override/abstract/... }

+ 5 - 5
compiler/jvm/symcpu.pas

@@ -379,15 +379,15 @@ implementation
         { create procdef }
         { create procdef }
         if not assigned(orgaccesspd) then
         if not assigned(orgaccesspd) then
           begin
           begin
-            pd:=cprocdef.create(normal_function_level);
+            pd:=cprocdef.create(normal_function_level,true);
             if df_generic in obj.defoptions then
             if df_generic in obj.defoptions then
               include(pd.defoptions,df_generic);
               include(pd.defoptions,df_generic);
             { method of this objectdef }
             { method of this objectdef }
             pd.struct:=obj;
             pd.struct:=obj;
             { can only construct the artificial accessorname now, because it requires
             { can only construct the artificial accessorname now, because it requires
-              pd.defid }
+              pd.unique_id_str }
             if not explicitwrapper then
             if not explicitwrapper then
-              accessorname:='$'+obj.symtable.realname^+'$'+realname+'$'+accessorname+'$'+tostr(pd.defid);
+              accessorname:='$'+obj.symtable.realname^+'$'+realname+'$'+accessorname+'$'+pd.unique_id_str;
           end
           end
         else
         else
           begin
           begin
@@ -397,9 +397,9 @@ implementation
             exclude(pd.procoptions,po_abstractmethod);
             exclude(pd.procoptions,po_abstractmethod);
             exclude(pd.procoptions,po_overridingmethod);
             exclude(pd.procoptions,po_overridingmethod);
             { can only construct the artificial accessorname now, because it requires
             { can only construct the artificial accessorname now, because it requires
-              pd.defid }
+              pd.unique_id_str }
             if not explicitwrapper then
             if not explicitwrapper then
-              accessorname:='$'+obj.symtable.realname^+'$'+realname+'$'+accessorname+'$'+tostr(pd.defid);
+              accessorname:='$'+obj.symtable.realname^+'$'+realname+'$'+accessorname+'$'+pd.unique_id_str;
             finish_copied_procdef(pd,accessorname,obj.symtable,obj);
             finish_copied_procdef(pd,accessorname,obj.symtable,obj);
             sym:=pd.procsym;
             sym:=pd.procsym;
           end;
           end;

+ 13 - 1
compiler/jvm/tgcpu.pas

@@ -55,7 +55,7 @@ unit tgcpu;
     uses
     uses
        verbose,
        verbose,
        cgbase,
        cgbase,
-       symconst,symdef,symsym,symcpu,defutil,
+       symconst,symtable,symdef,symsym,symcpu,defutil,
        cpubase,aasmcpu,
        cpubase,aasmcpu,
        hlcgobj,hlcgcpu;
        hlcgobj,hlcgcpu;
 
 
@@ -211,6 +211,18 @@ unit tgcpu;
                   result:=true;
                   result:=true;
                 end;
                 end;
             end;
             end;
+          filedef:
+            begin
+              case tfiledef(def).filetyp of
+                ft_text:
+                  result:=getifspecialtemp(list,search_system_type('TEXTREC').typedef,forcesize,temptype,ref);
+                ft_typed,
+                ft_untyped:
+                  result:=getifspecialtemp(list,search_system_type('FILEREC').typedef,forcesize,temptype,ref);
+                else
+                  internalerror(2015091405);
+              end;
+            end;
         end;
         end;
       end;
       end;
 
 

+ 2 - 2
compiler/link.pas

@@ -1156,7 +1156,7 @@ Implementation
 
 
     procedure TInternalLinker.ParseScript_Handle;
     procedure TInternalLinker.ParseScript_Handle;
       var
       var
-        s, para, keyword : String;
+        s{, para}, keyword : String;
         hp : TCmdStrListItem;
         hp : TCmdStrListItem;
         i : longint;
         i : longint;
       begin
       begin
@@ -1172,7 +1172,7 @@ Implementation
                 continue;
                 continue;
               end;
               end;
             keyword:=Upper(GetToken(s,' '));
             keyword:=Upper(GetToken(s,' '));
-            para:=GetToken(s,' ');
+            {para:=}GetToken(s,' ');
             if Trim(s)<>'' then
             if Trim(s)<>'' then
               Comment(V_Warning,'Unknown part "'+s+'" in "'+hp.str+'" internal linker script');
               Comment(V_Warning,'Unknown part "'+s+'" in "'+hp.str+'" internal linker script');
             if (keyword<>'SYMBOL') and
             if (keyword<>'SYMBOL') and

+ 80 - 15
compiler/llvm/aasmllvm.pas

@@ -101,6 +101,8 @@ interface
         constructor getelementptr_reg_size_ref_size_const(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:ptrint;indirect:boolean);
         constructor getelementptr_reg_size_ref_size_const(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:ptrint;indirect:boolean);
         constructor getelementptr_reg_tai_size_const(dst:tregister;const ai:tai;indextype:tdef;index1:ptrint;indirect:boolean);
         constructor getelementptr_reg_tai_size_const(dst:tregister;const ai:tai;indextype:tdef;index1:ptrint;indirect:boolean);
 
 
+        constructor blockaddress(dstreg: tregister; fun, lab: tasmsymbol);
+
         { e.g. dst = call retsize name (paras) }
         { e.g. dst = call retsize name (paras) }
         constructor call_size_name_paras(callpd: tdef; dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist);
         constructor call_size_name_paras(callpd: tdef; dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist);
         { e.g. dst = call retsize reg (paras) }
         { e.g. dst = call retsize reg (paras) }
@@ -147,6 +149,14 @@ interface
       constructor create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _vis: tllvmvisibility; _linkage: tllvmlinkage);
       constructor create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _vis: tllvmvisibility; _linkage: tllvmlinkage);
     end;
     end;
 
 
+    taillvmdeclflag =
+    (
+      ldf_definition,   { definition as opposed to (an external) declaration }
+      ldf_tls,          { tls definition }
+      ldf_unnamed_addr  { address doesn't matter, only content }
+    );
+    taillvmdeclflags = set of taillvmdeclflag;
+
     { declarations/definitions of symbols (procedures, variables), both defined
     { declarations/definitions of symbols (procedures, variables), both defined
       here and external }
       here and external }
     taillvmdecl = class(tai)
     taillvmdecl = class(tai)
@@ -156,9 +166,12 @@ interface
       def: tdef;
       def: tdef;
       sec: TAsmSectiontype;
       sec: TAsmSectiontype;
       alignment: shortint;
       alignment: shortint;
-      tls: boolean;
-      constructor create(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
+      flags: taillvmdeclflags;
+      secname: TSymStr;
+      constructor createdecl(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
+      constructor createdef(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
       constructor createtls(_namesym: tasmsymbol; _def: tdef; _alignment: shortint);
       constructor createtls(_namesym: tasmsymbol; _def: tdef; _alignment: shortint);
+      procedure setsecname(const name: TSymStr);
       destructor destroy; override;
       destructor destroy; override;
     end;
     end;
 
 
@@ -184,7 +197,7 @@ uses
 
 
     { taillvmprocdecl }
     { taillvmprocdecl }
 
 
-    constructor taillvmdecl.create(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
+    constructor taillvmdecl.createdecl(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
       begin
       begin
         inherited create;
         inherited create;
         typ:=ait_llvmdecl;
         typ:=ait_llvmdecl;
@@ -194,13 +207,29 @@ uses
         sec:=_sec;
         sec:=_sec;
         alignment:=_alignment;
         alignment:=_alignment;
         _namesym.declared:=true;
         _namesym.declared:=true;
+        flags:=[];
+      end;
+
+
+    constructor taillvmdecl.createdef(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
+      begin
+        createdecl(_namesym,_def,_initdata,_sec,_alignment);
+        include(flags,ldf_definition);
       end;
       end;
 
 
 
 
     constructor taillvmdecl.createtls(_namesym: tasmsymbol; _def: tdef; _alignment: shortint);
     constructor taillvmdecl.createtls(_namesym: tasmsymbol; _def: tdef; _alignment: shortint);
       begin
       begin
-        create(_namesym,_def,nil,sec_data,_alignment);
-        tls:=true;
+        createdef(_namesym,_def,nil,sec_data,_alignment);
+        include(flags,ldf_tls);
+      end;
+
+
+    procedure taillvmdecl.setsecname(const name: TSymStr);
+      begin
+        if sec<>sec_user then
+          internalerror(2015111501);
+        secname:=name;
       end;
       end;
 
 
 
 
@@ -404,7 +433,7 @@ uses
       begin
       begin
         case llvmopcode of
         case llvmopcode of
           la_ret, la_br, la_switch, la_indirectbr,
           la_ret, la_br, la_switch, la_indirectbr,
-          la_invoke, la_resume,
+          la_resume,
           la_unreachable,
           la_unreachable,
           la_store,
           la_store,
           la_fence,
           la_fence,
@@ -427,7 +456,7 @@ uses
           la_getelementptr,
           la_getelementptr,
           la_load,
           la_load,
           la_icmp, la_fcmp,
           la_icmp, la_fcmp,
-          la_phi, la_select, la_call,
+          la_phi, la_select,
           la_va_arg, la_landingpad:
           la_va_arg, la_landingpad:
             begin
             begin
               if opnr=0 then
               if opnr=0 then
@@ -435,6 +464,19 @@ uses
               else
               else
                 result:=operand_read;
                 result:=operand_read;
             end;
             end;
+          la_invoke, la_call:
+            begin
+              if opnr=1 then
+                result:=operand_write
+              else
+                result:=operand_read;
+            end;
+          la_blockaddress:
+            case opnr of
+              0: result:=operand_write
+              else
+                result:=operand_read;
+            end
           else
           else
             internalerror(2013103101)
             internalerror(2013103101)
         end;
         end;
@@ -468,10 +510,18 @@ uses
             end;
             end;
           la_invoke, la_call:
           la_invoke, la_call:
             begin
             begin
-              if opnr=0 then
-                result:=oper[1]^.def
-              else
-                internalerror(2013110102);
+              case opnr of
+                1: result:=oper[0]^.def;
+                3:
+                  begin
+                    if oper[3]^.typ=top_reg then
+                      result:=oper[2]^.def
+                    else
+                      internalerror(2015112001)
+                  end
+                else
+                  internalerror(2013110102);
+              end;
             end;
             end;
           la_br,
           la_br,
           la_unreachable:
           la_unreachable:
@@ -551,6 +601,12 @@ uses
                   internalerror(2013110110);
                   internalerror(2013110110);
               end;
               end;
             end;
             end;
+          la_blockaddress:
+            case opnr of
+              0: result:=voidcodepointertype
+              else
+                internalerror(2015111904);
+            end
           else
           else
             internalerror(2013103101)
             internalerror(2013103101)
         end;
         end;
@@ -896,6 +952,15 @@ uses
         loadconst(index+1,index1);
         loadconst(index+1,index1);
       end;
       end;
 
 
+    constructor taillvm.blockaddress(dstreg: tregister; fun, lab: tasmsymbol);
+      begin
+        create_llvm(la_blockaddress);
+        ops:=3;
+        loadreg(0,dstreg);
+        loadsymbol(1,fun,0);
+        loadsymbol(2,lab,0);
+      end;
+
 
 
     constructor taillvm.call_size_name_paras(callpd: tdef; dst: tregister; retsize: tdef; name:tasmsymbol; paras: tfplist);
     constructor taillvm.call_size_name_paras(callpd: tdef; dst: tregister; retsize: tdef; name:tasmsymbol; paras: tfplist);
       begin
       begin
@@ -906,9 +971,9 @@ uses
           have to insert a type conversion later from the alias def to the
           have to insert a type conversion later from the alias def to the
           call def here; we can't always do that at the point the call itself
           call def here; we can't always do that at the point the call itself
           is generated, because the alias declaration may occur anywhere }
           is generated, because the alias declaration may occur anywhere }
-        loaddef(0,callpd);
+        loaddef(0,retsize);
         loadreg(1,dst);
         loadreg(1,dst);
-        loaddef(2,retsize);
+        loaddef(2,callpd);
         loadsymbol(3,name,0);
         loadsymbol(3,name,0);
         loadparas(4,paras);
         loadparas(4,paras);
       end;
       end;
@@ -918,9 +983,9 @@ uses
       begin
       begin
         create_llvm(la_call);
         create_llvm(la_call);
         ops:=5;
         ops:=5;
-        loaddef(0,callpd);
+        loaddef(0,retsize);
         loadreg(1,dst);
         loadreg(1,dst);
-        loaddef(2,retsize);
+        loaddef(2,callpd);
         loadreg(3,reg);
         loadreg(3,reg);
         loadparas(4,paras);
         loadparas(4,paras);
       end;
       end;

+ 241 - 143
compiler/llvm/agllvm.pas

@@ -26,13 +26,18 @@ unit agllvm;
 interface
 interface
 
 
     uses
     uses
-      globtype,globals,
+      globtype,globals,systems,
       aasmbase,aasmtai,aasmdata,
       aasmbase,aasmtai,aasmdata,
       assemble;
       assemble;
 
 
     type
     type
       TLLVMInstrWriter = class;
       TLLVMInstrWriter = class;
-      { TLLVMAssember }
+
+      TLLVMModuleInlineAssemblyDecorator = class(TObject,IExternalAssemblerOutputFileDecorator)
+       function LinePrefix: AnsiString;
+       function LinePostfix: AnsiString;
+       function LineFilter(const s: AnsiString): AnsiString;
+      end;
 
 
       TLLVMAssember=class(texternalassembler)
       TLLVMAssember=class(texternalassembler)
       protected
       protected
@@ -47,8 +52,7 @@ interface
         procedure WriteOrdConst(hp: tai_const);
         procedure WriteOrdConst(hp: tai_const);
         procedure WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
         procedure WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
        public
        public
-        constructor create(smart: boolean); override;
-        procedure AsmLn; override;
+        constructor create(info: pasminfo; smart: boolean); override;
         function MakeCmdLine: TCmdStr; override;
         function MakeCmdLine: TCmdStr; override;
         procedure WriteTree(p:TAsmList);override;
         procedure WriteTree(p:TAsmList);override;
         procedure WriteAsmList;override;
         procedure WriteAsmList;override;
@@ -79,7 +83,7 @@ implementation
 
 
     uses
     uses
       SysUtils,
       SysUtils,
-      cutils,cfileutl,systems,
+      cutils,cfileutl,
       fmodule,verbose,
       fmodule,verbose,
       aasmcnst,symconst,symdef,symtable,
       aasmcnst,symconst,symdef,symtable,
       llvmbase,aasmllvm,itllvm,llvmdef,
       llvmbase,aasmllvm,itllvm,llvmdef,
@@ -133,6 +137,42 @@ implementation
       end;
       end;
 
 
 
 
+{****************************************************************************}
+{               Decorator for module-level inline assembly                   }
+{****************************************************************************}
+
+    function TLLVMModuleInlineAssemblyDecorator.LinePrefix: AnsiString;
+      begin
+        result:='module asm "';
+      end;
+
+
+    function TLLVMModuleInlineAssemblyDecorator.LinePostfix: AnsiString;
+      begin
+        result:='"';
+      end;
+
+
+    function TLLVMModuleInlineAssemblyDecorator.LineFilter(const s: AnsiString): AnsiString;
+      var
+        i: longint;
+      begin
+        result:='';
+        for i:=1 to length(s) do
+          begin
+            case s[i] of
+              #0..#31,
+              #127..#255,
+              '"','\':
+                result:=result+
+                        '\'+
+                        chr((ord(s[i]) shr 4)+ord('0'))+
+                        chr((ord(s[i]) and $f)+ord('0'));
+            else
+              result:=result+s[i];
+            end;
+          end;
+      end;
 
 
 
 
  {****************************************************************************}
  {****************************************************************************}
@@ -316,7 +356,7 @@ implementation
              tmpinline:=1;
              tmpinline:=1;
              tmpasmblock:=false;
              tmpasmblock:=false;
              hp:=o.ai;
              hp:=o.ai;
-             owner.AsmWrite(fstr);
+             owner.writer.AsmWrite(fstr);
              fstr:='';
              fstr:='';
              owner.WriteTai(false,false,tmpinline,tmpasmblock,hp);
              owner.WriteTai(false,false,tmpinline,tmpasmblock,hp);
              result:='';
              result:='';
@@ -349,7 +389,7 @@ implementation
         (and their output must come after everything that was processed in this
         (and their output must come after everything that was processed in this
          instruction, such as its opcode or previous operands) }
          instruction, such as its opcode or previous operands) }
       if owner.fdecllevel=0 then
       if owner.fdecllevel=0 then
-        owner.AsmWrite(#9);
+        owner.writer.AsmWrite(#9);
       sep:=' ';
       sep:=' ';
       done:=false;
       done:=false;
       opstart:=0;
       opstart:=0;
@@ -357,9 +397,9 @@ implementation
       case op of
       case op of
         la_type:
         la_type:
            begin
            begin
-             owner.asmwrite(llvmtypeidentifier(taillvm(hp).oper[0]^.def));
-             owner.asmwrite(' = type ');
-             owner.asmwrite(llvmencodetypedecl(taillvm(hp).oper[0]^.def));
+             owner.writer.AsmWrite(llvmtypeidentifier(taillvm(hp).oper[0]^.def));
+             owner.writer.AsmWrite(' = type ');
+             owner.writer.AsmWrite(llvmencodetypedecl(taillvm(hp).oper[0]^.def));
              done:=true;
              done:=true;
            end;
            end;
         la_ret, la_br, la_switch, la_indirectbr,
         la_ret, la_br, la_switch, la_indirectbr,
@@ -375,13 +415,23 @@ implementation
         la_call:
         la_call:
           begin
           begin
             if taillvm(hp).oper[1]^.reg<>NR_NO then
             if taillvm(hp).oper[1]^.reg<>NR_NO then
-              owner.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
+              owner.writer.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
             sep:=' ';
             sep:=' ';
             opstart:=2;
             opstart:=2;
           end;
           end;
+        la_blockaddress:
+          begin
+            owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,false));
+            owner.writer.AsmWrite(' = blockaddress(');
+            owner.writer.AsmWrite(getopstr(taillvm(hp).oper[1]^,false));
+            owner.writer.AsmWrite(',');
+            owner.writer.AsmWrite(getopstr(taillvm(hp).oper[2]^,false));
+            owner.writer.AsmWrite(')');
+            done:=true;
+          end;
         la_alloca:
         la_alloca:
           begin
           begin
-            owner.AsmWrite(getreferencestring(taillvm(hp).oper[0]^.ref^,false)+' = ');
+            owner.writer.AsmWrite(getreferencestring(taillvm(hp).oper[0]^.ref^,false)+' = ');
             sep:=' ';
             sep:=' ';
             opstart:=1;
             opstart:=1;
           end;
           end;
@@ -394,27 +444,27 @@ implementation
               data initialisers }
               data initialisers }
             if (taillvm(hp).oper[0]^.typ<>top_reg) or
             if (taillvm(hp).oper[0]^.typ<>top_reg) or
                (taillvm(hp).oper[0]^.reg<>NR_NO) then
                (taillvm(hp).oper[0]^.reg<>NR_NO) then
-              owner.AsmWrite(getopstr(taillvm(hp).oper[0]^,false)+' = ')
+              owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,false)+' = ')
             else
             else
               nested:=true;
               nested:=true;
-            owner.AsmWrite(llvm_op2str[op]);
+            owner.writer.AsmWrite(llvm_op2str[op]);
             if not nested then
             if not nested then
-              owner.AsmWrite(' ')
+              owner.writer.AsmWrite(' ')
             else
             else
-              owner.AsmWrite(' (');
-            owner.AsmWrite(getopstr(taillvm(hp).oper[1]^,false));
+              owner.writer.AsmWrite(' (');
+            owner.writer.AsmWrite(getopstr(taillvm(hp).oper[1]^,false));
             { if there's a tai operand, its def is used instead of an
             { if there's a tai operand, its def is used instead of an
               explicit def operand }
               explicit def operand }
             if taillvm(hp).ops=4 then
             if taillvm(hp).ops=4 then
               begin
               begin
-                owner.AsmWrite(' ');
-                owner.AsmWrite(getopstr(taillvm(hp).oper[2]^,false));
+                owner.writer.AsmWrite(' ');
+                owner.writer.AsmWrite(getopstr(taillvm(hp).oper[2]^,false));
                 opstart:=3;
                 opstart:=3;
               end
               end
             else
             else
               opstart:=2;
               opstart:=2;
-            owner.AsmWrite(' to ');
-            owner.AsmWrite(getopstr(taillvm(hp).oper[opstart]^,false));
+            owner.writer.AsmWrite(' to ');
+            owner.writer.AsmWrite(getopstr(taillvm(hp).oper[opstart]^,false));
             done:=true;
             done:=true;
           end
           end
         else
         else
@@ -422,7 +472,7 @@ implementation
             if (taillvm(hp).oper[0]^.typ<>top_reg) or
             if (taillvm(hp).oper[0]^.typ<>top_reg) or
                (taillvm(hp).oper[0]^.reg<>NR_NO) then
                (taillvm(hp).oper[0]^.reg<>NR_NO) then
               begin
               begin
-                owner.AsmWrite(getopstr(taillvm(hp).oper[0]^,true)+' = ');
+                owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,true)+' = ');
               end
               end
             else
             else
               nested:=true;
               nested:=true;
@@ -433,15 +483,15 @@ implementation
       { process operands }
       { process operands }
       if not done then
       if not done then
         begin
         begin
-          owner.AsmWrite(llvm_op2str[op]);
+          owner.writer.AsmWrite(llvm_op2str[op]);
           if nested then
           if nested then
-            owner.AsmWrite(' (');
+            owner.writer.AsmWrite(' (');
           if taillvm(hp).ops<>0 then
           if taillvm(hp).ops<>0 then
             begin
             begin
               for i:=opstart to taillvm(hp).ops-1 do
               for i:=opstart to taillvm(hp).ops-1 do
                 begin
                 begin
-                   owner.AsmWrite(sep);
-                   owner.AsmWrite(getopstr(taillvm(hp).oper[i]^,op in [la_load,la_store]));
+                   owner.writer.AsmWrite(sep);
+                   owner.writer.AsmWrite(getopstr(taillvm(hp).oper[i]^,op in [la_load,la_store]));
                    if (taillvm(hp).oper[i]^.typ in [top_def,top_cond,top_fpcond]) or
                    if (taillvm(hp).oper[i]^.typ in [top_def,top_cond,top_fpcond]) or
                       (op=la_call) then
                       (op=la_call) then
                      sep :=' '
                      sep :=' '
@@ -451,13 +501,14 @@ implementation
             end;
             end;
         end;
         end;
       if op=la_alloca then
       if op=la_alloca then
-        owner.AsmWrite(getreferencealignstring(taillvm(hp).oper[0]^.ref^));
+        owner.writer.AsmWrite(getreferencealignstring(taillvm(hp).oper[0]^.ref^));
       if nested then
       if nested then
-        owner.AsmWrite(')')
-      else
-        owner.AsmLn;
+        owner.writer.AsmWrite(')')
+      else if owner.fdecllevel=0 then
+        owner.writer.AsmLn;
     end;
     end;
 
 
+
 {****************************************************************************}
 {****************************************************************************}
 {                          LLVM Assembler writer                              }
 {                          LLVM Assembler writer                              }
 {****************************************************************************}
 {****************************************************************************}
@@ -520,7 +571,7 @@ implementation
     begin
     begin
       if not assigned(p) then
       if not assigned(p) then
        exit;
        exit;
-      replaceforbidden:=target_asm.dollarsign<>'$';
+      replaceforbidden:=asminfo^.dollarsign<>'$';
 
 
       InlineLevel:=0;
       InlineLevel:=0;
       asmblock:=false;
       asmblock:=false;
@@ -548,12 +599,12 @@ implementation
 
 
     procedure TLLVMAssember.WriteExtraHeader;
     procedure TLLVMAssember.WriteExtraHeader;
       begin
       begin
-        AsmWrite('target datalayout = "');
-        AsmWrite(target_info.llvmdatalayout);
-        AsmWriteln('"');
-        AsmWrite('target triple = "');
-        AsmWrite(llvm_target_name);
-        AsmWriteln('"');
+        writer.AsmWrite('target datalayout = "');
+        writer.AsmWrite(target_info.llvmdatalayout);
+        writer.AsmWriteln('"');
+        writer.AsmWrite('target triple = "');
+        writer.AsmWrite(llvm_target_name);
+        writer.AsmWriteln('"');
       end;
       end;
 
 
 
 
@@ -581,32 +632,32 @@ implementation
           begin
           begin
             case tai_realconst(hp).realtyp of
             case tai_realconst(hp).realtyp of
               aitrealconst_s32bit:
               aitrealconst_s32bit:
-                AsmWriteLn(target_asm.comment+'value: '+single2str(tai_realconst(hp).value.s32val));
+                writer.AsmWriteLn(asminfo^.comment+'value: '+single2str(tai_realconst(hp).value.s32val));
               aitrealconst_s64bit:
               aitrealconst_s64bit:
-                AsmWriteLn(target_asm.comment+'value: '+double2str(tai_realconst(hp).value.s64val));
+                writer.AsmWriteLn(asminfo^.comment+'value: '+double2str(tai_realconst(hp).value.s64val));
 {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
 {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
               { can't write full 80 bit floating point constants yet on non-x86 }
               { can't write full 80 bit floating point constants yet on non-x86 }
               aitrealconst_s80bit:
               aitrealconst_s80bit:
-                AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s80val));
+                writer.AsmWriteLn(asminfo^.comment+'value: '+extended2str(tai_realconst(hp).value.s80val));
 {$endif cpuextended}
 {$endif cpuextended}
               aitrealconst_s64comp:
               aitrealconst_s64comp:
-                AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s64compval));
+                writer.AsmWriteLn(asminfo^.comment+'value: '+extended2str(tai_realconst(hp).value.s64compval));
               else
               else
                 internalerror(2014050604);
                 internalerror(2014050604);
             end;
             end;
           end;
           end;
         case hp.realtyp of
         case hp.realtyp of
           aitrealconst_s32bit:
           aitrealconst_s32bit:
-            AsmWriteln(llvmdoubletostr(hp.value.s32val));
+            writer.AsmWriteln(llvmdoubletostr(hp.value.s32val));
           aitrealconst_s64bit:
           aitrealconst_s64bit:
-            AsmWriteln(llvmdoubletostr(hp.value.s64val));
+            writer.AsmWriteln(llvmdoubletostr(hp.value.s64val));
 {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
 {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
           aitrealconst_s80bit:
           aitrealconst_s80bit:
-            AsmWriteln(llvmextendedtostr(hp.value.s80val));
+            writer.AsmWriteln(llvmextendedtostr(hp.value.s80val));
 {$endif defined(cpuextended)}
 {$endif defined(cpuextended)}
           aitrealconst_s64comp:
           aitrealconst_s64comp:
             { handled as int64 most of the time in llvm }
             { handled as int64 most of the time in llvm }
-            AsmWriteln(tostr(round(hp.value.s64compval)));
+            writer.AsmWriteln(tostr(round(hp.value.s64compval)));
           else
           else
             internalerror(2014062401);
             internalerror(2014062401);
         end;
         end;
@@ -618,7 +669,7 @@ implementation
         consttyp: taiconst_type;
         consttyp: taiconst_type;
       begin
       begin
         if fdecllevel=0 then
         if fdecllevel=0 then
-          asmwrite(target_asm.comment+' const ');
+          writer.AsmWrite(asminfo^.comment+' const ');
         consttyp:=hp.consttype;
         consttyp:=hp.consttype;
         case consttyp of
         case consttyp of
           aitconst_got,
           aitconst_got,
@@ -642,26 +693,27 @@ implementation
           aitconst_64bit_unaligned:
           aitconst_64bit_unaligned:
             begin
             begin
               if fdecllevel=0 then
               if fdecllevel=0 then
-                AsmWrite(target_asm.comment);
+                writer.AsmWrite(asminfo^.comment);
               { can't have compile-time differences between symbols; these are
               { can't have compile-time differences between symbols; these are
                 normally for PIC, but llvm takes care of that for us }
                 normally for PIC, but llvm takes care of that for us }
               if assigned(hp.endsym) then
               if assigned(hp.endsym) then
                 internalerror(2014052902);
                 internalerror(2014052902);
               if assigned(hp.sym) then
               if assigned(hp.sym) then
                 begin
                 begin
-                  AsmWrite(LlvmAsmSymName(hp.sym));
+                  writer.AsmWrite(LlvmAsmSymName(hp.sym));
                   { can't have offsets }
                   { can't have offsets }
                   if hp.value<>0 then
                   if hp.value<>0 then
                     if fdecllevel<>0 then
                     if fdecllevel<>0 then
                       internalerror(2014052903)
                       internalerror(2014052903)
                     else
                     else
-                      asmwrite(' -- symbol offset: ' + tostr(hp.value));
+                      writer.AsmWrite(' -- symbol offset: ' + tostr(hp.value));
                 end
                 end
               else if hp.value=0 then
               else if hp.value=0 then
-                AsmWrite('zeroinitializer')
+                writer.AsmWrite('zeroinitializer')
               else
               else
-                AsmWrite(tostr(hp.value));
-              AsmLn;
+                writer.AsmWrite(tostr(hp.value));
+              if fdecllevel=0 then
+                writer.AsmLn;
             end;
             end;
           else
           else
             internalerror(200704251);
             internalerror(200704251);
@@ -671,6 +723,24 @@ implementation
 
 
     procedure TLLVMAssember.WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
     procedure TLLVMAssember.WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
 
 
+      procedure WriteFunctionFlags(pd: tprocdef);
+        begin
+          if (pos('FPC_SETJMP',upper(pd.mangledname))<>0) or
+             (pd.mangledname=(target_info.cprefix+'setjmp')) then
+            writer.AsmWrite(' returns_twice');
+          if po_inline in pd.procoptions then
+            writer.AsmWrite(' inlinehint');
+          { ensure that functions that happen to have the same name as a
+            standard C library function, but which are implemented in Pascal,
+            are not considered to have the same semantics as the C function with
+            the same name }
+          if not(po_external in pd.procoptions) then
+            writer.AsmWrite(' nobuiltin');
+          if po_noreturn in pd.procoptions then
+            writer.AsmWrite(' noreturn');
+        end;
+
+
       procedure WriteTypedConstData(hp: tai_abstracttypedconst);
       procedure WriteTypedConstData(hp: tai_abstracttypedconst);
         var
         var
           p: tai_abstracttypedconst;
           p: tai_abstracttypedconst;
@@ -683,38 +753,40 @@ implementation
           case hp.adetyp of
           case hp.adetyp of
             tck_record:
             tck_record:
               begin
               begin
-                AsmWrite(defstr);
-                AsmWrite(' ');
-                if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
-                  AsmWrite('<{')
+                writer.AsmWrite(defstr);
+                writer.AsmWrite(' ');
+                if (hp.def.typ in [objectdef,recorddef]) and
+                   (tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment) then
+                  writer.AsmWrite('<{')
                 else
                 else
-                  AsmWrite('{');
+                  writer.AsmWrite('{');
                 first:=true;
                 first:=true;
                 for p in tai_aggregatetypedconst(hp) do
                 for p in tai_aggregatetypedconst(hp) do
                   begin
                   begin
                     if not first then
                     if not first then
-                      AsmWrite(', ')
+                      writer.AsmWrite(', ')
                     else
                     else
                       first:=false;
                       first:=false;
                     WriteTypedConstData(p);
                     WriteTypedConstData(p);
                   end;
                   end;
-                if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
-                  AsmWrite('}>')
+                if (hp.def.typ in [recorddef,objectdef]) and
+                   (tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment) then
+                  writer.AsmWrite('}>')
                 else
                 else
-                  AsmWrite('}');
+                  writer.AsmWrite('}');
               end;
               end;
             tck_array:
             tck_array:
               begin
               begin
-                AsmWrite(defstr);
+                writer.AsmWrite(defstr);
                 first:=true;
                 first:=true;
                 gotstring:=false;
                 gotstring:=false;
                 for p in tai_aggregatetypedconst(hp) do
                 for p in tai_aggregatetypedconst(hp) do
                   begin
                   begin
                     if not first then
                     if not first then
-                      AsmWrite(',')
+                      writer.AsmWrite(',')
                     else
                     else
                       begin
                       begin
-                        AsmWrite(' ');
+                        writer.AsmWrite(' ');
                         if (tai_abstracttypedconst(p).adetyp=tck_simple) and
                         if (tai_abstracttypedconst(p).adetyp=tck_simple) and
                            (tai_simpletypedconst(p).val.typ=ait_string) then
                            (tai_simpletypedconst(p).val.typ=ait_string) then
                           begin
                           begin
@@ -722,7 +794,7 @@ implementation
                           end
                           end
                         else
                         else
                           begin
                           begin
-                            AsmWrite('[');
+                            writer.AsmWrite('[');
                           end;
                           end;
                         first:=false;
                         first:=false;
                       end;
                       end;
@@ -734,15 +806,15 @@ implementation
                     WriteTypedConstData(p);
                     WriteTypedConstData(p);
                   end;
                   end;
                 if not gotstring then
                 if not gotstring then
-                  AsmWrite(']');
+                  writer.AsmWrite(']');
               end;
               end;
             tck_simple:
             tck_simple:
               begin
               begin
                 pval:=tai_simpletypedconst(hp).val;
                 pval:=tai_simpletypedconst(hp).val;
                 if pval.typ<>ait_string then
                 if pval.typ<>ait_string then
                   begin
                   begin
-                    AsmWrite(defstr);
-                    AsmWrite(' ');
+                    writer.AsmWrite(defstr);
+                    writer.AsmWrite(' ');
                   end;
                   end;
                 WriteTai(replaceforbidden,do_line,InlineLevel,asmblock,pval);
                 WriteTai(replaceforbidden,do_line,InlineLevel,asmblock,pval);
               end;
               end;
@@ -758,27 +830,29 @@ implementation
         case hp.typ of
         case hp.typ of
           ait_comment :
           ait_comment :
             begin
             begin
-              AsmWrite(target_asm.comment);
-              AsmWritePChar(tai_comment(hp).str);
-              AsmLn;
+              writer.AsmWrite(asminfo^.comment);
+              writer.AsmWritePChar(tai_comment(hp).str);
+              if fdecllevel<>0 then
+                internalerror(2015090601);
+              writer.AsmLn;
             end;
             end;
 
 
           ait_regalloc :
           ait_regalloc :
             begin
             begin
               if (cs_asm_regalloc in current_settings.globalswitches) then
               if (cs_asm_regalloc in current_settings.globalswitches) then
                 begin
                 begin
-                  AsmWrite(#9+target_asm.comment+'Register ');
+                  writer.AsmWrite(#9+asminfo^.comment+'Register ');
                   repeat
                   repeat
-                    AsmWrite(std_regname(Tai_regalloc(hp).reg));
+                    writer.AsmWrite(std_regname(Tai_regalloc(hp).reg));
                      if (hp.next=nil) or
                      if (hp.next=nil) or
                        (tai(hp.next).typ<>ait_regalloc) or
                        (tai(hp.next).typ<>ait_regalloc) or
                        (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
                        (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
                       break;
                       break;
                     hp:=tai(hp.next);
                     hp:=tai(hp.next);
-                    AsmWrite(',');
+                    writer.AsmWrite(',');
                   until false;
                   until false;
-                  AsmWrite(' ');
-                  AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
+                  writer.AsmWrite(' ');
+                  writer.AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
                 end;
                 end;
             end;
             end;
 
 
@@ -798,8 +872,8 @@ implementation
 
 
           ait_datablock :
           ait_datablock :
             begin
             begin
-              AsmWrite(target_asm.comment);
-              AsmWriteln('datablock');
+              writer.AsmWrite(asminfo^.comment);
+              writer.AsmWriteln('datablock');
             end;
             end;
 
 
           ait_const:
           ait_const:
@@ -815,8 +889,8 @@ implementation
           ait_string :
           ait_string :
             begin
             begin
               if fdecllevel=0 then
               if fdecllevel=0 then
-                AsmWrite(target_asm.comment);
-              AsmWrite('c"');
+                writer.AsmWrite(asminfo^.comment);
+              writer.AsmWrite('c"');
               for i:=1 to tai_string(hp).len do
               for i:=1 to tai_string(hp).len do
                begin
                begin
                  ch:=tai_string(hp).str[i-1];
                  ch:=tai_string(hp).str[i-1];
@@ -829,9 +903,9 @@ implementation
                  else
                  else
                    s:=ch;
                    s:=ch;
                  end;
                  end;
-                 AsmWrite(s);
+                 writer.AsmWrite(s);
                end;
                end;
-              AsmWriteLn('"');
+              writer.AsmWriteLn('"');
             end;
             end;
 
 
           ait_label :
           ait_label :
@@ -848,21 +922,21 @@ implementation
                    begin
                    begin
                      { should be emitted as part of the variable/function def }
                      { should be emitted as part of the variable/function def }
                      //internalerror(2013010704);
                      //internalerror(2013010704);
-                     AsmWriteln(target_asm.comment+'global/privateextern label: '+tai_label(hp).labsym.name);
+                     writer.AsmWriteln(asminfo^.comment+'global/privateextern label: '+tai_label(hp).labsym.name);
                    end;
                    end;
                  if replaceforbidden then
                  if replaceforbidden then
-                   AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
+                   writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
                  else
                  else
-                   AsmWrite(tai_label(hp).labsym.name);
-                 AsmWriteLn(':');
+                   writer.AsmWrite(tai_label(hp).labsym.name);
+                 writer.AsmWriteLn(':');
                end;
                end;
             end;
             end;
 
 
           ait_symbol :
           ait_symbol :
             begin
             begin
               if fdecllevel=0 then
               if fdecllevel=0 then
-                AsmWrite(target_asm.comment);
-              AsmWriteln(LlvmAsmSymName(tai_symbol(hp).sym));
+                writer.AsmWrite(asminfo^.comment);
+              writer.AsmWriteln(LlvmAsmSymName(tai_symbol(hp).sym));
               { todo }
               { todo }
               if tai_symbol(hp).has_value then
               if tai_symbol(hp).has_value then
                 internalerror(2014062402);
                 internalerror(2014062402);
@@ -871,50 +945,55 @@ implementation
             begin
             begin
               if taillvmdecl(hp).def.typ=procdef then
               if taillvmdecl(hp).def.typ=procdef then
                 begin
                 begin
-                  if taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL] then
+                  if not(ldf_definition in taillvmdecl(hp).flags) then
                     begin
                     begin
-                      asmwrite('declare');
-                      asmwriteln(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), taillvmdecl(hp).namesym.name, lpd_decl));
+                      writer.AsmWrite('declare');
+                      writer.AsmWrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), taillvmdecl(hp).namesym.name, lpd_decl));
+                      WriteFunctionFlags(tprocdef(taillvmdecl(hp).def));
+                      writer.AsmLn;
                     end
                     end
                   else
                   else
                     begin
                     begin
-                      asmwrite('define');
-                      asmwrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), '', lpd_decl));
-                      asmwriteln(' {');
+                      writer.AsmWrite('define');
+                      writer.AsmWrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), '', lpd_decl));
+                      WriteFunctionFlags(tprocdef(taillvmdecl(hp).def));
+                      writer.AsmWriteln(' {');
                     end;
                     end;
                 end
                 end
               else
               else
                 begin
                 begin
-                  asmwrite(LlvmAsmSymName(taillvmdecl(hp).namesym));
+                  writer.AsmWrite(LlvmAsmSymName(taillvmdecl(hp).namesym));
                   case taillvmdecl(hp).namesym.bind of
                   case taillvmdecl(hp).namesym.bind of
                     AB_EXTERNAL:
                     AB_EXTERNAL:
-                      asmwrite(' = external ');
+                      writer.AsmWrite(' = external ');
                     AB_COMMON:
                     AB_COMMON:
-                      asmwrite(' = common ');
+                      writer.AsmWrite(' = common ');
                     AB_LOCAL:
                     AB_LOCAL:
-                      asmwrite(' = internal ');
+                      writer.AsmWrite(' = internal ');
                     AB_GLOBAL:
                     AB_GLOBAL:
-                      asmwrite(' = ');
+                      writer.AsmWrite(' = ');
                     AB_WEAK_EXTERNAL:
                     AB_WEAK_EXTERNAL:
-                      asmwrite(' = extern_weak ');
+                      writer.AsmWrite(' = extern_weak ');
                     AB_PRIVATE_EXTERN:
                     AB_PRIVATE_EXTERN:
-                      asmwrite('= linker_private ');
+                      writer.AsmWrite('= linker_private ');
                     else
                     else
                       internalerror(2014020104);
                       internalerror(2014020104);
                   end;
                   end;
-                  if taillvmdecl(hp).tls then
-                    asmwrite('thread_local ');
+                  if (ldf_tls in taillvmdecl(hp).flags) then
+                    writer.AsmWrite('thread_local ');
+                  if ldf_unnamed_addr in taillvmdecl(hp).flags then
+                    writer.AsmWrite('unnamed_addr ');
                   { todo: handle more different section types (mainly
                   { todo: handle more different section types (mainly
                       Objective-C }
                       Objective-C }
                   if taillvmdecl(hp).sec in [sec_rodata,sec_rodata_norel] then
                   if taillvmdecl(hp).sec in [sec_rodata,sec_rodata_norel] then
-                    asmwrite('unnamed_addr constant ')
+                    writer.AsmWrite('constant ')
                   else
                   else
-                    asmwrite('global ');
+                    writer.AsmWrite('global ');
                   if not assigned(taillvmdecl(hp).initdata) then
                   if not assigned(taillvmdecl(hp).initdata) then
                     begin
                     begin
-                      asmwrite(llvmencodetypename(taillvmdecl(hp).def));
+                      writer.AsmWrite(llvmencodetypename(taillvmdecl(hp).def));
                       if not(taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL]) then
                       if not(taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL]) then
-                        asmwrite(' zeroinitializer');
+                        writer.AsmWrite(' zeroinitializer');
                     end
                     end
                   else
                   else
                     begin
                     begin
@@ -932,33 +1011,40 @@ implementation
                         end;
                         end;
                       dec(fdecllevel);
                       dec(fdecllevel);
                     end;
                     end;
+                  { custom section name? }
+                  if taillvmdecl(hp).sec=sec_user then
+                    begin
+                      writer.AsmWrite(', section "');
+                      writer.AsmWrite(taillvmdecl(hp).secname);
+                      writer.AsmWrite('"');
+                    end;
                   { alignment }
                   { alignment }
-                  asmwrite(', align ');
-                  asmwriteln(tostr(taillvmdecl(hp).alignment));
+                  writer.AsmWrite(', align ');
+                  writer.AsmWriteln(tostr(taillvmdecl(hp).alignment));
                 end;
                 end;
             end;
             end;
           ait_llvmalias:
           ait_llvmalias:
             begin
             begin
-              asmwrite(LlvmAsmSymName(taillvmalias(hp).newsym));
-              asmwrite(' = alias ');
+              writer.AsmWrite(LlvmAsmSymName(taillvmalias(hp).newsym));
+              writer.AsmWrite(' = alias ');
               if taillvmalias(hp).linkage<>lll_default then
               if taillvmalias(hp).linkage<>lll_default then
                 begin
                 begin
                   str(taillvmalias(hp).linkage, s);
                   str(taillvmalias(hp).linkage, s);
-                  asmwrite(copy(s, length('lll_')+1, 255));
-                  asmwrite(' ');
+                  writer.AsmWrite(copy(s, length('lll_')+1, 255));
+                  writer.AsmWrite(' ');
                 end;
                 end;
               if taillvmalias(hp).vis<>llv_default then
               if taillvmalias(hp).vis<>llv_default then
                 begin
                 begin
                   str(taillvmalias(hp).vis, s);
                   str(taillvmalias(hp).vis, s);
-                  asmwrite(copy(s, length('llv_')+1, 255));
-                  asmwrite(' ');
+                  writer.AsmWrite(copy(s, length('llv_')+1, 255));
+                  writer.AsmWrite(' ');
                 end;
                 end;
               if taillvmalias(hp).def.typ=procdef then
               if taillvmalias(hp).def.typ=procdef then
-                asmwrite(llvmencodeproctype(tabstractprocdef(taillvmalias(hp).def), '', lpd_alias))
+                writer.AsmWrite(llvmencodeproctype(tabstractprocdef(taillvmalias(hp).def), '', lpd_alias))
               else
               else
-                asmwrite(llvmencodetypename(taillvmalias(hp).def));
-              asmwrite('* ');
-              asmwriteln(LlvmAsmSymName(taillvmalias(hp).oldsym));
+                writer.AsmWrite(llvmencodetypename(taillvmalias(hp).def));
+              writer.AsmWrite('* ');
+              writer.AsmWriteln(LlvmAsmSymName(taillvmalias(hp).oldsym));
             end;
             end;
           ait_symbolpair:
           ait_symbolpair:
             begin
             begin
@@ -975,9 +1061,9 @@ implementation
           ait_symbol_end :
           ait_symbol_end :
             begin
             begin
               if tai_symbol_end(hp).sym.typ=AT_FUNCTION then
               if tai_symbol_end(hp).sym.typ=AT_FUNCTION then
-                asmwriteln('}')
+                writer.AsmWriteln('}')
               else
               else
-                asmwriteln('; ait_symbol_end error, should not be generated');
+                writer.AsmWriteln('; ait_symbol_end error, should not be generated');
 //                internalerror(2013010711);
 //                internalerror(2013010711);
             end;
             end;
 
 
@@ -1022,8 +1108,10 @@ implementation
             begin
             begin
               WriteDirectiveName(tai_directive(hp).directive);
               WriteDirectiveName(tai_directive(hp).directive);
               if tai_directive(hp).name <>'' then
               if tai_directive(hp).name <>'' then
-                AsmWrite(tai_directive(hp).name);
-              AsmLn;
+                writer.AsmWrite(tai_directive(hp).name);
+              if fdecllevel<>0 then
+                internalerror(2015090602);
+              writer.AsmLn;
             end;
             end;
 
 
           ait_seh_directive :
           ait_seh_directive :
@@ -1033,12 +1121,14 @@ implementation
           ait_varloc:
           ait_varloc:
             begin
             begin
               if tai_varloc(hp).newlocationhi<>NR_NO then
               if tai_varloc(hp).newlocationhi<>NR_NO then
-                AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
+                writer.AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
                   std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation)))
                   std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation)))
               else
               else
-                AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
+                writer.AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
                   std_regname(tai_varloc(hp).newlocation)));
                   std_regname(tai_varloc(hp).newlocation)));
-              AsmLn;
+              if fdecllevel<>0 then
+                internalerror(2015090603);
+              writer.AsmLn;
             end;
             end;
            ait_typedconst:
            ait_typedconst:
              begin
              begin
@@ -1050,25 +1140,16 @@ implementation
       end;
       end;
 
 
 
 
-    constructor TLLVMAssember.create(smart: boolean);
+    constructor TLLVMAssember.create(info: pasminfo; smart: boolean);
       begin
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter:=TLLVMInstrWriter.create(self);
         InstrWriter:=TLLVMInstrWriter.create(self);
       end;
       end;
 
 
 
 
-    procedure TLLVMAssember.AsmLn;
-      begin
-        { don't write newlines in the middle of declarations }
-        if fdecllevel=0 then
-          inherited AsmLn;
-      end;
-
-
-
     procedure TLLVMAssember.WriteDirectiveName(dir: TAsmDirective);
     procedure TLLVMAssember.WriteDirectiveName(dir: TAsmDirective);
       begin
       begin
-        AsmWrite('.'+directivestr[dir]+' ');
+        writer.AsmWrite('.'+directivestr[dir]+' ');
       end;
       end;
 
 
 
 
@@ -1076,18 +1157,35 @@ implementation
       var
       var
         hal : tasmlisttype;
         hal : tasmlisttype;
         i: longint;
         i: longint;
+        a: TExternalAssembler;
+        decorator: TLLVMModuleInlineAssemblyDecorator;
       begin
       begin
         WriteExtraHeader;
         WriteExtraHeader;
-        AsmStartSize:=AsmSize;
 
 
         for hal:=low(TasmlistType) to high(TasmlistType) do
         for hal:=low(TasmlistType) to high(TasmlistType) do
           begin
           begin
-            AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
-            writetree(current_asmdata.asmlists[hal]);
-            AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
+            if not assigned(current_asmdata.asmlists[hal]) or
+               current_asmdata.asmlists[hal].Empty then
+              continue;
+            writer.AsmWriteLn(asminfo^.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
+            if hal<>al_pure_assembler then
+              writetree(current_asmdata.asmlists[hal])
+            else
+              begin
+                { write routines using the target-specific external assembler
+                  writer, filtered using the LLVM module-level assembly
+                  decorator }
+                decorator:=TLLVMModuleInlineAssemblyDecorator.Create;
+                writer.decorator:=decorator;
+                a:=GetExternalGnuAssemblerWithAsmInfoWriter(asminfo,writer);
+                a.WriteTree(current_asmdata.asmlists[hal]);
+                writer.decorator:=nil;
+                decorator.free;
+              end;
+            writer.AsmWriteLn(asminfo^.comment+'End asmlist '+AsmlistTypeStr[hal]);
           end;
           end;
 
 
-        AsmLn;
+        writer.AsmLn;
       end;
       end;
 
 
 
 

+ 134 - 38
compiler/llvm/hlcgllvm.pas

@@ -51,7 +51,7 @@ uses
       procedure deallocallcpuregisters(list: TAsmList); override;
       procedure deallocallcpuregisters(list: TAsmList); override;
 
 
      protected
      protected
-      procedure a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out calldef: tdef; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
+      procedure a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
      public
      public
       function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;override;
       function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;override;
       function a_call_reg(list: TAsmList; pd: tabstractprocdef; reg: tregister; const paras: array of pcgpara): tcgpara; override;
       function a_call_reg(list: TAsmList; pd: tabstractprocdef; reg: tregister; const paras: array of pcgpara): tcgpara; override;
@@ -94,8 +94,10 @@ uses
       procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override;
       procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override;
       procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;var ovloc : tlocation); override;
       procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;var ovloc : tlocation); override;
 
 
-      procedure g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tpointerdef; reg: tregister); override;
-      procedure g_ptrtypecast_ref(list: TAsmList; fromdef, todef: tpointerdef; var ref: treference); override;
+      procedure g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tdef; var reg: tregister); override;
+      procedure g_ptrtypecast_ref(list: TAsmList; fromdef: tpointerdef; todef: tdef; var ref: treference); override;
+
+      procedure g_set_addr_nonbitpacked_field_ref(list: TAsmList; recdef: tabstractrecorddef; field: tfieldvarsym; var recref: treference); override;
 
 
       procedure a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister; shuffle: pmmshuffle); override;
       procedure a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister; shuffle: pmmshuffle); override;
       procedure a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const ref: treference; shuffle: pmmshuffle); override;
       procedure a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const ref: treference; shuffle: pmmshuffle); override;
@@ -151,7 +153,8 @@ implementation
     aasmllvm,llvmbase,tgllvm,
     aasmllvm,llvmbase,tgllvm,
     symtable,symllvm,
     symtable,symllvm,
     paramgr,llvmpara,
     paramgr,llvmpara,
-    procinfo,cpuinfo,cgobj,cgllvm,cghlcpu;
+    procinfo,cpuinfo,cgobj,cgllvm,cghlcpu,
+    cgcpu,hlcgcpu;
 
 
   const
   const
     topcg2llvmop: array[topcg] of tllvmop =
     topcg2llvmop: array[topcg] of tllvmop =
@@ -256,7 +259,8 @@ implementation
                    OS_F128:
                    OS_F128:
                      a_loadmm_ref_reg(list,location^.def,location^.def,tmpref,location^.register,mms_movescalar);
                      a_loadmm_ref_reg(list,location^.def,location^.def,tmpref,location^.register,mms_movescalar);
                    OS_M8..OS_M128,
                    OS_M8..OS_M128,
-                   OS_MS8..OS_MS128:
+                   OS_MS8..OS_MS128,
+                   OS_32..OS_128:
                      a_loadmm_ref_reg(list,location^.def,location^.def,tmpref,location^.register,nil);
                      a_loadmm_ref_reg(list,location^.def,location^.def,tmpref,location^.register,nil);
                    else
                    else
                      internalerror(2010053101);
                      internalerror(2010053101);
@@ -332,7 +336,7 @@ implementation
     end;
     end;
 
 
 
 
-  procedure thlcgllvm.a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out calldef: tdef; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
+  procedure thlcgllvm.a_call_common(list: TAsmList; pd: tabstractprocdef; const paras: array of pcgpara; const forceresdef: tdef; out res: tregister; out hlretdef: tdef; out llvmretdef: tdef; out callparas: tfplist);
 
 
     procedure load_ref_anyreg(def: tdef; const ref: treference; reg: tregister; var callpara: pllvmcallpara);
     procedure load_ref_anyreg(def: tdef; const ref: treference; reg: tregister; var callpara: pllvmcallpara);
       begin
       begin
@@ -428,16 +432,6 @@ implementation
     if (pd.typ=procvardef) and
     if (pd.typ=procvardef) and
        not pd.is_addressonly then
        not pd.is_addressonly then
       pd:=tprocvardef(cprocvardef.getreusableprocaddr(pd));
       pd:=tprocvardef(cprocvardef.getreusableprocaddr(pd));
-    { if the function returns a function pointer type or is varargs, we
-      must specify the full function signature, otherwise we can only
-      specify the return type }
-    if (po_varargs in pd.procoptions) or
-       ((pd.proccalloption in cdecl_pocalls) and
-        (pd.paras.count>0) and
-        is_array_of_const(tparavarsym(pd.paras[pd.paras.count-1]).vardef)) then
-      calldef:=get_call_pd(pd)
-    else
-      calldef:=llvmretdef;
   end;
   end;
 
 
 
 
@@ -445,12 +439,11 @@ implementation
     var
     var
       callparas: tfplist;
       callparas: tfplist;
       llvmretdef,
       llvmretdef,
-      hlretdef,
-      calldef: tdef;
+      hlretdef: tdef;
       res: tregister;
       res: tregister;
     begin
     begin
-      a_call_common(list,pd,paras,forceresdef,res,calldef,hlretdef,llvmretdef,callparas);
-      list.concat(taillvm.call_size_name_paras(get_call_pd(pd),res,calldef,current_asmdata.RefAsmSymbol(pd.mangledname),callparas));
+      a_call_common(list,pd,paras,forceresdef,res,hlretdef,llvmretdef,callparas);
+      list.concat(taillvm.call_size_name_paras(get_call_pd(pd),res,llvmretdef,current_asmdata.RefAsmSymbol(pd.mangledname),callparas));
       result:=get_call_result_cgpara(pd,forceresdef);
       result:=get_call_result_cgpara(pd,forceresdef);
       set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
       set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
     end;
     end;
@@ -460,12 +453,11 @@ implementation
     var
     var
       callparas: tfplist;
       callparas: tfplist;
       llvmretdef,
       llvmretdef,
-      hlretdef,
-      calldef: tdef;
+      hlretdef: tdef;
       res: tregister;
       res: tregister;
     begin
     begin
-      a_call_common(list,pd,paras,nil,res,calldef,hlretdef,llvmretdef,callparas);
-      list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,calldef,reg,callparas));
+      a_call_common(list,pd,paras,nil,res,hlretdef,llvmretdef,callparas);
+      list.concat(taillvm.call_size_reg_paras(get_call_pd(pd),res,llvmretdef,reg,callparas));
       result:=get_call_result_cgpara(pd,nil);
       result:=get_call_result_cgpara(pd,nil);
       set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
       set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
     end;
     end;
@@ -529,8 +521,12 @@ implementation
                 truncate it before storing. Unfortunately, we cannot truncate
                 truncate it before storing. Unfortunately, we cannot truncate
                 records (nor bitcast them to integers), so we first have to
                 records (nor bitcast them to integers), so we first have to
                 store them to memory and then bitcast the pointer to them
                 store them to memory and then bitcast the pointer to them
+
+                We can't truncate an integer to 3/5/6/7 bytes either, so also
+                pass via a temp in that case
               }
               }
-              if fromsize.typ in [arraydef,recorddef] then
+              if (fromsize.typ in [arraydef,recorddef]) or
+                 (tosize.size in [3,5,6,7]) then
                 begin
                 begin
                   { store struct/array-in-register to memory }
                   { store struct/array-in-register to memory }
                   tg.gethltemp(list,fromsize,fromsize.size,tt_normal,tmpref);
                   tg.gethltemp(list,fromsize,fromsize.size,tt_normal,tmpref);
@@ -1085,7 +1081,7 @@ implementation
             list.concat(taillvmalias.create(asmsym,item.str,current_procinfo.procdef,llv_default,lll_default));
             list.concat(taillvmalias.create(asmsym,item.str,current_procinfo.procdef,llv_default,lll_default));
           item:=TCmdStrListItem(item.next);
           item:=TCmdStrListItem(item.next);
         end;
         end;
-      list.concat(taillvmdecl.create(asmsym,current_procinfo.procdef,nil,sec_code,current_procinfo.procdef.alignment));
+      list.concat(taillvmdecl.createdef(asmsym,current_procinfo.procdef,nil,sec_code,current_procinfo.procdef.alignment));
     end;
     end;
 
 
 
 
@@ -1140,11 +1136,6 @@ implementation
             LOC_FPUREGISTER,
             LOC_FPUREGISTER,
             LOC_MMREGISTER:
             LOC_MMREGISTER:
               begin
               begin
-                { inline assembler routines contain a ret at the end and never
-                  get here, but we do need a return at the end -> return an
-                  undefined value in this case }
-                if po_assembler in current_procinfo.procdef.procoptions then
-                  gen_load_uninitialized_function_result(list,current_procinfo.procdef,retpara.def,retpara);
                 { sign/zeroextension of function results is handled implicitly
                 { sign/zeroextension of function results is handled implicitly
                   via the signext/zeroext modifiers of the result, rather than
                   via the signext/zeroext modifiers of the result, rather than
                   in the code generator -> remove any explicit extensions here }
                   in the code generator -> remove any explicit extensions here }
@@ -1204,15 +1195,23 @@ implementation
     end;
     end;
 
 
 
 
-  procedure thlcgllvm.g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tpointerdef; reg: tregister);
+  procedure thlcgllvm.g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tdef; var reg: tregister);
+    var
+      hreg: tregister;
     begin
     begin
       { will insert a bitcast if necessary }
       { will insert a bitcast if necessary }
-      a_load_reg_reg(list,fromdef,todef,reg,reg);
+      if fromdef<>todef then
+        begin
+          hreg:=getregisterfordef(list,todef);
+          a_load_reg_reg(list,fromdef,todef,reg,hreg);
+          reg:=hreg;
+        end;
     end;
     end;
 
 
 
 
-  procedure thlcgllvm.g_ptrtypecast_ref(list: TAsmList; fromdef, todef: tpointerdef; var ref: treference);
+  procedure thlcgllvm.g_ptrtypecast_ref(list: TAsmList; fromdef: tpointerdef; todef: tdef; var ref: treference);
     var
     var
+      sref: treference;
       hreg: tregister;
       hreg: tregister;
     begin
     begin
       hreg:=getaddressregister(list,todef);
       hreg:=getaddressregister(list,todef);
@@ -1221,6 +1220,68 @@ implementation
     end;
     end;
 
 
 
 
+  procedure thlcgllvm.g_set_addr_nonbitpacked_field_ref(list: TAsmList; recdef: tabstractrecorddef; field: tfieldvarsym; var recref: treference);
+    var
+      parentdef,
+      subscriptdef,
+      currentstructdef,
+      llvmfielddef: tdef;
+      newbase: tregister;
+      implicitpointer: boolean;
+    begin
+      implicitpointer:=is_implicit_pointer_object_type(recdef);
+      currentstructdef:=recdef;
+      { in case the field is part of a parent of the current object,
+        index into the parents until we're at the parent containing the
+        field; if it's an implicit pointer type, these embedded parents
+        will be of the structure type of the class rather than of the
+        class time itself -> one indirection fewer }
+      while field.owner<>tabstractrecorddef(currentstructdef).symtable do
+        begin
+          { only objectdefs have parents and hence the owner of the
+            fieldvarsym can be different from the current def's owner }
+          parentdef:=tobjectdef(currentstructdef).childof;
+          if implicitpointer then
+            newbase:=getaddressregister(list,parentdef)
+          else
+            newbase:=getaddressregister(list,cpointerdef.getreusable(parentdef));
+          recref:=make_simple_ref(list,recref,recdef);
+          if implicitpointer then
+            subscriptdef:=currentstructdef
+          else
+            subscriptdef:=cpointerdef.getreusable(currentstructdef);
+          { recurse into the first field }
+          list.concat(taillvm.getelementptr_reg_size_ref_size_const(newbase,subscriptdef,recref,s32inttype,0,true));
+          reference_reset_base(recref,subscriptdef,newbase,field.offsetfromllvmfield,newalignment(recref.alignment,field.fieldoffset));
+          { go to the parent }
+          currentstructdef:=parentdef;
+        end;
+      { get the type of the corresponding field in the llvm shadow
+        definition }
+      llvmfielddef:=tabstractrecordsymtable(tabstractrecorddef(currentstructdef).symtable).llvmst[field].def;
+      if implicitpointer then
+        subscriptdef:=currentstructdef
+      else
+        subscriptdef:=cpointerdef.getreusable(currentstructdef);
+      { load the address of that shadow field }
+      newbase:=getaddressregister(list,cpointerdef.getreusable(llvmfielddef));
+      recref:=make_simple_ref(list,recref,recdef);
+      list.concat(taillvm.getelementptr_reg_size_ref_size_const(newbase,subscriptdef,recref,s32inttype,field.llvmfieldnr,true));
+      reference_reset_base(recref,subscriptdef,newbase,field.offsetfromllvmfield,newalignment(recref.alignment,field.fieldoffset+field.offsetfromllvmfield));
+      { in case of an 80 bits extended type, typecast from an array of 10
+        bytes (used because otherwise llvm will allocate the ABI-defined
+        size for extended, which is usually larger) into an extended }
+      if (llvmfielddef.typ=floatdef) and
+         (tfloatdef(llvmfielddef).floattype=s80real) then
+        g_ptrtypecast_ref(list,cpointerdef.getreusable(carraydef.getreusable(u8inttype,10)),cpointerdef.getreusable(s80floattype),recref);
+      { if it doesn't match the requested field exactly (variant record),
+        adjust the type of the pointer }
+      if (field.offsetfromllvmfield<>0) or
+         (llvmfielddef<>field.vardef) then
+        g_ptrtypecast_ref(list,cpointerdef.getreusable(llvmfielddef),cpointerdef.getreusable(field.vardef),recref);
+    end;
+
+
   procedure thlcgllvm.a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister; shuffle: pmmshuffle);
   procedure thlcgllvm.a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister; shuffle: pmmshuffle);
     var
     var
       href: treference;
       href: treference;
@@ -1588,6 +1649,7 @@ implementation
 
 
   procedure thlcgllvm.set_call_function_result(const list: TAsmList; const pd: tabstractprocdef; const llvmretdef, hlretdef: tdef; const resval: tregister; var retpara: tcgpara);
   procedure thlcgllvm.set_call_function_result(const list: TAsmList; const pd: tabstractprocdef; const llvmretdef, hlretdef: tdef; const resval: tregister; var retpara: tcgpara);
     var
     var
+      hreg: tregister;
       rettemp: treference;
       rettemp: treference;
     begin
     begin
       if not is_void(hlretdef) and
       if not is_void(hlretdef) and
@@ -1603,7 +1665,15 @@ implementation
                 everything to memory rather than potentially dealing with aggregates
                 everything to memory rather than potentially dealing with aggregates
                 in "registers" }
                 in "registers" }
               tg.gethltemp(list, hlretdef, hlretdef.size, tt_normal, rettemp);
               tg.gethltemp(list, hlretdef, hlretdef.size, tt_normal, rettemp);
-              a_load_reg_ref(list, llvmretdef, hlretdef, resval, rettemp);
+              case def2regtyp(llvmretdef) of
+                R_INTREGISTER,
+                R_ADDRESSREGISTER:
+                  a_load_reg_ref(list,llvmretdef,hlretdef,resval,rettemp);
+                R_FPUREGISTER:
+                  a_loadfpu_reg_ref(list,llvmretdef,hlretdef,resval,rettemp);
+                R_MMREGISTER:
+                  a_loadmm_reg_ref(list,llvmretdef,hlretdef,resval,rettemp,mms_movescalar);
+              end;
               { the return parameter now contains a value whose type matches the one
               { the return parameter now contains a value whose type matches the one
                 that the high level code generator expects instead of the llvm shim
                 that the high level code generator expects instead of the llvm shim
               }
               }
@@ -1620,8 +1690,23 @@ implementation
             end
             end
           else
           else
             begin
             begin
+              if llvmretdef<>hlretdef then
+                begin
+                  hreg:=getregisterfordef(list,hlretdef);
+                  case def2regtyp(llvmretdef) of
+                    R_INTREGISTER,
+                    R_ADDRESSREGISTER:
+                      a_load_reg_reg(list,llvmretdef,hlretdef,resval,hreg);
+                    R_FPUREGISTER:
+                      a_loadfpu_reg_reg(list,llvmretdef,hlretdef,resval,hreg);
+                    R_MMREGISTER:
+                      a_loadmm_reg_reg(list,llvmretdef,hlretdef,resval,hreg,mms_movescalar);
+                  end;
+                  retpara.location^.llvmloc.reg:=hreg
+                end
+              else
+                retpara.location^.llvmloc.reg:=resval;
               retpara.Location^.llvmloc.loc:=retpara.location^.loc;
               retpara.Location^.llvmloc.loc:=retpara.location^.loc;
-              retpara.location^.llvmloc.reg:=resval;
               retpara.Location^.llvmvalueloc:=true;
               retpara.Location^.llvmvalueloc:=true;
             end;
             end;
         end
         end
@@ -1719,8 +1804,19 @@ implementation
 
 
   procedure create_hlcodegen;
   procedure create_hlcodegen;
     begin
     begin
-      hlcg:=thlcgllvm.create;
-      cgllvm.create_codegen
+      if not assigned(current_procinfo) or
+         not(po_assembler in current_procinfo.procdef.procoptions) then
+        begin
+          tgobjclass:=ttgllvm;
+          hlcg:=thlcgllvm.create;
+          cgllvm.create_codegen
+        end
+      else
+        begin
+          tgobjclass:=orgtgclass;
+          hlcgcpu.create_hlcodegen;
+          { todo: handle/remove chlcgobj }
+        end;
     end;
     end;
 
 
 begin
 begin

+ 1 - 0
compiler/llvm/itllvm.pas

@@ -57,6 +57,7 @@ interface
         'icmp', 'fcmp',
         'icmp', 'fcmp',
         'phi', 'select', 'call',
         'phi', 'select', 'call',
         'va_arg', 'landingpad',
         'va_arg', 'landingpad',
+        'blockaddress',
         { fpc pseudo opcodes }
         { fpc pseudo opcodes }
         'type', { type definition }
         'type', { type definition }
         'invalid1', { la_x_to_inttoptr }
         'invalid1', { la_x_to_inttoptr }

+ 1 - 0
compiler/llvm/llvmbase.pas

@@ -65,6 +65,7 @@ interface
       la_icmp, la_fcmp,
       la_icmp, la_fcmp,
       la_phi, la_select, la_call,
       la_phi, la_select, la_call,
       la_va_arg, la_landingpad,
       la_va_arg, la_landingpad,
+      la_blockaddress,
       { fpc pseudo opcodes }
       { fpc pseudo opcodes }
       la_type, { type definition }
       la_type, { type definition }
       la_x_to_inttoptr, { have to convert something first to int before it can be converted to a pointer }
       la_x_to_inttoptr, { have to convert something first to int before it can be converted to a pointer }

+ 25 - 3
compiler/llvm/llvmdef.pas

@@ -478,10 +478,16 @@ implementation
                     encodedstr:=encodedstr+'*'
                     encodedstr:=encodedstr+'*'
                 end;
                 end;
               odt_interfacecom,
               odt_interfacecom,
+              odt_interfacecorba,
+              odt_dispinterface:
+                begin
+                  { type is a pointer to the vmt }
+                  llvmaddencodedtype_intern(tobjectdef(def).vmt_def,flags,encodedstr);
+                  if ([lef_typedecl,lef_noimplicitderef]*flags=[]) then
+                    encodedstr:=encodedstr+'*';
+                end;
               odt_interfacecom_function,
               odt_interfacecom_function,
               odt_interfacecom_property,
               odt_interfacecom_property,
-              odt_interfacecorba,
-              odt_dispinterface,
               odt_objcprotocol:
               odt_objcprotocol:
                 begin
                 begin
                   { opaque for now }
                   { opaque for now }
@@ -610,8 +616,22 @@ implementation
           { sret: hidden pointer for structured function result }
           { sret: hidden pointer for structured function result }
           if vo_is_funcret in hp.varoptions then
           if vo_is_funcret in hp.varoptions then
             begin
             begin
+              { "sret" is only valid for the firstparameter, while in FPC this
+                can sometimes be second one (self comes before). In general,
+                this is not a problem: we can just leave out sret, which means
+                the result will be a bit less well optimised), but it is for
+                AArch64: there, the sret parameter must be passed in a different
+                register (-> paranr_result is smaller than paranr_self for that
+                platform in symconst) }
+{$ifdef aarch64}
+              if not first then
+                internalerror(2015101404);
+{$endif aarch64}
               if withattributes then
               if withattributes then
-                encodedstr:=encodedstr+' sret'
+                 if first then
+                   encodedstr:=encodedstr+' sret'
+                 else { we can add some other attributes to optimise things,}
+                   encodedstr:=encodedstr+' noalias nocapture';
             end
             end
           else if not paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) and
           else if not paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) and
              llvmbyvalparaloc(paraloc) then
              llvmbyvalparaloc(paraloc) then
@@ -736,6 +756,8 @@ implementation
                     { other types should not appear currently, add as needed }
                     { other types should not appear currently, add as needed }
                     internalerror(2014012008);
                     internalerror(2014012008);
                   end;
                   end;
+              pointerdef:
+                typename:='p'+tostr(hdef.deflist_index);
               else
               else
                 { other types should not appear currently, add as needed }
                 { other types should not appear currently, add as needed }
                 internalerror(2014012009);
                 internalerror(2014012009);

+ 1 - 1
compiler/llvm/llvmpara.pas

@@ -140,7 +140,7 @@ unit llvmpara;
                 a pointer to the value that it should place on the stack (or
                 a pointer to the value that it should place on the stack (or
                 passed in registers, in some cases) }
                 passed in registers, in some cases) }
               paraloc^.llvmvalueloc:=false;
               paraloc^.llvmvalueloc:=false;
-              paraloc^.def:=cpointerdef.getreusable(paraloc^.def);
+              paraloc^.def:=cpointerdef.getreusable_no_free(paraloc^.def);
               paraloc^.size:=def_cgsize(paraloc^.def);
               paraloc^.size:=def_cgsize(paraloc^.def);
               paraloc^.loc:=LOC_REGISTER;
               paraloc^.loc:=LOC_REGISTER;
               paraloc^.register:=hlcg.getaddressregister(list,paraloc^.def);
               paraloc^.register:=hlcg.getaddressregister(list,paraloc^.def);

+ 24 - 12
compiler/llvm/llvmtype.pas

@@ -66,6 +66,7 @@ interface
         procedure appenddef_procvar(list:TAsmList;def:tprocvardef);override;
         procedure appenddef_procvar(list:TAsmList;def:tprocvardef);override;
         procedure appendprocdef(list:TAsmList;def:tprocdef);override;
         procedure appendprocdef(list:TAsmList;def:tprocdef);override;
         procedure appenddef_object(list:TAsmList;def: tobjectdef);override;
         procedure appenddef_object(list:TAsmList;def: tobjectdef);override;
+        procedure appenddef_classref(list: TAsmList; def: tclassrefdef);override;
         procedure appenddef_variant(list:TAsmList;def: tvariantdef);override;
         procedure appenddef_variant(list:TAsmList;def: tvariantdef);override;
         procedure appenddef_file(list:TasmList;def:tfiledef);override;
         procedure appenddef_file(list:TasmList;def:tfiledef);override;
 
 
@@ -180,7 +181,7 @@ implementation
         for opidx:=0 to p.ops-1 do
         for opidx:=0 to p.ops-1 do
           case p.oper[opidx]^.typ of
           case p.oper[opidx]^.typ of
             top_def:
             top_def:
-              appenddef(deftypelist,p.oper[opidx]^.def);
+              record_def(p.oper[opidx]^.def);
             top_tai:
             top_tai:
               collect_tai_info(deftypelist,p.oper[opidx]^.ai);
               collect_tai_info(deftypelist,p.oper[opidx]^.ai);
             top_ref:
             top_ref:
@@ -191,7 +192,7 @@ implementation
                   begin
                   begin
                     if (opidx=3) and
                     if (opidx=3) and
                        (p.llvmopcode=la_call) then
                        (p.llvmopcode=la_call) then
-                      record_asmsym_def(p.oper[opidx]^.ref^.symbol,tpointerdef(p.oper[0]^.def).pointeddef,false)
+                      record_asmsym_def(p.oper[opidx]^.ref^.symbol,tpointerdef(p.oper[2]^.def).pointeddef,false)
                     { not a named register }
                     { not a named register }
                     else if (p.oper[opidx]^.ref^.refaddr<>addr_full) then
                     else if (p.oper[opidx]^.ref^.refaddr<>addr_full) then
                       record_asmsym_def(p.oper[opidx]^.ref^.symbol,p.spilling_get_reg_type(opidx),false);
                       record_asmsym_def(p.oper[opidx]^.ref^.symbol,p.spilling_get_reg_type(opidx),false);
@@ -201,7 +202,7 @@ implementation
               for paraidx:=0 to p.oper[opidx]^.paras.count-1 do
               for paraidx:=0 to p.oper[opidx]^.paras.count-1 do
                 begin
                 begin
                   callpara:=pllvmcallpara(p.oper[opidx]^.paras[paraidx]);
                   callpara:=pllvmcallpara(p.oper[opidx]^.paras[paraidx]);
-                  appenddef(deftypelist,callpara^.def);
+                  record_def(callpara^.def);
                 end;
                 end;
           end;
           end;
       end;
       end;
@@ -212,19 +213,21 @@ implementation
         case p.typ of
         case p.typ of
           ait_llvmalias:
           ait_llvmalias:
             begin
             begin
-              appenddef(deftypelist,taillvmalias(p).def);
+              record_def(taillvmalias(p).def);
               record_asmsym_def(taillvmalias(p).newsym,taillvmalias(p).def,true);
               record_asmsym_def(taillvmalias(p).newsym,taillvmalias(p).def,true);
             end;
             end;
           ait_llvmdecl:
           ait_llvmdecl:
             begin
             begin
-              appenddef(deftypelist,taillvmdecl(p).def);
+              if taillvmdecl(p).namesym.Name='\01_U_$OBJPAS_$$_EXCEPTIONCLASS' then
+                writeln('here');
+              record_def(taillvmdecl(p).def);
               record_asmsym_def(taillvmdecl(p).namesym,taillvmdecl(p).def,true);
               record_asmsym_def(taillvmdecl(p).namesym,taillvmdecl(p).def,true);
               collect_asmlist_info(deftypelist,taillvmdecl(p).initdata);
               collect_asmlist_info(deftypelist,taillvmdecl(p).initdata);
             end;
             end;
           ait_llvmins:
           ait_llvmins:
             collect_llvmins_info(deftypelist,taillvm(p));
             collect_llvmins_info(deftypelist,taillvm(p));
           ait_typedconst:
           ait_typedconst:
-            appenddef(deftypelist,tai_abstracttypedconst(p).def);
+            record_def(tai_abstracttypedconst(p).def);
         end;
         end;
       end;
       end;
 
 
@@ -274,11 +277,11 @@ implementation
           la_call:
           la_call:
             if p.oper[3]^.typ=top_ref then
             if p.oper[3]^.typ=top_ref then
               begin
               begin
-                maybe_insert_extern_sym_decl(toplevellist,p.oper[3]^.ref^.symbol,tpointerdef(p.oper[0]^.def).pointeddef);
+                maybe_insert_extern_sym_decl(toplevellist,p.oper[3]^.ref^.symbol,tpointerdef(p.oper[2]^.def).pointeddef);
                 symdef:=get_asmsym_def(p.oper[3]^.ref^.symbol);
                 symdef:=get_asmsym_def(p.oper[3]^.ref^.symbol);
                 { the type used in the call is different from the type used to
                 { the type used in the call is different from the type used to
                   declare the symbol -> insert a typecast }
                   declare the symbol -> insert a typecast }
-                if not equal_llvm_defs(symdef,p.oper[0]^.def) then
+                if not equal_llvm_defs(symdef,p.oper[2]^.def) then
                   begin
                   begin
                     if symdef.typ=procdef then
                     if symdef.typ=procdef then
                       { ugly, but can't use getcopyas(procvardef) due to the
                       { ugly, but can't use getcopyas(procvardef) due to the
@@ -287,7 +290,7 @@ implementation
                         symtable) and "pointer to procedure" results in the
                         symtable) and "pointer to procedure" results in the
                         correct llvm type }
                         correct llvm type }
                       symdef:=cpointerdef.getreusable(tprocdef(symdef));
                       symdef:=cpointerdef.getreusable(tprocdef(symdef));
-                    cnv:=taillvm.op_reg_size_sym_size(la_bitcast,NR_NO,symdef,p.oper[3]^.ref^.symbol,p.oper[0]^.def);
+                    cnv:=taillvm.op_reg_size_sym_size(la_bitcast,NR_NO,symdef,p.oper[3]^.ref^.symbol,p.oper[2]^.def);
                     p.loadtai(3,cnv);
                     p.loadtai(3,cnv);
                   end;
                   end;
               end;
               end;
@@ -420,7 +423,7 @@ implementation
               sec:=sec_code
               sec:=sec_code
             else
             else
               sec:=sec_data;
               sec:=sec_data;
-            toplevellist.Concat(taillvmdecl.create(sym,def,nil,sec,def.alignment));
+            toplevellist.Concat(taillvmdecl.createdecl(sym,def,nil,sec,def.alignment));
             record_asmsym_def(sym,def,true);
             record_asmsym_def(sym,def,true);
           end;
           end;
       end;
       end;
@@ -472,7 +475,7 @@ implementation
       begin
       begin
         symdeflist:=tabstractrecordsymtable(def.symtable).llvmst.symdeflist;
         symdeflist:=tabstractrecordsymtable(def.symtable).llvmst.symdeflist;
         for i:=0 to symdeflist.Count-1 do
         for i:=0 to symdeflist.Count-1 do
-          appenddef(list,tllvmshadowsymtableentry(symdeflist[i]).def);
+          record_def(tllvmshadowsymtableentry(symdeflist[i]).def);
         if assigned(def.typesym) then
         if assigned(def.typesym) then
           list.concat(taillvm.op_size(LA_TYPE,record_def(def)));
           list.concat(taillvm.op_size(LA_TYPE,record_def(def)));
       end;
       end;
@@ -666,7 +669,16 @@ implementation
 
 
     procedure TLLVMTypeInfo.appenddef_object(list:TAsmList;def: tobjectdef);
     procedure TLLVMTypeInfo.appenddef_object(list:TAsmList;def: tobjectdef);
       begin
       begin
-        appenddef_abstractrecord(list,def);
+        if is_any_interface_kind(def) then
+          record_def(def.vmt_def)
+        else
+          appenddef_abstractrecord(list,def);
+      end;
+
+
+    procedure TLLVMTypeInfo.appenddef_classref(list: TAsmList; def: tclassrefdef);
+      begin
+        record_def(tobjectdef(tclassrefdef(def).pointeddef).vmt_def);
       end;
       end;
 
 
 
 

+ 56 - 6
compiler/llvm/nllvmcnv.pas

@@ -33,6 +33,7 @@ interface
          protected
          protected
           function first_int_to_real: tnode; override;
           function first_int_to_real: tnode; override;
           function first_int_to_bool: tnode; override;
           function first_int_to_bool: tnode; override;
+          function first_nil_to_methodprocvar: tnode; override;
           procedure second_int_to_int;override;
           procedure second_int_to_int;override;
          { procedure second_string_to_string;override; }
          { procedure second_string_to_string;override; }
          { procedure second_cstring_to_pchar;override; }
          { procedure second_cstring_to_pchar;override; }
@@ -44,7 +45,8 @@ interface
          procedure second_int_to_real;override;
          procedure second_int_to_real;override;
          { procedure second_real_to_real;override; }
          { procedure second_real_to_real;override; }
          { procedure second_cord_to_pointer;override; }
          { procedure second_cord_to_pointer;override; }
-         { procedure second_proc_to_procvar;override; }
+         procedure second_proc_to_procvar;override;
+         procedure second_nil_to_methodprocvar; override;
          procedure second_bool_to_int;override;
          procedure second_bool_to_int;override;
          procedure second_int_to_bool;override;
          procedure second_int_to_bool;override;
          { procedure second_load_smallset;override;  }
          { procedure second_load_smallset;override;  }
@@ -63,7 +65,7 @@ uses
   llvmbase,aasmllvm,
   llvmbase,aasmllvm,
   procinfo,
   procinfo,
   symconst,symtype,symdef,defutil,
   symconst,symtype,symdef,defutil,
-  cgbase,cgutils,hlcgobj,pass_2;
+  cgbase,cgutils,tgobj,hlcgobj,pass_2;
 
 
 { tllvmtypeconvnode }
 { tllvmtypeconvnode }
 
 
@@ -78,7 +80,20 @@ function tllvmtypeconvnode.first_int_to_bool: tnode;
   begin
   begin
     result:=inherited;
     result:=inherited;
     if not assigned(result) then
     if not assigned(result) then
-      expectloc:=LOC_JUMP;
+      begin
+        if not((nf_explicit in flags) and
+               not(left.location.loc in [LOC_FLAGS,LOC_JUMP])) then
+          expectloc:=LOC_JUMP;
+      end;
+  end;
+
+
+function tllvmtypeconvnode.first_nil_to_methodprocvar: tnode;
+  begin
+    result:=inherited;
+    if assigned(result) then
+      exit;
+    expectloc:=LOC_REFERENCE;
   end;
   end;
 
 
 
 
@@ -122,15 +137,50 @@ procedure tllvmtypeconvnode.second_pointer_to_array;
 procedure tllvmtypeconvnode.second_int_to_real;
 procedure tllvmtypeconvnode.second_int_to_real;
   var
   var
     op: tllvmop;
     op: tllvmop;
+    llvmtodef: tdef;
   begin
   begin
     if is_signed(left.resultdef) then
     if is_signed(left.resultdef) then
       op:=la_sitofp
       op:=la_sitofp
     else
     else
       op:=la_uitofp;
       op:=la_uitofp;
-    location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
-    location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
+    { see comment about currency in thlcgllvm.a_loadfpu_ref_reg }
+    if not is_currency(resultdef) then
+      llvmtodef:=resultdef
+    else
+      llvmtodef:=s80floattype;
+    location_reset(location,LOC_FPUREGISTER,def_cgsize(llvmtodef));
+    location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,llvmtodef);
     hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
     hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
-    current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_reg_size(op,location.register,left.resultdef,left.location.register,resultdef));
+    current_asmdata.CurrAsmList.concat(taillvm.op_reg_size_reg_size(op,location.register,left.resultdef,left.location.register,llvmtodef));
+  end;
+
+
+procedure tllvmtypeconvnode.second_proc_to_procvar;
+  begin
+    inherited;
+    if not tabstractprocdef(resultdef).is_addressonly and
+       not tabstractprocdef(left.resultdef).is_addressonly then
+      begin
+        if location.loc<>LOC_REFERENCE then
+          internalerror(2015111902);
+        hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,
+          cpointerdef.getreusable(left.resultdef),
+          cpointerdef.getreusable(resultdef),
+          location.reference);
+      end;
+  end;
+
+
+procedure tllvmtypeconvnode.second_nil_to_methodprocvar;
+  var
+    href: treference;
+  begin
+    tg.gethltemp(current_asmdata.CurrAsmList,resultdef,resultdef.size,tt_normal,href);
+    location_reset_ref(location,LOC_REFERENCE,def_cgsize(resultdef),href.alignment);
+    location.reference:=href;
+    hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(resultdef),cpointerdef.getreusable(methodpointertype),href);
+    hlcg.g_load_const_field_by_name(current_asmdata.CurrAsmList,trecorddef(methodpointertype),'proc',0,href);
+    hlcg.g_load_const_field_by_name(current_asmdata.CurrAsmList,trecorddef(methodpointertype),'self',0,href);
   end;
   end;
 
 
 
 

+ 95 - 2
compiler/llvm/nllvminl.pas

@@ -33,8 +33,11 @@ interface
       tllvminlinenode = class(tcginlinenode)
       tllvminlinenode = class(tcginlinenode)
        protected
        protected
         function first_get_frame: tnode; override;
         function first_get_frame: tnode; override;
+        function first_abs_real: tnode; override;
+        function first_sqr_real: tnode; override;
        public
        public
         procedure second_length; override;
         procedure second_length; override;
+        procedure second_sqr_real; override;
       end;
       end;
 
 
 
 
@@ -44,10 +47,11 @@ implementation
        verbose,globtype,constexp,
        verbose,globtype,constexp,
        aasmbase, aasmdata,
        aasmbase, aasmdata,
        symtype,symdef,defutil,
        symtype,symdef,defutil,
-       ncal,ncon,ninl,
+       nutils,nadd,nbas,ncal,ncon,nflw,ninl,nld,nmat,
        pass_2,
        pass_2,
        cgbase,cgutils,tgobj,hlcgobj,
        cgbase,cgutils,tgobj,hlcgobj,
-       cpubase;
+       cpubase,
+       llvmbase,aasmllvm;
 
 
 
 
      function tllvminlinenode.first_get_frame: tnode;
      function tllvminlinenode.first_get_frame: tnode;
@@ -56,6 +60,72 @@ implementation
            ccallparanode.create(genintconstnode(0),nil));
            ccallparanode.create(genintconstnode(0),nil));
        end;
        end;
 
 
+    { in general, generate regular expression rather than intrinsics: according
+      to the "Performance Tips for Frontend Authors", "The optimizer is quite
+      good at reasoning about general control flow and arithmetic, it is not
+      anywhere near as strong at reasoning about the various intrinsics. If
+      profitable for code generation purposes, the optimizer will likely form
+      the intrinsics itself late in the optimization pipeline." }
+
+    function tllvminlinenode.first_abs_real: tnode;
+      var
+        lefttemp,
+        resulttemp: ttempcreatenode;
+        stat: tstatementnode;
+      begin
+        result:=internalstatements(stat);
+        lefttemp:=ctempcreatenode.create(left.resultdef,left.resultdef.size,tt_persistent,true);
+        { assigned twice -> will be spilled if put in register }
+        resulttemp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,false);
+
+        addstatement(stat,lefttemp);
+        addstatement(stat,resulttemp);
+
+        { lefttemp:=left }
+        addstatement(stat,
+          cassignmentnode.create(ctemprefnode.create(lefttemp),left)
+        );
+
+        { if lefttemp>=0 then
+            resulttemp:=lefttemp
+          else
+            resulttemp:=-lefttemp
+        }
+        addstatement(stat,
+          cifnode.create(
+            caddnode.create(
+              gten,
+              ctemprefnode.create(lefttemp),
+              crealconstnode.create(0.0,left.resultdef)
+            ),
+            cassignmentnode.create(
+              ctemprefnode.create(resulttemp),
+              ctemprefnode.create(lefttemp)
+            ),
+            cassignmentnode.create(
+              ctemprefnode.create(resulttemp),
+              cunaryminusnode.create(ctemprefnode.create(lefttemp))
+            )
+          )
+        );
+        addstatement(stat,ctempdeletenode.create(lefttemp));
+        addstatement(stat,ctempdeletenode.create_normal_temp(resulttemp));
+        { return resulttemp }
+        addstatement(stat,ctemprefnode.create(resulttemp));
+        { reused }
+        left:=nil;
+      end;
+
+
+    function tllvminlinenode.first_sqr_real: tnode;
+      begin
+        result:=nil;
+        if use_vectorfpu(left.resultdef) then
+          expectloc:=LOC_MMREGISTER
+        else
+          expectloc:=LOC_FPUREGISTER;
+      end;
+
 
 
     procedure tllvminlinenode.second_length;
     procedure tllvminlinenode.second_length;
       var
       var
@@ -113,6 +183,29 @@ implementation
          end;
          end;
       end;
       end;
 
 
+
+    procedure tllvminlinenode.second_sqr_real;
+      begin
+        secondpass(left);
+        location.loc:=expectloc;
+        if expectloc=LOC_MMREGISTER then
+          begin
+            hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+            location.register:=hlcg.getmmregister(current_asmdata.CurrAsmList,resultdef);
+          end
+        else
+          begin
+            hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+            location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
+          end;
+        current_asmdata.CurrAsmList.concat(
+          taillvm.op_reg_size_reg_reg(la_fmul,
+            location.register,resultdef,
+            left.location.register,left.location.register
+          )
+        );
+      end;
+
 begin
 begin
   cinlinenode:=tllvminlinenode;
   cinlinenode:=tllvminlinenode;
 end.
 end.

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