Browse Source

* synchronized with trunk

git-svn-id: branches/wasm@46736 -
nickysn 4 years ago
parent
commit
d8a9bd4da0
45 changed files with 315 additions and 447 deletions
  1. 1 0
      .gitattributes
  2. 4 0
      compiler/ncal.pas
  3. 2 0
      compiler/nld.pas
  4. 51 24
      compiler/xtensa/cgcpu.pas
  5. 164 157
      compiler/xtensa/cpupara.pas
  6. 37 13
      compiler/xtensa/cpupi.pas
  7. 4 2
      compiler/xtensa/ncpuadd.pas
  8. 1 9
      tests/test/cg/tcalcla1.pp
  9. 1 6
      tests/test/cg/tcalcst1.pp
  10. 1 6
      tests/test/cg/tcalcst2.pp
  11. 1 7
      tests/test/cg/tcalcst3.pp
  12. 1 7
      tests/test/cg/tcalcst4.pp
  13. 1 7
      tests/test/cg/tcalcst5.pp
  14. 1 7
      tests/test/cg/tcalcst6.pp
  15. 1 7
      tests/test/cg/tcalcst7.pp
  16. 1 7
      tests/test/cg/tcalcst8.pp
  17. 15 0
      tests/test/cg/tcaldefs.inc
  18. 1 7
      tests/test/cg/tcalfun1.pp
  19. 1 7
      tests/test/cg/tcalfun2.pp
  20. 1 7
      tests/test/cg/tcalfun3.pp
  21. 1 7
      tests/test/cg/tcalfun4.pp
  22. 1 7
      tests/test/cg/tcalfun6.pp
  23. 1 7
      tests/test/cg/tcalfun7.pp
  24. 1 6
      tests/test/cg/tcalfun8.pp
  25. 1 6
      tests/test/cg/tcalobj1.pp
  26. 1 6
      tests/test/cg/tcalobj2.pp
  27. 1 6
      tests/test/cg/tcalobj3.pp
  28. 1 6
      tests/test/cg/tcalobj4.pp
  29. 1 6
      tests/test/cg/tcalobj6.pp
  30. 1 6
      tests/test/cg/tcalobj7.pp
  31. 1 7
      tests/test/cg/tcalval1.pp
  32. 1 7
      tests/test/cg/tcalval2.pp
  33. 1 7
      tests/test/cg/tcalval3.pp
  34. 1 7
      tests/test/cg/tcalval4.pp
  35. 1 7
      tests/test/cg/tcalval5.pp
  36. 1 7
      tests/test/cg/tcalval7.pp
  37. 1 7
      tests/test/cg/tcalval8.pp
  38. 1 7
      tests/test/cg/tcalvar1.pp
  39. 1 7
      tests/test/cg/tcalvar2.pp
  40. 1 7
      tests/test/cg/tcalvar3.pp
  41. 1 7
      tests/test/cg/tcalvar4.pp
  42. 1 7
      tests/test/cg/tcalvar5.pp
  43. 1 6
      tests/test/cg/tcalvar6.pp
  44. 1 7
      tests/test/cg/tcalvar7.pp
  45. 1 7
      tests/test/cg/tcalvar8.pp

+ 1 - 0
.gitattributes

@@ -13821,6 +13821,7 @@ tests/test/cg/tcalcst5.pp svneol=native#text/plain
 tests/test/cg/tcalcst6.pp svneol=native#text/plain
 tests/test/cg/tcalcst7.pp svneol=native#text/plain
 tests/test/cg/tcalcst8.pp svneol=native#text/plain
+tests/test/cg/tcaldefs.inc svneol=native#text/plain
 tests/test/cg/tcalext.pp svneol=native#text/plain
 tests/test/cg/tcalext3.pp svneol=native#text/plain
 tests/test/cg/tcalext4.pp svneol=native#text/plain

+ 4 - 0
compiler/ncal.pas

@@ -4446,6 +4446,10 @@ implementation
               not tabstractprocdef(right.resultdef).is_addressonly then
              maybe_load_in_temp(right);
 
+           { the return value might be stored on the current stack by allocating a temp. }
+           if not(paramanager.ret_in_param(procdefinition.returndef,procdefinition)) then
+             inc(current_procinfo.estimatedtempsize,procdefinition.returndef.size);
+
            { Create destination (temp or assignment-variable reuse) for function result if it not yet set }
            maybe_create_funcret_node;
 

+ 2 - 0
compiler/nld.pas

