ソースを参照

* synchronised with trunk till r40348

git-svn-id: branches/debug_eh@40349 -
Jonas Maebe 6 年 前
コミット
bfc7c58a69
100 ファイル変更903 行追加711 行削除
  1. 13 1
      .gitattributes
  2. 9 6
      compiler/Makefile
  3. 11 7
      compiler/Makefile.fpc
  4. 4 3
      compiler/aarch64/aasmcpu.pas
  5. 0 2
      compiler/aarch64/aoptcpu.pas
  6. 0 4
      compiler/aarch64/aoptcpub.pas
  7. 1 4
      compiler/aarch64/cgcpu.pas
  8. 0 1
      compiler/aarch64/ncpucnv.pas
  9. 0 1
      compiler/aarch64/ncpuinl.pas
  10. 0 1
      compiler/aarch64/racpugas.pas
  11. 0 1
      compiler/aasmcnst.pas
  12. 28 2
      compiler/aasmtai.pas
  13. 40 11
      compiler/aggas.pas
  14. 6 6
      compiler/aoptobj.pas
  15. 12 1
      compiler/aoptutils.pas
  16. 3 2
      compiler/arm/aasmcpu.pas
  17. 17 2
      compiler/arm/aoptcpu.pas
  18. 0 4
      compiler/arm/aoptcpub.pas
  19. 26 6
      compiler/arm/cgcpu.pas
  20. 3 3
      compiler/arm/cpubase.pas
  21. 1 0
      compiler/arm/cpunode.pas
  22. 8 0
      compiler/arm/cpupi.pas
  23. 97 0
      compiler/arm/narmld.pas
  24. 7 0
      compiler/assemble.pas
  25. 15 15
      compiler/avr/aoptcpu.pas
  26. 0 4
      compiler/avr/aoptcpub.pas
  27. 1 1
      compiler/avr/cpubase.pas
  28. 101 97
      compiler/avr/raavr.pas
  29. 76 77
      compiler/cclasses.pas
  30. 2 2
      compiler/cfileutl.pas
  31. 10 2
      compiler/cgbase.pas
  32. 30 4
      compiler/cgobj.pas
  33. 9 2
      compiler/cutils.pas
  34. 1 1
      compiler/dbgdwarf.pas
  35. 3 3
      compiler/entfile.pas
  36. 8 1
      compiler/globals.pas
  37. 10 1
      compiler/globtype.pas
  38. 4 3
      compiler/hlcgobj.pas
  39. 15 2
      compiler/htypechk.pas
  40. 8 223
      compiler/i386/aoptcpu.pas
  41. 0 4
      compiler/i386/aoptcpub.pas
  42. 8 1
      compiler/i386/cpupi.pas
  43. 3 5
      compiler/i386/n386flw.pas
  44. 0 4
      compiler/i8086/aoptcpub.pas
  45. 4 0
      compiler/i8086/cgcpu.pas
  46. 0 4
      compiler/jvm/aoptcpub.pas
  47. 2 2
      compiler/llvm/nllvmmem.pas
  48. 10 3
      compiler/m68k/aoptcpu.pas
  49. 0 4
      compiler/m68k/aoptcpub.pas
  50. 3 0
      compiler/m68k/cgcpu.pas
  51. 5 5
      compiler/machoutils.pas
  52. 0 4
      compiler/mips/aoptcpub.pas
  53. 1 1
      compiler/msg/errorct.msg
  54. 1 1
      compiler/msg/errord.msg
  55. 1 1
      compiler/msg/errorda.msg
  56. 1 1
      compiler/msg/errordu.msg
  57. 1 1
      compiler/msg/errore.msg
  58. 1 1
      compiler/msg/errores.msg
  59. 1 1
      compiler/msg/errorf.msg
  60. 1 1
      compiler/msg/errorfi.msg
  61. 1 1
      compiler/msg/errorhe.msg
  62. 1 1
      compiler/msg/errorheu.msg
  63. 1 1
      compiler/msg/errorid.msg
  64. 1 1
      compiler/msg/erroriu.msg
  65. 1 1
      compiler/msg/errorn.msg
  66. 1 1
      compiler/msg/errorpl.msg
  67. 1 1
      compiler/msg/errorpli.msg
  68. 1 1
      compiler/msg/errorpt.msg
  69. 1 1
      compiler/msg/errorptu.msg
  70. 1 1
      compiler/msg/errorr.msg
  71. 1 1
      compiler/msg/errorru.msg
  72. 1 1
      compiler/msg/errorues.msg
  73. 1 1
      compiler/msgidx.inc
  74. 1 1
      compiler/msgtxt.inc
  75. 4 6
      compiler/nadd.pas
  76. 37 1
      compiler/nbas.pas
  77. 42 12
      compiler/ncal.pas
  78. 16 0
      compiler/ncgbas.pas
  79. 10 9
      compiler/ncgflw.pas
  80. 2 2
      compiler/ncgld.pas
  81. 1 1
      compiler/ncgmem.pas
  82. 15 20
      compiler/ncgrtti.pas
  83. 5 16
      compiler/nflw.pas
  84. 1 1
      compiler/ngtcon.pas
  85. 12 4
      compiler/ninl.pas
  86. 6 2
      compiler/nld.pas
  87. 1 1
      compiler/nmem.pas
  88. 4 2
      compiler/node.pas
  89. 8 3
      compiler/nutils.pas
  90. 0 1
      compiler/ogbase.pas
  91. 18 9
      compiler/omfbase.pas
  92. 1 1
      compiler/optbase.pas
  93. 1 0
      compiler/optdfa.pas
  94. 10 1
      compiler/options.pas
  95. 11 20
      compiler/optutils.pas
  96. 4 0
      compiler/owomflib.pas
  97. 6 2
      compiler/pass_2.pas
  98. 3 0
      compiler/pdecl.pas
  99. 1 2
      compiler/pdecsub.pas
  100. 48 31
      compiler/pdecvar.pas

+ 13 - 1
.gitattributes

@@ -85,6 +85,7 @@ compiler/arm/narmcal.pas svneol=native#text/plain
 compiler/arm/narmcnv.pas svneol=native#text/plain
 compiler/arm/narmcnv.pas svneol=native#text/plain
 compiler/arm/narmcon.pas svneol=native#text/plain
 compiler/arm/narmcon.pas svneol=native#text/plain
 compiler/arm/narminl.pas svneol=native#text/plain
 compiler/arm/narminl.pas svneol=native#text/plain
+compiler/arm/narmld.pas svneol=native#text/pascal
 compiler/arm/narmmat.pas svneol=native#text/plain
 compiler/arm/narmmat.pas svneol=native#text/plain
 compiler/arm/narmmem.pas svneol=native#text/plain
 compiler/arm/narmmem.pas svneol=native#text/plain
 compiler/arm/narmset.pas svneol=native#text/plain
 compiler/arm/narmset.pas svneol=native#text/plain
@@ -6995,6 +6996,7 @@ packages/pastojs/src/pas2jscompiler.pp svneol=native#text/plain
 packages/pastojs/src/pas2jsfilecache.pp svneol=native#text/plain
 packages/pastojs/src/pas2jsfilecache.pp svneol=native#text/plain
 packages/pastojs/src/pas2jsfiler.pp svneol=native#text/plain
 packages/pastojs/src/pas2jsfiler.pp svneol=native#text/plain
 packages/pastojs/src/pas2jsfileutils.pp svneol=native#text/plain
 packages/pastojs/src/pas2jsfileutils.pp svneol=native#text/plain
+packages/pastojs/src/pas2jsfileutilsnodejs.inc svneol=native#text/plain
 packages/pastojs/src/pas2jsfileutilsunix.inc svneol=native#text/plain
 packages/pastojs/src/pas2jsfileutilsunix.inc svneol=native#text/plain
 packages/pastojs/src/pas2jsfileutilswin.inc svneol=native#text/plain
 packages/pastojs/src/pas2jsfileutilswin.inc svneol=native#text/plain
 packages/pastojs/src/pas2jslibcompiler.pp svneol=native#text/plain
 packages/pastojs/src/pas2jslibcompiler.pp svneol=native#text/plain
@@ -11062,6 +11064,13 @@ tests/tbf/tb0256.pp svneol=native#text/pascal
 tests/tbf/tb0257a.pp svneol=native#text/pascal
 tests/tbf/tb0257a.pp svneol=native#text/pascal
 tests/tbf/tb0257b.pp svneol=native#text/pascal
 tests/tbf/tb0257b.pp svneol=native#text/pascal
 tests/tbf/tb0258.pp svneol=native#text/pascal
 tests/tbf/tb0258.pp svneol=native#text/pascal
+tests/tbf/tb0259.pp svneol=native#text/plain
+tests/tbf/tb0260.pp svneol=native#text/plain
+tests/tbf/tb0261.pp svneol=native#text/pascal
+tests/tbf/tb0262.pp svneol=native#text/pascal
+tests/tbf/tb0263.pp svneol=native#text/pascal
+tests/tbf/tb0264.pp svneol=native#text/pascal
+tests/tbf/tb0265.pp svneol=native#text/pascal
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
@@ -11721,6 +11730,7 @@ tests/tbs/tb0649.pp -text svneol=native#text/pascal
 tests/tbs/tb0650.pp svneol=native#text/pascal
 tests/tbs/tb0650.pp svneol=native#text/pascal
 tests/tbs/tb0651.pp svneol=native#text/pascal
 tests/tbs/tb0651.pp svneol=native#text/pascal
 tests/tbs/tb0652.pp svneol=native#text/pascal
 tests/tbs/tb0652.pp svneol=native#text/pascal
+tests/tbs/tb0653.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb610.pp svneol=native#text/pascal
 tests/tbs/tb610.pp svneol=native#text/pascal
 tests/tbs/tb613.pp svneol=native#text/plain
 tests/tbs/tb613.pp svneol=native#text/plain
@@ -14654,6 +14664,7 @@ tests/webtbf/tw2739.pp svneol=native#text/plain
 tests/webtbf/tw2751.pp svneol=native#text/plain
 tests/webtbf/tw2751.pp svneol=native#text/plain
 tests/webtbf/tw2752.pp svneol=native#text/plain
 tests/webtbf/tw2752.pp svneol=native#text/plain
 tests/webtbf/tw2787.pp svneol=native#text/plain
 tests/webtbf/tw2787.pp svneol=native#text/plain
+tests/webtbf/tw27880.pp svneol=native#text/pascal
 tests/webtbf/tw2795.pp svneol=native#text/plain
 tests/webtbf/tw2795.pp svneol=native#text/plain
 tests/webtbf/tw28338.pp svneol=native#text/plain
 tests/webtbf/tw28338.pp svneol=native#text/plain
 tests/webtbf/tw28355.pp svneol=native#text/plain
 tests/webtbf/tw28355.pp svneol=native#text/plain
@@ -16028,7 +16039,6 @@ tests/webtbs/tw2780.pp svneol=native#text/plain
 tests/webtbs/tw27811.pp svneol=native#text/plain
 tests/webtbs/tw27811.pp svneol=native#text/plain
 tests/webtbs/tw27832.pp svneol=native#text/plain
 tests/webtbs/tw27832.pp svneol=native#text/plain
 tests/webtbs/tw2788.pp svneol=native#text/plain
 tests/webtbs/tw2788.pp svneol=native#text/plain
-tests/webtbs/tw27880.pp svneol=native#text/plain
 tests/webtbs/tw2789.pp svneol=native#text/plain
 tests/webtbs/tw2789.pp svneol=native#text/plain
 tests/webtbs/tw2794.pp svneol=native#text/plain
 tests/webtbs/tw2794.pp svneol=native#text/plain
 tests/webtbs/tw27998.pp svneol=native#text/plain
 tests/webtbs/tw27998.pp svneol=native#text/plain
@@ -16407,8 +16417,10 @@ tests/webtbs/tw3433.pp svneol=native#text/plain
 tests/webtbs/tw34332.pp svneol=native#text/pascal
 tests/webtbs/tw34332.pp svneol=native#text/pascal
 tests/webtbs/tw3435.pp svneol=native#text/plain
 tests/webtbs/tw3435.pp svneol=native#text/plain
 tests/webtbs/tw34380.pp svneol=native#text/plain
 tests/webtbs/tw34380.pp svneol=native#text/plain
+tests/webtbs/tw34385.pp svneol=native#text/plain
 tests/webtbs/tw3441.pp svneol=native#text/plain
 tests/webtbs/tw3441.pp svneol=native#text/plain
 tests/webtbs/tw3443.pp svneol=native#text/plain
 tests/webtbs/tw3443.pp svneol=native#text/plain
+tests/webtbs/tw34438.pp svneol=native#text/pascal
 tests/webtbs/tw3444.pp svneol=native#text/plain
 tests/webtbs/tw3444.pp svneol=native#text/plain
 tests/webtbs/tw34442.pp svneol=native#text/plain
 tests/webtbs/tw34442.pp svneol=native#text/plain
 tests/webtbs/tw3456.pp svneol=native#text/plain
 tests/webtbs/tw3456.pp svneol=native#text/plain

+ 9 - 6
compiler/Makefile

@@ -4220,6 +4220,7 @@ else
 INSTALLEXEFILE=$(EXENAME)
 INSTALLEXEFILE=$(EXENAME)
 endif
 endif
 PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 mips mipsel avr jvm i8086 aarch64 sparc64 riscv32 riscv64
 PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 mips mipsel avr jvm i8086 aarch64 sparc64 riscv32 riscv64
+PPC_SUFFIXES=386 68k ppc sparc arm armeb x64 ppc64 mips mipsel avr jvm 8086 a64 sparc64 rv32 rv64
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 SYMLINKINSTALL_TARGETS=$(addsuffix _symlink_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 SYMLINKINSTALL_TARGETS=$(addsuffix _symlink_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS)$(SYMLINKINSTALL_TARGETS)
 .PHONY: $(PPC_TARGETS) $(INSTALL_TARGETS)$(SYMLINKINSTALL_TARGETS)
@@ -4258,16 +4259,14 @@ ppuclean:
 tempclean:
 tempclean:
 	-$(DEL) $(PPCROSSNAME) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC) pp1.wpo pp2.wpo
 	-$(DEL) $(PPCROSSNAME) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC) pp1.wpo pp2.wpo
 execlean :
 execlean :
-	-$(DEL) ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcsparc64$(EXEEXT)
-	-$(DEL) ppcarm$(EXEEXT) ppcavr$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) ppca64$(EXEEXT)
-	-$(DEL) ppcross386$(EXEEXT) ppcross68k$(EXEEXT) ppcrossx64$(EXEEXT) ppcrossppc$(EXEEXT) ppcrosssparc$(EXEEXT) ppcrossppc64$(EXEEXT) ppcrosssparc64$(EXEEXT)
-	-$(DEL) ppcrossarm$(EXEEXT) ppcrossavr$(EXEEXT) ppcrossmips$(EXEEXT) ppcrossmipsel$(EXEEXT) ppcrossjvm$(EXEEXT) ppcross8086$(EXEEXT) ppcrossa64$(EXEEXT)
+	-$(DEL) $(addsuffix $(EXEEXT), $(addprefix ppc, $(PPC_SUFFIXES)))
+	-$(DEL) $(addsuffix $(EXEEXT), $(addprefix ppcross, $(PPC_SUFFIXES)))
 	-$(DEL) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2)
 	-$(DEL) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2)
 $(addsuffix _clean,$(ALLTARGETS)):
 $(addsuffix _clean,$(ALLTARGETS)):
 	-$(DELTREE) $(addprefix $(subst _clean,,$@),/units)
 	-$(DELTREE) $(addprefix $(subst _clean,,$@),/units)
+	-$(DELTREE) $(addprefix $(subst _clean,,$@),/bin)
 	-$(DEL) $(addprefix $(subst _clean,,$@)/,*$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT))
 	-$(DEL) $(addprefix $(subst _clean,,$@)/,*$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT))
-	-$(DEL) $(addprefix $(subst _clean,,$@)/,ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcarv$(EXEEXT) ppcsparc64$(EXEEXT))
-	-$(DEL) $(addprefix $(subst _clean,,$@)/,ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) ppca64$(EXEEXT) $(EXENAME))
+	-$(DEL) $(addprefix $(subst _clean,,$@)/ppc,$(addsuffix $(EXEEXT), $(PPC_SUFFIXES)))
 cycleclean: cleanall $(addsuffix _clean,$(CPC_TARGET))
 cycleclean: cleanall $(addsuffix _clean,$(CPC_TARGET))
 	-$(DEL) $(EXENAME)
 	-$(DEL) $(EXENAME)
 clean: tempclean execlean cleanall $(addsuffix _clean,$(CPC_TARGET)) $(addsuffix _clean,$(TARGET_DIRS))
 clean: tempclean execlean cleanall $(addsuffix _clean,$(CPC_TARGET)) $(addsuffix _clean,$(TARGET_DIRS))
@@ -4482,6 +4481,10 @@ fullcycle:
 	$(MAKE) distclean
 	$(MAKE) distclean
 	$(MAKE) cycle
 	$(MAKE) cycle
 	$(MAKE) ppuclean
 	$(MAKE) ppuclean
+ifdef DOWPOCYCLE
+	$(MAKE) rtlclean
+	$(MAKE) rtl 'FPC=$(BASEDIR)/$(EXENAME)'
+endif
 ifndef EXCLUDE_80BIT_TARGETS
 ifndef EXCLUDE_80BIT_TARGETS
 	$(MAKE) $(filter-out $(PPC_TARGET),$(CYCLETARGETS)) 'FPC=$(BASEDIR)/$(EXENAME)'
 	$(MAKE) $(filter-out $(PPC_TARGET),$(CYCLETARGETS)) 'FPC=$(BASEDIR)/$(EXENAME)'
 else
 else

+ 11 - 7
compiler/Makefile.fpc

@@ -455,6 +455,7 @@ endif
 #####################################################################
 #####################################################################
 
 
 PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 mips mipsel avr jvm i8086 aarch64 sparc64 riscv32 riscv64
 PPC_TARGETS=i386 m68k powerpc sparc arm armeb x86_64 powerpc64 mips mipsel avr jvm i8086 aarch64 sparc64 riscv32 riscv64
+PPC_SUFFIXES=386 68k ppc sparc arm armeb x64 ppc64 mips mipsel avr jvm 8086 a64 sparc64 rv32 rv64
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 INSTALL_TARGETS=$(addsuffix _exe_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 SYMLINKINSTALL_TARGETS=$(addsuffix _symlink_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 SYMLINKINSTALL_TARGETS=$(addsuffix _symlink_install,$(sort $(CYCLETARGETS) $(PPC_TARGETS)))
 
 
@@ -513,17 +514,15 @@ tempclean:
 	-$(DEL) $(PPCROSSNAME) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC) pp1.wpo pp2.wpo
 	-$(DEL) $(PPCROSSNAME) $(TEMPNAME) $(TEMPNAME1) $(TEMPNAME2) $(TEMPNAME3) $(MSG2INC) pp1.wpo pp2.wpo
 
 
 execlean :
 execlean :
-	-$(DEL) ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcppc64$(EXEEXT) ppcsparc64$(EXEEXT)
-	-$(DEL) ppcarm$(EXEEXT) ppcavr$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) ppca64$(EXEEXT)
-	-$(DEL) ppcross386$(EXEEXT) ppcross68k$(EXEEXT) ppcrossx64$(EXEEXT) ppcrossppc$(EXEEXT) ppcrosssparc$(EXEEXT) ppcrossppc64$(EXEEXT) ppcrosssparc64$(EXEEXT)
-	-$(DEL) ppcrossarm$(EXEEXT) ppcrossavr$(EXEEXT) ppcrossmips$(EXEEXT) ppcrossmipsel$(EXEEXT) ppcrossjvm$(EXEEXT) ppcross8086$(EXEEXT) ppcrossa64$(EXEEXT)
+	-$(DEL) $(addsuffix $(EXEEXT), $(addprefix ppc, $(PPC_SUFFIXES)))
+	-$(DEL) $(addsuffix $(EXEEXT), $(addprefix ppcross, $(PPC_SUFFIXES)))
 	-$(DEL) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2)
 	-$(DEL) $(EXENAME) $(TEMPWPONAME1) $(TEMPWPONAME2)
 
 
 $(addsuffix _clean,$(ALLTARGETS)):
 $(addsuffix _clean,$(ALLTARGETS)):
         -$(DELTREE) $(addprefix $(subst _clean,,$@),/units)
         -$(DELTREE) $(addprefix $(subst _clean,,$@),/units)
+        -$(DELTREE) $(addprefix $(subst _clean,,$@),/bin)
         -$(DEL) $(addprefix $(subst _clean,,$@)/,*$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT))
         -$(DEL) $(addprefix $(subst _clean,,$@)/,*$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT))
-        -$(DEL) $(addprefix $(subst _clean,,$@)/,ppc386$(EXEEXT) ppc68k$(EXEEXT) ppcx64$(EXEEXT) ppcppc$(EXEEXT) ppcsparc$(EXEEXT) ppcarv$(EXEEXT) ppcsparc64$(EXEEXT))
-        -$(DEL) $(addprefix $(subst _clean,,$@)/,ppcppc64$(EXEEXT) ppcarm$(EXEEXT) ppcmips$(EXEEXT) ppcmipsel$(EXEEXT) ppcjvm$(EXEEXT) ppc8086$(EXEEXT) ppca64$(EXEEXT) $(EXENAME))
+        -$(DEL) $(addprefix $(subst _clean,,$@)/ppc,$(addsuffix $(EXEEXT), $(PPC_SUFFIXES)))
 
 
 cycleclean: cleanall $(addsuffix _clean,$(CPC_TARGET))
 cycleclean: cleanall $(addsuffix _clean,$(CPC_TARGET))
         -$(DEL) $(EXENAME)
         -$(DEL) $(EXENAME)
@@ -831,7 +830,8 @@ cvstest:
 #
 #
 # 1. build a compiler using cycle
 # 1. build a compiler using cycle
 # 2. remove all .ppufiles
 # 2. remove all .ppufiles
-# 3. build all supported cross compilers except the
+# 3. clean and recompile rtl if DOWPOCYCLE is set
+# 4. build all supported cross compilers except the
 #    current PPC_TARGET which was already build
 #    current PPC_TARGET which was already build
 # unless FPC_SUPPORT_X87_TYPES_ON_WIN64 is set,
 # unless FPC_SUPPORT_X87_TYPES_ON_WIN64 is set,
 # win64 cannot compile i386 or i8086 compiler
 # win64 cannot compile i386 or i8086 compiler
@@ -852,6 +852,10 @@ fullcycle:
         $(MAKE) distclean
         $(MAKE) distclean
         $(MAKE) cycle
         $(MAKE) cycle
         $(MAKE) ppuclean
         $(MAKE) ppuclean
+ifdef DOWPOCYCLE
+        $(MAKE) rtlclean
+        $(MAKE) rtl 'FPC=$(BASEDIR)/$(EXENAME)'
+endif
 ifndef EXCLUDE_80BIT_TARGETS
 ifndef EXCLUDE_80BIT_TARGETS
         $(MAKE) $(filter-out $(PPC_TARGET),$(CYCLETARGETS)) 'FPC=$(BASEDIR)/$(EXENAME)'
         $(MAKE) $(filter-out $(PPC_TARGET),$(CYCLETARGETS)) 'FPC=$(BASEDIR)/$(EXENAME)'
 else
 else

+ 4 - 3
compiler/aarch64/aasmcpu.pas

@@ -592,7 +592,6 @@ implementation
 
 
     function simple_ref_type(op: tasmop; size:tcgsize; oppostfix: toppostfix; const ref: treference): tsimplereftype;
     function simple_ref_type(op: tasmop; size:tcgsize; oppostfix: toppostfix; const ref: treference): tsimplereftype;
       var
       var
-        maxoffs: asizeint;
         accesssize: longint;
         accesssize: longint;
       begin
       begin
         result:=sr_internal_illegal;
         result:=sr_internal_illegal;
@@ -922,8 +921,8 @@ implementation
 
 
 
 
     procedure BuildInsTabCache;
     procedure BuildInsTabCache;
-      var
-        i : longint;
+//      var
+//        i : longint;
       begin
       begin
 (*        new(instabcache);
 (*        new(instabcache);
         FillChar(instabcache^,sizeof(tinstabcache),$ff);
         FillChar(instabcache^,sizeof(tinstabcache),$ff);
@@ -1006,6 +1005,7 @@ implementation
 *)
 *)
 
 
     procedure insertpcrelativedata(list,listtoinsert : TAsmList);
     procedure insertpcrelativedata(list,listtoinsert : TAsmList);
