Browse Source

* synchronize with trunk

git-svn-id: branches/z80@44555 -
nickysn 5 years ago
parent
commit
6a2dbad8ca

+ 8 - 2
compiler/defutil.pas

@@ -372,7 +372,8 @@ interface
 implementation
 
     uses
-       verbose,cutils;
+       verbose,cutils,
+       cpuinfo;
 
     { returns true, if def uses FPU }
     function is_fpu(def : tdef) : boolean;
@@ -1518,7 +1519,12 @@ implementation
           objectdef :
             result:=int_cgsize(def.size);
           floatdef:
-            if cs_fp_emulation in current_settings.moduleswitches then
+            if (cs_fp_emulation in current_settings.moduleswitches)
+{$ifdef xtensa}
+              or not(tfloatdef(def).floattype=s32real)
+              or not(FPUXTENSA_SINGLE in fpu_capabilities[current_settings.fputype])
+{$endif xtensa}
+              then
               result:=int_cgsize(def.size)
             else
               result:=tfloat2tcgsize[tfloatdef(def).floattype];

+ 1 - 0
compiler/fpcdefs.inc

@@ -329,6 +329,7 @@
   {$define cpu32bitaddr}
   {$define cpu32bitalu}
   {$define cpufpemu}
+  {$define cpuflags} { xtensa has a boolean extension }
   {$define cputargethasfixedstack}
   {$define cpuneedsmulhelper}
   {$define cpuneedsdivhelper}

+ 23 - 15
compiler/nadd.pas

@@ -92,6 +92,10 @@ interface
             the code generation phase.
           }
           function first_addfloat : tnode; virtual;
+          {
+            generates softfloat code for the node
+          }
+          function first_addfloat_soft: tnode; virtual;
        private
           { checks whether a muln can be calculated as a 32bit }
           { * 32bit -> 64 bit                                  }
@@ -3623,26 +3627,16 @@ implementation
       end;
 
 
-    function taddnode.first_addfloat : tnode;
+    function taddnode.first_addfloat_soft : tnode;
       var
         procname: string[31];
         { do we need to reverse the result ? }
         notnode : boolean;
         fdef : tdef;
       begin
-        result := nil;
-        notnode := false;
-        fdef := nil;
-        { In non-emulation mode, real opcodes are
-          emitted for floating point values.
-        }
-        if not ((cs_fp_emulation in current_settings.moduleswitches)
-{$ifdef cpufpemu}
-                or (current_settings.fputype=fpu_soft)
-{$endif cpufpemu}
-                ) then
-          exit;
-
+        notnode:=false;
+        result:=nil;
+        fdef:=nil;
         if not(target_info.system in systems_wince) then
           begin
             case tfloatdef(left.resultdef).floattype of
@@ -3741,7 +3735,6 @@ implementation
               else
                 internalerror(2005082602);
             end;
-
           end;
         { cast softfpu result? }
         if not(target_info.system in systems_wince) then
@@ -3764,6 +3757,21 @@ implementation
           result:=cnotnode.create(result);
       end;
 
+    function taddnode.first_addfloat : tnode;
+      begin
+        result := nil;
+        { In non-emulation mode, real opcodes are
+          emitted for floating point values.
+        }
+        if not ((cs_fp_emulation in current_settings.moduleswitches)
+{$ifdef cpufpemu}
+                or (current_settings.fputype=fpu_soft)
+{$endif cpufpemu}
+                ) then
+          exit;
+        result:=first_addfloat_soft
+      end;
+
 
 {$ifdef cpuneedsmulhelper}
     function taddnode.use_mul_helper: boolean;

+ 3 - 0
compiler/ncgcnv.pas

@@ -220,6 +220,9 @@ interface
 {$elseif defined(sparcgen)}
         { Load left node into flag F_NE/F_E }
         resflags.Init(NR_ICC,F_NE);
+{$elseif defined(xtensa)}
+        { Xtensa uses its own implementation }
+        Internalerror(2020032901);
 {$else}
         { Load left node into flag F_NE/F_E }
         resflags:=F_NE;

+ 4 - 0
compiler/ncgutil.pas

