Prechádzať zdrojové kódy

* synchronized with trunk

git-svn-id: branches/tg74/avx512-0037785@48751 -
florian 4 rokov pred
rodič
commit
b83ed566bb
74 zmenil súbory, kde vykonal 2908 pridanie a 904 odobranie
  1. 10 0
      .gitattributes
  2. 2 2
      compiler/Makefile
  3. 2 2
      compiler/Makefile.fpc
  4. 4 0
      compiler/aarch64/cgcpu.pas
  5. 1 1
      compiler/aarch64/cpubase.pas
  6. 32 28
      compiler/arm/aasmcpu.pas
  7. 13 7
      compiler/arm/agarmgas.pas
  8. 4 4
      compiler/arm/armins.dat
  9. 4 4
      compiler/arm/armtab.inc
  10. 142 117
      compiler/arm/cgcpu.pas
  11. 1 1
      compiler/arm/cpubase.pas
  12. 13 15
      compiler/arm/cpuinfo.pas
  13. 2 2
      compiler/arm/narmset.pas
  14. 9 1
      compiler/arm/raarm.pas
  15. 18 2
      compiler/assemble.pas
  16. 61 3
      compiler/cfidwarf.pas
  17. 10 4
      compiler/dbgstabs.pas
  18. 10 6
      compiler/m68k/ag68kgas.pas
  19. 11 9
      compiler/m68k/cgcpu.pas
  20. 1 1
      compiler/m68k/n68kadd.pas
  21. 3 3
      compiler/m68k/n68kinl.pas
  22. 10 5
      compiler/m68k/n68kmem.pas
  23. 10 3
      compiler/msg/errore.msg
  24. 7 4
      compiler/msgidx.inc
  25. 302 298
      compiler/msgtxt.inc
  26. 10 0
      compiler/ncal.pas
  27. 3 0
      compiler/ncnv.pas
  28. 3 1
      compiler/options.pas
  29. 4 3
      compiler/parser.pas
  30. 1 0
      compiler/rautils.pas
  31. 0 1
      compiler/sparc/cpuelf.pas
  32. 1 1
      compiler/systems/i_linux.pas
  33. 6 0
      compiler/systems/t_embed.pas
  34. 1 2
      packages/cocoaint/src/foundation/NSProcessInfo.inc
  35. 19 0
      packages/fcl-db/fpmake.pp
  36. 17 7
      packages/fcl-db/src/base/bufdataset.pas
  37. 74 0
      packages/fcl-db/src/datadict/fpddmysql80.pp
  38. 208 208
      packages/fcl-db/src/sqldb/mysql/Makefile
  39. 2 2
      packages/fcl-db/src/sqldb/mysql/Makefile.fpc
  40. 12 0
      packages/fcl-db/src/sqldb/mysql/mysql80conn.pas
  41. 91 16
      packages/fcl-db/src/sqldb/mysql/mysqlconn.inc
  42. 1 1
      packages/fcl-db/src/sqldb/sqldb.pp
  43. 6 5
      packages/fcl-db/tests/sqldbtoolsunit.pas
  44. 1 0
      packages/fcl-passrc/src/pasuseanalyzer.pas
  45. 21 0
      packages/fcl-passrc/tests/tcuseanalyzer.pas
  46. 56 0
      packages/fcl-pdf/examples/monospacetext.pp
  47. 18 7
      packages/fcl-pdf/src/fpparsettf.pp
  48. 8 2
      packages/fcl-pdf/src/fpttfsubsetter.pp
  49. 5 2
      packages/fcl-process/src/amicommon/pipes.inc
  50. 66 11
      packages/fcl-process/src/amicommon/process.inc
  51. 21 1
      packages/fcl-process/src/pipes.pp
  52. 7 0
      packages/mysql/fpmake.pp
  53. 164 37
      packages/mysql/src/mysql.inc
  54. 12 0
      packages/mysql/src/mysql80dyn.pp
  55. 68 38
      packages/rtl-objpas/src/inc/dateutil.inc
  56. 8 1
      packages/rtl-unicode/fpmake.pp
  57. 180 0
      packages/rtl-unicode/src/inc/graphemebreakproperty.pp
  58. 511 0
      packages/rtl-unicode/src/inc/graphemebreakproperty_code.inc
  59. 1 1
      packages/symbolic/src/symbolic.pas
  60. 1 1
      rtl/embedded/Makefile
  61. 1 1
      rtl/embedded/Makefile.fpc
  62. 13 1
      rtl/embedded/arm/cortexm4f_start.inc
  63. 13 1
      rtl/freertos/arm/cortexm4f_start.inc
  64. 10 7
      rtl/linux/arm/sighnd.inc
  65. 1 0
      rtl/objpas/sysconst.pp
  66. 106 0
      tests/test/units/dateutil/test_scandatetime_ampm.pas
  67. 13 0
      tests/webtbf/tw38439.pp
  68. 1 1
      utils/unicode/cldrparser.lpr
  69. 7 7
      utils/unicode/data/readme.txt
  70. 1 0
      utils/unicode/fpmake.pp
  71. 58 0
      utils/unicode/gbpparser.lpi
  72. 379 0
      utils/unicode/gbpparser.lpr
  73. 8 8
      utils/unicode/parse-collations.bat
  74. 8 8
      utils/unicode/parse-collations.sh

+ 10 - 0
.gitattributes

@@ -3363,6 +3363,7 @@ packages/fcl-db/src/datadict/fpddmysql51.pp svneol=native#text/plain
 packages/fcl-db/src/datadict/fpddmysql55.pp svneol=native#text/plain
 packages/fcl-db/src/datadict/fpddmysql56.pp svneol=native#text/plain
 packages/fcl-db/src/datadict/fpddmysql57.pp svneol=native#text/plain
+packages/fcl-db/src/datadict/fpddmysql80.pp svneol=native#text/plain
 packages/fcl-db/src/datadict/fpddodbc.pp svneol=native#text/plain
 packages/fcl-db/src/datadict/fpddoracle.pp svneol=native#text/plain
 packages/fcl-db/src/datadict/fpddpq.pp svneol=native#text/plain
@@ -3494,6 +3495,7 @@ packages/fcl-db/src/sqldb/mysql/mysql51conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysql55conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysql56conn.pas svneol=native#text/pascal
 packages/fcl-db/src/sqldb/mysql/mysql57conn.pas svneol=native#text/plain
+packages/fcl-db/src/sqldb/mysql/mysql80conn.pas svneol=native#text/plain
 packages/fcl-db/src/sqldb/mysql/mysqlconn.inc svneol=native#text/plain
 packages/fcl-db/src/sqldb/odbc/Makefile svneol=native#text/plain
 packages/fcl-db/src/sqldb/odbc/Makefile.fpc svneol=native#text/plain
@@ -3880,6 +3882,7 @@ packages/fcl-pdf/Makefile svneol=native#text/plain
 packages/fcl-pdf/Makefile.fpc svneol=native#text/plain
 packages/fcl-pdf/examples/diamond.png -text svneol=unset#image/png
 packages/fcl-pdf/examples/metautf16.pp svneol=native#text/plain
+packages/fcl-pdf/examples/monospacetext.pp svneol=native#text/plain
 packages/fcl-pdf/examples/poppy.jpg -text
 packages/fcl-pdf/examples/testfppdf.lpi svneol=native#text/plain
 packages/fcl-pdf/examples/testfppdf.lpr svneol=native#text/plain
@@ -7725,6 +7728,7 @@ packages/mysql/src/mysql55.pp svneol=native#text/plain
 packages/mysql/src/mysql55dyn.pp svneol=native#text/plain
 packages/mysql/src/mysql56dyn.pp svneol=native#text/plain
 packages/mysql/src/mysql57dyn.pp svneol=native#text/plain
+packages/mysql/src/mysql80dyn.pp svneol=native#text/plain
 packages/ncurses/Makefile svneol=native#text/plain
 packages/ncurses/Makefile.fpc svneol=native#text/plain
 packages/ncurses/Makefile.fpc.fpcmake svneol=native#text/plain
@@ -9032,6 +9036,8 @@ packages/rtl-unicode/src/inc/cp949.pas svneol=native#text/pascal
 packages/rtl-unicode/src/inc/cp950.pas svneol=native#text/pascal
 packages/rtl-unicode/src/inc/cpbuildu.pp svneol=native#text/plain
 packages/rtl-unicode/src/inc/freebidi.pp svneol=native#text/plain
+packages/rtl-unicode/src/inc/graphemebreakproperty.pp svneol=native#text/plain
+packages/rtl-unicode/src/inc/graphemebreakproperty_code.inc svneol=native#text/plain
 packages/rtl-unicode/src/inc/ucadata.inc svneol=native#text/pascal
 packages/rtl-unicode/src/inc/ucadata_be.inc svneol=native#text/pascal
 packages/rtl-unicode/src/inc/ucadata_le.inc svneol=native#text/pascal
@@ -16042,6 +16048,7 @@ tests/test/units/cocoaall/tw36362.pp svneol=native#text/plain
 tests/test/units/cpu/tcpu1.pp svneol=native#text/pascal
 tests/test/units/crt/tcrt.pp svneol=native#text/plain
 tests/test/units/crt/tctrlc.pp svneol=native#text/plain
+tests/test/units/dateutil/test_scandatetime_ampm.pas svneol=native#text/plain
 tests/test/units/dateutil/testscandatetime.pas svneol=native#text/plain
 tests/test/units/dateutil/tunitdt1.pp svneol=native#text/pascal
 tests/test/units/dos/hello.pp svneol=native#text/plain
@@ -16713,6 +16720,7 @@ tests/webtbf/tw3812.pp svneol=native#text/plain
 tests/webtbf/tw38287.pp svneol=native#text/pascal
 tests/webtbf/tw38289a.pp svneol=native#text/pascal
 tests/webtbf/tw38289b.pp svneol=native#text/pascal
+tests/webtbf/tw38439.pp svneol=native#text/pascal
 tests/webtbf/tw3930a.pp svneol=native#text/plain
 tests/webtbf/tw3931b.pp svneol=native#text/plain
 tests/webtbf/tw3969.pp svneol=native#text/plain
@@ -19766,6 +19774,8 @@ utils/unicode/cldrtxt.pas svneol=native#text/plain
 utils/unicode/cldrxml.pas svneol=native#text/pascal
 utils/unicode/data/readme.txt svneol=native#text/plain
 utils/unicode/fpmake.pp svneol=native#text/plain
+utils/unicode/gbpparser.lpi svneol=native#text/plain
+utils/unicode/gbpparser.lpr svneol=native#text/pascal
 utils/unicode/grbtree.pas svneol=native#text/pascal
 utils/unicode/helper.pas svneol=native#text/pascal
 utils/unicode/parse-collations.bat svneol=native#text/plain

+ 2 - 2
compiler/Makefile

@@ -4641,7 +4641,7 @@ override DIFF:=$(CMP) -i218
 endif
 endif
 ifeq ($(OS_TARGET), darwin)
-CODESIGN?=$(strip $(wildcard $(addsuffix /codesign,$(SEARCHPATH))))
+CODESIGN?=$(firstword $(wildcard $(addsuffix /codesign$(SRCEXEEXT),$(SEARCHPATH))))
 endif
 ifneq ($(CYCLELEVEL),1)
 ifndef ALLOW_WARNINGS
@@ -4945,7 +4945,7 @@ ifneq ($(OS_TARGET),darwin)
 DIFFRESULT:=$(shell $(DIFF) $(OLDFPC) $(FPC))
 else
 ifneq ($(CODESIGN),)
-DIFFRESULT:=$(shell $(COPY) $(OLDFPC) $(OLDFPC).tmp; $(COPY) $(FPC) $(FPC).tmp; strip -no_uuid $(OLDFPC).tmp; strip -no_uuid $(FPC).tmp; $(CODESIGN) --remove-signature $(OLDFPC).tmp; codesign --remove-signature $(FPC).tmp; $(DIFF) $(OLDFPC).tmp $(FPC).tmp; $(RMPROG) $(OLDFPC).tmp $(FPC).tmp)
+DIFFRESULT:=$(shell $(COPY) $(OLDFPC) $(OLDFPC).tmp; $(COPY) $(FPC) $(FPC).tmp; strip -no_uuid $(OLDFPC).tmp; strip -no_uuid $(FPC).tmp; $(CODESIGN) --remove-signature $(OLDFPC).tmp; $(CODESIGN) --remove-signature $(FPC).tmp; $(DIFF) $(OLDFPC).tmp $(FPC).tmp; $(RMPROG) $(OLDFPC).tmp $(FPC).tmp)
 else
 DIFFRESULT:=$(shell $(COPY) $(OLDFPC) $(OLDFPC).tmp; $(COPY) $(FPC) $(FPC).tmp; strip -no_uuid $(OLDFPC).tmp; strip -no_uuid $(FPC).tmp; $(DIFF) $(OLDFPC).tmp $(FPC).tmp; $(RMPROG) $(OLDFPC).tmp $(FPC).tmp)
 endif

+ 2 - 2
compiler/Makefile.fpc

@@ -439,7 +439,7 @@ endif
 endif
 
 ifeq ($(OS_TARGET), darwin)
-CODESIGN?=$(strip $(wildcard $(addsuffix /codesign,$(SEARCHPATH))))
+CODESIGN?=$(firstword $(wildcard $(addsuffix /codesign$(SRCEXEEXT),$(SEARCHPATH))))
 endif
 
 # Use -Sew option by default
@@ -883,7 +883,7 @@ ifneq ($(OS_TARGET),darwin)
 DIFFRESULT:=$(shell $(DIFF) $(OLDFPC) $(FPC))
 else
 ifneq ($(CODESIGN),)
-DIFFRESULT:=$(shell $(COPY) $(OLDFPC) $(OLDFPC).tmp; $(COPY) $(FPC) $(FPC).tmp; strip -no_uuid $(OLDFPC).tmp; strip -no_uuid $(FPC).tmp; $(CODESIGN) --remove-signature $(OLDFPC).tmp; codesign --remove-signature $(FPC).tmp; $(DIFF) $(OLDFPC).tmp $(FPC).tmp; $(RMPROG) $(OLDFPC).tmp $(FPC).tmp)
+DIFFRESULT:=$(shell $(COPY) $(OLDFPC) $(OLDFPC).tmp; $(COPY) $(FPC) $(FPC).tmp; strip -no_uuid $(OLDFPC).tmp; strip -no_uuid $(FPC).tmp; $(CODESIGN) --remove-signature $(OLDFPC).tmp; $(CODESIGN) --remove-signature $(FPC).tmp; $(DIFF) $(OLDFPC).tmp $(FPC).tmp; $(RMPROG) $(OLDFPC).tmp $(FPC).tmp)
 else
 DIFFRESULT:=$(shell $(COPY) $(OLDFPC) $(OLDFPC).tmp; $(COPY) $(FPC) $(FPC).tmp; strip -no_uuid $(OLDFPC).tmp; strip -no_uuid $(FPC).tmp; $(DIFF) $(OLDFPC).tmp $(FPC).tmp; $(RMPROG) $(OLDFPC).tmp $(FPC).tmp)
 endif

+ 4 - 0
compiler/aarch64/cgcpu.pas

@@ -1797,12 +1797,16 @@ implementation
             reference_reset_base(ref,NR_SP,-16,ctempposinvalid,16,[]);
             ref.addressmode:=AM_PREINDEXED;
             list.concat(taicpu.op_reg_reg_ref(A_STP,NR_FP,NR_LR,ref));
+            current_asmdata.asmcfi.cfa_def_cfa_offset(list,2*sizeof(pint));
+            current_asmdata.asmcfi.cfa_offset(list,NR_FP,-16);
+            current_asmdata.asmcfi.cfa_offset(list,NR_LR,-8);
             if target_info.system=system_aarch64_win64 then
               list.concat(cai_seh_directive.create_offset(ash_savefplr_x,16));
             { initialise frame pointer }
             if current_procinfo.procdef.proctypeoption<>potype_exceptfilter then
               begin
                 a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_SP,NR_FP);
+                current_asmdata.asmcfi.cfa_def_cfa_register(list,NR_FP);
                 if target_info.system=system_aarch64_win64 then
                   list.concat(cai_seh_directive.create(ash_setfp));
               end

+ 1 - 1
compiler/aarch64/cpubase.pas

@@ -303,7 +303,7 @@ unit cpubase;
 
       NR_MM_RESULT_REG  = NR_D0;
 
-      NR_RETURN_ADDRESS_REG = NR_FUNCTION_RETURN_REG;
+      NR_RETURN_ADDRESS_REG = NR_LR;
 
       { Offset where the parent framepointer is pushed }
       PARENT_FRAMEPOINTER_OFFSET = 0;

+ 32 - 28
compiler/arm/aasmcpu.pas

@@ -189,6 +189,9 @@ uses
 
       pinsentry=^tinsentry;
 
+      taicpuflag = (cf_wideformat,cf_inIT,cf_lastinIT,cf_thumb);
+      taicpuflags = set of taicpuflag;
+
     const
       InsTab : array[0..instabentries-1] of TInsEntry={$i armtab.inc}
 
@@ -198,12 +201,12 @@ uses
     type
       taicpu = class(tai_cpu_abstract_sym)
          oppostfix : TOpPostfix;
-         wideformat : boolean;
          roundingmode : troundingmode;
+         flags : taicpuflags;
          procedure loadshifterop(opidx:longint;const so:tshifterop);
          procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset; ausermode: boolean=false);
          procedure loadconditioncode(opidx:longint;const acond:tasmcond);
-         procedure loadmodeflags(opidx:longint;const flags:tcpumodeflags);
+         procedure loadmodeflags(opidx:longint;const _modeflags:tcpumodeflags);
          procedure loadspecialreg(opidx:longint;const areg:tregister; const aflags:tspecialregflags);
          procedure loadrealconst(opidx:longint;const _value:bestreal);
 
@@ -235,8 +238,8 @@ uses
          constructor op_cond(op: tasmop; cond: tasmcond);
 
          { CPSxx }
-         constructor op_modeflags(op: tasmop; flags: tcpumodeflags);
-         constructor op_modeflags_const(op: tasmop; flags: tcpumodeflags; a: aint);
+         constructor op_modeflags(op: tasmop; _modeflags: tcpumodeflags);
+         constructor op_modeflags_const(op: tasmop; _modeflags: tcpumodeflags; a: aint);
 
          { MSR }
          constructor op_specialreg_reg(op: tasmop; specialreg: tregister; specialregflags: tspecialregflags; _op2: tregister);
@@ -273,9 +276,6 @@ uses
          procedure ppubuildderefimploper(var o:toper);override;
          procedure ppuderefoper(var o:toper);override;
       private
-         { pass1 info }
-         inIT,
-         lastinIT: boolean;
          { arm version info }
          fArmVMask,
          fArmMask  : longint;
@@ -404,14 +404,14 @@ implementation
          end;
       end;
 
-    procedure taicpu.loadmodeflags(opidx: longint; const flags: tcpumodeflags);
+    procedure taicpu.loadmodeflags(opidx: longint; const _modeflags: tcpumodeflags);
       begin
         allocate_oper(opidx+1);
         with oper[opidx]^ do
          begin
            if typ<>top_modeflags then
              clearop(opidx);
-           modeflags:=flags;
+           modeflags:=_modeflags;
            typ:=top_modeflags;
          end;
       end;
@@ -585,18 +585,18 @@ implementation
         loadconditioncode(0, cond);
       end;
 
-    constructor taicpu.op_modeflags(op: tasmop; flags: tcpumodeflags);
+    constructor taicpu.op_modeflags(op: tasmop; _modeflags: tcpumodeflags);
       begin
         inherited create(op);
         ops := 1;
-        loadmodeflags(0,flags);
+        loadmodeflags(0,_modeflags);
       end;
 
-    constructor taicpu.op_modeflags_const(op: tasmop; flags: tcpumodeflags; a: aint);
+    constructor taicpu.op_modeflags_const(op: tasmop; _modeflags: tcpumodeflags; a: aint);
       begin
         inherited create(op);
         ops := 2;
-        loadmodeflags(0,flags);
+        loadmodeflags(0,_modeflags);
         loadconst(1,a);
       end;
 
@@ -1427,7 +1427,7 @@ implementation
                                        (taicpu(curtai).oper[1]^.reg >= NR_R8) or
                                        (op2reg >= NR_R8) then
                                       begin
-                                        taicpu(curtai).wideformat:=true;
+                                        include(taicpu(curtai).flags,cf_wideformat);
 
                                         { Handle special cases where register rules are violated by optimizer/user }
                                         { if d == 13 || (d == 15 && S == ‘0’) || n == 15 || m IN [13,15] then UNPREDICTABLE; }
@@ -1698,8 +1698,14 @@ implementation
                       end;
                     else
                       begin
-                        taicpu(curtai).inIT:=in_it;
-                        taicpu(curtai).lastinIT:=in_it and (it_count=1);
+                        if in_it then
+                          include(taicpu(curtai).flags,cf_inIT)
+                        else
+                          exclude(taicpu(curtai).flags,cf_inIT);
+                        if in_it and (it_count=1) then
+                          include(taicpu(curtai).flags,cf_lastinIT)
+                        else
+                          exclude(taicpu(curtai).flags,cf_lastinIT);
 
                         if in_it then
                           begin
@@ -2204,7 +2210,6 @@ implementation
             IF_ARMv4,
             IF_ARMv4,
             IF_ARMv4T or IF_ARMv4,
-            IF_ARMv4T or IF_ARMv4 or IF_ARMv5,
             IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T,
             IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE,
             IF_ARMv4T or IF_ARMv4 or IF_ARMv5 or IF_ARMv5T or IF_ARMv5TE or IF_ARMv5TEJ,
@@ -2240,8 +2245,7 @@ implementation
       begin
         fArmVMask:=Masks[current_settings.cputype] or FPUMasks[current_settings.fputype];
 
-        if objdata.ThumbFunc then
-        //if current_settings.instructionset=is_thumb then
+        if cf_thumb in flags then
           begin
             fArmMask:=IF_THUMB;
             if CPUARM_HAS_THUMB2 in cpu_capabilities[current_settings.cputype] then
@@ -2497,7 +2501,7 @@ implementation
           end;
 
         { Check wideformat flag }
-        if wideformat and ((p^.flags and IF_WIDE)=0) then
+        if (cf_wideformat in flags) and ((p^.flags and IF_WIDE)=0) then
           begin
             matches:=0;
             exit;
@@ -2595,8 +2599,8 @@ implementation
         begin
           if (p^.code[0]=#$60) and
              (GenerateThumb2Code and
-              ((not inIT) and (oppostfix<>PF_S)) or
-              (inIT and (condition=C_None))) then
+              ((not(cf_inIT in flags)) and (oppostfix<>PF_S)) or
+              ((cf_inIT in flags) and (condition=C_None))) then
             begin
               Matches:=0;
               exit;
@@ -2610,10 +2614,10 @@ implementation
         end
       else if p^.code[0]=#$62 then
         begin
-          if (GenerateThumb2Code and
-              (condition<>C_None) and
-              (not inIT) and
-              (not lastinIT)) then
+          if GenerateThumb2Code and
+            (condition<>C_None) and
+            (not(cf_inIT in flags)) and
+            (not(cf_lastinIT in flags)) then
             begin
               Matches:=0;
               exit;
@@ -2621,7 +2625,7 @@ implementation
         end
       else if p^.code[0]=#$63 then
         begin
-          if inIT then
+          if cf_inIT in flags then
             begin
               Matches:=0;
               exit;
@@ -2642,7 +2646,7 @@ implementation
         end
       else if p^.code[0]=#$6B then
         begin
-          if inIT or
+          if (cf_inIT in flags) or
              (oppostfix<>PF_S) then
             begin
               Matches:=0;

+ 13 - 7
compiler/arm/agarmgas.pas

@@ -64,7 +64,6 @@ unit agarmgas;
         'armv3',
         'armv4',
         'armv4t',
-        'armv5',
         'armv5t',
         'armv5te',
         'armv5tej',
@@ -372,7 +371,7 @@ unit agarmgas;
 
     Procedure TArmInstrWriter.WriteInstruction(hp : tai);
     var op: TAsmOp;
-        postfix,s: string;
+        postfix,s,oppostfixstr: string;
         i: byte;
         sep: string[3];
     begin
@@ -380,20 +379,27 @@ unit agarmgas;
       postfix:='';
       if GenerateThumb2Code then
         begin
-          if taicpu(hp).wideformat then
+          if cf_wideformat in taicpu(hp).flags then
             postfix:='.w';
         end;