+(*
       var
       var
         curinspos,
         curinspos,
         penalty,
         penalty,
@@ -1021,6 +1021,7 @@ implementation
         l : tasmlabel;
         l : tasmlabel;
         doinsert,
         doinsert,
         removeref : boolean;
         removeref : boolean;
+*)
       begin
       begin
 (*
 (*
         curdata:=TAsmList.create;
         curdata:=TAsmList.create;

+ 0 - 2
compiler/aarch64/aoptcpu.pas

@@ -146,8 +146,6 @@ Implementation
 
 
 
 
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
   function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
-    var
-      next1: tai;
     begin
     begin
       result := false;
       result := false;
       if p.typ=ait_instruction then
       if p.typ=ait_instruction then

+ 0 - 4
compiler/aarch64/aoptcpub.pas

@@ -76,10 +76,6 @@ Const
 
 
   MaxCh = 3;
   MaxCh = 3;
 
 
-{ the maximum number of operands an instruction has }
-
-  MaxOps = 4;
-
 {Oper index of operand that contains the source (reference) with a load }
 {Oper index of operand that contains the source (reference) with a load }
 {instruction                                                            }
 {instruction                                                            }
 
 

+ 1 - 4
compiler/aarch64/cgcpu.pas

@@ -1127,18 +1127,15 @@ implementation
 
 
     procedure tcgaarch64.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister);
     procedure tcgaarch64.a_bit_scan_reg_reg(list: TAsmList; reverse: boolean; srcsize, dstsize: tcgsize; src, dst: TRegister);
       var
       var
-        bitsize,
-        signbit: longint;
+        bitsize: longint;
       begin
       begin
         if srcsize in [OS_64,OS_S64] then
         if srcsize in [OS_64,OS_S64] then
           begin
           begin
             bitsize:=64;
             bitsize:=64;
-            signbit:=6;
           end
           end
         else
         else
           begin
           begin
             bitsize:=32;
             bitsize:=32;
-            signbit:=5;
           end;
           end;
         { source is 0 -> dst will have to become 255 }
         { source is 0 -> dst will have to become 255 }
         list.concat(taicpu.op_reg_const(A_CMP,src,0));
         list.concat(taicpu.op_reg_const(A_CMP,src,0));

+ 0 - 1
compiler/aarch64/ncpucnv.pas

@@ -142,7 +142,6 @@ implementation
   procedure taarch64typeconvnode.second_int_to_bool;
   procedure taarch64typeconvnode.second_int_to_bool;
     var
     var
       resflags: tresflags;
       resflags: tresflags;
-      hlabel: tasmlabel;
     begin
     begin
       if (nf_explicit in flags) and
       if (nf_explicit in flags) and
          not(left.expectloc in [LOC_FLAGS,LOC_JUMP]) then
          not(left.expectloc in [LOC_FLAGS,LOC_JUMP]) then

+ 0 - 1
compiler/aarch64/ncpuinl.pas

@@ -128,7 +128,6 @@ implementation
     procedure taarch64inlinenode.second_abs_long;
     procedure taarch64inlinenode.second_abs_long;
       var
       var
         opsize : tcgsize;
         opsize : tcgsize;
-        hp : taicpu;
       begin
       begin
         secondpass(left);
         secondpass(left);
         opsize:=def_cgsize(left.resultdef);
         opsize:=def_cgsize(left.resultdef);

+ 0 - 1
compiler/aarch64/racpugas.pas

@@ -933,7 +933,6 @@ Unit racpugas;
         j  : longint;
         j  : longint;
         hs : string;
         hs : string;
         maxlen : longint;
         maxlen : longint;
-        icond : tasmcond;
       Begin
       Begin
         { making s a value parameter would break other assembler readers }
         { making s a value parameter would break other assembler readers }
         hs:=s;
         hs:=s;

+ 0 - 1
compiler/aasmcnst.pas

@@ -1726,7 +1726,6 @@ implementation
    function ttai_typedconstbuilder.begin_dynarray_const(arrdef:tdef;var startlab:tasmlabel;out arrlengthloc:ttypedconstplaceholder):tasmlabofs;
    function ttai_typedconstbuilder.begin_dynarray_const(arrdef:tdef;var startlab:tasmlabel;out arrlengthloc:ttypedconstplaceholder):tasmlabofs;
      var
      var
        dynarray_symofs: asizeint;
        dynarray_symofs: asizeint;
-       elesize: word;
      begin
      begin
        result.lab:=startlab;
        result.lab:=startlab;
        result.ofs:=0;
        result.ofs:=0;

+ 28 - 2
compiler/aasmtai.pas

@@ -145,7 +145,11 @@ interface
           { offset of symbol's GOT slot in GOT }
           { offset of symbol's GOT slot in GOT }
           aitconst_got,
           aitconst_got,
           { offset of symbol itself from GOT }
           { offset of symbol itself from GOT }
-          aitconst_gotoff_symbol
+          aitconst_gotoff_symbol,
+          { ARM TLS code }
+          aitconst_gottpoff,
+          aitconst_tpoff
+
         );
         );
 
 
         tairealconsttype = (
         tairealconsttype = (
@@ -852,11 +856,13 @@ interface
         { alignment for operator }
         { alignment for operator }
         tai_align_abstract = class(tai)
         tai_align_abstract = class(tai)
            aligntype : byte;   { 1 = no align, 2 = word align, 4 = dword align }
            aligntype : byte;   { 1 = no align, 2 = word align, 4 = dword align }
+           maxbytes  : byte;   { if needed bytes would be larger than maxbyes, alignment is ignored }
            fillsize  : byte;   { real size to fill }
            fillsize  : byte;   { real size to fill }
            fillop    : byte;   { value to fill with - optional }
            fillop    : byte;   { value to fill with - optional }
            use_op    : boolean;
            use_op    : boolean;
            constructor Create(b:byte);virtual;
            constructor Create(b:byte);virtual;
            constructor Create_op(b: byte; _op: byte);virtual;
            constructor Create_op(b: byte; _op: byte);virtual;
+           constructor create_max(b: byte; max: byte);virtual;
            constructor Create_zeros(b:byte);
            constructor Create_zeros(b:byte);
            constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
            constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
            procedure ppuwrite(ppufile:tcompilerppufile);override;
            procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -1757,7 +1763,7 @@ implementation
       end;
       end;
 
 
 
 
-    constructor tai_const.Create_rel_sym_offset(_typ: taiconst_type; _sym,_endsym: tasmsymbol; _ofs: int64);
+    constructor tai_const.Create_rel_sym_offset(_typ: taiconst_type; _sym, _endsym: tasmsymbol; _ofs: int64);
        begin
        begin
          self.create_sym_offset(_sym,_ofs);
          self.create_sym_offset(_sym,_ofs);
          consttype:=_typ;
          consttype:=_typ;
@@ -3093,6 +3099,7 @@ implementation
           fillsize:=0;
           fillsize:=0;
           fillop:=0;
           fillop:=0;
           use_op:=false;
           use_op:=false;
+          maxbytes:=aligntype;
        end;
        end;
 
 
 
 
@@ -3107,6 +3114,22 @@ implementation
           fillsize:=0;
           fillsize:=0;
           fillop:=_op;
           fillop:=_op;
           use_op:=true;
           use_op:=true;
+          maxbytes:=aligntype;
+       end;
+
+
+     constructor tai_align_abstract.create_max(b : byte; max : byte);
+       begin
+          inherited Create;
+          typ:=ait_align;
+          if b in [1,2,4,8,16,32] then
+            aligntype := b
+          else
+            aligntype := 1;
+          maxbytes:=max;
+          fillsize:=0;
+          fillop:=0;
+          use_op:=false;
        end;
        end;
 
 
 
 
@@ -3121,6 +3144,7 @@ implementation
          use_op:=true;
          use_op:=true;
          fillsize:=0;
          fillsize:=0;
          fillop:=0;
          fillop:=0;
+         maxbytes:=aligntype;
        end;
        end;
 
 
 
 
@@ -3140,6 +3164,7 @@ implementation
         fillsize:=0;
         fillsize:=0;
         fillop:=ppufile.getbyte;
         fillop:=ppufile.getbyte;
         use_op:=ppufile.getboolean;
         use_op:=ppufile.getboolean;
+        maxbytes:=ppufile.getbyte;
       end;
       end;
 
 
 
 
@@ -3149,6 +3174,7 @@ implementation
         ppufile.putbyte(aligntype);
         ppufile.putbyte(aligntype);
         ppufile.putbyte(fillop);
         ppufile.putbyte(fillop);
         ppufile.putboolean(use_op);
         ppufile.putboolean(use_op);
+        ppufile.putbyte(maxbytes);
       end;
       end;
 
 
 
 

+ 40 - 11
compiler/aggas.pas

@@ -347,9 +347,13 @@ implementation
             exit;
             exit;
           end;
           end;
 
 
-        if (atype=sec_threadvar) and
-          (target_info.system in (systems_windows+systems_wince)) then
-          secname:='.tls';
+        if atype=sec_threadvar then
+          begin
+            if (target_info.system in (systems_windows+systems_wince)) then
+              secname:='.tls'
+            else if (target_info.system in systems_linux) then
+              secname:='.tbss';
+          end;
 
 
         { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
         { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
           Thus, data which normally goes into .rodata and .rodata_norel sections must
           Thus, data which normally goes into .rodata and .rodata_norel sections must
@@ -620,9 +624,10 @@ implementation
         end;
         end;
 
 
 
 
-      procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint;lasthp:tai);
+      procedure doalign(alignment: byte; use_op: boolean; fillop: byte; maxbytes: byte; out last_align: longint;lasthp:tai);
         var
         var
           i: longint;
           i: longint;
+          alignment64 : int64;
 {$ifdef m68k}
 {$ifdef m68k}
           instr : string;
           instr : string;
 {$endif}
 {$endif}
@@ -649,14 +654,33 @@ implementation
                   else
                   else
                     begin
                     begin
 {$endif m68k}
 {$endif m68k}
-                  writer.AsmWrite(#9'.balign '+tostr(alignment));
-                  if use_op then
-                    writer.AsmWrite(','+tostr(fillop))
+                      alignment64:=alignment;
+                      if (maxbytes<>alignment) and ispowerof2(alignment64,i) then
+                        begin
+                          if use_op then
+                            begin
+                              writer.AsmWrite(#9'.p2align '+tostr(i)+','+tostr(fillop)+','+tostr(maxbytes));
+                              writer.AsmLn;
+                              writer.AsmWrite(#9'.p2align '+tostr(i-1)+','+tostr(fillop));
+                            end
+                          else
+                            begin
+                              writer.AsmWrite(#9'.p2align '+tostr(i)+',,'+tostr(maxbytes));
+                              writer.AsmLn;
+                              writer.AsmWrite(#9'.p2align '+tostr(i-1));
+                            end
+                        end
+                      else
+                        begin
+                          writer.AsmWrite(#9'.balign '+tostr(alignment));
+                          if use_op then
+                            writer.AsmWrite(','+tostr(fillop))
 {$ifdef x86}
 {$ifdef x86}
-                  { force NOP as alignment op code }
-                  else if (LastSecType=sec_code) and (asminfo^.id<>as_solaris_as) then
-                    writer.AsmWrite(',0x90');
+                          { force NOP as alignment op code }
+                          else if (LastSecType=sec_code) and (asminfo^.id<>as_solaris_as) then
+                            writer.AsmWrite(',0x90');
 {$endif x86}
 {$endif x86}
+                        end;
 {$ifdef m68k}
 {$ifdef m68k}
                     end;
                     end;
 {$endif m68k}
 {$endif m68k}
@@ -746,7 +770,7 @@ implementation
 
 
            ait_align :
            ait_align :
              begin
              begin
-               doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align,lasthp);
+               doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,tai_align_abstract(hp).maxbytes,last_align,lasthp);
              end;
              end;
 
 
            ait_section :
            ait_section :
@@ -923,6 +947,11 @@ implementation
                         WriteAixIntConst(tai_const(hp));
                         WriteAixIntConst(tai_const(hp));
                       writer.AsmLn;
                       writer.AsmLn;
                     end;
                     end;
+                 aitconst_gottpoff:
+                   begin
+                     writer.AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(gottpoff)+(.-'+tai_const(hp).endsym.name+tostr_with_plus(tai_const(hp).symofs)+')');
+                     writer.Asmln;
+                   end;
 {$endif cpu64bitaddr}
 {$endif cpu64bitaddr}
                  aitconst_got:
                  aitconst_got:
                    begin
                    begin

+ 6 - 6
compiler/aoptobj.pas

@@ -327,7 +327,7 @@ Unit AoptObj;
         function RegEndOfLife(reg: TRegister;p: taicpu): boolean;
         function RegEndOfLife(reg: TRegister;p: taicpu): boolean;
 
 
         { removes p from asml, updates registers and replaces it by a valid value, if this is the case true is returned }
         { removes p from asml, updates registers and replaces it by a valid value, if this is the case true is returned }
-        function RemoveCurrentP(var p : taicpu): boolean;
+        function RemoveCurrentP(var p : tai): boolean;
 
 
        { traces sucessive jumps to their final destination and sets it, e.g.
        { traces sucessive jumps to their final destination and sets it, e.g.
          je l1                je l3
          je l1                je l3
@@ -828,7 +828,7 @@ Unit AoptObj;
               If (TInstr(p).oper[Count]^.typ = Top_Ref) Then
               If (TInstr(p).oper[Count]^.typ = Top_Ref) Then
                 TmpResult := RefsEq(Ref, PInstr(p)^.oper[Count]^.ref^);
                 TmpResult := RefsEq(Ref, PInstr(p)^.oper[Count]^.ref^);
               Inc(Count);
               Inc(Count);
-            Until (Count = MaxOps) or TmpResult;
+            Until (Count = max_operands) or TmpResult;
           End;
           End;
         RefInInstruction := TmpResult;
         RefInInstruction := TmpResult;
       End;
       End;
@@ -1289,7 +1289,7 @@ Unit AoptObj;
       end;
       end;
 
 
 
 
-    function TAOptObj.RemoveCurrentP(var p : taicpu) : boolean;
+    function TAOptObj.RemoveCurrentP(var p : tai) : boolean;
       var
       var
         hp1 : tai;
         hp1 : tai;
       begin
       begin
@@ -1299,7 +1299,7 @@ Unit AoptObj;
         UpdateUsedRegs(tai(p.Next));
         UpdateUsedRegs(tai(p.Next));
         AsmL.Remove(p);
         AsmL.Remove(p);
         p.Free;
         p.Free;
-        p:=taicpu(hp1);
+        p:=hp1;
       end;
       end;
 
 
 
 
@@ -1551,7 +1551,7 @@ Unit AoptObj;
                                   and (hp1.typ <> ait_jcatch)
                                   and (hp1.typ <> ait_jcatch)
 {$endif}
 {$endif}
                                   do
                                   do
-                              if not(hp1.typ in ([ait_label,ait_align]+skipinstr)) then
+                              if not(hp1.typ in ([ait_label]+skipinstr)) then
                                 begin
                                 begin
                                   if (hp1.typ = ait_instruction) and
                                   if (hp1.typ = ait_instruction) and
                                      taicpu(hp1).is_jmp and
                                      taicpu(hp1).is_jmp and
@@ -1560,7 +1560,7 @@ Unit AoptObj;
                                      TAsmLabel(JumpTargetOp(taicpu(hp1))^.ref^.symbol).decrefs;
                                      TAsmLabel(JumpTargetOp(taicpu(hp1))^.ref^.symbol).decrefs;
                                   { don't kill start/end of assembler block,
                                   { don't kill start/end of assembler block,
                                     no-line-info-start/end etc }
                                     no-line-info-start/end etc }
-                                  if hp1.typ<>ait_marker then
+                                  if not(hp1.typ in [ait_align,ait_marker]) then
                                     begin
                                     begin
 {$ifdef cpudelayslot}
 {$ifdef cpudelayslot}
                                       if (hp1.typ=ait_instruction) and (taicpu(hp1).is_jmp) then
                                       if (hp1.typ=ait_instruction) and (taicpu(hp1).is_jmp) then

+ 12 - 1
compiler/aoptutils.pas

@@ -27,10 +27,13 @@ unit aoptutils;
   interface
   interface
 
 
     uses
     uses
-      aasmtai,aasmcpu;
+      cpubase,aasmtai,aasmcpu;
 
 
     function MatchOpType(const p : taicpu;type0: toptype) : Boolean;
     function MatchOpType(const p : taicpu;type0: toptype) : Boolean;
     function MatchOpType(const p : taicpu;type0,type1 : toptype) : Boolean;
     function MatchOpType(const p : taicpu;type0,type1 : toptype) : Boolean;
+{$if max_operands>2}
+    function MatchOpType(const p : taicpu; type0,type1,type2 : toptype) : Boolean;
+{$endif max_operands>2}
 
 
     { skips all labels and returns the next "real" instruction }
     { skips all labels and returns the next "real" instruction }
     function SkipLabels(hp: tai; var hp2: tai): boolean;
     function SkipLabels(hp: tai; var hp2: tai): boolean;
@@ -49,6 +52,14 @@ unit aoptutils;
       end;
       end;
 
 
 
 
+{$if max_operands>2}
+    function MatchOpType(const p : taicpu; type0,type1,type2 : toptype) : Boolean;
+      begin
+        Result:=(p.ops=3) and (p.oper[0]^.typ=type0) and (p.oper[1]^.typ=type1) and (p.oper[2]^.typ=type2);
+      end;
+{$endif max_operands>2}
+
+
     { skips all labels and returns the next "real" instruction }
     { skips all labels and returns the next "real" instruction }
     function SkipLabels(hp: tai; var hp2: tai): boolean;
     function SkipLabels(hp: tai; var hp2: tai): boolean;
       begin
       begin

+ 3 - 2
compiler/arm/aasmcpu.pas

@@ -1150,8 +1150,9 @@ implementation
                                           while assigned(hp2) do
                                           while assigned(hp2) do
                                             begin
                                             begin
                                               if (hp2.typ=ait_const) and (tai_const(hp2).sym=tai_const(hp).sym)
                                               if (hp2.typ=ait_const) and (tai_const(hp2).sym=tai_const(hp).sym)
-                                                and (tai_const(hp2).value=tai_const(hp).value) and (tai(hp2.previous).typ=ait_label)
-                                              then
+                                                and (tai_const(hp2).value=tai_const(hp).value) and (tai(hp2.previous).typ=ait_label) and
+                                                { gottpoff symbols are PC relative, so we cannot reuse them }
+                                                (tai_const(hp2).consttype<>aitconst_gottpoff) then
                                                 begin
                                                 begin
                                                   with taicpu(curtai).oper[curop]^.ref^ do
                                                   with taicpu(curtai).oper[curop]^.ref^ do
                                                     begin
                                                     begin

+ 17 - 2
compiler/arm/aoptcpu.pas

@@ -83,6 +83,10 @@ Implementation
     cgobj,procinfo,
     cgobj,procinfo,
     aasmbase,aasmdata;
     aasmbase,aasmdata;
 
 
+{ Range check must be disabled explicitly as conversions between signed and unsigned
+  32-bit values are done without explicit typecasts }
+{$R-}
+
   function CanBeCond(p : tai) : boolean;
   function CanBeCond(p : tai) : boolean;
     begin
     begin
       result:=
       result:=
@@ -1331,7 +1335,7 @@ Implementation
                         if taicpu(hp1).oper[1]^.ref^.index = taicpu(p).oper[0]^.reg then
                         if taicpu(hp1).oper[1]^.ref^.index = taicpu(p).oper[0]^.reg then
                           taicpu(hp1).oper[1]^.ref^.index := taicpu(p).oper[1]^.reg;
                           taicpu(hp1).oper[1]^.ref^.index := taicpu(p).oper[1]^.reg;
 
 
-                        dealloc:=FindRegDeAlloc(taicpu(p).oper[1]^.reg, taicpu(p.Next));
+                        dealloc:=FindRegDeAlloc(taicpu(p).oper[1]^.reg, tai(p.Next));
                         if Assigned(dealloc) then
                         if Assigned(dealloc) then
                           begin
                           begin
                             asml.remove(dealloc);
                             asml.remove(dealloc);
@@ -2516,6 +2520,15 @@ Implementation
 
 
   { TODO : schedule also forward }
   { TODO : schedule also forward }
   { TODO : schedule distance > 1 }
   { TODO : schedule distance > 1 }
+
+    { returns true if p might be a load of a pc relative tls offset }
+    function PossibleTLSLoad(const p: tai) : boolean;
+      begin
+        Result:=(p.typ=ait_instruction) and (taicpu(p).opcode=A_LDR) and (taicpu(p).oper[1]^.typ=top_ref) and (((taicpu(p).oper[1]^.ref^.base=NR_PC) and
+          (taicpu(p).oper[1]^.ref^.index<>NR_NO)) or ((taicpu(p).oper[1]^.ref^.base<>NR_NO) and
+          (taicpu(p).oper[1]^.ref^.index=NR_PC)));
+      end;
+
     var
     var
       hp1,hp2,hp3,hp4,hp5,insertpos : tai;
       hp1,hp2,hp3,hp4,hp5,insertpos : tai;
       list : TAsmList;
       list : TAsmList;
@@ -2572,7 +2585,9 @@ Implementation
             ) and
             ) and
             { if we modify the basereg AND the first instruction used that reg, we can not schedule }
             { if we modify the basereg AND the first instruction used that reg, we can not schedule }
             ((taicpu(hp1).oper[1]^.ref^.addressmode = AM_OFFSET) or
             ((taicpu(hp1).oper[1]^.ref^.addressmode = AM_OFFSET) or
-             not(instructionLoadsFromReg(taicpu(hp1).oper[1]^.ref^.base,p))) then
+             not(instructionLoadsFromReg(taicpu(hp1).oper[1]^.ref^.base,p))) and
+            not(PossibleTLSLoad(p)) and
+            not(PossibleTLSLoad(hp1)) then
             begin
             begin
               hp3:=tai(p.Previous);
               hp3:=tai(p.Previous);
               hp5:=tai(p.next);
               hp5:=tai(p.next);

+ 0 - 4
compiler/arm/aoptcpub.pas

@@ -76,10 +76,6 @@ Const
 
 
   MaxCh = 3;
   MaxCh = 3;
 
 
-{ the maximum number of operands an instruction has }
-
-  MaxOps = 4;
-
 {Oper index of operand that contains the source (reference) with a load }
 {Oper index of operand that contains the source (reference) with a load }
 {instruction                                                            }
 {instruction                                                            }
 
 

+ 26 - 6
compiler/arm/cgcpu.pas

@@ -107,13 +107,15 @@ unit cgcpu;
         { try to generate optimized 32 Bit multiplication, returns true if successful generated }
         { try to generate optimized 32 Bit multiplication, returns true if successful generated }
         function try_optimized_mul32_const_reg_reg(list: TAsmList; a: tcgint; src, dst: tregister) : boolean;
         function try_optimized_mul32_const_reg_reg(list: TAsmList; a: tcgint; src, dst: tregister) : boolean;
 
 
-        { clear out potential overflow bits from 8 or 16 bit operations  }
-        { the upper 24/16 bits of a register after an operation          }
+        { clear out potential overflow bits from 8 or 16 bit operations
+          the upper 24/16 bits of a register after an operation          }
         procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
         procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
 
 
         { mla for thumb requires that none of the registers is equal to r13/r15, this method ensures this }
         { mla for thumb requires that none of the registers is equal to r13/r15, this method ensures this }
         procedure safe_mla(list: TAsmList;op1,op2,op3,op4 : TRegister);
         procedure safe_mla(list: TAsmList;op1,op2,op3,op4 : TRegister);
 
 
+
+        procedure g_maybe_tls_init(list : TAsmList); override;
       end;
       end;
 
 
       { tcgarm is shared between normal arm and thumb-2 }
       { tcgarm is shared between normal arm and thumb-2 }
@@ -241,6 +243,10 @@ unit cgcpu;
        procinfo,cpupi,
        procinfo,cpupi,
        paramgr;
        paramgr;
 
 
+{ Range check must be disabled explicitly as conversions between signed and unsigned
+  32-bit values are done without explicit typecasts }
+{$R-}
+
 
 
     function get_fpu_postfix(def : tdef) : toppostfix;
     function get_fpu_postfix(def : tdef) : toppostfix;
       begin
       begin
@@ -1031,7 +1037,7 @@ unit cgcpu;
             { Doing two shifts instead of two bics might allow the peephole optimizer to fold the second shift
             { Doing two shifts instead of two bics might allow the peephole optimizer to fold the second shift
               into the following instruction}
               into the following instruction}
             else if (op = OP_AND) and
             else if (op = OP_AND) and
-                    is_continuous_mask(a, lsb, width) and
+                    is_continuous_mask(aword(a), lsb, width) and
                     ((lsb = 0) or ((lsb + width) = 32)) then
                     ((lsb = 0) or ((lsb + width) = 32)) then
               begin
               begin
                 shifterop_reset(so);
                 shifterop_reset(so);
@@ -2110,7 +2116,7 @@ unit cgcpu;
                    end;
                    end;
                end;
                end;
              end;
              end;
-        end;
+          end;
       end;
       end;
 
 
 
 
@@ -2472,6 +2478,8 @@ unit cgcpu;
                     a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,tmpreg);
                     a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,tmpreg);
                 indirection_done:=true;
                 indirection_done:=true;
               end
               end
+            else if ref.refaddr=addr_gottpoff then
+              current_procinfo.aktlocaldata.concat(tai_const.Create_rel_sym_offset(aitconst_gottpoff,ref.symbol,ref.relsymbol,ref.offset))
             else if (cs_create_pic in current_settings.moduleswitches) then
             else if (cs_create_pic in current_settings.moduleswitches) then
               if (tf_pic_uses_got in target_info.flags) then
               if (tf_pic_uses_got in target_info.flags) then
                 current_procinfo.aktlocaldata.concat(tai_const.Create_type_sym(aitconst_got,ref.symbol))
                 current_procinfo.aktlocaldata.concat(tai_const.Create_type_sym(aitconst_got,ref.symbol))
@@ -3267,6 +3275,15 @@ unit cgcpu;
       end;
       end;
 
 
 
 
+    procedure tbasecgarm.g_maybe_tls_init(list : TAsmList);
+      begin
+        list.concat(tai_regalloc.alloc(NR_R0,nil));
+        a_call_name(list,'fpc_read_tp',false);
+        a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_R0,current_procinfo.tlsoffset);
+        list.concat(tai_regalloc.dealloc(NR_R0,nil));
+      end;
+
+
     procedure tcg64farm.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
     procedure tcg64farm.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
       begin
       begin
         case op of
         case op of
@@ -4616,7 +4633,7 @@ unit cgcpu;
               list.concat(taicpu.op_reg_reg(A_UXTH,dst,src))
               list.concat(taicpu.op_reg_reg(A_UXTH,dst,src))
             else if (op = OP_AND) and is_thumb32_imm(not(dword(a))) then
             else if (op = OP_AND) and is_thumb32_imm(not(dword(a))) then
               list.concat(taicpu.op_reg_reg_const(A_BIC,dst,src,not(dword(a))))
               list.concat(taicpu.op_reg_reg_const(A_BIC,dst,src,not(dword(a))))
-            else if (op = OP_AND) and is_continuous_mask(not(a), shift, width) then
+            else if (op = OP_AND) and is_continuous_mask(aword(not(a)), shift, width) then
               begin
               begin
                 a_load_reg_reg(list,size,size,src,dst);
                 a_load_reg_reg(list,size,size,src,dst);
                 list.concat(taicpu.op_reg_const_const(A_BFC,dst,shift,width))
                 list.concat(taicpu.op_reg_const_const(A_BFC,dst,shift,width))
@@ -5022,7 +5039,10 @@ unit cgcpu;
                 cg.a_label(current_procinfo.aktlocaldata,l);
                 cg.a_label(current_procinfo.aktlocaldata,l);
                 tmpref.symboldata:=current_procinfo.aktlocaldata.last;
                 tmpref.symboldata:=current_procinfo.aktlocaldata.last;
 
 
-                current_procinfo.aktlocaldata.concat(tai_const.create_sym_offset(ref.symbol,ref.offset));
+                if ref.refaddr=addr_gottpoff then
+                  current_procinfo.aktlocaldata.concat(tai_const.Create_rel_sym_offset(aitconst_gottpoff,ref.symbol,ref.relsymbol,ref.offset))
+                else
+                  current_procinfo.aktlocaldata.concat(tai_const.create_sym_offset(ref.symbol,ref.offset));
 
 
                 { load consts entry }
                 { load consts entry }
                 tmpref.symbol:=l;
                 tmpref.symbol:=l;

+ 3 - 3
compiler/arm/cpubase.pas

@@ -377,7 +377,7 @@ unit cpubase;
       doesn't handle ROR_C detection }
       doesn't handle ROR_C detection }
     function is_thumb32_imm(d : aint) : boolean;
     function is_thumb32_imm(d : aint) : boolean;
     function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword):boolean;
     function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword):boolean;
-    function is_continuous_mask(d : aint;var lsb, width: byte) : boolean;
+    function is_continuous_mask(d : aword;var lsb, width: byte) : boolean;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function eh_return_data_regno(nr: longint): longint;
     function eh_return_data_regno(nr: longint): longint;
@@ -612,7 +612,7 @@ unit cpubase;
           end;
           end;
       end;
       end;
     
     
-    function is_continuous_mask(d : aint;var lsb, width: byte) : boolean;
+    function is_continuous_mask(d : aword;var lsb, width: byte) : boolean;
       var
       var
         msb : byte;
         msb : byte;
       begin
       begin
@@ -621,7 +621,7 @@ unit cpubase;
         
         
         width:=msb-lsb+1;
         width:=msb-lsb+1;
         
         
-        result:=(lsb<>255) and (msb<>255) and ((((1 shl (msb-lsb+1))-1) shl lsb) = d);
+        result:=(lsb<>255) and (msb<>255) and (aword(((1 shl (msb-lsb+1))-1) shl lsb) = d);
       end;
       end;
 
 
 
 

+ 1 - 0
compiler/arm/cpunode.pas

@@ -38,6 +38,7 @@ unit cpunode;
        narmcal,
        narmcal,
        narmmat,
        narmmat,
        narminl,
        narminl,
+       narmld,
        narmcnv,
        narmcnv,
        narmcon,
        narmcon,
        narmset,
        narmset,

+ 8 - 0
compiler/arm/cpupi.pas

@@ -49,6 +49,8 @@ unit cpupi;
           procedure generate_parameter_info;override;
           procedure generate_parameter_info;override;
           procedure allocate_got_register(list : TAsmList);override;
           procedure allocate_got_register(list : TAsmList);override;
           procedure postprocess_code;override;
           procedure postprocess_code;override;
+
+          procedure allocate_tls_register(list : TAsmList);override;
        end;
        end;
 
 
 
 
@@ -276,6 +278,12 @@ unit cpupi;
         finalizearmcode(aktproccode,aktlocaldata);
         finalizearmcode(aktproccode,aktlocaldata);
       end;
       end;
 
 
+
+    procedure tcpuprocinfo.allocate_tls_register(list: TAsmList);
+      begin
+        current_procinfo.tlsoffset:=cg.getaddressregister(list);
+      end;
+
 begin
 begin
    cprocinfo:=tcpuprocinfo;
    cprocinfo:=tcpuprocinfo;
 end.
 end.

+ 97 - 0
compiler/arm/narmld.pas

@@ -0,0 +1,97 @@
+{
+    Copyright (c) 1998-2018 by Florian Klaempfl
+
+    Generate arm assembler for load nodes
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit narmld;
+
+{$i fpcdefs.inc}
+
+interface
+
+    uses
+      globtype,
+      symsym,
+      node,ncgld,pass_1,aasmbase;
+
+    type
+      tarmloadnode = class(tcgloadnode)
+         procedure generate_threadvar_access(gvs : tstaticvarsym); override;
+      end;
+
+
+implementation
+
+    uses
+      globals,verbose,
+      cgbase,cgobj,cgutils,
+      aasmdata,
+      systems,
+      symcpu,symdef,
+      nld,
+      cpubase,
+      parabase,
+      procinfo;
+
+{*****************************************************************************
+                            TI386LOADNODE
+*****************************************************************************}
+
+    procedure tarmloadnode.generate_threadvar_access(gvs: tstaticvarsym);
+      var
+        paraloc1 : tcgpara;
+        pd: tprocdef;
+        href: treference;
+        hregister : tregister;
+        handled: boolean;
+        l : TAsmLabel;
+      begin
+        handled:=false;
+        if tf_section_threadvars in target_info.flags then
+          begin
+            if target_info.system in [system_arm_linux] then
+              begin
+                if not(pi_uses_threadvar in current_procinfo.flags) then
+                  internalerror(2012012101);
+                current_asmdata.getjumplabel(l);
+                reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA),-8,sizeof(AInt),[]);
+                href.refaddr:=addr_gottpoff;
+                href.relsymbol:=l;
+                hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
+                cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,hregister);
+                cg.a_label(current_asmdata.CurrAsmList,l);
+                reference_reset(href,0,[]);
+                href.base:=NR_PC;
+                href.index:=hregister;
+                hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
+                cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
+                location.reference.base:=current_procinfo.tlsoffset;
+                location.reference.index:=hregister;
+                handled:=true;
+              end;
+          end;
+
+        if not handled then
+          inherited;
+      end;
+
+
+begin
+   cloadnode:=tarmloadnode;
+end.

+ 7 - 0
compiler/assemble.pas

@@ -1700,6 +1700,13 @@ Implementation
                      { here we must determine the fillsize which is used in pass2 }
                      { here we must determine the fillsize which is used in pass2 }
                      Tai_align_abstract(hp).fillsize:=align(ObjData.CurrObjSec.Size,Tai_align_abstract(hp).aligntype)-
                      Tai_align_abstract(hp).fillsize:=align(ObjData.CurrObjSec.Size,Tai_align_abstract(hp).aligntype)-
                        ObjData.CurrObjSec.Size;
                        ObjData.CurrObjSec.Size;
+
+                     { maximum number of bytes for alignment exeeded? }
+                     if (Tai_align_abstract(hp).aligntype<>Tai_align_abstract(hp).maxbytes) and
+                       (Tai_align_abstract(hp).fillsize>Tai_align_abstract(hp).maxbytes) then
+                       Tai_align_abstract(hp).fillsize:=align(ObjData.CurrObjSec.Size,Byte(Tai_align_abstract(hp).aligntype div 2))-
+                         ObjData.CurrObjSec.Size;
+
                      ObjData.alloc(Tai_align_abstract(hp).fillsize);
                      ObjData.alloc(Tai_align_abstract(hp).fillsize);
                    end;
                    end;
                end;
                end;

+ 15 - 15
compiler/avr/aoptcpu.pas

@@ -349,7 +349,7 @@ Implementation
 
 
                             DebugMsg('Peephole LdiMov/Cp2Ldi/Cpi performed', p);
                             DebugMsg('Peephole LdiMov/Cp2Ldi/Cpi performed', p);
 
 
-                            RemoveCurrentP(taicpu(p));
+                            RemoveCurrentP(p);
                           end;
                           end;
                         ReleaseUsedRegs(TmpUsedRegs);
                         ReleaseUsedRegs(TmpUsedRegs);
                       end;
                       end;
@@ -541,7 +541,7 @@ Implementation
                       begin
                       begin
                         DebugMsg('Redundant Andi removed', p);
                         DebugMsg('Redundant Andi removed', p);
 
 
-                        result:=RemoveCurrentP(taicpu(p));
+                        result:=RemoveCurrentP(p);
                       end;
                       end;
                   end;
                   end;
                 A_ADD:
                 A_ADD:
@@ -552,7 +552,7 @@ Implementation
                     begin
                     begin
                       DebugMsg('Peephole AddAdc2Add performed', p);
                       DebugMsg('Peephole AddAdc2Add performed', p);
 
 
-                      result:=RemoveCurrentP(taicpu(p));
+                      result:=RemoveCurrentP(p);
                     end;
                     end;
                   end;
                   end;
                 A_SUB:
                 A_SUB:
@@ -565,7 +565,7 @@ Implementation
 
 
                       taicpu(hp1).opcode:=A_SUB;
                       taicpu(hp1).opcode:=A_SUB;
 
 
-                      result:=RemoveCurrentP(taicpu(p));
+                      result:=RemoveCurrentP(p);
                     end;
                     end;
                   end;
                   end;
                 A_CLR:
                 A_CLR:
@@ -588,7 +588,7 @@ Implementation
                       begin
                       begin
                         DebugMsg('Peephole ClrMov2Mov performed', p);
                         DebugMsg('Peephole ClrMov2Mov performed', p);
 
 
-                        result:=RemoveCurrentP(taicpu(p));
+                        result:=RemoveCurrentP(p);
                       end
                       end
                     { turn
                     { turn
                       clr rX
                       clr rX
@@ -625,7 +625,7 @@ Implementation
                             dealloc.Free;
                             dealloc.Free;
                           end;
                           end;
 
 
-                        result:=RemoveCurrentP(taicpu(p));
+                        result:=RemoveCurrentP(p);
                       end;
                       end;
                   end;
                   end;
                 A_PUSH:
                 A_PUSH:
@@ -667,9 +667,9 @@ Implementation
 
 
                            taicpu(hp3).loadreg(1, taicpu(p).oper[0]^.reg);
                            taicpu(hp3).loadreg(1, taicpu(p).oper[0]^.reg);
 
 
-                           RemoveCurrentP(taicpu(p));
-                           RemoveCurrentP(taicpu(p));
-                           result:=RemoveCurrentP(taicpu(p));
+                           RemoveCurrentP(p);
+                           RemoveCurrentP(p);
+                           result:=RemoveCurrentP(p);
                          end
                          end
                        else
                        else
                          begin
                          begin
@@ -757,7 +757,7 @@ Implementation
                           not(MatchInstruction(hp1,[A_CALL,A_RCALL])) then
                           not(MatchInstruction(hp1,[A_CALL,A_RCALL])) then
                           begin
                           begin
                             DebugMsg('Peephole Mov2Nop performed', p);
                             DebugMsg('Peephole Mov2Nop performed', p);
-                            result:=RemoveCurrentP(taicpu(p));
+                            result:=RemoveCurrentP(p);
                             ReleaseUsedRegs(TmpUsedRegs);
                             ReleaseUsedRegs(TmpUsedRegs);
                             exit;
                             exit;
                           end;
                           end;
@@ -807,7 +807,7 @@ Implementation
                         { p will be removed, update used register as we continue
                         { p will be removed, update used register as we continue
                           with the next instruction after p }
                           with the next instruction after p }
 
 
-                        result:=RemoveCurrentP(taicpu(p));
+                        result:=RemoveCurrentP(p);
                       end
                       end
                     { remove
                     { remove
                       mov reg0,reg0
                       mov reg0,reg0
@@ -819,7 +819,7 @@ Implementation
                       begin
                       begin
                         DebugMsg('Peephole RedundantMov performed', p);
                         DebugMsg('Peephole RedundantMov performed', p);
 
 
-                        result:=RemoveCurrentP(taicpu(p));
+                        result:=RemoveCurrentP(p);
                       end
                       end
                     {
                     {
                       Turn
                       Turn
@@ -870,7 +870,7 @@ Implementation
                         asml.remove(hp2);
                         asml.remove(hp2);
                         hp2.free;
                         hp2.free;
 
 
-                        result:=RemoveCurrentP(taicpu(p));
+                        result:=RemoveCurrentP(p);
                       end
                       end
                     {
                     {
                       Turn
                       Turn
@@ -913,7 +913,7 @@ Implementation
                             dealloc.Free;
                             dealloc.Free;
                           end;
                           end;
 
 
-                        result:=RemoveCurrentP(taicpu(p));
+                        result:=RemoveCurrentP(p);
 
 
                         asml.remove(hp2);
                         asml.remove(hp2);
                         hp2.free;
                         hp2.free;
@@ -968,7 +968,7 @@ Implementation
                         begin
                         begin
                           DebugMsg('Peephole MovMov2Mov performed', p);
                           DebugMsg('Peephole MovMov2Mov performed', p);
 
 
-                          result:=RemoveCurrentP(taicpu(p));
+                          result:=RemoveCurrentP(p);
 
 
                           GetNextInstruction(hp1,hp1);
                           GetNextInstruction(hp1,hp1);
                           if not assigned(hp1) then
                           if not assigned(hp1) then

+ 0 - 4
compiler/avr/aoptcpub.pas

@@ -75,10 +75,6 @@ Const
 
 
   MaxCh = 2;
   MaxCh = 2;
 
 
-{ the maximum number of operands an instruction has }
-
-  MaxOps = 2;
-
 {Oper index of operand that contains the source (reference) with a load }
 {Oper index of operand that contains the source (reference) with a load }
 {instruction                                                            }
 {instruction                                                            }
 
 

+ 1 - 1
compiler/avr/cpubase.pas

@@ -171,7 +171,7 @@ unit cpubase;
 *****************************************************************************}
 *****************************************************************************}
 
 
     const
     const
-      max_operands = 4;
+      max_operands = 2;
 
 
       maxintregs = 15;
       maxintregs = 15;
       maxfpuregs = 0;
       maxfpuregs = 0;

+ 101 - 97
compiler/avr/raavr.pas

@@ -58,204 +58,208 @@ unit raavr;
         Operands: array[0..max_operands-1] of TAVROpConstraint;
         Operands: array[0..max_operands-1] of TAVROpConstraint;
       end;
       end;
 
 
+{$PUSH}
+{$WARN 3177 off : Some fields coming after "$1" were not initialized}
   const
   const
     AVRInstrConstraint: array[TAsmOp] of TAVRInstrConstraint =
     AVRInstrConstraint: array[TAsmOp] of TAVRInstrConstraint =
       // A_NONE
       // A_NONE
-      ((numOperands: 0; Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+      ((numOperands: 0; Operands: ((typ: top_none), (typ: top_none))),
       // A_ADD
       // A_ADD
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_ADC
        // A_ADC
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_ADIW
        // A_ADIW
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even_24_30), (typ: top_const; max: 63; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even_24_30), (typ: top_const; max: 63; min: 0))),
        // A_SUB
        // A_SUB
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_SUBI
        // A_SUBI
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128))),
        // A_SBC
        // A_SBC
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_SBCI
        // A_SBCI
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128))),
        // A_SBRC
        // A_SBRC
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0))),
        // A_SBRS
        // A_SBRS
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0))),
        // A_SBIW
        // A_SBIW
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even_24_30), (typ: top_const; max: 63; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even_24_30), (typ: top_const; max: 63; min: 0))),
        // A_AND
        // A_AND
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_ANDI
        // A_ANDI
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128))),
        // A_OR
        // A_OR
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_ORI
        // A_ORI
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128))),
        // A_EOR
        // A_EOR
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_COM
        // A_COM
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_NEG
        // A_NEG
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_SBR
        // A_SBR
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128))),
        // A_CBR
        // A_CBR
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128))),
        // A_INC
        // A_INC
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_DEC
        // A_DEC
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_TST
        // A_TST
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_MUL
        // A_MUL
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_MULS
        // A_MULS
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_reg; rt: rt_16_31), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_reg; rt: rt_16_31))),
        // A_MULSU
        // A_MULSU
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23))),
        // A_FMUL
        // A_FMUL
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23))),
        // A_FMULS
        // A_FMULS
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23))),
        // A_FMULSU
        // A_FMULSU
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_23), (typ: top_reg; rt: rt_16_23))),
        // A_RJMP
        // A_RJMP
