mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 14:09:17 +02:00
* refactored i8086's thlcgcpu.location_force_mem:
o The checks for types that need special handling moved to separate methods, because they'll probably be used by the other hlcg.a_load*loc* methods as well. o Use voidcodepointertype and voidpointertype to avoid the ifs for checking the memory model. git-svn-id: trunk@27554 -
This commit is contained in:
parent
6810d643c4
commit
2e7aab0155
@ -41,6 +41,25 @@ interface
|
|||||||
{ thlcgcpu }
|
{ thlcgcpu }
|
||||||
|
|
||||||
thlcgcpu = class(thlcgx86)
|
thlcgcpu = class(thlcgx86)
|
||||||
|
private
|
||||||
|
{ checks whether the type needs special methodptr-like handling, when stored
|
||||||
|
in a LOC_REGISTER location. This applies to the following types:
|
||||||
|
- i8086 method pointers (incl. 6-byte mixed near + far),
|
||||||
|
- 6-byte records (only in the medium and compact memory model are these
|
||||||
|
loaded in a register)
|
||||||
|
- nested proc ptrs
|
||||||
|
When stored in a LOC_REGISTER tlocation, these types use both register
|
||||||
|
and registerhi with the following sizes:
|
||||||
|
|
||||||
|
register - cgsize = int_cgsize(voidcodepointertype.size)
|
||||||
|
registerhi - cgsize = int_cgsize(voidpointertype.size) }
|
||||||
|
function is_methodptr_like_type(d:tdef): boolean;
|
||||||
|
|
||||||
|
{ 4-byte records in registers need special handling as well. A record may
|
||||||
|
be located in registerhi:register if it was converted from a procvar or
|
||||||
|
in GetNextReg(register):register if it was converted from a longint.
|
||||||
|
We can tell between the two by checking whether registerhi has been set. }
|
||||||
|
function is_fourbyterecord(d:tdef): boolean;
|
||||||
protected
|
protected
|
||||||
procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
|
procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
|
||||||
public
|
public
|
||||||
@ -71,6 +90,27 @@ implementation
|
|||||||
|
|
||||||
{ thlcgcpu }
|
{ thlcgcpu }
|
||||||
|
|
||||||
|
function thlcgcpu.is_methodptr_like_type(d: tdef): boolean;
|
||||||
|
var
|
||||||
|
is_sixbyterecord,is_methodptr,is_nestedprocptr: Boolean;
|
||||||
|
begin
|
||||||
|
is_sixbyterecord:=(d.typ=recorddef) and (d.size=6);
|
||||||
|
is_methodptr:=(d.typ=procvardef)
|
||||||
|
and (po_methodpointer in tprocvardef(d).procoptions)
|
||||||
|
and not(po_addressonly in tprocvardef(d).procoptions);
|
||||||
|
is_nestedprocptr:=(d.typ=procvardef)
|
||||||
|
and is_nested_pd(tprocvardef(d))
|
||||||
|
and not(po_addressonly in tprocvardef(d).procoptions);
|
||||||
|
result:=is_sixbyterecord or is_methodptr or is_nestedprocptr;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function thlcgcpu.is_fourbyterecord(d: tdef): boolean;
|
||||||
|
begin
|
||||||
|
result:=(d.typ=recorddef) and (d.size=4);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure thlcgcpu.gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint);
|
procedure thlcgcpu.gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint);
|
||||||
var
|
var
|
||||||
locsize : tcgsize;
|
locsize : tcgsize;
|
||||||
@ -279,50 +319,20 @@ implementation
|
|||||||
procedure thlcgcpu.location_force_mem(list: TAsmList; var l: tlocation; size: tdef);
|
procedure thlcgcpu.location_force_mem(list: TAsmList; var l: tlocation; size: tdef);
|
||||||
var
|
var
|
||||||
r,tmpref: treference;
|
r,tmpref: treference;
|
||||||
is_sixbyterecord: Boolean;
|
|
||||||
is_fourbyterecord: Boolean;
|
|
||||||
is_methodptr: Boolean;
|
|
||||||
is_nestedprocptr: Boolean;
|
|
||||||
begin
|
begin
|
||||||
is_sixbyterecord:=(size.typ=recorddef) and (size.size=6);
|
if is_methodptr_like_type(size) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
|
||||||
is_fourbyterecord:=(size.typ=recorddef) and (size.size=4);
|
|
||||||
is_methodptr:=(size.typ=procvardef)
|
|
||||||
and (po_methodpointer in tprocvardef(size).procoptions)
|
|
||||||
and not(po_addressonly in tprocvardef(size).procoptions);
|
|
||||||
is_nestedprocptr:=(size.typ=procvardef)
|
|
||||||
and is_nested_pd(tprocvardef(size))
|
|
||||||
and not(po_addressonly in tprocvardef(size).procoptions);
|
|
||||||
|
|
||||||
{ handle i8086 method pointers (incl. 6-byte mixed near + far),
|
|
||||||
6-byte records and nested proc ptrs }
|
|
||||||
if (is_sixbyterecord or is_methodptr or is_nestedprocptr) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
|
|
||||||
begin
|
begin
|
||||||
tg.gethltemp(list,size,size.size,tt_normal,r);
|
tg.gethltemp(list,size,size.size,tt_normal,r);
|
||||||
tmpref:=r;
|
tmpref:=r;
|
||||||
|
|
||||||
if current_settings.x86memorymodel in x86_far_code_models then
|
a_load_reg_ref(list,voidcodepointertype,voidcodepointertype,l.register,tmpref);
|
||||||
begin
|
inc(tmpref.offset,voidcodepointertype.size);
|
||||||
cg.a_load_reg_ref(list,OS_32,OS_32,l.register,tmpref);
|
a_load_reg_ref(list,voidpointertype,voidpointertype,l.registerhi,tmpref);
|
||||||
inc(tmpref.offset,4);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
cg.a_load_reg_ref(list,OS_16,OS_16,l.register,tmpref);
|
|
||||||
inc(tmpref.offset,2);
|
|
||||||
end;
|
|
||||||
if current_settings.x86memorymodel in x86_far_data_models then
|
|
||||||
cg.a_load_reg_ref(list,OS_32,OS_32,l.registerhi,tmpref)
|
|
||||||
else
|
|
||||||
cg.a_load_reg_ref(list,OS_16,OS_16,l.registerhi,tmpref);
|
|
||||||
|
|
||||||
location_reset_ref(l,LOC_REFERENCE,l.size,0);
|
location_reset_ref(l,LOC_REFERENCE,l.size,0);
|
||||||
l.reference:=r;
|
l.reference:=r;
|
||||||
end
|
end
|
||||||
{ 4-byte records in registers need special handling as well. A record may
|
else if is_fourbyterecord(size) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
|
||||||
be located in registerhi:register if it was converted from a procvar or
|
|
||||||
in GetNextReg(register):register if it was converted from a longint.
|
|
||||||
We can tell between the two by checking whether registerhi has been set. }
|
|
||||||
else if is_fourbyterecord and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
|
|
||||||
begin
|
begin
|
||||||
tg.gethltemp(list,size,size.size,tt_normal,r);
|
tg.gethltemp(list,size,size.size,tt_normal,r);
|
||||||
tmpref:=r;
|
tmpref:=r;
|
||||||
|
Loading…
Reference in New Issue
Block a user