From 377f52ee6973a39540201e1d521cfcdabaa63277 Mon Sep 17 00:00:00 2001 From: nickysn Date: Mon, 30 Mar 2020 23:31:04 +0000 Subject: [PATCH] + started work on the sdcc-sdasz80 asm backend git-svn-id: branches/z80@44445 - --- .gitattributes | 1 + compiler/systems.inc | 1 + compiler/systems/i_embed.pas | 4 +- compiler/z80/agsdasz80.pas | 445 +++++++++++++++++++++++++++++++++++ compiler/z80/cputarg.pas | 3 + 5 files changed, 452 insertions(+), 2 deletions(-) create mode 100644 compiler/z80/agsdasz80.pas diff --git a/.gitattributes b/.gitattributes index 261e9a9f8a..db7e6c19a2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1052,6 +1052,7 @@ compiler/xtensa/xtensaatt.inc svneol=native#text/plain compiler/xtensa/xtensaop.inc svneol=native#text/plain compiler/xtensa/xtensareg.dat svneol=native#text/plain compiler/z80/aasmcpu.pas svneol=native#text/plain +compiler/z80/agsdasz80.pas svneol=native#text/plain compiler/z80/agz80asm.pas svneol=native#text/plain compiler/z80/aoptcpu.pas svneol=native#text/plain compiler/z80/aoptcpub.pas svneol=native#text/plain diff --git a/compiler/systems.inc b/compiler/systems.inc index 9a34be164a..aad9ac06c0 100644 --- a/compiler/systems.inc +++ b/compiler/systems.inc @@ -251,6 +251,7 @@ ,as_powerpc_gas_legacy { for systems with very old GAS versions only, which don't support eg. named sections } ,as_llvm_clang ,as_z80asm + ,as_sdcc_sdasz80 ); tlink = (ld_none, diff --git a/compiler/systems/i_embed.pas b/compiler/systems/i_embed.pas index 554b966b28..f805c3eb72 100644 --- a/compiler/systems/i_embed.pas +++ b/compiler/systems/i_embed.pas @@ -749,8 +749,8 @@ unit i_embed; Cprefix : ''; newline : #10; dirsep : '/'; - assem : as_z80asm; - assemextern : as_z80asm; + assem : as_sdcc_sdasz80; + assemextern : as_sdcc_sdasz80; link : ld_none; linkextern : ld_embedded; ar : ar_gnu_ar; diff --git a/compiler/z80/agsdasz80.pas b/compiler/z80/agsdasz80.pas new file mode 100644 index 0000000000..eefc82e1bc --- /dev/null +++ b/compiler/z80/agsdasz80.pas @@ -0,0 +1,445 @@ +{ + Copyright (c) 2003 by Florian Klaempfl + + This unit implements an asm for the Z80 + + 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 assembler writer for the sdcc-sdasz80 assembler: + http://sdcc.sourceforge.net/ +} + +unit agsdasz80; + +{$i fpcdefs.inc} + + interface + + uses + globtype,systems, + aasmtai,aasmdata, + assemble, + cpubase; + + type + + { TSdccSdasZ80Assembler } + + TSdccSdasZ80Assembler=class(TExternalAssembler) + private + function EscapeLabel(s: ansistring): ansistring; + public + procedure WriteTree(p : TAsmList); override; + procedure WriteAsmList;override; + function MakeCmdLine: TCmdStr; override; + end; + + implementation + + uses + cutils,globals,verbose, + aasmbase,aasmcpu, + cpuinfo, + cgbase,cgutils; + + const + line_length = 70; + max_tokens : longint = 25; + ait_const2str : array[aitconst_128bit..aitconst_64bit_unaligned] of string[20]=( + #9''#9,#9'DQ'#9,#9'DD'#9,#9'DW'#9,#9'DB'#9, + #9'FIXMESLEB',#9'FIXEMEULEB', + #9'DD RVA'#9,#9'DD SECREL32'#9, + #9'FIXME',#9'FIXME',#9'FIXME',#9'FIXME', + #9'DW'#9,#9'DD'#9,#9'DQ'#9 + ); + + function TSdccSdasZ80Assembler.EscapeLabel(s: ansistring): ansistring; + var + i: Integer; + begin + result:=''; + for i:=1 to length(s) do + if ((s[i]>='a') and (s[i]<='z')) or + ((s[i]>='A') and (s[i]<='Z')) or + ((s[i]>='0') and (s[i]<='9')) or + (s[i]='.') then + result:=result+s[i] + else if s[i]='_' then + result:=result+'__' + else + result:=result+('_'+HexStr(Ord(s[i]),2)); + end; + + procedure TSdccSdasZ80Assembler.WriteTree(p: TAsmList); + + function getreferencestring(var ref : treference) : string; + var + s : string; + begin + s:=''; + 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 index<>NR_NO then + internalerror(2011021701) + else if base<>NR_NO then + begin +// if addressmode=AM_PREDRECEMENT then +// s:='-'; + + //case base of + // NR_R26: + // s:=s+'X'; + // NR_R28: + // s:=s+'Y'; + // NR_R30: + // s:=s+'Z'; + // else + // s:=gas_regname(base); + //end; + //if addressmode=AM_POSTINCREMENT then + // s:=s+'+'; + // + //if offset>0 then + // s:=s+'+'+tostr(offset) + //else if offset<0 then + // s:=s+tostr(offset) + end + else if assigned(symbol) or (offset<>0) then + begin + //if assigned(symbol) then + // s:=ReplaceForbiddenAsmSymbolChars(symbol.name); + // + //if offset<0 then + // s:=s+tostr(offset) + //else if offset>0 then + // s:=s+'+'+tostr(offset); + //case refaddr of + // addr_hi8: + // s:='hi8('+s+')'; + // addr_hi8_gs: + // s:='hi8(gs('+s+'))'; + // addr_lo8: + // s:='lo8('+s+')'; + // addr_lo8_gs: + // s:='lo8(gs('+s+'))'; + // else + // s:='('+s+')'; + //end; + end; + end; + getreferencestring:=s; + end; + + + function getopstr(const o:toper) : string; + var + hs : string; + first : boolean; + r : 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:=ReplaceForbiddenAsmSymbolChars(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(2002070604); + //end; + end; + + //var op: TAsmOp; + // s: string; + // i: byte; + // sep: string[3]; + var + hp: tai; + s: string; + counter,lines,i,j,l,tokens: longint; + quoted: Boolean; + consttype: taiconst_type; + begin + if not assigned(p) then + exit; + hp:=tai(p.first); + while assigned(hp) do + begin + prefetch(pointer(hp.next)^); + case hp.typ of + ait_comment : + begin + writer.AsmWrite(asminfo^.comment); + writer.AsmWritePChar(tai_comment(hp).str); + writer.AsmLn; + end; + ait_align : + begin + if tai_align_abstract(hp).aligntype>1 then + writer.AsmWriteLn(asminfo^.comment+'Unsupported ALIGN '+tostr(tai_align_abstract(hp).aligntype)); + end; + ait_label : + begin + if tai_label(hp).labsym.is_used then + begin + writer.AsmWrite(EscapeLabel(tai_label(hp).labsym.name)); + writer.AsmWriteLn(':'); + end; + end; + ait_symbol : + begin + if tai_symbol(hp).has_value then + internalerror(2009090802); + { wasm is case insensitive, we nned to use only uppercase version + if both a lowercase and an uppercase version are provided } + {if (asminfo^.id = as_i386_wasm) then + begin + nhp:=tai(hp.next); + while assigned(nhp) and (nhp.typ in [ait_function_name,ait_force_line]) do + nhp:=tai(nhp.next); + if assigned(nhp) and (tai(nhp).typ=ait_symbol) and + (lower(tai_symbol(nhp).sym.name)=tai_symbol(hp).sym.name) then + begin + writer.AsmWriteln(asminfo^.comment+' '+tai_symbol(hp).sym.name+' removed'); + hp:=tai(nhp); + end; + end;} + {if tai_symbol(hp).is_global then + writer.AsmWriteLn(#9'PUBLIC'#9+tai_symbol(hp).sym.name);} + writer.AsmWrite(EscapeLabel(tai_symbol(hp).sym.name)); + {if assigned(hp.next) and not(tai(hp.next).typ in + [ait_const,ait_realconst,ait_string]) then} + writer.AsmWriteLn(':'); + end; + ait_symbol_end : + begin + end; + ait_const: + begin + consttype:=tai_const(hp).consttype; + case consttype of + {aitconst_uleb128bit, + aitconst_sleb128bit, + aitconst_128bit, + aitconst_64bit, + aitconst_32bit,} + aitconst_16bit, + aitconst_8bit, + aitconst_16bit_unaligned{, + aitconst_32bit_unaligned, + aitconst_64bit_unaligned, + aitconst_rva_symbol, + aitconst_secrel32_symbol} : + begin + writer.AsmWrite(ait_const2str[consttype]); + l:=0; + tokens:=1; + repeat + if assigned(tai_const(hp).sym) then + begin + if assigned(tai_const(hp).endsym) then + s:=EscapeLabel(tai_const(hp).endsym.name)+'-'+EscapeLabel(tai_const(hp).sym.name) + else + s:=EscapeLabel(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); + writer.AsmWrite(s); + inc(l,length(s)); + inc(tokens); + if (l>line_length) or + (tokens>max_tokens) or + (hp.next=nil) or + (tai(hp.next).typ<>ait_const) or + (tai_const(hp.next).consttype<>consttype) then + break; + hp:=tai(hp.next); + writer.AsmWrite(','); + until false; + { Substract section start for secrel32 type } + if consttype=aitconst_secrel32_symbol then + writer.AsmWrite(' - $$'); + writer.AsmLn; + end; + else + begin + writer.AsmWrite(asminfo^.comment); + writer.AsmWrite('WARNING: not yet implemented in assembler output: '); + Str(consttype,s); + writer.AsmWriteLn(s); + end; + end; + end; + ait_string : + begin + counter := 0; + lines := tai_string(hp).len div line_length; + { separate lines in different parts } + if tai_string(hp).len > 0 then + Begin + for j := 0 to lines-1 do + begin + writer.AsmWrite(#9#9'DB'#9); + quoted:=false; + for i:=counter to counter+line_length-1 do + begin + { it is an ascii character. } + if (ord(tai_string(hp).str[i])>31) and + (ord(tai_string(hp).str[i])<127) and + (tai_string(hp).str[i]<>'"') then + begin + if not(quoted) then + begin + if i>counter then + writer.AsmWrite(','); + writer.AsmWrite('"'); + end; + writer.AsmWrite(tai_string(hp).str[i]); + quoted:=true; + end { if > 31 and < 127 and ord('"') } + else + begin + if quoted then + writer.AsmWrite('"'); + if i>counter then + writer.AsmWrite(','); + quoted:=false; + writer.AsmWrite(tostr(ord(tai_string(hp).str[i]))); + end; + end; { end for i:=0 to... } + if quoted then writer.AsmWrite('"'); + writer.AsmWrite(target_info.newline); + counter := counter+line_length; + end; { end for j:=0 ... } + { do last line of lines } + if counter31) and + (ord(tai_string(hp).str[i])<128) and + (tai_string(hp).str[i]<>'"') then + begin + if not(quoted) then + begin + if i>counter then + writer.AsmWrite(','); + writer.AsmWrite('"'); + end; + writer.AsmWrite(tai_string(hp).str[i]); + quoted:=true; + end { if > 31 and < 128 and " } + else + begin + if quoted then + writer.AsmWrite('"'); + if i>counter then + writer.AsmWrite(','); + quoted:=false; + writer.AsmWrite(tostr(ord(tai_string(hp).str[i]))); + end; + end; { end for i:=0 to... } + if quoted then + writer.AsmWrite('"'); + end; + writer.AsmLn; + end; + else + begin + writer.AsmWrite(asminfo^.comment); + writer.AsmWrite('WARNING: not yet implemented in assembler output: '); + Str(hp.typ,s); + writer.AsmWriteLn(s); + end; + end; + hp:=tai(hp.next); + end; + //op:=taicpu(hp).opcode; + //s:=#9+gas_op2str[op]+cond2str[taicpu(hp).condition]; + //if taicpu(hp).ops<>0 then + // begin + // 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; + + + procedure TSdccSdasZ80Assembler.WriteAsmList; + var + hal: TAsmListType; + begin + for hal:=low(TasmlistType) to high(TasmlistType) do + begin + writer.AsmWriteLn(asminfo^.comment+'Begin asmlist '+AsmListTypeStr[hal]); + writetree(current_asmdata.asmlists[hal]); + writer.AsmWriteLn(asminfo^.comment+'End asmlist '+AsmListTypeStr[hal]); + end; + end; + + + function TSdccSdasZ80Assembler.MakeCmdLine: TCmdStr; + begin + result := {'-mmcu='+lower(cputypestr[current_settings.cputype])+' '+}inherited MakeCmdLine; + end; + + + const + as_sdcc_sdasZ80_asm_info : tasminfo = + ( + id : as_sdcc_sdasz80; + + idtxt : 'SDCC-SDASZ80'; + asmbin : 'sdcc-sdasz80'; + asmcmd : '-o $OBJ $EXTRAOPT $ASM'; + supported_targets : [system_Z80_embedded]; + flags : [af_needar,af_smartlink_sections]; + labelprefix : '.L'; + comment : '; '; + dollarsign: 's'; + ); + + +begin + RegisterAssembler(as_sdcc_sdasZ80_asm_info,TSdccSdasZ80Assembler); +end. diff --git a/compiler/z80/cputarg.pas b/compiler/z80/cputarg.pas index 7a8986fe0b..1702630ac5 100644 --- a/compiler/z80/cputarg.pas +++ b/compiler/z80/cputarg.pas @@ -46,6 +46,9 @@ implementation {$ifndef NOAGZ80ASM} ,agz80asm {$endif} + {$ifndef NOAGSDASZ80} + ,agsdasz80 + {$endif} {************************************** Assembler Readers