-       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 2047; min: -2048), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 2047; min: -2048), (typ: top_reg; rt: rt_all))),
        // A_IJMP
        // A_IJMP
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_EIJMP
        // A_EIJMP
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_JMP, max size depends on size op PC
        // A_JMP, max size depends on size op PC
-       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: (1 shl 22 - 1); min: 0), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: (1 shl 22 - 1); min: 0), (typ: top_none))),
        // A_RCALL
        // A_RCALL
-       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 2047; min: -2048), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 2047; min: -2048), (typ: top_none))),
        // A_ICALL
        // A_ICALL
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_EICALL
        // A_EICALL
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CALL, max size depends on size op PC
        // A_CALL, max size depends on size op PC
-       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: (1 shl 22 - 1); min: 0), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: (1 shl 22 - 1); min: 0), (typ: top_none))),
        // A_RET
        // A_RET
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_IRET
        // A_IRET
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CPSE
        // A_CPSE
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_CP
        // A_CP
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_CPC
        // A_CPC
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_CPI
        // A_CPI
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128))),
        // A_SBIC
        // A_SBIC
-       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 31; min: 0), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 31; min: 0), (typ: top_const; max: 7; min: 0))),
        // A_SBIS
        // A_SBIS
-       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 31; min: 0), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 31; min: 0), (typ: top_const; max: 7; min: 0))),
        // A_BRxx
        // A_BRxx
-       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 63; min: -64), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 63; min: -64), (typ: top_none))),
        // A_MOV
        // A_MOV
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_all))),
        // A_MOVW
        // A_MOVW
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even), (typ: top_reg; rt: rt_even), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_even), (typ: top_reg; rt: rt_even))),
        // A_LDI
        // A_LDI
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_const; max: 255; min: -128))),
        // A_LDS TODO: There are 2 versions with different machine codes and constant ranges. Could possibly distinguish based on size of PC?
        // A_LDS TODO: There are 2 versions with different machine codes and constant ranges. Could possibly distinguish based on size of PC?
        // Perhaps handle separately with a check on sub-architecture? Range check only important if smaller instruction code selected on larger arch
        // Perhaps handle separately with a check on sub-architecture? Range check only important if smaller instruction code selected on larger arch
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 65535; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 65535; min: 0))),
        // A_LD
        // A_LD
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_XYZ; am: [AM_UNCHANGED, AM_POSTINCREMENT, AM_PREDRECEMENT]), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_XYZ; am: [AM_UNCHANGED, AM_POSTINCREMENT, AM_PREDRECEMENT]))),
        // A_LDD
        // A_LDD
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_YZ; am: [AM_UNCHANGED]; minconst: 0; maxconst: 63), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_YZ; am: [AM_UNCHANGED]; minconst: 0; maxconst: 63))),
        // A_STS TODO: See LDS above
        // A_STS TODO: See LDS above
-       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 65535; min: 0), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 65535; min: 0), (typ: top_reg; rt: rt_all))),
        // A_ST
        // A_ST
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_XYZ; am: [AM_UNCHANGED, AM_POSTINCREMENT, AM_PREDRECEMENT]), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_XYZ; am: [AM_UNCHANGED, AM_POSTINCREMENT, AM_PREDRECEMENT]), (typ: top_reg; rt: rt_all))),
        // A_STD
        // A_STD
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_YZ; am: [AM_UNCHANGED]; minconst: 0; maxconst: 63), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_YZ; am: [AM_UNCHANGED]; minconst: 0; maxconst: 63), (typ: top_reg; rt: rt_all))),
        // A_LPM
        // A_LPM
-       (numOperands: (1 shl 0 + 1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0 + 1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]))),
        // A_ELPM
        // A_ELPM
-       (numOperands: (1 shl 0 + 1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0 + 1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]))),
        // A_SPM
        // A_SPM
-       (numOperands: (1 shl 0 + 1 shl 1); Operands: ((typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0 + 1 shl 1); Operands: ((typ: top_reg; rt: rt_Z; am: [AM_UNCHANGED, AM_POSTINCREMENT]), (typ: top_none))),
        // A_IN
        // A_IN
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 63; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 63; min: 0))),
        // A_OUT
        // A_OUT
-       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 63; min: 0), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 63; min: 0), (typ: top_reg; rt: rt_all))),
        // A_PUSH
        // A_PUSH
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_POP
        // A_POP
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_LSL
        // A_LSL
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_LSR
        // A_LSR
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_ROL
        // A_ROL
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_ROR
        // A_ROR
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_ASR
        // A_ASR
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_SWAP
        // A_SWAP
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_BSET
        // A_BSET
-       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 7; min: 0), (typ: top_none))),
        // A_BCLR
        // A_BCLR
-       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_const; max: 7; min: 0), (typ: top_none))),
        // A_SBI
        // A_SBI
-       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 32; min: 0), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 32; min: 0), (typ: top_const; max: 7; min: 0))),
        // A_CBI
        // A_CBI