@@ -332,7 +332,11 @@ implementation
                      LOC_FLAGS :
                        begin
                          cg.a_jmp_flags(list,p.location.resflags,truelabel);
+
+                         { e.g. xtensa has no default flags but uses a boolean register }
+{$ifndef xtensa}
                          cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
+{$endif xtensa}
                          cg.a_jmp_always(list,falselabel);
                        end;
 {$endif cpuflags}

+ 25 - 21
compiler/nld.pas

@@ -430,8 +430,8 @@ implementation
               ;
             constsym:
               begin
-                 if tconstsym(symtableentry).consttyp=constresourcestring then
-                   expectloc:=LOC_CREFERENCE;
+                if tconstsym(symtableentry).consttyp=constresourcestring then
+                  expectloc:=LOC_CREFERENCE;
               end;
             staticvarsym,
             localvarsym,
@@ -453,25 +453,25 @@ implementation
                   end;
               end;
             procsym :
-                begin
-                   { initialise left for nested procs if necessary }
-                   if (m_nested_procvars in current_settings.modeswitches) then
-                     setprocdef(fprocdef);
-                   { method pointer or nested proc ? }
-                   if assigned(left) then
-                     begin
-                        expectloc:=LOC_CREGISTER;
-                        firstpass(left);
-                     end;
-                end;
-           labelsym :
-             begin
-               if not assigned(tlabelsym(symtableentry).asmblocklabel) and
-                  not assigned(tlabelsym(symtableentry).code) then
-                 Message(parser_e_label_outside_proc);
-             end
-           else
-             internalerror(200104143);
+              begin
+                { initialise left for nested procs if necessary }
+                if (m_nested_procvars in current_settings.modeswitches) then
+                  setprocdef(fprocdef);
+                { method pointer or nested proc ? }
+                if assigned(left) then
+                  begin
+                     expectloc:=LOC_CREGISTER;
+                     firstpass(left);
+                  end;
+              end;
+            labelsym :
+              begin
+                if not assigned(tlabelsym(symtableentry).asmblocklabel) and
+                   not assigned(tlabelsym(symtableentry).code) then
+                  Message(parser_e_label_outside_proc);
+              end
+            else
+              internalerror(200104143);
          end;
       end;
 
@@ -751,6 +751,10 @@ implementation
                 and (use_vectorfpu(left.resultdef) and
                      use_vectorfpu(right.resultdef) and
                      (tfloatdef(left.resultdef).floattype=tfloatdef(right.resultdef).floattype))
+{$endif arm}
+{$ifdef xtensa}
+                and not((FPUXTENSA_SINGLE in fpu_capabilities[current_settings.fputype]) xor
+                  (FPUXTENSA_DOUBLE in fpu_capabilities[current_settings.fputype]))
 {$endif}
         then
           begin

+ 5 - 1
compiler/symdef.pas

@@ -2357,7 +2357,11 @@ implementation
 {$ifdef x86}
        result:=use_vectorfpu(self);
 {$else x86}
-       result:=(typ=floatdef) and not(cs_fp_emulation in current_settings.moduleswitches);
+       result:=(typ=floatdef) and not(cs_fp_emulation in current_settings.moduleswitches)
+{$ifdef xtensa}
+         and (FPUXTENSA_SINGLE in fpu_capabilities[init_settings.fputype]) and (tfloatdef(self).floattype=s32real)
+{$endif xtensa}
+         ;
 {$endif x86}
      end;
 

+ 75 - 0
compiler/xtensa/cgcpu.pas

@@ -57,7 +57,9 @@ interface
 
         procedure a_call_name(list:TAsmList;const s:string; weak: boolean);override;
         procedure a_call_reg(list:TAsmList;Reg:tregister);override;
+
         procedure a_jmp_name(list: TAsmList; const s: string);override;
+        procedure a_jmp_flags(list: TAsmList; const f: TResFlags; l: tasmlabel);override;
 
         procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);override;
         procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
@@ -67,8 +69,14 @@ interface
         procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override;
         procedure a_jmp_always(list: TAsmList; l: TAsmLabel);override;
 
