* merged macos entry/exit code generation into the general one.

This commit is contained in:
olle 2003-08-08 15:49:24 +00:00
parent e88e9a0d93
commit c2fe8dbd99
5 changed files with 169 additions and 181 deletions

View File

@ -100,11 +100,9 @@ unit cgcpu;
private
procedure g_stackframe_entry_sysv(list : taasmoutput;localsize : longint);
procedure g_return_from_proc_sysv(list : taasmoutput;parasize : aword);
procedure g_stackframe_entry_aix(list : taasmoutput;localsize : longint);
procedure g_return_from_proc_aix(list : taasmoutput;parasize : aword);
(* NOT IN USE: *)
procedure g_stackframe_entry_mac(list : taasmoutput;localsize : longint);
(* NOT IN USE: *)
procedure g_return_from_proc_mac(list : taasmoutput;parasize : aword);
@ -999,43 +997,6 @@ const
{ *********** entry/exit code and address loading ************ }
procedure tcgppc.g_stackframe_entry(list : taasmoutput;localsize : longint);
begin
case target_info.abi of
abi_powerpc_macos:
g_stackframe_entry_mac(list,localsize);
abi_powerpc_sysv:
g_stackframe_entry_sysv(list,localsize);
abi_powerpc_aix:
g_stackframe_entry_aix(list,localsize);
else
internalerror(2204001);
end;
end;
procedure tcgppc.g_return_from_proc(list : taasmoutput;parasize : aword);
begin
case target_info.abi of
abi_powerpc_macos:
g_return_from_proc_mac(list,parasize);
abi_powerpc_sysv:
g_return_from_proc_sysv(list,parasize);
abi_powerpc_aix:
g_return_from_proc_aix(list,parasize);
else
internalerror(2204001);
end;
end;
procedure tcgppc.g_stackframe_entry_aix(list : taasmoutput;localsize : longint);
begin
g_stackframe_entry_sysv(list,localsize);
end;
procedure tcgppc.g_stackframe_entry_sysv(list : taasmoutput;localsize : longint);
{ generated the entry code of a procedure/function. Note: localsize is the }
{ sum of the size necessary for local variables and the maximum possible }
{ combined size of ALL the parameters of a procedure called by the current }
@ -1102,12 +1063,32 @@ const
r.enum:=R_INTREGISTER;
r.number:=NR_R0;
list.concat(taicpu.op_reg(A_MFLR,r));
{ ... in caller's rframe }
reference_reset_base(href,rsp,4);
{ ... in caller's frame }
case target_info.abi of
abi_powerpc_aix:
reference_reset_base(href,rsp,LA_LR_AIX);
abi_powerpc_sysv:
reference_reset_base(href,rsp,LA_LR_SYSV);
end;
list.concat(taicpu.op_reg_ref(A_STW,r,href));
a_reg_dealloc(list,r);
end;
{ save the CR if necessary in callers frame. }
if not (po_assembler in current_procinfo.procdef.procoptions) then
if target_info.abi = abi_powerpc_aix then
if false then { Not needed at the moment. }
begin
r.enum:=R_INTREGISTER;
r.number:=NR_R0;
a_reg_alloc(list,r);
r2.enum:=R_CR;
list.concat(taicpu.op_reg_reg(A_MFSPR,r,r2));
reference_reset_base(href,rsp,LA_CR_AIX);
list.concat(taicpu.op_reg_ref(A_STW,r,href));
a_reg_dealloc(list,r);
end;
{ !!! always allocate space for all registers for now !!! }
if not (po_assembler in current_procinfo.procdef.procoptions) then
{ if usesfpr or usesgpr then }
@ -1281,14 +1262,7 @@ const
end;
end;
procedure tcgppc.g_return_from_proc_aix(list : taasmoutput;parasize : aword);
begin
g_return_from_proc_sysv(list,parasize);
end;
procedure tcgppc.g_return_from_proc_sysv(list : taasmoutput;parasize : aword);
procedure tcgppc.g_return_from_proc(list : taasmoutput;parasize : aword);
var
regcounter,firstregfpu,firstreggpr: TRegister;
@ -1357,7 +1331,7 @@ const
a_loadfpu_ref_reg(list,OS_F64,href,regcounter);
dec(href.offset,8);
end;
inc(href.offset,4);
inc(href.offset,4);
end
else
reference_reset_base(href,r2,-4);
@ -1401,6 +1375,7 @@ const
end;
*)
{ if we didn't generate the return code, we've to do it now }
if genret then
begin
@ -1410,16 +1385,39 @@ const
a_op_const_reg(list,OP_ADD,OS_ADDR,tppcprocinfo(current_procinfo).localsize,r);
{ load link register? }
if not (po_assembler in current_procinfo.procdef.procoptions) then
if (pi_do_call in current_procinfo.flags) then
begin
r.enum:=R_INTREGISTER;
r.number:=NR_STACK_POINTER_REG;
reference_reset_base(href,r,4);
r.enum:=R_INTREGISTER;
r.number:=NR_R0;
list.concat(taicpu.op_reg_ref(A_LWZ,r,href));
list.concat(taicpu.op_reg(A_MTLR,r));
end;
begin
if (pi_do_call in current_procinfo.flags) then
begin
r.enum:=R_INTREGISTER;
r.number:=NR_STACK_POINTER_REG;
case target_info.abi of
abi_powerpc_aix:
reference_reset_base(href,r,LA_LR_AIX);
abi_powerpc_sysv:
reference_reset_base(href,r,LA_LR_SYSV);
end;
r.enum:=R_INTREGISTER;
r.number:=NR_R0;
list.concat(taicpu.op_reg_ref(A_LWZ,r,href));
list.concat(taicpu.op_reg(A_MTLR,r));
end;
{ restore the CR if necessary from callers frame}
if target_info.abi = abi_powerpc_aix then
if false then { Not needed at the moment. }
begin
r.enum:=R_INTREGISTER;
r.number:=NR_STACK_POINTER_REG;
reference_reset_base(href,r,LA_CR_AIX);
r.enum:=R_INTREGISTER;
r.number:=NR_R0;
list.concat(taicpu.op_reg_ref(A_LWZ,r,href));
r2.enum:=R_CR;
list.concat(taicpu.op_reg_reg(A_MTSPR,r,r2));
a_reg_dealloc(list,r);
end;
end;
list.concat(taicpu.op_none(A_BLR));
end;
end;
@ -1584,6 +1582,8 @@ const
procedure tcgppc.g_stackframe_entry_mac(list : taasmoutput;localsize : longint);
(* NOT IN USE *)
{ generated the entry code of a procedure/function. Note: localsize is the }
{ sum of the size necessary for local variables and the maximum possible }
{ combined size of ALL the parameters of a procedure called by the current }
@ -1626,7 +1626,7 @@ const
a_reg_alloc(list,r);
r2.enum:=R_CR;
list.concat(taicpu.op_reg_reg(A_MFSPR,r,r2));
reference_reset_base(href,rsp,LA_CR);
reference_reset_base(href,rsp,LA_CR_AIX);
list.concat(taicpu.op_reg_ref(A_STW,r,href));
a_reg_dealloc(list,r);
@ -1679,6 +1679,7 @@ const
end;
procedure tcgppc.g_return_from_proc_mac(list : taasmoutput;parasize : aword);
(* NOT IN USE *)
var
regcounter: TRegister;
@ -1701,7 +1702,7 @@ const
{ restore the CR if necessary from callers frame
( !!! always done currently ) }
reference_reset_base(href,rsp,LA_CR);
reference_reset_base(href,rsp,LA_CR_AIX);
r.enum:=R_INTREGISTER;
r.number:=NR_R0;
list.concat(taicpu.op_reg_ref(A_LWZ,r,href));
@ -1763,37 +1764,32 @@ const
reference_reset(tmpref);
tmpref.offset := ref2.offset;
tmpref.symbol := ref2.symbol;
tmpref.symaddr := refs_full;
tmpref.base.number := NR_NO;
r2.enum:=R_INTREGISTER;
r2.number:=NR_RTOC;
list.concat(taicpu.op_reg_reg_ref(A_ADDI,r,r2,tmpref));
if ref2.base.number <> NR_NO then
list.concat(taicpu.op_reg_reg_reg(A_ADD,r,r,ref2.base));
end
else
begin
reference_reset(tmpref);
tmpref.symbol := ref2.symbol;
tmpref.offset := 0;
tmpref.symaddr := refs_full;
tmpref.base.enum := R_INTREGISTER;
tmpref.base.number := NR_RTOC;
list.concat(taicpu.op_reg_ref(A_LWZ,r,tmpref));
if ref2.base.number <> NR_NO then
begin
list.concat(taicpu.op_reg_reg_reg(A_ADD,r,r,ref2.base));
end;
if ref2.offset <> 0 then
begin
reference_reset(tmpref);
tmpref.offset := ref2.offset;
tmpref.symaddr := refs_full;
tmpref.base:= r;
list.concat(taicpu.op_reg_ref(A_LA,r,tmpref));
end;
end;
if ref2.base.number <> NR_NO then
list.concat(taicpu.op_reg_reg_reg(A_ADD,r,r,ref2.base));
//list.concat(tai_comment.create(strpnew('*** a_loadaddr_ref_reg')));
end
else
@ -2430,112 +2426,73 @@ const
var
tmpreg: tregister;
tmpregUsed: Boolean;
tmpref: treference;
r : Tregister;
largeOffset: Boolean;
begin
tmpreg.number := NR_NO;
if assigned(ref.symbol) or
(cardinal(ref.offset-low(smallint)) >
high(smallint)-low(smallint)) then
if target_info.system = system_powerpc_macos then
begin
if target_info.system = system_powerpc_macos then
begin
if ref.base.number <> NR_NO then
begin
if macos_direct_globals then
begin
{Generates
add tempreg, ref.base, RTOC
op reg, symbolplusoffset, tempreg
which is eqvivalent to the more comprehensive
addi tempreg, RTOC, symbolplusoffset
add tempreg, ref.base, tempreg
op reg, tempreg
but which saves one instruction.}
largeOffset:= (cardinal(ref.offset-low(smallint)) >
high(smallint)-low(smallint));
{$ifndef newra}
tmpreg := get_scratch_reg_address(list);
tmpreg := get_scratch_reg_address(list);
{$else newra}
tmpreg := rg.getregisterint(list,OS_ADDR);
tmpreg := rg.getregisterint(list,OS_ADDR);
{$endif newra}
reference_reset(tmpref);
tmpref.symbol := ref.symbol;
tmpref.offset := ref.offset;
tmpref.symaddr := refs_full;
tmpref.base:= tmpreg;
tmpregUsed:= false;
r.enum:=R_INTREGISTER;
r.number:=NR_RTOC;
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,
ref.base,r));
list.concat(taicpu.op_reg_ref(op,reg,tmpref));
end
else
begin
{$ifndef newra}
tmpreg := get_scratch_reg_address(list);
{$else newra}
tmpreg := rg.getregisterint(list,OS_ADDR);
{$endif newra}
reference_reset(tmpref);
tmpref.symbol := ref.symbol;
tmpref.offset := 0;
tmpref.symaddr := refs_full;
tmpref.base.enum:= R_INTREGISTER;
tmpref.base.number:= NR_RTOC;
list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref));
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,
ref.base,tmpreg));
reference_reset(tmpref);
tmpref.offset := ref.offset;
tmpref.symaddr := refs_full;
tmpref.base:= tmpreg;
list.concat(taicpu.op_reg_ref(op,reg,tmpref));
end;
//list.concat(tai_comment.create(strpnew('**** a_load_store 1')));
end
if assigned(ref.symbol) then
begin //Load symbol's value
reference_reset(tmpref);
tmpref.symbol := ref.symbol;
tmpref.base.enum:= R_INTREGISTER;
tmpref.base.number:= NR_RTOC;
if macos_direct_globals then
list.concat(taicpu.op_reg_ref(A_LA,tmpreg,tmpref))
else
begin
if macos_direct_globals then
begin
reference_reset(tmpref);
tmpref.symbol := ref.symbol;
tmpref.offset := ref.offset;
tmpref.symaddr := refs_full;
tmpref.base.enum:= R_INTREGISTER;
tmpref.base.number:= NR_RTOC;
list.concat(taicpu.op_reg_ref(op,reg,tmpref));
end
else
begin
{$ifndef newra}
tmpreg := get_scratch_reg_address(list);
{$else newra}
tmpreg := rg.getregisterint(list,OS_ADDR);
{$endif newra}
reference_reset(tmpref);
tmpref.symbol := ref.symbol;
tmpref.offset := 0;
tmpref.symaddr := refs_full;
tmpref.base.enum:= R_INTREGISTER;
tmpref.base.number:= NR_RTOC;
list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref));
list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref));
tmpregUsed:= true;
end;
reference_reset(tmpref);
tmpref.offset := ref.offset;
tmpref.symaddr := refs_full;
tmpref.base:= tmpreg;
list.concat(taicpu.op_reg_ref(op,reg,tmpref));
if largeOffset then
begin //Add hi part of offset
reference_reset(tmpref);
tmpref.offset := Hi(ref.offset);
if tmpregUsed then
list.concat(taicpu.op_reg_reg_ref(A_ADDIS,tmpreg,
tmpreg,tmpref))
else
list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,tmpref));
tmpregUsed:= true;
end;
end;
//list.concat(tai_comment.create(strpnew('*** a_load_store 2')));
end;
if tmpregUsed then
begin
//Add content of base register
if ref.base.number <> NR_NO then
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,
ref.base,tmpreg));
//Make ref ready to be used by op
ref.symbol:= nil;
ref.base:= tmpreg;
if largeOffset then
ref.offset := Lo(ref.offset);
list.concat(taicpu.op_reg_ref(op,reg,ref));
//list.concat(tai_comment.create(strpnew('*** a_load_store indirect global')));
end
else
list.concat(taicpu.op_reg_ref(op,reg,ref));
end
else {if target_info.system <> system_powerpc_macos}
begin
if assigned(ref.symbol) or
(cardinal(ref.offset-low(smallint)) >
high(smallint)-low(smallint)) then
begin
{$ifndef newra}
tmpreg := get_scratch_reg_address(list);
@ -2555,9 +2512,11 @@ const
ref.symaddr := refs_l;
list.concat(taicpu.op_reg_ref(op,reg,ref));
end
end
else
list.concat(taicpu.op_reg_ref(op,reg,ref));
else
list.concat(taicpu.op_reg_ref(op,reg,ref));
end;
if (tmpreg.number <> NR_NO) then
{$ifndef newra}
free_scratch_reg(list,tmpreg);
@ -2713,7 +2672,13 @@ begin
end.
{
$Log$
Revision 1.116 2003-07-23 11:02:23 jonas
Revision 1.118 2003-08-08 15:50:45 olle
* merged macos entry/exit code generation into the general one.
Revision 1.117 2002/10/01 05:24:28 olle
* made a_load_store more robust and to accept large offsets and cleaned up code
Revision 1.116 2003/07/23 11:02:23 jonas
* don't use rg.getregisterint() anymore in g_stackframe_entry_*, because
the register colouring has already occurred then, use a hard-coded
register instead

View File

@ -707,16 +707,18 @@ uses
CPU Dependent Constants
*****************************************************************************}
LinkageAreaSize = 24;
LinkageAreaSizeAIX = 24;
LinkageAreaSizeSYSV = 8;
{ offset in the linkage area for the saved stack pointer }
LA_SP = 0;
{ offset in the linkage area for the saved conditional register}
LA_CR = 4;
LA_CR_AIX = 4;
{ offset in the linkage area for the saved link register}
LA_LR = 8;
LA_LR_AIX = 8;
LA_LR_SYSV = 4;
{ offset in the linkage area for the saved RTOC register}
LA_RTOC = 20;
LA_RTOC_AIX = 20;
PARENT_FRAMEPOINTER_OFFSET = 12;
{*****************************************************************************
@ -886,7 +888,10 @@ implementation
end.
{
$Log$
Revision 1.62 2003-07-23 11:00:09 jonas
Revision 1.63 2003-08-08 15:51:16 olle
* merged macos entry/exit code generation into the general one.
Revision 1.62 2003/07/23 11:00:09 jonas
* "lastsaveintreg" is RS_R31 instead of RS_R27 with -dnewra, because
there are no scratch regs anymore

View File

@ -49,7 +49,7 @@ unit cpupi;
implementation
uses
globtype,globals,
globtype,globals,systems,
cpubase,
aasmtai,
tgobj,
@ -69,7 +69,12 @@ unit cpupi;
begin
if not(po_assembler in procdef.procoptions) then
begin
ofs:=align(maxpushedparasize+LinkageAreaSize,16);
case target_info.abi of
abi_powerpc_aix:
ofs:=align(maxpushedparasize+LinkageAreaSizeAIX,16);
abi_powerpc_sysv:
ofs:=align(maxpushedparasize+LinkageAreaSizeSYSV,16);
end;
inc(procdef.parast.address_fixup,ofs);
// inc(selfpointer_offset,ofs);
// inc(vmtpointer_offset,ofs);
@ -114,7 +119,10 @@ begin
end.
{
$Log$
Revision 1.24 2003-07-06 20:25:03 jonas
Revision 1.25 2003-08-08 15:52:50 olle
* merged macos entry/exit code generation into the general one.
Revision 1.24 2003/07/06 20:25:03 jonas
* fixed ppc compiler
Revision 1.23 2003/06/13 21:19:32 peter

View File

@ -150,7 +150,7 @@ interface
);
tabi = (abi_default
,abi_powerpc_sysv,abi_powerpc_aix,abi_powerpc_macos
,abi_powerpc_sysv,abi_powerpc_aix
);
{*****************************************************************************
@ -695,7 +695,10 @@ finalization
end.
{
$Log$
Revision 1.66 2003-07-21 11:52:57 florian
Revision 1.67 2003-08-08 15:49:24 olle
* merged macos entry/exit code generation into the general one.
Revision 1.66 2003/07/21 11:52:57 florian
* very basic stuff for the arm
Revision 1.65 2003/05/31 16:17:27 marco

View File

@ -88,7 +88,8 @@ unit i_macos;
heapsize : 256*1024;
stacksize : 262144;
DllScanSupported:false;
use_function_relative_addresses : true
use_function_relative_addresses : true;
abi : abi_powerpc_aix;
);
implementation
@ -102,7 +103,13 @@ initialization
end.
{
$Log$
Revision 1.9 2003-06-18 10:19:07 olle
Revision 1.11 2003-08-08 15:54:01 olle
* merged macos entry/exit code generation into the general one.
Revision 1.10 2002/08/18 17:10:15 olle
+ abi_powerpc_macos added to TSystemInfo
Revision 1.9 2003/06/18 10:19:07 olle
* changed .p to .pas to make the compiler compile
Revision 1.8 2003/01/13 22:15:58 florian