-       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 32; min: 0), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_const; max: 32; min: 0), (typ: top_const; max: 7; min: 0))),
        // A_SEC
        // A_SEC
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_SEH
        // A_SEH
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_SEI
        // A_SEI
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_SEN
        // A_SEN
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_SER
        // A_SER
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_16_31), (typ: top_none))),
        // A_SES
        // A_SES
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_SET
        // A_SET
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_SEV
        // A_SEV
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_SEZ
        // A_SEZ
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CLC
        // A_CLC
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CLH
        // A_CLH
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CLI
        // A_CLI
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CLN
        // A_CLN
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CLR
        // A_CLR
-       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 1); Operands: ((typ: top_reg; rt: rt_all), (typ: top_none))),
        // A_CLS
        // A_CLS
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CLT
        // A_CLT
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CLV
        // A_CLV
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_CLZ
        // A_CLZ
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_BST
        // A_BST
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0))),
        // A_BLD
        // A_BLD
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_all), (typ: top_const; max: 7; min: 0))),
        // A_BREAK
        // A_BREAK
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_NOP
        // A_NOP
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_SLEEP
        // A_SLEEP
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_WDR
        // A_WDR
-       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none), (typ: top_none), (typ: top_none))),
+       (numOperands: (1 shl 0); Operands: ((typ: top_none), (typ: top_none))),
        // A_XCH
        // A_XCH
-       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_Z), (typ: top_reg; rt: rt_all), (typ: top_none), (typ: top_none)))
+       (numOperands: (1 shl 2); Operands: ((typ: top_reg; rt: rt_Z), (typ: top_reg; rt: rt_all)))
        );
        );
+{$POP}
+
 
 
   implementation
   implementation
     uses
     uses

+ 76 - 77
compiler/cclasses.pas

@@ -1053,6 +1053,11 @@ begin
   FFreeObjects := True;
   FFreeObjects := True;
 end;
 end;
 
 
+function TFPObjectList.IndexOf(AObject: TObject): Integer;
+begin
+  Result := FList.IndexOf(Pointer(AObject));
+end;
+
 function TFPObjectList.GetCount: integer;
 function TFPObjectList.GetCount: integer;
 begin
 begin
   Result := FList.Count;
   Result := FList.Count;
@@ -1125,11 +1130,6 @@ begin
   end;
   end;
 end;
 end;
 
 
-function TFPObjectList.IndexOf(AObject: TObject): Integer;
-begin
-  Result := FList.IndexOf(Pointer(AObject));
-end;
-
 function TFPObjectList.FindInstanceOf(AClass: TClass; AExact: Boolean; AStartAt : Integer): Integer;
 function TFPObjectList.FindInstanceOf(AClass: TClass; AExact: Boolean; AStartAt : Integer): Integer;
 var
 var
   I : Integer;
   I : Integer;
@@ -1764,72 +1764,6 @@ begin
 end;
 end;
 
 
 
 
-{*****************************************************************************
-                               TFPHashObject
-*****************************************************************************}
-
-procedure TFPHashObject.InternalChangeOwner(HashObjectList:TFPHashObjectList;const s:TSymStr);
-var
-  Index : integer;
-begin
-  FOwner:=HashObjectList;
-  Index:=HashObjectList.Add(s,Self);
-  FStrIndex:=HashObjectList.List.List^[Index].StrIndex;
-end;
-
-
-constructor TFPHashObject.CreateNotOwned;
-begin
-  FStrIndex:=-1;
-end;
-
-
-constructor TFPHashObject.Create(HashObjectList:TFPHashObjectList;const s:TSymStr);
-begin
-  InternalChangeOwner(HashObjectList,s);
-end;
-
-
-procedure TFPHashObject.ChangeOwner(HashObjectList:TFPHashObjectList);
-begin
-  InternalChangeOwner(HashObjectList,PSymStr(@FOwner.List.Strs[FStrIndex])^);
-end;
-
-
-procedure TFPHashObject.ChangeOwnerAndName(HashObjectList:TFPHashObjectList;const s:TSymStr);
-begin
-  InternalChangeOwner(HashObjectList,s);
-end;
-
-
-procedure TFPHashObject.Rename(const ANewName:TSymStr);
-var
-  Index : integer;
-begin
-  Index:=FOwner.Rename(PSymStr(@FOwner.List.Strs[FStrIndex])^,ANewName);
-  if Index<>-1 then
-    FStrIndex:=FOwner.List.List^[Index].StrIndex;
-end;
-
-
-function TFPHashObject.GetName:TSymStr;
-begin
-  if FOwner<>nil then
-    Result:=PSymStr(@FOwner.List.Strs[FStrIndex])^
-  else
-    Result:='';
-end;
-
-
-function TFPHashObject.GetHash:Longword;
-begin
-  if FOwner<>nil then
-    Result:=FPHash(PSymStr(@FOwner.List.Strs[FStrIndex])^)
-  else
-    Result:=$ffffffff;
-end;
-
-
 {*****************************************************************************
 {*****************************************************************************
             TFPHashObjectList (Copied from rtl/objpas/classes/lists.inc)
             TFPHashObjectList (Copied from rtl/objpas/classes/lists.inc)
 *****************************************************************************}
 *****************************************************************************}
@@ -1862,6 +1796,11 @@ begin
   FHashList.Clear;
   FHashList.Clear;
 end;
 end;
 
 
+function TFPHashObjectList.IndexOf(AObject: TObject): Integer;
+begin
+  Result := FHashList.IndexOf(Pointer(AObject));
+end;
+
 function TFPHashObjectList.GetCount: integer;
 function TFPHashObjectList.GetCount: integer;
 begin
 begin
   Result := FHashList.Count;
   Result := FHashList.Count;
@@ -1944,12 +1883,6 @@ begin
     end;
     end;
 end;
 end;
 
 
-function TFPHashObjectList.IndexOf(AObject: TObject): Integer;
-begin
-  Result := FHashList.IndexOf(Pointer(AObject));
-end;
-
-
 function TFPHashObjectList.Find(const s:TSymStr): TObject;
 function TFPHashObjectList.Find(const s:TSymStr): TObject;
 begin
 begin
   result:=TObject(FHashList.Find(s));
   result:=TObject(FHashList.Find(s));
@@ -2031,6 +1964,72 @@ begin
 end;
 end;
 
 
 
 
+{*****************************************************************************
+                               TFPHashObject
+*****************************************************************************}
+
+procedure TFPHashObject.InternalChangeOwner(HashObjectList:TFPHashObjectList;const s:TSymStr);
+var
+  Index : integer;
+begin
+  FOwner:=HashObjectList;
+  Index:=HashObjectList.Add(s,Self);
+  FStrIndex:=HashObjectList.List.List^[Index].StrIndex;
+end;
+
+
+constructor TFPHashObject.CreateNotOwned;
+begin
+  FStrIndex:=-1;
+end;
+
+
+constructor TFPHashObject.Create(HashObjectList:TFPHashObjectList;const s:TSymStr);
+begin
+  InternalChangeOwner(HashObjectList,s);
+end;
+
+
+procedure TFPHashObject.ChangeOwner(HashObjectList:TFPHashObjectList);
+begin
+  InternalChangeOwner(HashObjectList,PSymStr(@FOwner.List.Strs[FStrIndex])^);
+end;
+
+
+procedure TFPHashObject.ChangeOwnerAndName(HashObjectList:TFPHashObjectList;const s:TSymStr);
+begin
+  InternalChangeOwner(HashObjectList,s);
+end;
+
+
+procedure TFPHashObject.Rename(const ANewName:TSymStr);
+var
+  Index : integer;
+begin
+  Index:=FOwner.Rename(PSymStr(@FOwner.List.Strs[FStrIndex])^,ANewName);
+  if Index<>-1 then
+    FStrIndex:=FOwner.List.List^[Index].StrIndex;
+end;
+
+
+function TFPHashObject.GetName:TSymStr;
+begin
+  if FOwner<>nil then
+    Result:=PSymStr(@FOwner.List.Strs[FStrIndex])^
+  else
+    Result:='';
+end;
+
+
+function TFPHashObject.GetHash:Longword;
+begin
+  if FOwner<>nil then
+    Result:=FPHash(PSymStr(@FOwner.List.Strs[FStrIndex])^)
+  else
+    Result:=$ffffffff;
+end;
+
+
 {****************************************************************************
 {****************************************************************************
                              TLinkedListItem
                              TLinkedListItem
  ****************************************************************************}
  ****************************************************************************}

+ 2 - 2
compiler/cfileutl.pas

@@ -146,7 +146,7 @@ interface
 {$NOTE TODO Amiga: implement PathConv() in System unit, which works with AnsiString}
 {$NOTE TODO Amiga: implement PathConv() in System unit, which works with AnsiString}
 function Unix2AmigaPath(path: ShortString): ShortString; external name 'PATHCONV';
 function Unix2AmigaPath(path: ShortString): ShortString; external name 'PATHCONV';
 {$ELSE}
 {$ELSE}
-function Unix2AmigaPath(path: String): String;{$IFDEF USEINLINE}inline;{$ENDIF}
+function Unix2AmigaPath(path: String): String;
 {$ENDIF}
 {$ENDIF}
 
 
 {$if FPC_FULLVERSION < 20701}
 {$if FPC_FULLVERSION < 20701}
@@ -191,7 +191,7 @@ implementation
 {$IFNDEF HASAMIGA}
 {$IFNDEF HASAMIGA}
 { Stub function for Unix2Amiga Path conversion functionality, only available in
 { Stub function for Unix2Amiga Path conversion functionality, only available in
   Amiga/MorphOS RTL. I'm open for better solutions. (KB) }
   Amiga/MorphOS RTL. I'm open for better solutions. (KB) }
-function Unix2AmigaPath(path: String): String;{$IFDEF USEINLINE}inline;{$ENDIF}
+function Unix2AmigaPath(path: String): String;
 begin
 begin
   Unix2AmigaPath:=path;
   Unix2AmigaPath:=path;
 end;
 end;

+ 10 - 2
compiler/cgbase.pas

@@ -63,8 +63,6 @@ interface
        TCGNonRefLoc=low(TCGLoc)..pred(LOC_CREFERENCE);
        TCGNonRefLoc=low(TCGLoc)..pred(LOC_CREFERENCE);
        TCGRefLoc=LOC_CREFERENCE..LOC_REFERENCE;
        TCGRefLoc=LOC_CREFERENCE..LOC_REFERENCE;
 
 
-       { since we have only 16bit offsets, we need to be able to specify the high
-         and lower 16 bits of the address of a symbol of up to 64 bit }
        trefaddr = (
        trefaddr = (
          addr_no,
          addr_no,
          addr_full,
          addr_full,
@@ -72,6 +70,8 @@ interface
          addr_pic_no_got
          addr_pic_no_got
          {$IF defined(POWERPC) or defined(POWERPC64) or defined(SPARC) or defined(MIPS) or defined(SPARC64)}
          {$IF defined(POWERPC) or defined(POWERPC64) or defined(SPARC) or defined(MIPS) or defined(SPARC64)}
          ,
          ,
+         { since we have only 16bit offsets, we need to be able to specify the high
+           and lower 16 bits of the address of a symbol of up to 64 bit }
          addr_low,         // bits 48-63
          addr_low,         // bits 48-63
          addr_high,        // bits 32-47
          addr_high,        // bits 32-47
          {$IF defined(POWERPC64)}
          {$IF defined(POWERPC64)}
@@ -122,6 +122,14 @@ interface
          ,addr_gdop_hix22
          ,addr_gdop_hix22
          ,addr_gdop_lox22
          ,addr_gdop_lox22
          {$endif SPARC64}
          {$endif SPARC64}
+         {$IFDEF ARM}
+         ,addr_gottpoff
+         ,addr_tpoff
+         {$ENDIF}
+         {$IFDEF i386}
+         ,addr_ntpoff
+         ,addr_tlsgd
+         {$ENDIF}
          );
          );
 
 
 
 

+ 30 - 4
compiler/cgobj.pas

@@ -437,6 +437,8 @@ unit cgobj;
 
 
           { initialize the pic/got register }
           { initialize the pic/got register }
           procedure g_maybe_got_init(list: TAsmList); virtual;
           procedure g_maybe_got_init(list: TAsmList); virtual;
+          { initialize the tls register if needed }
+          procedure g_maybe_tls_init(list : TAsmList); virtual;
           { allocallcpuregisters, a_call_name, deallocallcpuregisters sequence }
           { allocallcpuregisters, a_call_name, deallocallcpuregisters sequence }
           procedure g_call(list: TAsmList; const s: string);
           procedure g_call(list: TAsmList; const s: string);
           { Generate code to exit an unwind-protected region. The default implementation
           { Generate code to exit an unwind-protected region. The default implementation
@@ -1925,11 +1927,20 @@ implementation
     procedure tcg.a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference);
     procedure tcg.a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference);
       var
       var
         tmpreg : tregister;
         tmpreg : tregister;
+        tmpref : treference;
       begin
       begin
+        if assigned(ref.symbol) then
+          begin
+            tmpreg:=getaddressregister(list);
+            a_loadaddr_ref_reg(list,ref,tmpreg);
+            reference_reset_base(tmpref,tmpreg,0,ref.temppos,ref.alignment,[]);
+          end
+        else
+          tmpref:=ref;
         tmpreg:=getintregister(list,size);
         tmpreg:=getintregister(list,size);
-        a_load_ref_reg(list,size,size,ref,tmpreg);
+        a_load_ref_reg(list,size,size,tmpref,tmpreg);
         a_op_const_reg(list,op,size,a,tmpreg);
         a_op_const_reg(list,op,size,a,tmpreg);
-        a_load_reg_ref(list,size,size,tmpreg,ref);
+        a_load_reg_ref(list,size,size,tmpreg,tmpref);
       end;
       end;
 
 
 
 
@@ -1949,9 +1960,18 @@ implementation
     procedure tcg.a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister;  const ref: TReference);
     procedure tcg.a_op_reg_ref(list : TAsmList; Op: TOpCG; size: TCGSize;reg: TRegister;  const ref: TReference);
       var
       var
         tmpreg : tregister;
         tmpreg : tregister;
+        tmpref : treference;
       begin
       begin
+        if assigned(ref.symbol) then
+          begin
+            tmpreg:=getaddressregister(list);
+            a_loadaddr_ref_reg(list,ref,tmpreg);
+            reference_reset_base(tmpref,tmpreg,0,ref.temppos,ref.alignment,[]);
+          end
+        else
+          tmpref:=ref;
         tmpreg:=getintregister(list,size);
         tmpreg:=getintregister(list,size);
-        a_load_ref_reg(list,size,size,ref,tmpreg);
+        a_load_ref_reg(list,size,size,tmpref,tmpreg);
         if op in [OP_NEG,OP_NOT] then
         if op in [OP_NEG,OP_NOT] then
           begin
           begin
             if reg<>NR_NO then
             if reg<>NR_NO then
@@ -1960,7 +1980,7 @@ implementation
           end
           end
         else
         else
           a_op_reg_reg(list,op,size,reg,tmpreg);
           a_op_reg_reg(list,op,size,reg,tmpreg);
-        a_load_reg_ref(list,size,size,tmpreg,ref);
+        a_load_reg_ref(list,size,size,tmpreg,tmpref);
       end;
       end;
 
 
 
 
@@ -2763,6 +2783,12 @@ implementation
       begin
       begin
       end;
       end;
 
 
+
+    procedure tcg.g_maybe_tls_init(list: TAsmList);
+      begin
+      end;
+
+
     procedure tcg.g_call(list: TAsmList;const s: string);
     procedure tcg.g_call(list: TAsmList;const s: string);
       begin
       begin
         allocallcpuregisters(list);
         allocallcpuregisters(list);

+ 9 - 2
compiler/cutils.pas

@@ -144,7 +144,8 @@ interface
 
 
     { allocates mem for a copy of s, copies s to this mem and returns }
     { allocates mem for a copy of s, copies s to this mem and returns }
     { a pointer to this mem                                           }
     { a pointer to this mem                                           }
-    function stringdup(const s : string) : pshortstring;{$ifdef USEINLINE}inline;{$endif}
+    function stringdup(const s : shortstring) : pshortstring;{$ifdef USEINLINE}inline;{$endif}
+    function stringdup(const s : ansistring) : pshortstring;{$ifdef USEINLINE}inline;{$endif}
 
 
     {# Allocates memory for the string @var(s) and copies s as zero
     {# Allocates memory for the string @var(s) and copies s as zero
        terminated string to that allocated memory and returns a pointer
        terminated string to that allocated memory and returns a pointer
@@ -1221,13 +1222,19 @@ implementation
       end;
       end;
 
 
 
 
-    function stringdup(const s : string) : pshortstring;{$ifdef USEINLINE}inline;{$endif}
+    function stringdup(const s : shortstring) : pshortstring;{$ifdef USEINLINE}inline;{$endif}
       begin
       begin
          getmem(result,length(s)+1);
          getmem(result,length(s)+1);
          result^:=s;
          result^:=s;
       end;
       end;
 
 
 
 
+    function stringdup(const s : ansistring) : pshortstring;{$ifdef USEINLINE}inline;{$endif}
+      begin
+         getmem(result,length(s)+1);
+         result^:=s;
+      end;
+
     function CompareStr(const S1, S2: string): Integer;
     function CompareStr(const S1, S2: string): Integer;
       var
       var
         count, count1, count2: integer;
         count, count1, count2: integer;

+ 1 - 1
compiler/dbgdwarf.pas

@@ -2496,7 +2496,7 @@ implementation
             sl_absolutetype,
             sl_absolutetype,
             sl_typeconv:
             sl_typeconv:
               begin
               begin
-                currdef:=tfieldvarsym(symlist^.sym).vardef;
+                currdef:=symlist^.def;
                 { ignore, these don't change the address }
                 { ignore, these don't change the address }
               end;
               end;
             sl_vec:
             sl_vec:

+ 3 - 3
compiler/entfile.pas

@@ -196,8 +196,8 @@ type
     compiler : word;
     compiler : word;
     cpu      : word;
     cpu      : word;
     target   : word;
     target   : word;
-    flags    : longint;
-    size     : longint; { size of the ppufile without header }
+    flags    : dword;
+    size     : dword; { size of the ppufile without header }
   end;
   end;
   pentryheader=^tentryheader;
   pentryheader=^tentryheader;
 
 
@@ -668,7 +668,7 @@ begin
    end;
    end;
   if bufsize-bufidx>=sizeof(dword) then
   if bufsize-bufidx>=sizeof(dword) then
     begin
     begin
-      result:=Unaligned(plongint(@buf[bufidx])^);
+      result:=Unaligned(pdword(@buf[bufidx])^);
       inc(bufidx,sizeof(longint));
       inc(bufidx,sizeof(longint));
     end
     end
   else
   else

+ 8 - 1
compiler/globals.pas

@@ -164,6 +164,8 @@ interface
 
 
          disabledircache : boolean;
          disabledircache : boolean;
 
 
+         tlsmodel : ttlsmodel;
+
 {$if defined(i8086)}
 {$if defined(i8086)}
          x86memorymodel  : tx86memorymodel;
          x86memorymodel  : tx86memorymodel;
 {$endif defined(i8086)}
 {$endif defined(i8086)}
@@ -404,6 +406,9 @@ interface
           procalign : 0;
           procalign : 0;
           loopalign : 0;
           loopalign : 0;
           jumpalign : 0;
           jumpalign : 0;
+          jumpalignmax    : 0;
+          coalescealign   : 0;
+          coalescealignmax: 0;
           constalignmin : 0;
           constalignmin : 0;
           constalignmax : 0;
           constalignmax : 0;
           varalignmin : 0;
           varalignmin : 0;
@@ -553,6 +558,8 @@ interface
         minfpconstprec : s32real;
         minfpconstprec : s32real;
 
 
         disabledircache : false;
         disabledircache : false;
+
+        tlsmodel : tlsm_none;
 {$if defined(i8086)}
 {$if defined(i8086)}
         x86memorymodel : mm_small;
         x86memorymodel : mm_small;
 {$endif defined(i8086)}
 {$endif defined(i8086)}
@@ -1417,7 +1424,7 @@ implementation
        if localexepath='' then
        if localexepath='' then
         begin
         begin
           hs1 := ExtractFileName(exeName);
           hs1 := ExtractFileName(exeName);
-          ChangeFileExt(hs1,source_info.exeext);
+	  hs1 := ChangeFileExt(hs1,source_info.exeext);
 {$ifdef macos}
 {$ifdef macos}
           FindFile(hs1,GetEnvironmentVariable('Commands'),false,localExepath);
           FindFile(hs1,GetEnvironmentVariable('Commands'),false,localExepath);
 {$else macos}
 {$else macos}

+ 10 - 1
compiler/globtype.pas

@@ -700,10 +700,19 @@ interface
            for i8086 cpu huge memory model,
            for i8086 cpu huge memory model,
            as this changes SP register it requires special handling
            as this changes SP register it requires special handling
            to restore DS segment register  }
            to restore DS segment register  }
-         pi_has_open_array_parameter
+         pi_has_open_array_parameter,
+         { subroutine uses threadvars }
+         pi_uses_threadvar
        );
        );
        tprocinfoflags=set of tprocinfoflag;
        tprocinfoflags=set of tprocinfoflag;
 
 
+       ttlsmodel = (tlsm_none,
+         { elf tls model: works for all kind of code and thread vars }
+         tlsm_general,
+         { elf tls model: works only if the thread vars are declared and used in the same executable }
+         tlsm_local
+       );
+
     type
     type
       { float types -- warning, this enum/order is used internally by the RTL
       { float types -- warning, this enum/order is used internally by the RTL
         as well in rtl/inc/real2str.inc }
         as well in rtl/inc/real2str.inc }

+ 4 - 3
compiler/hlcgobj.pas

@@ -4567,13 +4567,14 @@ implementation
       cleanup_regvars(list);
       cleanup_regvars(list);
 {$endif OLDREGVARS}
 {$endif OLDREGVARS}
 
 
-      { finalize temporary data }
-      finalizetempvariables(list);
-
       { finalize paras data }
       { finalize paras data }
       if assigned(current_procinfo.procdef.parast) and
       if assigned(current_procinfo.procdef.parast) and
          not(po_assembler in current_procinfo.procdef.procoptions) then
          not(po_assembler in current_procinfo.procdef.procoptions) then
         current_procinfo.procdef.parast.SymList.ForEachCall(@final_paras,list);
         current_procinfo.procdef.parast.SymList.ForEachCall(@final_paras,list);
+
+      { finalize temporary data }
+      finalizetempvariables(list);
+
       current_procinfo:=old_current_procinfo;
       current_procinfo:=old_current_procinfo;
     end;
     end;
 
 

+ 15 - 2
compiler/htypechk.pas

@@ -183,7 +183,7 @@ interface
 
 
     { sets varsym varstate field correctly }
     { sets varsym varstate field correctly }
     type
     type
-      tvarstateflag = (vsf_must_be_valid,vsf_use_hints);
+      tvarstateflag = (vsf_must_be_valid,vsf_use_hints,vsf_use_hint_for_string_result);
       tvarstateflags = set of tvarstateflag;
       tvarstateflags = set of tvarstateflag;
     procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
     procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
 
 
@@ -1299,7 +1299,20 @@ implementation
                                begin
                                begin
                                  if (vo_is_funcret in hsym.varoptions) then
                                  if (vo_is_funcret in hsym.varoptions) then
                                    begin
                                    begin
-                                     if (vsf_use_hints in varstateflags) then
+                                     { An uninitialized function Result of a managed type needs special handling.
+                                       When passing it as a var parameter a warning need to be emitted, since a user
+                                       may expect Result to be empty (nil) by default as it happens with local vars
+                                       of a managed type. But this is not true for Result and may lead to serious issues.
+
+                                       The only exception is SetLength(Result, ?) for a string Result. A user always
+                                       expects undefined contents of the string after calling SetLength(). In such
+                                       case a hint need to be emitted.
+                                     }
+                                     if is_managed_type(hsym.vardef) then
+                                       if not ( is_string(hsym.vardef) and (vsf_use_hint_for_string_result in varstateflags) ) then
+                                         exclude(varstateflags,vsf_use_hints);
+
+                                     if vsf_use_hints in varstateflags then
                                        begin
                                        begin
                                          if is_managed_type(hsym.vardef) then
                                          if is_managed_type(hsym.vardef) then
                                            CGMessagePos(p.fileinfo,sym_h_managed_function_result_uninitialized)
                                            CGMessagePos(p.fileinfo,sym_h_managed_function_result_uninitialized)

+ 8 - 223
compiler/i386/aoptcpu.pas

@@ -152,9 +152,7 @@ end;
 
 
 procedure TCPUAsmOptimizer.PrePeepHoleOpts;
 procedure TCPUAsmOptimizer.PrePeepHoleOpts;
 var
 var
-  p,hp1: tai;
-  l: aint;
-  tmpRef: treference;
+  p: tai;
 begin
 begin
   p := BlockStart;
   p := BlockStart;
   while (p <> BlockEnd) Do
   while (p <> BlockEnd) Do
@@ -169,205 +167,8 @@ begin
               end;
               end;
             case taicpu(p).opcode Of
             case taicpu(p).opcode Of
               A_IMUL:
               A_IMUL:
-                {changes certain "imul const, %reg"'s to lea sequences}
-                begin
-                  if (taicpu(p).oper[0]^.typ = Top_Const) and
-                     (taicpu(p).oper[1]^.typ = Top_Reg) and
-                     (taicpu(p).opsize = S_L) then
-                    if (taicpu(p).oper[0]^.val = 1) then
-                      if (taicpu(p).ops = 2) then
-                       {remove "imul $1, reg"}
-                        begin
-                          hp1 := tai(p.Next);
-                          asml.remove(p);
-                          p.free;
-                          p := hp1;
-                          continue;
-                        end
-                      else
-                       {change "imul $1, reg1, reg2" to "mov reg1, reg2"}
-                        begin
-                          hp1 := taicpu.Op_Reg_Reg(A_MOV, S_L, taicpu(p).oper[1]^.reg,taicpu(p).oper[2]^.reg);
-                          InsertLLItem(p.previous, p.next, hp1);
-                          p.free;
-                          p := hp1;
-                        end
-                    else if
-                     ((taicpu(p).ops <= 2) or
-                      (taicpu(p).oper[2]^.typ = Top_Reg)) and
-                     (taicpu(p).oper[0]^.val <= 12) and
-                     not(cs_opt_size in current_settings.optimizerswitches) and
-                     (not(GetNextInstruction(p, hp1)) or
-                       {GetNextInstruction(p, hp1) and}
-                       not((tai(hp1).typ = ait_instruction) and
-                           ((taicpu(hp1).opcode=A_Jcc) and
-                            (taicpu(hp1).condition in [C_O,C_NO])))) then
-                      begin
-                        reference_reset(tmpref,1,[]);
-                        case taicpu(p).oper[0]^.val Of
-                          3: begin
-                             {imul 3, reg1, reg2 to
-                                lea (reg1,reg1,2), reg2
-                              imul 3, reg1 to
-                                lea (reg1,reg1,2), reg1}
-                               TmpRef.base := taicpu(p).oper[1]^.reg;
-                               TmpRef.index := taicpu(p).oper[1]^.reg;
-                               TmpRef.ScaleFactor := 2;
-                               if (taicpu(p).ops = 2) then
-                                 hp1 := taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[1]^.reg)
-                               else
-                                 hp1 := taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[2]^.reg);
-                               InsertLLItem(p.previous, p.next, hp1);
-                               p.free;
-                               p := hp1;
-                            end;
-                         5: begin
-                            {imul 5, reg1, reg2 to
-                               lea (reg1,reg1,4), reg2
-                             imul 5, reg1 to
-                               lea (reg1,reg1,4), reg1}
-                              TmpRef.base := taicpu(p).oper[1]^.reg;
-                              TmpRef.index := taicpu(p).oper[1]^.reg;
-                              TmpRef.ScaleFactor := 4;
-                              if (taicpu(p).ops = 2) then
-                                hp1 := taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[1]^.reg)
-                              else
-                                hp1 := taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[2]^.reg);
-                              InsertLLItem(p.previous, p.next, hp1);
-                              p.free;
-                              p := hp1;
-                            end;
-                         6: begin
-                            {imul 6, reg1, reg2 to
-                               lea (,reg1,2), reg2
-                               lea (reg2,reg1,4), reg2
-                             imul 6, reg1 to
-                               lea (reg1,reg1,2), reg1
-                               add reg1, reg1}
-                              if (current_settings.optimizecputype <= cpu_386) then
-                                begin
-                                  TmpRef.index := taicpu(p).oper[1]^.reg;
-                                  if (taicpu(p).ops = 3) then
-                                    begin
-                                      TmpRef.base := taicpu(p).oper[2]^.reg;
-                                      TmpRef.ScaleFactor := 4;
-                                      hp1 :=  taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[1]^.reg);
-                                    end
-                                  else
-                                    begin
-                                      hp1 :=  taicpu.op_reg_reg(A_ADD, S_L,
-                                        taicpu(p).oper[1]^.reg,taicpu(p).oper[1]^.reg);
-                                    end;
-                                  InsertLLItem(p, p.next, hp1);
-                                  reference_reset(tmpref,2,[]);
-                                  TmpRef.index := taicpu(p).oper[1]^.reg;
-                                  TmpRef.ScaleFactor := 2;
-                                  if (taicpu(p).ops = 3) then
-                                    begin
-                                      TmpRef.base := NR_NO;
-                                      hp1 :=  taicpu.op_ref_reg(A_LEA, S_L, TmpRef,
-                                        taicpu(p).oper[2]^.reg);
-                                    end
-                                  else
-                                    begin
-                                      TmpRef.base := taicpu(p).oper[1]^.reg;
-                                      hp1 := taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[1]^.reg);
-                                    end;
-                                  InsertLLItem(p.previous, p.next, hp1);
-                                  p.free;
-                                  p := tai(hp1.next);
-                                end
-                            end;
-                          9: begin
-                             {imul 9, reg1, reg2 to
-                                lea (reg1,reg1,8), reg2
-                              imul 9, reg1 to
-                                lea (reg1,reg1,8), reg1}
-                               TmpRef.base := taicpu(p).oper[1]^.reg;
-                               TmpRef.index := taicpu(p).oper[1]^.reg;
-                               TmpRef.ScaleFactor := 8;
-                               if (taicpu(p).ops = 2) then
-                                 hp1 := taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[1]^.reg)
-                               else
-                                 hp1 := taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[2]^.reg);
-                               InsertLLItem(p.previous, p.next, hp1);
-                               p.free;
-                               p := hp1;
-                             end;
-                         10: begin
-                            {imul 10, reg1, reg2 to
-                               lea (reg1,reg1,4), reg2
-                               add reg2, reg2
-                             imul 10, reg1 to
-                               lea (reg1,reg1,4), reg1
-                               add reg1, reg1}
-                               if (current_settings.optimizecputype <= cpu_386) then
-                                 begin
-                                   if (taicpu(p).ops = 3) then
-                                     hp1 :=  taicpu.op_reg_reg(A_ADD, S_L,
-                                       taicpu(p).oper[2]^.reg,taicpu(p).oper[2]^.reg)
-                                   else
-                                     hp1 := taicpu.op_reg_reg(A_ADD, S_L,
-                                       taicpu(p).oper[1]^.reg,taicpu(p).oper[1]^.reg);
-                                   InsertLLItem(p, p.next, hp1);
-                                   TmpRef.base := taicpu(p).oper[1]^.reg;
-                                   TmpRef.index := taicpu(p).oper[1]^.reg;
-                                   TmpRef.ScaleFactor := 4;
-                                   if (taicpu(p).ops = 3) then
-                                      hp1 :=  taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[2]^.reg)
-                                    else
-                                      hp1 :=  taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[1]^.reg);
-                                   InsertLLItem(p.previous, p.next, hp1);
-                                   p.free;
-                                   p := tai(hp1.next);
-                                 end
-                             end;
-                         12: begin
-                            {imul 12, reg1, reg2 to
-                               lea (,reg1,4), reg2
-                               lea (reg2,reg1,8), reg2
-                             imul 12, reg1 to
-                               lea (reg1,reg1,2), reg1
-                               lea (,reg1,4), reg1}
-                               if (current_settings.optimizecputype <= cpu_386)
-                                 then
-                                   begin
-                                     TmpRef.index := taicpu(p).oper[1]^.reg;
-                                     if (taicpu(p).ops = 3) then
-                                       begin
-                                         TmpRef.base := taicpu(p).oper[2]^.reg;
-                                         TmpRef.ScaleFactor := 8;
-                                         hp1 :=  taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[2]^.reg);
-                                       end
-                                     else
-                                       begin
-                                         TmpRef.base := NR_NO;
-                                         TmpRef.ScaleFactor := 4;
-                                         hp1 :=  taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[1]^.reg);
-                                       end;
-                                     InsertLLItem(p, p.next, hp1);
-                                     reference_reset(tmpref,2,[]);
-                                     TmpRef.index := taicpu(p).oper[1]^.reg;
-                                     if (taicpu(p).ops = 3) then
-                                       begin
-                                         TmpRef.base := NR_NO;
-                                         TmpRef.ScaleFactor := 4;
-                                         hp1 :=  taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[2]^.reg);
-                                       end
-                                     else
-                                       begin
-                                         TmpRef.base := taicpu(p).oper[1]^.reg;
-                                         TmpRef.ScaleFactor := 2;
-                                         hp1 :=  taicpu.op_ref_reg(A_LEA, S_L, TmpRef, taicpu(p).oper[1]^.reg);
-                                       end;
-                                     InsertLLItem(p.previous, p.next, hp1);
-                                     p.free;
-                                     p := tai(hp1.next);
-                                   end
-                             end
-                        end;
-                      end;
-                end;
+                if PrePeepholeOptIMUL(p) then
+                  Continue;
               A_SAR,A_SHR:
               A_SAR,A_SHR:
                 if PrePeepholeOptSxx(p) then
                 if PrePeepholeOptSxx(p) then
                   continue;
                   continue;
