Explorar el Código

merge of r31476 through r32427

git-svn-id: branches/interfacertti@32429 -
steve hace 10 años
padre
commit
d356e65415
Se han modificado 100 ficheros con 4507 adiciones y 2052 borrados
  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/pexports.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/pinline.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/symcreat.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/symtable.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_wii.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/t_aix.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_wii.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/tokens.pas 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/agx86int.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/cgx86.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/nx86con.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/nx86mem.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.res -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/socksvr.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/testez.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/testnres.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/xmldump.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/avl_tree.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/rtfpars.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/streamex.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/mysql55conn.pas svneol=native#text/plain
 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/odbc/Makefile 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/fpmake.pp 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.fpc 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/amigalib.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/cybergraphics.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/get9.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/video.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.fpc 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/mipsel/dllprt0.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/armdefines.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/lpc21x4.pp svneol=native#text/plain
 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/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/stm32f0xx.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_md.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/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/stm32f746.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/excepth.inc 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/fexpand.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/tnyheaph.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/ustringh.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/sysencodingh.inc svneol=native#text/pascal
 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/sysinth.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/unifun.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.fpc 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/tb0611.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/tb610.pp svneol=native#text/pascal
+tests/tbs/tb613.pp svneol=native#text/plain
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/ub0060.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/tcext5.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/cpptcl2.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/tcext6.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/cpptcl2.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/tcext5.c -text
 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/cpptcl2.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/taddr1.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/taddreal2.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/tvarol94.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/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/tfarptr2.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/tintr1.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/tmml.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/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/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/taddint1.pp svneol=native#text/pascal
 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/tenum2.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/testintf.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/texception8.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/tfillchr.pp svneol=native#text/plain
 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/tinterface5.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/tintfcdecl1.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/crt/tcrt.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/tbreak.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/tw2738.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/tw27515.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/tw2853e.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/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/tw28766.pp svneol=native#text/pascal
+tests/webtbs/tw28801.pp svneol=native#text/plain
 tests/webtbs/tw2883.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/tw2891.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/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/tw29040.pp svneol=native#text/plain
 tests/webtbs/tw2908.pp svneol=native#text/plain
 tests/webtbs/tw2911.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/uw2834.pp svneol=native#text/plain
 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/uw2956.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/dwlinear.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.pp 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/fpdocxmlopts.pas 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/plus.png -text svneol=unset#image/png
 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/sample-project.xml 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/fpgmake/fpgmake.pp 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
-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
 UNIXs = linux $(BSDs) solaris qnx haiku aix
-LIMIT83fs = go32v2 os2 emx watcom msdos
+LIMIT83fs = go32v2 os2 emx watcom msdos win16
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 .PHONY: FORCE
@@ -476,7 +476,7 @@ endif
 endif
 BuildOnlyBaseCPUs=jvm
 ifneq ($(wildcard utils),)
-NOUTILSTARGETS=embedded gba nds msdos $(BuildOnlyBaseCPUs)
+NOUTILSTARGETS=embedded gba nds msdos win16 $(BuildOnlyBaseCPUs)
 ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
 ifdef BUILDFULLNATIVE
 UTILS=1
@@ -720,6 +720,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override TARGET_DIRS+=compiler rtl utils packages ide installer
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 override TARGET_DIRS+=compiler rtl utils packages ide installer
 endif
@@ -1126,6 +1129,12 @@ ifeq ($(OS_TARGET),embedded)
 EXEEXT=.bin
 SHORTSUFFIX=emb
 endif
+ifeq ($(OS_TARGET),win16)
+STATICLIBPREFIX=
+STATICLIBEXT=.a
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w16
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -2522,6 +2531,14 @@ TARGET_DIRS_PACKAGES=1
 TARGET_DIRS_IDE=1
 TARGET_DIRS_INSTALLER=1
 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)
 TARGET_DIRS_COMPILER=1
 TARGET_DIRS_RTL=1

+ 1 - 1
Makefile.fpc

@@ -210,7 +210,7 @@ endif
 BuildOnlyBaseCPUs=jvm
 
 ifneq ($(wildcard utils),)
-NOUTILSTARGETS=embedded gba nds msdos $(BuildOnlyBaseCPUs)
+NOUTILSTARGETS=embedded gba nds msdos win16 $(BuildOnlyBaseCPUs)
 ifeq ($(findstring $(OS_TARGET),$(NOUTILSTARGETS)),)
 ifdef BUILDFULLNATIVE
 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
-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
 UNIXs = linux $(BSDs) solaris qnx haiku aix
-LIMIT83fs = go32v2 os2 emx watcom msdos
+LIMIT83fs = go32v2 os2 emx watcom msdos win16
 OSNeedsComspecToRunBatch = go32v2 watcom
 FORCE:
 .PHONY: FORCE
@@ -556,6 +556,9 @@ endif
 ifeq ($(OS_TARGET),nds)
 NoNativeBinaries=1
 endif
+ifeq ($(OS_TARGET),win16)
+NoNativeBinaries=1
+endif
 ifeq ($(FULL_TARGET),i386-linux)
 override TARGET_DIRS+=utils
 endif
@@ -793,6 +796,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 override TARGET_DIRS+=utils
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override TARGET_DIRS+=utils
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 override TARGET_DIRS+=utils
 endif
@@ -1036,6 +1042,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 override TARGET_PROGRAMS+=pp
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override TARGET_PROGRAMS+=pp
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 override TARGET_PROGRAMS+=pp
 endif
@@ -1280,6 +1289,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 override COMPILER_INCLUDEDIR+=$(CPC_TARGET)
 endif
@@ -1523,6 +1535,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 override COMPILER_UNITDIR+=$(COMPILERSOURCEDIR)
 endif
@@ -1766,6 +1781,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_TARGETDIR+=.
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override COMPILER_TARGETDIR+=.
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 override COMPILER_TARGETDIR+=.
 endif
@@ -2009,6 +2027,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 override COMPILER_UNITTARGETDIR+=$(CPU_UNITDIR)/units/$(FULL_TARGET)
 endif
@@ -2414,6 +2435,12 @@ ifeq ($(OS_TARGET),embedded)
 EXEEXT=.bin
 SHORTSUFFIX=emb
 endif
+ifeq ($(OS_TARGET),win16)
+STATICLIBPREFIX=
+STATICLIBEXT=.a
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w16
+endif
 ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
 FPCMADE=fpcmade.$(SHORTSUFFIX)
 ZIPSUFFIX=$(SHORTSUFFIX)
@@ -2906,6 +2933,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 REQUIRE_PACKAGES_RTL=1
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+REQUIRE_PACKAGES_RTL=1
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 REQUIRE_PACKAGES_RTL=1
 endif
@@ -3790,6 +3820,9 @@ endif
 ifeq ($(FULL_TARGET),i8086-msdos)
 TARGET_DIRS_UTILS=1
 endif
+ifeq ($(FULL_TARGET),i8086-win16)
+TARGET_DIRS_UTILS=1
+endif
 ifeq ($(FULL_TARGET),aarch64-linux)
 TARGET_DIRS_UTILS=1
 endif

+ 3 - 0
compiler/Makefile.fpc

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

+ 21 - 35
compiler/aarch64/agcpugas.pas

@@ -29,7 +29,7 @@ unit agcpugas;
   interface
 
     uses
-       globtype,
+       globtype,systems,
        aasmtai,
        aggas,
        cpubase,cpuinfo;
@@ -40,12 +40,11 @@ unit agcpugas;
       end;
 
       TAArch64Assembler=class(TGNUassembler)
-        constructor create(smart: boolean); override;
+        constructor create(info: pasminfo; smart: boolean); override;
       end;
 
       TAArch64AppleAssembler=class(TAppleGNUassembler)
-        constructor create(smart: boolean); override;
-        function MakeCmdLine: TCmdStr; override;
+        constructor create(info: pasminfo; smart: boolean); override;
       end;
 
 
@@ -65,7 +64,6 @@ unit agcpugas;
 
     uses
        cutils,globals,verbose,
-       systems,
        assemble,
        aasmcpu,
        itcpugas,
@@ -76,9 +74,9 @@ unit agcpugas;
 {                      AArch64 Assembler writer                              }
 {****************************************************************************}
 
-    constructor TAArch64Assembler.create(smart: boolean);
+    constructor TAArch64Assembler.create(info: pasminfo; smart: boolean);
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter := TAArch64InstrWriter.create(self);
       end;
 
@@ -86,30 +84,18 @@ unit agcpugas;
 {                      Apple AArch64 Assembler writer                        }
 {****************************************************************************}
 
-    constructor TAArch64AppleAssembler.create(smart: boolean);
+    constructor TAArch64AppleAssembler.create(info: pasminfo; smart: boolean);
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter := TAArch64InstrWriter.create(self);
       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                    }
 {****************************************************************************}
 
-    function getreferencestring(var ref : treference) : string;
+    function getreferencestring(asminfo: pasminfo; var ref : treference) : string;
       const
         darwin_addrpage2str: array[addr_page..addr_gotpageoffset] of string[11] =
            ('@PAGE','@PAGEOFF','@GOTPAGE','@GOTPAGEOFF');
@@ -130,7 +116,7 @@ unit agcpugas;
                      (ref.shiftmode<>SM_None) or
                      (ref.offset<>0) then
                     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]
                   else
                     result:=linux_addrpage2str[ref.refaddr]+ref.symbol.name
@@ -172,7 +158,7 @@ unit agcpugas;
                       addr_gotpageoffset,
                       addr_pageoffset:
                         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]
                           else
                             result:=result+', '+linux_addrpage2str[ref.refaddr]+ref.symbol.name
@@ -200,7 +186,7 @@ unit agcpugas;
       end;
 
 
-    function getopstr(hp: taicpu; opnr: longint; const o: toper): string;
+    function getopstr(asminfo: pasminfo; hp: taicpu; opnr: longint; const o: toper): string;
       begin
         case o.typ of
           top_reg:
@@ -248,7 +234,7 @@ unit agcpugas;
                 getopstr:=o.ref^.symbol.name;
               end
             else
-              getopstr:=getreferencestring(o.ref^);
+              getopstr:=getreferencestring(asminfo,o.ref^);
           else
             internalerror(2014121507);
         end;
@@ -274,11 +260,11 @@ unit agcpugas;
                  // debug code
                  // writeln(s);
                  // 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:=',';
               end;
           end;
-        owner.AsmWriteLn(s);
+        owner.writer.AsmWriteLn(s);
       end;
 
 
@@ -296,14 +282,14 @@ unit agcpugas;
             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];
-            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';
             comment : '# ';
             dollarsign: '$';
@@ -312,5 +298,5 @@ unit agcpugas;
 
 begin
   RegisterAssembler(as_aarch64_gas_info,TAArch64Assembler);
-  RegisterAssembler(as_aarch64_gas_darwin_info,TAArch64AppleAssembler);
+  RegisterAssembler(as_aarch64_clang_darwin_info,TAArch64AppleAssembler);
 end.

+ 7 - 1
compiler/aarch64/cpuinfo.pas

@@ -48,6 +48,12 @@ Type
      (ct_none
      );
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 
 Const
    { Is there support for dealing with multiple microcontrollers available }
@@ -66,7 +72,7 @@ Const
     {$WARN 3177 OFF}
    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}
 
    { 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].alignment:=voidpointertype.alignment;
                 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
                   begin
                     size:=OS_ADDR;
@@ -397,7 +397,7 @@ unit cpupara;
 
         if push_addr_param(varspez,paradef,p.proccalloption) then
           begin
-            paradef:=cpointerdef.getreusable(paradef);
+            paradef:=cpointerdef.getreusable_no_free(paradef);
             loc:=LOC_REGISTER;
             paracgsize:=OS_ADDR;
             paralen:=tcgsize2size[OS_ADDR];

+ 263 - 9
compiler/aasmcnst.pas

@@ -29,7 +29,7 @@ interface
 uses
   cclasses,globtype,constexp,
   aasmbase,aasmdata,aasmtai,
-  symconst,symtype,symdef,symsym;
+  symconst,symbase,symtype,symdef,symsym;
 
 type
    { typed const: integer/floating point/string/pointer/... const along with
@@ -92,6 +92,7 @@ type
      procedure addvalue(val: tai_abstracttypedconst);
      function valuecount: longint;
      procedure insertvaluebeforepos(val: tai_abstracttypedconst; pos: longint);
+     function replacevalueatpos(val: tai_abstracttypedconst; pos: longint): tai_abstracttypedconst;
      procedure finish;
      destructor destroy; override;
    end;
@@ -112,7 +113,17 @@ type
      { this symbol is the start of a block of data that should be
        dead-stripable/smartlinkable; may imply starting a new section, but
        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;
 
@@ -168,6 +179,14 @@ type
    end;
    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,
      instead create a cai_typedconstbuilder (this class can be overridden) }
    ttai_typedconstbuilder = class abstract
@@ -220,12 +239,17 @@ type
 
      { ensure that finalize_asmlist is called only once }
      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
        platform }
      function aggregate_kind(def: tdef): ttypedconstkind; virtual;
      { 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;
+     { 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
        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 }
      procedure mark_anon_aggregate_alignment; 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
+     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;
      { the datalist parameter specifies where the data for the string constant
        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 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.
        While parsing a typed constant these operators are encountered from
        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
        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_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
        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;
    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)
     protected
      procedure mark_anon_aggregate_alignment; 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
      { set the default value for caggregateinformation (= tlowlevelaggregateinformation) }
      class constructor classcreate;
+     function emit_placeholder(def: tdef): ttypedconstplaceholder; override;
    end;
 
    var
@@ -414,7 +465,7 @@ implementation
    uses
      verbose,globals,systems,widestr,
      fmodule,
-     symbase,symtable,defutil;
+     symtable,defutil;
 
 {****************************************************************************
                        taggregateinformation
@@ -508,6 +559,15 @@ implementation
       end;
 
 
+{****************************************************************************
+                             ttypedconstplaceholder
+ ****************************************************************************}
+
+    constructor ttypedconstplaceholder.create(d: tdef);
+      begin
+        def:=d;
+      end;
+
 {****************************************************************************
                             tai_abstracttypedconst
  ****************************************************************************}
@@ -685,6 +745,13 @@ implementation
      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;
      begin
        if fisstring then
@@ -819,22 +886,45 @@ implementation
           { in case of syntax errors, the aggregate may not have been finished }
           (ErrorCount=0) then
          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;
        { only now add items based on the symbolname, because it may be
          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
            maybe_new_object_file(prelist);
            { 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
-             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));
          end
        else if tcalo_new_section in options then
          new_section(prelist,section,secname,const_align(alignment))
        else
          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 sym.bind=AB_GLOBAL then
            prelist.concat(tai_symbol.Create_Global(sym,0))
@@ -851,6 +941,48 @@ implementation
      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);
      begin
        { by default we don't care about the type }
@@ -869,6 +1001,17 @@ implementation
      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;
      begin
        { darwin's linker does not support negative offsets }
@@ -1196,6 +1339,33 @@ implementation
      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;
      begin
        case typ of
@@ -1245,7 +1415,6 @@ implementation
        string_symofs: asizeint;
        startlab: tasmlabel;
        datadef: tdef;
-       uniwidestrrecdef: trecorddef;
        datatcb: ttai_typedconstbuilder;
      begin
        start_internal_data_builder(datalist,sec_rodata_norel,'',datatcb,startlab);
@@ -1286,7 +1455,7 @@ implementation
            { ending #0 }
            datatcb.emit_tai(Tai_const.Create_16bit(0),cwidechartype);
            datatcb.maybe_end_aggregate(datadef);
-           uniwidestrrecdef:=datatcb.end_anonymous_record;
+           datatcb.end_anonymous_record;
          end
        else
          { code generation for other sizes must be written }
@@ -1430,6 +1599,22 @@ implementation
      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);
      var
        info: taggregateinformation;
@@ -1564,13 +1749,32 @@ implementation
 
 
    procedure ttai_typedconstbuilder.queue_emit_const(cs: tconstsym);
+     var
+       resourcestrrec: trecorddef;
      begin
        if cs.consttyp<>constresourcestring then
          internalerror(2014062102);
        if fqueue_offset<>0 then
          internalerror(2014062103);
        { 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);
      end;
 
@@ -1598,6 +1802,28 @@ implementation
      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
  ****************************************************************************}
@@ -1608,6 +1834,17 @@ implementation
      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;
      var
        marker: tai_marker;
@@ -1637,6 +1874,23 @@ implementation
        info.anonrecmarker:=nil;
      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

+ 3 - 0
compiler/aasmdata.pas

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

+ 29 - 0
compiler/aasmtai.pas

@@ -135,6 +135,17 @@ interface
           aitconst_farptr,
           { i8086 segment of symbol; emits: 'DW SEG symbol' }
           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 }
           aitconst_got,
           { offset of symbol itself from GOT }
@@ -620,6 +631,8 @@ interface
           constructor Create_int_dataptr(_value: int64);
 {$ifdef i8086}
           constructor Create_seg_name(const name:string);
+          constructor Create_dgroup;
+          constructor Create_fardataseg;
 {$endif i8086}
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -1817,6 +1830,20 @@ implementation
         self.Createname(name,0);
         self.consttype:=aitconst_seg;
       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}
 
 