@@ -1253,6 +1253,8 @@ implementation
         if do_variant then
           tarraydef(resultdef).elementdef:=search_system_type('TVARREC').typedef;
         expectloc:=LOC_CREFERENCE;
+
+        inc(current_procinfo.estimatedtempsize,(tarraydef(resultdef).highrange+1)*tarraydef(resultdef).elementdef.size);
       end;
 
 

+ 51 - 24
compiler/xtensa/cgcpu.pas

@@ -80,6 +80,8 @@ interface
         procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
 
         procedure g_overflowcheck(list: TAsmList; const Loc:tlocation; def:tdef);override;
+
+        function create_data_entry(symbol: TAsmSymbol; offset: asizeint): TAsmLabel;
       end;
 
       tcg64fxtensa = class(tcg64f32)
@@ -314,11 +316,7 @@ implementation
           begin
             reference_reset(hr,4,[]);
 
-            current_asmdata.getjumplabel(l);
-            cg.a_label(current_procinfo.aktlocaldata,l);
-            current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(longint(a)));
-
-            hr.symbol:=l;
+            hr.symbol:=create_data_entry(nil,longint(a));
             list.concat(taicpu.op_reg_ref(A_L32R,reg,hr));
           end;
       end;
@@ -334,18 +332,11 @@ implementation
         if assigned(ref.symbol) or (ref.offset<-2048) or (ref.offset>2047) then
           begin
             reference_reset(tmpref,4,[]);
-            current_asmdata.getjumplabel(l);
-            cg.a_label(current_procinfo.aktlocaldata,l);
             tmpreg:=NR_NO;
 
-            if assigned(ref.symbol) then
-              current_procinfo.aktlocaldata.concat(tai_const.create_sym_offset(ref.symbol,ref.offset))
-            else if ref.offset<>0 then
-              current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
-
             { load consts entry }
             tmpreg:=getintregister(list,OS_INT);
-            tmpref.symbol:=l;
+            tmpref.symbol:=create_data_entry(ref.symbol,ref.offset);
             list.concat(taicpu.op_reg_ref(A_L32R,tmpreg,tmpref));
 
             if ref.base<>NR_NO then
@@ -708,31 +699,35 @@ implementation
                 begin
                   if stack_parameters and (pi_estimatestacksize in current_procinfo.flags) then
                     begin
+                      list.concat(tai_comment.Create(strpnew('Stackframe size was estimated before code generation due to stack parameters')));
+                      list.concat(tai_comment.Create(strpnew('  Calculated stackframe size: '+tostr(txtensaprocinfo(current_procinfo).stackframesize))));
+                      list.concat(tai_comment.Create(strpnew('  Max. outgoing parameter size: '+tostr(txtensaprocinfo(current_procinfo).maxpushedparasize))));
+                      list.concat(tai_comment.Create(strpnew('  End of last temporary location: '+tostr(tg.lasttemp))));
+                      list.concat(tai_comment.Create(strpnew('  Max. window rotation in bytes: '+tostr(txtensaprocinfo(current_procinfo).maxcall*4))));
+                      list.concat(tai_comment.Create(strpnew('  Required size after code generation: '+tostr(localsize))));
+
+                      { should never happen as localsize is derived from
+                        txtensaprocinfo(current_procinfo).stackframesize }
                       if localsize>txtensaprocinfo(current_procinfo).stackframesize then
-                        internalerror(2020031402)
-                      else
-                        localsize:=txtensaprocinfo(current_procinfo).stackframesize-registerarea;
+                        internalerror(2020031402);
+                      localsize:=txtensaprocinfo(current_procinfo).stackframesize;
                     end
                   else
                     begin
-                      { default spill area }
+                      localsize:=align(localsize,current_settings.alignment.localalignmax);
                       inc(localsize,4*4);
-                      { additional spill area? }
                       if pi_do_call in current_procinfo.flags then
                         inc(localsize,txtensaprocinfo(current_procinfo).maxcall*4);
-
-                      localsize:=align(localsize,current_settings.alignment.localalignmax);
                     end;
 
+                  if localsize<0 then
+                    Internalerror(2020083001);
                   if localsize>32760 then
                     begin
                       list.concat(taicpu.op_reg_const(A_ENTRY,NR_STACK_POINTER_REG,32));
 
                       reference_reset(ref,4,[]);
