mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-27 12:13:48 +02:00

+ Added postfix parsing in tattreader.GetToken - Removed all postfixed versions of OpCodes from the instruction list + Added all missing OpCodes from Xtensa ISA * Changed branch OpCode to A_B, similar to ARM + Added missing branch condition flags BCI and BSI * Updated existing compiler code that referred to the old postfixed instructions + Added prefix and postfix handling in TxtensaInstrWriter.WriteInstruction * Updated TCPUAddNode.second_addfloat to specify .S postfix * Updated tcpuunaryminusnode.second_float to specify .S postfix + Implemented prefix and postfix identification in txtensaattreader.is_asmopcode * Adapted branch condition extraction to respect postfixes * Changed itcpugas to call findreg_by_name_table from raatt.pas (same as issue #0037121, difficult to test these changes without including a fix for the register name search problem) git-svn-id: trunk@45672 -
193 lines
5.6 KiB
ObjectPascal
193 lines
5.6 KiB
ObjectPascal
{
|
|
Copyright (c) 2003 by Florian Klaempfl
|
|
|
|
This unit implements an asm for the Xtensa
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
****************************************************************************
|
|
}
|
|
{ This unit implements the GNU Assembler writer for the Xtensa
|
|
}
|
|
|
|
unit agcpugas;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
globtype,systems,
|
|
aasmtai,
|
|
assemble,aggas,
|
|
cpubase,cpuinfo;
|
|
|
|
type
|
|
TXtensaInstrWriter=class(TCPUInstrWriter)
|
|
procedure WriteInstruction(hp : tai);override;
|
|
end;
|
|
|
|
TXtensaGNUAssembler=class(TGNUassembler)
|
|
constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
|
|
function MakeCmdLine: TCmdStr; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
cutils,globals,verbose,
|
|
aasmcpu,
|
|
itcpugas,
|
|
cgbase,cgutils;
|
|
|
|
{****************************************************************************}
|
|
{ GNU Xtensa Assembler writer }
|
|
{****************************************************************************}
|
|
|
|
constructor TXtensaGNUAssembler.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
|
|
begin
|
|
inherited;
|
|
InstrWriter := TXtensaInstrWriter.create(self);
|
|
end;
|
|
|
|
|
|
function TXtensaGNUAssembler.MakeCmdLine: TCmdStr;
|
|
begin
|
|
result:=inherited MakeCmdLine;
|
|
end;
|
|
|
|
{****************************************************************************}
|
|
{ Helper routines for Instruction Writer }
|
|
{****************************************************************************}
|
|
|
|
function getreferencestring(var ref : treference) : string;
|
|
var
|
|
s : string;
|
|
begin
|
|
with ref do
|
|
begin
|
|
{$ifdef extdebug}
|
|
// if base=NR_NO then
|
|
// internalerror(200308292);
|
|
|
|
// if ((index<>NR_NO) or (shiftmode<>SM_None)) and ((offset<>0) or (symbol<>nil)) then
|
|
// internalerror(200308293);
|
|
{$endif extdebug}
|
|
|
|
if assigned(symbol) then
|
|
begin
|
|
s:=symbol.name;
|
|
if offset<>0 then
|
|
s:=s+tostr_with_plus(offset);
|
|
if refaddr=addr_pic then
|
|
s:=s+'(PLT)'
|
|
{else if refaddr=addr_tlscall then
|
|
s:=s+'(tlscall)'};
|
|
end
|
|
else
|
|
begin
|
|
s:=gas_regname(base);
|
|
if index<>NR_NO then
|
|
Internalerror(2020030802);
|
|
s:=s+','+tostr(offset);
|
|
end;
|
|
end;
|
|
getreferencestring:=s;
|
|
end;
|
|
|
|
|
|
function getopstr(const o:toper) : string;
|
|
var
|
|
hs : string;
|
|
first : boolean;
|
|
r, rs : tsuperregister;
|
|
begin
|
|
case o.typ of
|
|
top_reg:
|
|
getopstr:=gas_regname(o.reg);
|
|
top_const:
|
|
getopstr:=tostr(longint(o.val));
|
|
top_ref:
|
|
if o.ref^.refaddr=addr_full then
|
|
begin
|
|
hs:=o.ref^.symbol.name;
|
|
if o.ref^.offset>0 then
|
|
hs:=hs+'+'+tostr(o.ref^.offset)
|
|
else
|
|
if o.ref^.offset<0 then
|
|
hs:=hs+tostr(o.ref^.offset);
|
|
getopstr:=hs;
|
|
end
|
|
else
|
|
getopstr:=getreferencestring(o.ref^);
|
|
else
|
|
internalerror(2020030705);
|
|
end;
|
|
end;
|
|
|
|
|
|
Procedure TXtensaInstrWriter.WriteInstruction(hp : tai);
|
|
var op: TAsmOp;
|
|
s: string;
|
|
i: byte;
|
|
sep: string[3];
|
|
begin
|
|
op:=taicpu(hp).opcode;
|
|
if taicpu(hp).opIsPrefixed then
|
|
s:=#9'_'+gas_op2str[op]
|
|
else
|
|
s:=#9+gas_op2str[op];
|
|
if taicpu(hp).condition<>C_None then
|
|
s:=s+cond2str[taicpu(hp).condition];
|
|
if taicpu(hp).oppostfix <> PF_None then
|
|
s:=s+'.'+oppostfix2str[taicpu(hp).oppostfix];
|
|
if taicpu(hp).ops<>0 then
|
|
begin
|
|
if length(s)<5 then
|
|
sep:=#9#9
|
|
else
|
|
sep:=#9;
|
|
for i:=0 to taicpu(hp).ops-1 do
|
|
begin
|
|
s:=s+sep+getopstr(taicpu(hp).oper[i]^);
|
|
sep:=',';
|
|
end;
|
|
end;
|
|
owner.writer.AsmWriteLn(s);
|
|
end;
|
|
|
|
|
|
const
|
|
as_xtensa_gas_info : tasminfo =
|
|
(
|
|
id : as_gas;
|
|
|
|
idtxt : 'AS';
|
|
asmbin : 'as';
|
|
asmcmd : '-o $OBJ $EXTRAOPT $ASM --longcalls';
|
|
supported_targets : [system_xtensa_embedded,system_xtensa_linux,system_xtensa_freertos];
|
|
flags : [af_needar,af_smartlink_sections,af_supports_dwarf,af_stabs_use_function_absolute_addresses];
|
|
labelprefix : '.L';
|
|
labelmaxlen : -1;
|
|
comment : '# ';
|
|
dollarsign: '$';
|
|
);
|
|
|
|
|
|
begin
|
|
RegisterAssembler(as_xtensa_gas_info,TXtensaGNUAssembler);
|
|
end.
|
|
|