Răsfoiți Sursa

+ fpc_eh_return_data_regno() intrinsic to get the return register numbers
for the Dwarf EH exception handler result

git-svn-id: branches/debug_eh@40070 -

Jonas Maebe 6 ani în urmă
părinte
comite
8555ec1438

+ 10 - 0
compiler/aarch64/cpubase.pas

@@ -328,6 +328,7 @@ unit cpubase;
 
 
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
 
 
     function is_shifter_const(d: aint; size: tcgsize): boolean;
     function is_shifter_const(d: aint; size: tcgsize): boolean;
 
 
@@ -606,4 +607,13 @@ unit cpubase;
           end;
           end;
       end;
       end;
 
 
+
+  function eh_return_data_regno(nr: longint): longint;
+    begin
+      if (nr>=0) and (nr<2) then
+        result:=nr
+      else
+        result:=-1;
+    end;
+
 end.
 end.

+ 10 - 0
compiler/arm/cpubase.pas

@@ -380,6 +380,8 @@ unit cpubase;
     function is_continuous_mask(d : aint;var lsb, width: byte) : boolean;
     function is_continuous_mask(d : aint;var lsb, width: byte) : boolean;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
+
 
 
     function IsIT(op: TAsmOp) : boolean;
     function IsIT(op: TAsmOp) : boolean;
     function GetITLevels(op: TAsmOp) : longint;
     function GetITLevels(op: TAsmOp) : longint;
@@ -660,6 +662,14 @@ unit cpubase;
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];
       end;
       end;
 
 
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        if (nr>=0) and (nr<2) then
+          result:=nr
+        else
+          result:=-1;
+      end;
+
       { Low part of 64bit return value }
       { Low part of 64bit return value }
     function NR_FUNCTION_RESULT64_LOW_REG: tregister; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function NR_FUNCTION_RESULT64_LOW_REG: tregister; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     begin
     begin

+ 8 - 0
compiler/avr/cpubase.pas

@@ -305,6 +305,8 @@ unit cpubase;
 
 
     function dwarf_reg(r:tregister):byte;
     function dwarf_reg(r:tregister):byte;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
+
 
 
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
@@ -432,6 +434,12 @@ unit cpubase;
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];
       end;
       end;
 
 
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        result:=-1;
+      end;
+
+
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
     function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
       begin
         is_calljmp:= o in call_jmp_instructions;
         is_calljmp:= o in call_jmp_instructions;

+ 1 - 0
compiler/compinnr.pas

@@ -129,6 +129,7 @@ type
      in_hi_qword         = 107,
      in_hi_qword         = 107,
      in_const_swap_qword = 108,
      in_const_swap_qword = 108,
      in_prefetch_var     = 109,
      in_prefetch_var     = 109,
+     in_const_eh_return_data_regno = 110,
 
 
 { FPU functions }
 { FPU functions }
      in_trunc_real       = 120,
      in_trunc_real       = 120,

+ 6 - 0
compiler/jvm/cpubase.pas

@@ -277,6 +277,8 @@ uses
     function std_regname(r:Tregister):string;
     function std_regname(r:Tregister):string;
     function findreg_by_number(r:Tregister):tregisterindex;
     function findreg_by_number(r:Tregister):tregisterindex;
 
 
+    function eh_return_data_regno(nr: longint): longint;
+
     { since we don't use tasmconds, don't call this routine
     { since we don't use tasmconds, don't call this routine
       (it will internalerror). We need it anyway to get aoptobj
       (it will internalerror). We need it anyway to get aoptobj
       to compile (but it won't execute it).
       to compile (but it won't execute it).
@@ -340,6 +342,10 @@ uses
           result:=generic_regname(r);
           result:=generic_regname(r);
       end;
       end;
 
 
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        result:=-1;
+      end;
 
 
     function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
       begin

+ 6 - 0
compiler/m68k/cpubase.pas

@@ -370,6 +370,7 @@ unit cpubase;
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
 
 
     function isvalue8bit(val: tcgint): boolean;
     function isvalue8bit(val: tcgint): boolean;
     function isvalue16bit(val: tcgint): boolean;
     function isvalue16bit(val: tcgint): boolean;
@@ -600,6 +601,11 @@ implementation
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];
       end;
       end;
 
 
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        result:=-1;
+      end;
+
     { returns true if given value fits to an 8bit signed integer }
     { returns true if given value fits to an 8bit signed integer }
     function isvalue8bit(val: tcgint): boolean;
     function isvalue8bit(val: tcgint): boolean;
       begin
       begin

+ 11 - 0
compiler/mips/cpubase.pas

@@ -271,6 +271,7 @@ unit cpubase;
     function std_regname(r:Tregister):string;
     function std_regname(r:Tregister):string;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
 
 
   implementation
   implementation
 
 
@@ -417,5 +418,15 @@ unit cpubase;
         end;
         end;
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];
       end;
       end;
+
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        if (nr>=0) and (nr<2) then
+          result:=nr+4
+        else
+          result:=-1;
+      end;
+
+
 begin
 begin
 end.
 end.

+ 9 - 2
compiler/ninl.pas

@@ -126,7 +126,7 @@ implementation
       verbose,globals,systems,constexp,
       verbose,globals,systems,constexp,
       globtype,cutils,cclasses,fmodule,
       globtype,cutils,cclasses,fmodule,
       symconst,symdef,symsym,symcpu,symtable,paramgr,defcmp,defutil,symbase,
       symconst,symdef,symsym,symcpu,symtable,paramgr,defcmp,defutil,symbase,
-      cpuinfo,
+      cpuinfo,cpubase,
       pass_1,
       pass_1,
       ncal,ncon,ncnv,nadd,nld,nbas,nflw,nmem,nmat,nutils,
       ncal,ncon,ncnv,nadd,nld,nbas,nflw,nmem,nmat,nutils,
       nobjc,objcdef,
       nobjc,objcdef,
@@ -2294,7 +2294,14 @@ implementation
 {$else}
 {$else}
                      hp:=cpointerconstnode.create((vl2.uvalue shl 4)+vl.uvalue,voidpointertype);
                      hp:=cpointerconstnode.create((vl2.uvalue shl 4)+vl.uvalue,voidpointertype);
 {$endif}
 {$endif}
-                   end
+                   end;
+                 in_const_eh_return_data_regno:
+                   begin
+                     vl:=eh_return_data_regno(vl.svalue);
+                     if vl=-1 then
+                       CGMessagePos(left.fileinfo,type_e_range_check_error_bounds);
+                     result:=genintconstnode(vl);
+                   end;
                  else
                  else
                    internalerror(88);
                    internalerror(88);
                end;
                end;

+ 9 - 0
compiler/pexpr.pas

@@ -916,6 +916,15 @@ implementation
             begin
             begin
               statement_syssym:=inline_insert;
               statement_syssym:=inline_insert;
             end;
             end;
+          in_const_eh_return_data_regno:
+            begin
+              consume(_LKLAMMER);
+              in_args:=true;
+              p1:=comp_expr([ef_accept_equal]);
+              p2:=geninlinenode(l,true,p1);
+              consume(_RKLAMMER);
+              statement_syssym:=p2;
+            end;
           else
           else
             internalerror(15);
             internalerror(15);
 
 

+ 10 - 0
compiler/powerpc/cpubase.pas

@@ -398,6 +398,7 @@ uses
     function conditions_equal(const c1, c2: TAsmCond): boolean;
     function conditions_equal(const c1, c2: TAsmCond): boolean;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
 
 
 implementation
 implementation
 
 
@@ -575,4 +576,13 @@ implementation
       begin
       begin
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];
       end;
       end;
+
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        if (nr>=0) and (nr<2) then
+          result:=nr+3
+        else
+          result:=-1;
+      end;
+
 end.
 end.

+ 13 - 4
compiler/powerpc64/cpubase.pas

@@ -398,6 +398,7 @@ function inverse_cond(const c: TAsmCond): Tasmcond;
 function conditions_equal(const c1, c2: TAsmCond): boolean;
 function conditions_equal(const c1, c2: TAsmCond): boolean;
 function dwarf_reg(r:tregister):shortint;
 function dwarf_reg(r:tregister):shortint;
 function dwarf_reg_no_error(r:tregister):shortint;
 function dwarf_reg_no_error(r:tregister):shortint;
+function eh_return_data_regno(nr: longint): longint;
 
 
 implementation
 implementation
 
 
@@ -564,10 +565,18 @@ begin
     internalerror(200603251);
     internalerror(200603251);
 end;
 end;
 
 
-    function dwarf_reg_no_error(r:tregister):shortint;
-      begin
-        result:=regdwarf_table[findreg_by_number(r)];
-      end;
+function dwarf_reg_no_error(r:tregister):shortint;
+  begin
+    result:=regdwarf_table[findreg_by_number(r)];
+  end;
+
+function eh_return_data_regno(nr: longint): longint;
+begin
+  if (nr>=0) and (nr<2) then
+    result:=nr+3
+  else
+    result:=-1;
+end;
 
 
 end.
 end.
 
 

+ 1 - 0
compiler/psystem.pas

@@ -110,6 +110,7 @@ implementation
         systemunit.insert(csyssym.create('Insert',in_insert_x_y_z));
         systemunit.insert(csyssym.create('Insert',in_insert_x_y_z));
         systemunit.insert(csyssym.create('Delete',in_delete_x_y_z));
         systemunit.insert(csyssym.create('Delete',in_delete_x_y_z));
         systemunit.insert(csyssym.create('GetTypeKind',in_gettypekind_x));
         systemunit.insert(csyssym.create('GetTypeKind',in_gettypekind_x));
+        systemunit.insert(csyssym.create('fpc_eh_return_data_regno', in_const_eh_return_data_regno));
         systemunit.insert(cconstsym.create_ord('False',constord,0,pasbool1type));
         systemunit.insert(cconstsym.create_ord('False',constord,0,pasbool1type));
         systemunit.insert(cconstsym.create_ord('True',constord,1,pasbool1type));
         systemunit.insert(cconstsym.create_ord('True',constord,1,pasbool1type));
       end;
       end;

+ 9 - 0
compiler/riscv32/cpubase.pas

@@ -330,6 +330,7 @@ uses
     function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
 
 
     function conditions_equal(const c1,c2: TAsmCond): boolean;
     function conditions_equal(const c1,c2: TAsmCond): boolean;
 
 
@@ -444,6 +445,14 @@ implementation
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];
       end;
       end;
 
 
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        if (nr>=0) and (nr<4) then
+          result:=nr+10
+        else
+          result:=-1;
+      end;
+
     function conditions_equal(const c1, c2: TAsmCond): boolean;
     function conditions_equal(const c1, c2: TAsmCond): boolean;
       begin
       begin
         result:=c1=c2;
         result:=c1=c2;

+ 9 - 0
compiler/riscv64/cpubase.pas

@@ -345,6 +345,7 @@ const
     function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
 
 
     function conditions_equal(const c1,c2: TAsmCond): boolean;
     function conditions_equal(const c1,c2: TAsmCond): boolean;
 
 
@@ -459,6 +460,14 @@ implementation
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];
       end;
       end;
 
 
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        if (nr>=0) and (nr<4) then
+          result:=nr+10
+        else
+          result:=-1;
+      end;
+
     function conditions_equal(const c1, c2: TAsmCond): boolean;
     function conditions_equal(const c1, c2: TAsmCond): boolean;
       begin
       begin
         result:=c1=c2;
         result:=c1=c2;

+ 10 - 1
compiler/sparcgen/cpubase.pas

@@ -345,7 +345,7 @@ uses
     function findreg_by_number(r:Tregister):tregisterindex;
     function findreg_by_number(r:Tregister):tregisterindex;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
-
+    function eh_return_data_regno(nr: longint): longint;
 
 
 implementation
 implementation
 
 
@@ -536,6 +536,15 @@ implementation
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];
       end;
       end;
 
 
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+        if (nr>=0) and (nr<2) then
+          result:=nr+24
+        else
+          result:=-1;
+      end;
+
+
     procedure TResFlags.Init(r : TRegister; f : TSparcFlags);
     procedure TResFlags.Init(r : TRegister; f : TSparcFlags);
       begin
       begin
         FlagReg:=r;
         FlagReg:=r;

+ 12 - 0
compiler/x86/cpubase.pas

@@ -336,6 +336,7 @@ topsize2memsize: array[topsize] of integer =
     function std_regname(r:Tregister):string;
     function std_regname(r:Tregister):string;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
+    function eh_return_data_regno(nr: longint): longint;
 
 
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     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 conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
@@ -648,6 +649,17 @@ implementation
       end;
       end;
 
 
 
 
+    function eh_return_data_regno(nr: longint): longint;
+      begin
+         case nr of
+           0: result:=0;
+           1: result:=2;
+           else
+             result:=-1;
+         end;
+      end;
+
+
     function segment_regs_equal(r1, r2: tregister): boolean;
     function segment_regs_equal(r1, r2: tregister): boolean;
       begin
       begin
         if not is_segment_reg(r1) or not is_segment_reg(r2) then
         if not is_segment_reg(r1) or not is_segment_reg(r2) then

+ 1 - 0
rtl/inc/innr.inc

@@ -117,6 +117,7 @@ const
    fpc_in_hi_qword         = 107;
    fpc_in_hi_qword         = 107;
    fpc_in_const_swap_qword = 108;
    fpc_in_const_swap_qword = 108;
    fpc_in_prefetch_var     = 109;
    fpc_in_prefetch_var     = 109;
+   fpc_in_const_eh_return_data_regno = 110;
 
 
 { FPU functions }
 { FPU functions }
    fpc_in_trunc_real       = 120;
    fpc_in_trunc_real       = 120;

+ 1 - 0
rtl/inc/system.fpd

@@ -42,6 +42,7 @@ Procedure Dispose (P : TypedPointer; Des : TProcedure);
 Procedure Exclude (Var S : TSetType; E : TSetElement);
 Procedure Exclude (Var S : TSetType; E : TSetElement);
 Procedure Exit(Const X : TAnyType);
 Procedure Exit(Const X : TAnyType);
 Procedure Exit;
 Procedure Exit;
+Function FPC_EH_Return_Data_Regno(Nr: Longint): Longint;
 Function High (Arg: TypeOrVariable) : TOrdinal;
 Function High (Arg: TypeOrVariable) : TOrdinal;
 Procedure Inc (Var X : TOrdinal);
 Procedure Inc (Var X : TOrdinal);
 Procedure Inc (Var X : TOrdinal; Increment : TOrdinal);
 Procedure Inc (Var X : TOrdinal; Increment : TOrdinal);