+      { GNU AS does not like an S postfix for several instructions in thumb mode though it is the only
+        valid encoding of mvn in thumb mode according to the arm docs }
+      if GenerateThumbCode and (taicpu(hp).oppostfix=PF_S) and
+        ((op=A_MVN) or (op=A_ORR) or (op=A_AND) or (op=A_LSL) or (op=A_ADC) or (op=A_LSR) or (op=A_SBC) or (op=A_EOR) or (op=A_ROR)) then
+        oppostfixstr:=''
+      else
+        oppostfixstr:=oppostfix2str[taicpu(hp).oppostfix];
       if unified_syntax then
         begin
           if taicpu(hp).ops = 0 then
-            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix]
+            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfixstr
           else if taicpu(hp).oppostfix in [PF_8..PF_U32F64] then
-            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix]
+            s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfixstr
           else
-            s:=#9+gas_op2str[op]+oppostfix2str[taicpu(hp).oppostfix]+cond2str[taicpu(hp).condition]+postfix; // Conditional infixes are deprecated in unified syntax
+            s:=#9+gas_op2str[op]+oppostfixstr+cond2str[taicpu(hp).condition]+postfix; // Conditional infixes are deprecated in unified syntax
         end
       else
-        s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfix2str[taicpu(hp).oppostfix];
+        s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]+oppostfixstr;
       if taicpu(hp).ops<>0 then
         begin
           sep:=#9;

+ 4 - 4
compiler/arm/armins.dat

@@ -215,7 +215,7 @@ reg32                    \3\x01\x2F\xFF\x10            ARM32,ARMv4T
 reg8,reg8                \300\1\x10\101                ARM32,ARMv4
 
 [CMNcc]
-reglo,reglo             \x6B\x42\xC0                     THUMB,ARMv4T
+reglo,reglo             \x6F\x42\xC0                     THUMB,ARMv4T
 
 reg32,immshifter        \x80\xF1\x10\x0F\x00             THUMB32,ARMv6T2
 reg32,reg32             \x80\xEB\x10\x0F\x00             THUMB32,WIDE,ARMv6T2
@@ -226,10 +226,10 @@ reg32,reg32,shifterop   \xE\x1\x60                       ARM32,ARMv4
 reg32,immshifter        \xF\x1\x60                       ARM32,ARMv4
 
 [CMPcc]
-reglo,reglo             \x6B\x42\x80                     THUMB,ARMv4T
+reglo,reglo             \x6F\x42\x80                     THUMB,ARMv4T
 reg32,reg32             \x61\x45\x0                      THUMB,ARMv4T
 
-reglo,immshifter        \x6B\x28\x0                      THUMB,ARMv4T
+reglo,immshifter        \x6F\x28\x0                      THUMB,ARMv4T
 
 reg32,immshifter         \x80\xF1\xB0\x0F\x00           THUMB32,WIDE,ARMv6T2
 reg32,reg32              \x80\xEB\xB0\x0F\x00           THUMB32,WIDE,ARMv6T2
@@ -612,7 +612,7 @@ reg32,reg32,shifterop \xE\x1\x20                     ARM32,ARMv4
 reg32,immshifter      \xF\x3\x20                     ARM32,ARMv4
 
 [TSTcc]
-reglo,reglo           \x6B\x42\x00                   THUMB,ARMv4T
+reglo,reglo           \x6F\x42\x00                   THUMB,ARMv4T
 
 reg32,immshifter      \x80\xF0\x10\x0F\x00           THUMB32,ARMv6T2
 reg32,reg32           \x80\xEA\x10\x0F\x00           THUMB32,WIDE,ARMv6T2

+ 4 - 4
compiler/arm/armtab.inc

@@ -592,7 +592,7 @@
     opcode  : A_CMN;
     ops     : 2;
     optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none);
-    code    : #107#66#192;
+    code    : #111#66#192;
     flags   : if_thumb or if_armv4t
   ),
   (
@@ -641,7 +641,7 @@
     opcode  : A_CMP;
     ops     : 2;
     optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none);
-    code    : #107#66#128;
+    code    : #111#66#128;
     flags   : if_thumb or if_armv4t
   ),
   (
@@ -655,7 +655,7 @@
     opcode  : A_CMP;
     ops     : 2;
     optypes : (ot_reglo,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none);
-    code    : #107#40#0;
+    code    : #111#40#0;
     flags   : if_thumb or if_armv4t
   ),
   (
@@ -2328,7 +2328,7 @@
     opcode  : A_TST;
     ops     : 2;
     optypes : (ot_reglo,ot_reglo,ot_none,ot_none,ot_none,ot_none);
-    code    : #107#66#0;
+    code    : #111#66#0;
     flags   : if_thumb or if_armv4t
   ),
   (

+ 142 - 117
compiler/arm/cgcpu.pas

@@ -44,6 +44,7 @@ unit cgcpu;
         procedure a_load_const_cgpara(list : TAsmList;size : tcgsize;a : tcgint;const paraloc : TCGPara);override;
        protected
          procedure a_load_ref_cgparalocref(list: TAsmList; sourcesize: tcgsize; sizeleft: tcgint; const ref, paralocref: treference; const cgpara: tcgpara; const location: PCGParaLocation); override;
+         procedure init_mmregister_allocator;
        public
         procedure a_loadaddr_ref_cgpara(list : TAsmList;const r : treference;const paraloc : TCGPara);override;
 
@@ -294,21 +295,11 @@ unit cgcpu;
           rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
               [RS_R0,RS_R1,RS_R2,RS_R3,RS_R9,RS_R12,RS_R4,RS_R5,RS_R6,RS_R8,
                RS_R10,RS_R11,RS_R14],first_int_imreg,[]);
-        rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
+        if FPUARM_HAS_FPA in fpu_capabilities[current_settings.fputype] then
+          rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
             [RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7],first_fpu_imreg,[]);
-        { The register allocator currently cannot deal with multiple
-          non-overlapping subregs per register, so we can only use
-          half the single precision registers for now (as sub registers of the
-          double precision ones). }
-        if FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype] then
-          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD,
-              [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7,
-               RS_D16,RS_D17,RS_D18,RS_D19,RS_D20,RS_D21,RS_D22,RS_D23,RS_D24,RS_D25,RS_D26,RS_D27,RS_D28,RS_D29,RS_D30,RS_D31,
-               RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15
-              ],first_mm_imreg,[])
-        else
-          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD,
-              [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7,RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15],first_mm_imreg,[]);
+
+        init_mmregister_allocator;
       end;
 
 
@@ -588,6 +579,33 @@ unit cgcpu;
       end;
 
 
+    procedure tbasecgarm.init_mmregister_allocator;
+      begin
+        { The register allocator currently cannot deal with multiple
+          non-overlapping subregs per register, so we can only use
+          half the single precision registers for now (as sub registers of the
+          double precision ones). }
+        if (FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype]) and
+          (FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype]) then
+          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD,
+              [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7,
+               RS_D16,RS_D17,RS_D18,RS_D19,RS_D20,RS_D21,RS_D22,RS_D23,RS_D24,RS_D25,RS_D26,RS_D27,RS_D28,RS_D29,RS_D30,RS_D31,
+               RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15
+              ],first_mm_imreg,[])
+        else if (FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype]) then
+          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFS,
+              [RS_S0,RS_S1,RS_S2,RS_S3,RS_S4,RS_S5,RS_S6,RS_S7,
+               RS_S16,RS_S17,RS_S18,RS_S19,RS_S20,RS_S21,RS_S22,RS_S23,RS_S24,RS_S25,RS_S26,RS_S27,RS_S28,RS_S29,RS_S30,RS_S31,
+               RS_S8,RS_S9,RS_S10,RS_S11,RS_S12,RS_S13,RS_S14,RS_S15
+              ],first_mm_imreg,[])
+        else if FPUARM_HAS_VFP_EXTENSION in fpu_capabilities[current_settings.fputype] then
+          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD,
+              [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7,
+               RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15
+              ],first_mm_imreg,[]);
+      end;
+
+
     procedure tbasecgarm.a_loadaddr_ref_cgpara(list : TAsmList;const r : treference;const paraloc : TCGPara);
       var
         ref: treference;
@@ -728,9 +746,9 @@ unit cgcpu;
         (A_NONE,A_MOV,A_ADD,A_AND,A_NONE,A_NONE,A_MUL,A_MUL,A_NONE,A_NONE,A_ORR,
          A_ASR,A_LSL,A_LSR,A_SUB,A_EOR,A_NONE,A_ROR);
 
-      op_reg_postfix: array[TOpCG] of TOpPostfix =
-        (PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,
-         PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None);
+      op_reg_postfix_thumb: array[TOpCG] of TOpPostfix =
+        (PF_None,PF_None,PF_None,PF_S,PF_None,PF_None,PF_None,PF_None,PF_None,PF_None,PF_S,
+         PF_None,PF_S,PF_S,PF_None,PF_S,PF_None,PF_S);
 
     procedure tcgarm.a_op_const_reg_reg(list: TAsmList; op: TOpCg;
       size: tcgsize; a: tcgint; src, dst: tregister);
@@ -1889,7 +1907,7 @@ unit cgcpu;
          r : byte;
          mmregs,
          regs, saveregs : tcpuregisterset;
-         registerarea,
+         registerarea, offset,
          r7offset,
          stackmisalignment : pint;
          imm1, imm2: DWord;
@@ -1987,14 +2005,24 @@ unit cgcpu;
                              break;
                            end;
                      list.concat(setoppostfix(taicpu.op_ref_regset(A_STM,ref,R_INTREGISTER,R_SUBWHOLE,regs),PF_FD));
+                     current_asmdata.asmcfi.cfa_def_cfa_offset(list,registerarea);
                    end;
 
                 if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
                   begin
+                    offset:=-4;
+                    for r:=RS_R15 downto RS_R0 do
+                      if r in regs then
+                        begin
+                          current_asmdata.asmcfi.cfa_offset(list,newreg(R_INTREGISTER,r,R_SUBWHOLE),offset);
+                          dec(offset,4);
+                        end;
                     { the framepointer now points to the saved R15, so the saved
                       framepointer is at R11-12 (for get_caller_frame) }
                     list.concat(taicpu.op_reg_reg_const(A_SUB,NR_FRAME_POINTER_REG,NR_R12,4));
                     a_reg_dealloc(list,NR_R12);
+                    current_asmdata.asmcfi.cfa_def_cfa_register(list,current_procinfo.framepointer);
+                    current_asmdata.asmcfi.cfa_def_cfa_offset(list,4);
                   end;
               end
             else
@@ -2077,6 +2105,8 @@ unit cgcpu;
                     list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
                     a_reg_dealloc(list,NR_R12);
                   end;
+                if current_procinfo.framepointer=NR_STACK_POINTER_REG then
+                  current_asmdata.asmcfi.cfa_def_cfa_offset(list,registerarea+localsize);
               end;
 
             if (mmregs<>[]) or
@@ -3715,6 +3745,15 @@ unit cgcpu;
                    if r in regs then
                      inc(registerarea,4);
                  list.concat(taicpu.op_regset(A_PUSH,R_INTREGISTER,R_SUBWHOLE,regs));
+                 { we need to run the loop twice to get cfi right }
+                 registerarea:=0;
+                 for r:=RS_R0 to RS_R15 do
+                   if r in regs then
+                     begin
+                       inc(registerarea,4);
+                       current_asmdata.asmcfi.cfa_offset(list,newreg(R_INTREGISTER,r,R_SUBWHOLE),-registerarea);
+                     end;
+                 current_asmdata.asmcfi.cfa_def_cfa_offset(list,registerarea);
                end;
 
             stackmisalignment:=registerarea mod current_settings.alignment.localalignmax;
@@ -3754,18 +3793,14 @@ unit cgcpu;
                     a_load_const_reg(list,OS_ADDR,-localsize,NR_R4);
                     list.concat(taicpu.op_reg_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R4));
                     include(regs,RS_R4);
-
-                    //!!!! if current_procinfo.framepointer=NR_STACK_POINTER_REG then
-                    //!!!!   a_reg_alloc(list,NR_R12);
-                    //!!!! a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
-                    //!!!! list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
-                    //!!!! a_reg_dealloc(list,NR_R12);
                   end;
+                current_asmdata.asmcfi.cfa_def_cfa_offset(list,registerarea+localsize);
               end;
 
             if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
               begin
                 list.concat(taicpu.op_reg_reg_const(A_ADD,current_procinfo.framepointer,NR_STACK_POINTER_REG,0));
+                current_asmdata.asmcfi.cfa_def_cfa_register(list,current_procinfo.framepointer);
               end;
           end;
       end;
@@ -3907,7 +3942,7 @@ unit cgcpu;
                      a_internal_load_ref_reg(list,OS_S8,OS_S8,usedtmpref,tmpreg);
                    list.concat(taicpu.op_reg_const(A_LSL,tmpreg,8));
 
-                   list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                   list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                  end;
                OS_32,OS_S32:
                  begin
@@ -3937,7 +3972,7 @@ unit cgcpu;
                        inc(usedtmpref.offset,dir*2);
                        a_internal_load_ref_reg(list,OS_16,OS_16,usedtmpref,tmpreg);
                        list.concat(taicpu.op_reg_const(A_LSL,tmpreg,16));
-                       list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                       list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                      end
                    else
                      begin
@@ -3947,15 +3982,15 @@ unit cgcpu;
                        inc(usedtmpref.offset,dir);
                        a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
                        list.concat(taicpu.op_reg_const(A_LSL,tmpreg,8));
-                       list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                       list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                        inc(usedtmpref.offset,dir);
                        a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
                        list.concat(taicpu.op_reg_const(A_LSL,tmpreg,16));
-                       list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                       list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                        inc(usedtmpref.offset,dir);
                        a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
                        list.concat(taicpu.op_reg_const(A_LSL,tmpreg,24));
-                       list.concat(taicpu.op_reg_reg(A_ORR,reg,tmpreg));
+                       list.concat(setoppostfix(taicpu.op_reg_reg(A_ORR,reg,tmpreg),PF_S));
                      end;
                  end
                else
@@ -3978,7 +4013,7 @@ unit cgcpu;
           if not(size in [OS_8,OS_S8,OS_16,OS_S16,OS_32,OS_S32]) then
             internalerror(2002090908);
           if is_thumb_imm(a) then
-            list.concat(taicpu.op_reg_const(A_MOV,reg,a))
+            list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,reg,a),PF_S))
           else
             begin
               reference_reset(hr,4,[]);
@@ -4139,7 +4174,7 @@ unit cgcpu;
           OP_NEG:
             list.concat(taicpu.op_reg_reg(A_NEG,dst,src));
           OP_NOT:
-            list.concat(taicpu.op_reg_reg(A_MVN,dst,src));
+            list.concat(setoppostfix(taicpu.op_reg_reg(A_MVN,dst,src),PF_S));
           OP_DIV,OP_IDIV:
             internalerror(200308284);
           OP_ROL:
@@ -4150,13 +4185,13 @@ unit cgcpu;
               tmpreg:=getintregister(list,OS_32);
               a_load_const_reg(list,OS_32,32,tmpreg);
               list.concat(taicpu.op_reg_reg(A_SUB,tmpreg,src));
-              list.concat(taicpu.op_reg_reg(A_ROR,dst,src));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_ROR,dst,src),PF_S));
             end;
           else
             begin
               a_reg_alloc(list,NR_DEFAULTFLAGS);
               list.concat(setoppostfix(
-                taicpu.op_reg_reg(op_reg_opcg2asmop[op],dst,src),op_reg_postfix[op]));
+                taicpu.op_reg_reg(op_reg_opcg2asmop[op],dst,src),op_reg_postfix_thumb[op]));
             end;
         end;
         maybeadjustresult(list,op,size,dst);
@@ -4192,7 +4227,7 @@ unit cgcpu;
              // if cgsetflags or setflags then
              a_reg_alloc(list,NR_DEFAULTFLAGS);
             list.concat(setoppostfix(
-              taicpu.op_reg_const(op_reg_opcg2asmop[op],dst,a),op_reg_postfix[op]));
+              taicpu.op_reg_const(op_reg_opcg2asmop[op],dst,a),op_reg_postfix_thumb[op]));
 
             if (cgsetflags {!!! or setflags }) and (size in [OS_8,OS_16,OS_32]) then
               begin
@@ -4251,7 +4286,7 @@ unit cgcpu;
             { x := y and 0; just clears a register, this sometimes gets generated on 64bit ops.
               Just using mov x, #0 might allow some easier optimizations down the line. }
             else if (op = OP_AND) and (dword(a)=0) then
-              list.concat(taicpu.op_reg_const(A_MOV,dst,0))
+              list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,dst,0),PF_S))
             { x := y AND $FFFFFFFF just copies the register, so use mov for better optimizations }
             else if (op = OP_AND) and (not(dword(a))=0) then
               // do nothing
@@ -4307,10 +4342,10 @@ unit cgcpu;
         ai:=setcondition(taicpu.op_sym(A_B,l1),flags_to_cond(f));
         ai.is_jmp:=true;
         list.concat(ai);
-        list.concat(taicpu.op_reg_const(A_MOV,reg,0));
+        list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,reg,0),PF_S));
         list.concat(taicpu.op_sym(A_B,l2));
         cg.a_label(list,l1);
-        list.concat(taicpu.op_reg_const(A_MOV,reg,1));
+        list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,reg,1),PF_S));
         a_reg_dealloc(list,NR_DEFAULTFLAGS);
         cg.a_label(list,l2);
       end;
@@ -4329,30 +4364,11 @@ unit cgcpu;
           rg[R_INTREGISTER]:=trgintcputhumb2.create(R_INTREGISTER,R_SUBWHOLE,
               [RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,
                RS_R10,RS_R12,RS_R14],first_int_imreg,[]);
-        rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
+        if FPUARM_HAS_FPA in fpu_capabilities[current_settings.fputype] then
+          rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
             [RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7],first_fpu_imreg,[]);
 
-        if (FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype]) and
-          (FPUARM_HAS_VFP_DOUBLE in fpu_capabilities[current_settings.fputype]) then
-          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD,
-              [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7,
-               RS_D16,RS_D17,RS_D18,RS_D19,RS_D20,RS_D21,RS_D22,RS_D23,RS_D24,RS_D25,RS_D26,RS_D27,RS_D28,RS_D29,RS_D30,RS_D31,
-               RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15
-              ],first_mm_imreg,[])
-        else if (FPUARM_HAS_32REGS in fpu_capabilities[current_settings.fputype]) then
-          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFS,
-              [RS_S0,RS_S1,RS_S2,RS_S3,RS_S4,RS_S5,RS_S6,RS_S7,
-               RS_S16,RS_S17,RS_S18,RS_S19,RS_S20,RS_S21,RS_S22,RS_S23,RS_S24,RS_S25,RS_S26,RS_S27,RS_S28,RS_S29,RS_S30,RS_S31,
-               RS_S8,RS_S9,RS_S10,RS_S11,RS_S12,RS_S13,RS_S14,RS_S15
-              ],first_mm_imreg,[])
-        else if FPUARM_HAS_VFP_EXTENSION in fpu_capabilities[current_settings.fputype] then
-          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD,
-              [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7,
-               RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15
-              ],first_mm_imreg,[])
-        else
-          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
-              [RS_S0,RS_S1,RS_R2,RS_R3,RS_R4,RS_S31],first_mm_imreg,[]);
+        init_mmregister_allocator;
       end;
 
 
@@ -4897,15 +4913,18 @@ unit cgcpu;
           begin
             firstfloatreg:=RS_NO;
             lastfloatreg:=RS_NO;
-            { save floating point registers? }
-            for r:=RS_F0 to RS_F7 do
-              if r in rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall) then
-                begin
-                  if firstfloatreg=RS_NO then
-                    firstfloatreg:=r;
-                  lastfloatreg:=r;
-                  inc(stackmisalignment,12);
-                end;
+            if FPUARM_HAS_FPA in fpu_capabilities[current_settings.fputype] then
+              begin
+                { save floating point registers? }
+                for r:=RS_F0 to RS_F7 do
+                  if r in rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall) then
+                    begin
+                      if firstfloatreg=RS_NO then
+                        firstfloatreg:=r;
+                      lastfloatreg:=r;
+                      inc(stackmisalignment,12);
+                    end;
+              end;
 
             a_reg_alloc(list,NR_STACK_POINTER_REG);
             if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
@@ -4965,22 +4984,25 @@ unit cgcpu;
                   end;
               end;
 
-            if firstfloatreg<>RS_NO then
+            if FPUARM_HAS_FPA in fpu_capabilities[current_settings.fputype] then
               begin
-                reference_reset(ref,4,[]);
-                if tg.direction*tcpuprocinfo(current_procinfo).floatregstart>=1023 then
-                  begin
-                    a_load_const_reg(list,OS_ADDR,-tcpuprocinfo(current_procinfo).floatregstart,NR_R12);
-                    list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_R12,current_procinfo.framepointer,NR_R12));
-                    ref.base:=NR_R12;
-                  end
-                else
+                if firstfloatreg<>RS_NO then
                   begin
-                    ref.base:=current_procinfo.framepointer;
-                    ref.offset:=tcpuprocinfo(current_procinfo).floatregstart;
+                    reference_reset(ref,4,[]);
+                    if tg.direction*tcpuprocinfo(current_procinfo).floatregstart>=1023 then
+                      begin
+                        a_load_const_reg(list,OS_ADDR,-tcpuprocinfo(current_procinfo).floatregstart,NR_R12);
+                        list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_R12,current_procinfo.framepointer,NR_R12));
+                        ref.base:=NR_R12;
+                      end
+                    else
+                      begin
+                        ref.base:=current_procinfo.framepointer;
+                        ref.offset:=tcpuprocinfo(current_procinfo).floatregstart;
+                      end;
+                    list.concat(taicpu.op_reg_const_ref(A_SFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
+                      lastfloatreg-firstfloatreg+1,ref));
                   end;
-                list.concat(taicpu.op_reg_const_ref(A_SFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
-                  lastfloatreg-firstfloatreg+1,ref));
               end;
           end;
       end;
@@ -4999,38 +5021,41 @@ unit cgcpu;
         if not(nostackframe) then
           begin
             stackmisalignment:=0;
-            { restore floating point register }
-            firstfloatreg:=RS_NO;
-            lastfloatreg:=RS_NO;
-            { save floating point registers? }
-            for r:=RS_F0 to RS_F7 do
-              if r in rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall) then
-                begin
-                  if firstfloatreg=RS_NO then
-                    firstfloatreg:=r;
-                  lastfloatreg:=r;
-                  { floating point register space is already included in
-                    localsize below by calc_stackframe_size
-                   inc(stackmisalignment,12);
-                  }
-                end;
-
-            if firstfloatreg<>RS_NO then
+            if FPUARM_HAS_FPA in fpu_capabilities[current_settings.fputype] then
               begin
-                reference_reset(ref,4,[]);
-                if tg.direction*tcpuprocinfo(current_procinfo).floatregstart>=1023 then
-                  begin
-                    a_load_const_reg(list,OS_ADDR,-tcpuprocinfo(current_procinfo).floatregstart,NR_R12);
-                    list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_R12,current_procinfo.framepointer,NR_R12));
-                    ref.base:=NR_R12;
-                  end
-                else
+                { restore floating point register }
+                firstfloatreg:=RS_NO;
+                lastfloatreg:=RS_NO;
+                { save floating point registers? }
+                for r:=RS_F0 to RS_F7 do
+                  if r in rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall) then
+                    begin
+                      if firstfloatreg=RS_NO then
+                        firstfloatreg:=r;
+                      lastfloatreg:=r;
+                      { floating point register space is already included in
+                        localsize below by calc_stackframe_size
+                       inc(stackmisalignment,12);
+                      }
+                    end;
+
+                if firstfloatreg<>RS_NO then
                   begin
-                    ref.base:=current_procinfo.framepointer;
-                    ref.offset:=tcpuprocinfo(current_procinfo).floatregstart;
+                    reference_reset(ref,4,[]);
+                    if tg.direction*tcpuprocinfo(current_procinfo).floatregstart>=1023 then
+                      begin
+                        a_load_const_reg(list,OS_ADDR,-tcpuprocinfo(current_procinfo).floatregstart,NR_R12);
+                        list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_R12,current_procinfo.framepointer,NR_R12));
+                        ref.base:=NR_R12;
+                      end
+                    else
+                      begin
+                        ref.base:=current_procinfo.framepointer;
+                        ref.offset:=tcpuprocinfo(current_procinfo).floatregstart;
+                      end;
+                    list.concat(taicpu.op_reg_const_ref(A_LFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
+                      lastfloatreg-firstfloatreg+1,ref));
                   end;
