From 59c9854bd19f3f152e55eaac2c79d0e737d0848f Mon Sep 17 00:00:00 2001 From: SARG Date: Mon, 28 Dec 2020 16:31:40 +0100 Subject: [PATCH 1/3] gas64 - moving some lines in memcopy to avoid useless use of a register --- src/compiler/ir-gas64.bas | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/compiler/ir-gas64.bas b/src/compiler/ir-gas64.bas index c076768761..2ff84a585f 100644 --- a/src/compiler/ir-gas64.bas +++ b/src/compiler/ir-gas64.bas @@ -1753,17 +1753,16 @@ private sub memcopy(byval bytestoclear as Integer,byref src as string, byref dst end if end if - rnbb=reg_findfree(999996) - regnbb=*regstrq(rnbb) - if regsrc<>src then reghandle(rsrc)=KREGFREE :asm_info("hidden freeing register="+*regstrq(rsrc))''free registers if regdst<>dst then reghandle(rdst)=KREGFREE :asm_info("hidden freeing register="+*regstrq(rdst)) - reghandle(rnbb)=KREGFREE:asm_info("hidden freeing register="+*regstrq(rnbb)) nb8=nbbytes\8 ''copy by 8 bytes step if nb8>7 then ''greater than 7 times * 8 bytes + rnbb=reg_findfree(999996) + regnbb=*regstrq(rnbb) + reghandle(rnbb)=KREGFREE:asm_info("hidden freeing register="+*regstrq(rnbb)) asm_code("mov "+regnbb+", "+Str(nb8)) lname=*symbUniqueLabel( ) From 7a00dfc9bc3d77f32a8a3fe82df8eb02a6a2b220 Mon Sep 17 00:00:00 2001 From: SARG Date: Wed, 30 Dec 2020 01:36:10 +0100 Subject: [PATCH 2/3] fbc : reviewing of hGetMagicStructNumber(),hGetReturnTypeGas64Linux() and struct_analyze() for better understanding gas64 : use of hGetMagicStructNumber() --- src/compiler/ir-gas64.bas | 24 ++++++--------- src/compiler/symb-struct.bas | 57 ++++++++++++++++++++---------------- src/compiler/symb.bi | 15 ++++++++++ 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/src/compiler/ir-gas64.bas b/src/compiler/ir-gas64.bas index 2ff84a585f..aca17c8190 100644 --- a/src/compiler/ir-gas64.bas +++ b/src/compiler/ir-gas64.bas @@ -325,7 +325,7 @@ declare sub _emitscopebegin( byval s as FBSYMBOL ptr ) declare sub _emitscopeend( byval s as FBSYMBOL ptr ) declare sub _emitMacro( byval op as integer,byval v1 as IRVREG ptr, byval v2 as IRVREG ptr, byval vr as IRVREG ptr ) declare sub save_call(byref func as string,byval vr as IRVREG ptr,byval vrreg as integer) -declare sub struct_analyze(byval fld as FBSYMBOL ptr,byref class1 as integer,byref class2 as integer,byref limit as integer) +declare function hGetMagicStructNumber( byval sym as FBSYMBOL ptr ) as integer ''===================== globals =========================================== dim shared as EDBGCTX ctx_asm64 dim shared as long reghandle(KREGUPPER+2) @@ -2266,7 +2266,7 @@ private function param_analyze(byval dtype as FB_DATATYPE,byval struc as FBSYMBO ,byref cptarg as integer=0,byref cptint as integer=0,byref cptfloat as integer=0) as integer ''used in hdocall and also in procallocarg but here do not update cptarg/cptint/cptfloat..... dim as FBSYMBOL ptr fld = any - dim as integer lgt,intcpt,floatcpt,class1,class2,limit + dim as integer lgt,intcpt,floatcpt if ctx.target=FB_COMPTARGET_LINUX then '' LNX ================================================================================= @@ -2293,41 +2293,35 @@ private function param_analyze(byval dtype as FB_DATATYPE,byval struc as FBSYMBO lgt=struc->lgt asm_info("subtype/lgt="+*symbGetMangledName(struc)+" "+str(lgt)) if lgt<=typeGetSize( FB_DATATYPE_LONGINT )*2 then - ''by default floating point for first register - class1=2 - class2=0 - limit=7 - struct_analyze(struc,class1,class2,limit) - asm_info("typeregister="+str(class1+class2)) - select case as const class1+class2 - case 1 + select case as const hGetMagicStructNumber( struc ) + case KSTRUCT_R if cptint <6 then cptint+=1 return KPARAMR1 end if - case 2 + case KSTRUCT_X if cptfloat <8 then cptfloat+=1 return KPARAMX1 end if - case 5 + case KSTRUCT_RR if cptint <5 then cptint+=2 return KPARAMRR end if - case 9 + case KSTRUCT_RX if cptint <6 and cptfloat <8 then cptint+=1 cptfloat+=1 return KPARAMRX end if - case 6 + case KSTRUCT_XR if cptint <6 and cptfloat <8 then cptfloat+=1 cptint+=1 return KPARAMXR end if - case 10 + case KSTRUCT_XX if cptfloat <7 then cptfloat+=2 return KPARAMXX diff --git a/src/compiler/symb-struct.bas b/src/compiler/symb-struct.bas index 47f7f13687..ecd855b140 100644 --- a/src/compiler/symb-struct.bas +++ b/src/compiler/symb-struct.bas @@ -639,26 +639,32 @@ sub symbInsertInnerUDT _ end sub ''================================================ -'' for Linux structure parameters size<=16 +'' for Linux structure parameters size<=16 bytes ''================================================ - -sub struct_analyze( byval fld as FBSYMBOL ptr, byref part1 as integer, byref part2 as integer, byref limit as integer ) +'' if the structure size is less or equal to 16 bytes it could be passed directly in registers according the datatype fields +'' integers and floats could even be mixed using Rxx and Xmm +'' analyzing the 8 low bytes then the 8 high bytes to know if each block contains integer or/and float +'' if at least one integer field all the range is considered as integer +'' if the size is greater than 8 and the result is only KPART1FLOAT or KPART1INTEGER then the structure is totally float or totally integer +'' (the structure contains only an array of simple datatype) and the result is forced to KSTRUCT_XX or KSTRUCT_RR +''================================================ +private sub struct_analyze( byval fld as FBSYMBOL ptr, byref part1 as integer, byref part2 as integer, byref range as integer ) dim as integer lgt=fld->lgt fld = symbUdtGetFirstField(fld) while fld - if limit=7 and fld->ofs>7 then - limit+=8 - part2=8 + if range=KLOW8BYTES and fld->ofs>7 then + range = KHIGH8BYTES + part2 = KPART2FLOAT ''default end if if typegetclass(fld->typ)=FB_DATACLASS_UDT then - struct_analyze(fld->subtype,part1,part2,limit) + struct_analyze(fld->subtype,part1,part2,range) elseif typegetclass(fld->typ)=FB_DATACLASS_INTEGER then - if limit=7 then - part1=1 + if range=KLOW8BYTES then + part1=KPART1INTEGER else - part2=4 + part2=KPART2INTEGER end if end if fld=symbUdtGetNextField(fld) @@ -666,22 +672,21 @@ sub struct_analyze( byval fld as FBSYMBOL ptr, byref part1 as integer, byref par if lgt>8 then ''case array in type eg type udt / array(0 to 1) as integer /end type - if part1+part2=1 then - part1=5 - elseif part1+part2=2 then - part1=10 + if part1+part2=KPART1INTEGER then + part1=KSTRUCT_RR + elseif part1+part2=KPART1FLOAT then + part1=KSTRUCT_XX end if end if end sub - -private function hGetMagicStructNumber( byval sym as FBSYMBOL ptr ) as integer +function hGetMagicStructNumber( byval sym as FBSYMBOL ptr ) as integer '' by default floating point for first register - dim as integer part1 = 2 - dim as integer part2 = 0 - dim as integer limit = 7 + dim as integer part1 = KPART1FLOAT + dim as integer part2 = KPARTNOTDEF + dim as integer range = KLOW8BYTES - struct_analyze( sym, part1, part2, limit ) + struct_analyze( sym, part1, part2, range ) return part1 + part2 end function @@ -695,24 +700,24 @@ private function hGetReturnTypeGas64Linux( byval sym as FBSYMBOL ptr ) as intege if( sym->lgt <= typeGetSize( FB_DATATYPE_LONGINT ) * 2 ) then select case as const hGetMagicStructNumber( sym ) - case 1 ''only integers in RAX + case KSTRUCT_R ''only integers in RAX '' don't set retin2regs, it's handled by datatype only '' sym->udt.retin2regs = FB_STRUCT_R return FB_DATATYPE_LONGINT - case 2 ''only floats in XMM0 + case KSTRUCT_X ''only floats in XMM0 '' don't set retin2regs, it's handled by datatype only '' sym->udt.retin2regs = FB_STRUCT_X return FB_DATATYPE_DOUBLE - case 5 ''only integers in RAX/RDX + case KSTRUCT_RR ''only integers in RAX/RDX sym->udt.retin2regs = FB_STRUCT_RR return FB_DATATYPE_STRUCT - case 9 ''first part in RAX then in XMMO + case KSTRUCT_RX ''first part in RAX then in XMMO sym->udt.retin2regs = FB_STRUCT_RX return FB_DATATYPE_STRUCT - case 6 ''first part in XMMO then in RAX + case KSTRUCT_XR ''first part in XMMO then in RAX sym->udt.retin2regs = FB_STRUCT_XR return typeAddrOf( FB_DATATYPE_STRUCT ) - case 10 ''only floats in XMM0/XMM1 + case KSTRUCT_XX ''only floats in XMM0/XMM1 sym->udt.retin2regs = FB_STRUCT_XX return FB_DATATYPE_STRUCT case else diff --git a/src/compiler/symb.bi b/src/compiler/symb.bi index 0dd36912e4..7aa6d5dde2 100644 --- a/src/compiler/symb.bi +++ b/src/compiler/symb.bi @@ -275,6 +275,21 @@ enum FB_STRUCT_INREG FB_STRUCT_XX ''XMM0/XMM1 end enum +''for analyzing structures Linux only +#define KPARTNOTDEF 0 +#define KPART1FLOAT 2 +#define KPART2FLOAT 8 +#define KPART1INTEGER 1 +#define KPART2INTEGER 4 +#define KLOW8BYTES 1 +#define KHIGH8BYTES 2 +#define KSTRUCT_R KPART1INTEGER +#define KSTRUCT_X KPART1FLOAT +#define KSTRUCT_RR KPART1INTEGER + KPART2INTEGER +#define KSTRUCT_RX KPART1INTEGER + KPART2FLOAT +#define KSTRUCT_XR KPART1FLOAT + KPART2INTEGER +#define KSTRUCT_XX KPART1FLOAT + KPART2FLOAT + type FBSYMBOL_ as FBSYMBOL #ifndef ASTNODE_ From 9ae5735e023b081c2e03af431cf10e1b3e99adaa Mon Sep 17 00:00:00 2001 From: SARG Date: Thu, 31 Dec 2020 10:57:52 +0100 Subject: [PATCH 3/3] gas64 : fixing a bug due to freeing registers too quickly...... (previous commit in memcopy) --- src/compiler/ir-gas64.bas | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compiler/ir-gas64.bas b/src/compiler/ir-gas64.bas index aca17c8190..50e9aa5c43 100644 --- a/src/compiler/ir-gas64.bas +++ b/src/compiler/ir-gas64.bas @@ -1753,9 +1753,6 @@ private sub memcopy(byval bytestoclear as Integer,byref src as string, byref dst end if end if - if regsrc<>src then reghandle(rsrc)=KREGFREE :asm_info("hidden freeing register="+*regstrq(rsrc))''free registers - if regdst<>dst then reghandle(rdst)=KREGFREE :asm_info("hidden freeing register="+*regstrq(rdst)) - nb8=nbbytes\8 ''copy by 8 bytes step @@ -1817,6 +1814,10 @@ private sub memcopy(byval bytestoclear as Integer,byref src as string, byref dst asm_code("mov al, byte ptr ["+regsrc+"]") asm_code("mov byte ptr ["+regdst+"], al") end if + + if regsrc<>src then reghandle(rsrc)=KREGFREE :asm_info("hidden freeing register="+*regstrq(rsrc))''free registers + if regdst<>dst then reghandle(rdst)=KREGFREE :asm_info("hidden freeing register="+*regstrq(rdst)) + end sub private sub _init( )