@@ -1884,6 +1911,8 @@ implementation
             result:=2;
           aitconst_farptr:
             result:=4;
+          aitconst_dgroup,
+          aitconst_fardataseg,
           aitconst_seg:
             result:=2;
           aitconst_got:

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 232 - 229
compiler/aggas.pas


+ 1 - 3
compiler/aopt.pas

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

+ 30 - 10
compiler/aoptobj.pas

@@ -859,8 +859,6 @@ Unit AoptObj;
 
 
       procedure TAOptObj.UpdateUsedRegs(p : Tai);
-        var
-          i : TRegisterType;
         begin
           { this code is based on TUsedRegs.Update to avoid multiple passes through the asmlist,
             the code is duplicated here }
@@ -1176,7 +1174,9 @@ Unit AoptObj;
       end;
 {$pop}
 
-    function IsJumpToLabel(hp: taicpu): boolean;
+
+    { Returns True if hp is an unconditional jump to a label }
+    function IsJumpToLabelUncond(hp: taicpu): boolean;
       begin
 {$if defined(avr)}
         result:=(hp.opcode in aopt_uncondjmp) and
@@ -1192,6 +1192,16 @@ Unit AoptObj;
       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);
       var
         hp2: tai;
@@ -1223,8 +1233,11 @@ Unit AoptObj;
        the level parameter denotes how deeep we have already followed the jump,
        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;
+          {$endif}
 
       begin
         GetfinalDestination := false;
@@ -1238,7 +1251,7 @@ Unit AoptObj;
                (taicpu(p1).is_jmp) then
               if { the next instruction after the label where the jump hp arrives}
                  { is unconditional or of the same type as hp, so continue       }
-                 IsJumpToLabel(taicpu(p1))
+                 IsJumpToLabelUncond(taicpu(p1))
 {$if not defined(MIPS) and not defined(JVM)}
 { for MIPS, it isn't enough to check the condition; first operands must be same, too. }
                  or
@@ -1253,7 +1266,7 @@ Unit AoptObj;
                   SkipLabels(p1,p2) and
                   (p2.typ = ait_instruction) and
                   (taicpu(p2).is_jmp) and
-                   (IsJumpToLabel(taicpu(p2)) or
+                   (IsJumpToLabelUncond(taicpu(p2)) or
                    (conditions_equal(taicpu(p2).condition,hp.condition))) and
                   SkipLabels(p1,p1))
 {$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,
                           because it can never be executed
                         }
-                        if IsJumpToLabel(taicpu(p)) then
+                        if IsJumpToLabelUncond(taicpu(p)) then
                           begin
                             hp2:=p;
                             while GetNextInstruction(hp2, hp1) and
@@ -1386,11 +1399,11 @@ Unit AoptObj;
                                 end
                               else break;
                             end;
-                        { remove jumps to a label coming right after them }
                         if GetNextInstruction(p, hp1) then
                           begin
                             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
           { TODO: FIXME removing the first instruction fails}
                                 (p<>blockstart) then
@@ -1408,10 +1421,17 @@ Unit AoptObj;
                               end
                             else if assigned(hp1) then
                               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
                                   SkipLabels(hp1,hp1);
                                 if (tai(hp1).typ=ait_instruction) and
-                                  IsJumpToLabel(taicpu(hp1)) and
+                                  IsJumpToLabelUncond(taicpu(hp1)) and
                                   GetNextInstruction(hp1, hp2) and
                                   IsJumpToLabel(taicpu(p)) and
                                   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;
       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;
-          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
+              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;
-          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
-              result:=operand_read;
-          A_STREX:
-            result:=operand_write;
-          else
-            internalerror(200403151);
-        end;
+              internalerror(200403151);
+          end;
       end;
 
 
@@ -920,7 +1007,9 @@ implementation
                (tai(hp).typ=ait_instruction) and
                ((taicpu(hp).opcode=A_FLDS) 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;
         end;
 
@@ -943,12 +1032,10 @@ implementation
         penalty,
         lastinspos,
         { increased for every data element > 4 bytes inserted }
-        currentsize,
         extradataoffset,
         curop : longint;
         curtai,
         inserttai : tai;
-        ai_label : tai_label;
         curdatatai,hp,hp2 : tai;
         curdata : TAsmList;
         l : tasmlabel;
@@ -1320,7 +1407,6 @@ implementation
     procedure ensurethumbencodings(list: TAsmList);
       var
         curtai: tai;
-        op2reg: TRegister;
       begin
         { Do Thumb 16bit transformations to form valid instruction forms }
         curtai:=tai(list.first);

+ 44 - 14
compiler/arm/agarmgas.pas

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

+ 9 - 9
compiler/arm/aoptcpu.pas

@@ -2500,13 +2500,16 @@ Implementation
               hp3:=tai(p.Previous);
               hp5:=tai(p.next);
               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? }
               while assigned(hp3) and (hp3.typ<>ait_instruction) do
                 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
                       hp4:=hp3;
                       hp3:=tai(hp3.Previous);
@@ -2552,7 +2555,7 @@ Implementation
 {$endif DEBUG_PREREGSCHEDULER}
               asml.InsertBefore(hp1,insertpos);
               asml.InsertListBefore(insertpos,list);
-              p:=tai(p.next)
+              p:=tai(p.next);
             end
           else if p.typ=ait_instruction then
             p:=hp1
@@ -2629,8 +2632,7 @@ Implementation
   function TCpuThumb2AsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
     var
       hp : taicpu;
-      hp1,hp2 : tai;
-      oldreg : TRegister;
+      //hp1,hp2 : tai;
     begin
       result:=false;
       if inherited PeepHoleOptPass1Cpu(p) then
@@ -2757,10 +2759,8 @@ Implementation
   procedure TCpuThumb2AsmOptimizer.PeepHoleOptPass2;
     var
       p,hp1,hp2: tai;
-      l,l2 : longint;
+      l : longint;
       condition : tasmcond;
-      hp3: tai;
-      WasLast: boolean;
       { UsedRegs, TmpUsedRegs: TRegSet; }
 
     begin

+ 128 - 51
compiler/arm/cgcpu.pas

@@ -378,7 +378,14 @@ unit cgcpu;
            else
              InternalError(200308297);
          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
              if target_info.endian=endian_big then
                dir:=-1
@@ -479,7 +486,10 @@ unit cgcpu;
          else
            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);
        end;
 
@@ -651,7 +661,6 @@ unit cgcpu;
         if (tf_pic_uses_got in target_info.flags) and
            (cs_create_pic in current_settings.moduleswitches) then
           begin
-            include(current_procinfo.flags,pi_needs_got);
             r.refaddr:=addr_pic
           end
         else
@@ -1116,7 +1125,8 @@ unit cgcpu;
           OP_IMUL,
           OP_MUL:
             begin
-              if cgsetflags or setflags then
+              if (cgsetflags or setflags) and
+                 (CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) then
                 begin
                   overflowreg:=getintregister(list,size);
                   if op=OP_IMUL then
@@ -1184,28 +1194,39 @@ unit cgcpu;
     var
       asmop: tasmop;
     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;
 
     function tbasecgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
       var
         tmpreg1,tmpreg2 : tregister;
-        tmpref : treference;
-        l : tasmlabel;
       begin
         tmpreg1:=NR_NO;
 
@@ -1373,7 +1394,10 @@ unit cgcpu;
            else
              InternalError(200308299);
          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
              if target_info.endian=endian_big then
                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;
        var
          oppostfix:toppostfix;
+         href: treference;
+         tmpreg: TRegister;
        begin
          case ToSize of
            { signed integer registers }
@@ -1447,13 +1473,31 @@ unit cgcpu;
            else
              InternalError(2003082910);
          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;
 
 
      function tbasecgarm.a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
        var
          oppostfix:toppostfix;
+         so: tshifterop;
+         tmpreg: TRegister;
+         href: treference;
        begin
          case FromSize of
            { signed integer registers }
@@ -1471,7 +1515,33 @@ unit cgcpu;
            else
              InternalError(200308291);
          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;
 
      procedure tbasecgarm.a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);
@@ -1818,7 +1888,6 @@ unit cgcpu;
          registerarea,
          r7offset,
          stackmisalignment : pint;
-         postfix: toppostfix;
          imm1, imm2: DWord;
          stack_parameters : Boolean;
       begin
@@ -2056,7 +2125,6 @@ unit cgcpu;
          registerarea,
          stackmisalignment: pint;
          paddingreg: TSuperRegister;
-         mmpostfix: toppostfix;
          imm1, imm2: DWord;
       begin
         if not(nostackframe) then
@@ -2261,22 +2329,43 @@ unit cgcpu;
       var
         ref : treference;
         l : TAsmLabel;
+        regs : tcpuregisterset;
+        r: byte;
       begin
         if (cs_create_pic in current_settings.moduleswitches) and
            (pi_needs_got in current_procinfo.flags) and
            (tf_pic_uses_got in target_info.flags) then
           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);
             current_asmdata.getglobaldatalabel(l);
             cg.a_label(current_procinfo.aktlocaldata,l);
             ref.symbol:=l;
             ref.base:=NR_PC;
             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_procinfo.aktlocaldata.concat(tai_const.Create_rel_sym_offset(aitconst_32bit,l,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),-8));
             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;
 
@@ -2372,12 +2461,12 @@ unit cgcpu;
               begin
                 tmpreg:=g_indirect_sym_load(list,ref.symbol.name,asmsym2indsymflags(ref.symbol));
                 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;
               end
             else if (cs_create_pic in current_settings.moduleswitches) 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
                 begin
                   { 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))
           end
         else
-          current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
+            current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
 
         { load consts entry }
         if not indirection_done then
@@ -2419,6 +2508,8 @@ unit cgcpu;
                 tmpref.base:=current_procinfo.got;
                 tmpref.index:=tmpreg;
                 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;
 
@@ -3462,14 +3553,10 @@ unit cgcpu;
     procedure tthumbcgarm.g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);
       var
          ref : treference;
-         shift : byte;
          r : byte;
-         regs, saveregs : tcpuregisterset;
-         r7offset,
+         regs : tcpuregisterset;
          stackmisalignment : pint;
-         postfix: toppostfix;
-         registerarea,
-         imm1, imm2: DWord;
+         registerarea: DWord;
          stack_parameters: Boolean;
       begin
         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);
       var
-         ref : treference;
          LocalSize : longint;
-         r,
-         shift : byte;
-         saveregs,
+         r: byte;
          regs : tcpuregisterset;
          registerarea : DWord;
          stackmisalignment: pint;
-         imm1, imm2: DWord;
          stack_parameters : Boolean;
       begin
         if not(nostackframe) then
@@ -3778,7 +3861,6 @@ unit cgcpu;
 
      procedure tthumbcgarm.a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);
        var
-          imm_shift : byte;
           l : tasmlabel;
           hr : treference;
        begin
@@ -3940,8 +4022,7 @@ unit cgcpu;
 
     procedure tthumbcgarm.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
       var
-        tmpreg,overflowreg : tregister;
-        asmop : tasmop;
+        tmpreg : tregister;
       begin
         case op of
           OP_NEG:
@@ -3974,9 +4055,9 @@ unit cgcpu;
     procedure tthumbcgarm.a_op_const_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; dst: tregister);
       var
         tmpreg : tregister;
-        so : tshifterop;
+        {$ifdef DUMMY}
         l1 : longint;
-        imm1, imm2: DWord;
+        {$endif DUMMY}
       begin
         //!!! ovloc.loc:=LOC_VOID;
         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);
        var
-          imm_shift : byte;
           l : tasmlabel;
           hr : treference;
        begin
@@ -4663,7 +4743,6 @@ unit cgcpu;
 
 
     procedure tthumb2cgarm.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
-      var item: taicpu;
       begin
         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)));
@@ -4879,7 +4958,6 @@ unit cgcpu;
         tmpreg : tregister;
         tmpref : treference;
         l : tasmlabel;
-        so: tshifterop;
       begin
         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);
       var
         tmpreg : tregister;
-        b : byte;
       begin
         case op of
           OP_AND,OP_OR,OP_XOR:

+ 511 - 291
compiler/arm/cpuinfo.pas

@@ -251,9 +251,60 @@ Type
       ct_stm32f107vb,
       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_stm32f745xg,
@@ -353,14 +404,75 @@ Type
       ct_allwinner_a20,
 
       { 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
       ct_thumb2bare
      );
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { for this platform? }
@@ -430,320 +542,427 @@ Const
 
    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}
