|
@@ -48,8 +48,11 @@ interface
|
|
|
function sectionattrs_coff(atype:TAsmSectiontype):string;virtual;
|
|
|
procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
|
|
|
procedure WriteExtraHeader;virtual;
|
|
|
+ procedure WriteExtraFooter;virtual;
|
|
|
procedure WriteInstruction(hp: tai);
|
|
|
procedure WriteWeakSymbolDef(s: tasmsymbol); virtual;
|
|
|
+ procedure WriteAixStringConst(hp: tai_string);
|
|
|
+ procedure WriteAixIntConst(hp: tai_const);
|
|
|
public
|
|
|
function MakeCmdLine: TCmdStr; override;
|
|
|
procedure WriteTree(p:TAsmList);override;
|
|
@@ -475,7 +478,9 @@ implementation
|
|
|
system_i386_iphonesim,
|
|
|
system_powerpc64_darwin,
|
|
|
system_x86_64_darwin,
|
|
|
- system_arm_darwin:
|
|
|
+ system_arm_darwin,
|
|
|
+ system_powerpc_aix,
|
|
|
+ system_powerpc64_aix:
|
|
|
begin
|
|
|
if (atype in [sec_stub,sec_objc_data,sec_objc_const,sec_data_coalesced]) then
|
|
|
AsmWrite('.section ');
|
|
@@ -586,7 +591,7 @@ implementation
|
|
|
last_align:=alignment;
|
|
|
if alignment>1 then
|
|
|
begin
|
|
|
- if not(target_info.system in systems_darwin) then
|
|
|
+ if not(target_info.system in (systems_darwin+systems_aix)) then
|
|
|
begin
|
|
|
AsmWrite(#9'.balign '+tostr(alignment));
|
|
|
if use_op then
|
|
@@ -599,7 +604,7 @@ implementation
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
- { darwin as only supports .align }
|
|
|
+ { darwin and aix as only support .align }
|
|
|
if not ispowerof2(alignment,i) then
|
|
|
internalerror(2003010305);
|
|
|
AsmWrite(#9'.align '+tostr(i));
|
|
@@ -735,6 +740,28 @@ implementation
|
|
|
asmln;
|
|
|
end;
|
|
|
end
|
|
|
+ else if target_info.system in systems_aix then
|
|
|
+ begin
|
|
|
+ if tai_datablock(hp).is_global then
|
|
|
+ begin
|
|
|
+ asmwrite(#9'.globl ');
|
|
|
+ asmwriteln(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
|
|
|
+ asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
|
|
|
+ asmwriteln(':');
|
|
|
+ asmwrite(#9'.space ');
|
|
|
+ asmwriteln(tostr(tai_datablock(hp).size));
|
|
|
+ if not(LastSecType in [sec_data,sec_none]) then
|
|
|
+ writesection(LastSecType,'',secorder_default);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ asmwrite(#9'.lcomm ');
|
|
|
+ asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
|
|
|
+ asmwrite(',_data.bss_[RW],');
|
|
|
+ asmwrite(tostr(tai_datablock(hp).size)+',');
|
|
|
+ asmwriteln(tostr(last_align));
|
|
|
+ end;
|
|
|
+ end
|
|
|
else
|
|
|
begin
|
|
|
{$ifdef USE_COMM_IN_BSS}
|
|
@@ -818,19 +845,24 @@ implementation
|
|
|
begin
|
|
|
if assigned(tai_const(hp).sym) then
|
|
|
internalerror(200404292);
|
|
|
- AsmWrite(ait_const2str[aitconst_32bit]);
|
|
|
- if target_info.endian = endian_little then
|
|
|
+ if not(target_info.system in systems_aix) then
|
|
|
begin
|
|
|
- AsmWrite(tostr(longint(lo(tai_const(hp).value))));
|
|
|
- AsmWrite(',');
|
|
|
- AsmWrite(tostr(longint(hi(tai_const(hp).value))));
|
|
|
+ AsmWrite(ait_const2str[aitconst_32bit]);
|
|
|
+ if target_info.endian = endian_little then
|
|
|
+ begin
|
|
|
+ AsmWrite(tostr(longint(lo(tai_const(hp).value))));
|
|
|
+ AsmWrite(',');
|
|
|
+ AsmWrite(tostr(longint(hi(tai_const(hp).value))));
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ AsmWrite(tostr(longint(hi(tai_const(hp).value))));
|
|
|
+ AsmWrite(',');
|
|
|
+ AsmWrite(tostr(longint(lo(tai_const(hp).value))));
|
|
|
+ end;
|
|
|
end
|
|
|
else
|
|
|
- begin
|
|
|
- AsmWrite(tostr(longint(hi(tai_const(hp).value))));
|
|
|
- AsmWrite(',');
|
|
|
- AsmWrite(tostr(longint(lo(tai_const(hp).value))));
|
|
|
- end;
|
|
|
+ WriteAixIntConst(tai_const(hp));
|
|
|
AsmLn;
|
|
|
end;
|
|
|
{$endif cpu64bitaddr}
|
|
@@ -849,7 +881,19 @@ implementation
|
|
|
aitconst_darwin_dwarf_delta64,
|
|
|
aitconst_half16bit:
|
|
|
begin
|
|
|
- if (target_info.system in systems_darwin) and
|
|
|
+ { the AIX assembler (and for compatibility, the GNU
|
|
|
+ assembler when targeting AIX) automatically aligns
|
|
|
+ .short/.long/.llong to a multiple of 2/4/8 bytes. We
|
|
|
+ don't want that, since this may be data inside a packed
|
|
|
+ record -> use .vbyte instead (byte stream of fixed
|
|
|
+ length) }
|
|
|
+ if (target_info.system in systems_aix) and
|
|
|
+ (constdef in [aitconst_128bit,aitconst_64bit,aitconst_32bit,aitconst_16bit]) and
|
|
|
+ not assigned(tai_const(hp).sym) then
|
|
|
+ begin
|
|
|
+ WriteAixIntConst(tai_const(hp));
|
|
|
+ end
|
|
|
+ else if (target_info.system in systems_darwin) and
|
|
|
(constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
|
|
|
begin
|
|
|
AsmWrite(ait_const2str[aitconst_8bit]);
|
|
@@ -1023,31 +1067,36 @@ implementation
|
|
|
ait_string :
|
|
|
begin
|
|
|
pos:=0;
|
|
|
- for i:=1 to tai_string(hp).len do
|
|
|
- begin
|
|
|
- if pos=0 then
|
|
|
- begin
|
|
|
- AsmWrite(#9'.ascii'#9'"');
|
|
|
- pos:=20;
|
|
|
- end;
|
|
|
- ch:=tai_string(hp).str[i-1];
|
|
|
- case ch of
|
|
|
- #0, {This can't be done by range, because a bug in FPC}
|
|
|
- #1..#31,
|
|
|
- #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
|
|
|
- '"' : s:='\"';
|
|
|
- '\' : s:='\\';
|
|
|
- else
|
|
|
- s:=ch;
|
|
|
- end;
|
|
|
- AsmWrite(s);
|
|
|
- inc(pos,length(s));
|
|
|
- if (pos>line_length) or (i=tai_string(hp).len) then
|
|
|
- begin
|
|
|
- AsmWriteLn('"');
|
|
|
- pos:=0;
|
|
|
- end;
|
|
|
- end;
|
|
|
+ if not(target_info.system in systems_aix) then
|
|
|
+ begin
|
|
|
+ for i:=1 to tai_string(hp).len do
|
|
|
+ begin
|
|
|
+ if pos=0 then
|
|
|
+ begin
|
|
|
+ AsmWrite(#9'.ascii'#9'"');
|
|
|
+ pos:=20;
|
|
|
+ end;
|
|
|
+ ch:=tai_string(hp).str[i-1];
|
|
|
+ case ch of
|
|
|
+ #0, {This can't be done by range, because a bug in FPC}
|
|
|
+ #1..#31,
|
|
|
+ #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
|
|
|
+ '"' : s:='\"';
|
|
|
+ '\' : s:='\\';
|
|
|
+ else
|
|
|
+ s:=ch;
|
|
|
+ end;
|
|
|
+ AsmWrite(s);
|
|
|
+ inc(pos,length(s));
|
|
|
+ if (pos>line_length) or (i=tai_string(hp).len) then
|
|
|
+ begin
|
|
|
+ AsmWriteLn('"');
|
|
|
+ pos:=0;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ WriteAixStringConst(tai_string(hp));
|
|
|
end;
|
|
|
|
|
|
ait_label :
|
|
@@ -1112,6 +1161,30 @@ implementation
|
|
|
{ the dotted name is the name of the actual function entry }
|
|
|
AsmWrite('.');
|
|
|
end
|
|
|
+ else if (target_info.system in systems_aix) and
|
|
|
+ (tai_symbol(hp).sym.typ = AT_FUNCTION) then
|
|
|
+ begin
|
|
|
+ if target_info.system=system_powerpc_aix then
|
|
|
+ begin
|
|
|
+ s:=#9'.long .';
|
|
|
+ ch:='2';
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ s:=#9'.llong .';
|
|
|
+ ch:='3';
|
|
|
+ end;
|
|
|
+ AsmWriteLn(#9'.csect '+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+'[DS],'+ch);
|
|
|
+ AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+':');
|
|
|
+ AsmWriteln(s+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+', TOC[tc0], 0');
|
|
|
+ AsmWriteln(#9'.csect .text[PR]');
|
|
|
+ if (tai_symbol(hp).is_global) then
|
|
|
+ AsmWriteLn('.globl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
|
|
|
+ else
|
|
|
+ AsmWriteLn('.lglobl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name));
|
|
|
+ { the dotted name is the name of the actual function entry }
|
|
|
+ AsmWrite('.');
|
|
|
+ end
|
|
|
else
|
|
|
begin
|
|
|
if (target_info.system <> system_arm_linux) then
|
|
@@ -1275,6 +1348,11 @@ implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ procedure TGNUAssembler.WriteExtraFooter;
|
|
|
+ begin
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
procedure TGNUAssembler.WriteInstruction(hp: tai);
|
|
|
begin
|
|
|
InstrWriter.WriteInstruction(hp);
|
|
@@ -1287,6 +1365,113 @@ implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ procedure TGNUAssembler.WriteAixStringConst(hp: tai_string);
|
|
|
+ type
|
|
|
+ tterminationkind = (term_none,term_string,term_nostring);
|
|
|
+
|
|
|
+ var
|
|
|
+ i: longint;
|
|
|
+ pos: longint;
|
|
|
+ s: string;
|
|
|
+ ch: char;
|
|
|
+ instring: boolean;
|
|
|
+
|
|
|
+ procedure newstatement(terminationkind: tterminationkind);
|
|
|
+ begin
|
|
|
+ case terminationkind of
|
|
|
+ term_none: ;
|
|
|
+ term_string:
|
|
|
+ AsmWriteLn('"');
|
|
|
+ term_nostring:
|
|
|
+ AsmLn;
|
|
|
+ end;
|
|
|
+ AsmWrite(#9'.byte'#9);
|
|
|
+ pos:=20;
|
|
|
+ instring:=false;
|
|
|
+ end;
|
|
|
+
|
|
|
+ begin
|
|
|
+ pos:=0;
|
|
|
+ for i:=1 to hp.len do
|
|
|
+ begin
|
|
|
+ if pos=0 then
|
|
|
+ newstatement(term_none);
|
|
|
+ ch:=hp.str[i-1];
|
|
|
+ case ch of
|
|
|
+ #0..#31,
|
|
|
+ #127..#255 :
|
|
|
+ begin
|
|
|
+ if instring then
|
|
|
+ newstatement(term_string);
|
|
|
+ if pos=20 then
|
|
|
+ s:=tostr(ord(ch))
|
|
|
+ else
|
|
|
+ s:=', '+tostr(ord(ch))
|
|
|
+ end;
|
|
|
+ '"' :
|
|
|
+ if instring then
|
|
|
+ s:='""'
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if pos<>20 then
|
|
|
+ newstatement(term_nostring);
|
|
|
+ s:='"""';
|
|
|
+ instring:=true;
|
|
|
+ end;
|
|
|
+ else
|
|
|
+ if not instring then
|
|
|
+ begin
|
|
|
+ if (pos<>20) then
|
|
|
+ newstatement(term_nostring);
|
|
|
+ s:='"'+ch;
|
|
|
+ instring:=true;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ s:=ch;
|
|
|
+ end;
|
|
|
+ AsmWrite(s);
|
|
|
+ inc(pos,length(s));
|
|
|
+ if (pos>line_length) or (i=tai_string(hp).len) then
|
|
|
+ begin
|
|
|
+ if instring then
|
|
|
+ AsmWriteLn('"')
|
|
|
+ else
|
|
|
+ AsmLn;
|
|
|
+ pos:=0;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure TGNUAssembler.WriteAixIntConst(hp: tai_const);
|
|
|
+ var
|
|
|
+ pos, size: longint;
|
|
|
+ begin
|
|
|
+ { only big endian AIX supported for now }
|
|
|
+ if target_info.endian<>endian_big then
|
|
|
+ internalerror(2012010401);
|
|
|
+ { limitation: can only write 4 bytes at a time }
|
|
|
+ pos:=0;
|
|
|
+ size:=tai_const(hp).size;
|
|
|
+ while pos<(size-4) do
|
|
|
+ begin
|
|
|
+ AsmWrite(#9'.vbyte'#9'4, ');
|
|
|
+ AsmWriteln(tostr(longint(tai_const(hp).value shr ((size-pos-4)*8))));
|
|
|
+ inc(pos,4);
|
|
|
+ end;
|
|
|
+ AsmWrite(#9'.vbyte'#9);
|
|
|
+ AsmWrite(tostr(size-pos));
|
|
|
+ AsmWrite(', ');
|
|
|
+ case size-pos of
|
|
|
+ 1: AsmWrite(tostr(byte(tai_const(hp).value)));
|
|
|
+ 2: AsmWrite(tostr(word(tai_const(hp).value)));
|
|
|
+ 4: AsmWrite(tostr(longint(tai_const(hp).value)));
|
|
|
+ else
|
|
|
+ internalerror(2012010402);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
procedure TGNUAssembler.WriteAsmList;
|
|
|
var
|
|
|
n : string;
|