mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-04 13:50:36 +02:00
* factered WriteInstruction out of TGNUAssembler into its own class
* put Apple-specific GNU assembler stuff in its own class + darwin/x86 support to the assembler writer git-svn-id: trunk@2818 -
This commit is contained in:
parent
8a10afc29d
commit
ba6f1e4990
@ -41,29 +41,51 @@ interface
|
||||
|
||||
|
||||
type
|
||||
TCPUInstrWriter = class;
|
||||
{# This is a derived class which is used to write
|
||||
GAS styled assembler.
|
||||
|
||||
The WriteInstruction() method must be overriden
|
||||
to write a single instruction to the assembler
|
||||
file.
|
||||
}
|
||||
TGNUAssembler=class(texternalassembler)
|
||||
protected
|
||||
function sectionname(atype:TAsmSectiontype;const aname:string):string;virtual;
|
||||
procedure WriteSection(atype:TAsmSectiontype;const aname:string);
|
||||
procedure WriteExtraHeader;virtual;
|
||||
procedure WriteInstruction(hp: tai); virtual; abstract;
|
||||
public
|
||||
procedure WriteInstruction(hp: tai);{$ifdef USEINLINE}inline;{$endif}
|
||||
public
|
||||
procedure WriteTree(p:TAAsmoutput);override;
|
||||
procedure WriteAsmList;override;
|
||||
private
|
||||
destructor destroy; override;
|
||||
private
|
||||
setcount: longint;
|
||||
procedure WriteDecodedSleb128(a: aint);
|
||||
procedure WriteDecodedUleb128(a: aword);
|
||||
function NextSetLabel: string;
|
||||
protected
|
||||
InstrWriter: TCPUInstrWriter;
|
||||
end;
|
||||
|
||||
|
||||
{# This is the base class for writing instructions.
|
||||
|
||||
The WriteInstruction() method must be overriden
|
||||
to write a single instruction to the assembler
|
||||
file.
|
||||
}
|
||||
TCPUInstrWriter = class
|
||||
constructor create(_owner: TGNUAssembler);
|
||||
procedure WriteInstruction(hp : tai); virtual; abstract;
|
||||
protected
|
||||
owner: TGNUAssembler;
|
||||
end;
|
||||
|
||||
|
||||
TAppleGNUAssembler=class(TGNUAssembler)
|
||||
function sectionname(atype:TAsmSectiontype;const aname:string):string;override;
|
||||
private
|
||||
debugframecount: aint;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -195,6 +217,13 @@ implementation
|
||||
{ GNU Assembler writer }
|
||||
{****************************************************************************}
|
||||
|
||||
destructor TGNUAssembler.Destroy;
|
||||
begin
|
||||
InstrWriter.free;
|
||||
inherited destroy;
|
||||
end;
|
||||
|
||||
|
||||
function TGNUAssembler.NextSetLabel: string;
|
||||
begin
|
||||
inc(setcount);
|
||||
@ -210,7 +239,7 @@ implementation
|
||||
'.data',
|
||||
'.bss',
|
||||
'.threadvar',
|
||||
'__TEXT', { stubs }
|
||||
'', { stubs }
|
||||
'.stab',
|
||||
'.stabstr',
|
||||
'.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
|
||||
@ -225,7 +254,7 @@ implementation
|
||||
'.data.rel',
|
||||
'.bss',
|
||||
'.threadvar',
|
||||
'__TEXT', { stubs }
|
||||
'', { stubs }
|
||||
'.stab',
|
||||
'.stabstr',
|
||||
'.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
|
||||
@ -262,13 +291,13 @@ implementation
|
||||
AsmLn;
|
||||
case target_info.system of
|
||||
system_i386_OS2,
|
||||
system_i386_EMX : ;
|
||||
system_i386_EMX: ;
|
||||
system_powerpc_darwin,
|
||||
system_i386_darwin:
|
||||
begin
|
||||
if atype=sec_stub then
|
||||
if (atype = sec_stub) then
|
||||
AsmWrite('.section ');
|
||||
end;
|
||||
end
|
||||
else
|
||||
AsmWrite('.section ');
|
||||
end;
|
||||
@ -279,8 +308,17 @@ implementation
|
||||
AsmWrite(', "a", @progbits');
|
||||
sec_stub :
|
||||
begin
|
||||
if (target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
|
||||
AsmWrite(',__symbol_stub1,symbol_stubs,pure_instructions,16');
|
||||
case target_info.system of
|
||||
{ there are processor-independent shortcuts available }
|
||||
{ for this, namely .symbol_stub and .picsymbol_stub, but }
|
||||
{ they don't work and gcc doesn't use them either... }
|
||||
system_powerpc_darwin:
|
||||
AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
|
||||
system_i386_darwin:
|
||||
AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
|
||||
else
|
||||
internalerror(2006031101);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
AsmLn;
|
||||
@ -958,10 +996,16 @@ implementation
|
||||
|
||||
|
||||
procedure TGNUAssembler.WriteExtraHeader;
|
||||
|
||||
begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TGNUAssembler.WriteInstruction(hp: tai);{$ifdef USEINLINE}inline;{$endif}
|
||||
begin
|
||||
InstrWriter.WriteInstruction(hp);
|
||||
end;
|
||||
|
||||
|
||||
procedure TGNUAssembler.WriteAsmList;
|
||||
var
|
||||
p:dirstr;
|
||||
@ -1014,4 +1058,39 @@ implementation
|
||||
{$endif EXTDEBUG}
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************}
|
||||
{ Apple/GNU Assembler writer }
|
||||
{****************************************************************************}
|
||||
|
||||
function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string):string;
|
||||
begin
|
||||
if (target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
|
||||
case atype of
|
||||
sec_bss:
|
||||
{ all bss (lcomm) symbols are automatically put in the right }
|
||||
{ place by using the lcomm assembler directive }
|
||||
atype := sec_none;
|
||||
sec_debug_frame,
|
||||
sec_eh_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;
|
||||
|
||||
|
||||
{****************************************************************************}
|
||||
{ Abstract Instruction Writer }
|
||||
{****************************************************************************}
|
||||
|
||||
constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
|
||||
begin
|
||||
inherited create;
|
||||
owner := _owner;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -34,11 +34,15 @@ unit agarmgas;
|
||||
cpubase;
|
||||
|
||||
type
|
||||
PARMGNUAssembler=^TARMGNUAssembler;
|
||||
TARMGNUAssembler=class(TGNUassembler)
|
||||
procedure WriteInstruction(hp : tai);override;
|
||||
constructor create(smart: boolean); override;
|
||||
end;
|
||||
|
||||
TArmInstrWriter=class(TCPUInstrWriter)
|
||||
procedure WriteInstruction(hp : tai);override;
|
||||
end;
|
||||
|
||||
|
||||
const
|
||||
gas_shiftmode2str : array[tshiftmode] of string[3] = (
|
||||
'','lsl','lsr','asr','ror','rrx');
|
||||
@ -53,19 +57,20 @@ unit agarmgas;
|
||||
itcpugas,
|
||||
cgbase,cgutils;
|
||||
|
||||
const
|
||||
as_arm_gas_info : tasminfo =
|
||||
(
|
||||
id : as_gas;
|
||||
{****************************************************************************}
|
||||
{ GNU Arm Assembler writer }
|
||||
{****************************************************************************}
|
||||
|
||||
idtxt : 'AS';
|
||||
asmbin : 'as';
|
||||
asmcmd : '-o $OBJ $ASM';
|
||||
supported_target : system_any;
|
||||
flags : [af_allowdirect,af_needar,af_smartlink_sections];
|
||||
labelprefix : '.L';
|
||||
comment : '# ';
|
||||
);
|
||||
constructor TArmGNUAssembler.create(smart: boolean);
|
||||
begin
|
||||
inherited create(smart);
|
||||
InstrWriter := TArmInstrWriter.create(self);
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************}
|
||||
{ Helper routines for Instruction Writer }
|
||||
{****************************************************************************}
|
||||
|
||||
function getreferencestring(var ref : treference) : string;
|
||||
var
|
||||
@ -179,7 +184,7 @@ unit agarmgas;
|
||||
end;
|
||||
|
||||
|
||||
Procedure TARMGNUAssembler.WriteInstruction(hp : tai);
|
||||
Procedure TArmInstrWriter.WriteInstruction(hp : tai);
|
||||
var op: TAsmOp;
|
||||
s: string;
|
||||
i: byte;
|
||||
@ -228,10 +233,25 @@ unit agarmgas;
|
||||
sep:=',';
|
||||
end;
|
||||
end;
|
||||
AsmWriteLn(s);
|
||||
owner.AsmWriteLn(s);
|
||||
end;
|
||||
|
||||
|
||||
const
|
||||
as_arm_gas_info : tasminfo =
|
||||
(
|
||||
id : as_gas;
|
||||
|
||||
idtxt : 'AS';
|
||||
asmbin : 'as';
|
||||
asmcmd : '-o $OBJ $ASM';
|
||||
supported_target : system_any;
|
||||
flags : [af_allowdirect,af_needar,af_smartlink_sections];
|
||||
labelprefix : '.L';
|
||||
comment : '# ';
|
||||
);
|
||||
|
||||
|
||||
begin
|
||||
RegisterAssembler(as_arm_gas_info,TARMGNUAssembler);
|
||||
end.
|
||||
|
@ -36,15 +36,20 @@ unit agppcgas;
|
||||
globtype;
|
||||
|
||||
type
|
||||
PPPCGNUAssembler=^TPPCGNUAssembler;
|
||||
TPPCGNUAssembler=class(TGNUassembler)
|
||||
function sectionname(atype:TAsmSectiontype;const aname:string):string;override;
|
||||
constructor create(smart: boolean); override;
|
||||
procedure WriteExtraHeader;override;
|
||||
procedure WriteInstruction(hp : tai);override;
|
||||
private
|
||||
debugframecount: aint;
|
||||
end;
|
||||
|
||||
TPPCAppleGNUAssembler=class(TAppleGNUassembler)
|
||||
constructor create(smart: boolean); override;
|
||||
end;
|
||||
|
||||
|
||||
TPPCInstrWriter=class(TCPUInstrWriter)
|
||||
procedure WriteInstruction(hp : tai);override;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
@ -55,73 +60,48 @@ unit agppcgas;
|
||||
itcpugas,
|
||||
aasmcpu;
|
||||
|
||||
{****************************************************************************}
|
||||
{ GNU PPC Assembler writer }
|
||||
{****************************************************************************}
|
||||
|
||||
constructor TPPCGNUAssembler.create(smart: boolean);
|
||||
begin
|
||||
inherited create(smart);
|
||||
InstrWriter := TPPCInstrWriter.create(self);
|
||||
end;
|
||||
|
||||
|
||||
procedure TPPCGNUAssembler.WriteExtraHeader;
|
||||
var
|
||||
i : longint;
|
||||
begin
|
||||
if (target_info.system <> system_powerpc_darwin) then
|
||||
begin
|
||||
for i:=0 to 31 do
|
||||
AsmWriteln(#9'.set'#9'r'+tostr(i)+','+tostr(i));
|
||||
for i:=0 to 31 do
|
||||
AsmWriteln(#9'.set'#9'f'+tostr(i)+','+tostr(i));
|
||||
end;
|
||||
for i:=0 to 31 do
|
||||
AsmWriteln(#9'.set'#9'r'+tostr(i)+','+tostr(i));
|
||||
for i:=0 to 31 do
|
||||
AsmWriteln(#9'.set'#9'f'+tostr(i)+','+tostr(i));
|
||||
end;
|
||||
|
||||
const
|
||||
as_ppc_gas_info : tasminfo =
|
||||
(
|
||||
id : as_gas;
|
||||
|
||||
idtxt : 'AS';
|
||||
asmbin : 'as';
|
||||
asmcmd : '-o $OBJ $ASM';
|
||||
supported_target : system_any;
|
||||
flags : [af_allowdirect,af_needar,af_smartlink_sections];
|
||||
labelprefix : '.L';
|
||||
comment : '# ';
|
||||
);
|
||||
{****************************************************************************}
|
||||
{ GNU/Apple PPC Assembler writer }
|
||||
{****************************************************************************}
|
||||
|
||||
|
||||
as_ppc_gas_darwin_powerpc_info : tasminfo =
|
||||
(
|
||||
id : as_darwin;
|
||||
|
||||
idtxt : 'AS-Darwin';
|
||||
asmbin : 'as';
|
||||
asmcmd : '-o $OBJ $ASM -arch ppc';
|
||||
supported_target : system_any;
|
||||
flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
|
||||
labelprefix : 'L';
|
||||
comment : '# ';
|
||||
);
|
||||
|
||||
|
||||
refaddr2str: array[trefaddr] of string[3] = ('','','@ha','@l','');
|
||||
refaddr2str_darwin: array[trefaddr] of string[4] = ('','','ha16','lo16','');
|
||||
|
||||
|
||||
|
||||
function TPPCGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string):string;
|
||||
constructor TPPCAppleGNUAssembler.create(smart: boolean);
|
||||
begin
|
||||
if (target_info.system = system_powerpc_darwin) then
|
||||
case atype of
|
||||
sec_bss:
|
||||
{ all bss (lcomm) symbols are automatically put in the right }
|
||||
{ place by using the lcomm assembler directive }
|
||||
atype := sec_none;
|
||||
sec_debug_frame,
|
||||
sec_eh_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);
|
||||
inherited create(smart);
|
||||
InstrWriter := TPPCInstrWriter.create(self);
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************}
|
||||
{ Helper routines for Instruction Writer }
|
||||
{****************************************************************************}
|
||||
|
||||
const
|
||||
refaddr2str: array[trefaddr] of string[3] = ('','','@ha','@l','');
|
||||
refaddr2str_darwin: array[trefaddr] of string[4] = ('','','ha16','lo16','');
|
||||
|
||||
|
||||
function getreferencestring(var ref : treference) : string;
|
||||
var
|
||||
s : string;
|
||||
@ -322,7 +302,12 @@ unit agppcgas;
|
||||
end;
|
||||
end;
|
||||
|
||||
Procedure TPPCGNUAssembler.WriteInstruction(hp : tai);
|
||||
|
||||
{****************************************************************************}
|
||||
{ PowerPC Instruction Writer }
|
||||
{****************************************************************************}
|
||||
|
||||
Procedure TPPCInstrWriter.WriteInstruction(hp : tai);
|
||||
var op: TAsmOp;
|
||||
s: string;
|
||||
i: byte;
|
||||
@ -350,7 +335,7 @@ unit agppcgas;
|
||||
begin
|
||||
{ first write the current contents of s, because the symbol }
|
||||
{ may be 255 characters }
|
||||
asmwrite(s);
|
||||
owner.asmwrite(s);
|
||||
s:=getopstr_jmp(taicpu(hp).oper[0]^);
|
||||
end;
|
||||
end
|
||||
@ -376,10 +361,42 @@ unit agppcgas;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
AsmWriteLn(s);
|
||||
owner.AsmWriteLn(s);
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
Initialize
|
||||
*****************************************************************************}
|
||||
|
||||
const
|
||||
as_ppc_gas_info : tasminfo =
|
||||
(
|
||||
id : as_gas;
|
||||
|
||||
idtxt : 'AS';
|
||||
asmbin : 'as';
|
||||
asmcmd : '-o $OBJ $ASM';
|
||||
supported_target : system_any;
|
||||
flags : [af_allowdirect,af_needar,af_smartlink_sections];
|
||||
labelprefix : '.L';
|
||||
comment : '# ';
|
||||
);
|
||||
|
||||
|
||||
as_ppc_gas_darwin_powerpc_info : tasminfo =
|
||||
(
|
||||
id : as_darwin;
|
||||
|
||||
idtxt : 'AS-Darwin';
|
||||
asmbin : 'as';
|
||||
asmcmd : '-o $OBJ $ASM -arch ppc';
|
||||
supported_target : system_any;
|
||||
flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
|
||||
labelprefix : 'L';
|
||||
comment : '# ';
|
||||
);
|
||||
|
||||
begin
|
||||
RegisterAssembler(as_ppc_gas_info,TPPCGNUAssembler);
|
||||
RegisterAssembler(as_ppc_gas_darwin_powerpc_info,TPPCGNUAssembler);
|
||||
RegisterAssembler(as_ppc_gas_darwin_powerpc_info,TPPCAppleGNUAssembler);
|
||||
end.
|
||||
|
@ -35,13 +35,17 @@ uses
|
||||
cpubase;
|
||||
|
||||
type
|
||||
PPPCGNUAssembler = ^TPPCGNUAssembler;
|
||||
TPPCGNUAssembler = class(TGNUassembler)
|
||||
public
|
||||
constructor create(smart: boolean); override;
|
||||
procedure WriteExtraHeader; override;
|
||||
end;
|
||||
|
||||
TPPCInstrWriter = class(TCPUInstrWriter)
|
||||
procedure WriteInstruction(hp: tai); override;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -52,6 +56,17 @@ uses
|
||||
aasmcpu;
|
||||
|
||||
|
||||
{****************************************************************************}
|
||||
{ GNU PPC Assembler writer }
|
||||
{****************************************************************************}
|
||||
|
||||
constructor TPPCGNUAssembler.create(smart: boolean);
|
||||
begin
|
||||
inherited create(smart);
|
||||
InstrWriter := TPPCInstrWriter.create(self);
|
||||
end;
|
||||
|
||||
|
||||
procedure TPPCGNUAssembler.WriteExtraHeader;
|
||||
var
|
||||
i: longint;
|
||||
@ -62,20 +77,11 @@ begin
|
||||
AsmWriteln(#9'.set'#9'f' + tostr(i) + ',' + tostr(i));
|
||||
end;
|
||||
|
||||
{****************************************************************************}
|
||||
{ Helper routines for Instruction Writer }
|
||||
{****************************************************************************}
|
||||
|
||||
const
|
||||
as_ppc_gas_info: tasminfo =
|
||||
(
|
||||
id: as_gas;
|
||||
|
||||
idtxt: 'AS';
|
||||
asmbin: 'as';
|
||||
asmcmd: '-a64 -o $OBJ $ASM';
|
||||
supported_target: system_any;
|
||||
flags: [af_allowdirect, af_needar, af_smartlink_sections];
|
||||
labelprefix: '.L';
|
||||
comment: '# ';
|
||||
);
|
||||
|
||||
refaddr2str: array[trefaddr] of string[9] = ('', '', '', '@l', '@h', '@higher', '@highest', '@ha', '@highera', '@highesta');
|
||||
|
||||
function getreferencestring(var ref: treference): string;
|
||||
@ -273,7 +279,12 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPPCGNUAssembler.WriteInstruction(hp: tai);
|
||||
|
||||
{****************************************************************************}
|
||||
{ PowerPC Instruction Writer }
|
||||
{****************************************************************************}
|
||||
|
||||
procedure TPPCInstrWriter.WriteInstruction(hp: tai);
|
||||
var
|
||||
op: TAsmOp;
|
||||
s: string;
|
||||
@ -304,7 +315,7 @@ begin
|
||||
begin
|
||||
{ first write the current contents of s, because the symbol }
|
||||
{ may be 255 characters }
|
||||
asmwrite(s);
|
||||
owner.AsmWrite(s);
|
||||
s := getopstr_jmp(taicpu(hp).oper[0]^);
|
||||
end;
|
||||
end
|
||||
@ -330,10 +341,25 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
AsmWriteLn(s);
|
||||
owner.AsmWriteLn(s);
|
||||
end;
|
||||
|
||||
|
||||
const
|
||||
as_ppc_gas_info: tasminfo =
|
||||
(
|
||||
id: as_gas;
|
||||
|
||||
idtxt: 'AS';
|
||||
asmbin: 'as';
|
||||
asmcmd: '-a64 -o $OBJ $ASM';
|
||||
supported_target: system_any;
|
||||
flags: [af_allowdirect, af_needar, af_smartlink_sections];
|
||||
labelprefix: '.L';
|
||||
comment: '# ';
|
||||
);
|
||||
|
||||
|
||||
begin
|
||||
RegisterAssembler(as_ppc_gas_info, TPPCGNUAssembler);
|
||||
end.
|
||||
|
@ -31,9 +31,13 @@ interface
|
||||
|
||||
type
|
||||
TGasSPARC=class(TGnuAssembler)
|
||||
procedure WriteInstruction(hp:Tai);override;
|
||||
constructor create(smart: boolean); override;
|
||||
end;
|
||||
|
||||
TSPARCInstrWriter=class(TCPUInstrWriter)
|
||||
procedure WriteInstruction(hp:Tai);override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -41,6 +45,17 @@ implementation
|
||||
verbose,itcpugas,cgbase,cgutils;
|
||||
|
||||
|
||||
{****************************************************************************}
|
||||
{ GNU PPC Assembler writer }
|
||||
{****************************************************************************}
|
||||
|
||||
constructor TGasSPARC.create(smart: boolean);
|
||||
begin
|
||||
inherited create(smart);
|
||||
InstrWriter := TSPARCInstrWriter.create(self);
|
||||
end;
|
||||
|
||||
|
||||
function GetReferenceString(var ref:TReference):string;
|
||||
begin
|
||||
GetReferenceString:='';
|
||||
@ -123,7 +138,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure TGasSPARC.WriteInstruction(hp:Tai);
|
||||
procedure TSPARCInstrWriter.WriteInstruction(hp:Tai);
|
||||
var
|
||||
Op:TAsmOp;
|
||||
s:String;
|
||||
@ -143,14 +158,14 @@ implementation
|
||||
internalerror(200401045);
|
||||
{ FABSs %f<even>,%f<even> }
|
||||
s:=#9+std_op2str[A_FABSs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
|
||||
AsmWriteLn(s);
|
||||
owner.AsmWriteLn(s);
|
||||
{ FMOVs %f<odd>,%f<odd> }
|
||||
inc(taicpu(hp).oper[0]^.reg);
|
||||
inc(taicpu(hp).oper[1]^.reg);
|
||||
s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
|
||||
dec(taicpu(hp).oper[0]^.reg);
|
||||
dec(taicpu(hp).oper[1]^.reg);
|
||||
AsmWriteLn(s);
|
||||
owner.AsmWriteLn(s);
|
||||
end;
|
||||
A_FMOVd:
|
||||
begin
|
||||
@ -160,14 +175,14 @@ implementation
|
||||
internalerror(200401045);
|
||||
{ FMOVs %f<even>,%f<even> }
|
||||
s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
|
||||
AsmWriteLn(s);
|
||||
owner.AsmWriteLn(s);
|
||||
{ FMOVs %f<odd>,%f<odd> }
|
||||
inc(taicpu(hp).oper[0]^.reg);
|
||||
inc(taicpu(hp).oper[1]^.reg);
|
||||
s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
|
||||
dec(taicpu(hp).oper[0]^.reg);
|
||||
dec(taicpu(hp).oper[1]^.reg);
|
||||
AsmWriteLn(s);
|
||||
owner.AsmWriteLn(s);
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -181,7 +196,7 @@ implementation
|
||||
for i:=1 to taicpu(hp).ops-1 do
|
||||
s:=s+','+getopstr(taicpu(hp).oper[i]^);
|
||||
end;
|
||||
AsmWriteLn(s);
|
||||
owner.AsmWriteLn(s);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -34,14 +34,24 @@ interface
|
||||
|
||||
type
|
||||
Tx86ATTAssembler=class(TGNUassembler)
|
||||
private
|
||||
constructor create(smart: boolean); override;
|
||||
end;
|
||||
|
||||
Tx86AppleGNUAssembler=class(TAppleGNUassembler)
|
||||
constructor create(smart: boolean); override;
|
||||
end;
|
||||
|
||||
|
||||
Tx86InstrWriter=class(TCPUInstrWriter)
|
||||
private
|
||||
procedure WriteReference(var ref : treference);
|
||||
procedure WriteOper(const o:toper);
|
||||
procedure WriteOper_jmp(const o:toper);
|
||||
public
|
||||
public
|
||||
procedure WriteInstruction(hp: tai);override;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
@ -54,125 +64,145 @@ interface
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TX86ATTASMOUTPUT
|
||||
Tx86ATTAssembler
|
||||
****************************************************************************}
|
||||
|
||||
procedure Tx86AttAssembler.WriteReference(var ref : treference);
|
||||
constructor Tx86ATTAssembler.create(smart: boolean);
|
||||
begin
|
||||
inherited create(smart);
|
||||
InstrWriter := Tx86InstrWriter.create(self);
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
Tx86AppleGNUAssembler
|
||||
****************************************************************************}
|
||||
|
||||
constructor Tx86AppleGNUAssembler.create(smart: boolean);
|
||||
begin
|
||||
inherited create(smart);
|
||||
InstrWriter := Tx86InstrWriter.create(self);
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
Tx86InstrWriter
|
||||
****************************************************************************}
|
||||
|
||||
procedure Tx86InstrWriter.WriteReference(var ref : treference);
|
||||
begin
|
||||
with ref do
|
||||
begin
|
||||
{ have we a segment prefix ? }
|
||||
{ do we have a segment prefix ? }
|
||||
{ These are probably not correctly handled under GAS }
|
||||
{ should be replaced by coding the segment override }
|
||||
{ directly! - DJGPP FAQ }
|
||||
if segment<>NR_NO then
|
||||
AsmWrite(gas_regname(segment)+':');
|
||||
owner.AsmWrite(gas_regname(segment)+':');
|
||||
if assigned(symbol) then
|
||||
AsmWrite(symbol.name);
|
||||
owner.AsmWrite(symbol.name);
|
||||
if ref.refaddr=addr_pic then
|
||||
{$ifdef x86_64}
|
||||
AsmWrite('@GOTPCREL');
|
||||
owner.AsmWrite('@GOTPCREL');
|
||||
{$else x86_64}
|
||||
AsmWrite('@GOT');
|
||||
owner.AsmWrite('@GOT');
|
||||
{$endif x86_64}
|
||||
if offset<0 then
|
||||
AsmWrite(tostr(offset))
|
||||
owner.AsmWrite(tostr(offset))
|
||||
else
|
||||
if (offset>0) then
|
||||
begin
|
||||
if assigned(symbol) then
|
||||
AsmWrite('+'+tostr(offset))
|
||||
owner.AsmWrite('+'+tostr(offset))
|
||||
else
|
||||
AsmWrite(tostr(offset));
|
||||
owner.AsmWrite(tostr(offset));
|
||||
end
|
||||
else if (index=NR_NO) and (base=NR_NO) and (not assigned(symbol)) then
|
||||
AsmWrite('0');
|
||||
owner.AsmWrite('0');
|
||||
if (index<>NR_NO) and (base=NR_NO) then
|
||||
begin
|
||||
AsmWrite('(,'+gas_regname(index));
|
||||
owner.AsmWrite('(,'+gas_regname(index));
|
||||
if scalefactor<>0 then
|
||||
AsmWrite(','+tostr(scalefactor)+')')
|
||||
owner.AsmWrite(','+tostr(scalefactor)+')')
|
||||
else
|
||||
AsmWrite(')');
|
||||
owner.AsmWrite(')');
|
||||
end
|
||||
else
|
||||
if (index=NR_NO) and (base<>NR_NO) then
|
||||
AsmWrite('('+gas_regname(base)+')')
|
||||
owner.AsmWrite('('+gas_regname(base)+')')
|
||||
else
|
||||
if (index<>NR_NO) and (base<>NR_NO) then
|
||||
begin
|
||||
AsmWrite('('+gas_regname(base)+','+gas_regname(index));
|
||||
owner.AsmWrite('('+gas_regname(base)+','+gas_regname(index));
|
||||
if scalefactor<>0 then
|
||||
AsmWrite(','+tostr(scalefactor));
|
||||
AsmWrite(')');
|
||||
owner.AsmWrite(','+tostr(scalefactor));
|
||||
owner.AsmWrite(')');
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Tx86AttAssembler.WriteOper(const o:toper);
|
||||
procedure Tx86InstrWriter.WriteOper(const o:toper);
|
||||
begin
|
||||
case o.typ of
|
||||
top_reg :
|
||||
AsmWrite(gas_regname(o.reg));
|
||||
owner.AsmWrite(gas_regname(o.reg));
|
||||
top_ref :
|
||||
if o.ref^.refaddr in [addr_no,addr_pic] then
|
||||
WriteReference(o.ref^)
|
||||
else
|
||||
begin
|
||||
AsmWrite('$');
|
||||
owner.AsmWrite('$');
|
||||
if assigned(o.ref^.symbol) then
|
||||
AsmWrite(o.ref^.symbol.name);
|
||||
owner.AsmWrite(o.ref^.symbol.name);
|
||||
if o.ref^.offset>0 then
|
||||
AsmWrite('+'+tostr(o.ref^.offset))
|
||||
owner.AsmWrite('+'+tostr(o.ref^.offset))
|
||||
else
|
||||
if o.ref^.offset<0 then
|
||||
AsmWrite(tostr(o.ref^.offset))
|
||||
owner.AsmWrite(tostr(o.ref^.offset))
|
||||
else
|
||||
if not(assigned(o.ref^.symbol)) then
|
||||
AsmWrite('0');
|
||||
owner.AsmWrite('0');
|
||||
end;
|
||||
top_const :
|
||||
AsmWrite('$'+tostr(o.val));
|
||||
owner.AsmWrite('$'+tostr(o.val));
|
||||
else
|
||||
internalerror(10001);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Tx86AttAssembler.WriteOper_jmp(const o:toper);
|
||||
procedure Tx86InstrWriter.WriteOper_jmp(const o:toper);
|
||||
begin
|
||||
case o.typ of
|
||||
top_reg :
|
||||
AsmWrite('*'+gas_regname(o.reg));
|
||||
owner.AsmWrite('*'+gas_regname(o.reg));
|
||||
top_ref :
|
||||
begin
|
||||
if o.ref^.refaddr=addr_no then
|
||||
begin
|
||||
AsmWrite('*');
|
||||
owner.AsmWrite('*');
|
||||
WriteReference(o.ref^);
|
||||
end
|
||||
else
|
||||
begin
|
||||
AsmWrite(o.ref^.symbol.name);
|
||||
owner.AsmWrite(o.ref^.symbol.name);
|
||||
if o.ref^.refaddr=addr_pic then
|
||||
AsmWrite('@PLT');
|
||||
owner.AsmWrite('@PLT');
|
||||
if o.ref^.offset>0 then
|
||||
AsmWrite('+'+tostr(o.ref^.offset))
|
||||
owner.AsmWrite('+'+tostr(o.ref^.offset))
|
||||
else
|
||||
if o.ref^.offset<0 then
|
||||
AsmWrite(tostr(o.ref^.offset));
|
||||
owner.AsmWrite(tostr(o.ref^.offset));
|
||||
end;
|
||||
end;
|
||||
top_const :
|
||||
AsmWrite(tostr(o.val));
|
||||
owner.AsmWrite(tostr(o.val));
|
||||
else
|
||||
internalerror(10001);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Tx86AttAssembler.WriteInstruction(hp: tai);
|
||||
procedure Tx86InstrWriter.WriteInstruction(hp: tai);
|
||||
var
|
||||
op : tasmop;
|
||||
calljmp : boolean;
|
||||
@ -183,14 +213,14 @@ interface
|
||||
taicpu(hp).SetOperandOrder(op_att);
|
||||
op:=taicpu(hp).opcode;
|
||||
calljmp:=is_calljmp(op);
|
||||
AsmWrite(#9);
|
||||
owner.AsmWrite(#9);
|
||||
{ movsd should not be translated to movsl when there
|
||||
are (xmm) arguments }
|
||||
if (op=A_MOVSD) and (taicpu(hp).ops>0) then
|
||||
AsmWrite('movsd')
|
||||
owner.AsmWrite('movsd')
|
||||
else
|
||||
AsmWrite(gas_op2str[op]);
|
||||
AsmWrite(cond2str[taicpu(hp).condition]);
|
||||
owner.AsmWrite(gas_op2str[op]);
|
||||
owner.AsmWrite(cond2str[taicpu(hp).condition]);
|
||||
{ suffix needed ? fnstsw,fldcw don't support suffixes
|
||||
with binutils 2.9.5 under linux }
|
||||
{ if (Taicpu(hp).oper[0]^.typ=top_reg) and
|
||||
@ -209,13 +239,13 @@ interface
|
||||
(taicpu(hp).oper[0]^.typ=top_reg) and
|
||||
(getregtype(taicpu(hp).oper[0]^.reg)=R_FPUREGISTER)
|
||||
) then
|
||||
AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
|
||||
owner.AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
|
||||
{ process operands }
|
||||
if taicpu(hp).ops<>0 then
|
||||
begin
|
||||
if calljmp then
|
||||
begin
|
||||
AsmWrite(#9);
|
||||
owner.AsmWrite(#9);
|
||||
WriteOper_jmp(taicpu(hp).oper[0]^);
|
||||
end
|
||||
else
|
||||
@ -223,14 +253,14 @@ interface
|
||||
for i:=0 to taicpu(hp).ops-1 do
|
||||
begin
|
||||
if i=0 then
|
||||
AsmWrite(#9)
|
||||
owner.AsmWrite(#9)
|
||||
else
|
||||
AsmWrite(',');
|
||||
owner.AsmWrite(',');
|
||||
WriteOper(taicpu(hp).oper[i]^);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
AsmLn;
|
||||
owner.AsmLn;
|
||||
end;
|
||||
|
||||
{*****************************************************************************
|
||||
@ -263,6 +293,7 @@ interface
|
||||
comment : '# ';
|
||||
);
|
||||
|
||||
|
||||
as_i386_as_aout_info : tasminfo =
|
||||
(
|
||||
id : as_i386_as_aout;
|
||||
@ -274,6 +305,20 @@ interface
|
||||
labelprefix : 'L';
|
||||
comment : '# ';
|
||||
);
|
||||
|
||||
|
||||
as_i386_gas_darwin_info : tasminfo =
|
||||
(
|
||||
id : as_darwin;
|
||||
idtxt : 'AS-Darwin';
|
||||
asmbin : 'as';
|
||||
asmcmd : '-o $OBJ $ASM -arch i386';
|
||||
supported_target : system_any;
|
||||
flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
|
||||
labelprefix : 'L';
|
||||
comment : '# ';
|
||||
);
|
||||
|
||||
{$endif x86_64}
|
||||
|
||||
initialization
|
||||
@ -281,6 +326,7 @@ initialization
|
||||
RegisterAssembler(as_x86_64_as_info,Tx86ATTAssembler);
|
||||
{$else x86_64}
|
||||
RegisterAssembler(as_i386_as_info,Tx86ATTAssembler);
|
||||
RegisterAssembler(as_i386_gas_darwin_info,Tx86AppleGNUAssembler);
|
||||
RegisterAssembler(as_i386_as_aout_info,Tx86ATTAssembler);
|
||||
{$endif x86_64}
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user