-                list.concat(taicpu.op_reg_const_ref(A_LFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
-                  lastfloatreg-firstfloatreg+1,ref));
               end;
 
             regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
@@ -5347,11 +5372,11 @@ unit cgcpu;
         case op of
           OP_NEG:
             begin
-              list.concat(taicpu.op_reg_const(A_MOV,regdst.reglo,0));
-              list.concat(taicpu.op_reg_const(A_MOV,regdst.reghi,0));
+              list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,regdst.reglo,0),PF_S));
+              list.concat(setoppostfix(taicpu.op_reg_const(A_MOV,regdst.reghi,0),PF_S));
               cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
               list.concat(taicpu.op_reg_reg(A_SUB,regdst.reglo,regsrc.reglo));
-              list.concat(taicpu.op_reg_reg(A_SBC,regdst.reghi,regsrc.reghi));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_SBC,regdst.reghi,regsrc.reghi),PF_S));
               cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
             end;
           OP_NOT:
@@ -5368,13 +5393,13 @@ unit cgcpu;
             begin
               cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
               list.concat(taicpu.op_reg_reg(A_ADD,regdst.reglo,regsrc.reglo));
-              list.concat(taicpu.op_reg_reg(A_ADC,regdst.reghi,regsrc.reghi));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_ADC,regdst.reghi,regsrc.reghi),PF_S));
             end;
           OP_SUB:
             begin
               cg.a_reg_alloc(list,NR_DEFAULTFLAGS);
               list.concat(taicpu.op_reg_reg(A_SUB,regdst.reglo,regsrc.reglo));
-              list.concat(taicpu.op_reg_reg(A_SBC,regdst.reghi,regsrc.reghi));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_SBC,regdst.reghi,regsrc.reghi),PF_S));
             end;
           else
             internalerror(2003083105);
@@ -5409,7 +5434,7 @@ unit cgcpu;
 
                tmpreg:=cg.getintregister(list,OS_32);
                cg.a_load_const_reg(list,OS_32,aint(hi(value)),tmpreg);
-               list.concat(taicpu.op_reg_reg(A_ADC,reg.reghi,tmpreg));
+               list.concat(setoppostfix(taicpu.op_reg_reg(A_ADC,reg.reghi,tmpreg),PF_S));
             end;
           OP_SUB:
             begin
@@ -5428,7 +5453,7 @@ unit cgcpu;
 
               tmpreg:=cg.getintregister(list,OS_32);
               cg.a_load_const_reg(list,OS_32,hi(value),tmpreg);
-              list.concat(taicpu.op_reg_reg(A_SBC,reg.reghi,tmpreg));
+              list.concat(setoppostfix(taicpu.op_reg_reg(A_SBC,reg.reghi,tmpreg),PF_S));
             end;
           else
             internalerror(2003083106);

+ 1 - 1
compiler/arm/cpubase.pas

@@ -322,7 +322,7 @@ unit cpubase;
 
       NR_MM_RESULT_REG  = NR_D0;
 
-      NR_RETURN_ADDRESS_REG = NR_FUNCTION_RETURN_REG;
+      NR_RETURN_ADDRESS_REG = NR_R14;
 
       { Offset where the parent framepointer is pushed }
       PARENT_FRAMEPOINTER_OFFSET = 0;

+ 13 - 15
compiler/arm/cpuinfo.pas

@@ -40,7 +40,6 @@ Type
        cpu_armv3,
        cpu_armv4,
        cpu_armv4t,
-       cpu_armv5,
        cpu_armv5t,
        cpu_armv5te,
        cpu_armv5tej,
@@ -556,7 +555,6 @@ Const
      'ARMV3',
      'ARMV4',
      'ARMV4T',
-     'ARMV5',
      'ARMV5T',
      'ARMV5TE',
      'ARMV5TEJ',
@@ -1058,7 +1056,8 @@ Const
 
  type
    tcpuflags =
-      (CPUARM_HAS_ALL_MEM,    { CPU supports LDRSB/LDRSH/LDRH/STRH instructions           }
+      (CPUARM_HAS_THUMB,      { CPU supports THUMB                                        }
+       CPUARM_HAS_ALL_MEM,    { CPU supports LDRSB/LDRSH/LDRH/STRH instructions           }
        CPUARM_HAS_BX,         { CPU supports the BX instruction                           }
        CPUARM_HAS_BLX,        { CPU supports the BLX rX instruction                       }
        CPUARM_HAS_BLX_LABEL,  { CPU supports the BLX <label> instruction                  }
@@ -1092,22 +1091,21 @@ Const
      ( { cpu_none     } [],
        { cpu_armv3    } [],
        { cpu_armv4    } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_UMULL],
-       { cpu_armv4t   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_UMULL],
-       { cpu_armv5    } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
-       { cpu_armv5t   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
-       { cpu_armv5te  } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
-       { cpu_armv5tej } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
+       { cpu_armv4t   } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_UMULL],
+       { cpu_armv5t   } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_UMULL],
+       { cpu_armv5te  } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
+       { cpu_armv5tej } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_UMULL],
        { cpu_armv6    } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
        { cpu_armv6k   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
-       { cpu_armv6t2  } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv6z   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
-       { cpu_armv6m   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_REV],
+       { cpu_armv6t2  } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv6z   } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX,CPUARM_HAS_UMULL],
+       { cpu_armv6m   } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_REV],
        { the identifier armv7 is should not be used, it is considered being equal to armv7a }
        { cpu_armv7    } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv7a   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv7r   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv7m   } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
-       { cpu_armv7em  } [CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL]
+       { cpu_armv7a   } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv7r   } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv7m   } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL],
+       { cpu_armv7em  } [CPUARM_HAS_THUMB,CPUARM_HAS_ALL_MEM,CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_THUMB_IDIV,CPUARM_HAS_DMB,CPUARM_HAS_THUMB2,CPUARM_HAS_UMULL]
      );
 
      fpu_capabilities : array[tfputype] of set of tfpuflags =

+ 2 - 2
compiler/arm/narmset.pas

@@ -112,11 +112,11 @@ implementation
              right.resultdef, right.resultdef, true);
 
             hregister:=hlcg.getintregister(current_asmdata.CurrAsmList, opdef);
-            current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_MOV,hregister,1));
+            hlcg.a_load_const_reg(current_asmdata.CurrAsmList,opdef,1,hregister);
 
             if GenerateThumbCode or GenerateThumb2Code then
               begin
-                current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_LSL,hregister,left.location.register));
+                hlcg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_SHL,opdef,left.location.register,hregister);
                 cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
                 current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_TST,right.location.register,hregister));
               end

+ 9 - 1
compiler/arm/raarm.pas

@@ -43,13 +43,21 @@ unit raarm;
   implementation
 
     uses
+      globals,
+      cpuinfo,
       aasmcpu;
 
     function TARMInstruction.ConcatInstruction(p:TAsmList) : tai;
       begin
         result:=inherited ConcatInstruction(p);
         (result as taicpu).oppostfix:=oppostfix;
-        (result as taicpu).wideformat:=wideformat;
+        if wideformat then
+          include((result as taicpu).flags,cf_wideformat)
+        else
+          exclude((result as taicpu).flags,cf_wideformat);
+        { GNU As assumes implicit S postfix for some instructions in thumb mode }
+        if (current_settings.instructionset=is_thumb) and (((result as taicpu).oppostfix=PF_None) and ((opcode=A_MOV) and ((result as taicpu).oper[1]^.typ=top_const)) or (opcode=A_MVN)) then
+          (result as taicpu).oppostfix:=PF_S
       end;
 
 

+ 18 - 2
compiler/assemble.pas

@@ -205,6 +205,10 @@ interface
 
       TInternalAssembler=class(TAssembler)
       private
+{$ifdef ARM}
+        { true, if thumb instructions are generated }
+        Code16 : Boolean;
+{$endif ARM}
         FCObjOutput : TObjOutputclass;
         FCInternalAr : TObjectWriterClass;
         { the aasmoutput lists that need to be processed }
@@ -1290,6 +1294,9 @@ Implementation
         ObjOutput:=nil;
         ObjData:=nil;
         SmartAsm:=smart;
+{$ifdef ARM}
+        Code16:=current_settings.instructionset=is_thumb;
+{$endif ARM}
       end;
 
 
@@ -1713,8 +1720,11 @@ Implementation
                    asd_thumb_func:
                      ObjData.ThumbFunc:=true;
                    asd_code:
-                     { ai_directive(hp).name can be only 16 or 32, this is checked by the reader }
-                     ObjData.ThumbFunc:=tai_directive(hp).name='16';
+                     begin
+                       { ai_directive(hp).name can be only 16 or 32, this is checked by the reader }
+                       ObjData.ThumbFunc:=tai_directive(hp).name='16';
+                       Code16:=tai_directive(hp).name='16';
+                     end
 {$endif ARM}
 {$ifdef RISCV}
                    asd_option:
@@ -1746,6 +1756,12 @@ Implementation
                ObjData.alloc(Tai_string(hp).len);
              ait_instruction :
                begin
+{$ifdef arm}
+                 if code16 then
+                   include(taicpu(hp).flags,cf_thumb)
+                 else
+                   exclude(taicpu(hp).flags,cf_thumb);
+{$endif arm}
                  { reset instructions which could change in pass 2 }
                  Taicpu(hp).resetpass2;
                  ObjData.alloc(Taicpu(hp).Pass1(ObjData));

+ 61 - 3
compiler/cfidwarf.pas

@@ -244,8 +244,6 @@ implementation
           datatype:=dt_none;
       end;
 
-
-
 {****************************************************************************
                              TDwarfAsmCFILowLevel
 ****************************************************************************}
@@ -289,6 +287,20 @@ implementation
         list.concat(tai_const.create_uleb128bit(36));
         list.concat(tai_const.create_uleb128bit((-1) div data_alignment_factor));
       end;
+{$elseif defined(arm)}
+    procedure TDwarfAsmCFILowLevel.generate_initial_instructions(list:TAsmList);
+      begin
+        list.concat(tai_const.create_8bit(DW_CFA_def_cfa));
+        list.concat(tai_const.create_uleb128bit(dwarf_reg(NR_STACK_POINTER_REG)));
+        list.concat(tai_const.create_uleb128bit(0));
+      end;
+{$elseif defined(aarch64)}
+    procedure TDwarfAsmCFILowLevel.generate_initial_instructions(list:TAsmList);
+      begin
+        list.concat(tai_const.create_8bit(DW_CFA_def_cfa));
+        list.concat(tai_const.create_uleb128bit(dwarf_reg(NR_STACK_POINTER_REG)));
+        list.concat(tai_const.create_uleb128bit(0));
+      end;
 {$else}
     { if more cpu dependend stuff is implemented, this needs more refactoring }
     procedure TDwarfAsmCFILowLevel.generate_initial_instructions(list:TAsmList);
@@ -535,12 +547,58 @@ implementation
     procedure TDwarfAsmCFILowLevel.cfa_advance_loc(list:TAsmList);
       var
         currloclabel : tasmlabel;
+        hp : tai;
+        instrcount : longint;
+        dwarfloc: Integer;
       begin
         if FLastloclabel=nil then
           internalerror(200404082);
+        { search the list backwards and check if we really need an advance loc,
+          i.e. if real code/data has been generated since the last cfa_advance_loc
+          call
+        }
+        hp:=tai(list.Last);
+        while assigned(hp) do
+          begin
+            { if we encounter FLastloclabel without encountering code/data, see check below,
+              we do not need insert an advance_loc entry }
+            if (hp.typ=ait_label) and (tai_label(hp).labsym=FLastloclabel) then
+              exit;
+            { stop if we find any tai which results in code or data }
+            if not(hp.typ in ([ait_label]+SkipInstr)) then
+              break;
+            hp:=tai(hp.Previous);
+          end;
+
+        { check if the last advance entry is less then 8 instructions away:
+          as x86 instructions might not be bigger than 15 bytes and most other
+          CPUs use only 4 byte instructions or smaller, this is safe
+          we could search even more but this takes more time and 8 instructions should be normally enough
+        }
+        hp:=tai(list.Last);
+        instrcount:=0;
+        dwarfloc:=DW_CFA_advance_loc4;
+        while assigned(hp) and (instrcount<8) do
+          begin
+            { stop if we find any tai which results in code or data }
+            if not(hp.typ in ([ait_label,ait_instruction]+SkipInstr)) then
+              break;
+            if (hp.typ=ait_label) and (tai_label(hp).labsym=FLastloclabel) then
+              begin
+                dwarfloc:=DW_CFA_advance_loc1;
+                break;
+              end;
+            if hp.typ=ait_instruction then
+              inc(instrcount);
+            hp:=tai(hp.Previous);
+          end;
+
         current_asmdata.getlabel(currloclabel,alt_dbgframe);
         list.concat(tai_label.create(currloclabel));
-        DwarfList.concat(tdwarfitem.create_reloffset(DW_CFA_advance_loc4,doe_32bit,FLastloclabel,currloclabel));
+        if dwarfloc=DW_CFA_advance_loc1 then
+          DwarfList.concat(tdwarfitem.create_reloffset(DW_CFA_advance_loc1,doe_8bit,FLastloclabel,currloclabel))
+        else
+          DwarfList.concat(tdwarfitem.create_reloffset(DW_CFA_advance_loc4,doe_32bit,FLastloclabel,currloclabel));
         FLastloclabel:=currloclabel;
       end;
 

+ 10 - 4
compiler/dbgstabs.pas

@@ -1597,6 +1597,7 @@ implementation
       var
         st : string;
         ss : ansistring;
+        i : longint;
       begin
         ss:='';
         { Don't write info for default parameter values, the N_Func breaks
@@ -1609,10 +1610,15 @@ implementation
           conststring:
             begin
               if sym.value.len<200 then
-                if target_dbg.id=dbg_stabs then
-                  st:='s'''+backspace_quote(octal_quote(strpas(pchar(sym.value.valueptr)),[#0..#9,#11,#12,#14..#31,'''']),['"','\',#10,#13])+''''
-                else
-                  st:='s'''+stabx_quote_const(octal_quote(strpas(pchar(sym.value.valueptr)),[#0..#9,#11,#12,#14..#31,'''']))+''''
+                begin
+                  setlength(ss,sym.value.len);
+                  for i:=0 to sym.value.len-1 do
+                    ss[i+1]:=pchar(sym.value.valueptr)[i];
+                  if target_dbg.id=dbg_stabs then
+                    st:='s'''+backspace_quote(octal_quote(ss,[#0..#9,#11,#12,#14..#31,'''']),['"','\',#10,#13])+''''
+                  else
+                    st:='s'''+stabx_quote_const(octal_quote(ss,[#0..#9,#11,#12,#14..#31,'''']))+'''';
+                end
               else
                 st:='<constant string too long>';
             end;

+ 10 - 6
compiler/m68k/ag68kgas.pas

@@ -169,7 +169,7 @@ interface
       end;
 
 
-    function getopstr(var o:toper) : string;
+    function getopstr(size: topsize; var o:toper) : string;
       var
         i : tsuperregister;
       begin
@@ -220,10 +220,14 @@ interface
             getopstr:='#'+tostr(longint(o.val));
           top_realconst:
             begin
-              str(o.val_real,getopstr);
-              if getopstr[1]=' ' then
-                getopstr[1]:='+';
-              getopstr:='#0d'+getopstr;
+              case size of
+                S_FS:
+                  getopstr:='#0x'+hexstr(longint(single(o.val_real)),sizeof(single)*2);
+                S_FD:
+                  getopstr:='#0x'+hexstr(BestRealRec(o.val_real).Data,sizeof(bestreal)*2);
+              else
+                internalerror(2021020801);
+              end;
             end;
           else internalerror(200405021);
         end;
@@ -337,7 +341,7 @@ interface
                         sep:=':'
                       else
                         sep:=',';
-                      s:=s+sep+getopstr(taicpu(hp).oper[i]^);
+                      s:=s+sep+getopstr(taicpu(hp).opsize,taicpu(hp).oper[i]^);
                     end;
                 end;
            end;

+ 11 - 9
compiler/m68k/cgcpu.pas

@@ -1068,15 +1068,17 @@ unit cgcpu;
                     list.concat(taicpu.op_reg_reg(A_FMOVE, tcgsize2opsize[tosize], reg1, hreg));
                     list.concat(taicpu.op_reg_reg(A_FMOVE, tcgsize2opsize[tosize], hreg, reg2));
                   end;
+              OS_F64:
+                  begin
+                    //list.concat(tai_comment.create(strpnew('a_loadfpu_reg_reg rounding via stack')));
+                    reference_reset_base(href, NR_STACK_POINTER_REG, 0, ctempposinvalid, 0, []);
+                    href.direction:=dir_dec;
+                    list.concat(taicpu.op_reg_ref(A_FMOVE, tcgsize2opsize[tosize], reg1, href));
+                    href.direction:=dir_inc;
+                    list.concat(taicpu.op_ref_reg(A_FMOVE, tcgsize2opsize[tosize], href, reg2));
+                  end;
             else
-              begin
-                //list.concat(tai_comment.create(strpnew('a_loadfpu_reg_reg rounding via stack')));
-                reference_reset_base(href, NR_STACK_POINTER_REG, 0, ctempposinvalid, 0, []);
-                href.direction:=dir_dec;
-                list.concat(taicpu.op_reg_ref(A_FMOVE, tcgsize2opsize[tosize], reg1, href));
-                href.direction:=dir_inc;
-                list.concat(taicpu.op_ref_reg(A_FMOVE, tcgsize2opsize[tosize], href, reg2));
-              end;
+              internalerror(2021020802);
             end;
           end
         else
@@ -1098,7 +1100,7 @@ unit cgcpu;
         fixref(list,href,current_settings.fputype = fpu_coldfire);
         list.concat(taicpu.op_ref_reg(A_FMOVE,opsize,href,reg));
         if fromsize > tosize then
-          a_load_reg_reg(list,fromsize,tosize,reg,reg);
+          a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg);
       end;
 
     procedure tcg68k.a_loadfpu_reg_ref(list: TAsmList; fromsize,tosize: tcgsize; reg: tregister; const ref: treference);

+ 1 - 1
compiler/m68k/n68kadd.pas

@@ -201,7 +201,7 @@ implementation
             hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
 
             location.register := cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
-            cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmlist,OS_NO,OS_NO,left.location.register,location.register);
+            cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmlist,left.location.size,location.size,left.location.register,location.register);
           end;
 
         { emit the actual operation }

+ 3 - 3
compiler/m68k/n68kinl.pas

@@ -253,7 +253,7 @@ implementation
             //current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('second_sqr_real called!: left was cfpuregister!')));
             location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
             location.loc := LOC_FPUREGISTER;
-            cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmlist,OS_NO,OS_NO,left.location.register,location.register);
+            cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmlist,left.location.size,location.size,left.location.register,location.register);
           end;
         current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FMUL,fpuregopsize,left.location.register,location.register));
       end;
@@ -333,7 +333,7 @@ implementation
             begin
               hreg:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
               location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
-              cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmlist,OS_NO,OS_NO,left.location.register,location.register);
+              cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmlist,left.location.size,location.size,left.location.register,location.register);
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FINTRZ,fpuregopsize,left.location.register,hreg));
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSUB,fpuregopsize,hreg,location.register));
             end;
@@ -343,7 +343,7 @@ implementation
               location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
               href:=left.location.reference;
               tcg68k(cg).fixref(current_asmdata.CurrAsmList,href,current_settings.fputype = fpu_coldfire);
-              cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmlist,left.location.size,OS_NO,href,location.register);
+              cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmlist,left.location.size,location.size,href,location.register);
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FINTRZ,fpuregopsize,location.register,hreg));
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FSUB,fpuregopsize,hreg,location.register));
             end;

+ 10 - 5
compiler/m68k/n68kmem.pas

@@ -75,8 +75,11 @@ implementation
       var
         hreg: tregister;
         scaled: boolean;
+        regcgsize: tcgsize;
       begin
         scaled:=false;
+        regcgsize:=def_cgsize(regsize);
+
         //current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('updref: called')));
         if l<>1 then
           begin
@@ -86,8 +89,10 @@ implementation
                ((CPUM68K_HAS_INDEXSCALE8 in cpu_capabilities[current_settings.cputype]) and (l in [2,4,8]))) then
               begin
                 //current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('updref: mul')));
-                hreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_S32);
-                cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_IMUL,def_cgsize(regsize),l,maybe_const_reg,hreg);
+                hreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
+                cg.a_load_reg_reg(current_asmdata.CurrAsmList,regcgsize,OS_ADDR,maybe_const_reg,hreg);
+                cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_IMUL,OS_ADDR,l,hreg);
+                regcgsize:=OS_ADDR;
                 maybe_const_reg:=hreg;
               end
             else
@@ -104,7 +109,7 @@ implementation
               begin
                 //current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('updref: copytoa')));
                 hreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
-                cg.a_load_reg_reg(current_asmdata.CurrAsmList,def_cgsize(regsize),OS_ADDR,maybe_const_reg,hreg);
+                cg.a_load_reg_reg(current_asmdata.CurrAsmList,regcgsize,OS_ADDR,maybe_const_reg,hreg);
                 maybe_const_reg:=hreg;
               end;
             location.reference.base:=maybe_const_reg;
@@ -118,13 +123,13 @@ implementation
                 cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,location.reference,hreg);
                 reference_reset_base(location.reference,hreg,0,location.reference.temppos,location.reference.alignment,location.reference.volatility);
               end;
-            if def_cgsize(regsize) in [OS_8,OS_16] then
+            if regcgsize in [OS_8,OS_16] then
               begin
                 { index registers are always sign extended on m68k, so we have to zero extend by hand,
                   if the index variable is unsigned, and its width is less than the whole register }
                 //current_asmdata.CurrAsmList.concat(tai_comment.create(strpnew('updref: index zero extend')));
                 hreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_ADDR);
-                cg.a_load_reg_reg(current_asmdata.CurrAsmList,def_cgsize(regsize),OS_ADDR,maybe_const_reg,hreg);
+                cg.a_load_reg_reg(current_asmdata.CurrAsmList,regcgsize,OS_ADDR,maybe_const_reg,hreg);
                 maybe_const_reg:=hreg;
               end;
             { insert new index register }

+ 10 - 3
compiler/msg/errore.msg

@@ -2079,6 +2079,9 @@ type_e_generic_const_type_not_allowed=04128_E_Type not allowed for generic const
 type_e_cant_read_write_type_in_iso_mode=04129_E_Can't read or write variables of this type in iso mode
 % You are trying to \var{read} or \var{write} a variable from or to a
 % file of type text, which doesn't support that variable's type in the selected language mode (iso mode).
+type_w_array_size_does_not_match_size_of_constant_string=04130_W_The length of the constant string (length is $1) must be equal to the number of array elements ($2 elements)
+% ISO Pascal requires that string constants have the same length as the array to which them they are assigned.
+%
 % \end{description}
 #
 # Symtable
@@ -2579,7 +2582,7 @@ cg_w_interrupt_does_not_save_registers=06062_W_The target CPU does not support p
 #
 # Assembler reader
 #
-# 07145 is the last used one
+# 07146 is the last used one
 #
 asmr_d_start_reading=07000_DL_Starting $1 styled assembler parsing
 % This informs you that an assembler block is being parsed
@@ -2921,7 +2924,9 @@ asmr_w_segment_override_ignored_in_64bit_mode=07141_W_Segment base $1 will be ge
 asmr_e_mismatch_broadcasting_elements=07142_E_Mismatch broadcasting elements (expected: {$1} found: {$2})
 asmr_e_invalid_arrangement=07143_E_Invalid arrangement specifier "$1"
 asmr_e_a64_invalid_regset=07144_E_Registers in a register set must be consecutive.
-asmr_e_not_supported_combination_attsuffix_memrefsize_type=07145_E_Not supported combination opcode: $1 - att-suffix-type {$2} and memrefsize-type {$3}
+asmr_e_unknown_field=07145_E_Unknown field identifier
+% The internal assembler read cannot find the passed field identifier.
+asmr_e_not_supported_combination_attsuffix_memrefsize_type=07146_E_Not supported combination opcode: $1 - att-suffix-type {$2} and memrefsize-type {$3}
 #
 # Assembler/binary writers
 #
@@ -3422,7 +3427,7 @@ unit_u_ppu_llvm_mismatch=10067_U_Skipping unit, PPU and compiler have to be both
 #
 #  Options
 #