+        procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister);override;
+
         procedure g_concatcopy(list : TAsmList; const source,dest : treference; len : tcgint);override;
 
+        procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);override;
+        procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister);override;
+        procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
+
         procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
       end;
 
@@ -546,6 +554,16 @@ implementation
       end;
 
 
+    procedure tcgcpu.a_jmp_flags(list: TAsmList; const f: TResFlags; l: tasmlabel);
+      var
+        instr: taicpu;
+      begin
+        instr:=taicpu.op_reg_sym(A_Bcc,f.register,l);
+        instr.condition:=flags_to_cond(f.flag);
+        list.concat(instr);
+      end;
+
+
     procedure tcgcpu.g_proc_entry(list : TAsmList; localsize : longint;
       nostackframe : boolean);
       var
@@ -773,6 +791,20 @@ implementation
       end;
 
 
+    procedure tcgcpu.g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister);
+      var
+        hregister: TRegister;
+        instr: taicpu;
+      begin
+        a_load_const_reg(list,size,0,reg);
+        hregister:=getintregister(list,size);
+        a_load_const_reg(list,size,1,hregister);
+        instr:=taicpu.op_reg_reg_reg(A_MOV,reg,hregister,f.register);
+        instr.condition:=flags_to_cond(f.flag);
+        list.concat(instr);
+      end;
+
+
     procedure tcgcpu.g_concatcopy_move(list: tasmlist; const Source, dest: treference; len: tcgint);
       var
         paraloc1, paraloc2, paraloc3: TCGPara;
@@ -917,6 +949,49 @@ implementation
       end;
 
 
+     procedure tcgcpu.a_loadfpu_reg_reg(list: TAsmList; fromsize,tosize: tcgsize; reg1, reg2: tregister);
+       begin
+         if not(fromsize in [OS_32,OS_F32]) then
+           InternalError(2020032603);
+         list.concat(taicpu.op_reg_reg(A_MOV_S,reg2,reg1));
+       end;
+
+
+     procedure tcgcpu.a_loadfpu_ref_reg(list: TAsmList; fromsize,tosize: tcgsize; const ref: treference; reg: tregister);
+       var
+         href: treference;
+       begin
+         if not(fromsize in [OS_32,OS_F32]) then
+           InternalError(2020032602);
+         href:=ref;
+         if assigned(href.symbol) or
+           (href.index<>NR_NO) or
+           (((href.offset<0) or (href.offset>1020) or (href.offset mod 4<>0))) then
+           fixref(list,href);
+
+         list.concat(taicpu.op_reg_ref(A_LSI,reg,href));
+
+         if fromsize<>tosize then
+           a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg);
+       end;
+
+
+     procedure tcgcpu.a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference);
+       var
+         href: treference;
+       begin
+         if not(fromsize in [OS_32,OS_F32]) then
+           InternalError(2020032604);
+         href:=ref;
+         if assigned(href.symbol) or
+           (href.index<>NR_NO) or
+           (((href.offset<0) or (href.offset>1020) or (href.offset mod 4<>0))) then
+           fixref(list,href);
+
+         list.concat(taicpu.op_reg_ref(A_SSI,reg,href));
+       end;
+
+
     procedure tcgcpu.maybeadjustresult(list : TAsmList; op : TOpCg; size : tcgsize; dst : tregister);
       const
         overflowops = [OP_MUL,OP_SHL,OP_ADD,OP_SUB,OP_NEG];

+ 27 - 5
compiler/xtensa/cpubase.pas

@@ -78,7 +78,7 @@ unit cpubase;
 
       { Float Super register first and last }
       first_fpu_supreg    = RS_F0;
-      first_fpu_imreg     = $08;
+      first_fpu_imreg     = $10;
 
       { MM Super register first and last }
       first_mm_supreg    = RS_INVALID;
@@ -109,18 +109,27 @@ unit cpubase;
         C_GE,C_LT,C_GEU,C_LTU,
         C_ANY,C_BNONE,C_ALL,C_NALL,C_BC,C_BS,
         C_EQZ,C_NEZ,C_LTZ,C_GEZ,