-                      current_asmdata.getjumplabel(l);
-                      cg.a_label(current_procinfo.aktlocaldata,l);
-                      current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(longint(localsize-32)));
-                      ref.symbol:=l;
+                      ref.symbol:=create_data_entry(nil,longint(localsize-32));
                       list.concat(taicpu.op_reg_ref(A_L32R,NR_A8,ref));
 
                       list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_A8,NR_STACK_POINTER_REG,NR_A8));
@@ -1176,6 +1171,38 @@ implementation
       end;
 
 
+    function tcgcpu.create_data_entry(symbol: TAsmSymbol;offset: asizeint): TAsmLabel;
+      var
+        hp: tai;
+      begin
+        hp:=tai(current_procinfo.aktlocaldata.first);
+        while assigned(hp) do
+          begin
+            if (hp.typ=ait_label) and assigned(hp.Next) and
+              (tai(hp.Next).typ=ait_const) and
+              (tai_const(hp.Next).consttype=aitconst_ptr) and
+              (tai_const(hp.Next).sym=symbol) and
+              (tai_const(hp.Next).endsym=nil) and
+              ((assigned(symbol) and (tai_const(hp.Next).symofs=offset)) or
+               (not(assigned(symbol)) and (tai_const(hp.Next).value=offset))
+              ) then
+              begin
+                Result:=tai_label(hp).labsym;
+                exit;
+              end;
+            hp:=tai(hp.Next);
+          end;
+
+        current_asmdata.getjumplabel(Result);
+        cg.a_label(current_procinfo.aktlocaldata,Result);
+
+        if assigned(symbol) then
+          current_procinfo.aktlocaldata.concat(tai_const.create_sym_offset(symbol,offset))
+        else
+          current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(offset));
+      end;
+
+
     procedure tcg64fxtensa.a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);
       var
         instr: taicpu;

+ 164 - 157
compiler/xtensa/cpupara.pas

@@ -48,6 +48,8 @@ unit cpupara;
          function create_paraloc_info_intern(p : tabstractprocdef; side : tcallercallee;
            paras : tparalist; var curintreg : tsuperregister;
            var cur_stack_offset : aword; varargsparas : boolean) : longint;
+         function create_paraloc1_info_intern(p: tabstractprocdef; side: tcallercallee; paradef: tdef; var loc: TCGPara; varspez: tvarspez; varoptions: tvaroptions;
+           var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas: boolean): longint;
        end;
 
   implementation
@@ -151,7 +153,7 @@ unit cpupara;
           recorddef :
             result:=(varspez = vs_const);
           arraydef:
-            result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
+            result:=((varspez = vs_const) and (tarraydef(def).highrange>=tarraydef(def).lowrange)) or
                              is_open_array(def) or
                              is_array_of_const(def) or
                              is_array_constructor(def);
@@ -203,6 +205,8 @@ unit cpupara;
       var
         paraloc : pcgparalocation;
         retcgsize  : tcgsize;
+        cur_stack_offset: aword;
+        curintreg: tsuperregister;
       begin
         if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then
           exit;
@@ -245,6 +249,15 @@ unit cpupara;
             else
               paraloc^.register:=NR_A3;
           end
+        else if (result.def.size>4) and (result.def.size<=16) then
+          begin
+            init_values(p,side,curintreg,cur_stack_offset);
+            create_paraloc1_info_intern(p,side,result.def,result,vs_value,[],curintreg,cur_stack_offset,false);
+
+            { check if everything is ok }
+            if result.location^.loc=LOC_INVALID then
+              Internalerror(2020082901);
+          end
         else
           begin
             paraloc^.loc:=LOC_REGISTER;
@@ -292,189 +305,183 @@ unit cpupara;
 
 
     function tcpuparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;
-
       var
         cur_stack_offset: aword;
         curintreg: tsuperregister;
       begin
         init_values(p,side,curintreg,cur_stack_offset);
 
-        result := create_paraloc_info_intern(p,side,p.paras,curintreg,cur_stack_offset,false);
+        result:=create_paraloc_info_intern(p,side,p.paras,curintreg,cur_stack_offset,false);
+        if result<cur_stack_offset then
+          Internalerror(2020083001);
 
         create_funcretloc_info(p,side);
       end;
 
 
-
-    function tcpuparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
+    function tcpuparamanager.create_paraloc1_info_intern(p : tabstractprocdef; side: tcallercallee; paradef:tdef;var loc : TCGPara;varspez : tvarspez;varoptions : tvaroptions;
       var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas: boolean):longint;
       var
