diff --git a/src/compiler/ir-gas64.bas b/src/compiler/ir-gas64.bas index c076768761..50e9aa5c43 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) @@ -1753,17 +1753,13 @@ 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( ) @@ -1818,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( ) @@ -2267,7 +2267,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 ================================================================================= @@ -2294,41 +2294,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_