-        C_EQI,C_NEI,C_LTI,C_GEI,C_LTUI,C_GEUI
+        C_EQI,C_NEI,C_LTI,C_GEI,C_LTUI,C_GEUI,
+        C_F,C_T
       );
 
       TAsmConds = set of TAsmCond;
 
+      TResFlagsEnum = (F_Z,F_NZ);
+
+      TResFlags = record
+        register: TRegister;
+        flag: TResFlagsEnum;
+      end;
+
     const
       cond2str : array[TAsmCond] of string[4]=('',
         'eq','ne',                         
         'ge','lt','geu','ltu',
         'any','none','all','nall','bc','bs',
         'eqz','nez','ltz','gez',
-        'eqi','nei','lti','gei','ltui','geui'
+        'eqi','nei','lti','gei','ltui','geui',
+        'f','t'
       );
 
       uppercond2str : array[TAsmCond] of string[4]=('',
@@ -128,7 +137,8 @@ unit cpubase;
         'GE','LT','GEU','LTU',
         'ANY','NONE','ALL','NALL','BC','BS',
         'EQZ','NEZ','LTZ','GEZ',
-        'EQI','NEI','LTI','GEI','LTUI','GEUI'
+        'EQI','NEI','LTI','GEI','LTUI','GEUI',
+        'F','T'
       );
 
 {*****************************************************************************
@@ -246,6 +256,8 @@ unit cpubase;
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
+    function flags_to_cond(const f: TResFlagsEnum) : TAsmCond;
+
     { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
     function condition_in(const Subset, c: TAsmCond): Boolean;
 
@@ -361,13 +373,23 @@ unit cpubase;
           C_BNONE,C_ANY,C_NALL,C_BNONE,C_BS,C_BC,
 
           C_NEZ,C_EQZ,C_GEZ,C_LTZ,
-          C_NEI,C_EQI,C_GEI,C_LTI,C_GEUI,C_LTUI
+          C_NEI,C_EQI,C_GEI,C_LTI,C_GEUI,C_LTUI,
+          C_T,C_F
         );
       begin
         result := inverse[c];
       end;
 
 
+    function flags_to_cond(const f: TResFlagsEnum) : TAsmCond;
+      const flags2cond: array[TResFlagsEnum] of tasmcond = (
+          C_F,
+          C_T);
+      begin
+        flags_to_cond := flags2cond[f];
+      end;
+
+
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
         result := c1 = c2;

+ 12 - 8
compiler/xtensa/cpuinfo.pas

@@ -45,7 +45,8 @@ Type
    tfputype =
      (fpu_none,
       fpu_soft,
-      fpu_libgcc
+      fpu_libgcc,
+      fpu_hard
      );
 
 Type
@@ -97,7 +98,8 @@ Const
    fputypestr : array[tfputype] of string[10] = (
      'NONE',
      'SOFT',
-     'LIBGCC'
+     'LIBGCC',
+     'HARD'
    );
 
 
@@ -109,10 +111,10 @@ Const
    (
       (controllertypestr:'';		controllerunitstr:'';	cputype:cpu_none; fputype:fpu_none; abi: abi_default; flashbase:0),
       (controllertypestr:'ESP8266';	controllerunitstr:'ESP8266';	cputype:cpu_lx106; fputype:fpu_none; abi: abi_xtensa_call0; { flashbase:$40000000; flashsize:448*1024; srambase:$40070000; sramsize: 520*1024 }),
-      (controllertypestr:'ESP32';	controllerunitstr:'ESP32';	cputype:cpu_lx6; fputype:fpu_none; abi: abi_xtensa_windowed; flashbase:$40000000; flashsize:2*1024*1024),
-      (controllertypestr:'ESP32_D0WD';	controllerunitstr:'ESP32_D0WD';	cputype:cpu_lx6; fputype:fpu_none; abi: abi_xtensa_windowed; flashbase:$40000000; flashsize:448*1024; srambase:$40070000; sramsize: 520*1024),
-      (controllertypestr:'ESP32_D2WD';	controllerunitstr:'ESP32_D2WD';	cputype:cpu_lx6; fputype:fpu_none; abi: abi_xtensa_windowed; flashbase:$40000000; flashsize:448*1024; srambase:$40070000; sramsize: 520*1024),
-      (controllertypestr:'ESP32_S0WD';	controllerunitstr:'ESP32_S0WD';	cputype:cpu_lx6; fputype:fpu_none; abi: abi_xtensa_windowed; flashbase:$40000000; flashsize:448*1024; srambase:$40070000; sramsize: 520*1024)
+      (controllertypestr:'ESP32';	controllerunitstr:'ESP32';	cputype:cpu_lx6; fputype:fpu_hard; abi: abi_xtensa_windowed; flashbase:$40000000; flashsize:2*1024*1024),
+      (controllertypestr:'ESP32_D0WD';	controllerunitstr:'ESP32_D0WD';	cputype:cpu_lx6; fputype:fpu_hard; abi: abi_xtensa_windowed; flashbase:$40000000; flashsize:448*1024; srambase:$40070000; sramsize: 520*1024),
+      (controllertypestr:'ESP32_D2WD';	controllerunitstr:'ESP32_D2WD';	cputype:cpu_lx6; fputype:fpu_hard; abi: abi_xtensa_windowed; flashbase:$40000000; flashsize:448*1024; srambase:$40070000; sramsize: 520*1024),
+      (controllertypestr:'ESP32_S0WD';	controllerunitstr:'ESP32_S0WD';	cputype:cpu_lx6; fputype:fpu_hard; abi: abi_xtensa_windowed; flashbase:$40000000; flashsize:448*1024; srambase:$40070000; sramsize: 520*1024)
    );
 
    { Supported optimizations, only used for information }
@@ -138,7 +140,8 @@ Const
 
    tfpuflags =
       (
-        FPUXTENSA_DUMMY
+        FPUXTENSA_SINGLE, { FPU has single support }
+        FPUXTENSA_DOUBLE  { FPU has double support, this is a dummy so far for easier checking what code to generate }
       );
 
  const
@@ -153,7 +156,8 @@ Const
      (
        { fpu_none       } [],
        { fpu_soft       } [],
-       { fpu_libgcc     } []
+       { fpu_libgcc     } [],
+       { fpu_hard       } [FPUXTENSA_SINGLE]
      );
 
 Implementation

+ 3 - 23
compiler/xtensa/cpupara.pas

@@ -223,7 +223,7 @@ unit cpupara;
           exit;
 
         paraloc:=result.add_location;
-        if retcgsize in [OS_64,OS_S64] then
+        if retcgsize in [OS_64,OS_S64,OS_F64] then
           begin
             { low 32bits }
             paraloc^.loc:=LOC_REGISTER;
@@ -275,7 +275,7 @@ unit cpupara;
               end
             else
               paraloc^.register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(R_INTREGISTER,retcgsize));