-      (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}
-      (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}
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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 }
-      (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];
@@ -765,7 +984,8 @@ Const
 
  type
    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_LABEL,  { CPU supports the BLX <label> instruction                  }
        CPUARM_HAS_CLZ,        { CPU supports the CLZ instruction                          }
@@ -784,23 +1004,23 @@ Const
    cpu_capabilities : array[tcputype] of set of tcpuflags =
      ( { cpu_none     } [],
        { 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 }
-       { 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 }

+ 5 - 6
compiler/arm/cpupara.pas

@@ -131,7 +131,7 @@ unit cpupara;
         psym:=tparavarsym(pd.paras[nr-1]);
         pdef:=psym.vardef;
         if push_addr_param(psym.varspez,pdef,pd.proccalloption) then
-          pdef:=cpointerdef.getreusable(pdef);
+          pdef:=cpointerdef.getreusable_no_free(pdef);
         cgpara.reset;
         cgpara.size:=def_cgsize(pdef);
         cgpara.intsize:=tcgsize2size[cgpara.size];
@@ -257,7 +257,6 @@ unit cpupara;
       var
         i: longint;
         sym: tsym;
-        fpufield: boolean;
       begin
         if handle_common_ret_in_param(def,pd,result) then
           exit;
@@ -418,7 +417,7 @@ unit cpupara;
 
             if push_addr_param(hp.varspez,paradef,p.proccalloption) then
               begin
-                paradef:=cpointerdef.getreusable(paradef);
+                paradef:=cpointerdef.getreusable_no_free(paradef);
                 loc:=LOC_REGISTER;
                 paracgsize := OS_ADDR;
                 paralen := tcgsize2size[OS_ADDR];
@@ -512,7 +511,7 @@ unit cpupara;
                             { LOC_REFERENCE always contains everything that's left }
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.size:=int_cgsize(paralen);
-                            paraloc^.def:=carraydef.getreusable(u8inttype,paralen);
+                            paraloc^.def:=carraydef.getreusable_no_free(u8inttype,paralen);
                             if (side=callerside) then
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                             paraloc^.reference.offset:=stack_offset;
@@ -586,7 +585,7 @@ unit cpupara;
                             { LOC_REFERENCE always contains everything that's left }
                             paraloc^.loc:=LOC_REFERENCE;
                             paraloc^.size:=int_cgsize(paralen);
-                            paraloc^.def:=carraydef.getreusable(u8inttype,paralen);
+                            paraloc^.def:=carraydef.getreusable_no_free(u8inttype,paralen);
                             if (side=callerside) then
                               paraloc^.reference.index:=NR_STACK_POINTER_REG;
                             paraloc^.reference.offset:=stack_offset;
@@ -599,7 +598,7 @@ unit cpupara;
                         if push_addr_param(hp.varspez,paradef,p.proccalloption) then
                           begin
                             paraloc^.size:=OS_ADDR;
-                            paraloc^.def:=cpointerdef.getreusable(paradef);
+                            paraloc^.def:=cpointerdef.getreusable_no_free(paradef);
                             assignintreg
                           end
                         else

+ 0 - 1
compiler/arm/hlcgcpu.pas

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

+ 2 - 2
compiler/arm/narmadd.pas

@@ -330,8 +330,8 @@ interface
               else
                 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);
               current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_VMRS, NR_APSR_nzcv, NR_FPSCR));
             end;

+ 0 - 1
compiler/arm/narminl.pas

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

+ 2 - 2
compiler/arm/narmmat.pas

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

+ 1 - 5
compiler/arm/rgcpu.pas

@@ -174,7 +174,6 @@ unit rgcpu;
       var
         tmpref : treference;
         helplist : TAsmList;
-        l : tasmlabel;
         hreg : tregister;
         immshift: byte;
         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;
-      var
-        b : byte;
       begin
         result:=false;
         if abs(spilltemp.offset)>4095 then
@@ -611,8 +608,7 @@ unit rgcpu;
     procedure trgintcputhumb.add_cpu_interferences(p: tai);
       var
         r : tregister;
-        i,
-        hr : longint;
+        i : longint;
       begin
         if p.typ=ait_instruction then
           begin

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 511 - 317
compiler/assemble.pas


+ 5 - 6
compiler/avr/agavrgas.pas

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

+ 18 - 8
compiler/avr/aoptcpu.pas

@@ -171,14 +171,19 @@ Implementation
                                     A_INC,A_LSL,A_LSR,
                                     A_OR,A_ORI,A_ROL,A_ROR,A_SBC,A_SBCI,A_SUB,A_SUBI]) and
               GetNextInstruction(p, hp1) and
-              MatchInstruction(hp1, A_CP) and
-              (((taicpu(p).oper[0]^.reg = taicpu(hp1).oper[0]^.reg) and
-                (taicpu(hp1).oper[1]^.reg = NR_R1)) or
-               ((taicpu(p).oper[0]^.reg = taicpu(hp1).oper[1]^.reg) and
-                (taicpu(hp1).oper[0]^.reg = NR_R1) and
-                (taicpu(p).opcode in [A_ADC,A_ADD,A_AND,A_ANDI,A_ASR,A_COM,A_EOR,
-                                      A_LSL,A_LSR,
-                                      A_OR,A_ORI,A_ROL,A_ROR]))) and
+              ((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
               { be careful here, following instructions could use other flags
                 however after a jump fpc never depends on the value of flags }
@@ -203,6 +208,10 @@ Implementation
                   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);
 
                 asml.remove(hp1);
@@ -584,6 +593,7 @@ Implementation
                        (not RegModifiedBetween(taicpu(p).oper[1]^.reg, p, hp1)) and
                        (hp1.typ = ait_instruction) and
                        (taicpu(hp1).opcode in [A_PUSH,A_MOV,A_CP,A_CPC,A_ADD,A_SUB,A_ADC,A_SBC,A_EOR,A_AND,A_OR,
+                                               A_STD,A_ST,
                                                A_OUT,A_IN]) and
                        RegInInstruction(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
         i : longint;
         hp : PCGParaLocation;
+        ref: treference;
       begin
         if not(tcgsize2size[paraloc.Size] in [1..4]) then
           internalerror(2014011101);
 
         hp:=paraloc.location;
 
-        for i:=1 to tcgsize2size[paraloc.Size] do
+        i:=1;
+        while i<=tcgsize2size[paraloc.Size] do
           begin
             if not(assigned(hp)) then
               internalerror(2014011105);
+             //paramanager.allocparaloc(list,hp);
              case hp^.loc of
                LOC_REGISTER,LOC_CREGISTER:
                  begin
@@ -325,10 +328,20 @@ unit cgcpu;
                      (hp^.shiftval<>0) then
                      internalerror(2015041101);
                    a_load_const_reg(list,hp^.size,(a shr (8*(i-1))) and $ff,hp^.register);
+
+                   inc(i,tcgsize2size[hp^.size]);
                    hp:=hp^.Next;
                  end;
                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
                  internalerror(2002071004);
             end;
@@ -765,7 +778,8 @@ unit cgcpu;
              begin
                for i:=1 to tcgsize2size[size] do
                  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;
                    mask:=mask shl 8;
                    inc(shift,8);
@@ -775,7 +789,10 @@ unit cgcpu;
              begin
                for i:=1 to tcgsize2size[size] do
                  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;
                    mask:=mask shl 8;
                    inc(shift,8);
@@ -783,7 +800,10 @@ unit cgcpu;
              end;
            OP_SUB:
              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
                  begin
                    for i:=2 to tcgsize2size[size] do
@@ -871,6 +891,8 @@ unit cgcpu;
                curvalue:=a and mask;
                if curvalue=0 then
                  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
                  begin
                    tmpreg:=getintregister(list,OS_8);
@@ -946,7 +968,12 @@ unit cgcpu;
              if ((qword(a) and mask) shr shift)=0 then
                emit_mov(list,reg,NR_R1)
              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;
              inc(shift,8);

+ 155 - 144
compiler/avr/cpuinfo.pas

@@ -204,6 +204,12 @@ Type
       ct_attiny25
      );
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { for this platform? }
@@ -254,6 +260,8 @@ Const
    ((
         controllertypestr:'';
         controllerunitstr:'';
+        cputype: cpu_none;
+        fputype: fpu_soft;
         flashbase:0;
         flashsize:0;
         srambase:0;
@@ -264,6 +272,9 @@ Const
         (
         controllertypestr:'AVRSIM';
         controllerunitstr:'AVRSIM';
+        
+        cputype: cpu_avr5;
+        fputype: fpu_soft;
         flashbase:0;
         flashsize:$20000;
         srambase:0;
@@ -271,150 +282,150 @@ Const
         eeprombase:0;
         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 }

+ 2 - 2
compiler/avr/cpupara.pas

@@ -255,7 +255,7 @@ unit cpupara;
 
             if push_addr_param(hp.varspez,paradef,p.proccalloption) then
               begin
-                paradef:=cpointerdef.getreusable(paradef);
+                paradef:=cpointerdef.getreusable_no_free(paradef);
                 loc:=LOC_REGISTER;
                 paracgsize:=OS_ADDR;
                 paralen:=tcgsize2size[OS_ADDR];
@@ -353,7 +353,7 @@ unit cpupara;
                         if push_addr_param(hp.varspez,paradef,p.proccalloption) then
                           begin
                             paraloc^.size:=OS_ADDR;
-                            paraloc^.def:=cpointerdef.getreusable(paradef);
+                            paraloc^.def:=cpointerdef.getreusable_no_free(paradef);
                             assignintreg
                           end
                         else

+ 7 - 7
compiler/blockutl.pas

@@ -160,9 +160,9 @@ implementation
       { must be a valid Pascal identifier, because we will reference it when
         constructing the block initialiser }
       { 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 }
       if searchsym(name,srsym,srsymtable) then
         begin
@@ -174,7 +174,7 @@ implementation
       { find the type of the descriptor structure }
       descriptordef:=search_named_unit_globaltype('BLOCKRTL','FPC_BLOCK_DESCRIPTOR_SIMPLE',true).typedef;
       { create new static variable }
-      descriptor:=cstaticvarsym.create(name,vs_value,descriptordef,[]);
+      descriptor:=cstaticvarsym.create(name,vs_value,descriptordef,[],true);
       symtablestack.top.insert(descriptor);
       include(descriptor.symoptions,sp_internal);
       { create typed constant for the descriptor }
@@ -196,7 +196,7 @@ implementation
     begin
       { 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 }
-      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 }
       if searchsym(wrappername,srsym,srsymtable) then
         begin
@@ -227,7 +227,7 @@ implementation
         begin
           { alias for the type to invoke the procvar, used in the symcreat
             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;
         end;
     end;
@@ -253,7 +253,7 @@ implementation
       result:=cstaticvarsym.create(
         '$'+literalname,
         vs_value,
-        blockliteraldef,[]);
+        blockliteraldef,[],true);
       include(result.symoptions,sp_internal);
       symtablestack.top.insert(result);
       { initialise it }

+ 6 - 6
compiler/cclasses.pas

@@ -2881,7 +2881,7 @@ end;
         h: LongWord;
       begin
         h := FPHash(Key, KeyLen);
-        Entry := @FBucket[h mod FBucketCount];
+        Entry := @FBucket[h and (FBucketCount-1)];
         while Assigned(Entry^) and
           not ((Entry^^.HashValue = h) and (Entry^^.KeyLength = KeyLen) and
             (CompareByte(Entry^^.Key^, Key^, KeyLen) = 0)) do
@@ -2900,7 +2900,7 @@ end;
           end
         else
           begin
-            New(Result);
+            GetMem(Result,SizeOfItem);
             if FOwnsKeys then
             begin
               GetMem(Result^.Key, KeyLen);
@@ -2924,13 +2924,13 @@ end;
         i: Integer;
         e, n: PHashSetItem;
       begin
-        p := AllocMem(NewCapacity * SizeOfItem);
+        p := AllocMem(NewCapacity * SizeOf(PHashSetItem));
         for i := 0 to FBucketCount-1 do
           begin
             e := FBucket[i];
             while Assigned(e) do
             begin
-              chain := @p[e^.HashValue mod NewCapacity];
+              chain := @p[e^.HashValue and (NewCapacity-1)];
               n := e^.Next;
               e^.Next := chain^;
               chain^ := e;
@@ -2988,7 +2988,7 @@ end;
         h: LongWord;
       begin
         h := FPHash(Key, KeyLen, Tag);
-        Entry := @PPTagHashSetItem(FBucket)[h mod FBucketCount];
+        Entry := @PPTagHashSetItem(FBucket)[h and (FBucketCount-1)];
         while Assigned(Entry^) and
           not ((Entry^^.HashValue = h) and (Entry^^.KeyLength = KeyLen) and
             (Entry^^.Tag = Tag) and (CompareByte(Entry^^.Key^, Key^, KeyLen) = 0)) do
@@ -3007,7 +3007,7 @@ end;
           end
         else
           begin
-            New(Result);
+            Getmem(Result,SizeOfItem);
             if FOwnsKeys then
             begin
               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 }
              { simple cardinal                                          }
              cg.a_label(list,poslabel);
-             hdef:=corddef.create(u32bit,0,$ffffffff);
+             hdef:=corddef.create(u32bit,0,$ffffffff,false);
 
              location_copy(temploc,l);
              temploc.size:=OS_32;
@@ -944,7 +944,7 @@ unit cg64f32;
                end;
 
              hlcg.g_rangecheck(list,temploc,hdef,todef);
-             hdef.owner.deletedef(hdef);
+             hdef.free;
 
              if from_signed and to_signed then
                begin
@@ -971,11 +971,11 @@ unit cg64f32;
                  { if we get here, the 64bit value lies between }
                  { longint($80000000) and -1 (JM)               }
                  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);
                  temploc.size:=OS_32;
                  hlcg.g_rangecheck(list,temploc,hdef,todef);
-                 hdef.owner.deletedef(hdef);
+                 hdef.free;
                  cg.a_label(list,endlabel);
                end;
            end

+ 1 - 0
compiler/cgbase.pas

@@ -101,6 +101,7 @@ interface
          {$ENDIF}
          {$IFDEF i8086}
          ,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'
          {$ENDIF}
          {$IFDEF AARCH64}

+ 2 - 2
compiler/cgutils.pas

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

+ 7 - 1
compiler/compiler.pas