@@ -404,10 +205,6 @@ var
   hp3,hp4: tai;
   hp3,hp4: tai;
   v:aint;
   v:aint;
 
 
-  TmpRef: TReference;
-
-  TmpBool1, TmpBool2: Boolean;
-
   function GetFinalDestination(asml: TAsmList; hp: taicpu; level: longint): boolean;
   function GetFinalDestination(asml: TAsmList; hp: taicpu; level: longint): boolean;
   {traces sucessive jumps to their final destination and sets it, e.g.
   {traces sucessive jumps to their final destination and sets it, e.g.
    je l1                je l3
    je l1                je l3
@@ -524,18 +321,18 @@ begin
             { Handle Jmp Optimizations }
             { Handle Jmp Optimizations }
             if taicpu(p).is_jmp then
             if taicpu(p).is_jmp then
               begin
               begin
-      {the following if-block removes all code between a jmp and the next label,
-        because it can never be executed}
+                { the following if-block removes all code between a jmp and the next label,
+                  because it can never be executed }
                 if (taicpu(p).opcode = A_JMP) then
                 if (taicpu(p).opcode = A_JMP) then
                   begin
                   begin
                     hp2:=p;
                     hp2:=p;
                     while GetNextInstruction(hp2, hp1) and
                     while GetNextInstruction(hp2, hp1) and
                           (hp1.typ <> ait_label) do
                           (hp1.typ <> ait_label) do
-                      if not(hp1.typ in ([ait_label,ait_align]+skipinstr)) then
+                      if not(hp1.typ in ([ait_label]+skipinstr)) then
                         begin
                         begin
                           { don't kill start/end of assembler block,
                           { don't kill start/end of assembler block,
                             no-line-info-start/end etc }
                             no-line-info-start/end etc }
-                          if hp1.typ<>ait_marker then
+                          if not(hp1.typ in [ait_align,ait_marker]) then
                             begin
                             begin
                               asml.remove(hp1);
                               asml.remove(hp1);
                               hp1.free;
                               hp1.free;
@@ -596,18 +393,6 @@ begin
             else
             else
             { All other optimizes }
             { All other optimizes }
               begin
               begin
-                for l := 0 to taicpu(p).ops-1 Do
-                  if (taicpu(p).oper[l]^.typ = top_ref) then
-                    With taicpu(p).oper[l]^.ref^ Do
-                      begin
-                        if (base = NR_NO) and
-                           (index <> NR_NO) and
-                           (scalefactor in [0,1]) then
-                          begin
-                            base := index;
-                            index := NR_NO
-                          end
-                      end;
                 case taicpu(p).opcode Of
                 case taicpu(p).opcode Of
                   A_AND:
                   A_AND:
                     if OptPass1And(p) then
                     if OptPass1And(p) then
@@ -1012,7 +797,7 @@ end;
 
 
 procedure TCPUAsmOptimizer.PostPeepHoleOpts;
 procedure TCPUAsmOptimizer.PostPeepHoleOpts;
 var
 var
-  p,hp1,hp2: tai;
+  p,hp1: tai;
 begin
 begin
   p := BlockStart;
   p := BlockStart;
   ClearUsedRegs;
   ClearUsedRegs;

+ 0 - 4
compiler/i386/aoptcpub.pas

@@ -70,10 +70,6 @@ Const
 
 
   MaxCh = 3;
   MaxCh = 3;
 
 
-{ the maximum number of operands an instruction has }
-
-  MaxOps = 3;
-
 {Oper index of operand that contains the source (reference) with a load }
 {Oper index of operand that contains the source (reference) with a load }
 {instruction                                                            }
 {instruction                                                            }
 
 

+ 8 - 1
compiler/i386/cpupi.pas

@@ -95,11 +95,18 @@ unit cpupi;
           para_stack_size := 0;
           para_stack_size := 0;
       end;
       end;
 
 
+
     procedure tcpuprocinfo.allocate_got_register(list: tasmlist);
     procedure tcpuprocinfo.allocate_got_register(list: tasmlist);
       begin
       begin
         if (cs_create_pic in current_settings.moduleswitches) then
         if (cs_create_pic in current_settings.moduleswitches) then
           begin
           begin
-            got := cg.getaddressregister(list);
+            if pi_uses_threadvar in flags then
+              begin
+                cg.getcpuregister(list,NR_EBX);
+                got := NR_EBX;
+              end
+            else
+              got := cg.getaddressregister(list);
           end;
           end;
       end;
       end;
 
 

+ 3 - 5
compiler/i386/n386flw.pas

@@ -44,7 +44,7 @@ interface
     ti386tryfinallynode=class(tcgtryfinallynode)
     ti386tryfinallynode=class(tcgtryfinallynode)
       finalizepi: tcgprocinfo;
       finalizepi: tcgprocinfo;
       constructor create(l,r:TNode);override;
       constructor create(l,r:TNode);override;
-      constructor create_implicit(l,r,_t1:TNode);override;
+      constructor create_implicit(l,r:TNode);override;
       function pass_1: tnode;override;
       function pass_1: tnode;override;
       function simplify(forinline: boolean): tnode;override;
       function simplify(forinline: boolean): tnode;override;
       procedure pass_generate_code;override;
       procedure pass_generate_code;override;
@@ -183,9 +183,9 @@ constructor ti386tryfinallynode.create(l, r: TNode);
     include(finalizepi.flags,pi_uses_exceptions);
     include(finalizepi.flags,pi_uses_exceptions);
   end;
   end;
 
 
-constructor ti386tryfinallynode.create_implicit(l, r, _t1: TNode);
+constructor ti386tryfinallynode.create_implicit(l, r: TNode);
   begin
   begin
-    inherited create_implicit(l, r, _t1);
+    inherited create_implicit(l, r);
     if (target_info.system<>system_i386_win32) then
     if (target_info.system<>system_i386_win32) then
       exit;
       exit;
 
 
@@ -247,8 +247,6 @@ function ti386tryfinallynode.simplify(forinline: boolean): tnode;
         if implicitframe then
         if implicitframe then
           begin
           begin
             current_procinfo.finalize_procinfo:=finalizepi;
             current_procinfo.finalize_procinfo:=finalizepi;
-            { don't leave dangling pointer }
-            tcgprocinfo(current_procinfo).final_asmnode:=nil;
           end;
           end;
       end;
       end;
   end;
   end;

+ 0 - 4
compiler/i8086/aoptcpub.pas

@@ -70,10 +70,6 @@ Const
 
 
   MaxCh = 3;
   MaxCh = 3;
 
 
-{ the maximum number of operands an instruction has }
-
-  MaxOps = 3;
-
 {Oper index of operand that contains the source (reference) with a load }
 {Oper index of operand that contains the source (reference) with a load }
 {instruction                                                            }
 {instruction                                                            }
 
 

+ 4 - 0
compiler/i8086/cgcpu.pas

@@ -121,6 +121,10 @@ unit cgcpu;
        tgobj,
        tgobj,
        hlcgobj;
        hlcgobj;
 
 
+{ Range check must be disabled explicitly as the code uses
+  implicit typecast to aint troughout }
+{$R-}
+
     function use_push(const cgpara:tcgpara):boolean;
     function use_push(const cgpara:tcgpara):boolean;
       begin
       begin
         result:=(not paramanager.use_fixed_stack) and
         result:=(not paramanager.use_fixed_stack) and

+ 0 - 4
compiler/jvm/aoptcpub.pas

@@ -71,10 +71,6 @@ Const
 
 
   MaxCh = 2;
   MaxCh = 2;
 
 
-{ the maximum number of operands an instruction has }
-
-  MaxOps = 2;
-
 {Oper index of operand that contains the source (reference) with a load }
 {Oper index of operand that contains the source (reference) with a load }
 {instruction                                                            }
 {instruction                                                            }
 
 

+ 2 - 2
compiler/llvm/nllvmmem.pas

@@ -48,7 +48,7 @@ interface
         procedure pass_generate_code; override;
         procedure pass_generate_code; override;
         procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); override;
         procedure update_reference_reg_mul(maybe_const_reg: tregister; regsize: tdef; l: aint); override;
         procedure update_reference_reg_packed(maybe_const_reg: tregister; regsize: tdef; l: aint); override;
         procedure update_reference_reg_packed(maybe_const_reg: tregister; regsize: tdef; l: aint); override;
-        procedure update_reference_offset(var ref: treference; index, mulsize: aint); override;
+        procedure update_reference_offset(var ref: treference; index, mulsize: ASizeInt); override;
       end;
       end;
 
 
 
 
@@ -294,7 +294,7 @@ implementation
     end;
     end;
 
 
 
 
-  procedure tllvmvecnode.update_reference_offset(var ref: treference; index, mulsize: aint);
+  procedure tllvmvecnode.update_reference_offset(var ref: treference; index, mulsize: ASizeInt);
     begin
     begin
       if not is_packed_array(left.resultdef) or
       if not is_packed_array(left.resultdef) or
          not (tarraydef(left.resultdef).elementdef.typ in [enumdef,orddef]) then
          not (tarraydef(left.resultdef).elementdef.typ in [enumdef,orddef]) then

+ 10 - 3
compiler/m68k/aoptcpu.pas

@@ -49,6 +49,9 @@ unit aoptcpu;
     uses
     uses
       cutils, aasmcpu, cgutils, globals, verbose, cpuinfo, itcpugas;
       cutils, aasmcpu, cgutils, globals, verbose, cpuinfo, itcpugas;
 
 
+{ Range check must be disabled explicitly as conversions between signed and unsigned
+  32-bit values are done without explicit typecasts }
+{$R-}
 
 
     function opname(var p: tai): string;
     function opname(var p: tai): string;
       begin
       begin
@@ -139,7 +142,7 @@ unit aoptcpu;
       result:=false;
       result:=false;
 
 
       if GetNextInstruction(p,next) and 
       if GetNextInstruction(p,next) and 
-         (taicpu(next).typ = ait_instruction) and
+         (next.typ = ait_instruction) and
          (taicpu(next).opcode = taicpu(p).opcode) and
          (taicpu(next).opcode = taicpu(p).opcode) and
          (taicpu(p).opsize = taicpu(next).opsize) and
          (taicpu(p).opsize = taicpu(next).opsize) and
          (taicpu(p).oper[1]^.typ = top_reg) and
          (taicpu(p).oper[1]^.typ = top_reg) and
@@ -163,8 +166,10 @@ unit aoptcpu;
                     if MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) then
                     if MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) then
                       begin
                       begin
                         DebugMsg('Optimizer: '+opstr+' + '+opstr+' removed',p);
                         DebugMsg('Optimizer: '+opstr+' + '+opstr+' removed',p);
+			GetNextInstruction(p,next);
                         asml.remove(p);
                         asml.remove(p);
                         p.free;
                         p.free;
+			p:=next;
                       end
                       end
                     else
                     else
                       DebugMsg('Optimizer: '+opstr+' + '+opstr+' to '+opstr+' #1',p)
                       DebugMsg('Optimizer: '+opstr+' + '+opstr+' to '+opstr+' #1',p)
@@ -199,9 +204,9 @@ unit aoptcpu;
         end;
         end;
 
 
       if GetNextInstruction(p,next) and
       if GetNextInstruction(p,next) and
-         (taicpu(next).typ = ait_instruction) and
+         (next.typ = ait_instruction) and
          GetNextInstruction(next,next2) and
          GetNextInstruction(next,next2) and
-         (taicpu(next2).typ = ait_instruction) and
+         (next2.typ = ait_instruction) and
          (taicpu(next).opcode <> taicpu(p).opcode) and
          (taicpu(next).opcode <> taicpu(p).opcode) and
          (taicpu(next2).opcode = taicpu(p).opcode) and
          (taicpu(next2).opcode = taicpu(p).opcode) and
          (taicpu(p).oper[0]^.typ = top_reg) and
          (taicpu(p).oper[0]^.typ = top_reg) and
@@ -266,8 +271,10 @@ unit aoptcpu;
                    (taicpu(p).oper[0]^.ref^.offset = 0) then
                    (taicpu(p).oper[0]^.ref^.offset = 0) then
                   begin
                   begin
                     DebugMsg('Optimizer: LEA 0(Ax),Ax removed',p);
                     DebugMsg('Optimizer: LEA 0(Ax),Ax removed',p);
+		    GetNextInstruction(p,next);
                     asml.remove(p);
                     asml.remove(p);
                     p.free;
                     p.free;
