diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 2b7ec69fa3..ce79022f25 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -34,7 +34,7 @@ interface dos, {$ENDIF USE_SYSUTILS} cclasses, - globals, + globtype,globals, aasmbase,aasmtai,aasmcpu, assemble; @@ -56,13 +56,18 @@ interface public procedure WriteTree(p:TAAsmoutput);override; procedure WriteAsmList;override; + private + setcount: longint; + procedure WriteDecodedSleb128(a: aint); + procedure WriteDecodedUleb128(a: aword); + function NextSetLabel: string; end; implementation uses - cutils,globtype,systems, + cutils,systems, fmodule,finput,verbose, itcpugas ; @@ -190,6 +195,12 @@ implementation { GNU Assembler writer } {****************************************************************************} + function TGNUAssembler.NextSetLabel: string; + begin + inc(setcount); + result := target_asm.labelprefix+'$set$'+tostr(setcount); + end; + function TGNUAssembler.sectionname(atype:tasmsectiontype;const aname:string):string; const secnames : array[tasmsectiontype] of string[12] = ('', @@ -264,6 +275,53 @@ implementation end; + procedure TGNUAssembler.WriteDecodedUleb128(a: aword); + var + b: byte; + begin + repeat + b := a and $7f; + a := a shr 7; + if (a <> 0) then + b := b or $80; + AsmWrite(tostr(b)); + if (a <> 0) then + AsmWrite(',') + else + break; + until false; + end; + + + procedure TGNUAssembler.WriteDecodedSleb128(a: aint); + var + b, size: byte; + neg, more: boolean; + begin + more := true; + neg := a < 0; + size := sizeof(a)*8; + repeat + b := a and $7f; + a := a shr 7; + if (neg) then + a := a or -(1 shl (size - 7)); + if (((a = 0) and + (a and $40 = 0)) or + ((a = -1) and + (a and $40 <> 0))) then + more := false + else + b := b or $80; + AsmWrite(tostr(b)); + if (more) then + AsmWrite(',') + else + break; + until false; + end; + + procedure TGNUAssembler.WriteTree(p:TAAsmoutput); function needsObject(hp : tai_symbol) : boolean; @@ -284,7 +342,7 @@ implementation hp : tai; hp1 : tailineinfo; consttyp : taitype; - s : string; + s,t : string; i,pos,l : longint; InlineLevel : longint; last_align : longint; @@ -524,35 +582,63 @@ implementation ait_const_rva_symbol, ait_const_indirect_symbol : begin - AsmWrite(ait_const2str[hp.typ]); - consttyp:=hp.typ; - l:=0; - repeat - if assigned(tai_const(hp).sym) then - begin - if assigned(tai_const(hp).endsym) then - s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name + if (target_info.system in [system_powerpc_darwin,system_i386_darwin]) and + (hp.typ in [ait_const_uleb128bit,ait_const_sleb128bit]) then + begin + AsmWrite(ait_const2str[ait_const_8bit]); + case hp.typ of + ait_const_uleb128bit: + WriteDecodedUleb128(aword(tai_const(hp).value)); + ait_const_sleb128bit: + WriteDecodedSleb128(aint(tai_const(hp).value)); + end + end + else + begin + AsmWrite(ait_const2str[hp.typ]); + consttyp:=hp.typ; + l:=0; + t := ''; + repeat + if assigned(tai_const(hp).sym) then + begin + if assigned(tai_const(hp).endsym) then + begin + if (target_info.system in [system_powerpc_darwin,system_i386_darwin]) then + begin + s := NextSetLabel; + t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name; + end + else + s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name + end + else + s:=tai_const(hp).sym.name; + if tai_const(hp).value<>0 then + s:=s+tostr_with_plus(tai_const(hp).value); + end else - s:=tai_const(hp).sym.name; - if tai_const(hp).value<>0 then - s:=s+tostr_with_plus(tai_const(hp).value); - end - else - s:=tostr(tai_const(hp).value); - AsmWrite(s); - inc(l,length(s)); - { Values with symbols are written on a single line to improve - reading of the .s file (PFV) } - if assigned(tai_const(hp).sym) or - not(CurrSecType in [sec_data,sec_rodata]) or - (l>line_length) or - (hp.next=nil) or - (tai(hp.next).typ<>consttyp) or - assigned(tai_const(hp.next).sym) then - break; - hp:=tai(hp.next); - AsmWrite(','); - until false; + s:=tostr(tai_const(hp).value); + AsmWrite(s); + inc(l,length(s)); + { Values with symbols are written on a single line to improve + reading of the .s file (PFV) } + if assigned(tai_const(hp).sym) or + not(CurrSecType in [sec_data,sec_rodata]) or + (l>line_length) or + (hp.next=nil) or + (tai(hp.next).typ<>consttyp) or + assigned(tai_const(hp.next).sym) then + break; + hp:=tai(hp.next); + AsmWrite(','); + until false; + if (t <> '') then + begin + AsmLn; + AsmWrite(t); + end; + end; AsmLn; end; diff --git a/compiler/powerpc/agppcgas.pas b/compiler/powerpc/agppcgas.pas index 267df1db89..7d3eefd1f5 100644 --- a/compiler/powerpc/agppcgas.pas +++ b/compiler/powerpc/agppcgas.pas @@ -32,7 +32,8 @@ unit agppcgas; aasmbase, aasmtai, aggas, - cpubase; + cpubase, + globtype; type PPPCGNUAssembler=^TPPCGNUAssembler; @@ -40,13 +41,15 @@ unit agppcgas; function sectionname(atype:tasmsectiontype;const aname:string):string;override; procedure WriteExtraHeader;override; procedure WriteInstruction(hp : tai);override; + private + debugframecount: aint; end; implementation uses - cutils,globals,verbose,globtype, + cutils,globals,verbose, cgbase,cgutils,systems, assemble, itcpugas, @@ -88,7 +91,7 @@ unit agppcgas; asmbin : 'as'; asmcmd : '-o $OBJ $ASM'; supported_target : system_any; - flags : [af_allowdirect,af_needar,af_smartlink_sections]; + flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf]; labelprefix : 'L'; comment : '# '; ); @@ -101,9 +104,17 @@ unit agppcgas; function TPPCGNUAssembler.sectionname(atype:tasmsectiontype;const aname:string):string; begin - if (target_info.system = system_powerpc_darwin) and - (atype = sec_bss) then - atype := sec_code; + if (target_info.system = system_powerpc_darwin) then + case atype of + sec_bss: + atype := sec_code; + sec_debug_frame: + begin + result := '.section __DWARFA,__debug_frame,coalesced,no_toc+strip_static_syms'#10'EH_frame'+tostr(debugframecount)+':'; + inc(debugframecount); + exit; + end; + end; result := inherited sectionname(atype,aname); end;