@@ -370,7 +370,13 @@ begin
           { in case of 50 errors, this could cause another 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
           on ECompilerAbort do
             ;

+ 51 - 49
compiler/cresstr.pas

@@ -37,7 +37,7 @@ uses
 {$endif}
    cclasses,widestr,
    cutils,globtype,globals,systems,
-   symbase,symconst,symtype,symdef,symsym,
+   symbase,symconst,symtype,symdef,symsym,symtable,
    verbose,fmodule,ppu,
    aasmbase,aasmtai,aasmdata,aasmcnst,
    aasmcpu;
@@ -134,38 +134,36 @@ uses
         namelab,
         valuelab : tasmlabofs;
         resstrlab : tasmsymbol;
-        endsymlab : tasmsymbol;
         R : TResourceStringItem;
+        resstrdef: tdef;
         tcb : ttai_typedconstbuilder;
       begin
+        resstrdef:=search_system_type('TRESOURCESTRINGRECORD').typedef;
+
         { Put resourcestrings in a new objectfile. Putting it in multiple files
           makes the linking too dependent on the linker script requiring a SORT(*) for
           the data sections }
-        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 }
+        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);
-        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 }
         R:=TResourceStringItem(List.First);
         while assigned(R) do
           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
               valuelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,getansistringcodepage)
             else
@@ -173,10 +171,8 @@ uses
                 valuelab.lab:=nil;
                 valuelab.ofs:=0;
               end;
-            { Append the name as a ansistring. }
             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);
-
             {
               Resourcestring index:
                   TResourceStringRecord = Packed Record
@@ -186,35 +182,30 @@ uses
                      HashValue    : LongWord;
                    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);
+            tcb.free;
           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;
-        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;
 
     procedure Tresourcestrings.WriteRSJFile;
@@ -237,11 +228,22 @@ uses
             message1(general_e_errorwritingresourcefile,ResFileName);
             exit;
           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":[');
         R:=TResourceStringItem(List.First);
         while assigned(R) do
           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);
             ascii2unicode(R.Value,R.Len,current_settings.sourcecodepage,W);
             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);
 
     function PopCnt(AValue : Byte): Byte;
-      var
-        i : SizeInt;
       begin
         Result:=PopCntData[AValue and $f]+PopCntData[(AValue shr 4) and $f];
       end;

+ 69 - 31
compiler/dbgdwarf.pas

@@ -276,6 +276,17 @@ interface
         bit8: boolean;
       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 = class(TDebugInfo)
@@ -293,6 +304,9 @@ interface
         loclist: tdynamicarray;
         asmline: TAsmList;
 
+        { lookup table for def -> DWARF-labels }
+        dwarflabels: TDwarfLabHashSet;
+
         // The current entry in dwarf_info with the link to the abbrev-section
         dwarf_info_abbref_tai: tai_const;
         // Empty start-item of the abbrev-searchtree
@@ -328,7 +342,7 @@ interface
         procedure set_use_64bit_headers(state: boolean);
         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
           tvarrec for us (must only pass one element in the last parameter).  }
@@ -719,6 +733,16 @@ implementation
         Dispose(SI);
       end;
 
+
+{****************************************************************************
+                              TDwarfLabHashSet
+****************************************************************************}
+
+    class function TDwarfLabHashSet.SizeOfItem: Integer;
+      begin
+        Result:=sizeof(TDwarfHashSetItem);
+      end;
+
 {****************************************************************************
                               TDirIndexItem
 ****************************************************************************}
@@ -915,7 +939,9 @@ implementation
       end;
 
 
-    procedure TDebugInfoDwarf.set_def_dwarf_labs(def:tdef);
+    function TDebugInfoDwarf.get_def_dwarf_labs(def:tdef): PDwarfHashSetItem;
+      var
+        needstructdeflab: boolean;
       begin
         { Keep track of used dwarf entries, this info is only useful for dwarf entries
           referenced by the symbols. Definitions will always include all
@@ -923,18 +949,23 @@ implementation
         if def.dbg_state=dbg_state_unused then
           def.dbg_state:=dbg_state_used;
         { 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
+            { 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
               begin
                 if (ds_dwarf_dbg_info_written in def.defstates) then
                   begin
                     if not assigned(def.typesym) then
                       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;
                   end
                 else
@@ -945,20 +976,20 @@ implementation
                        (def.owner.symtabletype=globalsymtable) and
                        (def.owner.iscurrentunit) then
                       begin
-                        def.dwarf_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym, 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);
                       end
                     else
                       begin
                         { The pointer typecast is needed to prevent a problem with range checking
                           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
@@ -967,10 +998,10 @@ implementation
                 { The pointer typecast is needed to prevent a problem with range checking
                   on when the typecast is changed to 'as' }
                 { 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;
             if def.dbg_state=dbg_state_used then
               deftowritelist.Add(def);
@@ -980,20 +1011,17 @@ implementation
 
     function TDebugInfoDwarf.def_dwarf_lab(def: tdef): tasmsymbol;
       begin
-        set_def_dwarf_labs(def);
-        result:=def.dwarf_lab;
+        result:=get_def_dwarf_labs(def)^.lab;
       end;
 
     function TDebugInfoDwarf.def_dwarf_class_struct_lab(def: tobjectdef): tasmsymbol;
       begin
-        set_def_dwarf_labs(def);
-        result:=def.dwarf_struct_lab;
+        result:=get_def_dwarf_labs(def)^.struct_lab;
       end;
 
     function TDebugInfoDwarf.def_dwarf_ref_lab(def: tdef): tasmsymbol;
       begin
-        set_def_dwarf_labs(def);
-        result:=def.dwarf_ref_lab;
+        result:=get_def_dwarf_labs(def)^.ref_lab;
       end;
 
     constructor TDebugInfoDwarf.Create;
@@ -3117,6 +3145,15 @@ implementation
         storefilepos:=current_filepos;
         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;
 
         defnumberlist:=TFPObjectList.create(false);
@@ -3231,16 +3268,15 @@ implementation
         { end of abbrev table }
         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
           begin
             def := tdef(defnumberlist[i]);
             if assigned(def) then
-              begin
-                def.dwarf_lab:=nil;
-                def.dbg_state:=dbg_state_unused;
-              end;
+              def.dbg_state:=dbg_state_unused;
           end;
+        dwarflabels.free;
+        dwarflabels:=nil;
 
         defnumberlist.free;
         defnumberlist:=nil;
@@ -3436,7 +3472,9 @@ implementation
                     if (prevlabel = nil) or
                        { darwin's assembler cannot create an uleb128 of the difference }
                        { 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
                         asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
                         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_ignoreframepointer,     // ignore frame pointer parameter (for assignment-compatibility of global procedures to nested procvars)
           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;
@@ -1337,18 +1339,16 @@ implementation
                    end;
                  pointerdef :
                    begin
-{$ifdef x86}
                      { 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
                          if fromtreetype=niln then
                            eq:=te_equal
                          else
                            eq:=te_incompatible;
                        end
+                     { the types can be forward type, handle before normal type check !! }
                      else
-{$endif x86}
-                      { the types can be forward type, handle before normal type check !! }
                       if assigned(def_to.typesym) and
                          ((tpointerdef(def_to).pointeddef.typ=forwarddef) or
                           (tpointerdef(def_from).pointeddef.typ=forwarddef)) then
@@ -1420,7 +1420,7 @@ implementation
                        this is not allowed for complex procvars }
                      if (is_void(tpointerdef(def_to).pointeddef) or
                          (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
                         doconv:=tc_equal;
                         eq:=te_convert_l1;
@@ -1431,7 +1431,7 @@ implementation
                      { procedure variable can be assigned to an void pointer,
                        this not allowed for methodpointers }
                      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
                         doconv:=tc_proc_2_procvar;
                         eq:=te_convert_l2;
@@ -1955,9 +1955,27 @@ implementation
 
 
     function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
+
       var
         currpara1,
         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;
         hpd       : tprocdef;
         convtype  : tconverttype;
@@ -2096,9 +2114,32 @@ implementation
                             Message2(type_w_procvar_univ_conflicting_para,currpara1.vardef.typename,currpara2.vardef.typename)
                         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
                     exit;
                 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 }
               { a separate "open string" type -> we have to be able to        }
               { consider those as exact when resolving forward definitions.   }
@@ -2185,6 +2226,7 @@ implementation
          { check for method pointer and local procedure pointer:
              a) anything but procvars can be assigned to blocks
              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)
              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
@@ -2201,7 +2243,9 @@ implementation
            { can't explicitly check against procvars here, because
              def1 may already be a procvar due to a proc_to_procvar;
              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) }
              (is_nested_pd(def1) or
               not is_nested_pd(def2))) or
@@ -2220,7 +2264,7 @@ implementation
          { check return value and options, methodpointer is already checked }
          po_comp:=[po_interrupt,po_iocheck,po_varargs];
          { 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);
          if (m_delphi in current_settings.modeswitches) then
            exclude(po_comp,po_varargs);

+ 2 - 0
compiler/finput.pas

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

+ 32 - 0
compiler/fmodule.pas

@@ -1038,6 +1038,38 @@ implementation
             macrosymtablestack.free;
             macrosymtablestack:=nil;
           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;
 
 

+ 2 - 2
compiler/fpcdefs.inc

@@ -7,11 +7,9 @@
 
 { This reduces the memory requirements a lot }
 {$PACKENUM 1}
-{$ifdef FPC_HAS_VARSETS}
 {$ifndef FPC_BIG_ENDIAN}
 { $define USE_PACKSET1}
 {$endif}
-{$endif FPC_HAS_VARSETS}
 
 {$ifdef USE_PACKSET1}
 {$PACKSET 1}
@@ -239,8 +237,10 @@
   (but there we don't support it)
 }
 {$ifdef cpu64bitaddr}
+{$ifndef USE_STABS_64}
 {$define NoDbgStabs}
 {$endif}
+{$endif}
 
 {$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 }

+ 13 - 11
compiler/fppu.pas

@@ -1197,13 +1197,10 @@ var
              position in derefdata is not necessarily at the end }
             derefdata.seek(derefdata.size);
          tstoredsymtable(globalsymtable).buildderefimpl;
-         if (flags and uf_local_symtable)<>0 then
-           begin
-             tstoredsymtable(localsymtable).buildderef;
-             tstoredsymtable(localsymtable).buildderefimpl;
-           end;
          tunitwpoinfo(wpoinfo).buildderef;
          tunitwpoinfo(wpoinfo).buildderefimpl;
+         if (flags and uf_local_symtable)<>0 then
+           tstoredsymtable(localsymtable).buildderef_registered;
          writederefmap;
          writederefdata;
 
@@ -1477,9 +1474,12 @@ var
           end;
 
         { 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
-            tstoredsymtable(localsymtable).derefimpl;
+          tstoredsymtable(localsymtable).derefimpl(false);
 
          { read whole program optimisation-related information }
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
@@ -1608,12 +1608,14 @@ var
                if interface_compiled then
                  begin
                    Message1(unit_u_reresolving_unit,modulename^);
-                   tstoredsymtable(globalsymtable).deref;
-                   tstoredsymtable(globalsymtable).derefimpl;
+                   tstoredsymtable(globalsymtable).deref(false);
+                   tstoredsymtable(globalsymtable).derefimpl(false);
                    if assigned(localsymtable) then
                     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;
                    if assigned(wpoinfo) then
                      begin

+ 7 - 1
compiler/generic/cpuinfo.pas

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

+ 8 - 1
compiler/globals.pas

@@ -70,7 +70,13 @@ interface
        macmodeswitches =
          [m_mac,m_cvar_support,m_mac_procvar,m_nested_procvars,m_non_local_goto,m_isolike_unary_minus,m_default_inline];
        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 }
        maxnesting = 32;
@@ -303,6 +309,7 @@ interface
        nwcopyright  : string;
 
        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 }
 

+ 34 - 17
compiler/globtype.pas

@@ -160,7 +160,8 @@ interface
          cs_support_c_operators,
          { generation }
          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 }
          cs_create_smart,cs_create_dynamic,cs_create_pic,
          { browser switches are back }
@@ -168,7 +169,8 @@ interface
          { target specific }
          cs_executable_stack,
          { i8086 specific }
-         cs_huge_code
+         cs_huge_code,
+         cs_win16_smartcallbacks
        );
        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_opt_used_sections,cs_link_separate_dbg_file,
          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;
 
@@ -247,7 +251,18 @@ interface
            accidental uses of uninitialised values }
          ts_init_locals,
          { 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;
 
@@ -296,19 +311,13 @@ interface
        twpoptimizerswitches = set of twpoptimizerswitch;
 
     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
           name: string[22];
           { target switch can have an arbitratry value, not only on/off }
           hasvalue: boolean;
           { target switch can be used only globally }
           isglobal: boolean;
-          define: string[15];
+          define: string[25];
        end;
 
     const
@@ -338,7 +347,8 @@ interface
          (name: 'THUMBINTERWORKING';   hasvalue: false; isglobal: true ; define: ''),
          (name: 'LOWERCASEPROCSTART';  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 }
@@ -364,7 +374,7 @@ interface
        { Switches which can be changed by a mode (fpc,tp7,delphi) }
        tmodeswitch = (m_none,
          { 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}
          { more specific }
          m_class,               { delphi class model }
@@ -402,12 +412,15 @@ interface
                                     ansistring; similarly, char becomes unicodechar rather than ansichar }
          m_type_helpers,        { allows the declaration of "type helper" (non-Delphi) or "record helper"
                                   (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;
 
     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
        { Application types (platform specific) }
@@ -535,7 +548,7 @@ interface
        cstylearrayofconst = [pocall_cdecl,pocall_cppdecl,pocall_mwpascal];
 
        modeswitchstr : array[tmodeswitch] of string[18] = ('',
-         '','','','','','',
+         '','','','','','','',
          {$ifdef fpc_mode}'',{$endif}
          { more specific }
          'CLASS',
@@ -568,7 +581,11 @@ interface
          'FINALFIELDS',
          'UNICODESTRINGS',
          'TYPEHELPERS',
-         'CBLOCKS');
+         'CBLOCKS',
+         'ISOIO',
+         'ISOPROGRAMPARAS',
+         'ISOMOD'
+         );
 
 
      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;
 
           { 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
             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 }
 
@@ -3825,16 +3839,59 @@ implementation
       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
       { nothing to do }
     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
       { nothing to do }
     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);
     var
       hregister,
@@ -4389,22 +4446,6 @@ implementation
           { setinitname may generate a new section -> don't add to the
             current list, because we assume this remains a text section }
           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;
 
 
@@ -4991,7 +5032,7 @@ implementation
                   else
                     internalerror(2011020507);
 //                      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
           else
@@ -5114,6 +5155,8 @@ implementation
     end;
 
   procedure thlcgobj.gen_load_loc_cgpara(list: TAsmList; vardef: tdef; const l: tlocation; const cgpara: tcgpara);
+    var
+      tmploc: tlocation;
     begin
       { Handle Floating point types differently
 
@@ -5129,6 +5172,18 @@ implementation
           exit;
         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
         LOC_CONSTANT,
         LOC_REGISTER,
@@ -5228,15 +5283,21 @@ implementation
     end;
 
   procedure thlcgobj.record_generated_code_for_procdef(pd: tprocdef; code, data: TAsmList);
+    var
+      alt: TAsmListType;
     begin
+      if not(po_assembler in pd.procoptions) then
+        alt:=al_procedures
+      else
+        alt:=al_pure_assembler;
       { 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 }
       if assigned(data) and
          (not data.empty) then
-        current_asmdata.asmlists[al_procedures].concatlist(data);
+        current_asmdata.asmlists[alt].concatlist(data);
     end;
 
   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
       cclasses,cmsgs,tokens,cpuinfo,
       node,globtype,
-      symconst,symtype,symdef,symsym,symbase;
+      symconst,symtype,symdef,symsym,symbase,
+      pgentype;
 
     type
       Ttok2nodeRec=record
@@ -69,12 +70,13 @@ interface
         FParaNode   : tnode;
         FParaLength : smallint;
         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  maybe_specialize(var pd:tprocdef;spezcontext:tspecializationcontext):boolean;
       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);
         destructor destroy;override;
         procedure list(all:boolean);
@@ -187,7 +189,8 @@ implementation
        cutils,verbose,
        symtable,
        defutil,defcmp,
-       nbas,ncnv,nld,nmem,ncal,nmat,ninl,nutils,procinfo
+       nbas,ncnv,nld,nmem,ncal,nmat,ninl,nutils,procinfo,
+       pgenutil
        ;
 
     type
@@ -776,7 +779,7 @@ implementation
 
         { the nil as symtable signs firstcalln that this is
           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
           skip the overload choosing in callnode.pass_typecheck }
@@ -955,7 +958,7 @@ implementation
 
         { the nil as symtable signs firstcalln that this is
           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
           skip the overload choosing in callnode.pass_typecheck }
@@ -2110,7 +2113,7 @@ implementation
                            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
         if not assigned(sym) then
           internalerror(200411015);
@@ -2119,7 +2122,7 @@ implementation
         FProcsymtable:=st;
         FParanode:=ppn;
         FIgnoredCandidateProcs:=tfpobjectlist.create(false);
-        create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited);
+        create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited,spezcontext);
       end;
 
 