+		    p:=next;
                     result:=true;
                     result:=true;
                   end;
                   end;
               { Address register sub/add can be replaced with ADDQ/SUBQ or LEA if the value is in the
               { Address register sub/add can be replaced with ADDQ/SUBQ or LEA if the value is in the

+ 0 - 4
compiler/m68k/aoptcpub.pas

@@ -74,10 +74,6 @@ Const
 
 
   MaxCh = 3;
   MaxCh = 3;
 
 
-{ the maximum number of operands an instruction has }
-
-  MaxOps = 3;
-
 {Oper index of operand that contains the source (reference) with a load }
 {Oper index of operand that contains the source (reference) with a load }
 {instruction                                                            }
 {instruction                                                            }
 
 

+ 3 - 0
compiler/m68k/cgcpu.pas

@@ -138,6 +138,9 @@ unit cgcpu;
        symsym,symtable,defutil,paramgr,procinfo,
        symsym,symtable,defutil,paramgr,procinfo,
        rgobj,tgobj,rgcpu,fmodule;
        rgobj,tgobj,rgcpu,fmodule;
 
 
+{ Range check must be disabled explicitly as conversions between signed and unsigned
+  32-bit values are done without explicit typecasts }
+{$R-}
 
 
     const
     const
       { opcode table lookup }
       { opcode table lookup }

+ 5 - 5
compiler/machoutils.pas

@@ -255,10 +255,10 @@ uses
 
 
     function AllocMachoWriter(cputarget: cpu_type_t; ARawWriter: TRawWriter; AllowFreeWriter: Boolean): TMachoWriter;
     function AllocMachoWriter(cputarget: cpu_type_t; ARawWriter: TRawWriter; AllowFreeWriter: Boolean): TMachoWriter;
 
 
-    function sizeMachHeader(cputarget: cpu_type_t): integer; inline;
-    function sizeSegment(cputarget: cpu_type_t): integer; inline;
-    function sizeSection(cputarget: cpu_type_t): integer; inline;
-    function sizeNList(cputarget: cpu_type_t): integer; inline;
+    function sizeMachHeader(cputarget: cpu_type_t): integer;
+    function sizeSegment(cputarget: cpu_type_t): integer;
+    function sizeSection(cputarget: cpu_type_t): integer;
+    function sizeNList(cputarget: cpu_type_t): integer;
 
 
     function AlignAddr(cputarget: cpu_type_t; addr: qword): qword;
     function AlignAddr(cputarget: cpu_type_t; addr: qword): qword;
 
 
@@ -523,7 +523,7 @@ const
     end;
     end;
 
 
 
 
-  function sizeNList(cputarget: cpu_type_t): integer; inline;
+  function sizeNList(cputarget: cpu_type_t): integer;
     begin
     begin
       Result:=is64NlistSize[ cputarget and CPU_ARCH_ABI64 > 0];
       Result:=is64NlistSize[ cputarget and CPU_ARCH_ABI64 > 0];
     end;
     end;

+ 0 - 4
compiler/mips/aoptcpub.pas

@@ -69,10 +69,6 @@ Const
 
 
   MaxCh = 3;
   MaxCh = 3;
 
 
-{ the maximum number of operands an instruction has }
-
-  MaxOps = 3;
-
 {Oper index of operand that contains the source (reference) with a load }
 {Oper index of operand that contains the source (reference) with a load }
 {instruction                                                            }
 {instruction                                                            }
 
 

+ 1 - 1
compiler/msg/errorct.msg

@@ -719,7 +719,7 @@ parser_e_function_already_declared_public_forward=03120_E_La funci
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_No es poden utilitzar EXPORT i EXTERNAL conjuntament
 parser_e_not_external_and_export=03121_E_No es poden utilitzar EXPORT i EXTERNAL conjuntament
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_Encara no es permet "$1" dins de procediment/funció inserits
+parser_n_not_supported_for_inline=03123_N_Encara no es permet "$1" dins de procediment/funció inserits
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_S'ha deshabilitat l'inseriment
 parser_h_inlining_disabled=03124_H_S'ha deshabilitat l'inseriment
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errord.msg

@@ -845,7 +845,7 @@ parser_e_function_already_declared_public_forward=03120_E_Funktion ist bereits a
 % declaration in the \var{implementation} section.
 % declaration in the \var{implementation} section.
 parser_e_not_external_and_export=03121_E_Kann nicht EXPORT und EXTERNAL gleichzeitig benutzen
 parser_e_not_external_and_export=03121_E_Kann nicht EXPORT und EXTERNAL gleichzeitig benutzen
 % These two procedure directives are mutually exclusive.
 % These two procedure directives are mutually exclusive.
-parser_h_not_supported_for_inline=03123_H_$1 noch nicht innerhalb von inline Prozeduren/Funktionen unterst�tzt
+parser_n_not_supported_for_inline=03123_N_$1 noch nicht innerhalb von inline Prozeduren/Funktionen unterst�tzt
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining deaktiviert
 parser_h_inlining_disabled=03124_H_Inlining deaktiviert
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorda.msg

@@ -844,7 +844,7 @@ parser_e_function_already_declared_public_forward=03120_E_Funktionen "$1" er all
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_Kan ikke bruge både EXPORT og EXTERNAL
 parser_e_not_external_and_export=03121_E_Kan ikke bruge både EXPORT og EXTERNAL
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_Deklarationen "$1" er endnu ikke understøttet i inline procedurer/funktioner
+parser_n_not_supported_for_inline=03123_N_Deklarationen "$1" er endnu ikke understøttet i inline procedurer/funktioner
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining slået fra
 parser_h_inlining_disabled=03124_H_Inlining slået fra
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errordu.msg

@@ -845,7 +845,7 @@ parser_e_function_already_declared_public_forward=03120_E_Funktion ist bereits a
 % declaration in the \var{implementation} section.
 % declaration in the \var{implementation} section.
 parser_e_not_external_and_export=03121_E_Kann nicht EXPORT und EXTERNAL gleichzeitig benutzen
 parser_e_not_external_and_export=03121_E_Kann nicht EXPORT und EXTERNAL gleichzeitig benutzen
 % These two procedure directives are mutually exclusive.
 % These two procedure directives are mutually exclusive.
-parser_h_not_supported_for_inline=03123_H_$1 noch nicht innerhalb von inline Prozeduren/Funktionen unterstützt
+parser_n_not_supported_for_inline=03123_N_$1 noch nicht innerhalb von inline Prozeduren/Funktionen unterstützt
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining deaktiviert
 parser_h_inlining_disabled=03124_H_Inlining deaktiviert
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errore.msg

@@ -829,7 +829,7 @@ parser_e_function_already_declared_public_forward=03120_E_Function is already de
 % declaration in the \var{implementation} section.
 % declaration in the \var{implementation} section.
 parser_e_not_external_and_export=03121_E_Cannot use both EXPORT and EXTERNAL
 parser_e_not_external_and_export=03121_E_Cannot use both EXPORT and EXTERNAL
 % These two procedure directives are mutually exclusive.
 % These two procedure directives are mutually exclusive.
-parser_h_not_supported_for_inline=03123_H_"$1" not yet supported inside inline procedure/function
+parser_n_not_supported_for_inline=03123_N_"$1" not yet supported inside inline procedure/function
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining disabled
 parser_h_inlining_disabled=03124_H_Inlining disabled
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errores.msg

@@ -823,7 +823,7 @@ parser_e_function_already_declared_public_forward=03120_E_La funci
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_No se pueden usar ambos EXPORT y EXTERNAL
 parser_e_not_external_and_export=03121_E_No se pueden usar ambos EXPORT y EXTERNAL
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_"$1" aún no soportado en procedimientos/funciones inline
+parser_n_not_supported_for_inline=03123_N_"$1" aún no soportado en procedimientos/funciones inline
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining deshabilitado
 parser_h_inlining_disabled=03124_H_Inlining deshabilitado
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorf.msg

@@ -740,7 +740,7 @@ parser_e_not_external_and_export=03121_E_EXPORT et EXTERNAL sont incompatibles
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
 parser_e_name_keyword_expected=03122_E_Le mot r‚serv‚ NAME est requis ici
 parser_e_name_keyword_expected=03122_E_Le mot r‚serv‚ NAME est requis ici
 % The definition of an external variable needs a \var{name} clause.
 % The definition of an external variable needs a \var{name} clause.
-parser_h_not_supported_for_inline=03123_H_$1 n'est pas support‚ pour des fonctions INLINE
+parser_n_not_supported_for_inline=03123_N_$1 n'est pas support‚ pour des fonctions INLINE
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining d‚sactiv‚
 parser_h_inlining_disabled=03124_H_Inlining d‚sactiv‚
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorfi.msg

@@ -834,7 +834,7 @@ parser_e_function_already_declared_public_forward=03120_E_La fonction "$1" est d
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_Impossible d'utiliser à la fois EXPORT et EXTERNAL
 parser_e_not_external_and_export=03121_E_Impossible d'utiliser à la fois EXPORT et EXTERNAL
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_"$1" n'est pas encore supporté à l'intérieur de procédures/fonctions INLINE
+parser_n_not_supported_for_inline=03123_N_"$1" n'est pas encore supporté à l'intérieur de procédures/fonctions INLINE
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining désactivé
 parser_h_inlining_disabled=03124_H_Inlining désactivé
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorhe.msg

@@ -764,7 +764,7 @@ parser_e_function_already_declared_public_forward=03120_E_
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_ìà ðéúï ìäùúîù âí á EXPORT åâí EXTERNAL
 parser_e_not_external_and_export=03121_E_ìà ðéúï ìäùúîù âí á EXPORT åâí EXTERNAL
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_"$1" àéðå ðúîê òãééï áúåê ôåð÷öéú/ùâøú inline
+parser_n_not_supported_for_inline=03123_N_"$1" àéðå ðúîê òãééï áúåê ôåð÷öéú/ùâøú inline
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_äùéîåù äéùéø îáåèì
 parser_h_inlining_disabled=03124_H_äùéîåù äéùéø îáåèì
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorheu.msg

@@ -828,7 +828,7 @@ parser_e_function_already_declared_public_forward=03120_E_הגדרת הפונק
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_לא ניתן להשתמש גם ב EXPORT וגם EXTERNAL
 parser_e_not_external_and_export=03121_E_לא ניתן להשתמש גם ב EXPORT וגם EXTERNAL
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_"$1" אינו נתמך עדיין בתוך פונקצית/שגרת inline
+parser_n_not_supported_for_inline=03123_N_"$1" אינו נתמך עדיין בתוך פונקצית/שגרת inline
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_השימוש הישיר מבוטל
 parser_h_inlining_disabled=03124_H_השימוש הישיר מבוטל
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorid.msg

@@ -827,7 +827,7 @@ parser_e_function_already_declared_public_forward=03120_E_Fungsi sudah dideklara
 % \var{forward} dalam seksi \var{implmentation}.
 % \var{forward} dalam seksi \var{implmentation}.
 parser_e_not_external_and_export=03121_E_Tidak bisa menggunakan EXPORT dan EXTERNAL
 parser_e_not_external_and_export=03121_E_Tidak bisa menggunakan EXPORT dan EXTERNAL
 % Dua prosedur ini adalah mutual eksklusif
 % Dua prosedur ini adalah mutual eksklusif
-parser_h_not_supported_for_inline=03123_H_"$1" belum didukung di dalam inline procedure/function
+parser_n_not_supported_for_inline=03123_N_"$1" belum didukung di dalam inline procedure/function
 % Inline procedures tidak mendukung deklarasi ini.
 % Inline procedures tidak mendukung deklarasi ini.
 parser_h_inlining_disabled=03124_H_Inlining dimatikan
 parser_h_inlining_disabled=03124_H_Inlining dimatikan
 % Inlining dari prosedur dimatikan.
 % Inlining dari prosedur dimatikan.

+ 1 - 1
compiler/msg/erroriu.msg

@@ -771,7 +771,7 @@ parser_e_function_already_declared_public_forward=03120_E_La funzione 
 % declaration in the \var{implementation} section.
 % declaration in the \var{implementation} section.
 parser_e_not_external_and_export=03121_E_Non si possono usare sia EXPORT che EXTERNAL
 parser_e_not_external_and_export=03121_E_Non si possono usare sia EXPORT che EXTERNAL
 % These two procedure directives are mutually exclusive.
 % These two procedure directives are mutually exclusive.
-parser_h_not_supported_for_inline=03123_H_"$1" non è ancora supportata all'interno di procedure o funzioni inline
+parser_n_not_supported_for_inline=03123_N_"$1" non è ancora supportata all'interno di procedure o funzioni inline
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining disabilitato
 parser_h_inlining_disabled=03124_H_Inlining disabilitato
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorn.msg

@@ -828,7 +828,7 @@ parser_e_function_already_declared_public_forward=03120_E_Functie is al publiek/
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_Kan niet zowel EXPORT als EXTERNAL gebruiken
 parser_e_not_external_and_export=03121_E_Kan niet zowel EXPORT als EXTERNAL gebruiken
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_$1 wordt niet ondersteund voor inline procedure/functie
+parser_n_not_supported_for_inline=03123_N_$1 wordt niet ondersteund voor inline procedure/functie
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining uitgeschakeld
 parser_h_inlining_disabled=03124_H_Inlining uitgeschakeld
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorpl.msg

@@ -726,7 +726,7 @@ parser_e_function_already_declared_public_forward=03120_E_Funkcja jest ju
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_Nie mo¾na u¾y† jednocze˜nie EXPORT i EXTERNAL
 parser_e_not_external_and_export=03121_E_Nie mo¾na u¾y† jednocze˜nie EXPORT i EXTERNAL
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_$1 nieobsˆugiwane w procedurze/funkcji inline
+parser_n_not_supported_for_inline=03123_N_$1 nieobsˆugiwane w procedurze/funkcji inline
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inline wyˆ¥czone
 parser_h_inlining_disabled=03124_H_Inline wyˆ¥czone
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorpli.msg

@@ -726,7 +726,7 @@ parser_e_function_already_declared_public_forward=03120_E_Funkcja jest ju
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_Nie mo¿na u¿yæ jednocze¶nie EXPORT i EXTERNAL
 parser_e_not_external_and_export=03121_E_Nie mo¿na u¿yæ jednocze¶nie EXPORT i EXTERNAL
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_$1 nieobs³ugiwane w procedurze/funkcji inline
+parser_n_not_supported_for_inline=03123_N_$1 nieobs³ugiwane w procedurze/funkcji inline
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inline wy³±czone
 parser_h_inlining_disabled=03124_H_Inline wy³±czone
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorpt.msg

@@ -775,7 +775,7 @@ parser_e_function_already_declared_public_forward=03120_E_Fun
 % declaration in the \var{implementation} section.
 % declaration in the \var{implementation} section.
 parser_e_not_external_and_export=03121_E_Imposs¡vel usar ambos EXPORT e EXTERNAL
 parser_e_not_external_and_export=03121_E_Imposs¡vel usar ambos EXPORT e EXTERNAL
 % These two procedure directives are mutually exclusive.
 % These two procedure directives are mutually exclusive.
-parser_h_not_supported_for_inline=03123_H_"$1" nÆo suportado ainda dentro procedimento/fun‡Æo em linha
+parser_n_not_supported_for_inline=03123_N_"$1" nÆo suportado ainda dentro procedimento/fun‡Æo em linha
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Procedimentos em linha desabilitados
 parser_h_inlining_disabled=03124_H_Procedimentos em linha desabilitados
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorptu.msg

@@ -821,7 +821,7 @@ parser_e_function_already_declared_public_forward=03120_E_Função já declarada
 % declaration in the \var{implementation} section.
 % declaration in the \var{implementation} section.
 parser_e_not_external_and_export=03121_E_Impossível usar ambos EXPORT e EXTERNAL
 parser_e_not_external_and_export=03121_E_Impossível usar ambos EXPORT e EXTERNAL
 % These two procedure directives are mutually exclusive.
 % These two procedure directives are mutually exclusive.
-parser_h_not_supported_for_inline=03123_H_"$1" não suportado ainda dentro procedimento/função em linha
+parser_n_not_supported_for_inline=03123_N_"$1" não suportado ainda dentro procedimento/função em linha
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Procedimentos em linha desabilitados
 parser_h_inlining_disabled=03124_H_Procedimentos em linha desabilitados
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msg/errorr.msg

@@ -713,7 +713,7 @@ parser_e_function_already_declared_public_forward=03120_E_
 % ¢ ᥪ樨 \var{implmentation}.
 % ¢ ᥪ樨 \var{implmentation}.
 parser_e_not_external_and_export=03121_E_H¥«ì§ï ¨á¯®«ì§®¢ âì EXPORT ᮢ¬¥áâ­® á EXTERNAL
 parser_e_not_external_and_export=03121_E_H¥«ì§ï ¨á¯®«ì§®¢ âì EXPORT ᮢ¬¥áâ­® á EXTERNAL
 % ⨠¤¢¥ ¤¨à¥ªâ¨¢ë ïîâáï ¢§ ¨¬®¨áª«îç î騬¨
 % ⨠¤¢¥ ¤¨à¥ªâ¨¢ë ïîâáï ¢§ ¨¬®¨áª«îç î騬¨
-parser_h_not_supported_for_inline=03123_H_"$1" ­¥ ¯®¤¤¥p¦¨¢ ¥âáï ¢­yâp¨ INLINE ¯p®æ¥¤ypë/äy­ªæ¨¨
+parser_n_not_supported_for_inline=03123_N_"$1" ­¥ ¯®¤¤¥p¦¨¢ ¥âáï ¢­yâp¨ INLINE ¯p®æ¥¤ypë/äy­ªæ¨¨
 % ‚áâà ¨¢ ¥¬ë¥ ¯à®æ¥¤ãàë ­¥ ¯®¤¤¥à¦¨¢ îâ íâ®â ⨯ ®¡ê¥­¨ï.
 % ‚áâà ¨¢ ¥¬ë¥ ¯à®æ¥¤ãàë ­¥ ¯®¤¤¥à¦¨¢ îâ íâ®â ⨯ ®¡ê¥­¨ï.
 parser_h_inlining_disabled=03124_H_‚áâà ¨¢ ­¨¥ (INLINE) ®âª«î祭®
 parser_h_inlining_disabled=03124_H_‚áâà ¨¢ ­¨¥ (INLINE) ®âª«î祭®
 % ‚áâà ¨¢ ­¨¥ ¯à®æ¥¤ãà ®âª«î祭®.
 % ‚áâà ¨¢ ­¨¥ ¯à®æ¥¤ãà ®âª«î祭®.

+ 1 - 1
compiler/msg/errorru.msg

@@ -782,7 +782,7 @@ parser_e_function_already_declared_public_forward=03120_E_Функция "$1" у
 % в секции \var{implmentation}.
 % в секции \var{implmentation}.
 parser_e_not_external_and_export=03121_E_Hельзя использовать EXPORT совместно с EXTERNAL
 parser_e_not_external_and_export=03121_E_Hельзя использовать EXPORT совместно с EXTERNAL
 % Эти две директивы являются взаимоисключающими
 % Эти две директивы являются взаимоисключающими
-parser_h_not_supported_for_inline=03123_H_"$1" не поддеpживается внyтpи INLINE пpоцедypы/фyнкции
+parser_n_not_supported_for_inline=03123_N_"$1" не поддеpживается внyтpи INLINE пpоцедypы/фyнкции
 % Встраиваемые процедуры не поддерживают этот тип объявления.
 % Встраиваемые процедуры не поддерживают этот тип объявления.
 parser_h_inlining_disabled=03124_H_Встраивание (INLINE) отключено
 parser_h_inlining_disabled=03124_H_Встраивание (INLINE) отключено
 % Встраивание процедур отключено.
 % Встраивание процедур отключено.

+ 1 - 1
compiler/msg/errorues.msg

@@ -817,7 +817,7 @@ parser_e_function_already_declared_public_forward=03120_E_La función esta actua
 % declaration in the \var{implmentation} section.
 % declaration in the \var{implmentation} section.
 parser_e_not_external_and_export=03121_E_No se pueden usar ambos EXPORT y EXTERNAL
 parser_e_not_external_and_export=03121_E_No se pueden usar ambos EXPORT y EXTERNAL
 % These two procedure directives are mutually exclusive
 % These two procedure directives are mutually exclusive
-parser_h_not_supported_for_inline=03123_H_"$1" aún no soportado en procedimientos/funciones inline
+parser_n_not_supported_for_inline=03123_N_"$1" aún no soportado en procedimientos/funciones inline
 % Inline procedures don't support this declaration.
 % Inline procedures don't support this declaration.
 parser_h_inlining_disabled=03124_H_Inlining deshabilitado
 parser_h_inlining_disabled=03124_H_Inlining deshabilitado
 % Inlining of procedures is disabled.
 % Inlining of procedures is disabled.

+ 1 - 1
compiler/msgidx.inc

@@ -239,7 +239,7 @@ const
   parser_e_proc_dir_not_allowed_in_procvar=03119;
   parser_e_proc_dir_not_allowed_in_procvar=03119;
   parser_e_function_already_declared_public_forward=03120;
   parser_e_function_already_declared_public_forward=03120;
   parser_e_not_external_and_export=03121;
   parser_e_not_external_and_export=03121;
-  parser_h_not_supported_for_inline=03123;
+  parser_n_not_supported_for_inline=03123;
   parser_h_inlining_disabled=03124;
   parser_h_inlining_disabled=03124;
   parser_i_writing_browser_log=03125;
   parser_i_writing_browser_log=03125;
   parser_h_maybe_deref_caret_missing=03126;
   parser_h_maybe_deref_caret_missing=03126;

+ 1 - 1
compiler/msgtxt.inc

@@ -274,7 +274,7 @@ const msgtxt : array[0..000344,1..240] of char=(
   '03119_E_Procedure directive "$1" ','not allowed in procvar declaration'#000+
   '03119_E_Procedure directive "$1" ','not allowed in procvar declaration'#000+
   '03120_E_Function is already declared Public/Forward "$1"'#000+
   '03120_E_Function is already declared Public/Forward "$1"'#000+
   '03121_E_Cannot use both EXPORT and EXTERNAL'#000+
   '03121_E_Cannot use both EXPORT and EXTERNAL'#000+
-  '03123_H_"$1" not yet supported inside inline procedure/function'#000+
+  '03123_N_"$1" not yet supported inside inline procedure/function'#000+
   '03124_H_Inlining disabled'#000+
   '03124_H_Inlining disabled'#000+
   '03125_I_Writin','g Browser log $1'#000+
   '03125_I_Writin','g Browser log $1'#000+
   '03126_H_may be pointer dereference is missing'#000+
   '03126_H_may be pointer dereference is missing'#000+

+ 4 - 6
compiler/nadd.pas

@@ -377,11 +377,11 @@ implementation
 
 
     function taddnode.simplify(forinline : boolean) : tnode;
     function taddnode.simplify(forinline : boolean) : tnode;
 
 
-      function is_range_test(nodel, noder: taddnode; var value: tnode; var cl,cr: Tconstexprint): boolean;
+      function is_range_test(nodel, noder: taddnode; out value: tnode; var cl,cr: Tconstexprint): boolean;
         const
         const
           is_upper_test: array[ltn..gten] of boolean = (true,true,false,false);
           is_upper_test: array[ltn..gten] of boolean = (true,true,false,false);
-          inclusive_adjust: array[boolean,ltn..gten] of integer = ((1,0,-1,0),
-                                                                   (-1,0,1,0));
+          inclusive_adjust: array[boolean,ltn..gten] of integer = ((-1,0,1,0),
+                                                                   (1,0,-1,0));
         var
         var
           swapl, swapr: Boolean;
           swapl, swapr: Boolean;
           valuer: tnode;
           valuer: tnode;
@@ -1056,7 +1056,7 @@ implementation
             if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
             if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
               begin
               begin
                 { transform unsigned comparisons of (v>=x) and (v<=y)
                 { transform unsigned comparisons of (v>=x) and (v<=y)
-                  into (v-x)<(y-x)
+                  into (v-x)<=(y-x)
                 }
                 }
                 if (nodetype=andn) and
                 if (nodetype=andn) and
                    (left.nodetype in [ltn,lten,gtn,gten]) and
                    (left.nodetype in [ltn,lten,gtn,gten]) and
@@ -2964,10 +2964,8 @@ implementation
 
 
     function taddnode.first_adddynarray : tnode;
     function taddnode.first_adddynarray : tnode;
       var
       var
-        p: tnode;
         newstatement : tstatementnode;
         newstatement : tstatementnode;
         tempnode (*,tempnode2*) : ttempcreatenode;
         tempnode (*,tempnode2*) : ttempcreatenode;
-        cmpfuncname: string;
         para: tcallparanode;
         para: tcallparanode;
       begin
       begin
         result:=nil;
         result:=nil;

+ 37 - 1
compiler/nbas.pas

@@ -59,6 +59,14 @@ interface
        end;
        end;
        tspecializenodeclass = class of tspecializenode;
        tspecializenodeclass = class of tspecializenode;
 
 
+       tfinalizetempsnode = class(tnode)
+          constructor create;virtual;
+          function pass_1 : tnode;override;
+          function pass_typecheck:tnode;override;
+          function docompare(p: tnode): boolean; override;
+       end;
+       tfinalizetempsnodeclass = class of tfinalizetempsnode;
+
        tasmnode = class(tnode)
        tasmnode = class(tnode)
           p_asm : TAsmList;
           p_asm : TAsmList;
           currenttai : tai;
           currenttai : tai;
@@ -289,6 +297,7 @@ interface
        cnothingnode : tnothingnodeclass = tnothingnode;
        cnothingnode : tnothingnodeclass = tnothingnode;
        cerrornode : terrornodeclass = terrornode;
        cerrornode : terrornodeclass = terrornode;
        cspecializenode : tspecializenodeclass = tspecializenode;
        cspecializenode : tspecializenodeclass = tspecializenode;
+       cfinalizetempsnode: tfinalizetempsnodeclass = tfinalizetempsnode;
        casmnode : tasmnodeclass = tasmnode;
        casmnode : tasmnodeclass = tasmnode;
        cstatementnode : tstatementnodeclass = tstatementnode;
        cstatementnode : tstatementnodeclass = tstatementnode;
        cblocknode : tblocknodeclass = tblocknode;
        cblocknode : tblocknodeclass = tblocknode;
@@ -363,7 +372,6 @@ implementation
       end;
       end;
 
 
 
 
-
 {*****************************************************************************
 {*****************************************************************************
                              TFIRSTNOTHING
                              TFIRSTNOTHING
 *****************************************************************************}
 *****************************************************************************}
@@ -456,6 +464,34 @@ implementation
       end;
       end;
 
 
 
 
+{*****************************************************************************
+                             TFINALIZETEMPSNODE
+*****************************************************************************}
+
+    constructor tfinalizetempsnode.create;
+      begin
+        inherited create(finalizetempsn);
+      end;
+
+    function tfinalizetempsnode.pass_1: tnode;
+      begin
+        result:=nil;
+        expectloc:=LOC_VOID;
+      end;
+
+    function tfinalizetempsnode.pass_typecheck: tnode;
+      begin
+        resultdef:=voidtype;
+        result:=nil;
+      end;
+
+    function tfinalizetempsnode.docompare(p: tnode): boolean;
+      begin
+        { these nodes should never be coalesced }
+        result:=false;
+      end;
+
+
 {*****************************************************************************
 {*****************************************************************************
                             TSTATEMENTNODE
                             TSTATEMENTNODE
 *****************************************************************************}
 *****************************************************************************}

+ 42 - 12
compiler/ncal.pas

@@ -1903,18 +1903,27 @@ implementation
       var
       var
         lastinitstatement : tstatementnode;
         lastinitstatement : tstatementnode;
       begin
       begin
+        if not assigned(n) then
+          exit;
         if not assigned(callinitblock) then
         if not assigned(callinitblock) then
-          callinitblock:=internalstatements(lastinitstatement)
-        else
-          lastinitstatement:=laststatement(callinitblock);
+          begin
+            callinitblock:=internalstatements(lastinitstatement);
+            lastinitstatement.left.free;
+            lastinitstatement.left:=n;
+            firstpass(tnode(callinitblock));
+            exit;
+          end;
+        lastinitstatement:=laststatement(callinitblock);
         { all these nodes must be immediately typechecked, because this routine }
         { all these nodes must be immediately typechecked, because this routine }
         { can be called from pass_1 (i.e., after typecheck has already run) and }
         { can be called from pass_1 (i.e., after typecheck has already run) and }
         { moreover, the entire blocks themselves are also only typechecked in   }
         { moreover, the entire blocks themselves are also only typechecked in   }
         { pass_1, while the the typeinfo is already required after the          }
         { pass_1, while the the typeinfo is already required after the          }
         { typecheck pass for simplify purposes (not yet perfect, because the    }
         { typecheck pass for simplify purposes (not yet perfect, because the    }
         { statementnodes themselves are not typechecked this way)               }
         { statementnodes themselves are not typechecked this way)               }
-        firstpass(n);
         addstatement(lastinitstatement,n);
         addstatement(lastinitstatement,n);
+        firstpass(tnode(lastinitstatement));
+        { Update expectloc for callinitblock }
+        callinitblock.expectloc:=lastinitstatement.expectloc;
       end;
       end;
 
 
 
 
@@ -1922,13 +1931,22 @@ implementation
       var
       var
         lastdonestatement : tstatementnode;
         lastdonestatement : tstatementnode;
       begin
       begin
+        if not assigned(n) then
+          exit;
         if not assigned(callcleanupblock) then
         if not assigned(callcleanupblock) then
-          callcleanupblock:=internalstatements(lastdonestatement)
-        else
-          lastdonestatement:=laststatement(callcleanupblock);
+          begin
+            callcleanupblock:=internalstatements(lastdonestatement);
+            lastdonestatement.left.free;
+            lastdonestatement.left:=n;
+            firstpass(tnode(callcleanupblock));
+            exit;
+          end;
+        lastdonestatement:=laststatement(callcleanupblock);
         { see comments in add_init_statement }
         { see comments in add_init_statement }
-        firstpass(n);
         addstatement(lastdonestatement,n);
         addstatement(lastdonestatement,n);
+        firstpass(tnode(lastdonestatement));
+        { Update expectloc for callcleanupblock }
+        callcleanupblock.expectloc:=lastdonestatement.expectloc;
       end;
       end;
 
 
 
 
@@ -4373,8 +4391,12 @@ implementation
              result:=pass1_inline
              result:=pass1_inline
            else
            else
              begin
              begin
-               if (po_inline in procdefinition.procoptions) and not(po_compilerproc in procdefinition.procoptions) then
-                 Message1(cg_n_no_inline,tprocdef(procdefinition).customprocname([pno_proctypeoption, pno_paranames,pno_ownername, pno_noclassmarker]));
+               if (po_inline in procdefinition.procoptions) and not(po_compilerproc in procdefinition.procoptions) and
+                  (procdefinition.typ=procdef) and
+                  not (pio_inline_not_possible in tprocdef(procdefinition).implprocoptions) then
+                 begin
+                   Message1(cg_n_no_inline,tprocdef(procdefinition).customprocname([pno_proctypeoption, pno_paranames,pno_ownername, pno_noclassmarker]));
+                 end;
                mark_unregable_parameters;
                mark_unregable_parameters;
                result:=pass1_normal;
                result:=pass1_normal;
              end;
              end;
@@ -4594,7 +4616,8 @@ implementation
              ((tloadnode(n).symtable.symtabletype = staticsymtable) and
              ((tloadnode(n).symtable.symtabletype = staticsymtable) and
               (tloadnode(n).symtable = TSymtable(arg))) or
               (tloadnode(n).symtable = TSymtable(arg))) or
              { if the addr of the symbol is taken somewhere, it can be also non-local }
              { if the addr of the symbol is taken somewhere, it can be also non-local }
-             (tabstractvarsym(tloadnode(n).symtableentry).addr_taken)
+             ((tloadnode(n).symtableentry.typ in [localvarsym,paravarsym,staticvarsym]) and
+	      (tabstractvarsym(tloadnode(n).symtableentry).addr_taken))
             )
             )
            ) or
            ) or
            ((n.nodetype = subscriptn) and
            ((n.nodetype = subscriptn) and
@@ -4831,11 +4854,16 @@ implementation
         ptrtype: tdef;
         ptrtype: tdef;
         tempnode: ttempcreatenode;
         tempnode: ttempcreatenode;
         paraaddr: taddrnode;
         paraaddr: taddrnode;
+        isfuncretnode : boolean;
       begin
       begin
         ptrtype:=cpointerdef.getreusable(para.left.resultdef);
         ptrtype:=cpointerdef.getreusable(para.left.resultdef);
         tempnode:=ctempcreatenode.create(ptrtype,ptrtype.size,tt_persistent,true);
         tempnode:=ctempcreatenode.create(ptrtype,ptrtype.size,tt_persistent,true);
         addstatement(inlineinitstatement,tempnode);
         addstatement(inlineinitstatement,tempnode);
-        addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode));
+        isfuncretnode:=nf_is_funcret in para.left.flags;
+        if isfuncretnode then
+          addstatement(inlinecleanupstatement,ctempdeletenode.create_normal_temp(tempnode))
+        else
+          addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode));
         { inherit addr_taken flag }
         { inherit addr_taken flag }
         if (tabstractvarsym(para.parasym).addr_taken) then
         if (tabstractvarsym(para.parasym).addr_taken) then
           tempnode.includetempflag(ti_addr_taken);
           tempnode.includetempflag(ti_addr_taken);