-# 11062 is the last used one
+# 11063 is the last used one
 #
 option_usage=11000_O_$1 [options] <inputfile> [options]
 # BeginOfTeX
@@ -3579,6 +3584,8 @@ option_features_only_for_system_unit=11060_E_Feature switches are only supported
 % system unit through the ppu of the system unit.
 option_debug_info_requires_external_linker=11061_N_The selected debug format is not supported by the internal linker, switching to external linking
 option_valgrind_heaptrc_mismatch=11062_E_You can not use both options ($1) ($2) at same time.
+option_unsupported_fpu=11063_F_The selected FPU type "$1" is not supported by the selected instruction set "$2"
+% Not all instruction sets support all FPU types. For example on ARM, Thumb(-1) supports no FPU/VFP instruction set
 %\end{description}
 # EndOfTeX
 

+ 7 - 4
compiler/msgidx.inc

@@ -592,6 +592,7 @@ const
   type_e_forward_interface_type_does_not_match=04127;
   type_e_generic_const_type_not_allowed=04128;
   type_e_cant_read_write_type_in_iso_mode=04129;
+  type_w_array_size_does_not_match_size_of_constant_string=04130;
   sym_e_id_not_found=05000;
   sym_f_internal_error_in_symtablestack=05001;
   sym_e_duplicate_id=05002;
@@ -857,7 +858,8 @@ const
   asmr_e_mismatch_broadcasting_elements=07142;
   asmr_e_invalid_arrangement=07143;
   asmr_e_a64_invalid_regset=07144;
-  asmr_e_not_supported_combination_attsuffix_memrefsize_type=07145;
+  asmr_e_unknown_field=07145;
+  asmr_e_not_supported_combination_attsuffix_memrefsize_type=07146;
   asmw_f_too_many_asm_files=08000;
   asmw_f_assembler_output_not_supported=08001;
   asmw_f_comp_not_supported=08002;
@@ -1084,6 +1086,7 @@ const
   option_features_only_for_system_unit=11060;
   option_debug_info_requires_external_linker=11061;
   option_valgrind_heaptrc_mismatch=11062;
+  option_unsupported_fpu=11063;
   wpo_cant_find_file=12000;
   wpo_begin_processing=12001;
   wpo_end_processing=12002;
@@ -1137,9 +1140,9 @@ const
   option_info=11024;
   option_help_pages=11025;
 
-  MsgTxtSize = 87070;
+  MsgTxtSize = 87309;
 
   MsgIdxMax : array[1..20] of longint=(
-    28,107,361,130,99,63,146,36,223,68,
-    63,20,30,1,1,1,1,1,1,1
+    28,107,361,131,99,63,147,36,223,68,
+    64,20,30,1,1,1,1,1,1,1
   );

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 302 - 298
compiler/msgtxt.inc


+ 10 - 0
compiler/ncal.pas

@@ -1367,6 +1367,16 @@ implementation
                  if parasym.varspez in [vs_var,vs_out,vs_constref] then
                    set_unique(left);
 
+                 if (parasym.varspez=vs_const) and (parasym.vardef.typ=formaldef) then
+                   begin
+                     { compilerprocs never capture the address of their
+                       parameters }
+                     if not(po_compilerproc in aktcallnode.procdefinition.procoptions) then
+                       make_not_regable(left,[ra_addr_regable,ra_addr_taken])
+                     else
+                       make_not_regable(left,[ra_addr_regable])
+                   end
+                 else
                   case parasym.varspez of
                     vs_out :
                       begin

+ 3 - 0
compiler/ncnv.pas

@@ -1190,6 +1190,9 @@ implementation
         if (left.nodetype = stringconstn) and
            (tstringconstnode(left).cst_type=cst_conststring) then
            begin
+             if (m_iso in current_settings.modeswitches) and (arrsize<>tstringconstnode(left).len) and
+                is_char(tarraydef(resultdef).elementdef) then
+               Message2(type_w_array_size_does_not_match_size_of_constant_string,tostr(tstringconstnode(left).len),tostr(arrsize));
              { if the array of char is large enough we can use the string
                constant directly. This is handled in ncgcnv }
              if (arrsize>=tstringconstnode(left).len) and

+ 3 - 1
compiler/options.pas

@@ -1117,7 +1117,7 @@ begin
          (
           ((length(opt)>1) and (opt[2] in ['i','d','v','T','u','n','X','l','U'])) or
           ((length(opt)>3) and (opt[2]='F') and (opt[3]='e')) or
-          ((length(opt)>3) and (opt[2]='C') and (opt[3]='p')) or
+          ((length(opt)>3) and (opt[2]='C') and (opt[3] in ['a','f','p'])) or
           ((length(opt)>3) and (opt[2]='W') and (opt[3] in ['m','p']))
          )
         ) then
@@ -4485,6 +4485,8 @@ begin
       def_system_macro('CPUTHUMB');
       if not option.FPUSetExplicitly then
         init_settings.fputype:=fpu_soft;
+      if not(init_settings.fputype in [fpu_none,fpu_soft,fpu_libgcc]) then
+        Message2(option_unsupported_fpu,fputypestr[init_settings.fputype],'Thumb');
 {$if defined(FPC_ARMEL) or defined(FPC_ARMHF)}
       target_info.llvmdatalayout:='e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:32-n32-S64';
 {$else FPC_ARMAL or FPC_ARMHF}

+ 4 - 3
compiler/parser.pas

@@ -354,6 +354,10 @@ implementation
          exceptblockcounter:=0;
          current_settings.maxfpuregisters:=-1;
          current_settings.pmessage:=nil;
+
+         { Load current state from the init values }
+         current_settings:=init_settings;
+
        { reset the unit or create a new program }
          { a unit compiled at command line must be inside the loaded_unit list }
          if (compile_level=1) then
@@ -369,9 +373,6 @@ implementation
                 (current_module.state in [ms_compile,ms_second_compile])) then
            internalerror(200212281);
 
-         { Load current state from the init values }
-         current_settings:=init_settings;
-
          { load current asmdata from current_module }
          current_asmdata:=TAsmData(current_module.asmdata);
 

+ 1 - 0
compiler/rautils.pas

@@ -1645,6 +1645,7 @@ Begin
      sym:=search_struct_member(tabstractrecorddef(st.defowner),base);
      if not assigned(sym) then
       begin
+        Message(asmr_e_unknown_field);
         GetRecordOffsetSize:=false;
         exit;
       end;

+ 0 - 1
compiler/sparc/cpuelf.pas

@@ -136,6 +136,5 @@ implementation
 initialization
   RegisterAssembler(as_sparc_elf32_info,TElfAssembler);
   ElfTarget:=elf_target_sparc;
-
 end.
 

+ 1 - 1
compiler/systems/i_linux.pas

@@ -679,7 +679,7 @@ unit i_linux;
             name         : 'Linux for ARMEL';
             shortname    : 'Linux';
             flags        : [tf_needs_symbol_size,tf_needs_symbol_type,tf_files_case_sensitive,
-                            tf_requires_proper_alignment,tf_safecall_exceptions,
+                            tf_needs_dwarf_cfi,tf_requires_proper_alignment,tf_safecall_exceptions,
 {$ifdef tls_threadvars}
                             tf_section_threadvars,
 {$endif tls_threadvars}

+ 6 - 0
compiler/systems/t_embed.pas

@@ -1074,6 +1074,12 @@ begin
       Add('  .debug_str      0 : { *(.debug_str) }');
       Add('  .debug_loc      0 : { *(.debug_loc) }');
       Add('  .debug_macinfo  0 : { *(.debug_macinfo) }');
+      Add('  /* DWARF 3 */');
+      Add('  .debug_pubtypes 0 : { *(.debug_pubtypes) }');
+      Add('  .debug_ranges   0 : { *(.debug_ranges) }');
+      Add('  /* DWARF Extension.  */');
+      Add('  .debug_macro    0 : { *(.debug_macro) }');
+
       Add('}');
     end;
 {$endif AVR}

+ 1 - 2
packages/cocoaint/src/foundation/NSProcessInfo.inc

@@ -82,8 +82,7 @@ const
 {$ifdef CLASSES}
 
 type
-  NSProcessInfo_NSObject = objcclass external (NSObject)
-  public
+  NSProcessInfoActivity = objccategory external (NSProcessInfo)
     function beginActivityWithOptions_reason (options: NSActivityOptions; reason: NSString): NSObjectProtocol; message 'beginActivityWithOptions:reason:'; { available in 10_9, 7_0 }
     procedure endActivity (activity: NSObjectProtocol); message 'endActivity:'; { available in 10_9, 7_0 }
     procedure performActivityWithOptions_reason_usingBlock (options: NSActivityOptions; reason: NSString; block: OpaqueCBlock); message 'performActivityWithOptions:reason:usingBlock:'; { available in 10_9, 7_0 }

+ 19 - 0
packages/fcl-db/fpmake.pp

@@ -473,6 +473,14 @@ begin
           AddUnit('fpddsqldb');
           AddUnit('mysql57conn');
         end;
+    T:=P.Targets.AddUnit('fpddmysql80.pp', DatadictOSes);
+      with T.Dependencies do
+        begin
+          AddUnit('sqldb');
+          AddUnit('fpdatadict');
+          AddUnit('fpddsqldb');
+          AddUnit('mysql80conn');
+        end;
     T:=P.Targets.AddUnit('fpddodbc.pp', DatadictOSes);
       with T.Dependencies do
         begin
@@ -716,6 +724,17 @@ begin
           AddUnit('dbconst');
         end;
 
+    T:=P.Targets.AddUnit('mysql80conn.pas', SqldbConnectionOSes);
+    T.ResourceStrings:=true;
+      with T.Dependencies do
+        begin
+          AddInclude('mysqlconn.inc');
+          AddUnit('bufdataset');
+          AddUnit('sqldb');
+          AddUnit('db');
+          AddUnit('dbconst');
+        end;
+
     T:=P.Targets.AddUnit('odbcconn.pas', SqldbConnectionOSes);
       with T.Dependencies do
         begin

+ 17 - 7
packages/fcl-db/src/base/bufdataset.pas

@@ -1465,6 +1465,7 @@ var
   i,r  : integer;
   iGetResult : TGetResult;
   pc : TRecordBuffer;
+  CurBufIndex: TBufDatasetIndex;
 
 begin
   FOpen:=False;
@@ -1514,10 +1515,17 @@ begin
   if FAutoIncValue>-1 then FAutoIncValue:=1;
   if assigned(FParser) then FreeAndNil(FParser);
   For I:=FIndexes.Count-1 downto 0 do
-    if (BufIndexDefs[i].IndexType in [itDefault,itCustom]) or (BufIndexDefs[i].DiscardOnClose) then
-       BufIndexDefs[i].Free
+    begin
+    CurBufIndex:=BufIndexDefs[i];
+    if (CurBufIndex.IndexType in [itDefault,itCustom]) or (CurBufIndex.DiscardOnClose) then
+      begin
+      if FCurrentIndexDef=CurBufIndex then
+        FCurrentIndexDef:=nil;
+      CurBufIndex.Free;
+      end
     else
-       FreeAndNil(BufIndexDefs[i].FBufferIndex);
+      FreeAndNil(CurBufIndex.FBufferIndex);
+    end;
 end;
 
 procedure TCustomBufDataset.InternalFirst;
@@ -3149,16 +3157,18 @@ function TCustomBufDataset.GetIndexFieldNames: String;
 var
   i, p: integer;
   s: string;
+  IndexBuf: TBufIndex;
 
 begin
   Result := FIndexFieldNames;
-  if (CurrentIndexBuf=Nil) then
+  IndexBuf:=CurrentIndexBuf;
+  if (IndexBuf=Nil) then
     Exit;
   Result:='';
-  for i := 1 to WordCount(CurrentIndexBuf.FieldsName, [Limiter]) do
+  for i := 1 to WordCount(IndexBuf.FieldsName, [Limiter]) do
   begin
-    s := ExtractDelimited(i, CurrentIndexBuf.FieldsName, [Limiter]);
-    p := Pos(s, CurrentIndexBuf.DescFields);
+    s := ExtractDelimited(i, IndexBuf.FieldsName, [Limiter]);
+    p := Pos(s, IndexBuf.DescFields);
     if p>0 then
       s := s + Desc;
     Result := Result + Limiter + s;

+ 74 - 0
packages/fcl-db/src/datadict/fpddmysql80.pp

@@ -0,0 +1,74 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2007 by Michael Van Canneyt, member of the
+    Free Pascal development team
+
+    MySQL 8.0 Data Dictionary Engine Implementation.
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+unit fpddmysql80;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, sqldb, fpdatadict, fpddsqldb;
+  
+Type
+  { TSQLDBMySql80DDEngine }
+
+  TSQLDBMySql80DDEngine = Class(TSQLDBDDEngine)
+  Protected
+    Function CreateConnection(AConnectString  : String) : TSQLConnection; override;
+  Public
+    Class function Description : string; override;
+    Class function DBType : String; override;
+  end;
+
+Procedure RegisterMySQL80DDEngine;
+Procedure UnRegisterMySQL80DDEngine;
+
+implementation
+
+uses mysql80conn;
+
+Procedure RegisterMySQL80DDEngine;
+
+begin
+  RegisterDictionaryEngine(TSQLDBMySQL80DDEngine);
+end;
+
+Procedure UnRegisterMySQL80DDEngine;
+
+begin
+  UnRegisterDictionaryEngine(TSQLDBMySQL80DDEngine);
+end;
+
+{ TSQLDBMySql80DDEngine }
+
+function TSQLDBMySql80DDEngine.CreateConnection(AConnectString: String
+  ): TSQLConnection;
+begin
+  Result:=mysql80conn.TMySQL80Connection.Create(Self);
+end;
+
+class function TSQLDBMySql80DDEngine.Description: string;
+begin
+  Result:='Mysql 8.0 connection using SQLDB';
+end;
+
+class function TSQLDBMySql80DDEngine.DBType: String;
+begin
+  Result:='MySQL 8.0';
+end;
+
+end.
+

+ 208 - 208
packages/fcl-db/src/sqldb/mysql/Makefile

@@ -350,628 +350,628 @@ endif
 override PACKAGE_NAME=fcl-db
 PACKAGEDIR_MAIN:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-db/Makefile.fpc,$(PACKAGESDIR))))))
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-android)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-aros)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-macosclassic)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-sinclairql)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-macosclassic)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-aix)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-haiku)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-android)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-aros)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-netbsd)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-android)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-aros)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-freertos)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-ios)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc64-aix)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mips-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mipsel-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mipsel-android)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mips64el-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),jvm-java)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),jvm-android)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i8086-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i8086-msdos)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i8086-win16)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-win64)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-android)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-ios)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),wasm-wasm)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc64-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),riscv32-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),riscv32-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),riscv64-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),riscv64-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),xtensa-linux)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),xtensa-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),xtensa-freertos)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),z80-embedded)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),z80-zxspectrum)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),z80-msxdos)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),z80-amstradcpc)
-override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_UNITS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-haiku)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-nativent)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-iphonesim)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-android)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i386-aros)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-macosclassic)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),m68k-sinclairql)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-macosclassic)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-wii)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc-aix)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-haiku)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-netbsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-solaris)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-openbsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-iphonesim)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-android)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-aros)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),x86_64-dragonfly)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-netbsd)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-android)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-aros)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-freertos)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),arm-ios)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),powerpc64-aix)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),avr-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),armeb-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),armeb-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mips-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mipsel-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mipsel-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mipsel-android)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),mips64el-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),jvm-java)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),jvm-android)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i8086-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i8086-msdos)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),i8086-win16)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-darwin)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-win64)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-android)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),aarch64-ios)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),wasm-wasm)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),sparc64-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),riscv32-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),riscv32-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),riscv64-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),riscv64-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),xtensa-linux)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),xtensa-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),xtensa-freertos)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),z80-embedded)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),z80-zxspectrum)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),z80-msxdos)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 ifeq ($(FULL_TARGET),z80-amstradcpc)
-override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+override TARGET_RSTS+=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 endif
 override INSTALL_FPCPACKAGE=y
 ifeq ($(FULL_TARGET),i386-linux)

+ 2 - 2
packages/fcl-db/src/sqldb/mysql/Makefile.fpc

@@ -6,8 +6,8 @@
 main=fcl-db
 
 [target]
-units=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
-rsts=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn
+units=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
+rsts=mysql40conn mysql41conn mysql50conn mysql51conn mysql55conn mysql56conn mysql57conn mysql80conn
 
 [require]
 packages=fcl-xml mysql

+ 12 - 0
packages/fcl-db/src/sqldb/mysql/mysql80conn.pas

@@ -0,0 +1,12 @@
+{
+  Contains the TMysqlConnection for MySQL 8.0
+}
+
+unit mysql80conn;
+
+{$DEFINE MYSQL80_UP}
+{$DEFINE MYSQL80}
+
+{$i mysqlconn.inc}
+
+end.

+ 91 - 16
packages/fcl-db/src/sqldb/mysql/mysqlconn.inc

@@ -1,3 +1,6 @@
+{$IFDEF MYSQL80_UP}
+  {$DEFINE MYSQL57_UP}
+{$ENDIF}
 {$IFDEF MYSQL57_UP}
   {$DEFINE MYSQL56_UP}
 {$ENDIF}
@@ -17,6 +20,9 @@ interface
 
 uses
   Classes, SysUtils,bufdataset,sqldb,db,ctypes,fmtbcd,
+{$IFDEF mysql80}
+  mysql80dyn;
+{$ELSE}
 {$IFDEF mysql57}
   mysql57dyn;
 {$ELSE}
@@ -42,9 +48,13 @@ uses
 {$endif}
 {$ENDIF}
 {$ENDIF}
+{$ENDIF}
 
 Const
   MySQLVersion =
+{$IFDEF mysql80}
+    '8.0';
+{$ELSE}
 {$IFDEF mysql57}
     '5.7';
 {$ELSE}
@@ -69,6 +79,7 @@ Const
 {$endif}
 {$endif}
 {$ENDIF}
+{$ENDIF}
 {$ENDIF}
 
   MariaDBVersion =
@@ -96,6 +107,7 @@ Type
     FPreparedStatement : String;
     // Statement with param placeholders replaced with actual values.
     FActualStatement : String;
+    FStatement : String;
     Row : MYSQL_ROW;
     Lengths : pculong;                  { Lengths of the columns of the current row }
     RowsAffected : QWord;
@@ -209,6 +221,12 @@ Type
   end;
 
 
+  {$IFDEF mysql80}
+    TMySQL80Connection = Class(TConnectionName);
+    TMySQL80ConnectionDef = Class(TMySQLConnectionDef);
+    TMySQL80Transaction = Class(TTransactionName);
+    TMySQL80Cursor = Class(TCursorName);
+  {$ELSE}
   {$IFDEF mysql57}
     TMySQL57Connection = Class(TConnectionName);
     TMySQL57ConnectionDef = Class(TMySQLConnectionDef);
@@ -255,6 +273,7 @@ Type
   {$ENDIF}
   {$ENDIF}
   {$ENDIF}
+  {$ENDIF}
 
 implementation
 
@@ -264,15 +283,57 @@ uses
   DateUtils;
 
 const