@@ -2130,7 +2133,7 @@ implementation
         FProcsymtable:=nil;
         FParanode:=ppn;
         FIgnoredCandidateProcs:=tfpobjectlist.create(false);
-        create_candidate_list(false,false,false,false,false,false);
+        create_candidate_list(false,false,false,false,false,false,nil);
       end;
 
 
@@ -2144,13 +2147,16 @@ implementation
         while assigned(hp) do
          begin
            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);
            hp:=hpnext;
          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;
         var
@@ -2163,6 +2169,8 @@ implementation
           for j:=0 to srsym.ProcdefList.Count-1 do
             begin
               pd:=tprocdef(srsym.ProcdefList[j]);
+              if not maybe_specialize(pd,spezcontext) then
+                continue;
               if (po_ignore_for_overload_resolution in pd.procoptions) then
                 begin
                   FIgnoredCandidateProcs.add(pd);
@@ -2194,7 +2202,7 @@ implementation
                 FProcsym:=tprocsym(srsym);
               if po_overload in pd.procoptions then
                 result:=true;
-              ProcdefOverloadList.Add(srsym.ProcdefList[j]);
+              ProcdefOverloadList.Add(pd);
             end;
         end;
 
@@ -2275,7 +2283,7 @@ implementation
       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
         j          : integer;
         pd         : tprocdef;
@@ -2332,6 +2340,8 @@ implementation
                     for j:=0 to tprocsym(srsym).ProcdefList.Count-1 do
                       begin
                         pd:=tprocdef(tprocsym(srsym).ProcdefList[j]);
+                        if not maybe_specialize(pd,spezcontext) then
+                          continue;
                         if (po_ignore_for_overload_resolution in pd.procoptions) then
                           begin
                             FIgnoredCandidateProcs.add(pd);
@@ -2342,7 +2352,7 @@ implementation
                           FProcsym:=tprocsym(srsym);
                         if po_overload in pd.procoptions then
                           hasoverload:=true;
-                        ProcdefOverloadList.Add(tprocsym(srsym).ProcdefList[j]);
+                        ProcdefOverloadList.Add(pd);
                       end;
                     { when there is no explicit overload we stop searching,
                       except for Objective-C methods called via id }
@@ -2356,13 +2366,14 @@ implementation
       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
         j     : integer;
         pd    : tprocdef;
         hp    : pcandidate;
         pt    : tcallparanode;
-        found : boolean;
+        found,
+        added : boolean;
         st    : TSymtable;
         contextstructdef : tabstractrecorddef;
         ProcdefOverloadList : TFPObjectList;
@@ -2375,7 +2386,7 @@ implementation
         if not objcidcall and
            (FOperator=NOTOKEN) and
            (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
         if (FOperator<>NOTOKEN) then
           begin
@@ -2386,13 +2397,13 @@ implementation
               begin
                 if (pt.resultdef.typ=recorddef) and
                     (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);
               end;
-            collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit);
+            collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit,spezcontext);
           end
         else
-          collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit);
+          collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit,spezcontext);
 
         { determine length of parameter list.
           for operators also enable the variant-operators if
@@ -2433,6 +2444,7 @@ implementation
         for j:=0 to ProcdefOverloadList.Count-1 do
           begin
             pd:=tprocdef(ProcdefOverloadList[j]);
+            added:=false;
 
             { only when the # of parameter are supported by the procedure and
               it is visible }
@@ -2452,8 +2464,23 @@ implementation
                ) and
                (
                 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
               begin
                 { don't add duplicates, only compare visible parameters for the user }
@@ -2476,7 +2503,20 @@ implementation
                     hp:=hp^.next;
                   end;
                 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;
 
@@ -2525,6 +2565,33 @@ implementation
       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);
       var
         hp : pcandidate;

+ 39 - 43
compiler/i386/cgcpu.pas

@@ -36,7 +36,6 @@ unit cgcpu;
     type
       tcg386 = class(tcgx86)
         procedure init_register_allocators;override;
-        procedure do_register_allocation(list:TAsmList;headertai:tai);override;
 
         { passing parameter using push instead of mov }
         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;
       begin
         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
-          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_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;
       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);
       var
@@ -310,13 +295,6 @@ unit cgcpu;
         end;
 
       begin
-        { Release PIC register }
-        if (cs_create_pic in current_settings.moduleswitches) and
-           (tf_pic_uses_got in target_info.flags) and
-           (pi_needs_got in current_procinfo.flags) and
-           not(target_info.system in systems_darwin) then
-          list.concat(tai_regalloc.dealloc(NR_PIC_OFFSET_REG,nil));
-
         { MMX needs to call EMMS }
         if assigned(rg[R_MMXREGISTER]) and
            (rg[R_MMXREGISTER].uses_registers) then
@@ -548,26 +526,49 @@ unit cgcpu;
 
     procedure tcg386.g_maybe_got_init(list: TAsmList);
       var
-        notdarwin: boolean;
+        i: longint;
+        tmpreg: TRegister;
       begin
         { allocate 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) then
           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
-                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
             else
               begin
@@ -579,11 +580,6 @@ unit cgcpu;
                 a_label(list,current_procinfo.CurrGotLabel);
                 list.concat(taicpu.op_reg(A_POP,S_L,current_procinfo.got))
               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;
 

+ 7 - 1
compiler/i386/cpuinfo.pas

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

+ 2 - 2
compiler/i386/cpupara.pas

@@ -446,7 +446,7 @@ unit cpupara;
               begin
                 paralen:=sizeof(aint);
                 paracgsize:=OS_ADDR;
-                paradef:=cpointerdef.getreusable(paradef);
+                paradef:=cpointerdef.getreusable_no_free(paradef);
               end
             else
               begin
@@ -598,7 +598,7 @@ unit cpupara;
                       begin
                         paralen:=sizeof(aint);
                         paracgsize:=OS_ADDR;
-                        paradef:=cpointerdef.getreusable(paradef);
+                        paradef:=cpointerdef.getreusable_no_free(paradef);
                       end
                     else
                       begin

+ 1 - 2
compiler/i386/cpupi.pas

@@ -97,8 +97,7 @@ unit cpupi;
 
     procedure ti386procinfo.allocate_got_register(list: tasmlist);
       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
             got := cg.getaddressregister(list);
           end;

+ 2 - 14
compiler/i386/daopt386.pas

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

+ 27 - 0
compiler/i386/hlcgcpu.pas

@@ -41,6 +41,7 @@ interface
      protected
       procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
      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_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;
@@ -56,6 +57,7 @@ interface
 implementation
 
   uses
+    globals, procinfo,
     verbose,
     fmodule,systems,
     aasmbase,aasmtai,
@@ -180,6 +182,31 @@ implementation
     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);
     begin
       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);
 
     oldflowcontrol:=flowcontrol;
-    flowcontrol:=flowcontrol*[fc_unwind]+[fc_inflowcontrol];
+    flowcontrol:=[fc_inflowcontrol];
 
     { RTL will put exceptobject into EAX when jumping here }
     cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
@@ -241,7 +241,7 @@ function ti386tryfinallynode.simplify(forinline: boolean): tnode;
       begin
         finalizepi.code:=right;
         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);
         { For implicit frames, no actual code is available at this time,
           it is added later in assembler form. So store the nested procinfo

+ 2 - 2
compiler/i386/n386ld.pas

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

+ 4 - 78
compiler/i386/popt386.pas

@@ -44,7 +44,8 @@ uses
   cobjects,
 {$endif finaldestdebug}
   cpuinfo,cpubase,cgutils,daopt386,
-  cgx86;
+  cgx86,
+  aoptx86;
 
 
 function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
@@ -122,7 +123,7 @@ begin
        (taicpu(hp1).opcode = A_FILD))) and
      (taicpu(hp1).oper[0]^.typ = top_ref) 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
       { replacing fstp f;fld f by fst f is only valid for extended because of rounding }
       if (taicpu(p).opsize=S_FX) and
@@ -470,81 +471,6 @@ begin
 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 }
 procedure PeepHoleOptPass1(Asml: TAsmList; BlockStart, BlockEnd: tai);
 
@@ -2140,7 +2066,7 @@ begin
                                   (taicpu(hp2).condition=C_None) and
                                   { real label and jump, no further references to the
                                     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
                                    begin
                                      l:=0;

+ 65 - 1
compiler/i8086/aoptcpu.pas

@@ -28,14 +28,78 @@ unit aoptcpu;
   Interface
 
     uses
-      cpubase, aoptobj, aoptcpub, aopt;
+      cpubase, aoptobj, aoptcpub, aopt,
+      aasmtai;
 
     Type
       TCpuAsmOptimizer = class(TAsmOptimizer)
+        function PeepHoleOptPass1Cpu(var p : tai) : boolean; override;
       End;
 
   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
   casmoptimizer:=TCpuAsmOptimizer;
 end.

+ 129 - 42
compiler/i8086/cgcpu.pas

@@ -1660,55 +1660,124 @@ unit cgcpu;
         hl_skip: TAsmLabel;
         invf: TResFlags;
         tmpsize: TCgSize;
+        tmpopsize: topsize;
       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;
-          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;
-          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;
-        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;
 
 
@@ -1762,6 +1831,17 @@ unit cgcpu;
         { remove stackframe }
         if not nostackframe then
           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
               begin
                 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);
               end
             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));
           end;
 

+ 1 - 0
compiler/i8086/cpubase.inc

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

+ 7 - 1
compiler/i8086/cpuinfo.pas

@@ -73,6 +73,12 @@ Type
      (ct_none
      );
 
+   tcontrollerdatatype = record
+      controllertypestr, controllerunitstr: string[20];
+      cputype: tcputype; fputype: tfputype;
+      flashbase, flashsize, srambase, sramsize, eeprombase, eepromsize, bootbase, bootsize: dword;
+   end;
+
 
 Const
    { Is there support for dealing with multiple microcontrollers available }
@@ -85,7 +91,7 @@ Const
     {$WARN 3177 OFF}
    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}
 
    { 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]);
         pdef:=psym.vardef;
         if push_addr_param(psym.varspez,pdef,pd.proccalloption) then
-          pdef:=cpointerdef.getreusable(pdef);
+          pdef:=cpointerdef.getreusable_no_free(pdef);
         cgpara.reset;
         cgpara.size:=def_cgsize(pdef);
         cgpara.intsize:=tcgsize2size[cgpara.size];
@@ -442,7 +442,7 @@ unit cpupara;
               begin
                 paralen:=voidpointertype.size;
                 paracgsize:=int_cgsize(voidpointertype.size);
-                paradef:=cpointerdef.getreusable(paradef);
+                paradef:=cpointerdef.getreusable_no_free(paradef);
               end
             else
               begin
@@ -602,7 +602,7 @@ unit cpupara;
                       begin
                         paralen:=voidpointertype.size;
                         paracgsize:=int_cgsize(voidpointertype.size);
-                        paradef:=cpointerdef.getreusable(paradef);
+                        paradef:=cpointerdef.getreusable_no_free(paradef);
                       end
                     else
                       begin

+ 3 - 0
compiler/i8086/cputarg.pas

@@ -38,6 +38,9 @@ implementation
     {$ifndef NOTARGETMSDOS}
       ,t_msdos
     {$endif}
+    {$ifndef NOTARGETWIN}
+      ,t_win16
+    {$endif}
 
 {**************************************
              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_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_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); override;
 
@@ -380,6 +382,22 @@ implementation
     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);
     begin
       if paramanager.use_fixed_stack then

+ 29 - 4
compiler/i8086/n8086add.pas

