* a_loadfpu_* gets two size parameters: fromsize and tosize

* fixed downsizing the precision of floating point values
  * floating point constants are now treated using only the minimal
    precision required (e.g. 2.0 is now a single, 1.1 extended etc)
    (Delphi compatible)

git-svn-id: trunk@5927 -
This commit is contained in:
Jonas Maebe 2007-01-12 18:33:51 +00:00
parent ab79ccf277
commit e815b923d5
26 changed files with 296 additions and 291 deletions

View File

@ -69,9 +69,9 @@ unit cgcpu;
function a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference); override;
procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
procedure a_paramfpu_ref(list : TAsmList;size : tcgsize;const ref : treference;const paraloc : TCGPara);override;
{ comparison operations }
@ -231,7 +231,7 @@ unit cgcpu;
LOC_FPUREGISTER,LOC_CFPUREGISTER:
case location^.size of
OS_F32, OS_F64:
a_loadfpu_ref_reg(list,location^.size,tmpref,location^.register);
a_loadfpu_ref_reg(list,location^.size,location^.size,tmpref,location^.register);
else
internalerror(2002072801);
end;
@ -1009,7 +1009,7 @@ unit cgcpu;
begin
case hloc^.loc of
LOC_FPUREGISTER,LOC_CFPUREGISTER:
a_loadfpu_ref_reg(list,size,ref,hloc^.register);
a_loadfpu_ref_reg(list,size,size,ref,hloc^.register);
LOC_REGISTER :
case hloc^.size of
OS_F32:
@ -1035,17 +1035,17 @@ unit cgcpu;
end;
procedure tcgarm.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister);
procedure tcgarm.a_loadfpu_reg_reg(list: TAsmList; fromsize,tosize: tcgsize; reg1, reg2: tregister);
begin
list.concat(setoppostfix(taicpu.op_reg_reg(A_MVF,reg2,reg1),cgsize2fpuoppostfix[size]));
list.concat(setoppostfix(taicpu.op_reg_reg(A_MVF,reg2,reg1),cgsize2fpuoppostfix[tosize]));
end;
procedure tcgarm.a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister);
procedure tcgarm.a_loadfpu_ref_reg(list: TAsmList; fromsize,tosize: tcgsize; const ref: treference; reg: tregister);
var
oppostfix:toppostfix;
begin
case size of
case tosize of
OS_32,
OS_F32:
oppostfix:=PF_S;
@ -1061,11 +1061,11 @@ unit cgcpu;
end;
procedure tcgarm.a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference);
procedure tcgarm.a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference);
var
oppostfix:toppostfix;
begin
case size of
case tosize of
OS_F32:
oppostfix:=PF_S;
OS_F64:

View File

@ -236,11 +236,11 @@ unit cgobj;
procedure a_load_subsetreg_subsetref(list: TAsmlist; fromsubsetsize, tosubsetsize : tcgsize; const fromsreg: tsubsetregister; const tosref: tsubsetreference); virtual;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; size:tcgsize; reg1, reg2: tregister); virtual; abstract;
procedure a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister); virtual; abstract;
procedure a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference); virtual; abstract;
procedure a_loadfpu_loc_reg(list: TAsmList; const loc: tlocation; const reg: tregister);
procedure a_loadfpu_reg_loc(list: TAsmList; size: tcgsize; const reg: tregister; const loc: tlocation);
procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize:tcgsize; reg1, reg2: tregister); virtual; abstract;
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); virtual; abstract;
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); virtual; abstract;
procedure a_loadfpu_loc_reg(list: TAsmList; tosize: tcgsize; const loc: tlocation; const reg: tregister);
procedure a_loadfpu_reg_loc(list: TAsmList; fromsize: tcgsize; const reg: tregister; const loc: tlocation);
procedure a_paramfpu_reg(list : TAsmList;size : tcgsize;const r : tregister;const cgpara : TCGPara);virtual;
procedure a_paramfpu_ref(list : TAsmList;size : tcgsize;const ref : treference;const cgpara : TCGPara);virtual;
@ -1928,26 +1928,26 @@ implementation
end;
procedure tcg.a_loadfpu_loc_reg(list: TAsmList; const loc: tlocation; const reg: tregister);
procedure tcg.a_loadfpu_loc_reg(list: TAsmList; tosize: tcgsize; const loc: tlocation; const reg: tregister);
begin
case loc.loc of
LOC_REFERENCE, LOC_CREFERENCE:
a_loadfpu_ref_reg(list,loc.size,loc.reference,reg);
a_loadfpu_ref_reg(list,loc.size,tosize,loc.reference,reg);
LOC_FPUREGISTER, LOC_CFPUREGISTER:
a_loadfpu_reg_reg(list,loc.size,loc.register,reg);
a_loadfpu_reg_reg(list,loc.size,tosize,loc.register,reg);
else
internalerror(200203301);
end;
end;
procedure tcg.a_loadfpu_reg_loc(list: TAsmList; size: tcgsize; const reg: tregister; const loc: tlocation);
procedure tcg.a_loadfpu_reg_loc(list: TAsmList; fromsize: tcgsize; const reg: tregister; const loc: tlocation);
begin
case loc.loc of
LOC_REFERENCE, LOC_CREFERENCE:
a_loadfpu_reg_ref(list,size,reg,loc.reference);
a_loadfpu_reg_ref(list,fromsize,loc.size,reg,loc.reference);
LOC_FPUREGISTER, LOC_CFPUREGISTER:
a_loadfpu_reg_reg(list,size,reg,loc.register);
a_loadfpu_reg_reg(list,fromsize,loc.size,reg,loc.register);
else
internalerror(48991);
end;
@ -1962,19 +1962,19 @@ implementation
LOC_FPUREGISTER,LOC_CFPUREGISTER:
begin
cgpara.check_simple_location;
a_loadfpu_reg_reg(list,size,r,cgpara.location^.register);
a_loadfpu_reg_reg(list,size,size,r,cgpara.location^.register);
end;
LOC_REFERENCE,LOC_CREFERENCE:
begin
cgpara.check_simple_location;
reference_reset_base(ref,cgpara.location^.reference.index,cgpara.location^.reference.offset);
a_loadfpu_reg_ref(list,size,r,ref);
a_loadfpu_reg_ref(list,size,size,r,ref);
end;
LOC_REGISTER,LOC_CREGISTER:
begin
{ paramfpu_ref does the check_simpe_location check here if necessary }
tg.GetTemp(list,TCGSize2Size[size],tt_normal,ref);
a_loadfpu_reg_ref(list,size,r,ref);
a_loadfpu_reg_ref(list,size,size,r,ref);
a_paramfpu_ref(list,size,ref,cgpara);
tg.Ungettemp(list,ref);
end;
@ -1991,7 +1991,7 @@ implementation
cgpara.check_simple_location;
case cgpara.location^.loc of
LOC_FPUREGISTER,LOC_CFPUREGISTER:
a_loadfpu_ref_reg(list,size,ref,cgpara.location^.register);
a_loadfpu_ref_reg(list,size,size,ref,cgpara.location^.register);
LOC_REFERENCE,LOC_CREFERENCE:
begin
reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset);