@@ -4847,6 +4875,8 @@ implementation
         addstatement(inlineinitstatement,cassignmentnode.create(ctemprefnode.create(tempnode),
         addstatement(inlineinitstatement,cassignmentnode.create(ctemprefnode.create(tempnode),
           paraaddr));
           paraaddr));
         para.left:=cderefnode.create(ctemprefnode.create(tempnode));
         para.left:=cderefnode.create(ctemprefnode.create(tempnode));
+        if isfuncretnode then
+          Include(para.left.flags,nf_is_funcret);
       end;
       end;
 
 
 
 

+ 16 - 0
compiler/ncgbas.pas

@@ -68,6 +68,10 @@ interface
           procedure pass_generate_code;override;
           procedure pass_generate_code;override;
        end;
        end;
 
 
+       tcgfinalizetempsnode = class(tfinalizetempsnode)
+          procedure pass_generate_code; override;
+       end;
+
   implementation
   implementation
 
 
     uses
     uses
@@ -714,6 +718,17 @@ interface
       end;
       end;
 
 
 
 
+{*****************************************************************************
+                         TCGFINALIZETEMPSNODE
+*****************************************************************************}
+
+    procedure tcgfinalizetempsnode.pass_generate_code;
+      begin
+        hlcg.gen_finalize_code(current_asmdata.CurrAsmList);
+        location.loc:=LOC_VOID;
+      end;
+
+
 begin
 begin
    cnothingnode:=tcgnothingnode;
    cnothingnode:=tcgnothingnode;
    casmnode:=tcgasmnode;
    casmnode:=tcgasmnode;
@@ -722,4 +737,5 @@ begin
    ctempcreatenode:=tcgtempcreatenode;
    ctempcreatenode:=tcgtempcreatenode;
    ctemprefnode:=tcgtemprefnode;
    ctemprefnode:=tcgtemprefnode;
    ctempdeletenode:=tcgtempdeletenode;
    ctempdeletenode:=tcgtempdeletenode;
+   cfinalizetempsnode:=tcgfinalizetempsnode;
 end.
 end.

+ 10 - 9
compiler/ncgflw.pas

@@ -196,8 +196,9 @@ implementation
            hlcg.a_jmp_always(current_asmdata.CurrAsmList,lcont);
            hlcg.a_jmp_always(current_asmdata.CurrAsmList,lcont);
 
 
          if not(cs_opt_size in current_settings.optimizerswitches) then
          if not(cs_opt_size in current_settings.optimizerswitches) then
-            { align loop target }
-            current_asmdata.CurrAsmList.concat(Tai_align.Create(current_settings.alignment.loopalign));
+            { align loop target, as an unconditional jump is done before,
+              use jump align which assume that the instructions inserted as alignment are never executed }
+            current_asmdata.CurrAsmList.concat(cai_align.create_max(current_settings.alignment.jumpalign,current_settings.alignment.jumpalignmax));
 
 
          hlcg.a_label(current_asmdata.CurrAsmList,lloop);
          hlcg.a_label(current_asmdata.CurrAsmList,lloop);
 
 
@@ -319,6 +320,8 @@ implementation
 *)
 *)
                    ;
                    ;
                    hlcg.a_jmp_always(current_asmdata.CurrAsmList,hl);
                    hlcg.a_jmp_always(current_asmdata.CurrAsmList,hl);
+                   if not(cs_opt_size in current_settings.optimizerswitches) then
+                     current_asmdata.CurrAsmList.concat(cai_align.create_max(current_settings.alignment.jumpalign,current_settings.alignment.jumpalignmax));
                 end;
                 end;
               hlcg.a_label(current_asmdata.CurrAsmList,left.location.falselabel);
               hlcg.a_label(current_asmdata.CurrAsmList,left.location.falselabel);
               secondpass(t1);
               secondpass(t1);
@@ -347,12 +350,15 @@ implementation
                   current_asmdata.CurrAsmList := TAsmList.create;
                   current_asmdata.CurrAsmList := TAsmList.create;
                 end;
                 end;
 *)
 *)
-              current_asmdata.CurrAsmList.concat(cai_align.create(current_settings.alignment.jumpalign));
+              if not(cs_opt_size in current_settings.optimizerswitches) then
+                current_asmdata.CurrAsmList.concat(cai_align.create_max(current_settings.alignment.coalescealign,current_settings.alignment.coalescealignmax));
               hlcg.a_label(current_asmdata.CurrAsmList,left.location.falselabel);
               hlcg.a_label(current_asmdata.CurrAsmList,left.location.falselabel);
            end;
            end;
          if not(assigned(right)) then
          if not(assigned(right)) then
            begin
            begin
-              hlcg.a_label(current_asmdata.CurrAsmList,left.location.truelabel);
+             if not(cs_opt_size in current_settings.optimizerswitches) then
+               current_asmdata.CurrAsmList.concat(cai_align.create_max(current_settings.alignment.coalescealign,current_settings.alignment.coalescealignmax));
+             hlcg.a_label(current_asmdata.CurrAsmList,left.location.truelabel);
            end;
            end;
 
 
 (*
 (*
@@ -1183,11 +1189,6 @@ implementation
              { finally code only needed to be executed on exception (-> in
              { finally code only needed to be executed on exception (-> in
                if-branch -> fc_inflowcontrol) }
                if-branch -> fc_inflowcontrol) }
              flowcontrol:=[fc_inflowcontrol];
              flowcontrol:=[fc_inflowcontrol];
-             secondpass(t1);
-             if flowcontrol<>[fc_inflowcontrol] then
-               CGMessage(cg_e_control_flow_outside_finally);
-             if codegenerror then
-               exit;
              if (tf_safecall_exceptions in target_info.flags) and
              if (tf_safecall_exceptions in target_info.flags) and
                 (current_procinfo.procdef.proccalloption=pocall_safecall) then
                 (current_procinfo.procdef.proccalloption=pocall_safecall) then
                handle_safecall_exception
                handle_safecall_exception

+ 2 - 2
compiler/ncgld.pas

@@ -493,8 +493,8 @@ implementation
                          reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,location.reference.alignment,[])
                          reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,location.reference.alignment,[])
                      end
                      end
                    else
                    else
-                     location:=gvs.localloc;
-                 end;
+                      location:=gvs.localloc;
+                  end;
 
 
                 { make const a LOC_CREFERENCE }
                 { make const a LOC_CREFERENCE }
                 if (gvs.varspez=vs_const) and
                 if (gvs.varspez=vs_const) and

+ 1 - 1
compiler/ncgmem.pas

@@ -862,7 +862,7 @@ implementation
 
 
       var
       var
          offsetdec,
          offsetdec,
-         extraoffset : aint;
+         extraoffset : ASizeInt;
          rightp      : pnode;
          rightp      : pnode;
          newsize  : tcgsize;
          newsize  : tcgsize;
          mulsize,
          mulsize,

+ 15 - 20
compiler/ncgrtti.pas

@@ -175,6 +175,21 @@ implementation
                               TRTTIWriter
                               TRTTIWriter
 ***************************************************************************}
 ***************************************************************************}
 
 
