* reverted changes from 2214, needs to be split into several commits

git-svn-id: trunk@2215 -
This commit is contained in:
tom_at_work 2006-01-08 01:03:15 +00:00
parent 6313a9be7b
commit 8c8e25353b
6 changed files with 71 additions and 146 deletions

View File

@ -61,11 +61,6 @@ interface
sec_debug_frame, sec_debug_frame,
{ ELF resources } { ELF resources }
sec_fpc sec_fpc
{$IFDEF POWERPC64}
,
{ PPC64/Linux Table of contents section }
sec_toc
{$ENDIF POWERPC64}
); );
TAsmSectionOption = (aso_alloconly,aso_executable); TAsmSectionOption = (aso_alloconly,aso_executable);
@ -594,9 +589,6 @@ implementation
'eh_frame', 'eh_frame',
'debug_frame', 'debug_frame',
'fpc' 'fpc'
{$IFDEF POWERPC64}
, 'toc'
{$ENDIF POWERPC64}
); );
begin begin
if aname<>'' then if aname<>'' then

View File

@ -301,7 +301,7 @@ interface
end; end;
tasmdirective=(asd_non_lazy_symbol_pointer,asd_indirect_symbol,asd_lazy_symbol_pointer, tasmdirective=(asd_non_lazy_symbol_pointer,asd_indirect_symbol,asd_lazy_symbol_pointer,
asd_extern,asd_nasm_import{$IFDEF POWERPC64}, asd_toc_entry{$ENDIF POWERPC64}); asd_extern,asd_nasm_import);
tai_directive = class(tailineinfo) tai_directive = class(tailineinfo)
name : pstring; name : pstring;
@ -633,7 +633,7 @@ interface
stabtypestr : array[tstabtype] of string[5]=('stabs','stabn','stabd'); stabtypestr : array[tstabtype] of string[5]=('stabs','stabn','stabd');
directivestr : array[tasmdirective] of string[24]=( directivestr : array[tasmdirective] of string[24]=(
'non_lazy_symbol_pointer','indirect_symbol','lazy_symbol_pointer', 'non_lazy_symbol_pointer','indirect_symbol','lazy_symbol_pointer',
'extern','nasm_import'{$IFDEF POWERPC64}, 'tc'{$ENDIF POWERPC64} 'extern','nasm_import'
); );
var var

View File

@ -214,9 +214,6 @@ implementation
'.eh_frame', '.eh_frame',
'.debug_frame', '.debug_frame',
'fpc.resptrs' 'fpc.resptrs'
{$IFDEF POWERPC64}
, '.toc'
{$ENDIF}
); );
secnames_pic : array[tasmsectiontype] of string[12] = ('', secnames_pic : array[tasmsectiontype] of string[12] = ('',
'.text','.data.rel','.data.rel','.bss','.threadvar', '.text','.data.rel','.data.rel','.bss','.threadvar',
@ -228,9 +225,6 @@ implementation
'.eh_frame', '.eh_frame',
'.debug_frame', '.debug_frame',
'fpc.resptrs' 'fpc.resptrs'
{$IFDEF POWERPC64}
, '.toc'
{$ENDIF}
); );
var var
secname : string; secname : string;
@ -812,7 +806,7 @@ implementation
AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24'); AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
AsmWriteLn('.globl .' + tai_symbol(hp).sym.name); AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function'); AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
{ the dotted name is the name of the actual function entry } { the dotted name is the name of the actual function }
AsmWrite('.'); AsmWrite('.');
end end
else else
@ -854,11 +848,15 @@ implementation
AsmWriteLn(s+':'); AsmWriteLn(s+':');
AsmWrite(#9'.size'#9); AsmWrite(#9'.size'#9);
if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
AsmWrite('.'); begin
AsmWrite('.');
end;
AsmWrite(tai_symbol_end(hp).sym.name); AsmWrite(tai_symbol_end(hp).sym.name);
AsmWrite(', '+s+' - '); AsmWrite(', '+s+' - ');
if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
AsmWrite('.'); begin
AsmWrite('.');
end;
AsmWriteLn(tai_symbol_end(hp).sym.name); AsmWriteLn(tai_symbol_end(hp).sym.name);
end; end;
end; end;

View File

@ -56,7 +56,7 @@ unit parabase;
E.g. the value $5544433 is passed in bits 40-63 of the register (others are zero), E.g. the value $5544433 is passed in bits 40-63 of the register (others are zero),
but they should actually be stored in the first bits of the stack location reserved but they should actually be stored in the first bits of the stack location reserved
for this value. So they have to be shifted left by this amount of bits before. } for this value. So they have to be shifted left by this amount of bits before. }
{$IFDEF POWERPC64}shiftval : byte;{$ENDIF POWERPC64} {$IFDEF CPUPOWERPC64}shiftval : byte;{$ENDIF CPUPOWERPC64}
register : tregister); register : tregister);
end; end;

