+ optimized code generation on sparc

+ some stuff for pic code on sparc added
This commit is contained in:
florian 2005-01-23 17:14:21 +00:00
parent d5d331bced
commit 00324d38bf
4 changed files with 177 additions and 68 deletions

View File

@ -71,8 +71,10 @@ implementation
procedure tcgloadnode.generate_picvaraccess;
begin
{$ifndef sparc}
location.reference.base:=current_procinfo.got;
location.reference.symbol:=objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname+'@GOT',AB_EXTERNAL,AT_DATA);
{$endif sparc}
end;
@ -235,7 +237,8 @@ implementation
globalsymtable,
staticsymtable :
begin
if cs_create_pic in aktmoduleswitches then
if (target_info.system=system_powerpc_darwin) and
(cs_create_pic in aktmoduleswitches) then
begin
generate_picvaraccess;
if not(pi_needs_got in current_procinfo.flags) then
@ -951,7 +954,11 @@ begin
end.
{
$Log$
Revision 1.135 2005-01-04 16:37:09 peter
Revision 1.136 2005-01-23 17:14:21 florian
+ optimized code generation on sparc
+ some stuff for pic code on sparc added
Revision 1.135 2005/01/04 16:37:09 peter
* don't release temps for array of ansistring
Revision 1.134 2004/12/18 15:48:27 florian

View File

@ -354,6 +354,10 @@ implementation
{$ifdef SUPPORT_MMX}
registersmmx:=0;
{$endif SUPPORT_MMX}
if (cs_create_pic in aktmoduleswitches) and
not(symtableentry.typ in [paravarsym,localvarsym]) then
include(current_procinfo.flags,pi_needs_got);
case symtableentry.typ of
absolutevarsym :
;
@ -1177,7 +1181,11 @@ begin
end.
{
$Log$
Revision 1.142 2004-12-26 16:21:39 peter
Revision 1.143 2005-01-23 17:14:21 florian
+ optimized code generation on sparc
+ some stuff for pic code on sparc added
Revision 1.142 2004/12/26 16:21:39 peter
* resourcestring does not need exception frame
Revision 1.141 2004/12/07 13:52:54 michael

View File

@ -121,13 +121,10 @@ implementation
uses
globals,verbose,systems,cutils,
symdef,paramgr,
tgobj,procinfo,cpupi;
tgobj,
procinfo,cpupi;
{****************************************************************************
This is private property, keep out! :)
****************************************************************************}
function TCgSparc.IsSimpleRef(const ref:treference):boolean;
begin
if (ref.base=NR_NO) and (ref.index<>NR_NO) then
@ -153,6 +150,31 @@ implementation
ref.base:=ref.index;
ref.index:=NR_NO;
end;
if (cs_create_pic in aktmoduleswitches) and
assigned(ref.symbol) then
begin
tmpreg:=GetIntRegister(list,OS_INT);
reference_reset(tmpref);
tmpref.symbol:=ref.symbol;
tmpref.refaddr:=addr_pic;
if not(pi_needs_got in current_procinfo.flags) then
internalerror(200501161);
tmpref.index:=current_procinfo.got;
list.concat(taicpu.op_ref_reg(A_LD,tmpref,tmpreg));
ref.symbol:=nil;
if (ref.index<>NR_NO) then
begin
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.index,tmpreg));
ref.index:=tmpreg;
end
else
begin
if ref.base<>NR_NO then
ref.index:=tmpreg
else
ref.base:=tmpreg;
end;
end;
{ When need to use SETHI, do it first }
if assigned(ref.symbol) or
(ref.offset<simm13lo) or
@ -164,28 +186,31 @@ implementation
tmpref.offset:=ref.offset;
tmpref.refaddr:=addr_hi;
list.concat(taicpu.op_ref_reg(A_SETHI,tmpref,tmpreg));
{ Load the low part is left }
{$warning TODO Maybe not needed to load symbol}
tmpref.refaddr:=addr_lo;
list.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg));
{ The offset and symbol are loaded, reset in reference }
ref.offset:=0;
ref.symbol:=nil;
{ Only an index register or offset is allowed }
if tmpreg<>NR_NO then
if (ref.offset=0) and (ref.index=NR_NO) and
(ref.base=NR_NO) then
begin
if (ref.index<>NR_NO) then
begin
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.index,tmpreg));
ref.index:=tmpreg;
end
ref.refaddr:=addr_lo;
end
else
begin
{ Load the low part is left }
tmpref.refaddr:=addr_lo;
list.concat(taicpu.op_reg_ref_reg(A_OR,tmpreg,tmpref,tmpreg));
ref.offset:=0;
{ symbol is loaded }
ref.symbol:=nil;
end;
if (ref.index<>NR_NO) then
begin
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.index,tmpreg));
ref.index:=tmpreg;
end
else
begin
if ref.base<>NR_NO then
ref.index:=tmpreg
else
begin
if ref.base<>NR_NO then
ref.index:=tmpreg
else
ref.base:=tmpreg;
end;
ref.base:=tmpreg;
end;
end;
if (ref.base<>NR_NO) then
@ -236,10 +261,22 @@ implementation
procedure Tcgsparc.init_register_allocators;
begin
inherited init_register_allocators;
rg[R_INTREGISTER]:=Trgcpu.create(R_INTREGISTER,R_SUBD,
[RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,
RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7],
first_int_imreg,[]);
if (cs_create_pic in aktmoduleswitches) and
(pi_needs_got in current_procinfo.flags) then
begin
current_procinfo.got:=NR_L7;
rg[R_INTREGISTER]:=Trgcpu.create(R_INTREGISTER,R_SUBD,
[RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,
RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6],
first_int_imreg,[]);
end
else
rg[R_INTREGISTER]:=Trgcpu.create(R_INTREGISTER,R_SUBD,
[RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,
RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7],
first_int_imreg,[]);
rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBFS,
[RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7,
RS_F8,RS_F9,RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15,
@ -540,34 +577,62 @@ implementation
procedure TCgSparc.a_loadaddr_ref_reg(list : TAasmOutput;const ref : TReference;r : tregister);
var
tmpref : treference;
hreg : tregister;
tmpref,href : treference;
hreg,tmpreg : tregister;
begin
if (ref.base=NR_NO) and (ref.index<>NR_NO) then
href:=ref;
if (href.base=NR_NO) and (href.index<>NR_NO) then
internalerror(200306171);
if (cs_create_pic in aktmoduleswitches) and
assigned(href.symbol) then
begin
tmpreg:=GetIntRegister(list,OS_ADDR);
reference_reset(tmpref);
tmpref.symbol:=href.symbol;
tmpref.refaddr:=addr_pic;
if not(pi_needs_got in current_procinfo.flags) then
internalerror(200501161);
tmpref.base:=current_procinfo.got;
list.concat(taicpu.op_ref_reg(A_LD,tmpref,tmpreg));
href.symbol:=nil;
if (href.index<>NR_NO) then
begin
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,href.index,tmpreg));
href.index:=tmpreg;
end
else
begin
if href.base<>NR_NO then
href.index:=tmpreg
else
href.base:=tmpreg;
end;
end;
{ At least big offset (need SETHI), maybe base and maybe index }
if assigned(ref.symbol) or
(ref.offset<simm13lo) or
(ref.offset>simm13hi) then
if assigned(href.symbol) or
(href.offset<simm13lo) or
(href.offset>simm13hi) then
begin
hreg:=GetAddressRegister(list);
reference_reset(tmpref);
tmpref.symbol := ref.symbol;
tmpref.offset := ref.offset;
tmpref.symbol := href.symbol;
tmpref.offset := href.offset;
tmpref.refaddr := addr_hi;
list.concat(taicpu.op_ref_reg(A_SETHI,tmpref,hreg));
{ Only the low part is left }
tmpref.refaddr:=addr_lo;
list.concat(taicpu.op_reg_ref_reg(A_OR,hreg,tmpref,hreg));
if ref.base<>NR_NO then
if href.base<>NR_NO then
begin
if ref.index<>NR_NO then
if href.index<>NR_NO then
begin
list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.base,hreg));
list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.index,r));
list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,href.base,hreg));
list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,href.index,r));
end
else
list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.base,r));
list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,href.base,r));
end
else
begin
@ -577,33 +642,33 @@ implementation
end
else
{ At least small offset, maybe base and maybe index }
if ref.offset<>0 then
if href.offset<>0 then
begin
if ref.base<>NR_NO then
if href.base<>NR_NO then
begin
if ref.index<>NR_NO then
if href.index<>NR_NO then
begin
hreg:=GetAddressRegister(list);
list.concat(taicpu.op_reg_const_reg(A_ADD,ref.base,ref.offset,hreg));
list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,ref.index,r));
list.concat(taicpu.op_reg_const_reg(A_ADD,href.base,href.offset,hreg));
list.concat(taicpu.op_reg_reg_reg(A_ADD,hreg,href.index,r));
end
else
list.concat(taicpu.op_reg_const_reg(A_ADD,ref.base,ref.offset,r));
list.concat(taicpu.op_reg_const_reg(A_ADD,href.base,href.offset,r));
end
else
list.concat(taicpu.op_const_reg(A_MOV,ref.offset,r));
list.concat(taicpu.op_const_reg(A_MOV,href.offset,r));
end
else
{ Both base and index }
if ref.index<>NR_NO then
list.concat(taicpu.op_reg_reg_reg(A_ADD,ref.base,ref.index,r))
if href.index<>NR_NO then
list.concat(taicpu.op_reg_reg_reg(A_ADD,href.base,href.index,r))
else
{ Only base }
if ref.base<>NR_NO then
a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.base,r)
if href.base<>NR_NO then
a_load_reg_reg(list,OS_ADDR,OS_ADDR,href.base,r)
else
{ only offset, can be generated by absolute }
a_load_const_reg(list,OS_ADDR,ref.offset,r);
a_load_const_reg(list,OS_ADDR,href.offset,r);
end;
@ -650,7 +715,7 @@ implementation
if (a=0) then
list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],reg,NR_G0,reg))
else
a_op_const_reg_reg(list,op,size,a,reg,reg);
handle_reg_const_reg(list,TOpCG2AsmOp[op],reg,a,reg);
end;
@ -689,9 +754,8 @@ implementation
begin
if ispowerof2(a,power) then
begin
{ we can't do this easily in the asm. optimizer; overflow checking code
might depend on a set Y }
a_op_const_reg_reg(list,OP_SHL,size,power,src,dst);
{ can be done with a shift }
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
exit;
end;
end;
@ -942,6 +1006,11 @@ implementation
end
else
list.concat(Taicpu.Op_reg_const_reg(A_SAVE,NR_STACK_POINTER_REG,-LocalSize,NR_STACK_POINTER_REG));
if (cs_create_pic in aktmoduleswitches) and
(pi_needs_got in current_procinfo.flags) then
begin
current_procinfo.got:=NR_L7;
end;
end;
@ -1341,7 +1410,11 @@ begin
end.
{
$Log$
Revision 1.101 2005-01-07 16:22:54 florian
Revision 1.102 2005-01-23 17:14:21 florian
+ optimized code generation on sparc
+ some stuff for pic code on sparc added
Revision 1.101 2005/01/07 16:22:54 florian
+ implemented abi compliant handling of strucutured functions results on sparc platform
Revision 1.100 2005/01/01 13:19:09 florian

View File

@ -56,16 +56,19 @@ implementation
else if offset<0 then
GetReferenceString:=GetReferenceString+ToStr(offset);
case refaddr of
addr_hi :
addr_hi:
GetReferenceString:='%hi('+GetReferenceString+')';
addr_lo :
addr_lo:
GetReferenceString:='%lo('+GetReferenceString+')';
end;
end
else
begin
if assigned(symbol) then
{$ifdef extdebug}
if assigned(symbol) and
not(refaddr in [addr_pic,addr_lo]) then
internalerror(2003052601);
{$endif extdebug}
if base<>NR_NO then
GetReferenceString:=GetReferenceString+gas_regname(base);
if index=NR_NO then
@ -76,11 +79,24 @@ implementation
GetReferenceString:=GetReferenceString+'+'+ToStr(offset)
else if offset<0 then
GetReferenceString:=GetReferenceString+ToStr(offset);
{
else if (offset=0) and not(assigned(symbol)) then
GetReferenceString:=GetReferenceString+ToStr(offset);
}
if assigned(symbol) then
begin
if refaddr=addr_lo then
GetReferenceString:='%lo('+symbol.name+')+'+GetReferenceString
else
GetReferenceString:=symbol.name+'+'+GetReferenceString;
end;
end
else
begin
if Offset<>0 then
{$ifdef extdebug}
if (Offset<>0) or assigned(symbol) then
internalerror(2003052603);
{$endif extdebug}
GetReferenceString:=GetReferenceString+'+'+gas_regname(index);
end;
end;
@ -97,7 +113,8 @@ implementation
top_const:
getopstr:=tostr(longint(val));
top_ref:
if Oper.ref^.refaddr=addr_no then
if (oper.ref^.refaddr in [addr_no,addr_pic]) or ((oper.ref^.refaddr=addr_lo) and ((oper.ref^.base<>NR_NO) or
(oper.ref^.index<>NR_NO))) then
getopstr:='['+getreferencestring(ref^)+']'
else
getopstr:=getreferencestring(ref^);
@ -189,7 +206,11 @@ begin
end.
{
$Log$
Revision 1.30 2004-10-31 21:45:04 peter
Revision 1.31 2005-01-23 17:14:21 florian
+ optimized code generation on sparc
+ some stuff for pic code on sparc added
Revision 1.30 2004/10/31 21:45:04 peter
* generic tlocation
* move tlocation to cgutils