View File

@ -56,9 +56,9 @@ unit cgcpu;
procedure a_load_ref_ref(list : TAsmList;fromsize,tosize : tcgsize;const sref : treference;const dref : treference);override;
procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override;
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference); override;
procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
procedure a_loadmm_reg_reg(list: TAsmList;fromsize,tosize : tcgsize; reg1, reg2: tregister;shuffle : pmmshuffle); override;
procedure a_loadmm_ref_reg(list: TAsmList;fromsize,tosize : tcgsize; const ref: treference; reg: tregister;shuffle : pmmshuffle); override;
@ -550,22 +550,23 @@ unit cgcpu;
end;
procedure tcg68k.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister);
procedure tcg68k.a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);
begin
{ in emulation mode, only 32-bit single is supported }
if cs_fp_emulation in current_settings.moduleswitches then
list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg1,reg2))
else
list.concat(taicpu.op_reg_reg(A_FMOVE,S_FD,reg1,reg2));
list.concat(taicpu.op_reg_reg(A_FMOVE,tcgsize2opsize[tosize],reg1,reg2));
end;
procedure tcg68k.a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister);
procedure tcg68k.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister);
var
opsize : topsize;
href : treference;
tmpreg : tregister;
begin
opsize := tcgsize2opsize[size];
opsize := tcgsize2opsize[fromsize];
{ extended is not supported, since it is not available on Coldfire }
if opsize = S_FX then
internalerror(20020729);
@ -575,14 +576,18 @@ unit cgcpu;
if cs_fp_emulation in current_settings.moduleswitches then
list.concat(taicpu.op_ref_reg(A_MOVE,S_L,href,reg))
else
list.concat(taicpu.op_ref_reg(A_FMOVE,opsize,href,reg));
begin
list.concat(taicpu.op_ref_reg(A_FMOVE,opsize,href,reg));
if (tosize < fromsize) then
a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg);
end;
end;
procedure tcg68k.a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference);
procedure tcg68k.a_loadfpu_reg_ref(list: TAsmList; fromsize,tosize: tcgsize; reg: tregister; const ref: treference);
var
opsize : topsize;
begin
opsize := tcgsize2opsize[size];
opsize := tcgsize2opsize[tosize];
{ extended is not supported, since it is not available on Coldfire }
if opsize = S_FX then
internalerror(20020729);

View File

@ -137,7 +137,7 @@ interface
if pushedfpu then
begin
tmpreg := cg.getfpuregister(current_asmdata.CurrAsmList,left.location.size);
cg.a_loadfpu_loc_reg(current_asmdata.CurrAsmList,left.location,tmpreg);
cg.a_loadfpu_loc_reg(current_asmdata.CurrAsmList,left.location.size,left.location,tmpreg);
location_reset(left.location,LOC_FPUREGISTER,left.location.size);
left.location.register := tmpreg;
{$ifdef x86}

View File

@ -152,7 +152,7 @@ implementation
end
else
reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset);
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,left.location.size,left.location.register,href);
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,left.location.size,left.location.size,left.location.register,href);
end;
LOC_MMREGISTER,
LOC_CMMREGISTER:
@ -574,7 +574,7 @@ implementation
if getsupreg(procdefinition.funcretloc[callerside].register)<first_fpu_imreg then
cg.ungetcpuregister(current_asmdata.CurrAsmList,procdefinition.funcretloc[callerside].register);
hregister:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,location.size,location.register,hregister);
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,location.size,location.size,location.register,hregister);
location.register:=hregister;
{$endif x86}
end;
@ -745,7 +745,7 @@ implementation
internalerror(200408222);
if getsupreg(callerparaloc^.register)<first_fpu_imreg then
cg.getcpuregister(current_asmdata.CurrAsmList,callerparaloc^.register);
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,ppn.tempcgpara.size,tmpparaloc^.register,callerparaloc^.register);
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,tmpparaloc^.size,ppn.tempcgpara.size,tmpparaloc^.register,callerparaloc^.register);
end;
LOC_MMREGISTER:
begin
@ -783,7 +783,7 @@ implementation
LOC_REGISTER:
cg.a_load_reg_ref(current_asmdata.CurrAsmList,tmpparaloc^.size,tmpparaloc^.size,tmpparaloc^.register,href);
LOC_FPUREGISTER:
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,tmpparaloc^.size,tmpparaloc^.register,href);
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,tmpparaloc^.size,tmpparaloc^.size,tmpparaloc^.register,href);
LOC_MMREGISTER:
cg.a_loadmm_reg_ref(current_asmdata.CurrAsmList,tmpparaloc^.size,tmpparaloc^.size,tmpparaloc^.register,href,mms_movescalar);
else

View File

@ -290,7 +290,13 @@ interface
location.size:=def_cgsize(resultdef);
case expectloc of
LOC_FPUREGISTER:
;
begin
{ on sparc a move from double -> single means from two to one register. }
{ On all other platforms it also needs rounding to avoid that }
{ single(double_regvar) = double_regvar is true in all cases }
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register);
end;
LOC_MMREGISTER:
location_force_mmregscalar(current_asmdata.CurrAsmList,location,false);
else
@ -310,7 +316,7 @@ interface
else
begin
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,left.location.size);
cg.a_loadfpu_loc_reg(current_asmdata.CurrAsmList,left.location,location.register);
cg.a_loadfpu_loc_reg(current_asmdata.CurrAsmList,location.size,left.location,location.register);
end;
location_freetemp(current_asmdata.CurrAsmList,left.location);
end;

View File

@ -362,7 +362,6 @@ implementation
procedure tcgassignmentnode.pass_generate_code;
var
otlabel,hlabel,oflabel : tasmlabel;
fputyp : tfloattype;
href : treference;
releaseright : boolean;
len : aint;
@ -560,7 +559,7 @@ implementation
LOC_CFPUREGISTER :
begin
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,
right.location.size,
right.location.size,left.location.size,
right.location.reference,
left.location.register);
end;
@ -637,28 +636,17 @@ implementation
LOC_FPUREGISTER,
LOC_CFPUREGISTER :
begin
if (left.resultdef.typ=floatdef) then
fputyp:=tfloatdef(left.resultdef).floattype
else
if (right.resultdef.typ=floatdef) then
fputyp:=tfloatdef(right.resultdef).floattype
else
if (right.nodetype=typeconvn) and
(ttypeconvnode(right).left.resultdef.typ=floatdef) then
fputyp:=tfloatdef(ttypeconvnode(right).left.resultdef).floattype
else
fputyp:=s32real;
{ we can't do direct moves between fpu and mm registers }
if left.location.loc in [LOC_MMREGISTER,LOC_CMMREGISTER] then
begin
location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,false);
cg.a_loadmm_reg_reg(current_asmdata.CurrAsmList,
tfloat2tcgsize[fputyp],tfloat2tcgsize[fputyp],
right.location.size,left.location.size,
right.location.register,left.location.register,mms_movescalar);
end
else
cg.a_loadfpu_reg_loc(current_asmdata.CurrAsmList,
tfloat2tcgsize[fputyp],
right.location.size,
right.location.register,left.location);
end;
LOC_SUBSETREG,
@ -915,7 +903,7 @@ implementation
hp.left.location.register,href,mms_movescalar);
LOC_FPUREGISTER,
LOC_CFPUREGISTER :
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,hp.left.location.size,hp.left.location.register,href);
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,hp.left.location.size,hp.left.location.size,hp.left.location.register,href);
LOC_REFERENCE,
LOC_CREFERENCE :
begin

View File

@ -151,7 +151,7 @@ implementation
}
tg.gettemp(current_asmdata.CurrAsmList,tcgsize2size[_size],tt_normal,href);
{ store the floating point value in the temporary memory area }
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,_size,r,href);
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,_size,_size,r,href);
{ only single and double ieee are supported, for little endian
the signed bit is in the second dword }
href2:=href;
@ -166,7 +166,7 @@ implementation
end;
{ flip sign-bit (bit 31/63) of single/double }
cg.a_op_const_ref(current_asmdata.CurrAsmList,OP_XOR,OS_32,aint($80000000),href2);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,_size,href,r);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,_size,_size,href,r);
tg.ungetiftemp(current_asmdata.CurrAsmList,href);
end;
@ -193,7 +193,7 @@ implementation
begin
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,
def_cgsize(left.resultdef),
left.location.size,location.size,
left.location.reference,location.register);
emit_float_sign_change(location.register,def_cgsize(left.resultdef));
end;
@ -205,7 +205,7 @@ implementation
LOC_CFPUREGISTER:
begin
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,left.location.register,location.register);
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,location.register);
emit_float_sign_change(location.register,def_cgsize(left.resultdef));
end;
else

View File

@ -691,7 +691,7 @@ implementation
l.reference:=href;
end;
reg:=cg.getfpuregister(list,l.size);
cg.a_loadfpu_loc_reg(list,l,reg);
cg.a_loadfpu_loc_reg(list,l.size,l,reg);
location_freetemp(list,l);
location_reset(l,LOC_FPUREGISTER,l.size);
l.register:=reg;
@ -711,7 +711,7 @@ implementation
if (l.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) then
begin
tg.GetTemp(list,tcgsize2size[l.size],tt_normal,href);
cg.a_loadfpu_reg_ref(list,l.size,l.register,href);
cg.a_loadfpu_reg_ref(list,l.size,l.size,l.register,href);
location_reset(l,LOC_REFERENCE,l.size);
l.reference:=href;
end;
@ -749,7 +749,7 @@ implementation
LOC_CFPUREGISTER :
begin
tg.GetTemp(list,TCGSize2Size[l.size],tt_normal,r);
cg.a_loadfpu_reg_ref(list,l.size,l.register,r);
cg.a_loadfpu_reg_ref(list,l.size,l.size,l.register,r);
location_reset(l,LOC_REFERENCE,l.size);
l.reference:=r;
end;
@ -1393,7 +1393,7 @@ implementation
{ we can't do direct moves between fpu and mm registers }
if restmploc.loc in [LOC_MMREGISTER,LOC_CMMREGISTER] then
location_force_fpureg(list,restmploc,false);
cg.a_loadfpu_loc_reg(list,restmploc,funcretloc.register);
cg.a_loadfpu_loc_reg(list,reg_cgsize(funcretloc.register),restmploc,funcretloc.register);
end;
LOC_MMREGISTER:
begin
@ -1526,7 +1526,7 @@ implementation
LOC_MMREGISTER :
cg.a_loadmm_reg_ref(list,paraloc.size,paraloc.size,paraloc.register,ref,mms_movescalar);
LOC_FPUREGISTER :
cg.a_loadfpu_reg_ref(list,paraloc.size,paraloc.register,ref);
cg.a_loadfpu_reg_ref(list,paraloc.size,paraloc.size,paraloc.register,ref);
LOC_REFERENCE :
begin
reference_reset_base(href,paraloc.reference.index,paraloc.reference.offset);
@ -1551,7 +1551,7 @@ implementation
LOC_MMREGISTER :
cg.a_loadmm_reg_reg(list,paraloc.size,paraloc.size,paraloc.register,reg,mms_movescalar);
LOC_FPUREGISTER :
cg.a_loadfpu_reg_reg(list,paraloc.size,paraloc.register,reg);
cg.a_loadfpu_reg_reg(list,paraloc.size,paraloc.size,paraloc.register,reg);
LOC_REFERENCE :
begin
reference_reset_base(href,paraloc.reference.index,paraloc.reference.offset);
@ -1559,7 +1559,7 @@ implementation
R_INTREGISTER :
cg.a_load_ref_reg(list,paraloc.size,paraloc.size,href,reg);
R_FPUREGISTER :
cg.a_loadfpu_ref_reg(list,paraloc.size,href,reg);
cg.a_loadfpu_ref_reg(list,paraloc.size,paraloc.size,href,reg);
R_MMREGISTER :
cg.a_loadmm_ref_reg(list,paraloc.size,paraloc.size,href,reg,mms_movescalar);
else
@ -1710,7 +1710,7 @@ implementation
paraloc:=paraloc^.next;
end;
gen_alloc_regvar(list,currpara);
cg.a_loadfpu_ref_reg(list,currpara.initialloc.size,tempref,currpara.initialloc.register);
cg.a_loadfpu_ref_reg(list,currpara.initialloc.size,currpara.initialloc.size,tempref,currpara.initialloc.register);
tg.UnGetTemp(list,tempref);
{$else sparc}
unget_para(paraloc^);
@ -2533,7 +2533,7 @@ implementation
cg.a_load_reg_reg(list,n.location.size,n.location.size,n.location.register,rr.new);
end;
LOC_CFPUREGISTER:
cg.a_loadfpu_reg_reg(list,n.location.size,n.location.register,rr.new);
cg.a_loadfpu_reg_reg(list,n.location.size,n.location.size,n.location.register,rr.new);
{$ifdef SUPPORT_MMX}
LOC_CMMXREGISTER:
cg.a_loadmm_reg_reg(list,OS_M64,OS_M64,n.location.register,rr.new,nil);

View File

@ -1915,6 +1915,7 @@ begin
def_system_macro('FPC_HAS_VARSETS');
def_system_macro('FPC_HAS_VALGRINDBOOL');
def_system_macro('FPC_HAS_STR_CURRENCY');
def_system_macro('FPC_REAL2REAL_FIXED');
{$ifdef x86}
def_system_macro('INTERNAL_BACKTRACE');
{$endif}

View File

@ -2438,7 +2438,14 @@ implementation
d:=1.0;
end;
consume(_REALNUMBER);
p1:=crealconstnode.create(d,pbestrealtype^);
{$ifdef FPC_REAL2REAL_FIXED}
if (d = single(d)) then
p1:=crealconstnode.create(d,s32floattype)
else if (d = double(d)) then
p1:=crealconstnode.create(d,s64floattype)
else
{$endif FPC_REAL2REAL_FIXED}
p1:=crealconstnode.create(d,pbestrealtype^);
end;
_STRING :

View File

@ -65,11 +65,6 @@ unit cgcpu;
tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister); override;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference); override;
{ comparison operations }
procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
l : tasmlabel);override;
@ -261,7 +256,7 @@ const
LOC_FPUREGISTER,LOC_CFPUREGISTER:
case location^.size of
OS_F32, OS_F64:
a_loadfpu_ref_reg(list,location^.size,tmpref,location^.register);
a_loadfpu_ref_reg(list,location^.size,location^.size,tmpref,location^.register);
else
internalerror(2002072801);
end;
@ -469,67 +464,6 @@ const
end;
procedure tcgppc.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister);
var
instr: taicpu;
begin
instr := taicpu.op_reg_reg(A_FMR,reg2,reg1);
list.concat(instr);
rg[R_FPUREGISTER].add_move_instruction(instr);
end;
procedure tcgppc.a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister);
const
FpuLoadInstr: Array[OS_F32..OS_F64,boolean, boolean] of TAsmOp =
{ indexed? updating?}
(((A_LFS,A_LFSU),(A_LFSX,A_LFSUX)),
((A_LFD,A_LFDU),(A_LFDX,A_LFDUX)));
var
op: tasmop;
ref2: treference;
begin
{ several functions call this procedure with OS_32 or OS_64 }
{ so this makes life easier (FK) }
case size of
OS_32,OS_F32:
size:=OS_F32;
OS_64,OS_F64,OS_C64:
size:=OS_F64;
else
internalerror(200201121);
end;
ref2 := ref;
fixref(list,ref2);
op := fpuloadinstr[size,ref2.index <> NR_NO,false];
a_load_store(list,op,reg,ref2);
end;
procedure tcgppc.a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference);
const
FpuStoreInstr: Array[OS_F32..OS_F64,boolean, boolean] of TAsmOp =
{ indexed? updating?}
(((A_STFS,A_STFSU),(A_STFSX,A_STFSUX)),
((A_STFD,A_STFDU),(A_STFDX,A_STFDUX)));
var
op: tasmop;
ref2: treference;
begin
if not(size in [OS_F32,OS_F64]) then
internalerror(200201122);
ref2 := ref;
fixref(list,ref2);
op := fpustoreinstr[size,ref2.index <> NR_NO,false];
a_load_store(list,op,reg,ref2);
end;
procedure tcgppc.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: aint; reg: TRegister);
begin
@ -1064,7 +998,7 @@ const
reference_reset_base(href,NR_R1,-8);
for regcounter:=firstregfpu to RS_F31 do
begin
a_loadfpu_reg_ref(list,OS_F64,newreg(R_FPUREGISTER,regcounter,R_SUBNONE),href);
a_loadfpu_reg_ref(list,OS_F64,OS_F64,newreg(R_FPUREGISTER,regcounter,R_SUBNONE),href);
dec(href.offset,8);
end;
{ compute start of gpr save area }
@ -1209,7 +1143,7 @@ const
reference_reset_base(href,NR_R1,-8);
for regcounter := firstregfpu to RS_F31 do
begin
a_loadfpu_ref_reg(list,OS_F64,href,newreg(R_FPUREGISTER,regcounter,R_SUBNONE));
a_loadfpu_ref_reg(list,OS_F64,OS_F64,href,newreg(R_FPUREGISTER,regcounter,R_SUBNONE));
dec(href.offset,8);
end;
inc(href.offset,4);
@ -1707,8 +1641,8 @@ const
else
begin
copyreg := getfpuregister(list,OS_F64);
a_loadfpu_ref_reg(list,OS_F64,source,copyreg);
a_loadfpu_reg_ref(list,OS_F64,copyreg,dest);
a_loadfpu_ref_reg(list,OS_F64,OS_F64,source,copyreg);
a_loadfpu_reg_ref(list,OS_F64,OS_F64,copyreg,dest);
end;
exit;
end;
@ -1777,8 +1711,8 @@ const
copyreg := getfpuregister(list,OS_F64);
for count2 := 1 to count do
begin
a_loadfpu_ref_reg(list,OS_F64,src,copyreg);
a_loadfpu_reg_ref(list,OS_F64,copyreg,dst);
a_loadfpu_ref_reg(list,OS_F64,OS_F64,src,copyreg);
a_loadfpu_reg_ref(list,OS_F64,OS_F64,copyreg,dst);
inc(src.offset,8);
inc(dst.offset,8);
end;

View File