View File

@ -115,7 +115,6 @@ begin
if (target_info.system <> system_powerpc_darwin) then if (target_info.system <> system_powerpc_darwin) then
s := s + refaddr2str[refaddr]; s := s + refaddr2str[refaddr];
end; end;
if (refaddr = addr_pic) then s := s + ')';
if (index = NR_NO) and (base <> NR_NO) then if (index = NR_NO) and (base <> NR_NO) then
begin begin

View File

@ -174,14 +174,6 @@ uses
symconst, symsym, fmodule, symconst, symsym, fmodule,
rgobj, tgobj, cpupi, procinfo, paramgr; rgobj, tgobj, cpupi, procinfo, paramgr;
function ref2string(const ref : treference) : string;
begin
result := 'base : ' + inttostr(ord(ref.base)) + ' index : ' + inttostr(ord(ref.index)) + ' refaddr : ' + inttostr(ord(ref.refaddr)) + ' offset : ' + inttostr(ref.offset) + ' symbol : ';
if (assigned(ref.symbol)) then
result := result + ref.symbol.name;
end;
{ helper function which calculate "magic" values for replacement of unsigned { helper function which calculate "magic" values for replacement of unsigned
division by constant operation by multiplication. See the PowerPC compiler division by constant operation by multiplication. See the PowerPC compiler
developer manual for more information } developer manual for more information }
@ -383,7 +375,7 @@ begin
location^.register) location^.register)
else else
{$IFDEF extdebug} {$IFDEF extdebug}
list.concat(tai_comment.create(strpnew('a_param_ref with OS_NO, sizeleft ' + inttostr(sizeleft)))); list.concat(tai_comment.create(strpnew('a_param_ref with OS_NO, sizeleft ' + inttostr(sizeleft))));
{$ENDIF extdebug} {$ENDIF extdebug}
{ load non-integral sized memory location into register. This { load non-integral sized memory location into register. This
@ -702,10 +694,6 @@ var
ref2: treference; ref2: treference;
begin begin
{$IFDEF EXTDEBUG}
list.concat(tai_comment.create(strpnew('a_load_ref_reg ' + ref2string(ref))));
{$ENDIF EXTDEBUG}
if not (fromsize in [OS_8, OS_S8, OS_16, OS_S16, OS_32, OS_S32, OS_64, OS_S64]) then if not (fromsize in [OS_8, OS_S8, OS_16, OS_S16, OS_32, OS_S32, OS_64, OS_S64]) then
internalerror(2002090902); internalerror(2002090902);
ref2 := ref; ref2 := ref;
@ -886,7 +874,7 @@ var
internalerror(2005061701); internalerror(2005061701);
end else if (a = 1) then begin end else if (a = 1) then begin
cg.a_load_reg_reg(exprasmlist, OS_INT, OS_INT, src, dst); cg.a_load_reg_reg(exprasmlist, OS_INT, OS_INT, src, dst);
end else if (a = -1) and (signed) then begin end else if (a = -1) then begin
{ note: only in the signed case possible..., may overflow } { note: only in the signed case possible..., may overflow }
exprasmlist.concat(taicpu.op_reg_reg(negops[cs_check_overflow in aktlocalswitches], dst, src)); exprasmlist.concat(taicpu.op_reg_reg(negops[cs_check_overflow in aktlocalswitches], dst, src));
end else if (ispowerof2(a, power, isNegPower)) then begin end else if (ispowerof2(a, power, isNegPower)) then begin
@ -1510,35 +1498,31 @@ begin
ref2 := ref; ref2 := ref;
fixref(list, ref2, OS_64); fixref(list, ref2, OS_64);
{ load a symbol } { load a symbol }
if (assigned(ref2.symbol) or (hasLargeOffset(ref2))) then begin if assigned(ref2.symbol) or (hasLargeOffset(ref2)) then begin
{ add the symbol's value to the base of the reference, and if the } { add the symbol's value to the base of the reference, and if the }
{ reference doesn't have a base, create one } { reference doesn't have a base, create one }
reference_reset(tmpref); reference_reset(tmpref);
tmpref.offset := ref2.offset; tmpref.offset := ref2.offset;
tmpref.symbol := ref2.symbol; tmpref.symbol := ref2.symbol;
tmpref.relsymbol := ref2.relsymbol; tmpref.relsymbol := ref2.relsymbol;
{ load 64 bit reference into r. If the reference already has a base register, { load 64 bit reference into r. If the reference already has a base register,
first load the 64 bit value into a temp register, then add it to the result first load the 64 bit value into a temp register, then add it to the result
register rD } register rD }
if (ref2.base <> NR_NO) then begin if (ref2.base <> NR_NO) then begin
{ already have a base register, so allocate a new one } { already have a base register, so allocate a new one }
tempreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE); tempreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
end else begin end else begin
tempreg := r; tempreg := r;
end; end;
{ code for loading a reference from a symbol into a register rD } { code for loading a reference from a symbol into a register rD }
(* (*
lis rX,SYM@highest lis rX,SYM@highest
ori rX,SYM@higher ori rX,SYM@higher
sldi rX,rX,32 sldi rX,rX,32
oris rX,rX,SYM@h oris rX,rX,SYM@h
ori rX,rX,SYM@l ori rX,rX,SYM@l
*) *)
{$IFDEF EXTDEBUG}
list.concat(tai_comment.create(strpnew('loadaddr_ref_reg ')));
{$ENDIF EXTDEBUG}
if (assigned(tmpref.symbol)) then begin
tmpref.refaddr := addr_highest; tmpref.refaddr := addr_highest;
list.concat(taicpu.op_reg_ref(A_LIS, tempreg, tmpref)); list.concat(taicpu.op_reg_ref(A_LIS, tempreg, tmpref));
tmpref.refaddr := addr_higher; tmpref.refaddr := addr_higher;
@ -1548,30 +1532,27 @@ begin
list.concat(taicpu.op_reg_reg_ref(A_ORIS, tempreg, tempreg, tmpref)); list.concat(taicpu.op_reg_reg_ref(A_ORIS, tempreg, tempreg, tmpref));
tmpref.refaddr := addr_low; tmpref.refaddr := addr_low;
list.concat(taicpu.op_reg_reg_ref(A_ORI, tempreg, tempreg, tmpref)); list.concat(taicpu.op_reg_reg_ref(A_ORI, tempreg, tempreg, tmpref));
end else
a_load_const_reg(list, OS_ADDR, tmpref.offset, tempreg);
{ if there's already a base register, add the temp register contents to { if there's already a base register, add the temp register contents to
the base register } the base register }
if (ref2.base <> NR_NO) then begin if (ref2.base <> NR_NO) then begin
list.concat(taicpu.op_reg_reg_reg(A_ADD, r, tempreg, ref2.base)); list.concat(taicpu.op_reg_reg_reg(A_ADD, r, tempreg, ref2.base));
end; end;
end else if (ref2.offset <> 0) then begin end else if ref2.offset <> 0 then begin
{ no symbol, but offset <> 0 } { no symbol, but offset <> 0 }
if (ref2.base <> NR_NO) then begin if ref2.base <> NR_NO then begin
a_op_const_reg_reg(list, OP_ADD, OS_64, ref2.offset, ref2.base, r) a_op_const_reg_reg(list, OP_ADD, OS_64, ref2.offset, ref2.base, r)
{ FixRef makes sure that "(ref.index <> R_NO) and (ref.offset <> 0)" never { FixRef makes sure that "(ref.index <> R_NO) and (ref.offset <> 0)" never
occurs, so now only ref.offset has to be loaded } occurs, so now only ref.offset has to be loaded }
end else begin end else begin
a_load_const_reg(list, OS_64, ref2.offset, r); a_load_const_reg(list, OS_64, ref2.offset, r)
end; end;
end else if (ref2.index <> NR_NO) then begin end else if ref.index <> NR_NO then
list.concat(taicpu.op_reg_reg_reg(A_ADD, r, ref2.base, ref2.index)) list.concat(taicpu.op_reg_reg_reg(A_ADD, r, ref2.base, ref2.index))
end else if (ref2.base <> NR_NO) and else if (ref2.base <> NR_NO) and
(r <> ref2.base) then begin (r <> ref2.base) then
a_load_reg_reg(list, OS_ADDR, OS_ADDR, ref2.base, r) a_load_reg_reg(list, OS_ADDR, OS_ADDR, ref2.base, r)
//list.concat(taicpu.op_reg_reg(A_MR, ref2.base, r)); else begin
end else begin
list.concat(taicpu.op_reg_const(A_LI, r, 0)); list.concat(taicpu.op_reg_const(A_LI, r, 0));
end; end;
end; end;
@ -1596,7 +1577,7 @@ begin
{$IFDEF extdebug} {$IFDEF extdebug}
if len > high(aint) then if len > high(aint) then
internalerror(2002072704); internalerror(2002072704);
list.concat(tai_comment.create(strpnew('g_concatcopy1 ' + inttostr(len) + ' bytes left '))); list.concat(tai_comment.create(strpnew('g_concatcopy')));
{$ENDIF extdebug} {$ENDIF extdebug}
{ make sure short loads are handled as optimally as possible; { make sure short loads are handled as optimally as possible;
note that the data here never overlaps, so we can do a forward note that the data here never overlaps, so we can do a forward
@ -1606,7 +1587,6 @@ begin
if (len <= maxmoveunit) then begin if (len <= maxmoveunit) then begin
src := source; dst := dest; src := source; dst := dest;
list.concat(tai_comment.create(strpnew('g_concatcopy3 ' + inttostr(src.offset) + ' ' + inttostr(dst.offset))));
while (len <> 0) do begin while (len <> 0) do begin
if (len = 8) then begin if (len = 8) then begin
a_load_ref_ref(list, OS_64, OS_64, src, dst); a_load_ref_ref(list, OS_64, OS_64, src, dst);
@ -1627,10 +1607,6 @@ begin
end; end;
exit; exit;
end; end;
{$IFDEF extdebug}
list.concat(tai_comment.create(strpnew('g_concatcopy2 ' + inttostr(len) + ' bytes left ')));
{$ENDIF extdebug}
count := len div maxmoveunit; count := len div maxmoveunit;
@ -1854,54 +1830,36 @@ var
begin begin
l:=objectlibrary.getasmsymbol(symbol+'$got'); l:=objectlibrary.getasmsymbol(symbol+'$got');
if not(assigned(l)) then begin if not(assigned(l)) then begin
l:=objectlibrary.newasmsymbol(symbol+'$got',AB_LOCAL, AT_LABEL); l:=objectlibrary.newasmsymbol(symbol+'$got',AB_COMMON,AT_DATA);
asmlist[al_picdata].concat(tai_section.create(sec_toc, '.toc', 8));
asmlist[al_picdata].concat(tai_symbol.create(l,0)); asmlist[al_picdata].concat(tai_symbol.create(l,0));
asmlist[al_picdata].concat(tai_directive.create(asd_toc_entry, symbol + '[TC], ' + symbol)); asmlist[al_picdata].concat(tai_const.create_indirect_sym(objectlibrary.newasmsymbol(symbol,AB_EXTERNAL,AT_DATA)));
asmlist[al_picdata].concat(tai_const.create_32bit(0));
end; end;
reference_reset_symbol(ref,l,0); reference_reset_symbol(ref,l,0);
ref.base := NR_R2; ref.base := NR_R2;
ref.refaddr := addr_pic; result := cg.rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,result);
result := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
{$IFDEF EXTDEBUG}
list.concat(tai_comment.create(strpnew('loading got reference for ' + symbol)));
{$ENDIF EXTDEBUG}
// cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,result);
list.concat(taicpu.op_reg_ref(A_LD, result, ref));
end; end;
function tcgppc.fixref(list: taasmoutput; var ref: treference; const size : TCgsize): boolean; function tcgppc.fixref(list: taasmoutput; var ref: treference; const size : TCgsize): boolean;
var var
tmpreg: tregister; tmpreg: tregister;
name : string; name : string;
begin begin
result := false; result := false;
{ Avoids recursion. } if (cs_create_pic in aktmoduleswitches) and (assigned(ref.symbol)) and (ref.symbol.defbind = AB_EXTERNAL) then begin
if (ref.refaddr = addr_pic) then exit; if (length(name) > 100) then internalerror(123456);
{$IFDEF EXTDEBUG}
list.concat(tai_comment.create(strpnew('fixref0 ' + ref2string(ref))));
{$ENDIF EXTDEBUG}
{ if we have to create PIC, add the symbol to the TOC/GOT }
if (cs_create_pic in aktmoduleswitches) and (assigned(ref.symbol)) then begin
tmpreg := load_got_symbol(list, ref.symbol.name); tmpreg := load_got_symbol(list, ref.symbol.name);
if (ref.base = NR_NO) then if (ref.base = NR_NO) then
ref.base := tmpreg ref.base := tmpreg
else if (ref.index = NR_NO) then else if (ref.index = NR_NO) then
ref.index := tmpreg ref.index := tmpreg
else begin else
a_op_reg_reg_reg(list, OP_ADD, OS_ADDR, ref.base, tmpreg, tmpreg); list.concat(taicpu.op_reg_reg_reg(A_ADD,ref.base,ref.base,tmpreg));
ref.base := tmpreg;
end;
ref.symbol := nil; ref.symbol := nil;
{$IFDEF EXTDEBUG}
list.concat(tai_comment.create(strpnew('fixref-pic ' + ref2string(ref))));
{$ENDIF EXTDEBUG}
end; end;
if (ref.base = NR_NO) then begin if (ref.base = NR_NO) then begin
ref.base := ref.index; ref.base := ref.index;
ref.index := NR_NO; ref.index := NR_NO;
end; end;
@ -1910,14 +1868,9 @@ begin
result := true; result := true;
tmpreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE); tmpreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
a_op_reg_reg_reg(list, OP_ADD, size, ref.base, ref.index, tmpreg); a_op_reg_reg_reg(list, OP_ADD, size, ref.base, ref.index, tmpreg);
ref.base := tmpreg;
ref.index := NR_NO; ref.index := NR_NO;
ref.base := tmpreg;
end; end;
if (ref.index <> NR_NO) and (assigned(ref.symbol) or (ref.offset <> 0)) then
internalerror(2006010506);
{$IFDEF EXTDEBUG}
list.concat(tai_comment.create(strpnew('fixref1 ' + ref2string(ref))));
{$ENDIF EXTDEBUG}
end; end;
procedure tcgppc.a_load_store(list: taasmoutput; op: tasmop; reg: tregister; procedure tcgppc.a_load_store(list: taasmoutput; op: tasmop; reg: tregister;
@ -1931,18 +1884,6 @@ begin
which is not possible to directly map to instructions of the PowerPC architecture } which is not possible to directly map to instructions of the PowerPC architecture }
if (ref.index <> NR_NO) and ((ref.offset <> 0) or (assigned(ref.symbol))) then if (ref.index <> NR_NO) and ((ref.offset <> 0) or (assigned(ref.symbol))) then
internalerror(200310131); internalerror(200310131);
{ if this is a PIC'ed address, handle it and exit }
if (ref.refaddr = addr_pic) then begin
if (ref.offset <> 0) then
internalerror(2006010501);
if (ref.index <> NR_NO) then
internalerror(2006010502);
if (not assigned(ref.symbol)) then
internalerror(200601050);
list.concat(taicpu.op_reg_ref(op, reg, ref));
exit;
end;
{ for some instructions we need to check that the offset is divisible by at { for some instructions we need to check that the offset is divisible by at
least four. If not, add the bytes which are "off" to the base register and least four. If not, add the bytes which are "off" to the base register and
@ -1962,12 +1903,10 @@ begin
ref.offset := (ref.offset div 4) * 4; ref.offset := (ref.offset div 4) * 4;
end; end;
end; end;
{$IFDEF EXTDEBUG}
list.concat(tai_comment.create(strpnew('a_load_store1 ' + BoolToStr(ref.refaddr = addr_pic))));
{$ENDIF EXTDEBUG}
{ if we have to load/store from a symbol or large addresses, use a temporary register { if we have to load/store from a symbol or large addresses, use a temporary register
containing the address } containing the address }
if (assigned(ref.symbol) or (hasLargeOffset(ref))) then begin if assigned(ref.symbol) or (hasLargeOffset(ref)) then begin
tmpreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE); tmpreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
if (hasLargeOffset(ref) and (ref.base = NR_NO)) then begin if (hasLargeOffset(ref) and (ref.base = NR_NO)) then begin
@ -1997,20 +1936,17 @@ begin
} }
tmpreg2 := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE); tmpreg2 := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
if (assigned(tmpref.symbol)) then begin tmpref.refaddr := addr_highest;
tmpref.refaddr := addr_highest; list.concat(taicpu.op_reg_ref(A_LIS, tmpreg, tmpref));
list.concat(taicpu.op_reg_ref(A_LIS, tmpreg, tmpref)); tmpref.refaddr := addr_higher;
tmpref.refaddr := addr_higher; list.concat(taicpu.op_reg_reg_ref(A_ORI, tmpreg, tmpreg, tmpref));
list.concat(taicpu.op_reg_reg_ref(A_ORI, tmpreg, tmpreg, tmpref));
tmpref.refaddr := addr_high; tmpref.refaddr := addr_high;
list.concat(taicpu.op_reg_ref(A_LIS, tmpreg2, tmpref)); list.concat(taicpu.op_reg_ref(A_LIS, tmpreg2, tmpref));
tmpref.refaddr := addr_low; tmpref.refaddr := addr_low;
list.concat(taicpu.op_reg_reg_ref(A_ORI, tmpreg2, tmpreg2, tmpref)); list.concat(taicpu.op_reg_reg_ref(A_ORI, tmpreg2, tmpreg2, tmpref));
list.concat(taicpu.op_reg_reg_const_const(A_RLDIMI, tmpreg2, tmpreg, 32, 0)); list.concat(taicpu.op_reg_reg_const_const(A_RLDIMI, tmpreg2, tmpreg, 32, 0));
end else
a_load_const_reg(list, OS_ADDR, tmpref.offset, tmpreg2);
reference_reset(tmpref); reference_reset(tmpref);
tmpref.base := ref.base; tmpref.base := ref.base;