radi386.pas 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. {
  2. $Id$
  3. Copyright (c) 1998 by Florian Klaempfl
  4. Reads inline assembler and writes the lines direct to the output
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit radi386;
  19. interface
  20. uses
  21. tree;
  22. function assemble : ptree;
  23. implementation
  24. uses
  25. i386,hcodegen,globals,scanner,aasm,
  26. cobjects,symtable,types,verbose,asmutils;
  27. function assemble : ptree;
  28. var
  29. retstr,s,hs : string;
  30. c : char;
  31. ende : boolean;
  32. sym : psym;
  33. code : paasmoutput;
  34. l : longint;
  35. procedure writeasmline;
  36. var
  37. i : longint;
  38. begin
  39. i:=length(s);
  40. while (i>0) and (s[i] in [' ',#9]) do
  41. dec(i);
  42. s[0]:=chr(i);
  43. if s<>'' then
  44. code^.concat(new(pai_direct,init(strpnew(s))));
  45. { consider it set function set if the offset was loaded }
  46. if assigned(procinfo.retdef) and
  47. (pos(retstr,upper(s))>0) then
  48. procinfo.funcret_is_valid:=true;
  49. s:='';
  50. end;
  51. begin
  52. ende:=false;
  53. s:='';
  54. if assigned(procinfo.retdef) and
  55. is_fpu(procinfo.retdef) then
  56. procinfo.funcret_is_valid:=true;
  57. if assigned(procinfo.retdef) and
  58. (procinfo.retdef<>pdef(voiddef)) then
  59. retstr:=upper(tostr(procinfo.retoffset)+'('+att_reg2str[procinfo.framepointer]+')')
  60. else
  61. retstr:='';
  62. c:=asmgetchar;
  63. code:=new(paasmoutput,init);
  64. while not(ende) do
  65. begin
  66. case c of
  67. 'A'..'Z','a'..'z','_' : begin
  68. hs:='';
  69. while ((ord(c)>=ord('A')) and (ord(c)<=ord('Z')))
  70. or ((ord(c)>=ord('a')) and (ord(c)<=ord('z')))
  71. or ((ord(c)>=ord('0')) and (ord(c)<=ord('9')))
  72. or (c='_') do
  73. begin
  74. inc(byte(hs[0]));
  75. hs[length(hs)]:=c;
  76. c:=asmgetchar;
  77. end;
  78. if upper(hs)='END' then
  79. ende:=true
  80. else
  81. begin
  82. if c=':' then
  83. begin
  84. getsym(upper(hs),false);
  85. if srsym<>nil then
  86. Message(assem_w_using_defined_as_local);
  87. end;
  88. if upper(hs)='FWAIT' then
  89. FwaitWarning
  90. else
  91. { access to local variables }
  92. if assigned(aktprocsym) then
  93. begin
  94. { is the last written character an special }
  95. { char ? }
  96. if (s[length(s)]='%') and
  97. ret_in_acc(procinfo.retdef) and
  98. ((pos('AX',upper(hs))>0) or
  99. (pos('AL',upper(hs))>0)) then
  100. procinfo.funcret_is_valid:=true;
  101. if (s[length(s)]<>'%') and
  102. (s[length(s)]<>'$') and
  103. ((s[length(s)]<>'0') or (hs[1]<>'x')) then
  104. begin
  105. if assigned(aktprocsym^.definition^.localst) then
  106. sym:=aktprocsym^.definition^.localst^.search(upper(hs))
  107. else
  108. sym:=nil;
  109. if assigned(sym) then
  110. begin
  111. if sym^.typ=varsym then
  112. begin
  113. {variables set are after a comma }
  114. {like in movl %eax,I }
  115. if pos(',',s) > 0 then
  116. pvarsym(sym)^.is_valid:=1
  117. else
  118. if (pos('MOV',upper(s)) > 0) and (pvarsym(sym)^.is_valid=0) then
  119. Message1(sym_n_local_var_not_init_yet,hs);
  120. hs:='-'+tostr(pvarsym(sym)^.address)+'('+att_reg2str[procinfo.framepointer]+')';
  121. end
  122. else
  123. { call to local function }
  124. if (sym^.typ=procsym) and (pos('CALL',upper(s))>0) then
  125. begin
  126. hs:=pprocsym(sym)^.definition^.mangledname;
  127. end;
  128. end
  129. else
  130. begin
  131. if assigned(aktprocsym^.definition^.parast) then
  132. sym:=aktprocsym^.definition^.parast^.search(upper(hs))
  133. else
  134. sym:=nil;
  135. if assigned(sym) then
  136. begin
  137. if sym^.typ=varsym then
  138. begin
  139. l:=pvarsym(sym)^.address;
  140. { set offset }
  141. inc(l,aktprocsym^.definition^.parast^.call_offset);
  142. hs:=tostr(l)+'('+att_reg2str[procinfo.framepointer]+')';
  143. if pos(',',s) > 0 then
  144. pvarsym(sym)^.is_valid:=1;
  145. end;
  146. end
  147. { I added that but it creates a problem in line.ppi
  148. because there is a local label wbuffer and
  149. a static variable WBUFFER ...
  150. what would you decide, florian ?
  151. else
  152. begin
  153. getsym(upper(hs),false);
  154. sym:=srsym;
  155. if assigned(sym) and (sym^.typ = varsym)
  156. or (sym^.typ = typedconstsym) then
  157. hs:=sym^.mangledname;
  158. if (sym^.typ=procsym) and (pos('CALL',upper(s))>0) then
  159. begin
  160. if assigned(pprocsym(sym)^.definition^.nextoverloaded) then
  161. begin
  162. exterror:=strpnew(' calling an overloaded procedure in asm');
  163. warning(user_defined);
  164. end;
  165. hs:=pprocsym(sym)^.definition^.mangledname;
  166. end;
  167. end }
  168. else if upper(hs)='__SELF' then
  169. begin
  170. if assigned(procinfo._class) then
  171. hs:=tostr(procinfo.ESI_offset)+'('+att_reg2str[procinfo.framepointer]+')'
  172. else
  173. Message(assem_e_cannot_use_SELF_outside_a_method);
  174. end
  175. else if upper(hs)='__RESULT' then
  176. begin
  177. if assigned(procinfo.retdef) and
  178. (procinfo.retdef<>pdef(voiddef)) then
  179. begin
  180. hs:=retstr;
  181. end
  182. else
  183. Message(assem_w_void_function);
  184. end
  185. else if upper(hs)='__OLDEBP' then
  186. begin
  187. { complicate to check there }
  188. { we do it: }
  189. if lexlevel>2 then
  190. hs:=tostr(procinfo.framepointer_offset)
  191. +'('+att_reg2str[procinfo.framepointer]+')'
  192. else
  193. Message(assem_e_cannot_use___OLDEBP_outside_nested_procedure);
  194. end;
  195. end;
  196. { end;}
  197. end;
  198. end;
  199. s:=s+hs;
  200. end;
  201. end;
  202. '{',';',#10,#13 : begin
  203. if pos(retstr,s) > 0 then
  204. procinfo.funcret_is_valid:=true;
  205. writeasmline;
  206. c:=asmgetchar;
  207. end;
  208. #26 : Message(scan_f_end_of_file);
  209. else
  210. begin
  211. inc(byte(s[0]));
  212. s[length(s)]:=c;
  213. c:=asmgetchar;
  214. end;
  215. end;
  216. end;
  217. writeasmline;
  218. assemble:=genasmnode(code);
  219. end;
  220. end.
  221. {
  222. $Log$
  223. Revision 1.2 1998-04-08 16:58:06 pierre
  224. * several bugfixes
  225. ADD ADC and AND are also sign extended
  226. nasm output OK (program still crashes at end
  227. and creates wrong assembler files !!)
  228. procsym types sym in tdef removed !!
  229. Revision 1.1.1.1 1998/03/25 11:18:15 root
  230. * Restored version
  231. Revision 1.13 1998/03/24 21:48:33 florian
  232. * just a couple of fixes applied:
  233. - problem with fixed16 solved
  234. - internalerror 10005 problem fixed
  235. - patch for assembler reading
  236. - small optimizer fix
  237. - mem is now supported
  238. Revision 1.12 1998/03/10 16:27:43 pierre
  239. * better line info in stabs debug
  240. * symtabletype and lexlevel separated into two fields of tsymtable
  241. + ifdef MAKELIB for direct library output, not complete
  242. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  243. working
  244. + ifdef TESTFUNCRET for setting func result in underfunction, not
  245. working
  246. Revision 1.11 1998/03/10 01:17:26 peter
  247. * all files have the same header
  248. * messages are fully implemented, EXTDEBUG uses Comment()
  249. + AG... files for the Assembler generation
  250. Revision 1.10 1998/03/09 12:58:12 peter
  251. * FWait warning is only showed for Go32V2 and $E+
  252. * opcode tables moved to i386.pas/m68k.pas to reduce circular uses (and
  253. for m68k the same tables are removed)
  254. + $E for i386
  255. Revision 1.9 1998/03/06 00:52:51 peter
  256. * replaced all old messages from errore.msg, only ExtDebug and some
  257. Comment() calls are left
  258. * fixed options.pas
  259. Revision 1.8 1998/03/03 16:45:23 peter
  260. + message support for assembler parsers
  261. Revision 1.7 1998/03/02 01:49:14 peter
  262. * renamed target_DOS to target_GO32V1
  263. + new verbose system, merged old errors and verbose units into one new
  264. verbose.pas, so errors.pas is obsolete
  265. Revision 1.6 1998/02/13 10:35:35 daniel
  266. * Made Motorola version compilable.
  267. * Fixed optimizer
  268. Revision 1.5 1998/02/07 18:01:27 carl
  269. + fwait warning for emulation
  270. Revision 1.3 1997/11/30 18:12:17 carl
  271. * bugfix of line numbering.
  272. Revision 1.2 1997/11/28 18:14:44 pierre
  273. working version with several bug fixes
  274. Revision 1.1.1.1 1997/11/27 08:33:00 michael
  275. FPC Compiler CVS start
  276. Pre-CVS log:
  277. History:
  278. 19th october 1996:
  279. + created from old asmbl.pas
  280. 13th october 1996:
  281. + renamed to radi386
  282. }