mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-27 03:29:22 +02:00
* refactored general loc->cgpara loading code in ncgcal into helpers in
ncgutil it can be used elsewhere too - removed the code that checks for 64 bit integer types in the float para loading code, since is_64bit() can never return true for a floatdef git-svn-id: trunk@15318 -
This commit is contained in:
parent
ef824c53f8
commit
e9b62c1294
@ -119,11 +119,6 @@ implementation
|
||||
|
||||
|
||||
procedure tcgcallparanode.push_value_para;
|
||||
{$ifdef i386}
|
||||
var
|
||||
href : treference;
|
||||
size : longint;
|
||||
{$endif i386}
|
||||
begin
|
||||
{ we've nothing to push when the size of the parameter is 0 }
|
||||
if left.resultdef.size=0 then
|
||||
@ -139,173 +134,9 @@ implementation
|
||||
be handled by cpupara }
|
||||
|
||||
if left.resultdef.typ=floatdef then
|
||||
begin
|
||||
{$ifdef i386}
|
||||
if tempcgpara.location^.loc<>LOC_REFERENCE then
|
||||
internalerror(200309291);
|
||||
case left.location.loc of
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
begin
|
||||
size:=align(TCGSize2Size[left.location.size],tempcgpara.alignment);
|
||||
if tempcgpara.location^.reference.index=NR_STACK_POINTER_REG then
|
||||
begin
|
||||
cg.g_stackpointer_alloc(current_asmdata.CurrAsmList,size);
|
||||
reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
|
||||
end
|
||||
else
|
||||
reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset,tempcgpara.alignment);
|
||||
cg.a_loadfpu_reg_ref(current_asmdata.CurrAsmList,left.location.size,left.location.size,left.location.register,href);
|
||||
end;
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
begin
|
||||
size:=align(tfloatdef(left.resultdef).size,tempcgpara.alignment);
|
||||
if tempcgpara.location^.reference.index=NR_STACK_POINTER_REG then
|
||||
begin
|
||||
cg.g_stackpointer_alloc(current_asmdata.CurrAsmList,size);
|
||||
reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
|
||||
end
|
||||
else
|
||||
reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset,tempcgpara.alignment);
|
||||
cg.a_loadmm_reg_ref(current_asmdata.CurrAsmList,left.location.size,left.location.size,left.location.register,href,mms_movescalar);
|
||||
end;
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE :
|
||||
begin
|
||||
size:=align(left.resultdef.size,tempcgpara.alignment);
|
||||
if (not use_fixed_stack) and
|
||||
(tempcgpara.location^.reference.index=NR_STACK_POINTER_REG) then
|
||||
cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.reference,tempcgpara)
|
||||
else
|
||||
begin
|
||||
reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset,tempcgpara.alignment);
|
||||
cg.g_concatcopy(current_asmdata.CurrAsmList,left.location.reference,href,size);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
internalerror(2002042430);
|
||||
end;
|
||||
{$else i386}
|
||||
case left.location.loc of
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
case tempcgpara.location^.loc of
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE,
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER,
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER :
|
||||
cg.a_loadmm_reg_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara,mms_movescalar);
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
begin
|
||||
location_force_fpureg(current_asmdata.CurrAsmList,left.location,false);
|
||||
cg.a_loadfpu_reg_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara);
|
||||
end;
|
||||
else
|
||||
internalerror(200204249);
|
||||
end;
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
case tempcgpara.location^.loc of
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
begin
|
||||
location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,false);
|
||||
cg.a_loadmm_reg_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara,mms_movescalar);
|
||||
end;
|
||||
{ Some targets pass floats in normal registers }
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER,
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE,
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
cg.a_loadfpu_reg_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.register,tempcgpara);
|
||||
else
|
||||
internalerror(2002042433);
|
||||
end;
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE:
|
||||
case tempcgpara.location^.loc of
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
cg.a_loadmm_ref_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.reference,tempcgpara,mms_movescalar);
|
||||
{ Some targets pass floats in normal registers }
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER,
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE,
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
cg.a_loadfpu_ref_cgpara(current_asmdata.CurrAsmList,left.location.size,left.location.reference,tempcgpara);
|
||||
else
|
||||
internalerror(2002042431);
|
||||
end;
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER :
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{ use cg64 only for int64, not for 8 byte records }
|
||||
if is_64bit(left.resultdef) then
|
||||
cg64.a_load64_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{ Only a_load_ref_cgpara supports multiple locations, when the
|
||||
value is still a const or in a register then write it
|
||||
to a reference first. This situation can be triggered
|
||||
by typecasting an int64 constant to a record of 8 bytes }
|
||||
if left.location.size in [OS_64,OS_S64] then
|
||||
location_force_mem(current_asmdata.CurrAsmList,left.location);
|
||||
{$endif not cpu64bitalu}
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
internalerror(2002042432);
|
||||
end;
|
||||
{$endif i386}
|
||||
end
|
||||
gen_loadfpu_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara,left.resultdef.size)
|
||||
else
|
||||
begin
|
||||
case left.location.loc of
|
||||
LOC_CONSTANT,
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER,
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE :
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{ use cg64 only for int64, not for 8 byte records }
|
||||
if is_64bit(left.resultdef) then
|
||||
cg64.a_load64_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{ Only a_load_ref_cgpara supports multiple locations, when the
|
||||
value is still a const or in a register then write it
|
||||
to a reference first. This situation can be triggered
|
||||
by typecasting an int64 constant to a record of 8 bytes }
|
||||
if left.location.size in [OS_64,OS_S64] then
|
||||
location_force_mem(current_asmdata.CurrAsmList,left.location);
|
||||
{$endif not cpu64bitalu}
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara);
|
||||
end;
|
||||
end;
|
||||
{$ifdef SUPPORT_MMX}
|
||||
LOC_MMXREGISTER,
|
||||
LOC_CMMXREGISTER:
|
||||
cg.a_loadmm_reg_cgpara(current_asmdata.CurrAsmList,OS_M64,left.location.register,tempcgpara,nil);
|
||||
{$endif SUPPORT_MMX}
|
||||
else
|
||||
internalerror(200204241);
|
||||
end;
|
||||
end;
|
||||
gen_load_locnonfpu_cgpara(current_asmdata.CurrAsmList,left.location,tempcgpara,is_64bit(left.resultdef))
|
||||
end;
|
||||
|
||||
|
||||
|
@ -65,6 +65,12 @@ interface
|
||||
procedure location_force_mem(list:TAsmList;var l:tlocation);
|
||||
procedure location_force_mmregscalar(list:TAsmList;var l: tlocation;maybeconst:boolean);
|
||||
procedure location_force_mmreg(list:TAsmList;var l: tlocation;maybeconst:boolean);
|
||||
|
||||
{ load a location of a floatdef into a cgpara }
|
||||
procedure gen_loadfpu_loc_cgpara(list:TAsmList;const l: tlocation;const cgpara: tcgpara;locintsize: longint);
|
||||
{ load a location of a non-floatdef into a cgpara }
|
||||
procedure gen_load_locnonfpu_cgpara(list:TAsmList;const l: tlocation;const cgpara: tcgpara; is64bitint: boolean);
|
||||
|
||||
procedure register_maybe_adjust_setbase(list: TAsmList; var l: tlocation; setbase: aint);
|
||||
|
||||
{ Retrieve the location of the data pointed to in location l, when the location is
|
||||
@ -775,6 +781,193 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_loadfpu_loc_cgpara(list: TAsmList; const l: tlocation;const cgpara: tcgpara;locintsize: longint);
|
||||
var
|
||||
{$ifdef i386}
|
||||
href : treference;
|
||||
size : longint;
|
||||
{$else i386}
|
||||
tmploc : tlocation;
|
||||
{$endif i386}
|
||||
begin
|
||||
{$ifdef i386}
|
||||
if cgpara.location^.loc<>LOC_REFERENCE then
|
||||
internalerror(200309291);
|
||||
case l.loc of
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
begin
|
||||
size:=align(locintsize,cgpara.alignment);
|
||||
if (not use_fixed_stack) and
|
||||
(cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
|
||||
begin
|
||||
cg.g_stackpointer_alloc(list,size);
|
||||
reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
|
||||
end
|
||||
else
|
||||
reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
|
||||
cg.a_loadfpu_reg_ref(list,l.size,l.size,l.register,href);
|
||||
end;
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
begin
|
||||
{ can't use TCGSize2Size[l.size], because the size of an
|
||||
80 bit extended parameter can be either 10 or 12 bytes }
|
||||
size:=align(locintsize,cgpara.alignment);
|
||||
if (not use_fixed_stack) and
|
||||
(cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
|
||||
begin
|
||||
cg.g_stackpointer_alloc(list,size);
|
||||
reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
|
||||
end
|
||||
else
|
||||
reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
|
||||
cg.a_loadmm_reg_ref(list,l.size,l.size,l.register,href,mms_movescalar);
|
||||
end;
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE :
|
||||
begin
|
||||
size:=align(locintsize,cgpara.alignment);
|
||||
if (not use_fixed_stack) and
|
||||
(cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
|
||||
cg.a_load_ref_cgpara(list,l.size,l.reference,cgpara)
|
||||
else
|
||||
begin
|
||||
reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
|
||||
cg.g_concatcopy(list,l.reference,href,size);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
internalerror(2002042430);
|
||||
end;
|
||||
{$else i386}
|
||||
case l.loc of
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
case cgpara.location^.loc of
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE,
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER,
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER :
|
||||
cg.a_loadmm_reg_cgpara(list,l.size,l.register,cgpara,mms_movescalar);
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
begin
|
||||
tmploc:=l;
|
||||
location_force_fpureg(list,tmploc,false);
|
||||
cg.a_loadfpu_reg_cgpara(list,tmploc.size,tmploc.register,cgpara);
|
||||
end;
|
||||
else
|
||||
internalerror(200204249);
|
||||
end;
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
case cgpara.location^.loc of
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
begin
|
||||
tmploc:=l;
|
||||
location_force_mmregscalar(list,tmploc,false);
|
||||
cg.a_loadmm_reg_cgpara(list,tmploc.size,tmploc.register,cgpara,mms_movescalar);
|
||||
end;
|
||||
{ Some targets pass floats in normal registers }
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER,
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE,
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
cg.a_loadfpu_reg_cgpara(list,l.size,l.register,cgpara);
|
||||
else
|
||||
internalerror(2002042433);
|
||||
end;
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE:
|
||||
case cgpara.location^.loc of
|
||||
LOC_MMREGISTER,
|
||||
LOC_CMMREGISTER:
|
||||
cg.a_loadmm_ref_cgpara(list,l.size,l.reference,cgpara,mms_movescalar);
|
||||
{ Some targets pass floats in normal registers }
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER,
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE,
|
||||
LOC_FPUREGISTER,
|
||||
LOC_CFPUREGISTER:
|
||||
cg.a_loadfpu_ref_cgpara(list,l.size,l.reference,cgpara);
|
||||
else
|
||||
internalerror(2002042431);
|
||||
end;
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER :
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{ Only a_load_ref_cgpara supports multiple locations, when the
|
||||
value is still a const or in a register then write it
|
||||
to a reference first. This situation can be triggered
|
||||
by typecasting an int64 constant to a record of 8 bytes }
|
||||
tmploc:=l;
|
||||
if tmploc.size in [OS_64,OS_S64] then
|
||||
location_force_mem(list,tmploc);
|
||||
cg.a_load_loc_cgpara(list,tmploc,cgpara);
|
||||
{$else not cpu64bitalu}
|
||||
cg.a_load_loc_cgpara(list,l,cgpara);
|
||||
{$endif not cpu64bitalu}
|
||||
end;
|
||||
else
|
||||
internalerror(2002042432);
|
||||
end;
|
||||
{$endif i386}
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_load_locnonfpu_cgpara(list: TAsmList; const l: tlocation;const cgpara: tcgpara; is64bitint: boolean);
|
||||
{$ifndef cpu64bitalu}
|
||||
var
|
||||
tmploc: tlocation;
|
||||
{$endif not cpu64bitalu}
|
||||
begin
|
||||
case l.loc of
|
||||
LOC_CONSTANT,
|
||||
LOC_REGISTER,
|
||||
LOC_CREGISTER,
|
||||
LOC_REFERENCE,
|
||||
LOC_CREFERENCE :
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{ use cg64 only for int64, not for 8 byte records }
|
||||
if is64bitint then
|
||||
cg64.a_load64_loc_cgpara(list,l,cgpara)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
{ Only a_load_ref_cgpara supports multiple locations, when the
|
||||
value is still a const or in a register then write it
|
||||
to a reference first. This situation can be triggered
|
||||
by typecasting an int64 constant to a record of 8 bytes }
|
||||
tmploc:=l;
|
||||
if tmploc.size in [OS_64,OS_S64] then
|
||||
location_force_mem(list,tmploc);
|
||||
cg.a_load_loc_cgpara(list,tmploc,cgpara);
|
||||
{$else not cpu64bitalu}
|
||||
cg.a_load_loc_cgpara(list,l,cgpara);
|
||||
{$endif not cpu64bitalu}
|
||||
end;
|
||||
end;
|
||||
{$ifdef SUPPORT_MMX}
|
||||
LOC_MMXREGISTER,
|
||||
LOC_CMMXREGISTER:
|
||||
cg.a_loadmm_reg_cgpara(list,OS_M64,l.register,cgpara,nil);
|
||||
{$endif SUPPORT_MMX}
|
||||
else
|
||||
internalerror(200204241);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure register_maybe_adjust_setbase(list: TAsmList; var l: tlocation; setbase: aint);
|
||||
var
|
||||
tmpreg: tregister;
|
||||
|
Loading…
Reference in New Issue
Block a user