-         stack_offset: longint;
-         paralen: aint;
-         nextintreg : tsuperregister;
-         locdef,
-         fdef,
-         paradef : tdef;
-         paraloc : pcgparalocation;
-         i  : integer;
-         hp : tparavarsym;
-         loc : tcgloc;
-         paracgsize: tcgsize;
-         firstparaloc: boolean;
-
+        paralen: aint;
+        locdef,
+        fdef : tdef;
+        paraloc : pcgparalocation;
+        paracgsize: tcgsize;
+        firstparaloc: boolean;
+        locpara: TCGLoc;
       begin
 {$ifdef extdebug}
          if po_explicitparaloc in p.procoptions then
            internalerror(200411141);
 {$endif extdebug}
+        loc.reset;
+        { currently only support C-style array of const }
+        if (p.proccalloption in cstylearrayofconst) and
+           is_array_of_const(paradef) then
+          begin
+            paraloc:=loc.add_location;
+            { hack: the paraloc must be valid, but is not actually used }
+            paraloc^.loc := LOC_REGISTER;
+            paraloc^.register := NR_A2;
+            paraloc^.size := OS_ADDR;
+            paraloc^.def:=voidpointertype;
+            result:=cur_stack_offset;
+            exit;
+          end;
 
-         result:=0;
-         nextintreg := curintreg;
-         stack_offset := cur_stack_offset;
-
-          for i:=0 to paras.count-1 do
-            begin
-              hp:=tparavarsym(paras[i]);
-              paradef := hp.vardef;
-
-              hp.paraloc[side].reset;
-              { currently only support C-style array of const }
-              if (p.proccalloption in cstylearrayofconst) and
-                 is_array_of_const(paradef) then
-                begin
-                  paraloc:=hp.paraloc[side].add_location;
-                  { hack: the paraloc must be valid, but is not actually used }
-                  paraloc^.loc := LOC_REGISTER;
-                  paraloc^.register := NR_A2;
-                  paraloc^.size := OS_ADDR;
-                  paraloc^.def:=voidpointertype;
-                  break;
-                end;
-
-              if push_addr_param(hp.varspez,paradef,p.proccalloption) then
-                begin
-                  paradef:=cpointerdef.getreusable_no_free(paradef);
-                  loc:=LOC_REGISTER;
-                  paracgsize := OS_ADDR;
-                  paralen := tcgsize2size[OS_ADDR];
-                end
-              else
-                begin
-                  if not is_special_array(paradef) then
-                    paralen := paradef.size
-                  else
-                    paralen := tcgsize2size[def_cgsize(paradef)];
-                  if (paradef.typ in [objectdef,arraydef,recorddef,setdef,stringdef]) and
-                     not is_special_array(paradef) and
-                     (hp.varspez in [vs_value,vs_const]) then
-                    paracgsize:=int_cgsize(paralen)
-                  else
-                    begin
-                      paracgsize:=def_cgsize(paradef);
-                      if (paracgsize=OS_NO) then
-                        begin
-                          paracgsize:=OS_ADDR;
-                          paralen := tcgsize2size[OS_ADDR];
-                          paradef:=voidpointertype;
-                        end;
-                    end;
-                end;
+        if push_addr_param(varspez,paradef,p.proccalloption) then
+          begin
+            paradef:=cpointerdef.getreusable_no_free(paradef);
+            locpara:=LOC_REGISTER;
+            paracgsize := OS_ADDR;
+            paralen := tcgsize2size[OS_ADDR];
+          end
+        else
+          begin
+            if not is_special_array(paradef) then
+              paralen := paradef.size
+            else
+              paralen := tcgsize2size[def_cgsize(paradef)];
+            if (paradef.typ in [objectdef,arraydef,recorddef,setdef,stringdef]) and
+               not is_special_array(paradef) and
+               (varspez in [vs_value,vs_const]) then
+              paracgsize:=int_cgsize(paralen)
+            else
+              begin
+                paracgsize:=def_cgsize(paradef);
+                if (paracgsize=OS_NO) then
+                  begin
+                    paracgsize:=OS_ADDR;
+                    paralen := tcgsize2size[OS_ADDR];
+                    paradef:=voidpointertype;
+                  end;
+              end;
+          end;
 
-              loc:=getparaloc(paradef);
+        locpara:=getparaloc(paradef);
 
-              if (loc=LOC_REGISTER) and ((maxintreg-nextintreg+1)*4<paradef.size) then
-                begin
-                  loc:=LOC_REFERENCE;
-                  nextintreg:=maxintreg+1;
-                end;
+        if (locpara=LOC_REGISTER) and ((maxintreg-curintreg+1)*4<paradef.size) then
+          begin
+            locpara:=LOC_REFERENCE;
+            curintreg:=maxintreg+1;
+          end;
 
-              hp.paraloc[side].alignment:=std_param_align;
-              hp.paraloc[side].size:=paracgsize;
-              hp.paraloc[side].intsize:=paralen;
-              hp.paraloc[side].def:=paradef;
-              if (loc=LOC_REGISTER) and (is_64bit(paradef)) and
-                 odd(nextintreg-RS_A2) then
-                inc(nextintreg);
-              if (paralen = 0) then
-                if (paradef.typ = recorddef) then
+        loc.alignment:=std_param_align;
+        loc.size:=paracgsize;
+        loc.intsize:=paralen;
+        loc.def:=paradef;
+        if (locpara=LOC_REGISTER) and (is_64bit(paradef)) and
+           odd(curintreg-RS_A2) then
+          inc(curintreg);
+        if (paralen = 0) then
+          if (paradef.typ = recorddef) then
+            begin
+              paraloc:=loc.add_location;
+              paraloc^.loc := LOC_VOID;
+            end
+          else
+            internalerror(2020031407);
+        locdef:=paradef;
+        firstparaloc:=true;
+        { can become < 0 for e.g. 3-byte records }
+        while paralen>0 do
+          begin
+            paraloc:=loc.add_location;
+            { In case of po_delphi_nested_cc, the parent frame pointer
+              is always passed on the stack. }
+            if (locpara=LOC_REGISTER) and
+               (curintreg<=maxintreg) and
+               (not(vo_is_parentfp in varoptions) or
+                not(po_delphi_nested_cc in p.procoptions)) then
+              begin
+                paraloc^.loc:=locpara;
+                { make sure we don't lose whether or not the type is signed }
+                if (paradef.typ<>orddef) then
                   begin
-                    paraloc:=hp.paraloc[side].add_location;
-                    paraloc^.loc := LOC_VOID;
+                    paracgsize:=int_cgsize(paralen);
+                    locdef:=get_paraloc_def(paradef,paralen,firstparaloc);
+                  end;
+                if (paracgsize in [OS_NO,OS_64,OS_S64,OS_128,OS_S128]) then
+                  begin
+                    paraloc^.size:=OS_INT;
+                    paraloc^.def:=u32inttype;
                   end
                 else
-                  internalerror(2020031407);
-              locdef:=paradef;
-              firstparaloc:=true;
-              { can become < 0 for e.g. 3-byte records }
-              while (paralen > 0) do
-                begin
-                  paraloc:=hp.paraloc[side].add_location;
-                  { In case of po_delphi_nested_cc, the parent frame pointer
-                    is always passed on the stack. }
-                  if (loc = LOC_REGISTER) and
-                     (nextintreg <= maxintreg) and
-                     (not(vo_is_parentfp in hp.varoptions) or
-                      not(po_delphi_nested_cc in p.procoptions)) then
-                    begin
-                      paraloc^.loc := loc;
-                      { make sure we don't lose whether or not the type is signed }
-                      if (paradef.typ<>orddef) then
-                        begin
-                          paracgsize:=int_cgsize(paralen);
-                          locdef:=get_paraloc_def(paradef,paralen,firstparaloc);
-                        end;
-                      if (paracgsize in [OS_NO,OS_64,OS_S64,OS_128,OS_S128]) then
-                        begin
-                          paraloc^.size:=OS_INT;
-                          paraloc^.def:=u32inttype;
-                        end
-                      else
-                        begin
-                          paraloc^.size:=paracgsize;
-                          paraloc^.def:=locdef;
-                        end;
-                      paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBNONE);
-                      inc(nextintreg);
-                      dec(paralen,tcgsize2size[paraloc^.size]);
-                    end
-                  else { LOC_REFERENCE }
-                    begin
-                       paraloc^.loc:=LOC_REFERENCE;
-                       case loc of
-                         LOC_REGISTER,
-                         LOC_REFERENCE:
-                           begin
-                             paraloc^.size:=int_cgsize(paralen);
-                             if paraloc^.size<>OS_NO then
-                               paraloc^.def:=cgsize_orddef(paraloc^.size)
-                             else
-                               paraloc^.def:=carraydef.getreusable_no_free(u8inttype,paralen);
-                           end;
-                         else
-                           internalerror(2020031405);
-                       end;
-                       if side = callerside then
-                         paraloc^.reference.index:=NR_STACK_POINTER_REG
+                  begin
+                    paraloc^.size:=paracgsize;
+                    paraloc^.def:=locdef;
+                  end;
+                paraloc^.register:=newreg(R_INTREGISTER,curintreg,R_SUBNONE);
+                inc(curintreg);
+                dec(paralen,tcgsize2size[paraloc^.size]);
+              end
+            else { LOC_REFERENCE }
+              begin
+                 paraloc^.loc:=LOC_REFERENCE;
+                 case locpara of
+                   LOC_REGISTER,
+                   LOC_REFERENCE:
+                     begin
+                       paraloc^.size:=int_cgsize(paralen);
+                       if paraloc^.size<>OS_NO then
+                         paraloc^.def:=cgsize_orddef(paraloc^.size)
                        else
-                         paraloc^.reference.index:=current_procinfo.framepointer;
-
-                       paraloc^.reference.offset:=stack_offset;
-
-                       inc(stack_offset,align(paralen,4));
-                       while (paralen > 0) and
-                             (nextintreg < maxintreg) do
-                          begin
-                            inc(nextintreg);
-                            dec(paralen,sizeof(pint));
-                          end;
-                       paralen := 0;
+                         paraloc^.def:=carraydef.getreusable_no_free(u8inttype,paralen);
+                     end;
+                   else
+                     internalerror(2020031405);
+                 end;
+                 if side = callerside then
+                   paraloc^.reference.index:=NR_STACK_POINTER_REG
+                 else
+                   paraloc^.reference.index:=current_procinfo.framepointer;
+
+                 paraloc^.reference.offset:=cur_stack_offset;
+
+                 inc(cur_stack_offset,align(paralen,4));
+                 while (paralen > 0) and
+                       (curintreg < maxintreg) do
+                    begin
+                      inc(curintreg);
+                      dec(paralen,sizeof(pint));
                     end;
-                  firstparaloc:=false;
-                end;
-            end;
-         curintreg:=nextintreg;
-         cur_stack_offset:=stack_offset;
-         result:=stack_offset;
+                 paralen := 0;
+              end;
+            firstparaloc:=false;
+          end;
+         result:=cur_stack_offset;
+      end;
+
+
+    function tcpuparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
+      var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas: boolean):longint;
+      var
+        i : integer;
+      begin
+        result:=0;
+        for i:=0 to paras.count-1 do
+          result:=create_paraloc1_info_intern(p,side,tparavarsym(paras[i]).vardef,tparavarsym(paras[i]).paraloc[side],tparavarsym(paras[i]).varspez,
+            tparavarsym(paras[i]).varoptions,curintreg,cur_stack_offset,false);
       end;
 
 

+ 37 - 13
compiler/xtensa/cpupi.pas

@@ -56,6 +56,7 @@ unit cpupi;
 
     uses
        globals,systems,
+       verbose,
        tgobj,
        symconst,symtype,symsym,symcpu,paramgr,
        cgutils,
@@ -75,7 +76,6 @@ unit cpupi;
             maxcall:=8;
 
             { we do not use a frame pointer for the windowed abi }
-            include(flags,pi_estimatestacksize);
             framepointer:=NR_STACK_POINTER_REG;
           end
         else
@@ -93,7 +93,7 @@ unit cpupi;
         localsize : aint;
         i : longint;
       begin
-        maxpushedparasize:=Align(maxpushedparasize,4);
+        maxpushedparasize:=Align(maxpushedparasize,target_info.alignment.localalignmax);
         tg.setfirsttemp(maxpushedparasize);
 
         if po_nostackframe in procdef.procoptions then
@@ -102,26 +102,40 @@ unit cpupi;
         { estimate stack frame size }
         if pi_estimatestacksize in flags then
           begin
-            stackframesize:=maxpushedparasize;
+            stackframesize:=align(maxpushedparasize,target_info.alignment.localalignmax);
             localsize:=0;
             for i:=0 to procdef.localst.SymList.Count-1 do
               if tsym(procdef.localst.SymList[i]).typ=localvarsym then
-                inc(localsize,tabstractnormalvarsym(procdef.localst.SymList[i]).getsize);
+                begin
+                  localsize:=align(localsize,tabstractnormalvarsym(procdef.localst.SymList[i]).vardef.alignment);
+                  inc(localsize,tabstractnormalvarsym(procdef.localst.SymList[i]).getsize);
+                end;
             inc(stackframesize,localsize);