@@ -88,6 +88,11 @@ interface
             (rt = pointerconstn) and is_farpointer(rd) and
             is_constintnode(left) and
             (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
           begin
             t:=nil;
@@ -143,6 +148,18 @@ interface
                   else
                     internalerror(2014040606);
                 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
                 internalerror(2014040605);
             end;
@@ -886,10 +903,18 @@ interface
                end;
              LOC_CONSTANT :
                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;
              else
                internalerror(200203282);

+ 13 - 1
compiler/i8086/n8086cnv.pas

@@ -34,6 +34,7 @@ interface
 
        t8086typeconvnode = class(tx86typeconvnode)
        protected
+         function typecheck_int_to_int: tnode;override;
          function typecheck_proc_to_procvar: tnode;override;
          procedure second_proc_to_procvar;override;
        end;
@@ -46,11 +47,22 @@ implementation
       aasmbase,aasmtai,aasmdata,aasmcpu,
       symconst,symdef,symcpu,
       cgbase,cga,procinfo,pass_1,pass_2,
-      ncon,ncal,ncnv,
+      ncon,ncal,ncnv,nmem,n8086mem,
       cpubase,cpuinfo,
       cgutils,cgobj,hlcgobj,cgx86,ncgutil,
       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;
       begin
         if (current_settings.x86memorymodel in x86_far_code_models) and

+ 12 - 1
compiler/i8086/n8086con.pas

@@ -34,6 +34,7 @@ interface
 
       ti8086pointerconstnode = class(tcgpointerconstnode)
         constructor create(v : TConstPtrUInt;def:tdef);override;
+        procedure printnodedata(var t: text);override;
         procedure pass_generate_code;override;
       end;
 
@@ -44,7 +45,8 @@ implementation
       symconst,symdef,symcpu,
       defutil,
       cpubase,
-      cga,cgx86,cgobj,cgbase,cgutils;
+      cga,cgx86,cgobj,cgbase,cgutils,
+      node;
 
     {*****************************************************************************
                                T8086POINTERCONSTNODE
@@ -60,6 +62,15 @@ implementation
       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;
       begin
         { far pointer? }

+ 174 - 6
compiler/i8086/n8086ld.pas

@@ -28,23 +28,32 @@ interface
     uses
       globtype,
       symsym,symtype,
-      node,ncgld;
+      node,ncgld,nx86ld,aasmbase;
 
     type
-      ti8086loadnode = class(tcgloadnode)
+
+      { ti8086loadnode }
+
+      ti8086loadnode = class(tx86loadnode)
+        protected
          procedure generate_nested_access(vs: tsym); override;
          procedure generate_absaddr_access(vs: tabsolutevarsym); override;
+         procedure generate_threadvar_access(gvs: tstaticvarsym); override;
+        public
+         procedure pass_generate_code;override;
       end;
 
 
 implementation
 
     uses
-      globals,aasmdata,
-      symcpu,
+      globals,verbose,aasmdata,defutil,
+      symconst,symdef,symtable,symcpu,
       nld,
-      cgbase,cgobj,
-      cpubase,cpuinfo;
+      cgbase,cgobj,cgutils,
+      hlcgobj,
+      cpubase,cpuinfo,
+      parabase,paramgr;
 
 {*****************************************************************************
                             TI8086LOADNODE
@@ -85,6 +94,165 @@ implementation
         inherited;
       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
    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);
         hreg64hi:=left.location.register64.reghi;
         hreg64lo:=left.location.register64.reglo;
+        location.register64.reglo:=hreg64lo;
+        location.register64.reghi:=hreg64hi;
 
         v:=0;
         if right.nodetype=ordconstn then
@@ -425,6 +427,44 @@ implementation
                 emit_const_reg(A_RCR,S_W,1,hreg64lo);
               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
           begin
             { load right operators in a register }
@@ -452,14 +492,24 @@ implementation
               we've already handled them earlier as a special case }
             if right.nodetype<>ordconstn then
               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);
                 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,hreg64hi,hreg64hi);
                 cg.a_jmp_always(current_asmdata.CurrAsmList,l3);
                 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;
             cg.a_label(current_asmdata.CurrAsmList,l2);
             if nodetype=shln then
@@ -483,9 +533,6 @@ implementation
 
             cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_CX);
           end;
-
-        location.register64.reglo:=hreg64lo;
-        location.register64.reghi:=hreg64hi;
       end;
 
 

+ 20 - 0
compiler/i8086/n8086mem.pas

@@ -36,6 +36,9 @@ interface
         protected
          procedure set_absvarsym_resultdef; override;
          function typecheck_non_proc(realsource: tnode; out res: tnode): boolean; override;
+         procedure pass_generate_code;override;
+        public
+         get_offset_only: boolean;
        end;
 
        ti8086derefnode = class(tx86derefnode)
@@ -91,6 +94,23 @@ implementation
           result:=inherited;
       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
 *****************************************************************************}

+ 96 - 2
compiler/i8086/n8086tcon.pas

@@ -35,6 +35,7 @@ interface
 
       ti8086typedconstbuilder = class(tasmlisttypedconstbuilder)
        protected
+        procedure tc_emit_orddef(def: torddef; var node: tnode);override;
         procedure tc_emit_pointerdef(def: tpointerdef; var node: tnode);override;
       end;
 
@@ -42,10 +43,88 @@ interface
 implementation
 
 uses
-  ncnv,defcmp,defutil,aasmtai,symcpu;
+  verbose,
+  ncon,ncnv,ninl,nld,
+  defcmp,defutil,
+  aasmtai,
+  symconst,symtype,symsym,symcpu,
+  htypechk;
 
     { 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);
       var
         hp: tnode;
@@ -60,7 +139,22 @@ uses
                 node.free;
                 node:=hp;
               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
             if is_farpointer(def) or is_hugepointer(def) then
               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 }
     function default_far:boolean;
    public
-    constructor create(level:byte);override;
+    constructor create(level:byte;doregister:boolean);override;
     function address_type:tdef;override;
     function size:asizeint;override;
     procedure declared_far;override;
@@ -324,9 +324,9 @@ implementation
                              tcpuprocdef
 ****************************************************************************}
 
-  constructor tcpuprocdef.create(level: byte);
+  constructor tcpuprocdef.create(level: byte;doregister:boolean);
     begin
-      inherited create(level);
+      inherited create(level,doregister);
       if (current_settings.x86memorymodel in x86_far_code_models) and
          ((cs_huge_code in current_settings.moduleswitches) or
           (cs_force_far_calls in current_settings.localswitches)) then
@@ -387,8 +387,8 @@ implementation
 
   function tcpuprocdef.is_far: boolean;
     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;
 
 {****************************************************************************

+ 139 - 121
compiler/jvm/agjasmin.pas

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

+ 1 - 0
compiler/jvm/aoptcpu.pas

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

+ 7 - 1
compiler/jvm/cpuinfo.pas

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

+ 2 - 2
compiler/jvm/cpupara.pas

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

+ 2 - 1
compiler/jvm/hlcgcpu.pas

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

+ 14 - 3
compiler/jvm/jvmdef.pas

@@ -290,7 +290,17 @@ implementation
               encodedstr:=encodedstr+c;
             end;
           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 :
             begin
               encodedstr:=encodedstr+'L'+trecorddef(def).jvm_full_typename(true)+';'
@@ -505,6 +515,7 @@ implementation
                 is_open_array(def) or
                 is_array_of_const(def) or
                 is_array_constructor(def);
+          filedef,
           recorddef,
           setdef:
             result:=true;
@@ -919,8 +930,8 @@ implementation
                         begin
                           if tdef(container.defowner).typ<>procdef then
                             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;
                         end;
                     end;

+ 1 - 1
compiler/jvm/njvmcal.pas

@@ -591,7 +591,7 @@ implementation
                   in theory do that, because the parameter nodes have already
                   been bound to the current procdef's parasyms }
                 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;
                 left:=nil;
                 methodpointer:=nil;

+ 32 - 5
compiler/jvm/njvmcnv.pas

@@ -524,7 +524,7 @@ implementation
           with a single #0 }
         result:=ccallnode.create(ccallparanode.create(left,nil),tprocsym(ps),
           ps.owner,
-          cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[]);
+          cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[],nil);
         include(result.flags,nf_isproperty);
         result:=ctypeconvnode.create_explicit(result,resultdef);
         { reused }
@@ -863,7 +863,7 @@ implementation
           { call the (static class) method to get the raw bits }
           result:=ccallnode.create(ccallparanode.create(left,nil),
             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 }
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
@@ -882,7 +882,7 @@ implementation
             internalerror(2011062601);
           result:=ccallnode.create(ccallparanode.create(left,nil),
             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 }
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
@@ -899,7 +899,7 @@ implementation
           if not assigned(psym) or
              (psym.typ<>procsym) then
             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 }
           inserttypeconv_explicit(result,resultdef);
           { left is reused }
@@ -1121,6 +1121,24 @@ implementation
           result:=false;
         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
         fromclasscompatible,
         toclasscompatible: boolean;
@@ -1380,6 +1398,15 @@ implementation
               float(intvalue) will convert rather than re-interpret the value) }
           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 }
         result:=true;
         CGMessage2(type_e_illegal_type_conversion,left.resultdef.typename,resultdef.typename);
@@ -1479,7 +1506,7 @@ implementation
               if not assigned(ps) or
                  (ps.typ<>procsym) then
                 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.right:=nil;
               firstpass(call);

+ 2 - 2
compiler/jvm/njvminl.pas

@@ -595,7 +595,7 @@ implementation
               internalerror(2011031403);
             stringnonnull:=cassignmentnode.create(
               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 }
             stringnull:=cassignmentnode.create(
               ctemprefnode.create(lentemp),
@@ -618,7 +618,7 @@ implementation
               internalerror(2011052402);
             result:=
               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 }
             left:=nil;
           end

+ 1 - 1
compiler/jvm/njvmld.pas

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

+ 2 - 2
compiler/jvm/njvmmem.pas

@@ -332,7 +332,7 @@ implementation
             if not assigned(vs) or
                (tsym(vs).typ<>procsym) then
               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);
             { reused }
             left:=nil;
@@ -385,7 +385,7 @@ implementation
             { Pascal strings are 1-based, Java strings 0-based }
             result:=ccallnode.create(ccallparanode.create(
               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;
             right:=nil;
             exit;

+ 15 - 1
compiler/jvm/njvmutil.pas

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

+ 21 - 21
compiler/jvm/pjvm.pas

@@ -132,7 +132,7 @@ implementation
             while not(topowner.owner.symtabletype in [staticsymtable,globalsymtable]) do
               topowner:=topowner.owner.defowner;
             { create procdef }
-            pd:=cprocdef.create(topowner.owner.symtablelevel+1);
+            pd:=cprocdef.create(topowner.owner.symtablelevel+1,true);
             if df_generic in obj.defoptions then
               include(pd.defoptions,df_generic);
             { method of this objectdef }
@@ -297,7 +297,7 @@ implementation
         { 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
           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;
         include(enumclass.objectoptions,oo_is_enum_class);
         include(enumclass.objectoptions,oo_is_sealed);
@@ -307,11 +307,11 @@ implementation
           name that can be used in generated Pascal code without risking an
           identifier conflict (since it is local to this class; the global name
           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
           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
           will replace the current (real) typesym of that def with the alias }
         temptypesym.typedef:=def;
@@ -343,14 +343,14 @@ implementation
         { create static fields representing all enums }
         for i:=0 to tenumdef(def).symtable.symlist.count-1 do
           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);
             sym:=make_field_static(enumclass.symtable,fsym);
             { add alias for the field representing ordinal(0), for use in
               initialization code }
             if tenumsym(tenumdef(def).symtable.symlist[i]).value=0 then
               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);
                 aliassym.set_raw_mangledname(sym.mangledname);
               end;
@@ -359,7 +359,7 @@ implementation
           (used internally by the JDK) }
         arrdef:=carraydef.create(0,tenumdef(def).symtable.symlist.count-1,s32inttype);
         arrdef.elementdef:=enumclass;
-        arrsym:=ctypesym.create('__FPC_TEnumValues',arrdef);
+        arrsym:=ctypesym.create('__FPC_TEnumValues',arrdef,true);
         enumclass.symtable.insert(arrsym);
         { 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--
@@ -373,12 +373,12 @@ implementation
         if tenumdef(def).has_jumps then
           begin
             { 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);
             tobjectsymtable(enumclass.symtable).addfield(fsym,vis_strictprivate);
             { add class field with hash table that maps from FPC-declared ordinal value -> enum instance }
             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);
             make_field_static(enumclass.symtable,fsym);
             { add custom constructor }
@@ -435,7 +435,7 @@ implementation
           "Values" instance method -- that's also the reason why we insert the
           field only now, because we cannot disable duplicate identifier
           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;
         enumclass.symtable.insert(fsym,false);
         sym:=make_field_static(enumclass.symtable,fsym);
@@ -482,13 +482,13 @@ implementation
         { 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
           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;
         include(pvclass.objectoptions,oo_is_sealed);
         if df_generic in def.defoptions then
           include(pvclass.defoptions,df_generic);
         { 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 }
         if not islocal then
           pvclass.objextname:=stringdup(name)
@@ -511,7 +511,7 @@ implementation
 
         { add local alias for the procvartype that we can use when implementing
           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
           will replace the current (real) typesym of that def with the alias }
         temptypesym.typedef:=def;
@@ -527,12 +527,12 @@ implementation
            not islocal and
            not force_no_callback_intf then
           begin
-            pvintf:=cobjectdef.create(odt_interfacejava,'Callback',nil);
+            pvintf:=cobjectdef.create(odt_interfacejava,'Callback',nil,true);
             pvintf.objextname:=stringdup('Callback');
             if df_generic in def.defoptions then
               include(pvintf.defoptions,df_generic);
             { 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
               in the procvarclass itself) }
@@ -640,10 +640,10 @@ implementation
         wrapperpv.calcparas;
         { no use in creating a callback wrapper here, this procvar type isn't
           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
           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;
         symtablestack.top.insert(typ);
         symtablestack.pop(pd.owner);
@@ -737,7 +737,7 @@ implementation
             begin
               { make sure we don't emit a definition for this field (we'll do
                 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);
               { alias storage to the constsym }
               ssym.set_mangledname(csym.realname);
@@ -775,7 +775,7 @@ implementation
                 has been compiler -> insert a copy in the unit's staticsymtable
               }
               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.pop(current_module.localsymtable);
               { alias storage to the constsym }
@@ -836,8 +836,8 @@ implementation
         visname:=visibilityName[vis];
         replace(visname,' ','_');
         { 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 }
         exclude(result.procoptions,po_external);
         { not virtual/override/abstract/... }

+ 5 - 5
compiler/jvm/symcpu.pas

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

+ 13 - 1
compiler/jvm/tgcpu.pas

@@ -55,7 +55,7 @@ unit tgcpu;
     uses
        verbose,
        cgbase,
-       symconst,symdef,symsym,symcpu,defutil,
+       symconst,symtable,symdef,symsym,symcpu,defutil,
        cpubase,aasmcpu,
        hlcgobj,hlcgcpu;
 
@@ -211,6 +211,18 @@ unit tgcpu;
                   result:=true;
                 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;
 

+ 2 - 2
compiler/link.pas

@@ -1156,7 +1156,7 @@ Implementation
 
     procedure TInternalLinker.ParseScript_Handle;
       var
-        s, para, keyword : String;
+        s{, para}, keyword : String;
         hp : TCmdStrListItem;
         i : longint;
       begin
@@ -1172,7 +1172,7 @@ Implementation
                 continue;
               end;
             keyword:=Upper(GetToken(s,' '));
-            para:=GetToken(s,' ');
+            {para:=}GetToken(s,' ');
             if Trim(s)<>'' then
               Comment(V_Warning,'Unknown part "'+s+'" in "'+hp.str+'" internal linker script');
             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_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) }
         constructor call_size_name_paras(callpd: tdef; dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist);
         { 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);
     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
       here and external }
     taillvmdecl = class(tai)
@@ -156,9 +166,12 @@ interface
       def: tdef;
       sec: TAsmSectiontype;
       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);
+      procedure setsecname(const name: TSymStr);
       destructor destroy; override;
     end;
 
@@ -184,7 +197,7 @@ uses
 
     { 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
         inherited create;
         typ:=ait_llvmdecl;
@@ -194,13 +207,29 @@ uses
         sec:=_sec;
         alignment:=_alignment;
         _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;
 
 
     constructor taillvmdecl.createtls(_namesym: tasmsymbol; _def: tdef; _alignment: shortint);
       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;
 
 
@@ -404,7 +433,7 @@ uses
       begin
         case llvmopcode of
           la_ret, la_br, la_switch, la_indirectbr,
-          la_invoke, la_resume,
+          la_resume,
           la_unreachable,
           la_store,
           la_fence,
@@ -427,7 +456,7 @@ uses
           la_getelementptr,
           la_load,
           la_icmp, la_fcmp,
-          la_phi, la_select, la_call,
+          la_phi, la_select,
           la_va_arg, la_landingpad:
             begin
               if opnr=0 then
@@ -435,6 +464,19 @@ uses
               else
                 result:=operand_read;
             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
             internalerror(2013103101)
         end;
@@ -468,10 +510,18 @@ uses
             end;
           la_invoke, la_call:
             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;
           la_br,
           la_unreachable:
@@ -551,6 +601,12 @@ uses
                   internalerror(2013110110);
               end;
             end;
+          la_blockaddress:
+            case opnr of
+              0: result:=voidcodepointertype
+              else
+                internalerror(2015111904);
+            end
           else
             internalerror(2013103101)
         end;
@@ -896,6 +952,15 @@ uses
         loadconst(index+1,index1);
       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);
       begin
@@ -906,9 +971,9 @@ uses
           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
           is generated, because the alias declaration may occur anywhere }
-        loaddef(0,callpd);
+        loaddef(0,retsize);
         loadreg(1,dst);
-        loaddef(2,retsize);
+        loaddef(2,callpd);
         loadsymbol(3,name,0);
         loadparas(4,paras);
       end;
@@ -918,9 +983,9 @@ uses
       begin
         create_llvm(la_call);
         ops:=5;
-        loaddef(0,callpd);
+        loaddef(0,retsize);
         loadreg(1,dst);
-        loaddef(2,retsize);
+        loaddef(2,callpd);
         loadreg(3,reg);
         loadparas(4,paras);
       end;

+ 241 - 143
compiler/llvm/agllvm.pas

@@ -26,13 +26,18 @@ unit agllvm;
 interface
 
     uses
-      globtype,globals,
+      globtype,globals,systems,
       aasmbase,aasmtai,aasmdata,
       assemble;
 
     type
       TLLVMInstrWriter = class;
-      { TLLVMAssember }
+
+      TLLVMModuleInlineAssemblyDecorator = class(TObject,IExternalAssemblerOutputFileDecorator)
+       function LinePrefix: AnsiString;
+       function LinePostfix: AnsiString;
+       function LineFilter(const s: AnsiString): AnsiString;
+      end;
 
       TLLVMAssember=class(texternalassembler)
       protected
@@ -47,8 +52,7 @@ interface
         procedure WriteOrdConst(hp: tai_const);
         procedure WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
        public
-        constructor create(smart: boolean); override;
-        procedure AsmLn; override;
+        constructor create(info: pasminfo; smart: boolean); override;
         function MakeCmdLine: TCmdStr; override;
         procedure WriteTree(p:TAsmList);override;
         procedure WriteAsmList;override;
@@ -79,7 +83,7 @@ implementation
 
     uses
       SysUtils,
-      cutils,cfileutl,systems,
+      cutils,cfileutl,
       fmodule,verbose,
       aasmcnst,symconst,symdef,symtable,
       llvmbase,aasmllvm,itllvm,llvmdef,
@@ -133,6 +137,42 @@ implementation
       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;
              tmpasmblock:=false;
              hp:=o.ai;
-             owner.AsmWrite(fstr);
+             owner.writer.AsmWrite(fstr);
              fstr:='';
              owner.WriteTai(false,false,tmpinline,tmpasmblock,hp);
              result:='';
@@ -349,7 +389,7 @@ implementation
         (and their output must come after everything that was processed in this
          instruction, such as its opcode or previous operands) }
       if owner.fdecllevel=0 then
-        owner.AsmWrite(#9);
+        owner.writer.AsmWrite(#9);
       sep:=' ';
       done:=false;
       opstart:=0;
@@ -357,9 +397,9 @@ implementation
       case op of
         la_type:
            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;
            end;
         la_ret, la_br, la_switch, la_indirectbr,
@@ -375,13 +415,23 @@ implementation
         la_call:
           begin
             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:=' ';
             opstart:=2;
           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:
           begin
-            owner.AsmWrite(getreferencestring(taillvm(hp).oper[0]^.ref^,false)+' = ');
+            owner.writer.AsmWrite(getreferencestring(taillvm(hp).oper[0]^.ref^,false)+' = ');
             sep:=' ';
             opstart:=1;
           end;
@@ -394,27 +444,27 @@ implementation
               data initialisers }
             if (taillvm(hp).oper[0]^.typ<>top_reg) or
                (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
               nested:=true;
-            owner.AsmWrite(llvm_op2str[op]);
+            owner.writer.AsmWrite(llvm_op2str[op]);
             if not nested then
-              owner.AsmWrite(' ')
+              owner.writer.AsmWrite(' ')
             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
               explicit def operand }
             if taillvm(hp).ops=4 then
               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;
               end
             else
               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;
           end
         else
@@ -422,7 +472,7 @@ implementation
             if (taillvm(hp).oper[0]^.typ<>top_reg) or
                (taillvm(hp).oper[0]^.reg<>NR_NO) then
               begin
-                owner.AsmWrite(getopstr(taillvm(hp).oper[0]^,true)+' = ');
+                owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,true)+' = ');
               end
             else
               nested:=true;
@@ -433,15 +483,15 @@ implementation
       { process operands }
       if not done then
         begin
-          owner.AsmWrite(llvm_op2str[op]);
+          owner.writer.AsmWrite(llvm_op2str[op]);
           if nested then
-            owner.AsmWrite(' (');
+            owner.writer.AsmWrite(' (');
           if taillvm(hp).ops<>0 then
             begin
               for i:=opstart to taillvm(hp).ops-1 do
                 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
                       (op=la_call) then
                      sep :=' '
@@ -451,13 +501,14 @@ implementation
             end;
         end;
       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
-        owner.AsmWrite(')')
-      else
-        owner.AsmLn;
+        owner.writer.AsmWrite(')')
+      else if owner.fdecllevel=0 then
+        owner.writer.AsmLn;
     end;
 
+
 {****************************************************************************}
 {                          LLVM Assembler writer                              }
 {****************************************************************************}
@@ -520,7 +571,7 @@ implementation
     begin
       if not assigned(p) then
        exit;
-      replaceforbidden:=target_asm.dollarsign<>'$';
+      replaceforbidden:=asminfo^.dollarsign<>'$';
 
       InlineLevel:=0;
       asmblock:=false;
@@ -548,12 +599,12 @@ implementation
 
     procedure TLLVMAssember.WriteExtraHeader;
       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;
 
 
@@ -581,32 +632,32 @@ implementation
           begin
             case tai_realconst(hp).realtyp of
               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:
-                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)}
               { can't write full 80 bit floating point constants yet on non-x86 }
               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}
               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
                 internalerror(2014050604);
             end;
           end;
         case hp.realtyp of
           aitrealconst_s32bit:
-            AsmWriteln(llvmdoubletostr(hp.value.s32val));
+            writer.AsmWriteln(llvmdoubletostr(hp.value.s32val));
           aitrealconst_s64bit:
-            AsmWriteln(llvmdoubletostr(hp.value.s64val));
+            writer.AsmWriteln(llvmdoubletostr(hp.value.s64val));
 {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
           aitrealconst_s80bit:
-            AsmWriteln(llvmextendedtostr(hp.value.s80val));
+            writer.AsmWriteln(llvmextendedtostr(hp.value.s80val));
 {$endif defined(cpuextended)}
           aitrealconst_s64comp:
             { handled as int64 most of the time in llvm }
-            AsmWriteln(tostr(round(hp.value.s64compval)));
+            writer.AsmWriteln(tostr(round(hp.value.s64compval)));
           else
             internalerror(2014062401);
         end;
@@ -618,7 +669,7 @@ implementation
         consttyp: taiconst_type;
       begin
         if fdecllevel=0 then
-          asmwrite(target_asm.comment+' const ');
+          writer.AsmWrite(asminfo^.comment+' const ');
         consttyp:=hp.consttype;
         case consttyp of
           aitconst_got,
@@ -642,26 +693,27 @@ implementation
           aitconst_64bit_unaligned:
             begin
               if fdecllevel=0 then
-                AsmWrite(target_asm.comment);
+                writer.AsmWrite(asminfo^.comment);
               { can't have compile-time differences between symbols; these are
                 normally for PIC, but llvm takes care of that for us }
               if assigned(hp.endsym) then
                 internalerror(2014052902);
               if assigned(hp.sym) then
                 begin
-                  AsmWrite(LlvmAsmSymName(hp.sym));
+                  writer.AsmWrite(LlvmAsmSymName(hp.sym));
                   { can't have offsets }
                   if hp.value<>0 then
                     if fdecllevel<>0 then
                       internalerror(2014052903)
                     else
-                      asmwrite(' -- symbol offset: ' + tostr(hp.value));
+                      writer.AsmWrite(' -- symbol offset: ' + tostr(hp.value));
                 end
               else if hp.value=0 then
-                AsmWrite('zeroinitializer')
+                writer.AsmWrite('zeroinitializer')
               else
-                AsmWrite(tostr(hp.value));
-              AsmLn;
+                writer.AsmWrite(tostr(hp.value));
+              if fdecllevel=0 then
+                writer.AsmLn;
             end;
           else
             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 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);
         var
           p: tai_abstracttypedconst;
@@ -683,38 +753,40 @@ implementation
           case hp.adetyp of
             tck_record:
               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
-                  AsmWrite('{');
+                  writer.AsmWrite('{');
                 first:=true;
                 for p in tai_aggregatetypedconst(hp) do
                   begin
                     if not first then
-                      AsmWrite(', ')
+                      writer.AsmWrite(', ')
                     else
                       first:=false;
                     WriteTypedConstData(p);
                   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
-                  AsmWrite('}');
+                  writer.AsmWrite('}');
               end;
             tck_array:
               begin
-                AsmWrite(defstr);
+                writer.AsmWrite(defstr);
                 first:=true;
                 gotstring:=false;
                 for p in tai_aggregatetypedconst(hp) do
                   begin
                     if not first then
-                      AsmWrite(',')
+                      writer.AsmWrite(',')
                     else
                       begin
-                        AsmWrite(' ');
+                        writer.AsmWrite(' ');
                         if (tai_abstracttypedconst(p).adetyp=tck_simple) and
                            (tai_simpletypedconst(p).val.typ=ait_string) then
                           begin
@@ -722,7 +794,7 @@ implementation
                           end
                         else
                           begin
-                            AsmWrite('[');
+                            writer.AsmWrite('[');
                           end;
                         first:=false;
                       end;
@@ -734,15 +806,15 @@ implementation
                     WriteTypedConstData(p);
                   end;
                 if not gotstring then
-                  AsmWrite(']');
+                  writer.AsmWrite(']');
               end;
             tck_simple:
               begin
                 pval:=tai_simpletypedconst(hp).val;
                 if pval.typ<>ait_string then
                   begin
-                    AsmWrite(defstr);
-                    AsmWrite(' ');
+                    writer.AsmWrite(defstr);
+                    writer.AsmWrite(' ');
                   end;
                 WriteTai(replaceforbidden,do_line,InlineLevel,asmblock,pval);
               end;
@@ -758,27 +830,29 @@ implementation
         case hp.typ of
           ait_comment :
             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;
 
           ait_regalloc :
             begin
               if (cs_asm_regalloc in current_settings.globalswitches) then
                 begin
-                  AsmWrite(#9+target_asm.comment+'Register ');
+                  writer.AsmWrite(#9+asminfo^.comment+'Register ');
                   repeat
-                    AsmWrite(std_regname(Tai_regalloc(hp).reg));
+                    writer.AsmWrite(std_regname(Tai_regalloc(hp).reg));
                      if (hp.next=nil) or
                        (tai(hp.next).typ<>ait_regalloc) or
                        (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
                       break;
                     hp:=tai(hp.next);
-                    AsmWrite(',');
+                    writer.AsmWrite(',');
                   until false;
-                  AsmWrite(' ');
-                  AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
+                  writer.AsmWrite(' ');
+                  writer.AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
                 end;
             end;
 
@@ -798,8 +872,8 @@ implementation
 
           ait_datablock :
             begin
-              AsmWrite(target_asm.comment);
-              AsmWriteln('datablock');
+              writer.AsmWrite(asminfo^.comment);
+              writer.AsmWriteln('datablock');
             end;
 
           ait_const:
@@ -815,8 +889,8 @@ implementation
           ait_string :
             begin
               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
                begin
                  ch:=tai_string(hp).str[i-1];
@@ -829,9 +903,9 @@ implementation
                  else
                    s:=ch;
                  end;
-                 AsmWrite(s);
+                 writer.AsmWrite(s);
                end;
-              AsmWriteLn('"');
+              writer.AsmWriteLn('"');
             end;
 
           ait_label :
@@ -848,21 +922,21 @@ implementation
                    begin
                      { should be emitted as part of the variable/function def }
                      //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;
                  if replaceforbidden then
-                   AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
+                   writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
                  else
-                   AsmWrite(tai_label(hp).labsym.name);
-                 AsmWriteLn(':');
+                   writer.AsmWrite(tai_label(hp).labsym.name);
+                 writer.AsmWriteLn(':');
                end;
             end;
 
           ait_symbol :
             begin
               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 }
               if tai_symbol(hp).has_value then
                 internalerror(2014062402);
@@ -871,50 +945,55 @@ implementation
             begin
               if taillvmdecl(hp).def.typ=procdef then
                 begin
-                  if taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL] then
+                  if not(ldf_definition in taillvmdecl(hp).flags) then
                     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
                   else
                     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
               else
                 begin
-                  asmwrite(LlvmAsmSymName(taillvmdecl(hp).namesym));
+                  writer.AsmWrite(LlvmAsmSymName(taillvmdecl(hp).namesym));
                   case taillvmdecl(hp).namesym.bind of
                     AB_EXTERNAL:
-                      asmwrite(' = external ');
+                      writer.AsmWrite(' = external ');
                     AB_COMMON:
-                      asmwrite(' = common ');
+                      writer.AsmWrite(' = common ');
                     AB_LOCAL:
-                      asmwrite(' = internal ');
+                      writer.AsmWrite(' = internal ');
                     AB_GLOBAL:
-                      asmwrite(' = ');
+                      writer.AsmWrite(' = ');
                     AB_WEAK_EXTERNAL:
-                      asmwrite(' = extern_weak ');
+                      writer.AsmWrite(' = extern_weak ');
                     AB_PRIVATE_EXTERN:
-                      asmwrite('= linker_private ');
+                      writer.AsmWrite('= linker_private ');
                     else
                       internalerror(2014020104);
                   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
                       Objective-C }
                   if taillvmdecl(hp).sec in [sec_rodata,sec_rodata_norel] then
-                    asmwrite('unnamed_addr constant ')
+                    writer.AsmWrite('constant ')
                   else
-                    asmwrite('global ');
+                    writer.AsmWrite('global ');
                   if not assigned(taillvmdecl(hp).initdata) then
                     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
-                        asmwrite(' zeroinitializer');
+                        writer.AsmWrite(' zeroinitializer');
                     end
                   else
                     begin
@@ -932,33 +1011,40 @@ implementation
                         end;
                       dec(fdecllevel);
                     end;
+                  { custom section name? }
+                  if taillvmdecl(hp).sec=sec_user then
+                    begin
+                      writer.AsmWrite(', section "');
+                      writer.AsmWrite(taillvmdecl(hp).secname);
+                      writer.AsmWrite('"');
+                    end;
                   { alignment }
-                  asmwrite(', align ');
-                  asmwriteln(tostr(taillvmdecl(hp).alignment));
+                  writer.AsmWrite(', align ');
+                  writer.AsmWriteln(tostr(taillvmdecl(hp).alignment));
                 end;
             end;
           ait_llvmalias:
             begin
-              asmwrite(LlvmAsmSymName(taillvmalias(hp).newsym));
-              asmwrite(' = alias ');
+              writer.AsmWrite(LlvmAsmSymName(taillvmalias(hp).newsym));
+              writer.AsmWrite(' = alias ');
               if taillvmalias(hp).linkage<>lll_default then
                 begin
                   str(taillvmalias(hp).linkage, s);
-                  asmwrite(copy(s, length('lll_')+1, 255));
-                  asmwrite(' ');
+                  writer.AsmWrite(copy(s, length('lll_')+1, 255));
+                  writer.AsmWrite(' ');
                 end;
               if taillvmalias(hp).vis<>llv_default then
                 begin
                   str(taillvmalias(hp).vis, s);
-                  asmwrite(copy(s, length('llv_')+1, 255));
-                  asmwrite(' ');
+                  writer.AsmWrite(copy(s, length('llv_')+1, 255));
+                  writer.AsmWrite(' ');
                 end;
               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
-                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;
           ait_symbolpair:
             begin
@@ -975,9 +1061,9 @@ implementation
           ait_symbol_end :
             begin
               if tai_symbol_end(hp).sym.typ=AT_FUNCTION then
-                asmwriteln('}')
+                writer.AsmWriteln('}')
               else
-                asmwriteln('; ait_symbol_end error, should not be generated');
+                writer.AsmWriteln('; ait_symbol_end error, should not be generated');
 //                internalerror(2013010711);
             end;
 
@@ -1022,8 +1108,10 @@ implementation
             begin
               WriteDirectiveName(tai_directive(hp).directive);
               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;
 
           ait_seh_directive :
@@ -1033,12 +1121,14 @@ implementation
           ait_varloc:
             begin
               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)))
               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)));