-            paraloc^.size:=retcgsize;
+            paraloc^.size:=OS_32;
             paraloc^.def:=result.def;
           end;
       end;
@@ -424,30 +424,10 @@ unit cpupara;
                       inc(nextintreg);
                       dec(paralen,tcgsize2size[paraloc^.size]);
                     end
-                  else if (loc = LOC_FPUREGISTER) and
-                          (nextintreg <= maxintreg) then
-                    begin
-                      paraloc^.loc:=loc;
-                      paraloc^.size := paracgsize;
-                      paraloc^.def := paradef;
-                      paraloc^.register:=newreg(R_FPUREGISTER,nextintreg,R_SUBWHOLE);
-                      inc(nextintreg);
-                      dec(paralen,tcgsize2size[paraloc^.size]);
-                    end
                   else { LOC_REFERENCE }
                     begin
                        paraloc^.loc:=LOC_REFERENCE;
                        case loc of
-                         LOC_FPUREGISTER:
-                           begin
-                             paraloc^.size:=int_float_cgsize(paralen);
-                             case paraloc^.size of
-                               OS_F32: paraloc^.def:=s32floattype;
-                               OS_F64: paraloc^.def:=s64floattype;
-                               else
-                                 internalerror(2020031406);
-                             end;
-                           end;
                          LOC_REGISTER,
                          LOC_REFERENCE:
                            begin
@@ -496,7 +476,7 @@ unit cpupara;
       var
         cur_stack_offset: aword;
         parasize, l: longint;
-        curintreg, firstfloatreg: tsuperregister;
+        curintreg: tsuperregister;
         i : integer;
         hp: tparavarsym;
         paraloc: pcgparalocation;

+ 126 - 0
compiler/xtensa/ncpuadd.pas

@@ -30,11 +30,16 @@ interface
 
     type
        TCPUAddNode = class(tcgaddnode)
+       private
+         procedure pass_left_and_right;
        protected
          function pass_1 : tnode;override;
+         function first_addfloat: tnode;override;
          procedure second_cmpordinal;override;
          procedure second_cmpsmallset;override;
          procedure second_cmp64bit;override;
+         procedure second_cmpfloat;override;
+         procedure second_addfloat;override;
          procedure second_cmp;
        end;
 
@@ -176,6 +181,127 @@ interface
         second_cmp;
       end;
 
+
+    procedure TCPUAddNode.pass_left_and_right;
+      begin
+        { calculate the operator which is more difficult }
+        firstcomplex(self);
+
+        { in case of constant put it to the left }
+        if (left.nodetype=ordconstn) then
+         swapleftright;
+
+        secondpass(left);
+        secondpass(right);
+      end;
+
+
+    function TCPUAddNode.first_addfloat: tnode;
+      begin
+        result := nil;
+
+        if (FPUXTENSA_SINGLE in fpu_capabilities[current_settings.fputype]) and
+          (tfloatdef(left.resultdef).floattype=s32real) and (nodetype<>slashn) then
+          begin
+            if nodetype in [equaln,unequaln,lten,ltn,gten,gtn] then
+              expectloc:=LOC_FLAGS
+            else
+              expectloc:=LOC_FPUREGISTER;
+          end
+        else
+          result:=first_addfloat_soft;
+      end;
+
+
+    procedure TCPUAddNode.second_addfloat;
+      var
+        op    : TAsmOp;
+        cmpop,
+        singleprec , inv: boolean;
+      begin
+        pass_left_and_right;
+        if (nf_swapped in flags) then
+          swapleftright;
+
+        hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
+        hlcg.location_force_fpureg(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
+
+        cmpop:=false;
+        inv:=false;
+        case nodetype of
+          addn :
+            op:=A_ADD_S;
+          muln :
+            op:=A_MUL_S;
+          subn :
+            op:=A_SUB_S;
+          unequaln,
+          equaln:
+            begin
+              op:=A_OEQ_S;
+              cmpop:=true;
+            end;
+          ltn:
+            begin
+              op:=A_OLT_S;
+              cmpop:=true;
+            end;
+          lten:
+            begin
+              op:=A_OLE_S;
+              cmpop:=true;
+            end;
+          gtn:
+            begin
+              op:=A_OLT_S;
+              swapleftright;
+              cmpop:=true;
+            end;
+          gten:
+            begin
+              op:=A_OLE_S;
+              swapleftright;
+              cmpop:=true;
+            end;
+          else
+            internalerror(2020032601);
+        end;
+
+        { initialize de result }
+        if cmpop then
+          begin
+           location_reset(location,LOC_FLAGS,OS_NO);
+           location.resflags.register:=NR_B0;
+           location.resflags.flag:=F_NZ;
+          end
+        else
+         begin
+           location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
+           location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
+         end;
+
+        { emit the actual operation }
+        if cmpop then
+          begin
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register));
+            cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
+
+            if inv then
+              location.resflags.flag:=F_Z;
+          end
+        else
+          begin
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,right.location.register));
+            cg.maybe_check_for_fpu_exception(current_asmdata.CurrAsmList);
+          end;
+      end;
+
+
+    procedure TCPUAddNode.second_cmpfloat;
+      begin
+        second_addfloat;
+      end;
+
 begin
   caddnode:=tcpuaddnode;
 end.

+ 48 - 23
compiler/xtensa/ncpucnv.pas

@@ -30,29 +30,9 @@ interface
 
     type
        tcputypeconvnode = class(tcgtypeconvnode)
-         protected
-         //  function first_int_to_real: tnode;override;
-         //  function first_real_to_real: tnode; override;
-         { procedure second_int_to_int;override; }
-         { procedure second_string_to_string;override; }
-         { procedure second_cstring_to_pchar;override; }
-         { procedure second_string_to_chararray;override; }
-         { procedure second_array_to_pointer;override; }
-         // function first_int_to_real: tnode; override;
-         { procedure second_pointer_to_array;override; }
-         { procedure second_chararray_to_string;override; }
-         { procedure second_char_to_string;override; }
-         //  procedure second_int_to_real;override;
-         // procedure second_real_to_real;override;
-         { procedure second_cord_to_pointer;override; }
-         { procedure second_proc_to_procvar;override; }
-         { procedure second_bool_to_int;override; }
-           procedure second_int_to_bool;override;
-         { procedure second_load_smallset;override;  }
-         { procedure second_ansistring_to_pchar;override; }
-         { procedure second_pchar_to_string;override; }
-         { procedure second_class_to_intf;override; }
-         { procedure second_char_to_char;override; }
+       protected
+         function first_real_to_real: tnode;override;
+         procedure second_int_to_bool;override;
        end;
 
 implementation
@@ -70,6 +50,51 @@ implementation
                              tcputypeconvnode
 *****************************************************************************}
 
+    function tcputypeconvnode.first_real_to_real: tnode;
+      begin
+        if (FPUXTENSA_SINGLE in fpu_capabilities[current_settings.fputype]) and
+          not(FPUXTENSA_DOUBLE in fpu_capabilities[current_settings.fputype]) then
+          begin
+            case tfloatdef(left.resultdef).floattype of
+              s32real:
+                case tfloatdef(resultdef).floattype of
+                  s64real:
+                    result:=ctypeconvnode.create_explicit(ccallnode.createintern('float32_to_float64',ccallparanode.create(
+                      ctypeconvnode.create_internal(left,search_system_type('FLOAT32REC').typedef),nil)),resultdef);
+                  s32real:
+                    begin
+                      result:=left;
+                      left:=nil;
+                    end;
+                  else
+                    internalerror(200610151);
+                end;
+              s64real:
+                case tfloatdef(resultdef).floattype of
+                  s32real:
+                    result:=ctypeconvnode.create_explicit(ccallnode.createintern('float64_to_float32',ccallparanode.create(
+                      ctypeconvnode.create_internal(left,search_system_type('FLOAT64').typedef),nil)),resultdef);
+                  s64real:
+                    begin
+                      result:=left;
+                      left:=nil;
+                    end;
+                  else
+                    internalerror(200610152);
+                end;
+              else
+                internalerror(200610153);
+            end;
+            left:=nil;
+            firstpass(result);
+            exit;
+          end
+        else
+          Result := inherited first_real_to_real;
+      end;
+
+
+
     procedure tcputypeconvnode.second_int_to_bool;
       var
         hreg1, onereg: tregister;

+ 31 - 16
compiler/xtensa/ncpumat.pas

@@ -121,25 +121,40 @@ implementation
     procedure tcpuunaryminusnode.second_float;
       begin
         secondpass(left);
-        case current_settings.fputype of
-          fpu_soft:
-            begin
+        if (current_settings.fputype=fpu_soft) or (tfloatdef(left.resultdef).floattype<>s32real) or
+          not(FPUXTENSA_SINGLE in fpu_capabilities[current_settings.fputype]) then
+          begin
+            if not(left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
               hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
-              location:=left.location;
-              case location.size of
-                OS_32:
-                  cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
-                OS_64:
-                  cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
-              else
-                internalerror(2014033101);
-              end;
-            end
-          else
-            internalerror(2009112602);
-        end;
+            location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+            if location.size in [OS_64,OS_S64,OS_F64] then
+              begin
+                location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+                location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+              end
+            else
+              location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
+
+            case location.size of
+              OS_32:
+                cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),left.location.register,location.register);
+              OS_64:
+                cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),left.location.registerhi,location.registerhi);
+            else
+              internalerror(2014033101);
+            end;
+          end
+        else
+          begin
+            if not(left.location.loc in [LOC_CFPUREGISTER,LOC_FPUREGISTER]) then
+              hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,false);
+            location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
+            location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
+            current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_NEG_S,location.register,left.location.register));
+          end;
       end;
 
