* 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:
Jonas Maebe 2009-07-19 13:57:23 +00:00
parent bc8ccacab8
commit 34c985cfa6
15 changed files with 139 additions and 37 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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 }

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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
View 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.