mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-13 11:24:14 +02:00
* added register type parameter to cgsize2subreg(), as the subreg can
depend on that (and correct a number of cases where this was wrong) * set the correct subreg type for xmm x86_64 parameter registers (resolved mantis #14067) git-svn-id: trunk@13410 -
This commit is contained in:
parent
bc8ccacab8
commit
34c985cfa6
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9201,6 +9201,7 @@ tests/webtbs/tw14019.pp svneol=native#text/plain
|
||||
tests/webtbs/tw14020.pp svneol=native#text/plain
|
||||
tests/webtbs/tw14020a.pp svneol=native#text/plain
|
||||
tests/webtbs/tw14040.pp svneol=native#text/plain
|
||||
tests/webtbs/tw14067.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1407.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1408.pp svneol=native#text/plain
|
||||
tests/webtbs/tw1409.pp svneol=native#text/plain
|
||||
|
@ -354,7 +354,7 @@ unit cpubase;
|
||||
|
||||
{ Returns the tcgsize corresponding with the size of reg.}
|
||||
function reg_cgsize(const reg: tregister) : tcgsize;
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
procedure inverse_flags(var f: TResFlags);
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
@ -391,7 +391,7 @@ unit cpubase;
|
||||
);
|
||||
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
begin
|
||||
cgsize2subreg:=R_SUBWHOLE;
|
||||
end;
|
||||
|
@ -332,7 +332,7 @@ unit cpubase;
|
||||
|
||||
{ Returns the tcgsize corresponding with the size of reg.}
|
||||
function reg_cgsize(const reg: tregister) : tcgsize;
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
procedure inverse_flags(var f: TResFlags);
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
function findreg_by_number(r:Tregister):tregisterindex;
|
||||
@ -367,7 +367,7 @@ unit cpubase;
|
||||
);
|
||||
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
begin
|
||||
cgsize2subreg:=R_SUBWHOLE;
|
||||
end;
|
||||
|
@ -638,7 +638,7 @@ implementation
|
||||
begin
|
||||
if not assigned(rg[R_INTREGISTER]) then
|
||||
internalerror(200312122);
|
||||
result:=rg[R_INTREGISTER].getregister(list,cgsize2subreg(size));
|
||||
result:=rg[R_INTREGISTER].getregister(list,cgsize2subreg(R_INTREGISTER,size));
|
||||
end;
|
||||
|
||||
|
||||
@ -646,7 +646,7 @@ implementation
|
||||
begin
|
||||
if not assigned(rg[R_FPUREGISTER]) then
|
||||
internalerror(200312123);
|
||||
result:=rg[R_FPUREGISTER].getregister(list,cgsize2subreg(size));
|
||||
result:=rg[R_FPUREGISTER].getregister(list,cgsize2subreg(R_FPUREGISTER,size));
|
||||
end;
|
||||
|
||||
|
||||
@ -654,7 +654,7 @@ implementation
|
||||
begin
|
||||
if not assigned(rg[R_MMREGISTER]) then
|
||||
internalerror(2003121214);
|
||||
result:=rg[R_MMREGISTER].getregister(list,cgsize2subreg(size));
|
||||
result:=rg[R_MMREGISTER].getregister(list,cgsize2subreg(R_MMREGISTER,size));
|
||||
end;
|
||||
|
||||
|
||||
@ -675,7 +675,7 @@ implementation
|
||||
var
|
||||
subreg:Tsubregister;
|
||||
begin
|
||||
subreg:=cgsize2subreg(size);
|
||||
subreg:=cgsize2subreg(getregtype(reg),size);
|
||||
result:=reg;
|
||||
setsubreg(result,subreg);
|
||||
{ notify RA }
|
||||
|
@ -328,7 +328,7 @@ unit cpubase;
|
||||
|
||||
procedure inverse_flags(var r : TResFlags);
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
function reg_cgsize(const reg: tregister): tcgsize;
|
||||
|
||||
function findreg_by_number(r:Tregister):tregisterindex;
|
||||
@ -407,7 +407,7 @@ implementation
|
||||
flags_to_cond := flags2cond[f];
|
||||
end;
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
var p: pointer;
|
||||
begin
|
||||
case s of
|
||||
|
@ -247,9 +247,9 @@ unit cpupara;
|
||||
p.funcretloc[side].loc:=LOC_REGISTER;
|
||||
p.funcretloc[side].size:=retcgsize;
|
||||
if side=callerside then
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(R_INTREGISTER,retcgsize))
|
||||
else
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(R_INTREGISTER,retcgsize));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -395,7 +395,7 @@ uses
|
||||
procedure create_cond_imm(BO,BI:byte;var r : TAsmCond);
|
||||
procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
{ Returns the tcgsize corresponding with the size of reg.}
|
||||
function reg_cgsize(const reg: tregister) : tcgsize;
|
||||
|
||||
@ -535,7 +535,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
begin
|
||||
cgsize2subreg:=R_SUBWHOLE;
|
||||
end;
|
||||
|
@ -300,9 +300,9 @@ unit cpupara;
|
||||
p.funcretloc[side].loc:=LOC_REGISTER;
|
||||
p.funcretloc[side].size:=retcgsize;
|
||||
if side=callerside then
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(R_INTREGISTER,retcgsize))
|
||||
else
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(R_INTREGISTER,retcgsize));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -398,7 +398,7 @@ function flags_to_cond(const f: TResFlags): TAsmCond;
|
||||
procedure create_cond_imm(BO, BI: byte; var r: TAsmCond);
|
||||
procedure create_cond_norm(cond: TAsmCondFlag; cr: byte; var r: TasmCond);
|
||||
|
||||
function cgsize2subreg(s: Tcgsize): Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s: Tcgsize): Tsubregister;
|
||||
{ Returns the tcgsize corresponding with the size of reg.}
|
||||
function reg_cgsize(const reg: tregister): tcgsize;
|
||||
|
||||
@ -533,7 +533,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function cgsize2subreg(s: Tcgsize): Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s: Tcgsize): Tsubregister;
|
||||
begin
|
||||
cgsize2subreg := R_SUBWHOLE;
|
||||
end;
|
||||
|
@ -239,10 +239,10 @@ begin
|
||||
p.funcretloc[side].size := retcgsize;
|
||||
if side = callerside then
|
||||
p.funcretloc[side].register := newreg(R_INTREGISTER,
|
||||
RS_FUNCTION_RESULT_REG, cgsize2subreg(retcgsize))
|
||||
RS_FUNCTION_RESULT_REG, cgsize2subreg(R_INTREGISTER, retcgsize))
|
||||
else
|
||||
p.funcretloc[side].register := newreg(R_INTREGISTER,
|
||||
RS_FUNCTION_RETURN_REG, cgsize2subreg(retcgsize));
|
||||
RS_FUNCTION_RETURN_REG, cgsize2subreg(R_INTREGISTER, retcgsize));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -336,7 +336,7 @@ uses
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
|
||||
function flags_to_cond(const f: TResFlags) : TAsmCond;
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
function reg_cgsize(const reg: tregister): tcgsize;
|
||||
function std_regname(r:Tregister):string;
|
||||
function std_regnum_search(const s:string):Tregister;
|
||||
@ -395,12 +395,28 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
begin
|
||||
if s in [OS_64,OS_S64] then
|
||||
cgsize2subreg:=R_SUBQ
|
||||
else
|
||||
cgsize2subreg:=R_SUBWHOLE;
|
||||
case regtype of
|
||||
R_FPUREGISTER:
|
||||
case s of
|
||||
OS_F32:
|
||||
cgsize2subreg:=R_SUBFS;
|
||||
OS_F64:
|
||||
cgsize2subreg:=R_SUBFD;
|
||||
OS_F128:
|
||||
cgsize2subreg:=R_SUBFQ;
|
||||
else
|
||||
internalerror(2009071903);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
if s in [OS_64,OS_S64] then
|
||||
cgsize2subreg:=R_SUBQ
|
||||
else
|
||||
cgsize2subreg:=R_SUBWHOLE;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -196,9 +196,9 @@ implementation
|
||||
p.funcretloc[side].loc:=LOC_REGISTER;
|
||||
p.funcretloc[side].size:=retcgsize;
|
||||
if (side=callerside) then
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(R_INTREGISTER,retcgsize))
|
||||
else
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(R_INTREGISTER,retcgsize));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -244,7 +244,7 @@ uses
|
||||
Helpers
|
||||
*****************************************************************************}
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
function reg2opsize(r:Tregister):topsize;
|
||||
function reg_cgsize(const reg: tregister): tcgsize;
|
||||
function is_calljmp(o:tasmop):boolean;
|
||||
@ -295,7 +295,7 @@ implementation
|
||||
Helpers
|
||||
*****************************************************************************}
|
||||
|
||||
function cgsize2subreg(s:Tcgsize):Tsubregister;
|
||||
function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
|
||||
begin
|
||||
case s of
|
||||
OS_8,OS_S8:
|
||||
@ -308,9 +308,24 @@ implementation
|
||||
cgsize2subreg:=R_SUBQ;
|
||||
OS_M64:
|
||||
cgsize2subreg:=R_SUBNONE;
|
||||
OS_F32,OS_F64,OS_C64,
|
||||
OS_F32,OS_F64,OS_C64:
|
||||
case regtype of
|
||||
R_FPUREGISTER:
|
||||
cgsize2subreg:=R_SUBWHOLE;
|
||||
R_MMREGISTER:
|
||||
case s of
|
||||
OS_F32:
|
||||
cgsize2subreg:=R_SUBMMS;
|
||||
OS_F64:
|
||||
cgsize2subreg:=R_SUBMMD;
|
||||
else
|
||||
internalerror(2009071901);
|
||||
end;
|
||||
else
|
||||
internalerror(2009071902);
|
||||
end;
|
||||
OS_M128,OS_MS128:
|
||||
cgsize2subreg:=R_SUBWHOLE;
|
||||
cgsize2subreg:=R_SUBMMWHOLE;
|
||||
else
|
||||
internalerror(200301231);
|
||||
end;
|
||||
|
@ -472,9 +472,9 @@ unit cpupara;
|
||||
begin
|
||||
p.funcretloc[side].size:=retcgsize;
|
||||
if side=callerside then
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(retcgsize))
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RESULT_REG,cgsize2subreg(R_INTREGISTER,retcgsize))
|
||||
else
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(retcgsize));
|
||||
p.funcretloc[side].register:=newreg(R_INTREGISTER,RS_FUNCTION_RETURN_REG,cgsize2subreg(R_INTREGISTER,retcgsize));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -577,7 +577,7 @@ unit cpupara;
|
||||
{ s64comp is pushed in an int register }
|
||||
if paraloc^.size=OS_C64 then
|
||||
paraloc^.size:=OS_64;
|
||||
subreg:=cgsize2subreg(paraloc^.size);
|
||||
subreg:=cgsize2subreg(R_INTREGISTER,paraloc^.size);
|
||||
end;
|
||||
|
||||
{ winx64 uses different registers }
|
||||
@ -598,11 +598,20 @@ unit cpupara;
|
||||
paraloc:=hp.paraloc[side].add_location;
|
||||
paraloc^.loc:=LOC_MMREGISTER;
|
||||
|
||||
case paracgsize of
|
||||
OS_F32:
|
||||
subreg:=R_SUBMMS;
|
||||
OS_F64:
|
||||
subreg:=R_SUBMMD;
|
||||
else
|
||||
subreg:=R_SUBMMWHOLE;
|
||||
end;
|
||||
|
||||
{ winx64 uses different registers }
|
||||
if target_info.system=system_x86_64_win64 then
|
||||
paraloc^.register:=newreg(R_MMREGISTER,parammsupregs_winx64[mmparareg],R_SUBNONE)
|
||||
paraloc^.register:=newreg(R_MMREGISTER,parammsupregs_winx64[mmparareg],subreg)
|
||||
else
|
||||
paraloc^.register:=newreg(R_MMREGISTER,parammsupregs[mmparareg],R_SUBNONE);
|
||||
paraloc^.register:=newreg(R_MMREGISTER,parammsupregs[mmparareg],subreg);
|
||||
if paracgsize=OS_F128 then
|
||||
paraloc^.size:=OS_F64
|
||||
else
|
||||
|
61
tests/webtbs/tw14067.pp
Normal file
61
tests/webtbs/tw14067.pp
Normal file
@ -0,0 +1,61 @@
|
||||
{ %cpu=x86_64 }
|
||||
{ %interactive }
|
||||
|
||||
{ check the assembler file for superfluous register moves from/to the
|
||||
parameter xmm regs }
|
||||
|
||||
program disasm;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
Classes, SysUtils
|
||||
{ you can add units after this };
|
||||
|
||||
(*procedure ProcReg(A: Int64; B: Int64; C: Int64; D: Int64; E, F, G, H: Int64); register;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure ProcStd(A: Int64; B: Int64; C: Int64; D: Int64; E, F, G, H: Int64); stdcall;
|
||||
begin
|
||||
|
||||
end;*)
|
||||
|
||||
procedure ProcFReg(A, B, C, D, E, F, G, H: Double); register;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure ProcFStd(A, B, C, D, E, F, G, H: Double); stdcall;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
begin
|
||||
(*asm
|
||||
push %R8
|
||||
pop %R8
|
||||
end;
|
||||
ProcReg($10, $20, $30, $40, $50, $60, $70, $80);
|
||||
asm
|
||||
push %R8
|
||||
pop %R8
|
||||
end;
|
||||
ProcStd($10, $20, $30, $40, $50, $60, $70, $80);
|
||||
asm
|
||||
push %R8
|
||||
pop %R8
|
||||
end;
|
||||
ProcFReg(0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80);
|
||||
asm
|
||||
push %R8
|
||||
pop %R8
|
||||
end; *)
|
||||
ProcFStd(0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80);
|
||||
(*asm
|
||||
push %R8
|
||||
pop %R8
|
||||
end;*)
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user