* 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:
Jonas Maebe 2010-05-22 16:05:04 +00:00
parent ef824c53f8
commit e9b62c1294
2 changed files with 195 additions and 171 deletions

View File

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

View File

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