+
     procedure tcpushlshrnode.second_64bit;
       var
         v : TConstExprInt;

+ 8 - 1
packages/fcl-db/src/sqldb/odbc/odbcconn.pas

@@ -999,7 +999,14 @@ begin
       SQL_TINYINT:       begin FieldType:=ftSmallint;   FieldSize:=0; end;
       SQL_BIGINT:        begin FieldType:=ftLargeint;   FieldSize:=0; end;
       SQL_BINARY:        begin FieldType:=ftBytes;      FieldSize:=ColumnSize; end;
-      SQL_VARBINARY:     begin FieldType:=ftVarBytes;   FieldSize:=ColumnSize; end;
+      SQL_VARBINARY:
+      begin
+        FieldSize:=ColumnSize;
+        if FieldSize=BLOB_BUF_SIZE then // SQL_VARBINARY declared as VARBINARY(MAX) must be ftBlob - variable data size
+          FieldType:=ftBlob
+        else
+          FieldType:=ftVarBytes;
+      end;
       SQL_LONGVARBINARY: begin FieldType:=ftBlob;       FieldSize:=BLOB_BUF_SIZE; end; // is a blob
       SQL_TYPE_DATE:     begin FieldType:=ftDate;       FieldSize:=0; end;
       SQL_SS_TIME2,

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

@@ -27,7 +27,7 @@ Type
                     poNoConsole,poNewConsole,
                     poDefaultErrorMode,poNewProcessGroup,
                     poDebugProcess,poDebugOnlyThisProcess,
-                    poPassInput,porunidle);
+                    poPassInput,poRunIdle);
 
   TShowWindowOptions = (swoNone,swoHIDE,swoMaximize,swoMinimize,swoRestore,swoShow,
                         swoShowDefault,swoShowMaximized,swoShowMinimized,

+ 1 - 1
packages/fpmkunit/src/fpmkunit.pp

@@ -188,7 +188,7 @@ Const
   OSCPUSupported : array[TOS,TCpu] of boolean = (
     { os          none   i386    m68k  ppc    sparc  x86_64 arm    ppc64  avr    armeb  mips   mipsel mips64 mips64el jvm    i8086 aarch64 wasm   sparc64 riscv32 riscv64  xtensa }
     { none }    ( false, false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false, false, false,  false,  false,   false),
-    { linux }   ( false, true,  true,  true,  true,  true,  true,  true,  false, true , true , true , true , true ,   false, false, true , false, true ,  true ,  true,    false),
+    { linux }   ( false, true,  true,  true,  true,  true,  true,  true,  false, true , true , true , true , true ,   false, false, true , false, true ,  true ,  true,    true ),
     { go32v2 }  ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false, false, false,  false,  false,   false),
     { win32 }   ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false, false, false,  false,  false,   false),
     { os2 }     ( false, true,  false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false, false, false,  false,  false,   false),

+ 1 - 1
utils/fpcm/fpcmmain.pp

@@ -116,7 +116,7 @@ interface
       { This table is kept OS,Cpu because it is easier to maintain (PFV) }
       OSCpuPossible : array[TOS,TCpu] of boolean = (
         { os          i386    m68k  ppc    sparc  x86_64 arm    ppc64  avr    armeb  armel  mips   mipsel mips64 misp64el jvm    i8086  aarch64 wasm sparc64 riscv32 riscv64 xtensa z80 }
-        { linux }   ( true,  true,  true,  true,  true,  true,  true,  false, true,  false, true,  true,  false, false,   false, false, true,  false, true,  true,   true,   false, false),
+        { linux }   ( true,  true,  true,  true,  true,  true,  true,  false, true,  false, true,  true,  false, false,   false, false, true,  false, true,  true,   true,   true,  false),
         { go32v2 }  ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false, false, false, false,  false,  false, false),
         { win32 }   ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false, false, false, false,  false,  false, false),
         { os2 }     ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false, false, false, false,  false,  false, false),