{*****************************************************************************} { File : cpugas.pas } { Author : Mazen NEIFER } { Project : Free Pascal Compiler (FPC) } { Creation date : 2002\05\01 } { Last modification date : 2002\08\22 } { Licence : GPL } { Bug report : mazen.neifer.01@supaero.org } {*****************************************************************************} { $Id$ Copyright (c) 1998-2000 by Florian Klaempfl This unit implements an asmoutput class for SPARC AT&T syntax 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. ****************************************************************************} UNIT CpuGas; {$MACRO ON}{$INCLUDE fpcdefs.inc} INTERFACE USES cclasses,cpubase, globals, aasmbase,aasmtai,aasmcpu,assemble,aggas; TYPE TGasSPARC=class(TGnuAssembler) PROCEDURE WriteInstruction(hp:Tai);OVERRIDE; END; IMPLEMENTATION USES strings, dos, globtype, fmodule,finput, cutils,systems, verbose; {$DEFINE gas_reg2str:=std_reg2str} CONST line_length = 70; VAR {$ifdef GDB} n_line : byte; { different types of source lines } linecount, includecount : longint; funcname : pchar; stabslastfileinfo : tfileposinfo; {$endif} lastsec : tsection; { last section type written } lastfileinfo : tfileposinfo; infile, lastinfile : tinputfile; symendcount : longint; function fixline(s:string):string; { return s with all leading and ending spaces and tabs removed } var i,j,k : longint; begin i:=length(s); while (i>0) and (s[i] in [#9,' ']) do dec(i); j:=1; while (jR_NONE then s:=gas_reg2str[segment]+':' else s:=''; if assigned(symbol) then s:=s+symbol.name; if offset<0 then s:=s+tostr(offset) else if (offset>0) then begin if assigned(symbol) then s:=s+'+'+tostr(offset) else s:=s+tostr(offset); end else if (index=R_NONE) and (base=R_NONE) and not assigned(symbol) then s:=s+'0'; if (index<>R_NONE) and (base=R_NONE) then begin s:=s+'(,'+gas_reg2str[index]; if scalefactor<>0 then s:=s+','+tostr(scalefactor)+')' else s:=s+')'; end else if (index=R_NONE) and (base<>R_NONE) then s:=s+'('+gas_reg2str[base]+')' else if (index<>R_NONE) and (base<>R_NONE) then begin s:=s+'('+gas_reg2str[base]+','+gas_reg2str[index]; if scalefactor<>0 then s:=s+','+tostr(scalefactor)+')' else s := s+')'; end; end; getreferencestring:=s; end; function getopstr(const o:toper) : string; var hs : string; begin case o.typ of top_reg : getopstr:=gas_reg2str[o.reg]; top_ref : getopstr:=getreferencestring(o.ref^); top_const : getopstr:='$'+tostr(longint(o.val)); top_symbol : begin if assigned(o.sym) then hs:='$'+o.sym.name else hs:='$'; if o.symofs>0 then hs:=hs+'+'+tostr(o.symofs) else if o.symofs<0 then hs:=hs+tostr(o.symofs) else if not(assigned(o.sym)) then hs:=hs+'0'; getopstr:=hs; end; else internalerror(10001); end; end; function getopstr_jmp(const o:toper) : string; var hs : string; begin case o.typ of top_reg : getopstr_jmp:='*'+gas_reg2str[o.reg]; top_ref : getopstr_jmp:='*'+getreferencestring(o.ref^); top_const : getopstr_jmp:=tostr(longint(o.val)); top_symbol : begin hs:=o.sym.name; if o.symofs>0 then hs:=hs+'+'+tostr(o.symofs) else if o.symofs<0 then hs:=hs+tostr(o.symofs); getopstr_jmp:=hs; end; else internalerror(10001); end; end; {**************************************************************************** TISPARCATTASMOUTPUT ****************************************************************************} const ait_const2str:array[ait_const_32bit..ait_const_8bit]of string[8]=(#9'.long'#9,#9'.short'#9,#9'.byte'#9); procedure TGasSPARC.WriteInstruction(hp:Tai); var Op:TAsmOp; s:STRING; i:Integer; sep:STRING[3]; begin if hp.typ<>ait_instruction then Exit; taicpu(hp).SetOperandOrder(op_att); op:=taicpu(hp).opcode; {call maybe not translated to call} s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition]; if is_CallJmp(op) then { call and jmp need an extra handling } { this code is only called if jmp isn't a labeled instruction } { quick hack to overcome a problem with manglednames=255 chars } begin s:=#9+std_op2str[op]+#9+getopstr_jmp(taicpu(hp).oper[0]); end ELSE BEGIN {process operands} s:=#9+std_op2str[op]; IF taicpu(hp).ops<>0 THEN BEGIN { if not is_calljmp(op) then sep:=',' else } sep:=#9; FOR i:=0 TO taicpu(hp).ops-1 DO BEGIN s:=s+sep+getopstr(taicpu(hp).oper[i]); sep:=','; END; END; END; AsmWriteLn(s); END; {***************************************************************************** Initialize *****************************************************************************} CONST as_SPARC_as_info:TAsmInfo=( id : as_gas; idtxt : 'AS'; asmbin : 'as'; asmcmd : '-o $OBJ $ASM'; supported_target : system_any; outputbinary: false; allowdirect : true; needar : true; labelprefix_only_inside_procedure : false; labelprefix : '.L'; comment : '# '; secnames : ({sec_none}'', {no section} {sec_code}'.text', {executable code} {sec_data}'.data', {initialized R/W data} {sec_bss}'.bss', {uninitialized R/W data} {sec_idata2}'.comment', {comments} {sec_idata4}'.debug', {debugging information} {sec_idata5}'.rodata', {RO data} {sec_idata6}'.line', {line numbers info for symbolic debug} {sec_idata7}'.init', {runtime intialization code} {sec_edata}'.fini', {runtime finalization code} {sec_stab}'.stab', {sec_stabstr} '.stabstr', {sec_common}'.note') {note info} ); INITIALIZATION RegisterAssembler(as_SPARC_as_info,TGasSPARC); END.