mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 15:29:14 +02:00
* first implementation of pic for i386
git-svn-id: trunk@2107 -
This commit is contained in:
parent
2aa9653a61
commit
fb4557d71e
@ -194,6 +194,9 @@ unit cgobj;
|
|||||||
procedure a_call_name(list : taasmoutput;const s : string);virtual; abstract;
|
procedure a_call_name(list : taasmoutput;const s : string);virtual; abstract;
|
||||||
procedure a_call_reg(list : taasmoutput;reg : tregister);virtual; abstract;
|
procedure a_call_reg(list : taasmoutput;reg : tregister);virtual; abstract;
|
||||||
procedure a_call_ref(list : taasmoutput;ref : treference);virtual; abstract;
|
procedure a_call_ref(list : taasmoutput;ref : treference);virtual; abstract;
|
||||||
|
{ same as a_call_name, might be overriden on certain architectures to emit
|
||||||
|
static calls without usage of a got trampoline }
|
||||||
|
procedure a_call_name_static(list : taasmoutput;const s : string);virtual;
|
||||||
|
|
||||||
{ move instructions }
|
{ move instructions }
|
||||||
procedure a_load_const_reg(list : taasmoutput;size : tcgsize;a : aint;register : tregister);virtual; abstract;
|
procedure a_load_const_reg(list : taasmoutput;size : tcgsize;a : aint;register : tregister);virtual; abstract;
|
||||||
@ -2014,6 +2017,12 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcg.a_call_name_static(list : taasmoutput;const s : string);
|
||||||
|
begin
|
||||||
|
a_call_name(list,s);
|
||||||
|
end;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TCG64
|
TCG64
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
@ -103,8 +103,14 @@ interface
|
|||||||
is_reset,
|
is_reset,
|
||||||
is_unit,
|
is_unit,
|
||||||
in_interface, { processing the implementation part? }
|
in_interface, { processing the implementation part? }
|
||||||
in_global : boolean; { allow global settings }
|
{ allow global settings }
|
||||||
mode_switch_allowed : boolean; { Whether a mode switch is still allowed at this point in the parsing.}
|
in_global : boolean;
|
||||||
|
{ Whether a mode switch is still allowed at this point in the parsing.}
|
||||||
|
mode_switch_allowed,
|
||||||
|
{ generate pic helper which loads eip in ecx (for leave procedures) }
|
||||||
|
requires_ecx_pic_helper,
|
||||||
|
{ generate pic helper which loads eip in ebx (for non leave procedures) }
|
||||||
|
requires_ebx_pic_helper : boolean;
|
||||||
mainfilepos : tfileposinfo;
|
mainfilepos : tfileposinfo;
|
||||||
recompile_reason : trecompile_reason; { the reason why the unit should be recompiled }
|
recompile_reason : trecompile_reason; { the reason why the unit should be recompiled }
|
||||||
crc,
|
crc,
|
||||||
|
@ -36,6 +36,8 @@ unit cgcpu;
|
|||||||
type
|
type
|
||||||
tcg386 = class(tcgx86)
|
tcg386 = class(tcgx86)
|
||||||
procedure init_register_allocators;override;
|
procedure init_register_allocators;override;
|
||||||
|
procedure do_register_allocation(list:Taasmoutput;headertai:tai);override;
|
||||||
|
|
||||||
{ passing parameter using push instead of mov }
|
{ passing parameter using push instead of mov }
|
||||||
procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const cgpara : tcgpara);override;
|
procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const cgpara : tcgpara);override;
|
||||||
procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const cgpara : tcgpara);override;
|
procedure a_param_const(list : taasmoutput;size : tcgsize;a : aint;const cgpara : tcgpara);override;
|
||||||
@ -75,11 +77,11 @@ unit cgcpu;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure Tcg386.init_register_allocators;
|
procedure tcg386.init_register_allocators;
|
||||||
begin
|
begin
|
||||||
inherited init_register_allocators;
|
inherited init_register_allocators;
|
||||||
if cs_create_pic in aktmoduleswitches then
|
if cs_create_pic in aktmoduleswitches then
|
||||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP,RS_EBX])
|
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP])
|
||||||
else
|
else
|
||||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
|
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
|
||||||
rg[R_MMXREGISTER]:=trgcpu.create(R_MMXREGISTER,R_SUBNONE,[RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7],first_mm_imreg,[]);
|
rg[R_MMXREGISTER]:=trgcpu.create(R_MMXREGISTER,R_SUBNONE,[RS_XMM0,RS_XMM1,RS_XMM2,RS_XMM3,RS_XMM4,RS_XMM5,RS_XMM6,RS_XMM7],first_mm_imreg,[]);
|
||||||
@ -87,6 +89,13 @@ unit cgcpu;
|
|||||||
rgfpu:=Trgx86fpu.create;
|
rgfpu:=Trgx86fpu.create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure tcg386.do_register_allocation(list:Taasmoutput;headertai:tai);
|
||||||
|
begin
|
||||||
|
if pi_needs_got in current_procinfo.flags then
|
||||||
|
include(rg[R_INTREGISTER].used_in_proc,getsupreg(current_procinfo.got));
|
||||||
|
inherited do_register_allocation(list,headertai);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcg386.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const cgpara : tcgpara);
|
procedure tcg386.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;const cgpara : tcgpara);
|
||||||
var
|
var
|
||||||
@ -556,7 +565,7 @@ unit cgcpu;
|
|||||||
if make_global then
|
if make_global then
|
||||||
List.concat(Tai_symbol.Createname_global(labelname,AT_FUNCTION,0))
|
List.concat(Tai_symbol.Createname_global(labelname,AT_FUNCTION,0))
|
||||||
else
|
else
|
||||||
List.concat(Tai_symbol.Createname(labelname,AT_FUNCTION,0));
|
List.concat(Tai_symbol.Createname(labelname,AT_FUNCTION,0));
|
||||||
|
|
||||||
{ set param1 interface to self }
|
{ set param1 interface to self }
|
||||||
g_adjust_self_value(list,procdef,ioffset);
|
g_adjust_self_value(list,procdef,ioffset);
|
||||||
|
@ -116,6 +116,11 @@ interface
|
|||||||
|
|
||||||
procedure location_free(list: taasmoutput; const location : TLocation);
|
procedure location_free(list: taasmoutput; const location : TLocation);
|
||||||
|
|
||||||
|
function getprocalign : longint;
|
||||||
|
|
||||||
|
procedure gen_pic_helpers(list : taasmoutput);
|
||||||
|
procedure gen_got_load(list : taasmoutput);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -1339,7 +1344,7 @@ implementation
|
|||||||
href : treference;
|
href : treference;
|
||||||
begin
|
begin
|
||||||
case paraloc.loc of
|
case paraloc.loc of
|
||||||
LOC_REGISTER :
|
LOC_REGISTER :
|
||||||
begin
|
begin
|
||||||
{$IFDEF CPUPOWERPC64}
|
{$IFDEF CPUPOWERPC64}
|
||||||
if (paraloc.shiftval <> 0) then
|
if (paraloc.shiftval <> 0) then
|
||||||
@ -1884,6 +1889,25 @@ implementation
|
|||||||
cg.g_restore_standard_registers(list);
|
cg.g_restore_standard_registers(list);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure gen_got_load(list : taasmoutput);
|
||||||
|
begin
|
||||||
|
{ if loading got is necessary for more cpus, it can be moved
|
||||||
|
to the cg }
|
||||||
|
{$ifdef i386}
|
||||||
|
{ allocate PIC register }
|
||||||
|
if (cs_create_pic in aktmoduleswitches) and
|
||||||
|
(tf_pic_uses_got in target_info.flags) and
|
||||||
|
(pi_needs_got in current_procinfo.flags) then
|
||||||
|
begin
|
||||||
|
current_module.requires_ebx_pic_helper:=true;
|
||||||
|
cg.a_call_name_static(list,'fpc_geteipasebx');
|
||||||
|
list.concat(taicpu.op_sym_ofs_reg(A_ADD,S_L,objectlibrary.newasmsymbol('_GLOBAL_OFFSET_TABLE_',AB_EXTERNAL,AT_DATA),0,NR_PIC_OFFSET_REG));
|
||||||
|
list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
|
||||||
|
{ ecx could be used in leave procedures }
|
||||||
|
current_procinfo.got:=NR_EBX;
|
||||||
|
end;
|
||||||
|
{$endif i386}
|
||||||
|
end;
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
External handling
|
External handling
|
||||||
@ -2274,4 +2298,42 @@ implementation
|
|||||||
cg.g_maybe_testvmt(list,vmtreg,objdef);
|
cg.g_maybe_testvmt(list,vmtreg,objdef);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function getprocalign : longint;
|
||||||
|
begin
|
||||||
|
{ gprof uses 16 byte granularity }
|
||||||
|
if (cs_profile in aktmoduleswitches) then
|
||||||
|
result:=16
|
||||||
|
else
|
||||||
|
result:=aktalignment.procalign;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure gen_pic_helpers(list : taasmoutput);
|
||||||
|
var
|
||||||
|
href : treference;
|
||||||
|
begin
|
||||||
|
{ if other cpus require such helpers as well, it can be solved more cleaner }
|
||||||
|
{$ifdef i386}
|
||||||
|
if current_module.requires_ebx_pic_helper then
|
||||||
|
begin
|
||||||
|
new_section(list,sec_code,'fpc_geteipasebx',0);
|
||||||
|
list.concat(tai_symbol.Createname('fpc_geteipasebx',AT_FUNCTION,getprocalign));
|
||||||
|
reference_reset(href);
|
||||||
|
href.base:=NR_ESP;
|
||||||
|
list.concat(taicpu.op_ref_reg(A_MOV,S_L,href,NR_EBX));
|
||||||
|
list.concat(taicpu.op_none(A_RET,S_NO));
|
||||||
|
end;
|
||||||
|
if current_module.requires_ecx_pic_helper then
|
||||||
|
begin
|
||||||
|
new_section(list,sec_code,'fpc_geteipasecx',0);
|
||||||
|
list.concat(tai_symbol.Createname('fpc_geteipasecx',AT_FUNCTION,getprocalign));
|
||||||
|
reference_reset(href);
|
||||||
|
href.base:=NR_ESP;
|
||||||
|
list.concat(taicpu.op_ref_reg(A_MOV,S_L,href,NR_ECX));
|
||||||
|
list.concat(taicpu.op_none(A_RET,S_NO));
|
||||||
|
end;
|
||||||
|
{$endif i386}
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -371,7 +371,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
procedure AddUnit(const s:string);
|
procedure AddUnit(const s:string);
|
||||||
var
|
var
|
||||||
hp : tppumodule;
|
hp : tppumodule;
|
||||||
@ -812,13 +811,13 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure delete_duplicate_macros(p:TNamedIndexItem; arg:pointer);
|
procedure delete_duplicate_macros(p:TNamedIndexItem; arg:pointer);
|
||||||
var
|
var
|
||||||
hp: tsymentry;
|
hp: tsymentry;
|
||||||
begin
|
begin
|
||||||
hp:= current_module.localmacrosymtable.search(p.name);
|
hp:= current_module.localmacrosymtable.search(p.name);
|
||||||
if assigned(hp) then
|
if assigned(hp) then
|
||||||
current_module.localmacrosymtable.delete(hp);
|
current_module.localmacrosymtable.delete(hp);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure proc_unit;
|
procedure proc_unit;
|
||||||
|
|
||||||
@ -1172,6 +1171,9 @@ implementation
|
|||||||
gen_intf_wrappers(asmlist[al_procedures],current_module.globalsymtable);
|
gen_intf_wrappers(asmlist[al_procedures],current_module.globalsymtable);
|
||||||
gen_intf_wrappers(asmlist[al_procedures],current_module.localsymtable);
|
gen_intf_wrappers(asmlist[al_procedures],current_module.localsymtable);
|
||||||
|
|
||||||
|
{ generate pic helpers to load eip if necessary }
|
||||||
|
gen_pic_helpers(asmlist[al_procedures]);
|
||||||
|
|
||||||
{ generate a list of threadvars }
|
{ generate a list of threadvars }
|
||||||
{$ifndef segment_threadvars}
|
{$ifndef segment_threadvars}
|
||||||
InsertThreadvars;
|
InsertThreadvars;
|
||||||
@ -1494,6 +1496,8 @@ implementation
|
|||||||
{ generate wrappers for interfaces }
|
{ generate wrappers for interfaces }
|
||||||
gen_intf_wrappers(asmlist[al_procedures],current_module.localsymtable);
|
gen_intf_wrappers(asmlist[al_procedures],current_module.localsymtable);
|
||||||
|
|
||||||
|
{ generate pic helpers to load eip if necessary }
|
||||||
|
gen_pic_helpers(asmlist[al_procedures]);
|
||||||
{$ifndef segment_threadvars}
|
{$ifndef segment_threadvars}
|
||||||
{ generate a list of threadvars }
|
{ generate a list of threadvars }
|
||||||
InsertThreadvars;
|
InsertThreadvars;
|
||||||
|
@ -611,7 +611,6 @@ implementation
|
|||||||
oldfilepos : tfileposinfo;
|
oldfilepos : tfileposinfo;
|
||||||
templist : Taasmoutput;
|
templist : Taasmoutput;
|
||||||
headertai : tai;
|
headertai : tai;
|
||||||
curralign : longint;
|
|
||||||
begin
|
begin
|
||||||
{ the initialization procedure can be empty, then we
|
{ the initialization procedure can be empty, then we
|
||||||
don't need to generate anything. When it was an empty
|
don't need to generate anything. When it was an empty
|
||||||
@ -798,6 +797,11 @@ implementation
|
|||||||
aktproccode.insertlistafter(stackcheck_asmnode.currenttai,templist)
|
aktproccode.insertlistafter(stackcheck_asmnode.currenttai,templist)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ load got if necessary }
|
||||||
|
aktfilepos:=entrypos;
|
||||||
|
gen_got_load(templist);
|
||||||
|
aktproccode.insertlistafter(headertai,templist);
|
||||||
|
|
||||||
{ The procedure body is finished, we can now
|
{ The procedure body is finished, we can now
|
||||||
allocate the registers }
|
allocate the registers }
|
||||||
cg.do_register_allocation(aktproccode,headertai);
|
cg.do_register_allocation(aktproccode,headertai);
|
||||||
@ -866,15 +870,9 @@ implementation
|
|||||||
(cs_use_lineinfo in aktglobalswitches) then
|
(cs_use_lineinfo in aktglobalswitches) then
|
||||||
debuginfo.insertlineinfo(aktproccode);
|
debuginfo.insertlineinfo(aktproccode);
|
||||||
|
|
||||||
{ gprof uses 16 byte granularity }
|
|
||||||
if (cs_profile in aktmoduleswitches) then
|
|
||||||
curralign:=16
|
|
||||||
else
|
|
||||||
curralign:=aktalignment.procalign;
|
|
||||||
|
|
||||||
{ add the procedure to the al_procedures }
|
{ add the procedure to the al_procedures }
|
||||||
maybe_new_object_file(asmlist[al_procedures]);
|
maybe_new_object_file(asmlist[al_procedures]);
|
||||||
new_section(asmlist[al_procedures],sec_code,lower(procdef.mangledname),curralign);
|
new_section(asmlist[al_procedures],sec_code,lower(procdef.mangledname),getprocalign);
|
||||||
asmlist[al_procedures].concatlist(aktproccode);
|
asmlist[al_procedures].concatlist(aktproccode);
|
||||||
{ save local data (casetable) also in the same file }
|
{ save local data (casetable) also in the same file }
|
||||||
if assigned(aktlocaldata) and
|
if assigned(aktlocaldata) and
|
||||||
|
@ -55,6 +55,7 @@ unit cgx86;
|
|||||||
procedure a_call_name(list : taasmoutput;const s : string);override;
|
procedure a_call_name(list : taasmoutput;const s : string);override;
|
||||||
procedure a_call_reg(list : taasmoutput;reg : tregister);override;
|
procedure a_call_reg(list : taasmoutput;reg : tregister);override;
|
||||||
procedure a_call_ref(list : taasmoutput;ref : treference);override;
|
procedure a_call_ref(list : taasmoutput;ref : treference);override;
|
||||||
|
procedure a_call_name_static(list : taasmoutput;const s : string);override;
|
||||||
|
|
||||||
procedure a_op_const_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; a: aint; reg: TRegister); override;
|
procedure a_op_const_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; a: aint; reg: TRegister); override;
|
||||||
procedure a_op_const_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; a: aint; const ref: TReference); override;
|
procedure a_op_const_ref(list : taasmoutput; Op: TOpCG; size: TCGSize; a: aint; const ref: TReference); override;
|
||||||
@ -153,7 +154,8 @@ unit cgx86;
|
|||||||
uses
|
uses
|
||||||
globals,verbose,systems,cutils,
|
globals,verbose,systems,cutils,
|
||||||
dwarf,
|
dwarf,
|
||||||
symdef,defutil,paramgr,procinfo;
|
symdef,defutil,paramgr,procinfo,
|
||||||
|
fmodule;
|
||||||
|
|
||||||
const
|
const
|
||||||
TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE,A_ADD,A_AND,A_DIV,
|
TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE,A_ADD,A_AND,A_DIV,
|
||||||
@ -400,6 +402,7 @@ unit cgx86;
|
|||||||
hreg:=getaddressregister(list);
|
hreg:=getaddressregister(list);
|
||||||
href.refaddr:=addr_pic;
|
href.refaddr:=addr_pic;
|
||||||
href.base:=current_procinfo.got;
|
href.base:=current_procinfo.got;
|
||||||
|
include(current_procinfo.flags,pi_needs_got);
|
||||||
list.concat(taicpu.op_ref_reg(A_MOV,S_L,href,hreg));
|
list.concat(taicpu.op_ref_reg(A_MOV,S_L,href,hreg));
|
||||||
|
|
||||||
ref.symbol:=nil;
|
ref.symbol:=nil;
|
||||||
@ -544,13 +547,30 @@ unit cgx86;
|
|||||||
sym:=objectlibrary.newasmsymbol(s,AB_EXTERNAL,AT_FUNCTION);
|
sym:=objectlibrary.newasmsymbol(s,AB_EXTERNAL,AT_FUNCTION);
|
||||||
reference_reset_symbol(r,sym,0);
|
reference_reset_symbol(r,sym,0);
|
||||||
if cs_create_pic in aktmoduleswitches then
|
if cs_create_pic in aktmoduleswitches then
|
||||||
r.refaddr:=addr_pic
|
begin
|
||||||
|
{$ifdef i386}
|
||||||
|
include(current_procinfo.flags,pi_needs_got);
|
||||||
|
{$endif i386}
|
||||||
|
r.refaddr:=addr_pic
|
||||||
|
end
|
||||||
else
|
else
|
||||||
r.refaddr:=addr_full;
|
r.refaddr:=addr_full;
|
||||||
list.concat(taicpu.op_ref(A_CALL,S_NO,r));
|
list.concat(taicpu.op_ref(A_CALL,S_NO,r));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcgx86.a_call_name_static(list : taasmoutput;const s : string);
|
||||||
|
var
|
||||||
|
sym : tasmsymbol;
|
||||||
|
r : treference;
|
||||||
|
begin
|
||||||
|
sym:=objectlibrary.newasmsymbol(s,AB_EXTERNAL,AT_FUNCTION);
|
||||||
|
reference_reset_symbol(r,sym,0);
|
||||||
|
r.refaddr:=addr_full;
|
||||||
|
list.concat(taicpu.op_ref(A_CALL,S_NO,r));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgx86.a_call_reg(list : taasmoutput;reg : tregister);
|
procedure tcgx86.a_call_reg(list : taasmoutput;reg : tregister);
|
||||||
begin
|
begin
|
||||||
list.concat(taicpu.op_reg(A_CALL,S_NO,reg));
|
list.concat(taicpu.op_reg(A_CALL,S_NO,reg));
|
||||||
@ -718,6 +738,7 @@ unit cgx86;
|
|||||||
reference_reset_symbol(tmpref,ref.symbol,0);
|
reference_reset_symbol(tmpref,ref.symbol,0);
|
||||||
tmpref.refaddr:=addr_pic;
|
tmpref.refaddr:=addr_pic;
|
||||||
tmpref.base:=current_procinfo.got;
|
tmpref.base:=current_procinfo.got;
|
||||||
|
include(current_procinfo.flags,pi_needs_got);
|
||||||
list.concat(taicpu.op_ref_reg(A_MOV,S_L,tmpref,r));
|
list.concat(taicpu.op_ref_reg(A_MOV,S_L,tmpref,r));
|
||||||
{$endif x86_64}
|
{$endif x86_64}
|
||||||
if offset<>0 then
|
if offset<>0 then
|
||||||
@ -1817,16 +1838,6 @@ unit cgx86;
|
|||||||
cg.g_stackpointer_alloc(list,localsize);
|
cg.g_stackpointer_alloc(list,localsize);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ allocate PIC register }
|
|
||||||
if (cs_create_pic in aktmoduleswitches) and
|
|
||||||
(tf_pic_uses_got in target_info.flags) then
|
|
||||||
begin
|
|
||||||
a_call_name(list,'FPC_GETEIPINEBX');
|
|
||||||
list.concat(taicpu.op_sym_ofs_reg(A_ADD,tcgsize2opsize[OS_ADDR],objectlibrary.newasmsymbol('_GLOBAL_OFFSET_TABLE_',AB_EXTERNAL,AT_DATA),0,NR_PIC_OFFSET_REG));
|
|
||||||
list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
|
|
||||||
current_procinfo.got:=NR_PIC_OFFSET_REG;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,20 +28,22 @@ function cpuid_support : boolean;assembler;
|
|||||||
Tested under go32v1 and Linux on c6x86 with CpuID enabled and disabled (PFV)
|
Tested under go32v1 and Linux on c6x86 with CpuID enabled and disabled (PFV)
|
||||||
}
|
}
|
||||||
asm
|
asm
|
||||||
pushf
|
push ebx
|
||||||
pushf
|
pushf
|
||||||
pop eax
|
pushf
|
||||||
mov ebx,eax
|
pop eax
|
||||||
xor eax,200000h
|
mov ebx,eax
|
||||||
|
xor eax,200000h
|
||||||
push eax
|
push eax
|
||||||
popf
|
popf
|
||||||
pushf
|
pushf
|
||||||
pop eax
|
pop eax
|
||||||
popf
|
popf
|
||||||
and eax,200000h
|
and eax,200000h
|
||||||
and ebx,200000h
|
and ebx,200000h
|
||||||
cmp eax,ebx
|
cmp eax,ebx
|
||||||
setnz al
|
setnz al
|
||||||
|
pop ebx
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$asmmode ATT}
|
{$asmmode ATT}
|
||||||
@ -53,9 +55,9 @@ function sse_support : boolean;
|
|||||||
if cpuid_support then
|
if cpuid_support then
|
||||||
begin
|
begin
|
||||||
asm
|
asm
|
||||||
movl $1,%eax
|
movl $1,%eax
|
||||||
cpuid
|
cpuid
|
||||||
movl %edx,_edx
|
movl %edx,_edx
|
||||||
end;
|
end;
|
||||||
sse_support:=(_edx and $2000000)<>0;
|
sse_support:=(_edx and $2000000)<>0;
|
||||||
end
|
end
|
||||||
@ -96,12 +98,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function geteipasebx : pointer;assembler;[public,alias:'FPC_GETEIPINEBX'];
|
|
||||||
asm
|
|
||||||
movl (%esp),%ebx
|
|
||||||
ret
|
|
||||||
end;
|
|
||||||
|
|
||||||
{$ifndef FPC_SYSTEM_HAS_MOVE}
|
{$ifndef FPC_SYSTEM_HAS_MOVE}
|
||||||
{$define FPC_SYSTEM_HAS_MOVE}
|
{$define FPC_SYSTEM_HAS_MOVE}
|
||||||
procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];assembler;
|
procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];assembler;
|
||||||
|
Loading…
Reference in New Issue
Block a user