+            stackframesize:=align(stackframesize,target_info.alignment.localalignmax);
 
             localsize:=0;
             for i:=0 to procdef.parast.SymList.Count-1 do
               if tsym(procdef.parast.SymList[i]).typ=paravarsym then
                 begin
                   if tabstractnormalvarsym(procdef.parast.SymList[i]).varspez in [vs_var,vs_out,vs_constref] then
-                    inc(localsize,4)
+                    begin
+                      localsize:=align(localsize,4);
+                      inc(localsize,4)
+                    end
                   else if is_open_string(tabstractnormalvarsym(procdef.parast.SymList[i]).vardef) then
                     inc(localsize,256)
                   else
-                    inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize);
+                    begin
+                      localsize:=align(localsize,tparavarsym(procdef.parast.SymList[i]).paraloc[calleeside].alignment);
+                      inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize);
+                    end;
                 end;
             inc(stackframesize,localsize);
 
+            stackframesize:=align(stackframesize,target_info.alignment.localalignmax);
+            inc(stackframesize,estimatedtempsize);
+
+            stackframesize:=align(stackframesize,4);
             if pi_needs_implicit_finally in flags then
               inc(stackframesize,40);
 
@@ -131,7 +145,12 @@ unit cpupi;
             if procdef.proctypeoption in [potype_constructor] then
               inc(stackframesize,40*2);
 
-            inc(stackframesize,estimatedtempsize);
+            { default spill area }
+            inc(stackframesize,4*4);
+
+            { additional spill area? }
+            if pi_do_call in current_procinfo.flags then
+              inc(stackframesize,maxcall*4);
 
             stackframesize:=Align(stackframesize,target_info.alignment.localalignmax);
           end;
@@ -140,16 +159,21 @@ unit cpupi;
 
     function txtensaprocinfo.calc_stackframe_size:longint;
       var
-         r : byte;
+         r, extra: byte;
          regs: tcpuregisterset;
       begin
         if pi_estimatestacksize in flags then
-          result:=stackframesize
-        else
           begin
-            maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
-            result:=Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+maxpushedparasize;
-          end;
+            if pi_do_call in current_procinfo.flags then
+              extra:=4*4+maxcall*4
+            else
+              extra:=0;
+            if Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+extra>stackframesize then
+              InternalError(2020082801);
+            result:=stackframesize
+          end
+        else
+          result:=Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+maxpushedparasize;
       end;
 
 

+ 4 - 2
compiler/xtensa/ncpuadd.pas

@@ -158,7 +158,7 @@ interface
 
         location_reset_jump(location,truelab,falselab);
 
-        hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
+        hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,cgsize_orddef(OS_INT),true);
                                             
         if is_signed(left.resultdef) then
           case nodetype of
@@ -187,7 +187,9 @@ interface
           cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_INT,cond,right.location.value,left.location.register,location.truelabel)
         else
           begin
-            force_reg_left_right(false,false);
+            if not(right.location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
+              hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,cgsize_orddef(OS_INT),true);
+
             if nf_swapped in flags then
                cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cond,left.location.register,right.location.register,location.truelabel)
              else

+ 1 - 9
tests/test/cg/tcalcla1.pp

@@ -24,15 +24,7 @@ program tcalcla1;
 {$mode objfpc}
 {$R+}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-  {$if defined(FPC_MM_LARGE) or defined(FPC_MM_HUGE)}
-    {$hugecode on}
-  {$endif}
-{$endif}
+{$i tcaldefs.inc}
 
  const
  { should be defined depending on CPU target }

+ 1 - 6
tests/test/cg/tcalcst1.pp

@@ -28,12 +28,7 @@ program tcalcst1;
   {$define tp}
 {$endif}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 6
tests/test/cg/tcalcst2.pp

@@ -28,12 +28,7 @@ program tcalcst2;
   {$define tp}
 {$endif}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalcst3.pp

@@ -28,13 +28,7 @@ program tcalcst3;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalcst4.pp

@@ -28,13 +28,7 @@ program tcalcst4;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalcst5.pp

@@ -29,13 +29,7 @@ program tcalcst5;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalcst6.pp

@@ -34,13 +34,7 @@ program tcalcst6;
   {$define safecall_is_cdecl}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalcst7.pp

@@ -28,13 +28,7 @@ program tcalcst7;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalcst8.pp

@@ -28,13 +28,7 @@ program tcalcst8;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 15 - 0
tests/test/cg/tcaldefs.inc

