Ver código fonte

* patch by Christo Crause: support call0 abi in entry/exit code, part of #37242

git-svn-id: trunk@45685 -
florian 5 anos atrás
pai
commit
caee96399e
1 arquivos alterados com 86 adições e 4 exclusões
  1. 86 4
      compiler/xtensa/cgcpu.pas

+ 86 - 4
compiler/xtensa/cgcpu.pas

@@ -140,9 +140,15 @@ implementation
     procedure tcgcpu.init_register_allocators;
       begin
         inherited init_register_allocators;
-        rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
-            [RS_A2,RS_A3,RS_A4,RS_A5,RS_A6,RS_A7,RS_A8,RS_A9,
-             RS_A10,RS_A11,RS_A12,RS_A13,RS_A14,RS_A15],first_int_imreg,[]);
+        if target_info.abi = abi_xtensa_call0 then
+          rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
+              [RS_A2,RS_A3,RS_A4,RS_A5,RS_A6,RS_A7,{RS_A8,}RS_A9,
+               RS_A10,RS_A11,RS_A12,RS_A13,RS_A14{,RS_A15}],first_int_imreg,[])
+        else
+          rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
+              [RS_A2,RS_A3,RS_A4,RS_A5,RS_A6,RS_A7,RS_A8,RS_A9,
+               RS_A10,RS_A11,RS_A12,RS_A13,RS_A14,RS_A15],first_int_imreg,[]);
+
         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,RS_F8,RS_F9,
              RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15],first_fpu_imreg,[]);
@@ -737,12 +743,88 @@ implementation
 
     procedure tcgcpu.g_proc_exit(list : TAsmList; parasize : longint;
      nostackframe : boolean);
+      var
+         ref : treference;
+         r : byte;
+         regs : tcpuregisterset;
+         stackmisalignment : pint;
+         regoffset : LongInt;
+         stack_parameters : Boolean;
+         registerarea : PtrInt;
+         l : TAsmLabel;
+         LocalSize: longint;
       begin
         case target_info.abi of
           abi_xtensa_windowed:
             list.Concat(taicpu.op_none(A_RETW));
           abi_xtensa_call0:
-            list.Concat(taicpu.op_none(A_RET));
+            begin
+              if not(nostackframe) then
+                begin
+                  LocalSize:=current_procinfo.calc_stackframe_size;
+                  LocalSize:=align(LocalSize,4);
+                  stack_parameters:=current_procinfo.procdef.stack_tainting_parameter(calleeside);
+                  registerarea:=0;
+                  regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
+                  if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+                    Include(regs,RS_A15);
+                  if pi_do_call in current_procinfo.flags then
+                    Include(regs,RS_A0);
+                  if regs<>[] then
+                     begin
+                       for r:=RS_A0 to RS_A15 do
+                         if r in regs then
+                           inc(registerarea,4);
+                     end;
+                  inc(localsize,registerarea);
+
+                  if LocalSize<>0 then
+                    begin
+                      localsize:=align(localsize,current_settings.alignment.localalignmax);
+                      // Determine reference mode required to access stack
+                      reference_reset(ref,4,[]);
+                      ref.base:=NR_STACK_POINTER_REG;
+                      ref.offset:=localsize;
+                      if ref.offset>1024 then
+                        begin
+                          if ref.offset<=1024+32512 then
+                            begin
+                              // allocation done in proc_entry
+                              //list.concat(taicpu.op_reg_reg_const(A_ADDMI,NR_A8,NR_STACK_POINTER_REG,ref.offset and $fffffc00));
+                              ref.offset:=ref.offset and $3ff;
+                              ref.base:=NR_A8;
+                            end
+                          else
+                            { fix me! }
+                            Internalerror(2020031101);
+                        end;
+
+                      // restore a15 if used
+                      if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
+                        begin
+                          dec(ref.offset,4);
+                          list.concat(taicpu.op_reg_ref(A_L32I,NR_A15,ref));
+                          a_reg_dealloc(list,NR_FRAME_POINTER_REG);
+                        end;
+
+                      // restore rest of registers
+                      if regs<>[] then
+                        begin
+                          for r:=RS_A14 downto RS_A0 do
+                            if r in regs then
+                              begin
+                                dec(ref.offset,4);
+                                list.concat(taicpu.op_reg_ref(A_L32I,newreg(R_INTREGISTER,r,R_SUBWHOLE),ref));
+                              end;
+                        end;
+
+                      // restore stack pointer
+                      list.concat(taicpu.op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,localsize));
+                      a_reg_dealloc(list,NR_STACK_POINTER_REG);
+                    end;
+                  end;
+              list.Concat(taicpu.op_none(A_RET));
+            end
           else
             Internalerror(2020031403);
         end;