+    function TRTTIWriter.get_rtti_label(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
+      begin
+        result:=ref_rtti(def,rt,indirect,'');
+      end;
+
+    function TRTTIWriter.get_rtti_label_ord2str(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
+      begin
+        result:=ref_rtti(def,rt,indirect,'_o2s');
+      end;
+
+    function TRTTIWriter.get_rtti_label_str2ord(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
+      begin
+        result:=ref_rtti(def,rt,indirect,'_s2o');
+      end;
+
     procedure TRTTIWriter.write_methods(tcb:ttai_typedconstbuilder;st:tsymtable;visibilities:tvisibilities);
     procedure TRTTIWriter.write_methods(tcb:ttai_typedconstbuilder;st:tsymtable;visibilities:tvisibilities);
       var
       var
         rtticount,
         rtticount,
@@ -1291,8 +1306,6 @@ implementation
             tcb.free;
             tcb.free;
           end;
           end;
 
 
-        var
-          riif : byte;
         begin
         begin
            write_header(tcb,def,tkRecord);
            write_header(tcb,def,tkRecord);
            { need extra reqalign record, because otherwise the u32 int will
            { need extra reqalign record, because otherwise the u32 int will
@@ -1439,8 +1452,6 @@ implementation
         procedure objectdef_rtti(def: tobjectdef);
         procedure objectdef_rtti(def: tobjectdef);
 
 
           procedure objectdef_rtti_fields(def:tobjectdef);
           procedure objectdef_rtti_fields(def:tobjectdef);
-          var
-            riif : byte;
           begin
           begin
             { - for compatiblity with record RTTI we need to write a terminator-
             { - for compatiblity with record RTTI we need to write a terminator-
                 Nil pointer for initrtti as well for objects
                 Nil pointer for initrtti as well for objects
@@ -2051,21 +2062,5 @@ implementation
           end;
           end;
       end;
       end;
 
 
-
-    function TRTTIWriter.get_rtti_label(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
-      begin
-        result:=ref_rtti(def,rt,indirect,'');
-      end;
-
-    function TRTTIWriter.get_rtti_label_ord2str(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
-      begin
-        result:=ref_rtti(def,rt,indirect,'_o2s');
-      end;
-
-    function TRTTIWriter.get_rtti_label_str2ord(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
-      begin
-        result:=ref_rtti(def,rt,indirect,'_s2o');
-      end;
-
 end.
 end.
 
 

+ 5 - 16
compiler/nflw.pas

@@ -189,10 +189,10 @@ interface
        end;
        end;
        ttryexceptnodeclass = class of ttryexceptnode;
        ttryexceptnodeclass = class of ttryexceptnode;
 
 
-       ttryfinallynode = class(tloopnode)
+       ttryfinallynode = class(tbinarynode)
           implicitframe : boolean;
           implicitframe : boolean;
           constructor create(l,r:tnode);virtual;reintroduce;
           constructor create(l,r:tnode);virtual;reintroduce;
-          constructor create_implicit(l,r,_t1:tnode);virtual;
+          constructor create_implicit(l,r:tnode);virtual;
           function pass_typecheck:tnode;override;
           function pass_typecheck:tnode;override;
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function simplify(forinline:boolean): tnode;override;
           function simplify(forinline:boolean): tnode;override;
@@ -2299,14 +2299,14 @@ implementation
 
 
     constructor ttryfinallynode.create(l,r:tnode);
     constructor ttryfinallynode.create(l,r:tnode);
       begin
       begin
-        inherited create(tryfinallyn,l,r,nil,nil);
+        inherited create(tryfinallyn,l,r);
         implicitframe:=false;
         implicitframe:=false;
       end;
       end;
 
 
 
 
-    constructor ttryfinallynode.create_implicit(l,r,_t1:tnode);
+    constructor ttryfinallynode.create_implicit(l,r:tnode);
       begin
       begin
-        inherited create(tryfinallyn,l,r,_t1,nil);
+        inherited create(tryfinallyn,l,r);
         implicitframe:=true;
         implicitframe:=true;
       end;
       end;
 
 
@@ -2323,14 +2323,6 @@ implementation
         typecheckpass(right);
         typecheckpass(right);
         // "except block" is "used"? (JM)
         // "except block" is "used"? (JM)
         set_varstate(right,vs_readwritten,[vsf_must_be_valid]);
         set_varstate(right,vs_readwritten,[vsf_must_be_valid]);
-
-        { special finally block only executed when there was an exception }
-        if assigned(t1) then
-          begin
-            typecheckpass(t1);
-            // "finally block" is "used"? (JM)
-            set_varstate(t1,vs_readwritten,[vsf_must_be_valid]);
-          end;
       end;
       end;
 
 
 
 
@@ -2342,9 +2334,6 @@ implementation
 
 
         firstpass(right);
         firstpass(right);
 
 
-        if assigned(t1) then
-          firstpass(t1);
-
         include(current_procinfo.flags,pi_do_call);
         include(current_procinfo.flags,pi_do_call);
 
 
         { pi_uses_exceptions is an information for the optimizer and it
         { pi_uses_exceptions is an information for the optimizer and it

+ 1 - 1
compiler/ngtcon.pas

@@ -1522,7 +1522,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
         bp   : tbitpackedval;
         bp   : tbitpackedval;
         error,
         error,
         is_packed: boolean;
         is_packed: boolean;
-        startoffset: aint;
+        startoffset: aword;
 
 
       procedure handle_stringconstn;
       procedure handle_stringconstn;
         begin
         begin

+ 12 - 4
compiler/ninl.pas

@@ -41,6 +41,7 @@ interface
           function pass_typecheck_cpu:tnode;virtual;
           function pass_typecheck_cpu:tnode;virtual;
           function simplify(forinline : boolean): tnode;override;
           function simplify(forinline : boolean): tnode;override;
           function docompare(p: tnode): boolean; override;
           function docompare(p: tnode): boolean; override;
+          procedure mark_write;override;
 
 
           { returns a node tree where the inc/dec are replaced by add/sub }
           { returns a node tree where the inc/dec are replaced by add/sub }
           function getaddsub_for_incdec : tnode;
           function getaddsub_for_incdec : tnode;
@@ -1740,7 +1741,7 @@ implementation
         { last param must be var }
         { last param must be var }
         destppn:=ppn.left;
         destppn:=ppn.left;
         valid_for_var(destppn,true);
         valid_for_var(destppn,true);
-        set_varstate(destppn,vs_written,[vsf_must_be_valid]);
+        set_varstate(destppn,vs_written,[vsf_must_be_valid,vsf_use_hints,vsf_use_hint_for_string_result]);
         { first param must be a string or dynamic array ...}
         { first param must be a string or dynamic array ...}
         isarray:=is_dynamic_array(destppn.resultdef);
         isarray:=is_dynamic_array(destppn.resultdef);
         if not((destppn.resultdef.typ=stringdef) or
         if not((destppn.resultdef.typ=stringdef) or
@@ -4084,6 +4085,16 @@ implementation
       end;
       end;
 
 
 
 
+    procedure tinlinenode.mark_write;
+      begin
+        case inlinenumber of
+	  in_aligned_x, in_unaligned_x:
+           tcallparanode(left).left.mark_write;
+        else
+          inherited mark_write;
+        end;
+      end;
+
     function tinlinenode.first_pi : tnode;
     function tinlinenode.first_pi : tnode;
       begin
       begin
         result:=crealconstnode.create(getpi,pbestrealtype^);
         result:=crealconstnode.create(getpi,pbestrealtype^);
@@ -4754,8 +4765,6 @@ implementation
 
 
        var
        var
          procname : String;
          procname : String;
-         c : longint;
-         n,
          newn,
          newn,
          datan,
          datan,
          datacountn,
          datacountn,
@@ -4956,7 +4965,6 @@ implementation
          n,
          n,
          arrn,
          arrn,
          firstn : tnode;
          firstn : tnode;
-         startidx,
          i : longint;
          i : longint;
          arrconstr : tarrayconstructornode;
          arrconstr : tarrayconstructornode;
          newstatement : tstatementnode;
          newstatement : tstatementnode;

+ 6 - 2
compiler/nld.pas

@@ -429,7 +429,10 @@ implementation
                   include(current_procinfo.flags,pi_needs_got);
                   include(current_procinfo.flags,pi_needs_got);
                 { call to get address of threadvar }
                 { call to get address of threadvar }
                 if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then
                 if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then
-                  include(current_procinfo.flags,pi_do_call);
+                  begin
+                    include(current_procinfo.flags,pi_do_call);
+                    include(current_procinfo.flags,pi_uses_threadvar);
+                  end;
               end;
               end;
             procsym :
             procsym :
                 begin
                 begin
@@ -514,7 +517,6 @@ implementation
 
 
       begin
       begin
          inherited create(assignn,l,r);
          inherited create(assignn,l,r);
-         l.mark_write;
          assigntype:=at_normal;
          assigntype:=at_normal;
          if r.nodetype = typeconvn then
          if r.nodetype = typeconvn then
            ttypeconvnode(r).warn_pointer_to_signed:=false;
            ttypeconvnode(r).warn_pointer_to_signed:=false;
@@ -584,6 +586,8 @@ implementation
 
 
         typecheckpass(left);
         typecheckpass(left);
 
 
+        left.mark_write;
+
         { PI. This is needed to return correct resultdef of add nodes for ansistrings
         { PI. This is needed to return correct resultdef of add nodes for ansistrings
           rawbytestring return needs to be replaced by left.resultdef }
           rawbytestring return needs to be replaced by left.resultdef }
         oldassignmentnode:=aktassignmentnode;
         oldassignmentnode:=aktassignmentnode;

+ 1 - 1
compiler/nmem.pas

@@ -1176,7 +1176,7 @@ implementation
       begin
       begin
         include(flags,nf_write);
         include(flags,nf_write);
         { see comment in tsubscriptnode.mark_write }
         { see comment in tsubscriptnode.mark_write }
-        if not(is_implicit_pointer_object_type(left.resultdef)) then
+        if not(is_implicit_array_pointer(left.resultdef)) then
           left.mark_write;
           left.mark_write;
       end;
       end;
 
 

+ 4 - 2
compiler/node.pas

@@ -110,7 +110,8 @@ interface
           loadparentfpn,    { Load the framepointer of the parent for nested procedures }
           loadparentfpn,    { Load the framepointer of the parent for nested procedures }
           objcselectorn,    { node for an Objective-C message selector }
           objcselectorn,    { node for an Objective-C message selector }
           objcprotocoln,    { node for an Objective-C @protocol() expression (returns metaclass associated with protocol) }
           objcprotocoln,    { node for an Objective-C @protocol() expression (returns metaclass associated with protocol) }
-          specializen       { parser-only node to handle Delphi-mode inline specializations }
+          specializen,      { parser-only node to handle Delphi-mode inline specializations }
+          finalizetempsn        { Internal node used to clean up code generator temps (warning: must NOT create additional tepms that may need to be finalised!) }
        );
        );
 
 
        tnodetypeset = set of tnodetype;
        tnodetypeset = set of tnodetype;
@@ -194,7 +195,8 @@ interface
           'loadparentfpn',
           'loadparentfpn',
           'objcselectorn',
           'objcselectorn',
           'objcprotocoln',
           'objcprotocoln',
-          'specializen');
+          'specializen',
+          'finalizetempsn');
 
 
       { a set containing all const nodes }
       { a set containing all const nodes }
       nodetype_const = [niln,
       nodetype_const = [niln,

+ 8 - 3
compiler/nutils.pas

@@ -196,7 +196,7 @@ implementation
               result := foreachnode(procmethod,tcallnode(n).funcretnode,f,arg) or result;
               result := foreachnode(procmethod,tcallnode(n).funcretnode,f,arg) or result;
               result := foreachnode(procmethod,tnode(tcallnode(n).callcleanupblock),f,arg) or result;
               result := foreachnode(procmethod,tnode(tcallnode(n).callcleanupblock),f,arg) or result;
             end;
             end;
-          ifn, whilerepeatn, forn, tryexceptn, tryfinallyn:
+          ifn, whilerepeatn, forn, tryexceptn:
             begin
             begin
               { not in one statement, won't work because of b- }
               { not in one statement, won't work because of b- }
               result := foreachnode(procmethod,tloopnode(n).t1,f,arg) or result;
               result := foreachnode(procmethod,tloopnode(n).t1,f,arg) or result;
@@ -293,7 +293,7 @@ implementation
               result := foreachnodestatic(procmethod,tcallnode(n).funcretnode,f,arg) or result;
               result := foreachnodestatic(procmethod,tcallnode(n).funcretnode,f,arg) or result;
               result := foreachnodestatic(procmethod,tnode(tcallnode(n).callcleanupblock),f,arg) or result;
               result := foreachnodestatic(procmethod,tnode(tcallnode(n).callcleanupblock),f,arg) or result;
             end;
             end;
-          ifn, whilerepeatn, forn, tryexceptn, tryfinallyn:
+          ifn, whilerepeatn, forn, tryexceptn:
             begin
             begin
               { not in one statement, won't work because of b- }
               { not in one statement, won't work because of b- }
               result := foreachnodestatic(procmethod,tloopnode(n).t1,f,arg) or result;
               result := foreachnodestatic(procmethod,tloopnode(n).t1,f,arg) or result;
@@ -963,6 +963,11 @@ implementation
                   end;
                   end;
 
 
                 end;
                 end;
+              finalizetempsn:
+                begin
+                  result:=NODE_COMPLEXITY_INF;
+                  exit;
+                end;
               else
               else
                 begin
                 begin
                   result := NODE_COMPLEXITY_INF;
                   result := NODE_COMPLEXITY_INF;
@@ -1337,7 +1342,7 @@ implementation
     function check_for_sideeffect(var n: tnode; arg: pointer): foreachnoderesult;
     function check_for_sideeffect(var n: tnode; arg: pointer): foreachnoderesult;
       begin
       begin
         result:=fen_false;
         result:=fen_false;
-        if (n.nodetype in [assignn,calln,asmn]) or
+        if (n.nodetype in [assignn,calln,asmn,finalizetempsn]) or
           ((n.nodetype=inlinen) and
           ((n.nodetype=inlinen) and
            (tinlinenode(n).inlinenumber in [in_write_x,in_writeln_x,in_read_x,in_readln_x,in_str_x_string,
            (tinlinenode(n).inlinenumber in [in_write_x,in_writeln_x,in_read_x,in_readln_x,in_str_x_string,
              in_val_x,in_reset_x,in_rewrite_x,in_reset_typedfile,in_rewrite_typedfile,
              in_val_x,in_reset_x,in_rewrite_x,in_reset_typedfile,in_rewrite_typedfile,

+ 0 - 1
compiler/ogbase.pas

@@ -275,7 +275,6 @@ interface
      private
      private
        FData       : TDynamicArray;
        FData       : TDynamicArray;
        FSecOptions : TObjSectionOptions;
        FSecOptions : TObjSectionOptions;
-       FComdatSelection : TObjSectionComdatSelection;
        FCachedFullName : pshortstring;
        FCachedFullName : pshortstring;
        FSizeLimit : TObjSectionOfs;
        FSizeLimit : TObjSectionOfs;
        procedure SetSecOptions(Aoptions:TObjSectionOptions);
        procedure SetSecOptions(Aoptions:TObjSectionOptions);

+ 18 - 9
compiler/omfbase.pas

@@ -1349,18 +1349,23 @@ implementation
         internalerror(2015033103);
         internalerror(2015033103);
       SetLength(s, len);
       SetLength(s, len);
       UniqueString(s);
       UniqueString(s);
-      Move(RawData[Offset+1],s[1],len);
+      if len>0 then
+        Move(RawData[Offset+1],s[1],len);
     end;
     end;
 
 
   function TOmfRawRecord.WriteStringAt(Offset: Integer; s: string): Integer;
   function TOmfRawRecord.WriteStringAt(Offset: Integer; s: string): Integer;
+    var
+      len : longint;
     begin
     begin
-      if Length(s)>255 then
+      len:=Length(s);
+      if len>255 then
         internalerror(2015033101);
         internalerror(2015033101);
-      result:=Offset+Length(s)+1;
+      result:=Offset+len+1;
       if result>High(RawData) then
       if result>High(RawData) then
         internalerror(2015033102);
         internalerror(2015033102);
-      RawData[Offset]:=Length(s);
-      Move(s[1], RawData[Offset+1], Length(s));
+      RawData[Offset]:=len;
+      if len>0 then
+        Move(s[1], RawData[Offset+1], len);
     end;
     end;
 
 
   function TOmfRawRecord.ReadIndexedRef(Offset: Integer; out IndexedRef: Integer): Integer;
   function TOmfRawRecord.ReadIndexedRef(Offset: Integer; out IndexedRef: Integer): Integer;
@@ -1420,7 +1425,7 @@ implementation
       b:=0;
       b:=0;
       for I:=-3 to RecordLength-2 do
       for I:=-3 to RecordLength-2 do
         b:=byte(b+RawData[I]);
         b:=byte(b+RawData[I]);
-      SetChecksumByte($100-b);
+      SetChecksumByte(byte($100-b));
     end;
     end;
 
 
   function TOmfRawRecord.VerifyChecksumByte: boolean;
   function TOmfRawRecord.VerifyChecksumByte: boolean;
@@ -1521,14 +1526,18 @@ implementation
     end;
     end;
 
 
   procedure TOmfRecord_COMENT.EncodeTo(RawRecord: TOmfRawRecord);
   procedure TOmfRecord_COMENT.EncodeTo(RawRecord: TOmfRawRecord);
+    var
+      len : longint;
     begin
     begin
       RawRecord.RecordType:=RT_COMENT;
       RawRecord.RecordType:=RT_COMENT;
-      if (Length(FCommentString)+3)>High(RawRecord.RawData) then
+      len:=Length(FCommentString);
+      if (len+3)>High(RawRecord.RawData) then
         internalerror(2015033105);
         internalerror(2015033105);
-      RawRecord.RecordLength:=Length(FCommentString)+3;
+      RawRecord.RecordLength:=len+3;
       RawRecord.RawData[0]:=CommentType;
       RawRecord.RawData[0]:=CommentType;
       RawRecord.RawData[1]:=CommentClass;
       RawRecord.RawData[1]:=CommentClass;
-      Move(FCommentString[1],RawRecord.RawData[2],Length(FCommentString));
+      if len>0 then
+        Move(FCommentString[1],RawRecord.RawData[2],len);
       RawRecord.CalculateChecksumByte;
       RawRecord.CalculateChecksumByte;
     end;
     end;
 
 

+ 1 - 1
compiler/optbase.pas

@@ -44,7 +44,7 @@ unit optbase;
         defsum : tdfaset;
         defsum : tdfaset;
         avail : tdfaset;
         avail : tdfaset;
         { estimation, how often the node is executed per subroutine call times 100, calculated by optutils.CalcExecutionWeight }
         { estimation, how often the node is executed per subroutine call times 100, calculated by optutils.CalcExecutionWeight }
-        executionweight : aword;
+        executionweight : longint;
       end;
       end;
 
 
       poptinfo = ^toptinfo;
       poptinfo = ^toptinfo;

+ 1 - 0
compiler/optdfa.pas

@@ -383,6 +383,7 @@ unit optdfa;
             temprefn,
             temprefn,
             loadn,
             loadn,
             typeconvn,
             typeconvn,
+            derefn,
             assignn:
             assignn:
               begin
               begin
                 if not(assigned(node.optinfo^.def)) and
                 if not(assigned(node.optinfo^.def)) and

+ 10 - 1
compiler/options.pas

@@ -3671,7 +3671,6 @@ var
   env: ansistring;
   env: ansistring;
   i : tfeature;
   i : tfeature;
   j : longint;
   j : longint;
-  abi : tabi;
   tmplist : TCmdStrList;
   tmplist : TCmdStrList;
   cmditem,
   cmditem,
   tmpcmditem : TCmdStrListItem;
   tmpcmditem : TCmdStrListItem;
@@ -4032,6 +4031,15 @@ begin
      not(cs_link_separate_dbg_file in init_settings.globalswitches) then
      not(cs_link_separate_dbg_file in init_settings.globalswitches) then
     exclude(init_settings.globalswitches,cs_link_strip);
     exclude(init_settings.globalswitches,cs_link_strip);
 
 
+  { choose a reasonable tls model }
+  if (tf_section_threadvars in target_info.flags) and (init_settings.tlsmodel=tlsm_none) then
+    begin
+      if cs_create_pic in init_settings.moduleswitches then
+        init_settings.tlsmodel:=tlsm_general
+      else
+        init_settings.tlsmodel:=tlsm_local;
+    end;
+
   { set Mac OS X version default macros if not specified explicitly }
   { set Mac OS X version default macros if not specified explicitly }
   option.MaybeSetDefaultMacVersionMacro;
   option.MaybeSetDefaultMacVersionMacro;
 
 
@@ -4399,6 +4407,7 @@ begin
    begin
    begin
      init_settings.alignment.procalign:=1;
      init_settings.alignment.procalign:=1;
      init_settings.alignment.jumpalign:=1;
      init_settings.alignment.jumpalign:=1;
+     init_settings.alignment.coalescealign:=1;
      init_settings.alignment.loopalign:=1;
      init_settings.alignment.loopalign:=1;
 {$ifdef x86}
 {$ifdef x86}
      { constalignmax=1 keeps the executable and thus the memory foot print small but
      { constalignmax=1 keeps the executable and thus the memory foot print small but

+ 11 - 20
compiler/optutils.pas

@@ -49,7 +49,7 @@ unit optutils;
     procedure CalcDefSum(p : tnode);
     procedure CalcDefSum(p : tnode);
 
 
     { calculates/estimates the field execution weight of optinfo }
     { calculates/estimates the field execution weight of optinfo }
-    procedure CalcExecutionWeights(p : tnode;Initial : AWord = 100);
+    procedure CalcExecutionWeights(p : tnode;Initial : longint = 100);
 
 
     { returns true, if n is a valid node and has life info }
     { returns true, if n is a valid node and has life info }
     function has_life_info(n : tnode) : boolean;
     function has_life_info(n : tnode) : boolean;
@@ -359,50 +359,41 @@ unit optutils;
 
 
     function SetExecutionWeight(var n: tnode; arg: pointer): foreachnoderesult;
     function SetExecutionWeight(var n: tnode; arg: pointer): foreachnoderesult;
       var
       var
-        Weight : AWord;
+        Weight : longint;
         i : Integer;
         i : Integer;
       begin
       begin
         Result:=fen_false;
         Result:=fen_false;
         n.allocoptinfo;
         n.allocoptinfo;
-        Weight:=PAWord(arg)^;
+        Weight:=max(plongint(arg)^,1);
         case n.nodetype of
         case n.nodetype of
           casen:
           casen:
             begin
             begin
               CalcExecutionWeights(tcasenode(n).left,Weight);
               CalcExecutionWeights(tcasenode(n).left,Weight);
               for i:=0 to tcasenode(n).blocks.count-1 do
               for i:=0 to tcasenode(n).blocks.count-1 do
-                CalcExecutionWeights(pcaseblock(tcasenode(n).blocks[i])^.statement,max(1,Weight div case_count_labels(tcasenode(n).labels)));
+                CalcExecutionWeights(pcaseblock(tcasenode(n).blocks[i])^.statement,Weight div case_count_labels(tcasenode(n).labels));
 
 
-              CalcExecutionWeights(tcasenode(n).elseblock,max(1,Weight div case_count_labels(tcasenode(n).labels)));
+              CalcExecutionWeights(tcasenode(n).elseblock,Weight div case_count_labels(tcasenode(n).labels));
               Result:=fen_norecurse_false;
               Result:=fen_norecurse_false;
             end;
             end;
           whilerepeatn:
           whilerepeatn:
             begin
             begin
-              CalcExecutionWeights(twhilerepeatnode(n).right,max(Weight,1)*8);
-              CalcExecutionWeights(twhilerepeatnode(n).left,max(Weight,1)*8);
+              CalcExecutionWeights(twhilerepeatnode(n).right,Weight*8);
+              CalcExecutionWeights(twhilerepeatnode(n).left,Weight*8);
               Result:=fen_norecurse_false;
               Result:=fen_norecurse_false;
             end;
             end;
           ifn:
           ifn:
             begin
             begin
               CalcExecutionWeights(tifnode(n).left,Weight);
               CalcExecutionWeights(tifnode(n).left,Weight);
-              CalcExecutionWeights(tifnode(n).right,max(Weight div 2,1));
-              CalcExecutionWeights(tifnode(n).t1,max(Weight div 2,1));
+              CalcExecutionWeights(tifnode(n).right,Weight div 2);
+              CalcExecutionWeights(tifnode(n).t1,Weight div 2);
               Result:=fen_norecurse_false;
               Result:=fen_norecurse_false;
             end;
             end;
-          else
-{$push}
-{ The code below emits two warnings if ptruint and aword are the same type }
-{$warn 4044 off}
-{$warn 6018 off}
-            if PAWord(arg)^ > high(aword) then
-              n.optinfo^.executionweight:=high(AWord)
-            else
-              n.optinfo^.executionweight:=PAWord(arg)^;
-{$pop}
         end;
         end;
+        n.optinfo^.executionweight:=Weight;
       end;
       end;
 
 
 
 
-    procedure CalcExecutionWeights(p : tnode;Initial : AWord = 100);
+    procedure CalcExecutionWeights(p : tnode;Initial : longint = 100);
       begin
       begin
         if assigned(p) then
         if assigned(p) then
           foreachnodestatic(pm_postprocess,p,@SetExecutionWeight,Pointer(@Initial));
           foreachnodestatic(pm_postprocess,p,@SetExecutionWeight,Pointer(@Initial));

+ 4 - 0
compiler/owomflib.pas

@@ -421,6 +421,9 @@ implementation
             repeat
             repeat
               pb:=@blocks[h.block_x];
               pb:=@blocks[h.block_x];
               success:=false;
               success:=false;
+	      {$push}
+	      { Disable range check in that part of code }
+	      {$R-}
               repeat
               repeat
                 if pb^[h.bucket_x]=0 then
                 if pb^[h.bucket_x]=0 then
                   begin
                   begin
@@ -440,6 +443,7 @@ implementation
                   end;
                   end;
                 h.bucket_x:=(h.bucket_x+h.bucket_d) mod nbuckets;
                 h.bucket_x:=(h.bucket_x+h.bucket_d) mod nbuckets;
               until h.bucket_x=start_bucket;
               until h.bucket_x=start_bucket;
+	      {$pop}
               if not success then
               if not success then
                 begin
                 begin
                   h.block_x:=(h.block_x+h.block_d) mod nblocks;
                   h.block_x:=(h.block_x+h.block_d) mod nblocks;

+ 6 - 2
compiler/pass_2.pas

@@ -156,7 +156,8 @@ implementation
              'loadparentfpn',
              'loadparentfpn',
              'objselectorn',
              'objselectorn',
              'objcprotocoln',
              'objcprotocoln',
-             'specializen'
+             'specializen',
+             'finalizetemps'
              );
              );
       var
       var
         p: pchar;
         p: pchar;
@@ -180,6 +181,7 @@ implementation
          oldcodegenerror  : boolean;
          oldcodegenerror  : boolean;
          oldlocalswitches : tlocalswitches;
          oldlocalswitches : tlocalswitches;
          oldpos    : tfileposinfo;
          oldpos    : tfileposinfo;
+         oldexecutionweight : longint;
       begin
       begin
          if not assigned(p) then
          if not assigned(p) then
           internalerror(200208221);
           internalerror(200208221);
@@ -191,8 +193,9 @@ implementation
             current_filepos:=p.fileinfo;
             current_filepos:=p.fileinfo;
             current_settings.localswitches:=p.localswitches;
             current_settings.localswitches:=p.localswitches;
             codegenerror:=false;
             codegenerror:=false;
+            oldexecutionweight:=cg.executionweight;
             if assigned(p.optinfo) then
             if assigned(p.optinfo) then
-              cg.executionweight:=min(p.optinfo^.executionweight,QWord(high(cg.executionweight)))
+              cg.executionweight:=min(p.optinfo^.executionweight,high(cg.executionweight))
             else
             else
               cg.executionweight:=100;
               cg.executionweight:=100;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
@@ -227,6 +230,7 @@ implementation
             codegenerror:=codegenerror or oldcodegenerror;
             codegenerror:=codegenerror or oldcodegenerror;
             current_settings.localswitches:=oldlocalswitches;
             current_settings.localswitches:=oldlocalswitches;
             current_filepos:=oldpos;
             current_filepos:=oldpos;
+            cg.executionweight:=oldexecutionweight;
           end
           end
          else
          else
            codegenerror:=true;
            codegenerror:=true;

+ 3 - 0
compiler/pdecl.pas

@@ -274,6 +274,9 @@ implementation
                      to it from the structure or linking will fail }
                      to it from the structure or linking will fail }
                    if symtablestack.top.symtabletype in [recordsymtable,ObjectSymtable] then
                    if symtablestack.top.symtabletype in [recordsymtable,ObjectSymtable] then
                      begin
                      begin
+                       { note: we keep hdef so that we might at least read the
+                               constant data correctly for error recovery }
+                       check_allowed_for_var_or_const(hdef,false);
                        sym:=cfieldvarsym.create(orgname,varspez,hdef,[],true);
                        sym:=cfieldvarsym.create(orgname,varspez,hdef,[],true);
                        symtablestack.top.insert(sym);
                        symtablestack.top.insert(sym);
                        sym:=make_field_static(symtablestack.top,tfieldvarsym(sym));
                        sym:=make_field_static(symtablestack.top,tfieldvarsym(sym));

+ 1 - 2
compiler/pdecsub.pas

@@ -2960,8 +2960,7 @@ const
       }
       }
       var
       var
         p     : longint;
         p     : longint;
-        name,
-        other : TIDString;
+        name : TIDString;
         po_comp : tprocoptions;
         po_comp : tprocoptions;
         tokenloc : TFilePosInfo;
         tokenloc : TFilePosInfo;
       begin
       begin

+ 48 - 31
compiler/pdecvar.pas

@@ -28,7 +28,7 @@ interface
 
 
     uses
     uses
       cclasses,
       cclasses,
-      symtable,symsym,symdef;
+      symtable,symsym,symdef,symtype;
 
 
     type
     type
       tvar_dec_option=(vd_record,vd_object,vd_threadvar,vd_class,vd_final,vd_canreorder,vd_check_generic);
       tvar_dec_option=(vd_record,vd_object,vd_threadvar,vd_class,vd_final,vd_canreorder,vd_check_generic);
@@ -44,6 +44,8 @@ interface
 
 
     procedure try_consume_sectiondirective(var asection: ansistring);
     procedure try_consume_sectiondirective(var asection: ansistring);
 
 
+    function check_allowed_for_var_or_const(def:tdef;allowdynarray:boolean):boolean;
+
 implementation
 implementation
 
 
     uses
     uses
@@ -54,7 +56,7 @@ implementation
        globtype,globals,tokens,verbose,constexp,
        globtype,globals,tokens,verbose,constexp,
        systems,
        systems,
        { symtable }
        { symtable }
-       symconst,symbase,symtype,defutil,defcmp,symcreat,
+       symconst,symbase,defutil,defcmp,symcreat,
 {$if defined(i386) or defined(i8086)}
 {$if defined(i386) or defined(i8086)}
        symcpu,
        symcpu,
 {$endif}
 {$endif}
@@ -1541,6 +1543,47 @@ implementation
       end;
       end;
 
 
 
 
+    function check_allowed_for_var_or_const(def:tdef;allowdynarray:boolean):boolean;
+      var
+        stowner,tmpdef : tdef;
+        st : tsymtable;
+      begin
+        result:=true;
+        st:=symtablestack.top;
+        if not (st.symtabletype in [recordsymtable,objectsymtable]) then
+          exit;
+        stowner:=tdef(st.defowner);
+        while assigned(stowner) and (stowner.typ in [objectdef,recorddef]) do
+          begin
+            if def.typ=arraydef then
+              begin
+                tmpdef:=def;
+                while (tmpdef.typ=arraydef) do
+                  begin
+                    { dynamic arrays are allowed in certain cases }
+                    if allowdynarray and (ado_IsDynamicArray in tarraydef(tmpdef).arrayoptions) then
+                      begin
+                        tmpdef:=nil;
+                        break;
+                      end;
+                    tmpdef:=tarraydef(tmpdef).elementdef;
+                  end;
+              end
+            else
+              tmpdef:=def;
+            if assigned(tmpdef) and
+                (is_object(tmpdef) or is_record(tmpdef)) and
+                is_owned_by(tabstractrecorddef(stowner),tabstractrecorddef(tmpdef)) then
+              begin
+                Message1(type_e_type_is_not_completly_defined,tabstractrecorddef(tmpdef).RttiName);
+                result:=false;
+                break;
+              end;
+            stowner:=tdef(stowner.owner.defowner);
+          end;
+      end;
+
+
     procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc : ppvariantrecdesc;out had_generic:boolean);
     procedure read_record_fields(options:Tvar_dec_options; reorderlist: TFPObjectList; variantdesc : ppvariantrecdesc;out had_generic:boolean);
       var
       var
          sc : TFPObjectList;
          sc : TFPObjectList;
@@ -1644,35 +1687,9 @@ implementation
              { allow only static fields reference to struct where they are declared }
              { allow only static fields reference to struct where they are declared }
              if not (vd_class in options) then
              if not (vd_class in options) then
                begin
                begin
-                 stowner:=tdef(recst.defowner);
-                 while assigned(stowner) and (stowner.typ in [objectdef,recorddef]) do
-                   begin
-                     if hdef.typ=arraydef then
-                       begin
-                         tmpdef:=hdef;
-                         while (tmpdef.typ=arraydef) do
-                           begin
-                             { dynamic arrays are allowed }
-                             if ado_IsDynamicArray in tarraydef(tmpdef).arrayoptions then
-                               begin
-                                 tmpdef:=nil;
-                                 break;
-                               end;
-                             tmpdef:=tarraydef(tmpdef).elementdef;
-                           end;
-                       end
-                     else
-                       tmpdef:=hdef;
-                     if assigned(tmpdef) and
-                         (is_object(tmpdef) or is_record(tmpdef)) and
-                         is_owned_by(tabstractrecorddef(stowner),tabstractrecorddef(tmpdef)) then
-                       begin
-                         Message1(type_e_type_is_not_completly_defined, tabstractrecorddef(tmpdef).RttiName);
-                         { for error recovery or compiler will crash later }
-                         hdef:=generrordef;
-                       end;
-                     stowner:=tdef(stowner.owner.defowner);
-                   end;
+                 if not check_allowed_for_var_or_const(hdef,true) then
+                   { for error recovery or compiler will crash later }
+                   hdef:=generrordef;
                end;
                end;
 
 
              { Process procvar directives }
              { Process procvar directives }

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