-  Mysql_Option_Names : array[mysql_option] of string = ('MYSQL_OPT_CONNECT_TIMEOUT','MYSQL_OPT_COMPRESS',
-     'MYSQL_OPT_NAMED_PIPE','MYSQL_INIT_COMMAND',
-     'MYSQL_READ_DEFAULT_FILE','MYSQL_READ_DEFAULT_GROUP',
-     'MYSQL_SET_CHARSET_DIR','MYSQL_SET_CHARSET_NAME',
-     'MYSQL_OPT_LOCAL_INFILE','MYSQL_OPT_PROTOCOL',
-     'MYSQL_SHARED_MEMORY_BASE_NAME','MYSQL_OPT_READ_TIMEOUT',
-     'MYSQL_OPT_WRITE_TIMEOUT','MYSQL_OPT_USE_RESULT',
-     'MYSQL_OPT_USE_REMOTE_CONNECTION','MYSQL_OPT_USE_EMBEDDED_CONNECTION',
-     'MYSQL_OPT_GUESS_CONNECTION','MYSQL_SET_CLIENT_IP',
+  Mysql_Option_Names : array[mysql_option] of string = (
+     'MYSQL_OPT_CONNECT_TIMEOUT',
+     'MYSQL_OPT_COMPRESS',
+     'MYSQL_OPT_NAMED_PIPE',
+     'MYSQL_INIT_COMMAND',
+     'MYSQL_READ_DEFAULT_FILE',
+     'MYSQL_READ_DEFAULT_GROUP',
+     'MYSQL_SET_CHARSET_DIR',
+     'MYSQL_SET_CHARSET_NAME',
+     'MYSQL_OPT_LOCAL_INFILE',
+     'MYSQL_OPT_PROTOCOL',
+     'MYSQL_SHARED_MEMORY_BASE_NAME',
+     'MYSQL_OPT_READ_TIMEOUT',
+     'MYSQL_OPT_WRITE_TIMEOUT',
+     'MYSQL_OPT_USE_RESULT'
+     {$IFDEF MYSQL80}
+     ,'MYSQL_REPORT_DATA_TRUNCATION',
+     'MYSQL_OPT_RECONNECT',
+     'MYSQL_PLUGIN_DIR',
+     'MYSQL_DEFAULT_AUTH',
+     'MYSQL_OPT_BIND',
+     'MYSQL_OPT_SSL_KEY',
+     'MYSQL_OPT_SSL_CERT',
+     'MYSQL_OPT_SSL_CA',
+     'MYSQL_OPT_SSL_CAPATH',
+     'MYSQL_OPT_SSL_CIPHER',
+     'MYSQL_OPT_SSL_CRL',
+     'MYSQL_OPT_SSL_CRLPATH',
+     'MYSQL_OPT_CONNECT_ATTR_RESET',
+     'MYSQL_OPT_CONNECT_ATTR_ADD',
+     'MYSQL_OPT_CONNECT_ATTR_DELETE',
+     'MYSQL_SERVER_PUBLIC_KEY',
+     'MYSQL_ENABLE_CLEARTEXT_PLUGIN',
+     'MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS',
+     'MYSQL_OPT_MAX_ALLOWED_PACKET',
+     'MYSQL_OPT_NET_BUFFER_LENGTH',
+     'MYSQL_OPT_TLS_VERSION',
+     'MYSQL_OPT_SSL_MODE',
+     'MYSQL_OPT_GET_SERVER_PUBLIC_KEY',
+     'MYSQL_OPT_RETRY_COUNT',
+     'MYSQL_OPT_OPTIONAL_RESULTSET_METADATA',
+     'MYSQL_OPT_SSL_FIPS_MODE',
+     'MYSQL_OPT_TLS_CIPHERSUITES',
+     'MYSQL_OPT_COMPRESSION_ALGORITHMS',
+     'MYSQL_OPT_ZSTD_COMPRESSION_LEVEL',
+     'MYSQL_OPT_LOAD_DATA_LOCAL_DIR'
+     {$ELSE}
+     ,'MYSQL_OPT_USE_REMOTE_CONNECTION',
+     'MYSQL_OPT_USE_EMBEDDED_CONNECTION',
+     'MYSQL_OPT_GUESS_CONNECTION',
+     'MYSQL_SET_CLIENT_IP',
      'MYSQL_SECURE_AUTH'
 {$IFDEF MYSQL50_UP}
      ,'MYSQL_REPORT_DATA_TRUNCATION', 'MYSQL_OPT_RECONNECT'
@@ -293,6 +354,7 @@ const
 {$ENDIF}
 {$ENDIF}
 {$ENDIF}
+{$ENDIF}
 {$ENDIF}
      );
 
@@ -300,9 +362,9 @@ Resourcestring
   SErrServerConnectFailed = 'Server connect failed.';
   SErrSetCharsetFailed = 'Failed to set connection character set: %s';
   SErrDatabaseSelectFailed = 'Failed to select database: %s';
-  SErrDatabaseCreate = 'Failed to create database: %s';
-  SErrDatabaseDrop = 'Failed to drop database: %s';
-  SErrNoData = 'No data for record';
+  //SErrDatabaseCreate = 'Failed to create database: %s';
+  //SErrDatabaseDrop = 'Failed to drop database: %s';
+  //SErrNoData = 'No data for record';
   SErrExecuting = 'Error executing query: %s';
   SErrFetchingdata = 'Error fetching row data: %s';
   SErrGettingResult = 'Error getting result set: %s';
@@ -547,6 +609,9 @@ end;
 
 Function TConnectionName.AllocateCursorHandle: TSQLCursor;
 begin
+  {$IFDEF mysql80}
+    Result:=TMySQL80Cursor.Create;
+  {$ELSE}
   {$IFDEF mysql57}
     Result:=TMySQL57Cursor.Create;
   {$ELSE}
@@ -572,6 +637,7 @@ begin
   {$EndIf}
   {$ENDIF}
   {$ENDIF}
+  {$ENDIF}
 end;
 
 Procedure TConnectionName.DeAllocateCursorHandle(var cursor : TSQLCursor);
@@ -597,7 +663,7 @@ begin
     if assigned(AParams) and (AParams.count > 0) then
       FPreparedStatement := AParams.ParseSQL(FPreparedStatement,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psSimulated,paramBinding,ParamReplaceString);
     FPrepared:=True;
-    end
+    end;
 end;
 
 procedure TConnectionName.UnPrepareStatement(cursor: TSQLCursor);
@@ -743,8 +809,6 @@ begin
       begin
       if AField^.flags and AUTO_INCREMENT_FLAG <> 0 then
         NewType := ftAutoInc
-      else if AField^.flags and UNSIGNED_FLAG <> 0 then
-        NewType := ftLongWord
       else
         NewType := ftInteger;
       end;
@@ -1417,6 +1481,9 @@ end;
 
 class function TMySQLConnectionDef.ConnectionClass: TSQLConnectionClass;
 begin
+  {$IFDEF mysql80}
+    Result:=TMySQL80Connection;
+  {$ELSE}
   {$IFDEF mysql57}
     Result:=TMySQL57Connection;
   {$ELSE}
@@ -1442,6 +1509,7 @@ begin
   {$endif}
   {$ENDIF}
   {$ENDIF}
+  {$ENDIF}
 end;
 
 class function TMySQLConnectionDef.Description: String;
@@ -1469,6 +1537,12 @@ begin
   Result:=MysqlLoadedLibrary;
 end;
 
+{$IFDEF mysql80}
+  initialization
+    RegisterConnection(TMySQL80ConnectionDef);
+  finalization
+    UnRegisterConnection(TMySQL80ConnectionDef);
+{$ELSE}
 {$IFDEF mysql57}
   initialization
     RegisterConnection(TMySQL57ConnectionDef);
@@ -1512,7 +1586,8 @@ end;
       {$EndIf}
     {$EndIf}
   {$ENDIF}
-{$endif}
+{$ENDIF}
+{$ENDIF}
 {$ENDIF}
 {$ENDIF}
 

+ 1 - 1
packages/fcl-db/src/sqldb/sqldb.pp

@@ -3137,7 +3137,7 @@ begin
       UpdateServerIndexDefs;
 
     FStatement.Execute;
-    if not Cursor.FSelectable then
+    if (Cursor=nil) or (not Cursor.FSelectable) then
       DatabaseError(SErrNoSelectStatement,Self);
 
     // InternalInitFieldDef is only called after a prepare. i.e. not twice if

+ 6 - 5
packages/fcl-db/tests/sqldbtoolsunit.pas

@@ -7,7 +7,7 @@ interface
 uses
   Classes, SysUtils, toolsunit
   ,db, sqldb
-  ,mysql40conn, mysql41conn, mysql50conn, mysql51conn, mysql55conn, mysql56conn, mysql57conn
+  ,mysql40conn, mysql41conn, mysql50conn, mysql51conn, mysql55conn, mysql56conn, mysql57conn, mysql80conn
   ,ibconnection
   ,pqconnection
   ,odbcconn
@@ -20,13 +20,13 @@ uses
   ;
 
 type
-  TSQLConnType = (mysql40,mysql41,mysql50,mysql51,mysql55,mysql56,mysql57,postgresql,interbase,odbc,oracle,sqlite3,mssql,sybase);
+  TSQLConnType = (mysql40,mysql41,mysql50,mysql51,mysql55,mysql56,mysql57,mysql80,postgresql,interbase,odbc,oracle,sqlite3,mssql,sybase);
   TSQLServerType = (ssFirebird, ssInterbase, ssMSSQL, ssMySQL, ssOracle, ssPostgreSQL, ssSQLite, ssSybase, ssUnknown);
 
 const
-  MySQLConnTypes = [mysql40,mysql41,mysql50,mysql51,mysql55,mysql56,mysql57];
+  MySQLConnTypes = [mysql40,mysql41,mysql50,mysql51,mysql55,mysql56,mysql57,mysql80];
   SQLConnTypesNames : Array [TSQLConnType] of String[19] =
-        ('MYSQL40','MYSQL41','MYSQL50','MYSQL51','MYSQL55','MYSQL56','MYSQL57','POSTGRESQL','INTERBASE','ODBC','ORACLE','SQLITE3','MSSQL','SYBASE');
+        ('MYSQL40','MYSQL41','MYSQL50','MYSQL51','MYSQL55','MYSQL56','MYSQL57','MYSQL80','POSTGRESQL','INTERBASE','ODBC','ORACLE','SQLITE3','MSSQL','SYBASE');
              
   STestNotApplicable = 'This test does not apply to this sqldb connection type';
 
@@ -150,7 +150,7 @@ const
 
   // fall back mapping (e.g. in case GetConnectionInfo(citServerType) is not implemented)
   SQLConnTypeToServerTypeMap : array[TSQLConnType] of TSQLServerType =
-    (ssMySQL,ssMySQL,ssMySQL,ssMySQL,ssMySQL,ssMySQL,ssMySQL,ssPostgreSQL,ssFirebird,ssUnknown,ssOracle,ssSQLite,ssMSSQL,ssSybase);
+    (ssMySQL,ssMySQL,ssMySQL,ssMySQL,ssMySQL,ssMySQL,ssMySQL,ssMysql,ssPostgreSQL,ssFirebird,ssUnknown,ssOracle,ssSQLite,ssMSSQL,ssSybase);
 
 
 function IdentifierCase(const s: string): string;
@@ -183,6 +183,7 @@ begin
     MYSQL55:    Fconnection := TMySQL55Connection.Create(nil);
     MYSQL56:    Fconnection := TMySQL56Connection.Create(nil);
     MYSQL57:    Fconnection := TMySQL57Connection.Create(nil);
+    MYSQL80:    Fconnection := TMySQL80Connection.Create(nil);
     SQLITE3:    Fconnection := TSQLite3Connection.Create(nil);
     POSTGRESQL: Fconnection := TPQConnection.Create(nil);
     INTERBASE : Fconnection := TIBConnection.Create(nil);

+ 1 - 0
packages/fcl-passrc/src/pasuseanalyzer.pas

@@ -2847,6 +2847,7 @@ begin
     begin
     // write without read
     if (vmExternal in El.VarModifiers)
+    or (El.ClassType=TPasProperty)
         or ((El.Parent is TPasClassType) and TPasClassType(El.Parent).IsExternal) then
       exit;
     if El.Visibility in [visPrivate,visStrictPrivate] then

+ 21 - 0
packages/fcl-passrc/tests/tcuseanalyzer.pas

@@ -114,6 +114,7 @@ type
     procedure TestM_Hint_InterfaceUnitVariableUsed;
     procedure TestM_Hint_ValueParameterIsAssignedButNeverUsed;
     procedure TestM_Hint_LocalVariableIsAssignedButNeverUsed;
+    procedure TestM_Hint_PropertyIsAssignedButNeverUsed;
     procedure TestM_Hint_LocalXYNotUsed;
     procedure TestM_Hint_PrivateFieldIsNeverUsed;
     procedure TestM_Hint_PrivateFieldIsAssignedButNeverUsed;
@@ -1917,6 +1918,26 @@ begin
   CheckUseAnalyzerUnexpectedHints;
 end;
 
+procedure TTestUseAnalyzer.TestM_Hint_PropertyIsAssignedButNeverUsed;
+begin
+  StartProgram(true);
+  Add([
+  'type',
+  '  TObject = class',
+  '  private',
+  '    FSize: word;',
+  '  public',
+  '    property ReadSize: word read FSize;',
+  '    property WriteSize: word write FSize;',
+  '  end;',
+  'var o: TObject;',
+  'begin',
+  '  o.WriteSize:=o.ReadSize;',
+  '']);
+  AnalyzeProgram;
+  CheckUseAnalyzerUnexpectedHints;
+end;
+
 procedure TTestUseAnalyzer.TestM_Hint_LocalXYNotUsed;
 begin
   StartProgram(true);

+ 56 - 0
packages/fcl-pdf/examples/monospacetext.pp

@@ -0,0 +1,56 @@
+program monospacetext;
+
+{$mode objfpc}{$H+}
+{$codepage UTF8}
+
+uses
+  Classes, SysUtils,
+  fpPDF;
+
+var
+  PDF: TPDFDocument;
+  Font1, Font2, Font3, Font4: integer;
+begin
+  if ParamCount<1 then
+    begin
+    Writeln(stderr,'Usage : monospacetext <fontdir>');
+    Writeln(stderr,'Needed fonts : cour.ttf, arial.ttf, verdanab.ttf consola.ttf');
+    Halt(1);
+    end;
+  PDF := TPDFDocument.Create(nil);
+  PDF.Infos.Producer := '';
+  PDF.Infos.CreationDate := Now;
+  PDF.Options := [poPageOriginAtTop, {poNoEmbeddedFonts,} poSubsetFont, poCompressFonts, poCompressImages];
+  PDF.DefaultOrientation := ppoPortrait;
+  PDF.DefaultPaperType := ptA4;
+  PDF.DefaultUnitOfMeasure := uomMillimeters;
+  PDF.FontDirectory := paramstr(1);
+  PDF.StartDocument;
+  PDF.Sections.AddSection;
+  PDF.Sections[0].AddPage(PDF.Pages.AddPage);;
+
+  //FontIndex := PDF.AddFont('Courier');
+  Font1 := PDF.AddFont('cour.ttf', 'Courier New');
+  Font2 := PDF.AddFont('arial.ttf', 'Arial');
+  Font3 := PDF.AddFont('verdanab.ttf', 'Verdana');
+  Font4 := PDF.AddFont('consola.ttf', 'Consolas');
+  PDF.Pages[0].SetFont(Font1, 10);
+  PDF.Pages[0].WriteText(10,10,'AEIOU-ÁÉÍÓÚ-ČŠŇŽ');
+  PDF.Pages[0].WriteText(10,15,'----------------');
+
+  PDF.Pages[0].SetFont(Font2, 10);
+  PDF.Pages[0].WriteText(10,30,'AEIOU-ÁÉÍÓÚ-ČŠŇŽ');
+  PDF.Pages[0].WriteText(10,35,'----------------');
+
+  PDF.Pages[0].SetFont(Font3, 10);
+  PDF.Pages[0].WriteText(10,40,'AEIOU-ÁÉÍÓÚ-ČŠŇŽ');
+  PDF.Pages[0].WriteText(10,45,'----------------');
+
+  PDF.Pages[0].SetFont(Font4, 10);
+  PDF.Pages[0].WriteText(10,50,'AEIOU-ÁÉÍÓÚ-ČŠŇŽ');
+  PDF.Pages[0].WriteText(10,55,'----------------');
+
+  PDF.SaveToFile('test.pdf');
+  PDF.Free;
+end.
+

+ 18 - 7
packages/fcl-pdf/src/fpparsettf.pp

@@ -822,13 +822,13 @@ begin
   if embed and not Embeddable then
     raise ETTF.Create(rsFontEmbeddingNotAllowed);
   PrepareEncoding(Encoding);
-//  MissingWidth:=ToNatural(Widths[Chars[CharCodes^[32]]].AdvanceWidth);  // Char(32) - Space character
-  FMissingWidth := Widths[Chars[CharCodes^[32]]].AdvanceWidth;  // Char(32) - Space character
+//  MissingWidth:=ToNatural(GetAdvanceWidth(Chars[CharCodes^[32]]));  // Char(32) - Space character
+  FMissingWidth := GetAdvanceWidth(Chars[CharCodes^[32]]);  // Char(32) - Space character
   for I:=0 to 255 do
   begin
     if (CharCodes^[i]>=0) and (CharCodes^[i]<=High(Chars))
-    and (Widths[Chars[CharCodes^[i]]].AdvanceWidth> 0) and (CharNames^[i]<> '.notdef') then
-      CharWidth[I]:= ToNatural(Widths[Chars[CharCodes^[I]]].AdvanceWidth)
+    and (GetAdvanceWidth(Chars[CharCodes^[i]])> 0) and (CharNames^[i]<> '.notdef') then
+      CharWidth[I]:= ToNatural(GetAdvanceWidth(Chars[CharCodes^[I]]))
     else
       CharWidth[I]:= FMissingWidth;
   end;
@@ -930,8 +930,19 @@ begin
 end;
 
 function TTFFileInfo.GetAdvanceWidth(AIndex: word): word;
-begin
-  Result := Widths[AIndex].AdvanceWidth;
+var
+  i: SizeInt;
+begin
+  // There may be more glyphs than elements in the array, in which
+  // case the last entry is to be used.
+  // https://docs.microsoft.com/en-us/typography/opentype/spec/hmtx
+  i := Length(Widths);
+  if AIndex >= i then
+    Dec(i)
+  else
+    i := AIndex;
+
+  Result := Widths[i].AdvanceWidth;
 end;
 
 function TTFFileInfo.ItalicAngle: single;
@@ -972,7 +983,7 @@ function TTFFileInfo.GetMissingWidth: integer;
 begin
   if FMissingWidth = 0 then
   begin
-    FMissingWidth := Widths[Chars[CharCodes^[32]]].AdvanceWidth;  // 32 is in reference to the Space character
+    FMissingWidth := GetAdvanceWidth(Chars[CharCodes^[32]]);  // 32 is in reference to the Space character
   end;
   Result := FMissingWidth;
 end;

+ 8 - 2
packages/fcl-pdf/src/fpttfsubsetter.pp

@@ -940,12 +940,18 @@ end;
 function TFontSubsetter.buildHmtxTable: TStream;
 var
   n: integer;
+  GID: longint;
+  LastGID: longint;
 begin
   Result := TMemoryStream.Create;
+  LastGID := Length(FFontInfo.Widths)-1;
   for n := 0 to FGlyphIDs.Count-1 do
   begin
-    WriteUInt16(Result, FFontInfo.Widths[FGlyphIDs[n].GID].AdvanceWidth);
-    WriteInt16(Result, FFontInfo.Widths[FGlyphIDs[n].GID].LSB);
+    GID := FGlyphIDs[n].GID;
+    if GID > LastGID then
+      GID := LastGID;
+    WriteUInt16(Result, FFontInfo.Widths[GID].AdvanceWidth);
+    WriteInt16(Result, FFontInfo.Widths[GID].LSB);
   end;
 end;
 

+ 5 - 2
packages/fcl-process/src/amicommon/pipes.inc

@@ -27,9 +27,12 @@ end;
 
 
 Function TInputPipeStream.GetNumBytesAvailable: DWord;
-
+var
+  fib: TFileInfoBlock;
 begin
   Result := 0;
+  if Boolean(ExamineFH(BPTR(Handle), @fib)) then
+    Result := fib.fib_size;
 end;
 
 function TInputPipeStream.GetPosition: Int64;
@@ -53,5 +56,5 @@ begin
    FileClose(FHandle);
    if DeleteIt then
      AmigaDos.dosDeleteFile(@(Filename[0]));
- end;  
+ end;
 end;

+ 66 - 11
packages/fcl-process/src/amicommon/process.inc

@@ -65,6 +65,13 @@ end;
 var
   UID: Integer = 0;
 
+{$ifdef MorphOS}
+const
+  BUF_LINE = 0; // flush on \n, etc
+  BUF_FULL = 1; // never flush except when needed
+  BUF_NONE = 2; // no buffering
+{$endif}
+
 Procedure TProcess.Execute;
 var
   I: integer;
@@ -74,6 +81,10 @@ var
   Params: string;
   TempName: string;
   cos: BPTR;
+  {$ifdef MorphOS}
+  inA, inB, OutA, OutB: BPTR;
+  Res: Integer;
+  {$endif}
 begin
   if (ApplicationName = '') and (CommandLine = '') and (Executable = '') then
    raise EProcess.Create (SNoCommandline);
@@ -114,17 +125,61 @@ begin
     ChDir (FCurrentDirectory);
    end;
   try
-   cos := BPTR(0);
-   repeat
-     Inc(UID);
-     TempName := 'T:PrO_'+ HexStr(FindTask(nil)) + '_' + IntToHex(UID,8);
-   until not FileExists(TempName);
-   //sysdebugln('TProcess start: "' + ExecName + ' ' + Params+'"  >' + TempName);
-   cos := AmigaDos.DosOpen(PChar(TempName), MODE_READWRITE);
-   FExitCode := LongInt(amigados.Execute(PChar(ExecName + ' ' + Params), BPTR(0), cos));
-   DosSeek(cos, 0, OFFSET_BEGINNING);
-   CreateStreams(0, THandle(cos),0);
-   //FExitCode := ExecuteProcess (ExecName, Params);
+    {$ifdef MorphOS}
+    if (poUsePipes in Options) and (not (poWaitOnExit in Options)) then
+    begin
+      FProcessID := 0;
+      // Pipenames, should be unique
+      TempName := 'PIPE:PrO_' + HexStr(Self) + HexStr(GetTickCount, 8);
+      inA := DOSOpen(PChar(TempName), MODE_OLDFILE);
+      inB := DOSOpen(PChar(TempName), MODE_NEWFILE);
+      TempName := TempName + 'o';
+      outA := DOSOpen(PChar(TempName), MODE_OLDFILE);
+      outB := DOSOpen(PChar(TempName), MODE_NEWFILE);
+      // set buffer for all pipes
+      SetVBuf(inA, nil, BUF_NONE, -1);
+      SetVBuf(inB, nil, BUF_LINE, -1);
+      SetVBuf(outA, nil, BUF_NONE, -1);
+      SetVBuf(outB, nil, BUF_LINE, -1);
+      // the actual Start of the command with given parameter and streams
+      Res := SystemTags(PChar(ExecName + ' ' + Params),
+                        [SYS_Input, AsTag(outA),
+                         SYS_Output, AsTag(inB),
+                         SYS_Asynch, AsTag(True),
+                         TAG_END]);
+      // the two streams will be destroyed by system, we do not need to care about
+      // the other two we will destroy when the PipeStreams they are attached to are destroyed
+      if Res <> -1 then
+      begin
+        FProcessID := 1;
+        CreateStreams(THandle(outB), THandle(inA),0);
+      end
+      else
+      begin
+        // if the command did not start, we need to delete all Streams
+        if outB <> BPTR(0) then DosClose(outB);
+        if outA <> BPTR(0) then DosClose(outA);
+        if inB <> BPTR(0) then DosClose(inB);
+        if inA <> BPTR(0) then DosClose(inA);
+      end;
+    end
+    else
+    {$endif}
+    begin
+      // if no streams needed we still use the old sychronous way
+      FProcessID := 0;
+      cos := BPTR(0);
+      repeat
+        Inc(UID);
+        TempName := 'T:PrO_'+ HexStr(FindTask(nil)) + '_' + IntToHex(UID,8);
+      until not FileExists(TempName);
+      //sysdebugln('TProcess start: "' + ExecName + ' ' + Params+'"  >' + TempName);
+      cos := AmigaDos.DosOpen(PChar(TempName), MODE_READWRITE);
+      FExitCode := LongInt(amigados.Execute(PChar(ExecName + ' ' + Params), BPTR(0), cos));
+      DosSeek(cos, 0, OFFSET_BEGINNING);
+      CreateStreams(0, THandle(cos),0);
+    end;
+    //FExitCode := ExecuteProcess (ExecName, Params);
   except
 (* Normalize the raised exception so that it is aligned to other platforms. *)
     On E: EOSError do

+ 21 - 1
packages/fcl-process/src/pipes.pp

@@ -91,10 +91,30 @@ begin
 end;
 
 Function TInputPipeStream.Read (Var Buffer; Count : Longint) : longint;
-
+{$ifdef MorphOS}
+var
+  i: Integer;
+  Runner: PByte;
+{$endif}
 begin
+  {$ifdef MorphOS}
+  FillChar(Buffer, Count, 0);
+  if FGetS(Handle, @Buffer, Count) = nil then
+    Result := 0
+  else
+  begin
+    Result := 0;
+    Runner := @Buffer;
+    repeat
+      if Runner^ = 0 then
+        Break;
+      Inc(Result);
+    until Result >= Count;
+  end;
+  {$else}
   Result:=Inherited Read(Buffer,Count);
   Inc(FPos,Result);
+  {$endif}
 end;
 
 function TInputPipeStream.Seek(const Offset: int64; Origin: TSeekOrigin): int64;

+ 7 - 0
packages/mysql/fpmake.pp

@@ -151,6 +151,13 @@ begin
         end;
     T.ResourceStrings := True;
 
+    T:=P.Targets.AddUnit('mysql80dyn.pp');
+      with T.Dependencies do
+        begin
+          AddInclude('mysql.inc');
+        end;
+    T.ResourceStrings := True;
+
     P.ExamplePath.Add('examples');
     P.Targets.AddExampleProgram('testdb3.pp');
     P.Targets.AddExampleProgram('testdb4.pp');

+ 164 - 37
packages/mysql/src/mysql.inc

@@ -31,7 +31,9 @@ uses
   {$DEFINE extdecl:=cdecl}
   const
     mysqllib = 'libmysqlclient.'+sharedsuffix;
-  {$IF DEFINED(mysql57)}
+  {$IF DEFINED(mysql80)}
+    mysqlvlib = mysqllib+'.21';
+  {$ELSEIF DEFINED(mysql57)}
     mysqlvlib = mysqllib+'.20';
   {$ELSEIF DEFINED(mysql55) or DEFINED(mysql56)}
     mysqlvlib = mysqllib+'.18';
@@ -53,6 +55,10 @@ uses
 {$ENDIF}
 
 
+{$IFDEF mysql80}
+  {$DEFINE mysql57}
+{$ENDIF mysql80}
+
 {$IFDEF mysql57}
   {$DEFINE mysql56}
 {$ENDIF mysql57}
@@ -151,22 +157,46 @@ uses
      MYSQL_SERVICENAME = 'MySQL';
 
   type
-     enum_server_command = (COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
-       COM_FIELD_LIST,COM_CREATE_DB,COM_DROP_DB,
-       COM_REFRESH,COM_SHUTDOWN,COM_STATISTICS,
-       COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
-       COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
-       COM_CHANGE_USER,COM_BINLOG_DUMP,COM_TABLE_DUMP,
-       COM_CONNECT_OUT,COM_REGISTER_SLAVE,
+     enum_server_command = (
+       COM_SLEEP,
+       COM_QUIT,
+       COM_INIT_DB,
+       COM_QUERY,
+       COM_FIELD_LIST,
+       COM_CREATE_DB,
+       COM_DROP_DB,
+       COM_REFRESH,
+       COM_SHUTDOWN, // deprecated
+       COM_STATISTICS,
+       COM_PROCESS_INFO,
+       COM_CONNECT,
+       COM_PROCESS_KILL,
+       COM_DEBUG,
+       COM_PING,
+       COM_TIME,
+       COM_DELAYED_INSERT,
+       COM_CHANGE_USER,
+       COM_BINLOG_DUMP,
+       COM_TABLE_DUMP,
+       COM_CONNECT_OUT,
+       COM_REGISTER_SLAVE,
 {$IFDEF mysql50}
-       COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE,
-       COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH,
+       COM_STMT_PREPARE,
+       COM_STMT_EXECUTE,
+       COM_STMT_SEND_LONG_DATA,
+       COM_STMT_CLOSE,
+       COM_STMT_RESET,
+       COM_SET_OPTION,
+       COM_STMT_FETCH,
  {$IFDEF mysql51}
        COM_DAEMON,
   {$IFDEF mysql56}
        COM_BINLOG_DUMP_GTID,
    {$IFDEF mysql57}
        COM_RESET_CONNECTION,
+     {$IFDEF mysql80}
+       COM_CLONE,
+     {$ENDIF}
    {$ENDIF}
   {$ENDIF}
  {$ENDIF}
@@ -236,6 +266,11 @@ uses
        FIELD_IS_DROPPED = (1 shl 26);         // Intern: Field is being dropped
    {$IFDEF mysql57}
        EXPLICIT_NULL_FLAG = (1 shl 27);       // Field is explicitly specified as NULL by the user
+     {$IFDEF mysql80}
+       FIELD_IS_MARKED = (1 shl 28);       // Intern: field is marked, general purpose
+       NOT_SECONDARY_FLAG = (1 << 29); // Field will not be loaded in secondary engine.
+       FIELD_IS_INVISIBLE = (1 << 30); // Field is explicitly marked as invisible by the user.
+     {$ENDIF}
    {$ENDIF}
   {$ENDIF}
  {$ENDIF}
@@ -247,7 +282,8 @@ uses
        REFRESH_HOSTS = 8;          // Flush host cache
        REFRESH_STATUS = 16;        // Flush status variables
        REFRESH_THREADS = 32;       // Flush thread cache
-       REFRESH_SLAVE = 64;         // Reset master info and restart slave thread
+       REFRESH_REPLICA = 64;         // Reset master info and restart replica thread
+       REFRESH_SLAVE = REFRESH_REPLICA;  // Reset master info and restart slave thread
        REFRESH_MASTER = 128;       // Remove all bin logs in the index and truncate the index
        REFRESH_ERROR_LOG = 256;    // Rotate only the erorr log
        REFRESH_ENGINE_LOG = 512;   // Flush all storage engine logs
@@ -259,13 +295,19 @@ uses
     { The following can't be set with mysql_refresh()  }
        REFRESH_READ_LOCK = 16384;          // Lock tables for read
        REFRESH_FAST = 32768;               // Intern flag
+
+       {$IFNDEF mysql80}
        REFRESH_QUERY_CACHE = 65536;        // RESET (remove all queries) from query cache
        REFRESH_QUERY_CACHE_FREE = $20000;  // pack query cache
-
        REFRESH_DES_KEY_FILE = $40000;
+       {$ENDIF}
+
        REFRESH_USER_RESOURCES = $80000;
        REFRESH_FOR_EXPORT = $100000;       // FLUSH TABLES ... FOR EXPORT
        REFRESH_OPTIMIZER_COSTS = $200000;  // FLUSH OPTIMIZER_COSTS
+       {$IFDEF mysql80}
+       REFRESH_PERSIST = $400000;          // RESET PERSIST
+       {$ENDIF}
 
        CLIENT_LONG_PASSWORD = 1;           // new more secure passwords
        CLIENT_FOUND_ROWS = 2;              // Found instead of affected rows
@@ -292,6 +334,11 @@ uses
        CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS : cardinal = (1 shl 22);    // Don't close the connection for a connection with expired password.
        CLIENT_SESSION_TRACK : cardinal = (1 shl 23);  // Capable of handling server state change information. Its a hint to the server to include the state change information in Ok packet.
        CLIENT_DEPRECATE_EOF : cardinal = (1 shl 24);  // Client no longer needs EOF packet
+       {$IFDEF mysql80}
+       CLIENT_OPTIONAL_RESULTSET_METADATA : cardinal = (1 shl 25);  // client can handle optional metadata information in the resultset
+       CLIENT_ZSTD_COMPRESSION_ALGORITHM : cardinal = (1 shl 26); // Client sets this flag when it is configured to use zstd compression method
+       CLIENT_QUERY_ATTRIBUTES : cardinal = (1 shl 27); // Can send the optional part containing the query parameter set(s)
+       {$ENDIF}
        CLIENT_SSL_VERIFY_SERVER_CERT : cardinal = 1 shl 30;
        CLIENT_REMEMBER_OPTIONS : cardinal = 1 shl 31;
 
@@ -384,17 +431,17 @@ uses
             return_status: pcuint;
             reading_or_writing: cuchar;
             save_char: cchar;
-            unused1: my_bool;  // Please remove with the next incompatible ABI change
-            unused2: my_bool;  // Please remove with the next incompatible ABI change
+              unused1: my_bool;  // Please remove with the next incompatible ABI change
+              unused2: my_bool;  // Please remove with the next incompatible ABI change
             compress: my_bool;
-            unused3: my_bool;  // Please remove with the next incompatible ABI change
+              unused3: my_bool;  // Please remove with the next incompatible ABI change
             { Pointer to query object in query cache, do not equal NULL (0) for
               queries in cache that have not stored its results yet }
-            unused: pcuchar;
+              unused: pcuchar;
             last_errno: cuint;
             error: cuchar;
-            unused4: my_bool;  // Please remove with the next incompatible ABI change
-            unused5: my_bool;  // Please remove with the next incompatible ABI change
+              unused4: my_bool;  // Please remove with the next incompatible ABI change
+              unused5: my_bool;  // Please remove with the next incompatible ABI change
             { Client library error message buffer. Actually belongs to struct MYSQL. }
             last_error: array[0..MYSQL_ERRMSG_SIZE-1] of cchar;
             { Client library sqlstate buffer. Set along with the error message. }
@@ -462,25 +509,44 @@ uses
        packet_error : culong = culong(not(0));
 
     type
-       enum_field_types = (MYSQL_TYPE_DECIMAL,MYSQL_TYPE_TINY,
-         MYSQL_TYPE_SHORT,MYSQL_TYPE_LONG,MYSQL_TYPE_FLOAT,
-         MYSQL_TYPE_DOUBLE,MYSQL_TYPE_NULL,
-         MYSQL_TYPE_TIMESTAMP,MYSQL_TYPE_LONGLONG,
-         MYSQL_TYPE_INT24,MYSQL_TYPE_DATE,MYSQL_TYPE_TIME,
-         MYSQL_TYPE_DATETIME,MYSQL_TYPE_YEAR,
+       enum_field_types = (
+         MYSQL_TYPE_DECIMAL,
+         MYSQL_TYPE_TINY,
+         MYSQL_TYPE_SHORT,
+         MYSQL_TYPE_LONG,
+         MYSQL_TYPE_FLOAT,
+         MYSQL_TYPE_DOUBLE,
+         MYSQL_TYPE_NULL,
+         MYSQL_TYPE_TIMESTAMP,
+         MYSQL_TYPE_LONGLONG,
+         MYSQL_TYPE_INT24,
+         MYSQL_TYPE_DATE,
+         MYSQL_TYPE_TIME,
+         MYSQL_TYPE_DATETIME,
+         MYSQL_TYPE_YEAR,
          MYSQL_TYPE_NEWDATE,
 {$IFDEF mysql50}
          MYSQL_TYPE_VARCHAR, MYSQL_TYPE_BIT,
  {$IFDEF mysql56}
          MYSQL_TYPE_TIMESTAMP2, MYSQL_TYPE_DATETIME2, MYSQL_TYPE_TIME2,
+   {$IFDEF mysql80}
+         MYSQL_TYPE_TYPED_ARRAY, // Used for replication only
+         MYSQL_TYPE_INVALID := 243,
+         MYSQL_TYPE_BOOL := 244, // Currently just a placeholder
+         MYSQL_TYPE_JSON := 245,
+   {$ENDIF}
  {$ENDIF}
          MYSQL_TYPE_NEWDECIMAL := 246,
 {$ENDIF}
          MYSQL_TYPE_ENUM := 247,
-         MYSQL_TYPE_SET := 248,MYSQL_TYPE_TINY_BLOB := 249,
-         MYSQL_TYPE_MEDIUM_BLOB := 250,MYSQL_TYPE_LONG_BLOB := 251,
-         MYSQL_TYPE_BLOB := 252,MYSQL_TYPE_VAR_STRING := 253,
-         MYSQL_TYPE_STRING := 254,MYSQL_TYPE_GEOMETRY := 255
+         MYSQL_TYPE_SET := 248,
+         MYSQL_TYPE_TINY_BLOB := 249,
+         MYSQL_TYPE_MEDIUM_BLOB := 250,
+         MYSQL_TYPE_LONG_BLOB := 251,
+         MYSQL_TYPE_BLOB := 252,
+         MYSQL_TYPE_VAR_STRING := 253,
+         MYSQL_TYPE_STRING := 254,
+         MYSQL_TYPE_GEOMETRY := 255
          );
 
     { For backward compatibility  }
@@ -907,15 +973,57 @@ uses
        MYSQL_DATA = st_mysql_data;
        PMYSQL_DATA = ^MYSQL_DATA;
 
-       mysql_option = (MYSQL_OPT_CONNECT_TIMEOUT,MYSQL_OPT_COMPRESS,
-         MYSQL_OPT_NAMED_PIPE,MYSQL_INIT_COMMAND,
-         MYSQL_READ_DEFAULT_FILE,MYSQL_READ_DEFAULT_GROUP,
-         MYSQL_SET_CHARSET_DIR,MYSQL_SET_CHARSET_NAME,
-         MYSQL_OPT_LOCAL_INFILE,MYSQL_OPT_PROTOCOL,
-         MYSQL_SHARED_MEMORY_BASE_NAME,MYSQL_OPT_READ_TIMEOUT,
-         MYSQL_OPT_WRITE_TIMEOUT,MYSQL_OPT_USE_RESULT,
-         MYSQL_OPT_USE_REMOTE_CONNECTION,MYSQL_OPT_USE_EMBEDDED_CONNECTION,
-         MYSQL_OPT_GUESS_CONNECTION,MYSQL_SET_CLIENT_IP,
+       mysql_option = (
+         MYSQL_OPT_CONNECT_TIMEOUT,
+         MYSQL_OPT_COMPRESS,
+         MYSQL_OPT_NAMED_PIPE,
+         MYSQL_INIT_COMMAND,
+         MYSQL_READ_DEFAULT_FILE,
+         MYSQL_READ_DEFAULT_GROUP,
+         MYSQL_SET_CHARSET_DIR,
+         MYSQL_SET_CHARSET_NAME,
+         MYSQL_OPT_LOCAL_INFILE,
+         MYSQL_OPT_PROTOCOL,
+         MYSQL_SHARED_MEMORY_BASE_NAME,
+         MYSQL_OPT_READ_TIMEOUT,
+         MYSQL_OPT_WRITE_TIMEOUT,
+         MYSQL_OPT_USE_RESULT,
+         {$IFDEF MYSQL80}
+         MYSQL_REPORT_DATA_TRUNCATION,
+         MYSQL_OPT_RECONNECT,
+         MYSQL_PLUGIN_DIR,
+         MYSQL_DEFAULT_AUTH,
+         MYSQL_OPT_BIND,
+         MYSQL_OPT_SSL_KEY,
+         MYSQL_OPT_SSL_CERT,
+         MYSQL_OPT_SSL_CA,
+         MYSQL_OPT_SSL_CAPATH,
+         MYSQL_OPT_SSL_CIPHER,
+         MYSQL_OPT_SSL_CRL,
+         MYSQL_OPT_SSL_CRLPATH,
+         MYSQL_OPT_CONNECT_ATTR_RESET,
+         MYSQL_OPT_CONNECT_ATTR_ADD,
+         MYSQL_OPT_CONNECT_ATTR_DELETE,
+         MYSQL_SERVER_PUBLIC_KEY,
+         MYSQL_ENABLE_CLEARTEXT_PLUGIN,
+         MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
+         MYSQL_OPT_MAX_ALLOWED_PACKET,
+         MYSQL_OPT_NET_BUFFER_LENGTH,
+         MYSQL_OPT_TLS_VERSION,
+         MYSQL_OPT_SSL_MODE,
+         MYSQL_OPT_GET_SERVER_PUBLIC_KEY,
+         MYSQL_OPT_RETRY_COUNT,
+         MYSQL_OPT_OPTIONAL_RESULTSET_METADATA,
+         MYSQL_OPT_SSL_FIPS_MODE,
+         MYSQL_OPT_TLS_CIPHERSUITES,
+         MYSQL_OPT_COMPRESSION_ALGORITHMS,
+         MYSQL_OPT_ZSTD_COMPRESSION_LEVEL,
+         MYSQL_OPT_LOAD_DATA_LOCAL_DIR
+         {$ELSE}
+         MYSQL_OPT_USE_REMOTE_CONNECTION,
+         MYSQL_OPT_USE_EMBEDDED_CONNECTION,
+         MYSQL_OPT_GUESS_CONNECTION,
+         MYSQL_SET_CLIENT_IP,
          MYSQL_SECURE_AUTH
 {$IFDEF MYSQL50}
          ,MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT
@@ -936,6 +1044,7 @@ uses
    {$ENDIF}
   {$ENDIF}
  {$ENDIF}
+{$ENDIF}
 {$ENDIF}
          );
 
@@ -1000,6 +1109,19 @@ uses
             shared_memory_base_name : Pchar;
 {$ENDIF}
             max_allowed_packet : culong;
+{$IFDEF Mysql80}
+            compress : my_bool;
+            named_pipe : my_bool;
+            bind_address: Pchar;
+            report_data_truncation: my_bool;
+            { function pointers for local infile support  }
+            local_infile_init : function (_para1:Ppointer; _para2:Pchar; _para3:pointer):cint;cdecl;
+            local_infile_read : function (_para1:pointer; _para2:Pchar; _para3:cuint):cint;
+            local_infile_end : procedure (_para1:pointer);
+            local_infile_error : function (_para1:pointer; _para2:Pchar; _para3:cuint):cint;
+            local_infile_userdata : pointer;
+            extension : ^st_mysql_options_extention;
+{$ELSE}
             use_ssl : my_bool;               // if to use SSL or not
             compress : my_bool;
             named_pipe : my_bool;
@@ -1043,6 +1165,7 @@ uses
 {$IFDEF mysql51}
             extension : ^st_mysql_options_extention;
 {$ENDIF}
+{$ENDIF}
 {$ENDIF}
          end;
 
@@ -1144,6 +1267,8 @@ uses
             free_me : my_bool;           // If free in mysql_close
             reconnect : my_bool;         // set to 1 if automatic reconnect
             scramble : array[0..(SCRAMBLE_LENGTH+1)-1] of char;  // session-wide random string
+{$IFDEF mysql80}
+{$ELSE}
     {  Set if this is the original connection, not a master or a slave we have
        added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave()      }
             rpl_pivot : my_bool;
@@ -1153,6 +1278,7 @@ uses
             next_slave : Pst_mysql;
             last_used_slave : Pst_mysql; // needed for round-robin slave pick
             last_used_con : Pst_mysql;   // needed for send/read/store/use result to work correctly with replication
+{$ENDIF}
 {$IFDEF mysql41}
             stmts : Pointer;             // was PList, list of all statements
             methods : Pst_mysql_methods;
@@ -2099,3 +2225,4 @@ end;
 initialization
   Refcount := 0;
 {$ENDIF}
+end.

+ 12 - 0
packages/mysql/src/mysql80dyn.pp

@@ -0,0 +1,12 @@
+{
+  Contains the MySQL calls for MySQL 8.0
+}
+
+unit mysql80dyn;
+
+{$DEFINE LinkDynamically}
+{$DEFINE MYSQL80}
+
+{$i mysql.inc}
+
+end.

+ 68 - 38
packages/rtl-objpas/src/inc/dateutil.inc

@@ -44,6 +44,19 @@ const
   DaySaturday  = 6;
   DaySunday    = 7;
 
+  MonthJanuary   = 1;
+  MonthFebruary  = 2;
+  MonthMarch     = 3;
+  MonthApril     = 4;
+  MonthMay       = 5;
+  MonthJune      = 6;
+  MonthJuly      = 7;
+  MonthAugust    = 8;
+  MonthSeptember = 9;
+  MonthOctober   = 10;
+  MonthNovember  = 11;
+  MonthDecember  = 12;
+
   // Fraction of a day
   OneHour        = TDateTime(1)/HoursPerDay;
   OneMinute      = TDateTime(1)/MinsPerDay;
@@ -2379,6 +2392,8 @@ begin
 end;
 
 function scandatetime(const pattern:string;const s:string;const fmt:TFormatSettings;startpos:integer=1) : tdatetime;
+const
+  EPS = 1E-15;
 
 var len ,ind  : integer;
     yy,mm,dd  : integer;
@@ -2558,44 +2573,59 @@ begin
                        end;
                      end;
                'A' : begin
-                            i:=findimatch(AMPMformatting,@ptrn[pind]);
-                            case i of
-                              0: begin
-                                   i:=findimatch(['AM','PM'],@s[ind]);
-                                   case i of
-                                     0: ;
-                                     1: timeval:=timeval+12*hrfactor;
-                                   else
-                                     arraymatcherror
-                                     end;
-                                   inc(pind,length(AMPMformatting[0]));
-                                   inc(ind,2);
-                                 end;
-                              1: begin
-                                    case upcase(s[ind]) of
-                                     'A' : ;
-                                     'P' : timeval:=timeval+12*hrfactor;
-                                   else
-                                     arraymatcherror
-                                     end;
-                                   inc(pind,length(AMPMformatting[1]));
-                                   inc(ind);
-                                 end;
-                               2: begin
-                                    i:=findimatch([fmt.timeamstring,fmt.timepmstring],@s[ind]);
-                                    case i of
-                                     0: inc(ind,length(fmt.timeamstring));
-                                     1: begin
-                                          timeval:=timeval+12*hrfactor;
-                                          inc(ind,length(fmt.timepmstring));
-                                        end;
-                                   else
-                                     arraymatcherror
-                                     end;
-                                   inc(pind,length(AMPMformatting[2]));
-                                 end;
-                            else  // no AM/PM match. Assume 'a' is simply a char
-                                matchchar(ptrn[pind]);
+                        i:=findimatch(AMPMformatting,@ptrn[pind]);
+                        case i of
+                            0: begin
+                                 if timeval >= 13*hrfactor - EPS then
+                                   raiseexception(SAMPMError);
+                                 i:=findimatch(['AM','PM'],@s[ind]);
+                                 case i of
+                                   0: if timeval >= 12*hrfactor then
+                                        timeval := timeval - 12*hrfactor;
+                                   1: if (timeval + EPS >= hrfactor) and (timeval + EPS <= 12*hrfactor) then
+                                        timeval:=timeval+12*hrfactor;
+                                 else
+                                   arraymatcherror
+                                   end;
+                                 inc(pind,length(AMPMformatting[0]));
+                                 inc(ind,2);
+                               end;
+                            1: begin
+                                 if timeval >= 13*hrfactor - EPS then
+                                   raiseexception(SAMPMError);
+                                  case upcase(s[ind]) of
+                                   'A' : if timeval >= 12*hrfactor then
+                                           timeval := timeval - 12*hrfactor;
+                                   'P' : if (timeval + EPS >= hrfactor) and (timeval + EPS <= 12*hrfactor) then
+                                           timeval := timeval + 12*hrfactor;
+                                 else
+                                   arraymatcherror
+                                   end;
+                                 inc(pind,length(AMPMformatting[1]));
+                                 inc(ind);
+                               end;
+                             2: begin
+                                  if timeval >= 13*hrfactor - EPS then
+                                    raiseexception(SAMPMError);
+                                  i:=findimatch([fmt.timeamstring,fmt.timepmstring],@s[ind]);
+                                  case i of
+                                   0: begin
+                                        if timeval >= 12*hrfactor then
+                                          timeval := timeval - 12*hrfactor;
+                                        inc(ind,length(fmt.timeamstring));
+                                      end;
+                                   1: begin
+                                        if (timeval + EPS >= hrfactor) and (timeval + EPS <= 12*hrfactor) then
+                                          timeval:=timeval + 12*hrfactor;
+                                        inc(ind,length(fmt.timepmstring));
+                                      end;
+                                 else
+                                   arraymatcherror
+                                  end;
+                                 inc(pind,length(AMPMformatting[2]));
+                               end;
+                           else  // no AM/PM match. Assume 'a' is simply a char
+                               matchchar(ptrn[pind]);
                              end;
                          end;
                '/' : matchchar(fmt.dateSeparator);

+ 8 - 1
packages/rtl-unicode/fpmake.pp

@@ -16,11 +16,12 @@ Const
   CPUnits       = [aix,amiga,aros,android,beos,darwin,iphonesim,ios,emx,gba,nds,freebsd,go32v2,haiku,linux,morphos,netbsd,netware,netwlibc,openbsd,os2,solaris,watcom,wii,win32,win64,wince,dragonfly,freertos];
   utf8bidiOSes  = [netware,netwlibc];
   freebidiOSes  = [netware,netwlibc];
+  GraphemeBreakPropertyOSes = AllOSes;
 
 // Character not movable because fpwidestring depends on it.
 //  CharacterOSes = [android,darwin,freebsd,linux,netbsd,openbsd,solaris,win32,win64,dragonfly];
 
-  UnicodeAllOSes =   CollationOSes + utf8bidiOSes + freebidiOSes + CPUnits;
+  UnicodeAllOSes =   CollationOSes + utf8bidiOSes + freebidiOSes + CPUnits + GraphemeBreakPropertyOSes;
 
 // Amiga has a crt in its RTL dir, but it is commented in the makefile
 
@@ -138,6 +139,12 @@ begin
     T:=P.Targets.AddImplicitUnit('cp950.pas',CPUnits);
 
 //    T:=P.Targets.AddUnit('character.pp',characterOSes);
+
+    T:=P.Targets.AddUnit('graphemebreakproperty.pp',GraphemeBreakPropertyOSes);
+    with T.Dependencies do
+      begin
+        AddInclude('graphemebreakproperty_code.inc');
+      end;
   end
 end;
 

+ 180 - 0
packages/rtl-unicode/src/inc/graphemebreakproperty.pp

@@ -0,0 +1,180 @@
+{ GraphemeBreakProperty Unicode data unit.
+
+  Copyright (C) 2021 Nikolay Nikolov <[email protected]>
+
+  This library is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Library General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or (at your
+  option) any later version with the following modification:
+
+  As a special exception, the copyright holders of this library give you
+  permission to link this library with independent modules to produce an
+  executable, regardless of the license terms of these independent modules,and
+  to copy and distribute the resulting executable under terms of your choice,
+  provided that you also meet, for each linked independent module, the terms
+  and conditions of the license of that module. An independent module is a
+  module which is not derived from or based on this library. If you modify
+  this library, you may extend this exception to your version of the library,
+  but you are not obligated to do so. If you do not wish to do so, delete this
+  exception statement from your 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 Library General Public License
+  for more details.
+
+  You should have received a copy of the GNU Library General Public License
+  along with this library; if not, write to the Free Software Foundation,
+  Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA.
+}
+
+unit graphemebreakproperty;
+
+{$MODE objfpc}
+
+interface
+
+type
+  TGraphemeBreakProperty = (
+    gbpOther,
+    gbpPrepend,
+    gbpCR,
+    gbpLF,
+    gbpControl,
+    gbpExtend,
+    gpbRegional_Indicator,
+    gbpSpacingMark,
+    gbpL,
+    gbpV,
+    gbpT,
+    gbpLV,
+    gbpLVT,
+    gbpE_Base,
+    gbpE_Modifier,
+    gbpZWJ,
+    gbpGlue_After_Zwj,
+    gbpE_Base_GAZ);
+
+  { TUnicodeStringExtendedGraphemeClustersEnumerator }
+
+  TUnicodeStringExtendedGraphemeClustersEnumerator = class
+  private
+    FStr: UnicodeString;
+    FCurrentIndexStart: SizeInt;
+    FCurrentIndexEnd: SizeInt;
+    FNextIndexEnd: SizeInt;
+    FNextGBP: TGraphemeBreakProperty;
+    FNextCodePoint: UCS4Char;
+    FCurrentGBP: TGraphemeBreakProperty;
+    FCurrentCodePoint: UCS4Char;
+    FRI_Sequence_Length: Integer;
+    FE_Base_EBG_Extend_Sequence: Boolean;
+    function GetCurrent: UnicodeString;
+    procedure FetchNextChar;
+  public
+    constructor Create(const S: UnicodeString);
+    function GetEnumerator: TUnicodeStringExtendedGraphemeClustersEnumerator;
+    function MoveNext: Boolean;
+    property Current: UnicodeString read GetCurrent;
+  end;
+
+function GetGraphemeBreakProperty(Ch: UCS4Char): TGraphemeBreakProperty;
+
+implementation
+
+function GetGraphemeBreakProperty(Ch: UCS4Char): TGraphemeBreakProperty;
+begin
+  {$I graphemebreakproperty_code.inc}
+end;
+
+{ TUnicodeStringExtendedGraphemeClustersEnumerator }
+
+function TUnicodeStringExtendedGraphemeClustersEnumerator.GetCurrent: UnicodeString;
+begin
+  Result := Copy(FStr, FCurrentIndexStart, FCurrentIndexEnd - FCurrentIndexStart + 1);
+end;
+
+procedure TUnicodeStringExtendedGraphemeClustersEnumerator.FetchNextChar;
+begin
+  Inc(FNextIndexEnd);
+  if FNextIndexEnd <= Length(FStr) then
+  begin
+    FNextCodePoint := Ord(FStr[FNextIndexEnd]);
+    { high surrogate, followed by low surrogate? }
+    if (FNextCodePoint >= $D800) and (FNextCodePoint <= $DBFF) and ((FNextIndexEnd + 1) <= Length(FStr)) and
+       (Ord(FStr[FNextIndexEnd + 1]) >= $DC00) and (Ord(FStr[FNextIndexEnd + 1]) <= $DFFF) then
+    begin
+      Inc(FNextIndexEnd);
+      FNextCodePoint := $10000 + (((FNextCodePoint - $D800) shl 10) or (Ord(FStr[FNextIndexEnd]) - $DC00));
+    end;
+  end
+  else
+    FNextCodePoint := 0;
+  FNextGBP := GetGraphemeBreakProperty(FNextCodePoint);
+end;
+
+constructor TUnicodeStringExtendedGraphemeClustersEnumerator.Create(const S: UnicodeString);
+begin
+  FStr := S;
+  FCurrentIndexStart := 0;
+  FCurrentIndexEnd := 0;
+  FNextIndexEnd := 0;
+  FRI_Sequence_Length := 0;
+  FE_Base_EBG_Extend_Sequence := False;
+  FetchNextChar;
+end;
+
+function TUnicodeStringExtendedGraphemeClustersEnumerator.GetEnumerator: TUnicodeStringExtendedGraphemeClustersEnumerator;
+begin
+  Result := Self;
+end;
+
+function TUnicodeStringExtendedGraphemeClustersEnumerator.MoveNext: Boolean;
+begin
+  FCurrentIndexStart := FCurrentIndexEnd + 1;
+  if FCurrentIndexStart > Length(FStr) then
+    Exit(false);
+  repeat
+    FCurrentGBP := FNextGBP;
+    FCurrentCodePoint := FNextCodePoint;
+    FCurrentIndexEnd := FNextIndexEnd;
+    if FCurrentGBP = gpbRegional_Indicator then
+      Inc(FRI_Sequence_Length)
+    else
+      FRI_Sequence_Length := 0;
+    FE_Base_EBG_Extend_Sequence := (FCurrentGBP in [gbpE_Base, gbpE_Base_GAZ]) or (FE_Base_EBG_Extend_Sequence and (FCurrentGBP = gbpExtend));
+    FetchNextChar;
+    if FNextIndexEnd > Length(FStr) then
+      Exit(True);
+
+    { Do not break between a CR and LF. Otherwise, break before and after controls. }
+    if (FCurrentGBP = gbpCR) and (FNextGBP = gbpLF) then
+      continue
+    else if (FCurrentGBP in [gbpControl, gbpCR, gbpLF]) or (FNextGBP in [gbpControl, gbpCR, gbpLF]) then
+      Exit(True)
+    { Do not break Hangul syllable sequences. }
+    else if ((FCurrentGBP = gbpL) and (FNextGBP in [gbpL, gbpV, gbpLV, gbpLVT])) or
+            ((FCurrentGBP in [gbpLV, gbpV]) and (FNextGBP in [gbpV, gbpT])) or
+            ((FCurrentGBP in [gbpLVT, gbpT]) and (FNextGBP = gbpT)) then
+      continue
+    { Do not break before extending characters or ZWJ. }
+    else if FNextGBP in [gbpExtend, gbpZWJ] then
+      continue
+    { Only for extended grapheme clusters:
+      Do not break before SpacingMarks, or after Prepend characters. }
+    else if (FCurrentGBP = gbpPrepend) or (FNextGBP = gbpSpacingMark) then
+      continue
+    { Do not break within emoji modifier sequences or emoji zwj sequences. }
+    else if ((FCurrentGBP = gbpZWJ) and (FNextGBP in [gbpGlue_After_Zwj, gbpE_Base_GAZ])) or
+            (FE_Base_EBG_Extend_Sequence and (FNextGBP = gbpE_Modifier)) then
+      continue
+    { Do not break within emoji flag sequences. That is, do not break between regional indicator (RI) symbols if there is an odd number of RI characters before the break point. }
+    else if (FCurrentGBP = gpbRegional_Indicator) and (FNextGBP = gpbRegional_Indicator) and Odd(FRI_Sequence_Length) then
+      continue
+    { Otherwise, break everywhere. }
+    else
+      Exit(True);
+  until False;
+end;
+
+end.

+ 511 - 0
packages/rtl-unicode/src/inc/graphemebreakproperty_code.inc

@@ -0,0 +1,511 @@
+{ do not edit, this file is autogenerated by the gbpparser tool }
+if Ch=13then result:=gbpCR else
+if Ch=10then result:=gbpLF else
+if Ch=8205then result:=gbpZWJ else
+if(Ch>=127462)and(Ch<=127487)then result:=gpbRegional_Indicator else
+if(Ch>=127995)and(Ch<=127999)then result:=gbpE_Modifier else
+if(Ch>=128102)and(Ch<=128105)then result:=gbpE_Base_GAZ else
+if(Ch>=44032)and(Ch<=55203)then begin if((Ch-44032)mod 28)=0then result:=gbpLV else result:=gbpLVT end else
+if((Ch>=4352)and(Ch<=4447))or
+((Ch>=43360)and(Ch<=43388))then result:=gbpL else
+if((Ch>=4448)and(Ch<=4519))or
+((Ch>=55216)and(Ch<=55238))then result:=gbpV else
+if((Ch>=4520)and(Ch<=4607))or
+((Ch>=55243)and(Ch<=55291))then result:=gbpT else
+if(Ch=10084)or
+(Ch=128139)or
+(Ch=128488)then result:=gbpGlue_After_Zwj else
+if((Ch>=1536)and(Ch<=1541))or
+(Ch=1757)or
+(Ch=1807)or
+(Ch=2274)or
+(Ch=3406)or
+(Ch=69821)or
+((Ch>=70082)and(Ch<=70083))then result:=gbpPrepend else
+if((Ch>=0)and(Ch<=31))or
+((Ch>=127)and(Ch<=159))or
+(Ch=173)or
+(Ch=1564)or
+(Ch=6158)or
+(Ch=8203)or
+((Ch>=8206)and(Ch<=8207))or
+((Ch>=8232)and(Ch<=8238))or
+((Ch>=8288)and(Ch<=8303))or
+((Ch>=55296)and(Ch<=57343))or
+(Ch=65279)or
+((Ch>=65520)and(Ch<=65531))or
+((Ch>=113824)and(Ch<=113827))or
+((Ch>=119155)and(Ch<=119162))or
+((Ch>=917504)and(Ch<=917535))or
+((Ch>=917632)and(Ch<=917759))or
+((Ch>=918000)and(Ch<=921599))then result:=gbpControl else
+if(Ch=9757)or
+(Ch=9977)or
+((Ch>=9994)and(Ch<=9997))or
+(Ch=127877)or
+((Ch>=127939)and(Ch<=127940))or
+((Ch>=127946)and(Ch<=127947))or
+((Ch>=128066)and(Ch<=128067))or
+((Ch>=128070)and(Ch<=128080))or
+(Ch=128110)or
+((Ch>=128112)and(Ch<=128120))or
+(Ch=128124)or
+((Ch>=128129)and(Ch<=128131))or
+((Ch>=128133)and(Ch<=128135))or
+(Ch=128170)or
+(Ch=128373)or
+(Ch=128378)or
+(Ch=128400)or
+((Ch>=128405)and(Ch<=128406))or
+((Ch>=128581)and(Ch<=128583))or
+((Ch>=128587)and(Ch<=128591))or
+(Ch=128675)or
+((Ch>=128692)and(Ch<=128694))or
+(Ch=128704)or
+((Ch>=129304)and(Ch<=129310))or
+(Ch=129318)or
+(Ch=129328)or
+((Ch>=129331)and(Ch<=129337))or
+((Ch>=129340)and(Ch<=129342))then result:=gbpE_Base else
+case Ch of
+768..879,
+1155..1161,
+1425..1469,
+1471,
+1473..1474,
+1476..1477,
+1479,
+1552..1562,
+1611..1631,
+1648,
+1750..1756,
+1759..1764,
+1767..1768,
+1770..1773,
+1809,
+1840..1866,
+1958..1968,
+2027..2035,
+2070..2073,
+2075..2083,
+2085..2087,
+2089..2093,
+2137..2139,
+2260..2306,
+2362,
+2364,
+2369..2376,
+2381,
+2385..2391,
+2402..2403,
+2433,
+2492,
+2494,
+2497..2500,
+2509,
+2519,
+2530..2531,
+2561..2562,
+2620,
+2625..2626,
+2631..2632,
+2635..2637,
+2641,
+2672..2673,
+2677,
+2689..2690,
+2748,
+2753..2757,
+2759..2760,
+2765,
+2786..2787,
+2817,
+2876,
+2878..2879,
+2881..2884,
+2893,
+2902..2903,
+2914..2915,
+2946,
+3006,
+3008,
+3021,
+3031,
+3072,
+3134..3136,
+3142..3144,
+3146..3149,
+3157..3158,
+3170..3171,
+3201,
+3260,
+3263,
+3266,
+3270,
+3276..3277,
+3285..3286,
+3298..3299,
+3329,
+3390,
+3393..3396,
+3405,
+3415,
+3426..3427,
+3530,
+3535,
+3538..3540,
+3542,
+3551,
+3633,
+3636..3642,
+3655..3662,
+3761,
+3764..3769,
+3771..3772,
+3784..3789,
+3864..3865,
+3893,
+3895,
+3897,
+3953..3966,
+3968..3972,
+3974..3975,
+3981..3991,
+3993..4028,
+4038,
+4141..4144,
+4146..4151,
+4153..4154,
+4157..4158,
+4184..4185,
+4190..4192,
+4209..4212,
+4226,
+4229..4230,
+4237,
+4253,
+4957..4959,
+5906..5908,
+5938..5940,
+5970..5971,
+6002..6003,
+6068..6069,
+6071..6077,
+6086,
+6089..6099,
+6109,
+6155..6157,
+6277..6278,
+6313,
+6432..6434,
+6439..6440,
+6450,
+6457..6459,
+6679..6680,
+6683,
+6742,
+6744..6750,
+6752,
+6754,
+6757..6764,
+6771..6780,
+6783,
+6832..6846,
+6912..6915,
+6964,
+6966..6970,
+6972,
+6978,
+7019..7027,
+7040..7041,
+7074..7077,
+7080..7081,
+7083..7085,
+7142,
+7144..7145,
+7149,
+7151..7153,
+7212..7219,
+7222..7223,
+7376..7378,
+7380..7392,
+7394..7400,
+7405,
+7412,
+7416..7417,
+7616..7669,
+7675..7679,
+8204,
+8400..8432,
+11503..11505,
+11647,
+11744..11775,
+12330..12335,
+12441..12442,
+42607..42610,
+42612..42621,
+42654..42655,
+42736..42737,
+43010,
+43014,
+43019,
+43045..43046,
+43204..43205,
+43232..43249,
+43302..43309,
+43335..43345,
+43392..43394,
+43443,
+43446..43449,
+43452,
+43493,
+43561..43566,
+43569..43570,
+43573..43574,
+43587,
+43596,
+43644,
+43696,
+43698..43700,
+43703..43704,
+43710..43711,
+43713,
+43756..43757,
+43766,
+44005,
+44008,
+44013,
+64286,
+65024..65039,
+65056..65071,
+65438..65439,
+66045,
+66272,
+66422..66426,
+68097..68099,
+68101..68102,
+68108..68111,
+68152..68154,
+68159,
+68325..68326,
+69633,
+69688..69702,
+69759..69761,
+69811..69814,
+69817..69818,
+69888..69890,
+69927..69931,
+69933..69940,
+70003,
+70016..70017,
+70070..70078,
+70090..70092,
+70191..70193,
+70196,
+70198..70199,
+70206,
+70367,
+70371..70378,
+70400..70401,
+70460,
+70462,
+70464,
+70487,
+70502..70508,
+70512..70516,
+70712..70719,
+70722..70724,
+70726,
+70832,
+70835..70840,
+70842,
+70845,
+70847..70848,
+70850..70851,
+71087,
+71090..71093,
+71100..71101,
+71103..71104,
+71132..71133,
+71219..71226,
+71229,
+71231..71232,
+71339,
+71341,
+71344..71349,
+71351,
+71453..71455,
+71458..71461,
+71463..71467,
+72752..72758,
+72760..72765,
+72767,
+72850..72871,
+72874..72880,
+72882..72883,
+72885..72886,
+92912..92916,
+92976..92982,
+94095..94098,
+113821..113822,
+119141,
+119143..119145,
+119150..119170,
+119173..119179,
+119210..119213,
+119362..119364,
+121344..121398,
+121403..121452,
+121461,
+121476,
+121499..121503,
+121505..121519,
+122880..122886,
+122888..122904,
+122907..122913,
+122915..122916,
+122918..122922,
+125136..125142,
+125252..125258,
+917536..917999:result:=gbpExtend;
+2307,
+2363,
+2366..2368,
+2377..2380,
+2382..2383,
+2434..2435,
+2495..2496,
+2503..2504,
+2507..2508,
+2563,
+2622..2624,
+2691,
+2750..2752,
+2761,
+2763..2764,
+2818..2819,
+2880,
+2887..2888,
+2891..2892,
+3007,
+3009..3010,
+3014..3016,
+3018..3020,
+3073..3075,
+3137..3140,
+3202..3203,
+3262,
+3264..3265,
+3267..3268,
+3271..3272,
+3274..3275,
+3330..3331,
+3391..3392,
+3398..3400,
+3402..3404,
+3458..3459,
+3536..3537,
+3544..3550,
+3570..3571,
+3635,
+3763,
+3902..3903,
+3967,
+4145,
+4155..4156,
+4182..4183,
+4228,
+6070,
+6078..6085,
+6087..6088,
+6435..6438,
+6441..6443,
+6448..6449,
+6451..6456,
+6681..6682,
+6741,
+6743,
+6765..6770,
+6916,
+6965,
+6971,
+6973..6977,
+6979..6980,
+7042,
+7073,
+7078..7079,
+7082,
+7143,
+7146..7148,
+7150,
+7154..7155,
+7204..7211,
+7220..7221,
+7393,
+7410..7411,
+43043..43044,
+43047,
+43136..43137,
+43188..43203,
+43346..43347,
+43395,
+43444..43445,
+43450..43451,
+43453..43456,
+43567..43568,
+43571..43572,
+43597,
+43755,
+43758..43759,
+43765,
+44003..44004,
+44006..44007,
+44009..44010,
+44012,
+69632,
+69634,
+69762,
+69808..69810,
+69815..69816,
+69932,
+70018,
+70067..70069,
+70079..70080,
+70188..70190,
+70194..70195,
+70197,
+70368..70370,
+70402..70403,
+70463,
+70465..70468,
+70471..70472,
+70475..70477,
+70498..70499,
+70709..70711,
+70720..70721,
+70725,
+70833..70834,
+70841,
+70843..70844,
+70846,
+70849,
+71088..71089,
+71096..71099,
+71102,
+71216..71218,
+71227..71228,
+71230,
+71340,
+71342..71343,
+71350,
+71456..71457,
+71462,
+72751,
+72766,
+72873,
+72881,
+72884,
+94033..94078,
+119142,
+119149:result:=gbpSpacingMark;
+else result:=gbpOther end

+ 1 - 1
packages/symbolic/src/symbolic.pas

@@ -240,7 +240,7 @@ const InfixOperatorName   : array[addo..powo] of char= ('+','-','*','/','^');
              'LOG10','LOG2','LNXP1','!','ARCTAN2',
              'STEP','POWER','HYPOT','LOGN');
      LenFunctionNames : array[cosx..lognx] of longint=
-             (3,3,3,3,3,3,2,3,1,5,6,6,6,4,4,4,7,7,7,5,4,5,1,7,4,5,5,4);
+             (3,3,3,3,4,3,2,3,1,5,6,6,6,4,4,4,7,7,7,5,4,5,1,7,4,5,5,4);
 
 {$I exprstrs.inc}
 

+ 1 - 1
rtl/embedded/Makefile

@@ -374,7 +374,7 @@ CPU_SPECIFIC_COMMON_UNITS=
 ifeq ($(ARCH),arm)
 CPU_SPECIFIC_COMMON_UNITS=sysutils math classes fgl macpas typinfo types rtlconsts getopts lineinfo
 ifeq ($(SUBARCH),armv7m)
-CPU_UNITS=lm3fury lm3tempest stm32f10x_ld stm32f10x_md stm32f10x_hd stm32f10x_xl stm32f10x_conn stm32f10x_cl lpc13xx lpc1768 lm4f120 sam3x8e xmc4500 cortexm3 cortexm4 # thumb2_bare
+CPU_UNITS=lm3fury lm3tempest stm32f10x_ld stm32f10x_md stm32f10x_hd stm32f10x_xl stm32f10x_conn stm32f10x_cl lpc13xx lpc1768 sam3x8e xmc4500 cortexm3 cortexm4 # thumb2_bare
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(SUBARCH),armv7em)

+ 1 - 1
rtl/embedded/Makefile.fpc

@@ -71,7 +71,7 @@ CPU_SPECIFIC_COMMON_UNITS=
 ifeq ($(ARCH),arm)
 CPU_SPECIFIC_COMMON_UNITS=sysutils math classes fgl macpas typinfo types rtlconsts getopts lineinfo
 ifeq ($(SUBARCH),armv7m)
-CPU_UNITS=lm3fury lm3tempest stm32f10x_ld stm32f10x_md stm32f10x_hd stm32f10x_xl stm32f10x_conn stm32f10x_cl lpc13xx lpc1768 lm4f120 sam3x8e xmc4500 cortexm3 cortexm4 # thumb2_bare
+CPU_UNITS=lm3fury lm3tempest stm32f10x_ld stm32f10x_md stm32f10x_hd stm32f10x_xl stm32f10x_conn stm32f10x_cl lpc13xx lpc1768 sam3x8e xmc4500 cortexm3 cortexm4 # thumb2_bare
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(SUBARCH),armv7em)

+ 13 - 1
rtl/embedded/arm/cortexm4f_start.inc

@@ -43,6 +43,14 @@ asm
   str r1, [r0]
 {$endif REMAP_VECTTAB}
 
+{$if defined(FPUARM_HAS_VFP_EXTENSION)}
+  ldr r0, .Lcpacr
+  ldr r1, [r0]
+  orr r1, r1, #0xf00000
+  str r1, [r0]
+  dsb
+  isb
+{$endif defined(FPUARM_HAS_VFP_EXTENSION)}
   bl PASCALMAIN
   b HaltProc
 
@@ -56,10 +64,14 @@ asm
   .long _data
 .L_edata:
   .long _edata
+{$if defined(FPUARM_HAS_VFP_EXTENSION)}
+.Lcpacr:
+  .long 0xE000ED88
+{$endif defined(FPUARM_HAS_VFP_EXTENSION)}
 {$ifdef REMAP_VECTTAB}
 .Lvtor:
   .long 0xE000ED08
 .Ltext_start:
   .long _text_start
 {$endif REMAP_VECTTAB}
-end;
+end;

+ 13 - 1
rtl/freertos/arm/cortexm4f_start.inc

@@ -43,6 +43,14 @@ asm
   str r1, [r0]
 {$endif REMAP_VECTTAB}
 
+{$if defined(FPUARM_HAS_VFP_EXTENSION)}
+  ldr r0, .Lcpacr
+  ldr r1, [r0]
+  orr r1, r1, #0xf00000
+  str r1, [r0]
+  dsb
+  isb
+{$endif defined(FPUARM_HAS_VFP_EXTENSION)}
   bl PASCALMAIN
   b HaltProc
 
@@ -56,10 +64,14 @@ asm
   .long _data
 .L_edata:
   .long _edata
+{$if defined(FPUARM_HAS_VFP_EXTENSION)}
+.Lcpacr:
+  .long 0xE000ED88
+{$endif defined(FPUARM_HAS_VFP_EXTENSION)}
 {$ifdef REMAP_VECTTAB}
 .Lvtor:
   .long 0xE000ED08
 .Ltext_start:
   .long _text_start
 {$endif REMAP_VECTTAB}
-end;
+end;

+ 10 - 7
rtl/linux/arm/sighnd.inc

@@ -20,10 +20,10 @@ begin
   result:=@HandleErrorAddrFrame;
 end;
 
-{$ifndef CPUTHUMB}
+{$if not(defined(CPUTHUMB)) and not(defined(CPUTHUMB2))}
 Procedure SignalToHandleErrorAddrFrame_ARM(Errno : longint;addr : CodePointer; frame : Pointer); nostackframe; assembler;
 asm
-{$if FPC_VERSION >= 30200}
+{$if FPC_FULLVERSION >= 30200}
 .code 32
 {$endif}
   // the address is of the faulting instruction, and sigreturn will
@@ -38,9 +38,9 @@ asm
   pop {r0,r1,r2,pc}
 .text
 end;
-{$endif not CPUTHUMB}
+{$endif not(defined(CPUTHUMB)) and not(defined(CPUTHUMB2))}
 
-{$if FPC_VERSION >= 30200}
+{$if FPC_FULLVERSION >= 30200}
 Procedure SignalToHandleErrorAddrFrame_Thumb(Errno : longint;addr : CodePointer; frame : Pointer); nostackframe; assembler;
 asm
 .thumb_func
@@ -57,6 +57,9 @@ asm
   mov lr, r0
   pop {r0,r1,r2,pc}
 .text
+{$if not(defined(CPUTHUMB)) and not(defined(CPUTHUMB2))}
+.code 32
+{$endif not(defined(CPUTHUMB)) and not(defined(CPUTHUMB2))}
 end;
 {$endif}
 
@@ -98,14 +101,14 @@ begin
       ucontext^.uc_mcontext.arm_r0:=res;
       ucontext^.uc_mcontext.arm_r1:=uContext^.uc_mcontext.arm_pc;
       ucontext^.uc_mcontext.arm_r2:=uContext^.uc_mcontext.arm_fp;
-{$if FPC_VERSION >= 30200}
-{$ifndef CPUTHUMB}
+{$if FPC_FULLVERSION >= 30200}
+{$if not(defined(CPUTHUMB)) and not(defined(CPUTHUMB2))}
       if (ucontext^.uc_mcontext.arm_cpsr and (1 shl 5))=0 then
         begin
           ucontext^.uc_mcontext.arm_pc:=ptruint(@SignalToHandleErrorAddrFrame_ARM);
         end
       else
-{$endif not CPUTHUMB}
+{$endif not(defined(CPUTHUMB)) and not(defined(CPUTHUMB2))}
         begin
           ucontext^.uc_mcontext.arm_pc:=ptruint(@SignalToHandleErrorAddrFrame_Thumb);
         end;

+ 1 - 0
rtl/objpas/sysconst.pp

@@ -145,6 +145,7 @@ const
   SHHMMError                    = 'mm in a sequence hh:mm is interpreted as minutes. No longer versions allowed! (Position : %d).' ;
   SFullpattern                  = 'Couldn''t match entire pattern string. Input too short at pattern position %d.';
   SPatternCharMismatch          = 'Pattern mismatch char "%s" at position %d.';
+  SAMPMError                    = 'Hour >= 13 not allowed in AM/PM mode.';
 
   SShortMonthNameJan = 'Jan';
   SShortMonthNameFeb = 'Feb';

+ 106 - 0
tests/test/units/dateutil/test_scandatetime_ampm.pas

@@ -0,0 +1,106 @@
+program test_scandatetime_ampm;
+{$mode objfpc}
+{$h+}
+uses
+  SysUtils, DateUtils, StrUtils;
+
+Var
+ ErrCount : Integer;
+
+function SameDateTime(dt1, dt2: TDateTime): Boolean;
+const
+  EPS = 1/(24*60*60*100*10);  // 0.1 ms
+begin
+  Result := abs(dt1 - dt2) < EPS;
+end;
+
+procedure Test(AExpected: TDateTime; AFormatStr, ADateTimeStr: String; NeedError : Boolean = False);
+var
+  dt: TDateTime;
+begin
+  Write(PadRight(ADateTimeStr, 36), ' --->   ');
+  Write(PadRight(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', dt), 25));
+  try
+    dt := ScanDateTime(AFormatStr, ADateTimeStr);
+    if dt = AExpected then WriteLn('OK') else 
+     begin
+     Inc(ErrCount);
+     WriteLn('ERROR');
+     end;
+  except on E:Exception do
+    begin
+    if not NeedError then
+      inc(errcount);
+    WriteLn('ERROR: ', E.Message);
+    end;
+  end;
+end;
+
+begin
+  errCount:=0;
+  WriteLn('Using current format settings...');
+  Test(EncodeDateTime(2014, 4, 2, 0, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 12:00 am');
+  Test(EncodeDateTime(2014, 4, 2, 0, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 12:00 AM');
+  Test(EncodeDateTime(2014, 4, 2, 0, 1, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 12:01 am');
+  Test(EncodeDateTime(2014, 4, 2, 1, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 01:00 am');
+  Test(EncodeDateTime(2014, 4, 2,11, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 11:00 am');
+  Test(EncodeDateTime(2014, 4, 2,11,59, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 11:59 am');
+  Test(EncodeDateTime(2014, 4, 2,11,59,59,999), 'mmmm dd??, yyyy, hh:nn:ss.zzz am/pm', 'April 2nd, 2014, 11:59:59.999 am');
+  Test(EncodeDateTime(2014, 4, 2,12, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 12:00 pm');
+  Test(EncodeDateTime(2014, 4, 2,12, 0, 0,  1), 'mmmm dd??, yyyy, hh:nn:ss.zzz am/pm', 'April 2nd, 2014, 12:00:00.001 pm');
+  Test(EncodeDateTime(2014, 4, 2,13, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 01:00 pm');
+  Test(EncodeDateTime(2014, 4, 2,13, 1, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 01:01 pm');
+  Test(EncodeDateTime(2014, 4, 2,23, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 11:00 pm');
+  Test(EncodeDateTime(2014, 4, 2,23,59,59,999), 'mmmm dd??, yyyy, hh:nn:ss.zzz am/pm', 'April 2nd, 2014, 11:59:59.999 pm');
+
+  WriteLn;
+
+  Test(EncodeDateTime(2014, 4, 2, 0, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 12:00 a');
+  Test(EncodeDateTime(2014, 4, 2, 0, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 12:00 A');
+  Test(EncodeDateTime(2014, 4, 2, 0, 1, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 12:01 a');
+  Test(EncodeDateTime(2014, 4, 2, 1, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 01:00 a');
+  Test(EncodeDateTime(2014, 4, 2,11, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 11:00 a');
+  Test(EncodeDateTime(2014, 4, 2,11,59, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 11:59 a');
+  Test(EncodeDateTime(2014, 4, 2,11,59,59,999), 'mmmm dd??, yyyy, hh:nn:ss.zzz a/p', 'April 2nd, 2014, 11:59:59.999 a');
+  Test(EncodeDateTime(2014, 4, 2,12, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 12:00 p');
+  Test(EncodeDateTime(2014, 4, 2,12, 0, 0,  1), 'mmmm dd??, yyyy, hh:nn:ss.zzz a/p', 'April 2nd, 2014, 12:00:00.001 p');
+  Test(EncodeDateTime(2014, 4, 2,13, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 01:00 p');
+  Test(EncodeDateTime(2014, 4, 2,13, 1, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 01:01 p');
+  Test(EncodeDateTime(2014, 4, 2,23, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn a/p', 'April 2nd, 2014, 11:00 p');
+  Test(EncodeDateTime(2014, 4, 2,23,59,59,999), 'mmmm dd??, yyyy, hh:nn:ss.zzz a/p', 'April 2nd, 2014, 11:59:59.999 p');
+
+  WriteLn;
+
+  FormatSettings.TimeAMString := 'vorm';
+  FormatSettings.TimePMString := 'nachm';
+  WriteLn('Using modified format settings with ampm=', FormatSettings.TimeAMString, '/', FormatSettings.TimePMString);
+  Test(EncodeDateTime(2014, 4, 2, 0, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 12:00 vorm');
+  Test(EncodeDateTime(2014, 4, 2, 0, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 12:00 VORM');
+  Test(EncodeDateTime(2014, 4, 2, 0, 1, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 12:01 vorm');
+  Test(EncodeDateTime(2014, 4, 2, 1, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 01:00 vorm');
+  Test(EncodeDateTime(2014, 4, 2,11, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 11:00 vorm');
+  Test(EncodeDateTime(2014, 4, 2,11,59, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 11:59 vorm');
+  Test(EncodeDateTime(2014, 4, 2,11,59,59,999), 'mmmm dd??, yyyy, hh:nn:ss.zzz ampm', 'April 2nd, 2014, 11:59:59.999 vorm');
+  Test(EncodeDateTime(2014, 4, 2,12, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 12:00 nachm');
+  Test(EncodeDateTime(2014, 4, 2,12, 0, 0,  1), 'mmmm dd??, yyyy, hh:nn:ss.zzz ampm', 'April 2nd, 2014, 12:00:00.001 nachm');
+  Test(EncodeDateTime(2014, 4, 2,13, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 01:00 nachm');
+  Test(EncodeDateTime(2014, 4, 2,13, 1, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 01:01 nachm');
+  Test(EncodeDateTime(2014, 4, 2,23, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 2nd, 2014, 11:00 nachm');
+  Test(EncodeDateTime(2014, 4, 2,23,59,59,999), 'mmmm dd??, yyyy, hh:nn:ss.zzz ampm', 'April 2nd, 2014, 11:59:59.999 nachm');
+  Test(EncodeDateTime(2014, 4, 3,12, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn ampm', 'April 3rd, 2014, 12:00 nachm');
+  WriteLn('The next test should raise an exception.');
+
+  try
+    Test(EncodeDateTime(2014, 4, 2,13, 0, 0,  0), 'mmmm dd??, yyyy, hh:nn am/pm', 'April 2nd, 2014, 13:00 pm',True);
+   
+  except on E:Exception do
+    begin
+    WriteLn('OK, exception received: ', E.Message);
+    end;
+  end;
+
+  WriteLn;
+  WriteLn('Test complete. Press RETURN to exit.');
+  Halt(Ord(errcount>0));
+//  ReadLn;
+end.

+ 13 - 0
tests/webtbf/tw38439.pp

@@ -0,0 +1,13 @@
+{ %fail }
+{ %opt=-Sew }
+{$mode iso}
+program string1(input, output);
+    var
+        c: packed array [1..5] of char;
+        inline: packed array [1..10] of char;
+begin
+    c := '1234567890';
+    writeln(c);
+    inline := '12345';
+    writeln(inline);
+end.

+ 1 - 1
utils/unicode/cldrparser.lpr

@@ -54,7 +54,7 @@ const
     '         <HaltOnFail> may be one of (y, Y, t, T, 1) to halt the execution on the first failing.' + sLineBreak +
     ' ' + sLineBreak +
     '  The program expects some files to be present in the <dataDir> folder : ' + sLineBreak +
-    '     - UCA_Rules_SHORT.xml ' + sLineBreak +
+    '     - UCA_Rules_SHORT.txt ' + sLineBreak +
     '     - allkeys.txt this is the file allkeys_CLDR.txt renamed to allkeys.txt' + sLineBreak +
     '  These files are in the core.zip file of the CLDR release files. The CLDR''version used should be synchronized the' + sLineBreak +
     '  version of the Unicode version used, for example for Uniocde 7 it will be CLDR 26.' + sLineBreak +

+ 7 - 7
utils/unicode/data/readme.txt

@@ -1,13 +1,13 @@
 This folder requires the next files to be present:
 
-  Extracted from http://www.unicode.org/Public/6.2.0/ucd/UCD.zip:
-    * UnicodeData.txt 
+  Extracted from https://www.unicode.org/Public/zipped/9.0.0/UCD.zip:
+    * UnicodeData.txt
     * HangulSyllableType.txt
     * PropList.txt
 
-  Extracted from http://www.unicode.org/Public/UCA/6.2.0/CollationAuxiliary.zip:
-    * allkeys.txt : this file is actually the allkeys_CLDR.txt file renamed. It is the CLDR's root collation.
-    * UCA_Rules_SHORT.xml
+#???  Extracted from http://www.unicode.org/Public/UCA/6.2.0/CollationAuxiliary.zip:
 
-  Extracted from http://www.unicode.org/Public/cldr/22/core.zip (see the "common\collation" folder):
-    * all the language specific xml files (de.xml, es.xml, ...)
+  Extracted from https://www.unicode.org/Public/cldr/30/core.zip
+    * allkeys.txt : this file is actually the allkeys_CLDR.txt file renamed. It is the CLDR's root collation.
+    * UCA_Rules_SHORT.txt
+    * all the language specific xml files (de.xml, es.xml, ...) (see the "common\collation" folder):

+ 1 - 0
utils/unicode/fpmake.pp

@@ -60,6 +60,7 @@ begin
 
     T:=P.Targets.AddProgram('cldrparser.lpr');
     T:=P.Targets.AddProgram('unihelper.lpr');
+    T:=P.Targets.AddProgram('gbpparser.lpr');
 
     end;
 end;

+ 58 - 0
utils/unicode/gbpparser.lpi

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="11"/>
+    <General>
+      <Flags>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <MainUnitHasTitleStatement Value="False"/>
+        <MainUnitHasScaledStatement Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <Title Value="gbpparser"/>
+      <UseAppBundle Value="False"/>
+      <ResourceType Value="res"/>
+    </General>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+      <Modes Count="0"/>
+    </RunParams>
+    <Units Count="1">
+      <Unit0>
+        <Filename Value="gbpparser.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit0>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <Target>
+      <Filename Value="gbpparser"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+      <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 379 - 0
utils/unicode/gbpparser.lpr

@@ -0,0 +1,379 @@
+{ Parser and code generator for the GraphemeBreakProperty.
+
+  Copyright (C) 2021 Nikolay Nikolov <[email protected]>
+
+  This source 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 code 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.
+
+  A copy of the GNU General Public License is available on the World Wide Web
+  at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
+  to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+  Boston, MA 02110-1335, USA.
+}
+
+
+program gbpparser;
+
+{$mode objfpc}{$H+}
+
+uses
+  SysUtils, StrUtils;
+
+type
+  TGraphemeBreakProperty = (
+    gbpOther,
+    gbpPrepend,
+    gbpCR,
+    gbpLF,
+    gbpControl,
+    gbpExtend,
+    gpbRegional_Indicator,
+    gbpSpacingMark,
+    gbpL,
+    gbpV,
+    gbpT,
+    gbpLV,
+    gbpLVT,
+    gbpE_Base,
+    gbpE_Modifier,
+    gbpZWJ,
+    gbpGlue_After_Zwj,
+    gbpE_Base_GAZ);
+
+  TRange = record
+    RangeLo, RangeHi: UCS4Char;
+  end;
+  TRanges = array of TRange;
+
+var
+  GraphemeBreakProperties: array [UCS4Char] of TGraphemeBreakProperty;
+  GBPStats: array [TGraphemeBreakProperty] of record
+    Exists: Boolean;
+    Handled: Boolean;
+    MinValue: UCS4Char;
+    MaxValue: UCS4Char;
+    Count: LongInt;
+    Ranges: TRanges;
+  end;
+
+function ParseGraphemeBreakProperty(S: string): TGraphemeBreakProperty;
+begin
+  S := Trim(S);
+  case S of
+    'Prepend':
+      Result := gbpPrepend;
+    'CR':
+      Result := gbpCR;
+    'LF':
+      Result := gbpLF;
+    'Control':
+      Result := gbpControl;
+    'Extend':
+      Result := gbpExtend;
+    'Regional_Indicator':
+      Result := gpbRegional_Indicator;
+    'SpacingMark':
+      Result := gbpSpacingMark;
+    'L':
+      Result := gbpL;
+    'V':
+      Result := gbpV;
+    'T':
+      Result := gbpT;
+    'LV':
+      Result := gbpLV;
+    'LVT':
+      Result := gbpLVT;
+    'E_Base':
+      Result := gbpE_Base;
+    'E_Modifier':
+      Result := gbpE_Modifier;
+    'ZWJ':
+      Result := gbpZWJ;
+    'Glue_After_Zwj':
+      Result := gbpGlue_After_Zwj;
+    'E_Base_GAZ':
+      Result := gbpE_Base_GAZ;
+    else
+      raise EArgumentException('Unknown grapheme break property: ''' + S + '''');
+  end;
+end;
+
+procedure ParseRange(S: string; out RangeLo, RangeHi: UCS4Char);
+var
+  dp: SizeInt;
+begin
+  S := Trim(S);
+  dp := Pos('..', S);
+  if dp > 0 then
+  begin
+    RangeLo := StrToInt('$' + LeftStr(S, dp - 1));
+    RangeHi := StrToInt('$' + Copy(S, dp + 2, Length(S) - dp + 3));
+  end
+  else
+  begin
+    RangeLo := StrToInt('$' + S);
+    RangeHi := RangeLo;
+  end;
+end;
+
+procedure ParseGraphemeBreakProperties(const FileName: string);
+var
+  InF: TextFile;
+  S: string;
+  SplitS: TStringArray;
+  LineNr: Integer = 0;
+  gbp: TGraphemeBreakProperty;
+  RangeLo, RangeHi, R: UCS4Char;
+begin
+  if not FileExists(FileName) then
+  begin
+    Writeln('File doesn''t exist: ', FileName);
+    Halt(1);
+  end;
+  AssignFile(InF, FileName);
+  Reset(InF);
+  while not EoF(InF) do
+  begin
+    Inc(LineNr);
+    Readln(InF, S);
+    S := Trim(S);
+    if Pos('#', S) > 0 then
+      S := LeftStr(S, Pos('#', S) - 1);
+    if S <> '' then
+    begin
+      SplitS := S.Split([';']);
+      if Length(SplitS) <> 2 then
+        raise Exception.Create('Invalid number of ; separators on line ' + IntToStr(LineNr));
+      ParseRange(SplitS[0], RangeLo, RangeHi);
+      gbp := ParseGraphemeBreakProperty(SplitS[1]);
+      for R := RangeLo to RangeHi do
+        GraphemeBreakProperties[R] := gbp;
+    end;
+  end;
+  CloseFile(InF);
+end;
+
+procedure CalcStatsAndRanges;
+var
+  Ch: UCS4Char;
+  gbp, prev_gbp: TGraphemeBreakProperty;
+begin
+  FillChar(GBPStats, SizeOf(GBPStats), 0);
+  gbp := Low(TGraphemeBreakProperty);
+  for Ch := Low(UCS4Char) to High(UCS4Char) do
+  begin
+    prev_gbp := gbp;
+    gbp := GraphemeBreakProperties[Ch];
+    with GBPStats[gbp] do
+    begin
+      if not Exists then
+      begin
+        Exists := True;
+        MinValue := Ch;
+        MaxValue := Ch;
+        Count := 1;
+        SetLength(Ranges, 1);
+        Ranges[0].RangeLo := Ch;
+        Ranges[0].RangeHi := Ch;
+      end
+      else
+      begin
+        MaxValue := Ch;
+        Inc(Count);
+        if prev_gbp <> gbp then
+        begin
+          SetLength(Ranges, Length(Ranges) + 1);
+          with Ranges[High(Ranges)] do
+          begin
+            RangeLo := Ch;
+            RangeHi := Ch;
+          end;
+        end
+        else
+          Ranges[High(Ranges)].RangeHi := Ch;
+      end;
+    end;
+  end;
+end;
+
+procedure MaybeCoalesceRanges(RLo, RHi: UCS4Char);
+var
+  gbp: TGraphemeBreakProperty;
+  RI: Integer;
+begin
+  for gbp := Succ(Low(TGraphemeBreakProperty)) to High(TGraphemeBreakProperty) do
+    if GBPStats[gbp].Exists and (not GBPStats[gbp].Handled) then
+    begin
+      for RI := 0 to High(GBPStats[gbp].Ranges) - 1 do
+        if (GBPStats[gbp].Ranges[RI].RangeHi = (RLo - 1)) and
+           (GBPStats[gbp].Ranges[RI + 1].RangeLo = (RHi + 1)) then
+        begin
+          GBPStats[gbp].Ranges[RI].RangeHi := GBPStats[gbp].Ranges[RI + 1].RangeHi;
+          Delete(GBPStats[gbp].Ranges, RI + 1, 1);
+          exit;
+        end;
+    end;
+end;
+
+function FindMinRangeCount: Integer;
+var
+  gbp: TGraphemeBreakProperty;
+begin
+  Result := High(Integer);
+  for gbp := Succ(Low(TGraphemeBreakProperty)) to High(TGraphemeBreakProperty) do
+    if GBPStats[gbp].Exists and (not GBPStats[gbp].Handled) and (Length(GBPStats[gbp].Ranges) < Result) then
+      Result := Length(GBPStats[gbp].Ranges);
+end;
+
+function ApplyLV_LVTCompression: Boolean;
+const
+  RangeLo = 44032;
+  RangeHi = 55203;
+var
+  Ch: UCS4Char;
+begin
+  Result := False;
+  if (GBPStats[gbpLV].MinValue <> RangeLo) or (GBPStats[gbpLV].MaxValue <> (RangeHi - 27)) or
+     (GBPStats[gbpLVT].MinValue <> (RangeLo + 1)) or (GBPStats[gbpLVT].MaxValue <> RangeHi) then
+    exit;
+  for Ch := RangeLo to RangeHi do
+  begin
+    if ((Ch - RangeLo) mod 28) = 0 then
+    begin
+      if GraphemeBreakProperties[Ch] <> gbpLV then
+        exit;
+    end
+    else
+    begin
+      if GraphemeBreakProperties[Ch] <> gbpLVT then
+        exit;
+    end;
+  end;
+  Result := True;
+end;
+
+procedure GenCode(const OutFileName: string);
+const
+  RangeCountThreshold = 30{400};
+var
+  gbp: TGraphemeBreakProperty;
+  RI, NextRangeCount: Integer;
+  OutFile: TextFile;
+begin
+  Writeln('Generating file: ', OutFileName);
+
+  AssignFile(OutFile, OutFileName);
+  Rewrite(OutFile);
+
+  Writeln(OutFile, '{ do not edit, this file is autogenerated by the gbpparser tool }');
+
+  { unused properties are already handled }
+  for gbp := Succ(Low(TGraphemeBreakProperty)) to High(TGraphemeBreakProperty) do
+    if not GBPStats[gbp].Exists then
+      GBPStats[gbp].Handled := True;
+
+  { handle single codepoints first }
+  for gbp := Succ(Low(TGraphemeBreakProperty)) to High(TGraphemeBreakProperty) do
+    if (not GBPStats[gbp].Handled) and (GBPStats[gbp].Count = 1) then
+    begin
+      if GBPStats[gbp].MinValue <> GBPStats[gbp].MaxValue then
+        raise Exception.Create('Internal error');
+      Writeln(OutFile, 'if Ch=', GBPStats[gbp].MinValue, 'then result:=',gbp,' else');
+      GBPStats[gbp].Handled := True;
+      MaybeCoalesceRanges(GBPStats[gbp].MinValue, GBPStats[gbp].MaxValue);
+    end;
+
+  { handle single range codepoints next }
+  while FindMinRangeCount = 1 do
+    for gbp := Succ(Low(TGraphemeBreakProperty)) to High(TGraphemeBreakProperty) do
+      if (not GBPStats[gbp].Handled) and (Length(GBPStats[gbp].Ranges) = 1) then
+      begin
+        Writeln(OutFile, 'if(Ch>=', GBPStats[gbp].MinValue, ')and(Ch<=', GBPStats[gbp].MaxValue, ')then result:=',gbp,' else');
+        GBPStats[gbp].Handled := True;
+        MaybeCoalesceRanges(GBPStats[gbp].MinValue, GBPStats[gbp].MaxValue);
+      end;
+
+  if ApplyLV_LVTCompression then
+  begin
+    Writeln(OutFile, 'if(Ch>=44032)and(Ch<=55203)then begin if((Ch-44032)mod 28)=0then result:=gbpLV else result:=gbpLVT end else');
+    GBPStats[gbpLV].Handled := True;
+    GBPStats[gbpLVT].Handled := True;
+  end;
+
+  repeat
+    NextRangeCount := FindMinRangeCount;
+    if NextRangeCount <= RangeCountThreshold then
+      for gbp := Succ(Low(TGraphemeBreakProperty)) to High(TGraphemeBreakProperty) do
+      begin
+        if not GBPStats[gbp].Handled and (Length(GBPStats[gbp].Ranges) <= NextRangeCount) then
+        begin
+          GBPStats[gbp].Handled := True;
+          Write(OutFile, 'if');
+          for RI := 0 to High(GBPStats[gbp].Ranges) do
+          begin
+            if RI <> 0 then
+              Writeln(OutFile, 'or');
+            with GBPStats[gbp].Ranges[RI] do
+            begin
+              if RangeLo = RangeHi then
+                Write(OutFile, '(Ch=', RangeLo, ')')
+              else
+                Write(OutFile, '((Ch>=', RangeLo, ')and(Ch<=', RangeHi, '))');
+              MaybeCoalesceRanges(RangeLo, RangeHi);
+            end;
+          end;
+          Writeln(OutFile, 'then result:=',gbp,' else');
+        end;
+      end;
+  until NextRangeCount > RangeCountThreshold;
+
+  if NextRangeCount <> High(Integer) then
+  begin
+    //for gbp := Succ(Low(TGraphemeBreakProperty)) to High(TGraphemeBreakProperty) do
+    //  if not GBPStats[gbp].Handled then
+    //    Writeln(gbp, ' ', GBPStats[gbp].MinValue, '..', GBPStats[gbp].MaxValue, ' ', GBPStats[gbp].Count, ' ', Length(GBPStats[gbp].Ranges), ' ', (GBPStats[gbp].MaxValue - GBPStats[gbp].MinValue + 7) div 8);
+    Writeln(OutFile, 'case Ch of');
+    for gbp := Succ(Low(TGraphemeBreakProperty)) to High(TGraphemeBreakProperty) do
+    begin
+      if not GBPStats[gbp].Handled then
+      begin
+        GBPStats[gbp].Handled := True;
+        for RI := 0 to High(GBPStats[gbp].Ranges) do
+        begin
+          if RI <> 0 then
+            Writeln(OutFile, ',');
+          with GBPStats[gbp].Ranges[RI] do
+          begin
+            if RangeLo = RangeHi then
+              Write(OutFile, RangeLo)
+            else
+              Write(OutFile, RangeLo, '..', RangeHi);
+          end;
+        end;
+        Writeln(OutFile, ':result:=', gbp, ';');
+      end;
+    end;
+    Writeln(OutFile, 'else result:=gbpOther end');
+  end
+  else
+    Writeln(OutFile, 'result:=gbpOther');
+
+  CloseFile(OutFile);
+end;
+
+begin
+  FillChar(GraphemeBreakProperties, SizeOf(GraphemeBreakProperties), 0);
+  ParseGraphemeBreakProperties('data/UCD/auxiliary/GraphemeBreakProperty.txt');
+  CalcStatsAndRanges;
+  GenCode('graphemebreakproperty_code.inc');
+  Writeln('Done');
+end.
+

+ 8 - 8
utils/unicode/parse-collations.bat

@@ -1,17 +1,17 @@
-cldrparser.exe de.xml -d.\data -o.\data
+cldrparser.exe de -d.\data -o.\data
 echo
-cldrparser es.xml -d.\data -o.\data
+cldrparser es -d.\data -o.\data
 echo
-cldrparser fr_CA.xml -d.\data -o.\data
+cldrparser fr_CA -d.\data -o.\data
 echo
-cldrparser ja.xml -d.\data -o.\data
+cldrparser ja -d.\data -o.\data
 echo
-cldrparser ko.xml -d.\data -o.\data
+cldrparser ko -d.\data -o.\data
 echo
-cldrparser ru.xml -d.\data -o.\data
+cldrparser ru -d.\data -o.\data
 echo
-cldrparser sv.xml -d.\data -o.\data
+cldrparser sv -d.\data -o.\data
 echo
-cldrparser zh.xml -d.\data -o.\data
+cldrparser zh -d.\data -o.\data
 
 pause

+ 8 - 8
utils/unicode/parse-collations.sh

@@ -1,18 +1,18 @@
 #!/bin/bash
-./cldrparser de.xml -d./data -o./data
+./cldrparser de -d./data -o./data
 echo
-./cldrparser es.xml -d./data -o./data
+./cldrparser es -d./data -o./data
 echo
-./cldrparser fr_CA.xml -d./data -o./data
+./cldrparser fr_CA -d./data -o./data
 echo
-./cldrparser ja.xml -d./data -o./data
+./cldrparser ja -d./data -o./data
 echo
-./cldrparser ko.xml -d./data -o./data
+./cldrparser ko -d./data -o./data
 echo
-./cldrparser ru.xml -d./data -o./data
+./cldrparser ru -d./data -o./data
 echo
-./cldrparser sv.xml -d./data -o./data
+./cldrparser sv -d./data -o./data
 echo
-./cldrparser zh.xml -d./data -o./data
+./cldrparser zh -d./data -o./data
 
 read -p "Press [Enter] key to continue ..."

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov