mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-13 05:29:34 +02:00
* 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:
parent
ab79ccf277
commit
e815b923d5
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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}
|
||||
|
@ -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 :
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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*
|
||||
|
Loading…
Reference in New Issue
Block a user