@@ -63,7 +63,7 @@ rbp+24 param 2
63
63
rbp+ 16 param 1 calling --> rsp + x / called --> rbp + 16 , 24 ,.. to 8 +x* 8
64
64
return addr (after call )
65
65
rbp old rbp
66
- rbp- 8 rax 14 saved registers (arbitrary even not used) --> rbp - 8 to - 12
66
+ rbp- 8 rax 14 saved registers (arbitrary even not used) --> rbp - 8 to - 112
67
67
- 16 rbx
68
68
- 24 rcx
69
69
- 32 rdx
@@ -158,7 +158,7 @@ if variadic register save area, only for parameters not defined
158
158
#define KREGFREE - 2 ''register not free
159
159
#define KREGRSVD - 3 ''register reserved
160
160
#define KREGLOCK - 4 ''register locked (used as parameter)
161
- #define KREGUPPER 15
161
+ #define KREGUPPER 15 ''registers 0 to 15 / 16=rip /17=dummy reg to avoid crash
162
162
#define KNOTFOUND - 1
163
163
#define KSIZEPROCTXT 4000000 ''initial size of proc_txt used for speed up text adding
164
164
#define KLIMITROOM 150 ''upper limit for spilling (number of room = KLIMITROOM+1, zero based)
@@ -473,7 +473,6 @@ private sub check_optim(byref code as string)
473
473
code= "#O4" +code+newline+ string ( ctx.indent* 3 , 32 )+newcode+ " #Optim 4"
474
474
end if
475
475
else
476
- 'print code;" part1="+part1+" part2="+part2+" prevpart1="+prevpart1+" prevpart2="+prevpart2
477
476
if part2=prevpart1 and part1 [0 ]=asc( "r" ) then
478
477
asm_info( "OPTIMIZATION 5 (lea)" )
479
478
'asm_info("removed =lea "+prevpart1+", "+prevpart2)
@@ -1172,7 +1171,7 @@ private function hgetdatatype_asm64 _
1172
1171
select case as const dtype
1173
1172
'' UDT?
1174
1173
case FB_DATATYPE_STRUCT
1175
- ''à creuser à un moment appel hGetDataType_asm64 avec direct subtype et non sym....
1174
+ ''to be checked hGetDataType_asm64 with direct subtype and not sym....
1176
1175
if subtype then
1177
1176
if ( subtype->udt.dbg.typenum = INVALID ) then hDeclUDT_asm64( subtype, dimtbelements )
1178
1177
desc += str( subtype->udt.dbg.typenum )
@@ -1512,9 +1511,10 @@ private function reg_findfree(byval vreg as long,byval regparam as integer=-1) a
1512
1511
end function
1513
1512
''=====================================================================
1514
1513
'' in case of callptr avoid potential register used as parameter
1515
- '' eg op1=-1520[rdx] --> op1=-1520[r11] and mov r11, rdx
1514
+ '' eg op1=-1520[rdx] --> op1=-1520[r11] and ' mov r11, rdx'
1516
1515
1517
- ''todo find an more efficient way as it swaps all the POTENTIAL registers not only those laterly used
1516
+ '' note : it swaps all the POTENTIAL registers not only those laterly used
1517
+ '' op1=-1520[r8] --> op1=-1520[r11] and 'mov r11, r8' even if r8 will be not be used as parameter
1518
1518
''=====================================================================
1519
1519
private sub reg_callptr( byref op1 as string , byref op3 as string )
1520
1520
dim as long regfree
@@ -1665,11 +1665,15 @@ end function
1665
1665
''=====================================================================
1666
1666
private sub reg_transfer( byval regtrans as long , byval regsource as long )
1667
1667
dim as long regfree
1668
-
1669
- ''not used so nothing to do
1670
- if reghandle(regtrans)=KREGFREE then exit sub
1668
+ ''not used or already transfered in reg_callptr so nothing to do
1669
+ if reghandle(regtrans)=KREGFREE or reghandle(regtrans)=KREGLOCK then exit sub
1671
1670
''used in source of parameter
1672
- if regtrans=regsource then exit sub
1671
+ if regtrans=regsource then
1672
+ ''freeing the register
1673
+ asm_info( "in reg_transfer release regtrans=" +*regstrq(regtrans))
1674
+ reghandle(regtrans)=KREGFREE
1675
+ exit sub
1676
+ end if
1673
1677
1674
1678
''find a free register for transfering or just spilling if no free register (returning same register)
1675
1679
asm_info( "Transfering register in other register otherwise spilling" )
@@ -2340,7 +2344,6 @@ end function
2340
2344
private function _supportsop( byval op as integer , byval dtype as Integer ) as integer
2341
2345
''return true if the function is availiable directly in the backend
2342
2346
'asm_info("_supportsop="+astdumpopToStr( op )+" "+typedumpToStr(dtype,0))
2343
- 'Print "_supportsop="+astdumpopToStr( op )+" "+typedumpToStr(dtype,0)
2344
2347
select case as const ( op )
2345
2348
'case AST_OP_SGN, AST_OP_FIX, AST_OP_FRAC, _
2346
2349
' AST_OP_ASIN, AST_OP_ACOS, AST_OP_TAN, AST_OP_ATAN, _
@@ -3141,7 +3144,7 @@ private sub bop_float( _
3141
3144
asm_code(lname1+ ":" )
3142
3145
end if
3143
3146
3144
- case AST_OP_ADD,AST_OP_SUB,AST_OP_MUL,AST_OP_DIV ''todo optimiser xmm1 si memoire faire directement
3147
+ case AST_OP_ADD,AST_OP_SUB,AST_OP_MUL,AST_OP_DIV ''todo optimize xmm1 if memory
3145
3148
select case op
3146
3149
case AST_OP_ADD
3147
3150
asm_code(addreg+ "xmm0, xmm1" )
@@ -3475,12 +3478,6 @@ private sub hloadoperandsandwritebop(byval op as integer,byval v1 as IRVREG ptr,
3475
3478
''op2 is a register
3476
3479
asm_code( "or " +op1bis+ ", " +op2)
3477
3480
asm_code( "mov " +op1+ ", " +op1bis)
3478
- '===
3479
- 'asm_code("mov rax, "+op2)
3480
- 'asm_code("not rax")
3481
- 'asm_code("or "+op1+", rax")
3482
- 'asm_code("not "+op2)
3483
- 'asm_code("or "+op1+", "+op2)
3484
3481
end if
3485
3482
if vr<> 0 then restore_vrreg(vr,vrreg)
3486
3483
case AST_OP_XOR
@@ -3567,13 +3564,6 @@ private sub hloadoperandsandwritebop(byval op as integer,byval v1 as IRVREG ptr,
3567
3564
if ctx.target=FB_COMPTARGET_LINUX andalso fbGetOption( FB_COMPOPT_OUTTYPE ) = FB_OUTTYPE_DYNAMICLIB then
3568
3565
3569
3566
if v1->sym<> 0 andalso (symbIsCommon(v1->sym)) then
3570
- ''todo if two op1 are common etc
3571
- 'temporeg=reg_findfree(999998)
3572
- 'regtempo1=*regstrq(temporeg)
3573
- 'reghandle(temporeg)=KREGFREE
3574
- 'asm_code("mov "+regtempo1+", "+*symbGetMangledName(v1->sym)+"@GOTPCREL[rip]")
3575
- 'op1=regtempo1
3576
-
3577
3567
asm_code( "mov rax, " +*symbGetMangledName(v1->sym)+ "@GOTPCREL[rip]" )
3578
3568
asm_code( "mov rax, [rax]" )
3579
3569
op1= "rax"
@@ -3601,8 +3591,6 @@ private sub hloadoperandsandwritebop(byval op as integer,byval v1 as IRVREG ptr,
3601
3591
if tempodtype<>FB_DATATYPE_BOOLEAN then
3602
3592
asm_code( "neg " +*regstrq(vrreg))
3603
3593
end if
3604
- 'asm_code("movzx rax, al") ''eventually neg rax
3605
- '' or used movzx eax, al / neg eax / cdqe --> result in rax
3606
3594
restore_vrreg(vr,vrreg)
3607
3595
else
3608
3596
asm_code( "j" +suffix+ " " +*symbGetMangledName( label ))
@@ -3989,7 +3977,6 @@ private sub _emituop(byval op as integer,byval v1 as IRVREG ptr,byval vr as IRVR
3989
3977
asm_code( "mov " +*regstrq(reg_findreal(tempo))+ ", " +*regstrq(KREG_RCX))
3990
3978
op1=*regstrq(reg_findreal(tempo))
3991
3979
if vrreg=KREG_RCX then vrreg=reg_findreal(tempo)
3992
- 'if op1=*regstrq(KREG_RCX) then op1=*regstrq(reg_findreal(tempo))
3993
3980
else
3994
3981
ctx.usedreg Or =( 1 Shl KREG_RCX)
3995
3982
end if
@@ -4138,6 +4125,7 @@ private sub _emitconvert( byval v1 as IRVREG ptr, byval v2 as IRVREG ptr )
4138
4125
4139
4126
if (v1dtype=FB_DATATYPE_INTEGER and v2dtype=FB_DATATYPE_LONGINT) or (v2dtype=FB_DATATYPE_INTEGER and v1dtype=FB_DATATYPE_LONGINT) _
4140
4127
or (v1dtype=FB_DATATYPE_INTEGER and v2dtype=FB_DATATYPE_ENUM) or (v2dtype=FB_DATATYPE_INTEGER and v1dtype=FB_DATATYPE_ENUM) _
4128
+ or (v1dtype=FB_DATATYPE_UINT and v2dtype=FB_DATATYPE_ENUM) or (v2dtype=FB_DATATYPE_UINT and v1dtype=FB_DATATYPE_ENUM) _
4141
4129
Or (v1dtype=FB_DATATYPE_UINT and v2dtype=FB_DATATYPE_ULONGINT) Or (v2dtype=FB_DATATYPE_UINT and v1dtype=FB_DATATYPE_ULONGINT) then
4142
4130
asm_info( "no convert as exactly same datatype" )
4143
4131
*v1=*v2
@@ -5260,7 +5248,8 @@ private sub hdocall(byval proc as FBSYMBOL ptr,byref pname as string,byref first
5260
5248
if v2->sym= 0 then
5261
5249
if v2->vidx->sym= 0 then
5262
5250
if v2->vidx->reg<>- 1 then
5263
- op1=Str(v2->ofs)+ "[" +*regstrq(reg_findreal(v2->vidx->reg))+ "]"
5251
+ reg2=reg_findreal(v2->vidx->reg)
5252
+ op1=Str(v2->ofs)+ "[" +*regstrq(reg2)+ "]"
5264
5253
else
5265
5254
''2 levels
5266
5255
reg2=reg_findreal(v2->vidx->vidx->reg)
@@ -5288,7 +5277,8 @@ private sub hdocall(byval proc as FBSYMBOL ptr,byref pname as string,byref first
5288
5277
end if
5289
5278
5290
5279
if v2->vidx->typ=IR_VREGTYPE_REG then
5291
- op1= "[" +regtempo+ "+" +*regstrq(reg_findreal(v2->vidx->reg))+ "]"
5280
+ reg2=reg_findreal(v2->vidx->reg)
5281
+ op1= "[" +regtempo+ "+" +*regstrq(reg2)+ "]"
5292
5282
elseif v2->vidx->typ=IR_VREGTYPE_VAR then
5293
5283
if symbIsStatic(v2->vidx->sym) Or symbisshared(v2->vidx->sym) then
5294
5284
op3+=newline2+ "add " +regtempo+ ", " +*symbGetMangledName(v2->vidx->sym)+ "[rip+" +Str(v2->vidx->ofs)+ "]"
@@ -5326,7 +5316,8 @@ private sub hdocall(byval proc as FBSYMBOL ptr,byref pname as string,byref first
5326
5316
end if
5327
5317
5328
5318
case IR_VREGTYPE_PTR ''format ofs1 <vidx=reg>
5329
- op1=Str(v2->ofs)+ "[" +*regstrq(reg_findreal(v2->vidx->reg))+ "]"
5319
+ reg2=reg_findreal(v2->vidx->reg)
5320
+ op1=Str(v2->ofs)+ "[" +*regstrq(reg2)+ "]"
5330
5321
5331
5322
case IR_VREGTYPE_OFS ''format varname ofs1 static ofs1 could be zero
5332
5323
op1=*symbGetMangledName(v2->sym)+ "[rip+" +str(v2->ofs)+ "]"
@@ -5778,7 +5769,8 @@ private sub hdocall(byval proc as FBSYMBOL ptr,byref pname as string,byref first
5778
5769
asm_code(pushstr(istr))
5779
5770
next
5780
5771
end if
5781
-
5772
+ ''unlock registers to avoid save just below
5773
+ if callptr then reg_allowed( true )
5782
5774
''preparing the save of registers in use by the calling and that can be used by the called
5783
5775
reg_save
5784
5776
@@ -6077,7 +6069,7 @@ private sub _emitmem(byval op as integer,byval v1 as IRVREG ptr,byval v2 as IRVR
6077
6069
6078
6070
if v2->typ=IR_VREGTYPE_REG then ''todo to be replace by repsto
6079
6071
op2=*regstrq(reg_findreal(v2->reg))
6080
- asm_code( "test " +op2+ "," +op2)
6072
+ asm_code( "test " +op2+ ", " +op2)
6081
6073
lname2=*symbUniqueLabel( )
6082
6074
''zero byte to clear so skip
6083
6075
asm_code( "jz " +lname2)
@@ -6251,7 +6243,6 @@ end sub
6251
6243
private sub _emitcomment( byval text as zstring ptr )
6252
6244
#ifdef basicdata
6253
6245
if text= 0 Or LTrim(*text)= "" Or left(ltrim(*text, Any Chr( 32 )+Chr( 9 )), 1 )= "'" then exit sub
6254
- 'print left(Trim(*text),20)
6255
6246
6256
6247
hWriteasm64 ( "# -----------------------------------------" )
6257
6248
hWriteasm64 ( "# basic --> " + Trim(*text, Any " " +Chr( 9 )) )
@@ -6393,17 +6384,16 @@ private sub _emitprocbegin(byval proc as FBSYMBOL ptr,byval initlabel as FBSYMBO
6393
6384
asm_info( hEmitProcHeader( proc) )
6394
6385
6395
6386
''variadic ?
6396
- var param = symbGetProcLastParam ( proc )
6397
- while ( param )
6387
+ var param = symbGetProcTailParam ( proc )
6388
+ if param then
6398
6389
if ( symbGetParamMode( param ) = FB_PARAMMODE_VARARG ) then
6399
6390
ctx.variadic= true
6400
6391
if ctx.target=FB_COMPTARGET_LINUX then
6401
6392
''14 registers (6 rxx and 8 xmmn) could be used for arguments, the others are on stack
6402
6393
ctx.stk+= 14 * 8
6403
6394
end if
6404
6395
end if
6405
- param = symbGetProcPrevParam( proc, param )
6406
- wend
6396
+ end if
6407
6397
6408
6398
asm_code( ".text" )
6409
6399
if symbisprivate(proc)= FALSE then
@@ -6597,7 +6587,7 @@ end sub
6597
6587
6598
6588
private sub _emitMacro( byval op as integer , byval v1 as IRVREG ptr, byval v2 as IRVREG ptr, byval vr as IRVREG ptr )
6599
6589
dim as IRVREG ptr tempo1,tempo2
6600
- dim as long savereg,startarg
6590
+ dim as long savereg,startarg,vreg
6601
6591
dim as string regvalist,lname1,lname2
6602
6592
asm_info( "Macro op=" + astdumpopToStr( op ))
6603
6593
asm_info( "v1=" +vregdumpfull(v1))
@@ -6637,6 +6627,18 @@ private sub _emitMacro( byval op as integer,byval v1 as IRVREG ptr, byval v2 as
6637
6627
_emitstore(v1,tempo1)
6638
6628
end if
6639
6629
6630
+ if v2->typ=IR_VREGTYPE_PTR then
6631
+ ''removal of useless register as v2 not used / PTR -> ofs1 <vidx=reg>
6632
+ vreg=v2->vidx->reg
6633
+ for ireg as integer = 1 to KREGUPPER
6634
+ if reghandle(ireg)=vreg then
6635
+ asm_info( "VA_START release for PTR reg not used=" +str(vreg))
6636
+ reghandle(ireg)=KREGFREE
6637
+ exit for
6638
+ end if
6639
+ next
6640
+ end if
6641
+
6640
6642
case AST_OP_VA_ARG
6641
6643
6642
6644
'# -----------------------------------------
@@ -6717,6 +6719,17 @@ private sub _emitMacro( byval op as integer,byval v1 as IRVREG ptr, byval v2 as
6717
6719
6718
6720
case AST_OP_VA_END
6719
6721
asm_info( "Call emit macro END nothing to do ?" )
6722
+ if v1->typ=IR_VREGTYPE_PTR then
6723
+ ''removal of useless register as v1 not used / PTR -> ofs1 <vidx=reg>
6724
+ vreg=v1->vidx->reg
6725
+ for ireg as integer = 1 to KREGUPPER
6726
+ if reghandle(ireg)=vreg then
6727
+ asm_info( "VA_END release for PTR reg not used=" +str(vreg))
6728
+ reghandle(ireg)=KREGFREE
6729
+ exit for
6730
+ end if
6731
+ next
6732
+ end if
6720
6733
case AST_OP_VA_COPY
6721
6734
if ctx.target=FB_COMPTARGET_LINUX then
6722
6735
''linux
0 commit comments