Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 16 additions & 22 deletions src/compiler/ir-gas64.bas
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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( )
Expand Down Expand Up @@ -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( )
Expand Down Expand Up @@ -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 =================================================================================
Expand All @@ -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
Expand Down
57 changes: 31 additions & 26 deletions src/compiler/symb-struct.bas
Original file line number Diff line number Diff line change
Expand Up @@ -639,49 +639,54 @@ 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)
wend

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
Expand All @@ -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
Expand Down
15 changes: 15 additions & 0 deletions src/compiler/symb.bi
Original file line number Diff line number Diff line change
Expand Up @@ -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_
Expand Down