@@ -0,0 +1,15 @@
+{$ifdef freertos}
+  {$define cpusmall}
+{$endif freertos}
+{$ifdef embedded}
+  {$define cpusmall}
+{$endif embedded}
+{$ifdef cpu68k}
+  {$define cpusmall}
+{$endif}
+{$ifdef cpui8086}
+  {$define cpusmall}
+  {$if defined(FPC_MM_LARGE) or defined(FPC_MM_HUGE)}
+    {$hugecode on}
+  {$endif}
+{$endif}

+ 1 - 7
tests/test/cg/tcalfun1.pp

@@ -31,13 +31,7 @@
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
   { REAL should map to single or double }
   { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalfun2.pp

@@ -31,13 +31,7 @@
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
   { REAL should map to single or double }
   { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalfun3.pp

@@ -31,13 +31,7 @@
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
   { REAL should map to single or double }
   { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalfun4.pp

@@ -33,13 +33,7 @@
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
   { REAL should map to single or double }
   { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalfun6.pp

@@ -31,13 +31,7 @@
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
   { REAL should map to single or double }
   { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalfun7.pp

@@ -31,13 +31,7 @@
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
   { REAL should map to single or double }
   { so it is not checked, since single  }

+ 1 - 6
tests/test/cg/tcalfun8.pp

@@ -31,13 +31,8 @@
   {$define tp}
 {$endif}
 
+{$i tcaldefs.inc}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
 
   { REAL should map to single or double }
   { so it is not checked, since single  }

+ 1 - 6
tests/test/cg/tcalobj1.pp

@@ -20,12 +20,7 @@
 program tcalobj1;
 {$R+}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  const
  { should be defined depending on CPU target }

+ 1 - 6
tests/test/cg/tcalobj2.pp

@@ -20,12 +20,7 @@
 program tcalobj2;
 {$R+}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  const
  { should be defined depending on CPU target }

+ 1 - 6
tests/test/cg/tcalobj3.pp

@@ -20,12 +20,7 @@
 program tcalobj3;
 {$R+}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  const
  { should be defined depending on CPU target }

+ 1 - 6
tests/test/cg/tcalobj4.pp

@@ -22,12 +22,7 @@
 program tcalobj4;
 {$R+}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  const
  { should be defined depending on CPU target }

+ 1 - 6
tests/test/cg/tcalobj6.pp

@@ -20,12 +20,7 @@
 program tcalobj6;
 {$R+}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  const
  { should be defined depending on CPU target }

+ 1 - 6
tests/test/cg/tcalobj7.pp

@@ -20,12 +20,7 @@
 program tcalobj7;
 {$R+}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  const
  { should be defined depending on CPU target }

+ 1 - 7
tests/test/cg/tcalval1.pp

@@ -30,13 +30,7 @@ program tcalval1;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalval2.pp

@@ -28,13 +28,7 @@ program tcalval2;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalval3.pp

@@ -30,13 +30,7 @@ program tcalval3;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalval4.pp

@@ -30,13 +30,7 @@ program tcalval4;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalval5.pp

@@ -32,13 +32,7 @@ program tcalval5;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalval7.pp

@@ -30,13 +30,7 @@ program tcalval7;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalval8.pp

@@ -30,13 +30,7 @@ program tcalval8;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalvar1.pp

@@ -28,13 +28,7 @@ program tcalvar1;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalvar2.pp

@@ -28,13 +28,7 @@ program tcalvar2;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalvar3.pp

@@ -28,13 +28,7 @@ program tcalvar3;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalvar4.pp

@@ -30,13 +30,7 @@ program tcalvar4;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalvar5.pp

@@ -32,13 +32,7 @@ program tcalvar5;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 6
tests/test/cg/tcalvar6.pp

@@ -36,12 +36,7 @@ program tcalvar6;
   {$define safecall_is_cdecl}
 {$endif}
 
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalvar7.pp

@@ -30,13 +30,7 @@ program tcalvar7;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }

+ 1 - 7
tests/test/cg/tcalvar8.pp

@@ -30,13 +30,7 @@ program tcalvar8;
   {$define tp}
 {$endif}
 
-
-{$ifdef cpu68k}
-  {$define cpusmall}
-{$endif}
-{$ifdef cpui8086}
-  {$define cpusmall}
-{$endif}
+{$i tcaldefs.inc}
 
  { REAL should map to single or double }
  { so it is not checked, since single  }