@ -503,7 +503,15 @@ unit cpupara;
else { LOC_REFERENCE }
begin
paraloc^.loc:=LOC_REFERENCE;
paraloc^.size:=int_cgsize(paralen);
case loc of
LOC_FPUREGISTER:
paraloc^.size:=int_float_cgsize(paralen);
LOC_REGISTER,
LOC_REFERENCE:
paraloc^.size:=int_cgsize(paralen);
else
internalerror(2006011101);
end;
if (side = callerside) then
paraloc^.reference.index:=NR_STACK_POINTER_REG
else
@ -511,7 +519,7 @@ unit cpupara;
paraloc^.reference.index:=NR_R12;
tppcprocinfo(current_procinfo).needs_frame_pointer := true;
end;
if (target_info.abi = abi_powerpc_aix) and
(hp.paraloc[side].intsize < 3) then
paraloc^.reference.offset:=stack_offset+(4-paralen)

View File

@ -41,7 +41,7 @@ interface
{ procedure second_chararray_to_string;override; }
{ procedure second_char_to_string;override; }
procedure second_int_to_real;override;
procedure second_real_to_real;override;
{ procedure second_real_to_real;override; }
{ procedure second_cord_to_pointer;override; }
{ procedure second_proc_to_procvar;override; }
{ procedure second_bool_to_int;override; }
@ -210,37 +210,24 @@ implementation
dec(ref.offset,4);
tmpfpureg := cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,tempconst.location.reference,
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,OS_F64,tempconst.location.reference,
tmpfpureg);
tempconst.free;
location.register := cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,ref,location.register);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,OS_F64,ref,location.register);
tg.ungetiftemp(current_asmdata.CurrAsmList,ref);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_FSUB,location.register,
location.register,tmpfpureg));
{ work around bug in some PowerPC processors }
if (tfloatdef(resultdef).floattype = s32real) then
{ make sure the precision is correct }
if (tfloatdef(resultdef).floattype = s32real) then
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FRSP,location.register,
location.register));
end;
procedure tppctypeconvnode.second_real_to_real;
begin
inherited second_real_to_real;
{ work around bug in some powerpc processors where doubles aren't }
{ properly converted to singles }
if (tfloatdef(left.resultdef).floattype = s64real) and
(tfloatdef(resultdef).floattype = s32real) then
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FRSP,location.register,
location.register));
end;
begin
ctypeconvnode:=tppctypeconvnode;
end.

View File

@ -599,7 +599,7 @@ end;
src1 := cg.getfpuregister(current_asmdata.CurrAsmList,def_cgsize(left.resultdef));
location.register := src1;
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,
def_cgsize(left.resultdef),
left.location.size,left.location.size,
left.location.reference,src1);
end
else

View File

@ -70,15 +70,6 @@ type
procedure a_load_subsetreg_reg(list : TAsmList; subsetsize, tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
procedure a_load_const_subsetreg(list: TAsmlist; subsetsize: tcgsize; a: aint; const sreg: tsubsetregister); override;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2:
tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref:
treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg:
tregister; const ref: treference); override;
{ comparison operations }
procedure a_cmp_const_reg_label(list: TAsmList; size: tcgsize; cmp_op:
topcmp; a: aint; reg: tregister;
@ -538,7 +529,7 @@ begin
LOC_FPUREGISTER, LOC_CFPUREGISTER:
case location^.size of
OS_F32, OS_F64:
a_loadfpu_ref_reg(list, location^.size, tmpref, location^.register);
a_loadfpu_ref_reg(list, location^.size, location^.size, tmpref, location^.register);
else
internalerror(2002072801);
end;
@ -871,64 +862,6 @@ begin
a_load_reg_subsetreg(list, subsetsize, subsetsize, tmpreg, sreg);
end;
procedure tcgppc.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize;
reg1, reg2: tregister);
var
instr: taicpu;
begin
instr := taicpu.op_reg_reg(A_FMR, reg2, reg1);
list.concat(instr);
rg[R_FPUREGISTER].add_move_instruction(instr);
end;
procedure tcgppc.a_loadfpu_ref_reg(list: TAsmList; size: tcgsize;
const ref: treference; reg: tregister);
const
FpuLoadInstr: array[OS_F32..OS_F64, boolean, boolean] of TAsmOp =
{ indexed? updating?}
(((A_LFS, A_LFSU), (A_LFSX, A_LFSUX)),
((A_LFD, A_LFDU), (A_LFDX, A_LFDUX)));
var
op: tasmop;
ref2: treference;
begin
{ several functions call this procedure with OS_32 or OS_64
so this makes life easier (FK) }
case size of
OS_32, OS_F32:
size := OS_F32;
OS_64, OS_F64, OS_C64:
size := OS_F64;
else
internalerror(200201121);
end;
ref2 := ref;
fixref(list, ref2);
op := fpuloadinstr[size, ref2.index <> NR_NO, false];
a_load_store(list, op, reg, ref2);
end;
procedure tcgppc.a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg:
tregister; const ref: treference);
const
FpuStoreInstr: array[OS_F32..OS_F64, boolean, boolean] of TAsmOp =
{ indexed? updating? }
(((A_STFS, A_STFSU), (A_STFSX, A_STFSUX)),
((A_STFD, A_STFDU), (A_STFDX, A_STFDUX)));
var
op: tasmop;
ref2: treference;
begin
if not (size in [OS_F32, OS_F64]) then
internalerror(200201122);
ref2 := ref;
fixref(list, ref2);
op := fpustoreinstr[size, ref2.index <> NR_NO, false];
a_load_store(list, op, reg, ref2);
end;
procedure tcgppc.a_op_const_reg(list: TAsmList; Op: TOpCG; size: TCGSize; a:
aint; reg: TRegister);
begin
@ -1392,6 +1325,7 @@ begin
para.paraloc[calleeside].Location^.register, para.localloc.reference);
LOC_FPUREGISTER, LOC_CFPUREGISTER:
a_loadfpu_reg_ref(list, para.paraloc[calleeside].Location^.size,
para.paraloc[calleeside].Location^.size,
para.paraloc[calleeside].Location^.register, para.localloc.reference);
LOC_MMREGISTER, LOC_CMMREGISTER:
{ not supported }
@ -1407,6 +1341,7 @@ begin
para.localloc.reference, para.paraloc[calleeside].Location^.register);
LOC_FPUREGISTER, LOC_CFPUREGISTER:
a_loadfpu_ref_reg(list, para.paraloc[calleeside].Location^.size,
para.paraloc[calleeside].Location^.size,
para.localloc.reference, para.paraloc[calleeside].Location^.register);
LOC_MMREGISTER, LOC_CMMREGISTER:
{ not supported }
@ -1469,8 +1404,8 @@ var
reference_reset_base(href, NR_STACK_POINTER_REG, -8);
if (fprcount > 0) then
for regcount := RS_F31 downto firstregfpu do begin
a_loadfpu_reg_ref(list, OS_FLOAT, newreg(R_FPUREGISTER, regcount,
R_SUBNONE), href);
a_loadfpu_reg_ref(list, OS_FLOAT, OS_FLOAT, newreg(R_FPUREGISTER,
regcount, R_SUBNONE), href);
dec(href.offset, tcgsize2size[OS_FLOAT]);
end;
if (gprcount > 0) then
@ -1605,7 +1540,7 @@ var
reference_reset_base(href, NR_STACK_POINTER_REG, -tcgsize2size[OS_FLOAT]);
if (fprcount > 0) then
for regcount := RS_F31 downto firstregfpu do begin
a_loadfpu_ref_reg(list, OS_FLOAT, href, newreg(R_FPUREGISTER, regcount,
a_loadfpu_ref_reg(list, OS_FLOAT, OS_FLOAT, href, newreg(R_FPUREGISTER, regcount,
R_SUBNONE));
dec(href.offset, tcgsize2size[OS_FLOAT]);
end;
@ -1880,8 +1815,8 @@ begin
if count > 0 then begin
a_reg_alloc(list, NR_F0);
for count2 := 1 to count do begin
a_loadfpu_ref_reg(list, OS_F64, src, NR_F0);
a_loadfpu_reg_ref(list, OS_F64, NR_F0, dst);
a_loadfpu_ref_reg(list, OS_F64, OS_F64, src, NR_F0);
a_loadfpu_reg_ref(list, OS_F64, OS_F64, NR_F0, dst);
inc(src.offset, 8);
inc(dst.offset, 8);
end;

View File

@ -412,7 +412,15 @@ begin
{ either LOC_REFERENCE, or one of the above which must be passed on the
stack because of insufficient registers }
paraloc^.loc := LOC_REFERENCE;
paraloc^.size := int_cgsize(paralen);
case loc of
LOC_FPUREGISTER:
paraloc^.size:=int_float_cgsize(paralen);
LOC_REGISTER,
LOC_REFERENCE:
paraloc^.size:=int_cgsize(paralen);
else
internalerror(2006011101);
end;
if (side = callerside) then
paraloc^.reference.index := NR_STACK_POINTER_REG
else begin

View File

@ -178,7 +178,7 @@ begin
cg.a_load_reg_ref(current_asmdata.CurrAsmList, OS_S64, OS_S64, valuereg, disp);
// lfd frD, disp(r1)
location.register := cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64, disp, location.register);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64, OS_F64, disp, location.register);
// fcfid frD, frD
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FCFID, location.register,
location.register));
@ -186,7 +186,7 @@ begin
{ ts:todo use TOC for this constant or at least schedule better }
// lfd frC, const
tmpfpuconst := cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,tempconst.location.reference,
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,OS_F64,tempconst.location.reference,
tmpfpuconst);
tempconst.free;
@ -204,10 +204,10 @@ begin
// lfd frT1, disp(R1)
tmpfpureg := cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64, disp, tmpfpureg);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64, OS_F64, disp, tmpfpureg);
// lfd frD, disp+8(R1)
location.register := cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64, disp2, location.register);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64, OS_F64, disp2, location.register);
// fcfid frT1, frT1
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FCFID, tmpfpureg,
@ -225,6 +225,10 @@ begin
// free reference
tg.ungetiftemp(current_asmdata.CurrAsmList, disp);
// make sure the precision is correct
if (tfloatdef(resultdef).floattype = s32real) then
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FRSP,location.register,
location.register));
end;
begin

View File

@ -336,10 +336,10 @@ begin
begin
if (left.resultdef.typ = floatdef) then begin
src1 := cg.getfpuregister(current_asmdata.CurrAsmList,
def_cgsize(left.resultdef));
left.location.size);
location.register := src1;
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,
def_cgsize(left.resultdef),
left.location.size,left.location.size,
left.location.reference, src1);
end else begin
src1 := cg.getintregister(current_asmdata.CurrAsmList, OS_64);

View File

@ -45,6 +45,11 @@ unit cgppc;
procedure a_load_reg_ref(list: TAsmList; fromsize, tosize: TCGSize;
reg: tregister; const ref: treference); override;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
protected
function get_darwin_call_stub(const s: string): tasmsymbol;
procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
@ -203,6 +208,87 @@ unit cgppc;
end;
procedure tcgppcgen.a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);
var
op: tasmop;
instr: taicpu;
begin
if not(fromsize in [OS_F32,OS_F64]) or
not(tosize in [OS_F32,OS_F64]) then
internalerror(2006123110);
if (tosize < fromsize) then
op:=A_FRSP
else
op:=A_FMR;
instr := taicpu.op_reg_reg(op,reg2,reg1);
list.concat(instr);
if (op = A_FMR) then
rg[R_FPUREGISTER].add_move_instruction(instr);
end;
procedure tcgppcgen.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister);
const
FpuLoadInstr: Array[OS_F32..OS_F64,boolean, boolean] of TAsmOp =
{ indexed? updating?}
(((A_LFS,A_LFSU),(A_LFSX,A_LFSUX)),
((A_LFD,A_LFDU),(A_LFDX,A_LFDUX)));
var
op: tasmop;
ref2: treference;
begin
if not(fromsize in [OS_F32,OS_F64]) or
not(tosize in [OS_F32,OS_F64]) then
internalerror(200201121);
ref2 := ref;
fixref(list,ref2);
op := fpuloadinstr[fromsize,ref2.index <> NR_NO,false];
a_load_store(list,op,reg,ref2);
if (fromsize > tosize) then
a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg);
end;
procedure tcgppcgen.a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference);
const
FpuStoreInstr: Array[OS_F32..OS_F64,boolean, boolean] of TAsmOp =
{ indexed? updating?}
(((A_STFS,A_STFSU),(A_STFSX,A_STFSUX)),
((A_STFD,A_STFDU),(A_STFDX,A_STFDUX)));
var
op: tasmop;
ref2: treference;
{$ifndef cpu64bit}
reg2: tregister;
{$endif cpu64bit}
begin
if not(fromsize in [OS_F32,OS_F64]) or
not(tosize in [OS_F32,OS_F64]) then
internalerror(200201122);
ref2 := ref;
fixref(list,ref2);
op := fpustoreinstr[tosize,ref2.index <> NR_NO,false];
{$ifndef cpu64bit}
{ some ppc's have a bug whereby storing a double to memory }
{ as single corrupts the value -> convert double to single }
{ first }
if (tosize < fromsize) then
begin
reg2:=getfpuregister(list,tosize);
a_loadfpu_reg_reg(list,fromsize,tosize,reg,reg2);
reg:=reg2;
end;
{$endif not cpu64bit}
a_load_store(list,op,reg,ref2);
end;
procedure tcgppcgen.a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister);
var
fromsreg, tosreg: tsubsetregister;

View File

@ -68,9 +68,9 @@ interface
procedure a_load_reg_reg(list:TAsmList;FromSize,ToSize:TCgSize;reg1,reg2:tregister);override;
procedure a_loadaddr_ref_reg(list:TAsmList;const ref:TReference;r:tregister);override;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list:TAsmList;size:tcgsize;reg1, reg2:tregister);override;
procedure a_loadfpu_ref_reg(list:TAsmList;size:tcgsize;const ref:TReference;reg:tregister);override;
procedure a_loadfpu_reg_ref(list:TAsmList;size:tcgsize;reg:tregister;const ref:TReference);override;
procedure a_loadfpu_reg_reg(list:TAsmList;fromsize,tosize:tcgsize;reg1, reg2:tregister);override;
procedure a_loadfpu_ref_reg(list:TAsmList;fromsize,tosize:tcgsize;const ref:TReference;reg:tregister);override;
procedure a_loadfpu_reg_ref(list:TAsmList;fromsize,tosize:tcgsize;reg:tregister;const ref:TReference);override;
{ comparison operations }
procedure a_cmp_const_reg_label(list:TAsmList;size:tcgsize;cmp_op:topcmp;a:aint;reg:tregister;l:tasmlabel);override;
procedure a_cmp_reg_reg_label(list:TAsmList;size:tcgsize;cmp_op:topcmp;reg1,reg2:tregister;l:tasmlabel);override;
@ -423,7 +423,7 @@ implementation
href : treference;
begin
tg.GetTemp(list,TCGSize2Size[size],tt_normal,href);
a_loadfpu_reg_ref(list,size,r,href);
a_loadfpu_reg_ref(list,size,size,r,href);
a_paramfpu_ref(list,size,href,paraloc);
tg.Ungettemp(list,href);
end;
@ -678,39 +678,57 @@ implementation
end;
procedure TCgSparc.a_loadfpu_reg_reg(list:TAsmList;size:tcgsize;reg1, reg2:tregister);
procedure TCgSparc.a_loadfpu_reg_reg(list:TAsmList;fromsize,tosize:tcgsize;reg1, reg2:tregister);
const
FpuMovInstr : Array[OS_F32..OS_F64] of TAsmOp =
(A_FMOVS,A_FMOVD);
FpuMovInstr : Array[OS_F32..OS_F64,OS_F32..OS_F64] of TAsmOp =
((A_FMOVS,A_FSTOD),(A_FDTOS,A_FMOVD));
var
op: TAsmOp;
instr : taicpu;
begin
if reg1<>reg2 then
begin
instr:=taicpu.op_reg_reg(fpumovinstr[size],reg1,reg2);
list.Concat(instr);
{ Notify the register allocator that we have written a move instruction so
it can try to eliminate it. }
add_move_instruction(instr);
end;
op:=fpumovinstr[fromsize,tosize];
instr:=taicpu.op_reg_reg(op,reg1,reg2);
list.Concat(instr);
{ Notify the register allocator that we have written a move instruction so
it can try to eliminate it. }
if (op = A_FMOVS) or
(op = A_FMOVD) then
add_move_instruction(instr);
end;
procedure TCgSparc.a_loadfpu_ref_reg(list:TAsmList;size:tcgsize;const ref:TReference;reg:tregister);
procedure TCgSparc.a_loadfpu_ref_reg(list:TAsmList;fromsize,tosize:tcgsize;const ref:TReference;reg:tregister);
const
FpuLoadInstr : Array[OS_F32..OS_F64] of TAsmOp =
(A_LDF,A_LDDF);
var
tmpreg: tregister;
begin
handle_load_store(list,false,fpuloadinstr[size],reg,ref);
if (fromsize<>tosize) then
begin
tmpreg:=reg;
reg:=getfpuregister(list,fromsize);
end;
handle_load_store(list,false,fpuloadinstr[fromsize],reg,ref);
if (fromsize<>tosize) then
a_loadfpu_reg_reg(list,fromsize,tosize,reg,tmpreg);
end;
procedure TCgSparc.a_loadfpu_reg_ref(list:TAsmList;size:tcgsize;reg:tregister;const ref:TReference);
procedure TCgSparc.a_loadfpu_reg_ref(list:TAsmList;fromsize,tosize:tcgsize;reg:tregister;const ref:TReference);
const
FpuLoadInstr : Array[OS_F32..OS_F64] of TAsmOp =
(A_STF,A_STDF);
var
tmpreg: tregister;
begin
handle_load_store(list,true,fpuloadinstr[size],reg,ref);
if (fromsize<>tosize) then
begin
tmpreg:=getfpuregister(list,tosize);
a_loadfpu_reg_reg(list,fromsize,tosize,reg,tmpreg);
reg:=tmpreg;
end;
handle_load_store(list,true,fpuloadinstr[tosize],reg,ref);
end;

View File

@ -40,7 +40,7 @@ interface
{ procedure second_chararray_to_string;override; }
{ procedure second_char_to_string;override; }
procedure second_int_to_real;override;
procedure second_real_to_real;override;
{ procedure second_real_to_real;override; }
{ procedure second_cord_to_pointer;override; }
{ procedure second_proc_to_procvar;override; }
{ procedure second_bool_to_int;override; }
@ -117,7 +117,7 @@ implementation
begin
location_force_mem(current_asmdata.CurrAsmList,left.location);
{ Load memory in fpu register }
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F32,left.location.reference,location.register);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F32,OS_F32,left.location.reference,location.register);
tg.ungetiftemp(current_asmdata.CurrAsmList,left.location.reference);
{ Convert value in fpu register from integer to float }
case tfloatdef(resultdef).floattype of
@ -156,7 +156,7 @@ implementation
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,OS_F64);
location_force_mem(current_asmdata.CurrAsmList,left.location);
{ Load memory in fpu register }
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F32,left.location.reference,location.register);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F32,OS_F32,left.location.reference,location.register);
tg.ungetiftemp(current_asmdata.CurrAsmList,left.location.reference);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FiTOd,location.register,location.register));
@ -175,7 +175,7 @@ implementation
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit($41f00000));
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit(0));
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,href,hregister);
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,OS_F64,OS_F64,href,hregister);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_FADDD,location.register,hregister,location.register));
cg.a_label(current_asmdata.CurrAsmList,l2);
@ -194,6 +194,7 @@ implementation
end;
(*
procedure tsparctypeconvnode.second_real_to_real;
const
conv_op : array[tfloattype,tfloattype] of tasmop = (
@ -217,7 +218,7 @@ implementation
location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,left.location.register,location.register));
end;
*)
procedure tsparctypeconvnode.second_int_to_bool;
var

View File

@ -72,9 +72,9 @@ unit cgx86;
procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override;
{ fpu move instructions }
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference); override;
procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
{ vector register move instructions }
procedure a_loadmm_reg_reg(list: TAsmList; fromsize, tosize : tcgsize;reg1, reg2: tregister;shuffle : pmmshuffle); override;
@ -152,6 +152,7 @@ unit cgx86;
uses
globals,verbose,systems,cutils,
symdef,defutil,paramgr,procinfo,
tgobj,
fmodule;
const
@ -490,7 +491,7 @@ unit cgx86;
end;
OS_F80 :
begin
op:=A_FSTP;
op:=A_FSTP;
s:=S_FX;
end;
OS_C64 :
@ -847,35 +848,51 @@ unit cgx86;
{ all fpu load routines expect that R_ST[0-7] means an fpu regvar and }
{ R_ST means "the current value at the top of the fpu stack" (JM) }
procedure tcgx86.a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister);
procedure tcgx86.a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);
var
href: treference;
op: tasmop;
s: topsize;
begin
if (reg1<>NR_ST) then
begin
list.concat(taicpu.op_reg(A_FLD,S_NO,rgfpu.correct_fpuregister(reg1,rgfpu.fpuvaroffset)));
floatloadops(tosize,op,s);
list.concat(taicpu.op_reg(op,s,rgfpu.correct_fpuregister(reg1,rgfpu.fpuvaroffset)));
inc_fpu_stack;
end;
if (reg2<>NR_ST) then
begin
list.concat(taicpu.op_reg(A_FSTP,S_NO,rgfpu.correct_fpuregister(reg2,rgfpu.fpuvaroffset)));
floatstoreops(tosize,op,s);
list.concat(taicpu.op_reg(op,s,rgfpu.correct_fpuregister(reg2,rgfpu.fpuvaroffset)));
dec_fpu_stack;
end;
{ OS_F80 < OS_C64, but OS_C64 fits perfectly in OS_F80 }
if (reg1=NR_ST) and
(reg2=NR_ST) and
(tosize<>OS_F80) and
(tosize<fromsize) then
begin
{ can't round down to lower precision in x87 :/ }
tg.gettemp(list,tcgsize2size[tosize],tt_persistent,href);
a_loadfpu_reg_ref(list,fromsize,tosize,NR_ST,href);
a_loadfpu_ref_reg(list,tosize,tosize,href,NR_ST);
end;
end;
procedure tcgx86.a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister);
procedure tcgx86.a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister);
begin
floatload(list,size,ref);
if (reg<>NR_ST) then
a_loadfpu_reg_reg(list,size,NR_ST,reg);
floatload(list,fromsize,ref);
a_loadfpu_reg_reg(list,fromsize,tosize,NR_ST,reg);
end;
procedure tcgx86.a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference);
procedure tcgx86.a_loadfpu_reg_ref(list: TAsmList; fromsize,tosize: tcgsize; reg: tregister; const ref: treference);
begin
if reg<>NR_ST then
a_loadfpu_reg_reg(list,size,reg,NR_ST);
floatstore(list,size,ref);
a_loadfpu_reg_reg(list,fromsize,tosize,reg,NR_ST);
floatstore(list,tosize,ref);
end;

View File

@ -192,12 +192,12 @@ implementation
LOC_CFPUREGISTER:
begin
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,
left.location.register,location.register);
left.location.size,left.location.register,location.register);
end;
LOC_REFERENCE,LOC_CREFERENCE:
begin
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,
def_cgsize(left.resultdef),
left.location.size,left.location.size,
left.location.reference,location.register);
end;
LOC_MMREGISTER,LOC_CMMREGISTER:

View File

@ -204,7 +204,7 @@ interface
begin
location.register:=NR_ST;
cg.a_loadfpu_ref_reg(current_asmdata.CurrAsmList,
def_cgsize(left.resultdef),
left.location.size,location.size,
left.location.reference,location.register);
emit_none(A_FCHS,S_NO);
end;
@ -212,7 +212,7 @@ interface
LOC_CFPUREGISTER:
begin
{ "load st,st" is ignored by the code generator }
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,left.location.register,NR_ST);
cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmList,left.location.size,location.size,left.location.register,NR_ST);
location.register:=NR_ST;
emit_none(A_FCHS,S_NO);
end;

View File

@ -295,7 +295,7 @@ implementation
{ then save it }
tg.GetTemp(list,extended_size,tt_persistent,hr);
saved[r.enum].ofs:=hr.offset;
cg.a_loadfpu_reg_ref(list,OS_FLOAT,r,hr);
cg.a_loadfpu_reg_ref(list,OS_FLOAT,OS_FLOAT,r,hr);
cg.a_reg_dealloc(list,r);
include(unusedregsfpu,r.enum);
inc(countunusedregsfpu);
@ -324,7 +324,7 @@ implementation
r2.number:=NR_FRAME_POINTER_REG;
reference_reset_base(hr,r2,saved[r.enum].ofs);
cg.a_reg_alloc(list,r);
cg.a_loadfpu_ref_reg(list,OS_FLOAT,hr,r);
cg.a_loadfpu_ref_reg(list,OS_FLOAT,OS_FLOAT,hr,r);
if not (r.enum in unusedregsfpu) then
{ internalerror(10)
in n386cal we always save/restore the reg *state*