-              AsmLn;
+              if fdecllevel<>0 then
+                internalerror(2015090603);
+              writer.AsmLn;
             end;
            ait_typedconst:
              begin
@@ -1050,25 +1140,16 @@ implementation
       end;
 
 
-    constructor TLLVMAssember.create(smart: boolean);
+    constructor TLLVMAssember.create(info: pasminfo; smart: boolean);
       begin
-        inherited create(smart);
+        inherited;
         InstrWriter:=TLLVMInstrWriter.create(self);
       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);
       begin
-        AsmWrite('.'+directivestr[dir]+' ');
+        writer.AsmWrite('.'+directivestr[dir]+' ');
       end;
 
 
@@ -1076,18 +1157,35 @@ implementation
       var
         hal : tasmlisttype;
         i: longint;
+        a: TExternalAssembler;
+        decorator: TLLVMModuleInlineAssemblyDecorator;
       begin
         WriteExtraHeader;
-        AsmStartSize:=AsmSize;
 
         for hal:=low(TasmlistType) to high(TasmlistType) do
           begin
-            AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
-            writetree(current_asmdata.asmlists[hal]);
-            AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
+            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;
 
-        AsmLn;
+        writer.AsmLn;
       end;
 
 

+ 134 - 38
compiler/llvm/hlcgllvm.pas

@@ -51,7 +51,7 @@ uses
       procedure deallocallcpuregisters(list: TAsmList); override;
 
      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
       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;
@@ -94,8 +94,10 @@ uses
       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_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_reg_ref(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const ref: treference; shuffle: pmmshuffle); override;
@@ -151,7 +153,8 @@ implementation
     aasmllvm,llvmbase,tgllvm,
     symtable,symllvm,
     paramgr,llvmpara,
-    procinfo,cpuinfo,cgobj,cgllvm,cghlcpu;
+    procinfo,cpuinfo,cgobj,cgllvm,cghlcpu,
+    cgcpu,hlcgcpu;
 
   const
     topcg2llvmop: array[topcg] of tllvmop =
@@ -256,7 +259,8 @@ implementation
                    OS_F128:
                      a_loadmm_ref_reg(list,location^.def,location^.def,tmpref,location^.register,mms_movescalar);
                    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);
                    else
                      internalerror(2010053101);
@@ -332,7 +336,7 @@ implementation
     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);
       begin
@@ -428,16 +432,6 @@ implementation
     if (pd.typ=procvardef) and
        not pd.is_addressonly then
       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;
 
 
@@ -445,12 +439,11 @@ implementation
     var
       callparas: tfplist;
       llvmretdef,
-      hlretdef,
-      calldef: tdef;
+      hlretdef: tdef;
       res: tregister;
     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);
       set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
     end;
@@ -460,12 +453,11 @@ implementation
     var
       callparas: tfplist;
       llvmretdef,
-      hlretdef,
-      calldef: tdef;
+      hlretdef: tdef;
       res: tregister;
     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);
       set_call_function_result(list,pd,llvmretdef,hlretdef,res,result);
     end;
@@ -529,8 +521,12 @@ implementation
                 truncate it before storing. Unfortunately, we cannot truncate
                 records (nor bitcast them to integers), so we first have to
                 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
                   { store struct/array-in-register to memory }
                   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));
           item:=TCmdStrListItem(item.next);
         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;
 
 
@@ -1140,11 +1136,6 @@ implementation
             LOC_FPUREGISTER,
             LOC_MMREGISTER:
               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
                   via the signext/zeroext modifiers of the result, rather than
                   in the code generator -> remove any explicit extensions here }
@@ -1204,15 +1195,23 @@ implementation
     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
       { 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;
 
 
-  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
+      sref: treference;
       hreg: tregister;
     begin
       hreg:=getaddressregister(list,todef);
@@ -1221,6 +1220,68 @@ implementation
     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);
     var
       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);
     var
+      hreg: tregister;
       rettemp: treference;
     begin
       if not is_void(hlretdef) and
@@ -1603,7 +1665,15 @@ implementation
                 everything to memory rather than potentially dealing with aggregates
                 in "registers" }
               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
                 that the high level code generator expects instead of the llvm shim
               }
@@ -1620,8 +1690,23 @@ implementation
             end
           else
             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.reg:=resval;
               retpara.Location^.llvmvalueloc:=true;
             end;
         end
@@ -1719,8 +1804,19 @@ implementation
 
   procedure create_hlcodegen;
     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;
 
 begin

+ 1 - 0
compiler/llvm/itllvm.pas

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

+ 1 - 0
compiler/llvm/llvmbase.pas

@@ -65,6 +65,7 @@ interface
       la_icmp, la_fcmp,
       la_phi, la_select, la_call,
       la_va_arg, la_landingpad,
+      la_blockaddress,
       { fpc pseudo opcodes }
       la_type, { type definition }
       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+'*'
                 end;
               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_property,
-              odt_interfacecorba,
-              odt_dispinterface,
               odt_objcprotocol:
                 begin
                   { opaque for now }
@@ -610,8 +616,22 @@ implementation
           { sret: hidden pointer for structured function result }
           if vo_is_funcret in hp.varoptions then
             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
-                encodedstr:=encodedstr+' sret'
+                 if first then
+                   encodedstr:=encodedstr+' sret'
+                 else { we can add some other attributes to optimise things,}
+                   encodedstr:=encodedstr+' noalias nocapture';
             end
           else if not paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) and
              llvmbyvalparaloc(paraloc) then
@@ -736,6 +756,8 @@ implementation
                     { other types should not appear currently, add as needed }
                     internalerror(2014012008);
                   end;
+              pointerdef:
+                typename:='p'+tostr(hdef.deflist_index);
               else
                 { other types should not appear currently, add as needed }
                 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
                 passed in registers, in some cases) }
               paraloc^.llvmvalueloc:=false;
-              paraloc^.def:=cpointerdef.getreusable(paraloc^.def);
+              paraloc^.def:=cpointerdef.getreusable_no_free(paraloc^.def);
               paraloc^.size:=def_cgsize(paraloc^.def);
               paraloc^.loc:=LOC_REGISTER;
               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 appendprocdef(list:TAsmList;def:tprocdef);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_file(list:TasmList;def:tfiledef);override;
 
@@ -180,7 +181,7 @@ implementation
         for opidx:=0 to p.ops-1 do
           case p.oper[opidx]^.typ of
             top_def:
-              appenddef(deftypelist,p.oper[opidx]^.def);
+              record_def(p.oper[opidx]^.def);
             top_tai:
               collect_tai_info(deftypelist,p.oper[opidx]^.ai);
             top_ref:
@@ -191,7 +192,7 @@ implementation
                   begin
                     if (opidx=3) and
                        (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 }
                     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);
@@ -201,7 +202,7 @@ implementation
               for paraidx:=0 to p.oper[opidx]^.paras.count-1 do
                 begin
                   callpara:=pllvmcallpara(p.oper[opidx]^.paras[paraidx]);
-                  appenddef(deftypelist,callpara^.def);
+                  record_def(callpara^.def);
                 end;
           end;
       end;
@@ -212,19 +213,21 @@ implementation
         case p.typ of
           ait_llvmalias:
             begin
-              appenddef(deftypelist,taillvmalias(p).def);
+              record_def(taillvmalias(p).def);
               record_asmsym_def(taillvmalias(p).newsym,taillvmalias(p).def,true);
             end;
           ait_llvmdecl:
             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);
               collect_asmlist_info(deftypelist,taillvmdecl(p).initdata);
             end;
           ait_llvmins:
             collect_llvmins_info(deftypelist,taillvm(p));
           ait_typedconst:
-            appenddef(deftypelist,tai_abstracttypedconst(p).def);
+            record_def(tai_abstracttypedconst(p).def);
         end;
       end;
 
@@ -274,11 +277,11 @@ implementation
           la_call:
             if p.oper[3]^.typ=top_ref then
               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);
                 { the type used in the call is different from the type used to
                   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
                     if symdef.typ=procdef then
                       { ugly, but can't use getcopyas(procvardef) due to the
@@ -287,7 +290,7 @@ implementation
                         symtable) and "pointer to procedure" results in the
                         correct llvm type }
                       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);
                   end;
               end;
@@ -420,7 +423,7 @@ implementation
               sec:=sec_code
             else
               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);
           end;
       end;
@@ -472,7 +475,7 @@ implementation
       begin
         symdeflist:=tabstractrecordsymtable(def.symtable).llvmst.symdeflist;
         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
           list.concat(taillvm.op_size(LA_TYPE,record_def(def)));
       end;
@@ -666,7 +669,16 @@ implementation
 
     procedure TLLVMTypeInfo.appenddef_object(list:TAsmList;def: tobjectdef);
       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;
 
 

+ 56 - 6
compiler/llvm/nllvmcnv.pas

@@ -33,6 +33,7 @@ interface
          protected
           function first_int_to_real: tnode; override;
           function first_int_to_bool: tnode; override;
+          function first_nil_to_methodprocvar: tnode; override;
           procedure second_int_to_int;override;
          { procedure second_string_to_string;override; }
          { procedure second_cstring_to_pchar;override; }
@@ -44,7 +45,8 @@ interface
          procedure second_int_to_real;override;
          { procedure second_real_to_real;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_int_to_bool;override;
          { procedure second_load_smallset;override;  }
@@ -63,7 +65,7 @@ uses
   llvmbase,aasmllvm,
   procinfo,
   symconst,symtype,symdef,defutil,
-  cgbase,cgutils,hlcgobj,pass_2;
+  cgbase,cgutils,tgobj,hlcgobj,pass_2;
 
 { tllvmtypeconvnode }
 
@@ -78,7 +80,20 @@ function tllvmtypeconvnode.first_int_to_bool: tnode;
   begin
     result:=inherited;
     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;
 
 
@@ -122,15 +137,50 @@ procedure tllvmtypeconvnode.second_pointer_to_array;
 procedure tllvmtypeconvnode.second_int_to_real;
   var
     op: tllvmop;
+    llvmtodef: tdef;
   begin
     if is_signed(left.resultdef) then
       op:=la_sitofp
     else
       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);
-    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;
 
 

+ 95 - 2
compiler/llvm/nllvminl.pas

@@ -33,8 +33,11 @@ interface
       tllvminlinenode = class(tcginlinenode)
        protected
         function first_get_frame: tnode; override;
+        function first_abs_real: tnode; override;
+        function first_sqr_real: tnode; override;
        public
         procedure second_length; override;
+        procedure second_sqr_real; override;
       end;
 
 
@@ -44,10 +47,11 @@ implementation
        verbose,globtype,constexp,
        aasmbase, aasmdata,
        symtype,symdef,defutil,
-       ncal,ncon,ninl,
+       nutils,nadd,nbas,ncal,ncon,nflw,ninl,nld,nmat,
        pass_2,
        cgbase,cgutils,tgobj,hlcgobj,
-       cpubase;
+       cpubase,
+       llvmbase,aasmllvm;
 
 
      function tllvminlinenode.first_get_frame: tnode;
@@ -56,6 +60,72 @@ implementation
            ccallparanode.create(genintconstnode(0),nil));
        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;
       var
@@ -113,6 +183,29 @@ implementation
          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
   cinlinenode:=tllvminlinenode;
 end.

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio