From 8555ec1438b674ddb8f1df33e314b0f5ff1dbfd2 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sun, 28 Oct 2018 18:16:38 +0000 Subject: [PATCH] + 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 - --- compiler/aarch64/cpubase.pas | 10 ++++++++++ compiler/arm/cpubase.pas | 10 ++++++++++ compiler/avr/cpubase.pas | 8 ++++++++ compiler/compinnr.pas | 1 + compiler/jvm/cpubase.pas | 6 ++++++ compiler/m68k/cpubase.pas | 6 ++++++ compiler/mips/cpubase.pas | 11 +++++++++++ compiler/ninl.pas | 11 +++++++++-- compiler/pexpr.pas | 9 +++++++++ compiler/powerpc/cpubase.pas | 10 ++++++++++ compiler/powerpc64/cpubase.pas | 17 +++++++++++++---- compiler/psystem.pas | 1 + compiler/riscv32/cpubase.pas | 9 +++++++++ compiler/riscv64/cpubase.pas | 9 +++++++++ compiler/sparcgen/cpubase.pas | 11 ++++++++++- compiler/x86/cpubase.pas | 12 ++++++++++++ rtl/inc/innr.inc | 1 + rtl/inc/system.fpd | 1 + 18 files changed, 136 insertions(+), 7 deletions(-) diff --git a/compiler/aarch64/cpubase.pas b/compiler/aarch64/cpubase.pas index dc71039dff..cf6dcaba7f 100644 --- a/compiler/aarch64/cpubase.pas +++ b/compiler/aarch64/cpubase.pas @@ -328,6 +328,7 @@ unit cpubase; function dwarf_reg(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; @@ -606,4 +607,13 @@ unit cpubase; 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. diff --git a/compiler/arm/cpubase.pas b/compiler/arm/cpubase.pas index 105f2ddb0a..03a3a48bf0 100644 --- a/compiler/arm/cpubase.pas +++ b/compiler/arm/cpubase.pas @@ -380,6 +380,8 @@ unit cpubase; function is_continuous_mask(d : aint;var lsb, width: byte) : boolean; function dwarf_reg(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 GetITLevels(op: TAsmOp) : longint; @@ -660,6 +662,14 @@ unit cpubase; 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 + else + result:=-1; + end; + { Low part of 64bit return value } function NR_FUNCTION_RESULT64_LOW_REG: tregister; {$ifdef USEINLINE}inline;{$endif USEINLINE} begin diff --git a/compiler/avr/cpubase.pas b/compiler/avr/cpubase.pas index 1e8d776bea..91d356d5e2 100644 --- a/compiler/avr/cpubase.pas +++ b/compiler/avr/cpubase.pas @@ -305,6 +305,8 @@ unit cpubase; function dwarf_reg(r:tregister):byte; 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} @@ -432,6 +434,12 @@ unit cpubase; result:=regdwarf_table[findreg_by_number(r)]; end; + function eh_return_data_regno(nr: longint): longint; + begin + result:=-1; + end; + + function is_calljmp(o:tasmop):boolean;{$ifdef USEINLINE}inline;{$endif USEINLINE} begin is_calljmp:= o in call_jmp_instructions; diff --git a/compiler/compinnr.pas b/compiler/compinnr.pas index cda8a0fafd..183c767a91 100644 --- a/compiler/compinnr.pas +++ b/compiler/compinnr.pas @@ -129,6 +129,7 @@ type in_hi_qword = 107, in_const_swap_qword = 108, in_prefetch_var = 109, + in_const_eh_return_data_regno = 110, { FPU functions } in_trunc_real = 120, diff --git a/compiler/jvm/cpubase.pas b/compiler/jvm/cpubase.pas index e880bf76a7..4de0882c24 100644 --- a/compiler/jvm/cpubase.pas +++ b/compiler/jvm/cpubase.pas @@ -277,6 +277,8 @@ uses function std_regname(r:Tregister):string; 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 (it will internalerror). We need it anyway to get aoptobj to compile (but it won't execute it). @@ -340,6 +342,10 @@ uses result:=generic_regname(r); 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} begin diff --git a/compiler/m68k/cpubase.pas b/compiler/m68k/cpubase.pas index 1e33be9975..c0640b9698 100644 --- a/compiler/m68k/cpubase.pas +++ b/compiler/m68k/cpubase.pas @@ -370,6 +370,7 @@ unit cpubase; function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE} function dwarf_reg(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 isvalue16bit(val: tcgint): boolean; @@ -600,6 +601,11 @@ implementation result:=regdwarf_table[findreg_by_number(r)]; end; + function eh_return_data_regno(nr: longint): longint; + begin + result:=-1; + end; + { returns true if given value fits to an 8bit signed integer } function isvalue8bit(val: tcgint): boolean; begin diff --git a/compiler/mips/cpubase.pas b/compiler/mips/cpubase.pas index a9be2f8b91..578af51d0f 100644 --- a/compiler/mips/cpubase.pas +++ b/compiler/mips/cpubase.pas @@ -271,6 +271,7 @@ unit cpubase; function std_regname(r:Tregister):string; function dwarf_reg(r:tregister):shortint; function dwarf_reg_no_error(r:tregister):shortint; + function eh_return_data_regno(nr: longint): longint; implementation @@ -417,5 +418,15 @@ unit cpubase; end; 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+4 + else + result:=-1; + end; + + begin end. diff --git a/compiler/ninl.pas b/compiler/ninl.pas index 9d963b6f1e..6c245e460d 100644 --- a/compiler/ninl.pas +++ b/compiler/ninl.pas @@ -126,7 +126,7 @@ implementation verbose,globals,systems,constexp, globtype,cutils,cclasses,fmodule, symconst,symdef,symsym,symcpu,symtable,paramgr,defcmp,defutil,symbase, - cpuinfo, + cpuinfo,cpubase, pass_1, ncal,ncon,ncnv,nadd,nld,nbas,nflw,nmem,nmat,nutils, nobjc,objcdef, @@ -2294,7 +2294,14 @@ implementation {$else} hp:=cpointerconstnode.create((vl2.uvalue shl 4)+vl.uvalue,voidpointertype); {$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 internalerror(88); end; diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas index 861a5c894c..34db98327e 100644 --- a/compiler/pexpr.pas +++ b/compiler/pexpr.pas @@ -916,6 +916,15 @@ implementation begin statement_syssym:=inline_insert; 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 internalerror(15); diff --git a/compiler/powerpc/cpubase.pas b/compiler/powerpc/cpubase.pas index 1861c9e8f4..43687af816 100644 --- a/compiler/powerpc/cpubase.pas +++ b/compiler/powerpc/cpubase.pas @@ -398,6 +398,7 @@ uses function conditions_equal(const c1, c2: TAsmCond): boolean; function dwarf_reg(r:tregister):shortint; function dwarf_reg_no_error(r:tregister):shortint; + function eh_return_data_regno(nr: longint): longint; implementation @@ -575,4 +576,13 @@ implementation 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. diff --git a/compiler/powerpc64/cpubase.pas b/compiler/powerpc64/cpubase.pas index e1353aedcb..732c608306 100644 --- a/compiler/powerpc64/cpubase.pas +++ b/compiler/powerpc64/cpubase.pas @@ -398,6 +398,7 @@ function inverse_cond(const c: TAsmCond): Tasmcond; function conditions_equal(const c1, c2: TAsmCond): boolean; function dwarf_reg(r:tregister):shortint; function dwarf_reg_no_error(r:tregister):shortint; +function eh_return_data_regno(nr: longint): longint; implementation @@ -564,10 +565,18 @@ begin internalerror(200603251); 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. diff --git a/compiler/psystem.pas b/compiler/psystem.pas index 650bb7121d..397bd42a60 100644 --- a/compiler/psystem.pas +++ b/compiler/psystem.pas @@ -110,6 +110,7 @@ implementation systemunit.insert(csyssym.create('Insert',in_insert_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('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('True',constord,1,pasbool1type)); end; diff --git a/compiler/riscv32/cpubase.pas b/compiler/riscv32/cpubase.pas index ce791de4ce..257580bc80 100644 --- a/compiler/riscv32/cpubase.pas +++ b/compiler/riscv32/cpubase.pas @@ -330,6 +330,7 @@ uses function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE} function dwarf_reg(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; @@ -444,6 +445,14 @@ implementation result:=regdwarf_table[findreg_by_number(r)]; 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; begin result:=c1=c2; diff --git a/compiler/riscv64/cpubase.pas b/compiler/riscv64/cpubase.pas index 60cd897aa4..5ee8b1dc5b 100644 --- a/compiler/riscv64/cpubase.pas +++ b/compiler/riscv64/cpubase.pas @@ -345,6 +345,7 @@ const function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE} function dwarf_reg(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; @@ -459,6 +460,14 @@ implementation result:=regdwarf_table[findreg_by_number(r)]; 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; begin result:=c1=c2; diff --git a/compiler/sparcgen/cpubase.pas b/compiler/sparcgen/cpubase.pas index 425f175f3f..4db0f58fe8 100644 --- a/compiler/sparcgen/cpubase.pas +++ b/compiler/sparcgen/cpubase.pas @@ -345,7 +345,7 @@ uses function findreg_by_number(r:Tregister):tregisterindex; function dwarf_reg(r:tregister):shortint; function dwarf_reg_no_error(r:tregister):shortint; - + function eh_return_data_regno(nr: longint): longint; implementation @@ -536,6 +536,15 @@ implementation 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+24 + else + result:=-1; + end; + + procedure TResFlags.Init(r : TRegister; f : TSparcFlags); begin FlagReg:=r; diff --git a/compiler/x86/cpubase.pas b/compiler/x86/cpubase.pas index b176657d5d..a454a790d7 100644 --- a/compiler/x86/cpubase.pas +++ b/compiler/x86/cpubase.pas @@ -336,6 +336,7 @@ topsize2memsize: array[topsize] of integer = function std_regname(r:Tregister):string; function dwarf_reg(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 conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE} @@ -648,6 +649,17 @@ implementation 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; begin if not is_segment_reg(r1) or not is_segment_reg(r2) then diff --git a/rtl/inc/innr.inc b/rtl/inc/innr.inc index e461cdc735..71f8a5a9ba 100644 --- a/rtl/inc/innr.inc +++ b/rtl/inc/innr.inc @@ -117,6 +117,7 @@ const fpc_in_hi_qword = 107; fpc_in_const_swap_qword = 108; fpc_in_prefetch_var = 109; + fpc_in_const_eh_return_data_regno = 110; { FPU functions } fpc_in_trunc_real = 120; diff --git a/rtl/inc/system.fpd b/rtl/inc/system.fpd index 6d7ddf604a..9ab0b4ab09 100644 --- a/rtl/inc/system.fpd +++ b/rtl/inc/system.fpd @@ -42,6 +42,7 @@ Procedure Dispose (P : TypedPointer; Des : TProcedure); Procedure Exclude (Var S : TSetType; E : TSetElement); Procedure Exit(Const X : TAnyType); Procedure Exit; +Function FPC_EH_Return_Data_Regno(Nr: Longint): Longint; Function High (Arg: TypeOrVariable) : TOrdinal; Procedure Inc (Var X : TOrdinal); Procedure Inc (Var X : TOrdinal; Increment : TOrdinal);