cpugas.pas 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. {*****************************************************************************}
  2. { File : cpugas.pas }
  3. { Author : Mazen NEIFER }
  4. { Project : Free Pascal Compiler (FPC) }
  5. { Creation date : 2002\05\01 }
  6. { Last modification date : 2002\08\22 }
  7. { Licence : GPL }
  8. { Bug report : [email protected] }
  9. {*****************************************************************************}
  10. { $Id$
  11. Copyright (c) 1998-2000 by Florian Klaempfl
  12. This unit implements an asmoutput class for SPARC AT&T syntax
  13. This program is free software; you can redistribute it and/or modify
  14. it under the terms of the GNU General Public License as published by
  15. the Free Software Foundation; either version 2 of the License, or
  16. (at your option) any later version.
  17. This program is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. GNU General Public License for more details.
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. ****************************************************************************}
  25. UNIT CpuGas;
  26. {$MACRO ON}{$INCLUDE fpcdefs.inc}
  27. INTERFACE
  28. USES
  29. cclasses,cpubase,
  30. globals,
  31. aasmbase,aasmtai,aasmcpu,assemble,aggas;
  32. TYPE
  33. TGasSPARC=class(TGnuAssembler)
  34. PROCEDURE WriteInstruction(hp:Tai);OVERRIDE;
  35. END;
  36. IMPLEMENTATION
  37. USES
  38. strings,
  39. dos,
  40. globtype,
  41. fmodule,finput,
  42. cutils,systems,
  43. verbose;
  44. {$DEFINE gas_reg2str:=std_reg2str}
  45. CONST
  46. line_length = 70;
  47. VAR
  48. {$ifdef GDB}
  49. n_line : byte; { different types of source lines }
  50. linecount,
  51. includecount : longint;
  52. funcname : pchar;
  53. stabslastfileinfo : tfileposinfo;
  54. {$endif}
  55. lastsec : tsection; { last section type written }
  56. lastfileinfo : tfileposinfo;
  57. infile,
  58. lastinfile : tinputfile;
  59. symendcount : longint;
  60. function fixline(s:string):string;
  61. {
  62. return s with all leading and ending spaces and tabs removed
  63. }
  64. var
  65. i,j,k : longint;
  66. begin
  67. i:=length(s);
  68. while (i>0) and (s[i] in [#9,' ']) do
  69. dec(i);
  70. j:=1;
  71. while (j<i) and (s[j] in [#9,' ']) do
  72. inc(j);
  73. for k:=j to i do
  74. if s[k] in [#0..#31,#127..#255] then
  75. s[k]:='.';
  76. fixline:=Copy(s,j,i-j+1);
  77. end;
  78. function single2str(d : single) : string;
  79. var
  80. hs : string;
  81. begin
  82. str(d,hs);
  83. { replace space with + }
  84. if hs[1]=' ' then
  85. hs[1]:='+';
  86. single2str:='0d'+hs
  87. end;
  88. function double2str(d : double) : string;
  89. var
  90. hs : string;
  91. begin
  92. str(d,hs);
  93. { replace space with + }
  94. if hs[1]=' ' then
  95. hs[1]:='+';
  96. double2str:='0d'+hs
  97. end;
  98. function extended2str(e : extended) : string;
  99. var
  100. hs : string;
  101. begin
  102. str(e,hs);
  103. { replace space with + }
  104. if hs[1]=' ' then
  105. hs[1]:='+';
  106. extended2str:='0d'+hs
  107. end;
  108. function getreferencestring(var ref : treference) : string;
  109. var
  110. s : string;
  111. begin
  112. with ref do
  113. begin
  114. inc(offset,offsetfixup);
  115. offsetfixup:=0;
  116. { have we a segment prefix ? }
  117. { These are probably not correctly handled under GAS }
  118. { should be replaced by coding the segment override }
  119. { directly! - DJGPP FAQ }
  120. if segment<>R_NO then
  121. s:=gas_reg2str[segment]+':'
  122. else
  123. s:='';
  124. if assigned(symbol) then
  125. s:=s+symbol.name;
  126. if offset<0 then
  127. s:=s+tostr(offset)
  128. else
  129. if (offset>0) then
  130. begin
  131. if assigned(symbol) then
  132. s:=s+'+'+tostr(offset)
  133. else
  134. s:=s+tostr(offset);
  135. end
  136. else if (index=R_NO) and (base=R_NO) and not assigned(symbol) then
  137. s:=s+'0';
  138. if (index<>R_NO) and (base=R_NO) then
  139. begin
  140. s:=s+'(,'+gas_reg2str[index];
  141. if scalefactor<>0 then
  142. s:=s+','+tostr(scalefactor)+')'
  143. else
  144. s:=s+')';
  145. end
  146. else
  147. if (index=R_NO) and (base<>R_NO) then
  148. s:=s+'('+gas_reg2str[base]+')'
  149. else
  150. if (index<>R_NO) and (base<>R_NO) then
  151. begin
  152. s:=s+'('+gas_reg2str[base]+','+gas_reg2str[index];
  153. if scalefactor<>0 then
  154. s:=s+','+tostr(scalefactor)+')'
  155. else
  156. s := s+')';
  157. end;
  158. end;
  159. getreferencestring:=s;
  160. end;
  161. function getopstr(const o:toper) : string;
  162. var
  163. hs : string;
  164. begin
  165. case o.typ of
  166. top_reg :
  167. getopstr:=gas_reg2str[o.reg];
  168. top_ref :
  169. getopstr:=getreferencestring(o.ref^);
  170. top_const :
  171. getopstr:='$'+tostr(longint(o.val));
  172. top_symbol :
  173. begin
  174. if assigned(o.sym) then
  175. hs:='$'+o.sym.name
  176. else
  177. hs:='$';
  178. if o.symofs>0 then
  179. hs:=hs+'+'+tostr(o.symofs)
  180. else
  181. if o.symofs<0 then
  182. hs:=hs+tostr(o.symofs)
  183. else
  184. if not(assigned(o.sym)) then
  185. hs:=hs+'0';
  186. getopstr:=hs;
  187. end;
  188. else
  189. internalerror(10001);
  190. end;
  191. end;
  192. function getopstr_jmp(const o:toper) : string;
  193. var
  194. hs : string;
  195. begin
  196. case o.typ of
  197. top_reg :
  198. getopstr_jmp:='*'+gas_reg2str[o.reg];
  199. top_ref :
  200. getopstr_jmp:='*'+getreferencestring(o.ref^);
  201. top_const :
  202. getopstr_jmp:=tostr(longint(o.val));
  203. top_symbol :
  204. begin
  205. hs:=o.sym.name;
  206. if o.symofs>0 then
  207. hs:=hs+'+'+tostr(o.symofs)
  208. else
  209. if o.symofs<0 then
  210. hs:=hs+tostr(o.symofs);
  211. getopstr_jmp:=hs;
  212. end;
  213. else
  214. internalerror(10001);
  215. end;
  216. end;
  217. {****************************************************************************
  218. TISPARCATTASMOUTPUT
  219. ****************************************************************************}
  220. const
  221. ait_const2str : array[ait_const_32bit..ait_const_8bit] of string[8]=
  222. (#9'.long'#9,#9'.short'#9,#9'.byte'#9);
  223. PROCEDURE TGasSPARC.WriteInstruction(hp:Tai);
  224. VAR
  225. Op:TAsmOp;
  226. s:STRING;
  227. i:Integer;
  228. sep:STRING[3];
  229. BEGIN
  230. IF hp.typ<>ait_instruction
  231. THEN
  232. Exit;
  233. taicpu(hp).SetOperandOrder(op_att);
  234. op:=taicpu(hp).opcode;
  235. { call maybe not translated to call }
  236. s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition];
  237. IF is_CallJmp(op)
  238. THEN
  239. { call and jmp need an extra handling }
  240. { this code is only called if jmp isn't a labeled instruction }
  241. { quick hack to overcome a problem with manglednames=255 chars }
  242. BEGIN
  243. { IF op<>A_JMPl
  244. THEN
  245. s:=cond2str(op,taicpu(hp).condition)+','
  246. ELSE}
  247. s:=#9'b'#9;
  248. s:=s+getopstr_jmp(taicpu(hp).oper[0]);
  249. END
  250. ELSE
  251. BEGIN {process operands}
  252. s:=#9+std_op2str[op];
  253. IF taicpu(hp).ops<>0
  254. THEN
  255. BEGIN
  256. {
  257. if not is_calljmp(op) then
  258. sep:=','
  259. else
  260. }
  261. sep:=#9;
  262. FOR i:=0 TO taicpu(hp).ops-1 DO
  263. BEGIN
  264. s:=s+sep+getopstr(taicpu(hp).oper[i]);
  265. sep:=',';
  266. END;
  267. END;
  268. END;
  269. AsmWriteLn(s);
  270. END;
  271. {*****************************************************************************
  272. Initialize
  273. *****************************************************************************}
  274. CONST
  275. as_SPARC_as_info:TAsmInfo=(
  276. id : as_gas;
  277. idtxt : 'AS';
  278. asmbin : 'as';
  279. asmcmd : '-o $OBJ $ASM';
  280. supported_target : system_any;
  281. outputbinary: false;
  282. allowdirect : true;
  283. needar : true;
  284. labelprefix_only_inside_procedure : false;
  285. labelprefix : '.L';
  286. comment : '# ';
  287. secnames : ({sec_none}'', {no section}
  288. {sec_code}'.text', {executable code}
  289. {sec_data}'.data', {initialized R/W data}
  290. {sec_bss}'.bss', {uninitialized R/W data}
  291. {sec_idata2}'.comment', {comments}
  292. {sec_idata4}'.debug', {debugging information}
  293. {sec_idata5}'.rodata', {RO data}
  294. {sec_idata6}'.line', {line numbers info for symbolic debug}
  295. {sec_idata7}'.init', {runtime intialization code}
  296. {sec_edata}'.fini', {runtime finalization code}
  297. {sec_stab}'.stab',
  298. {sec_stabstr} '.stabstr',
  299. {sec_common}'.note') {note info}
  300. );
  301. INITIALIZATION
  302. RegisterAssembler(as_SPARC_as_info,TGasSPARC);
  303. END.