ra386dir.pas 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 Ra386dir;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. tree;
  23. function assemble : ptree;
  24. implementation
  25. uses
  26. fmodule,globals,scanner,aasm,cpubase,cpuasm,
  27. cutils,cobjects,symconst,symtable,types,verbose,
  28. {$ifdef NEWCG}
  29. cgbase,
  30. {$else}
  31. hcodegen,
  32. {$endif}
  33. rautils,ra386;
  34. function assemble : ptree;
  35. var
  36. retstr,s,hs : string;
  37. c : char;
  38. ende : boolean;
  39. sym : psym;
  40. code : paasmoutput;
  41. i,l : longint;
  42. procedure writeasmline;
  43. var
  44. i : longint;
  45. begin
  46. i:=length(s);
  47. while (i>0) and (s[i] in [' ',#9]) do
  48. dec(i);
  49. s[0]:=chr(i);
  50. if s<>'' then
  51. code^.concat(new(pai_direct,init(strpnew(s))));
  52. { consider it set function set if the offset was loaded }
  53. if assigned(procinfo^.returntype.def) and
  54. (pos(retstr,upper(s))>0) then
  55. procinfo^.funcret_state:=vs_assigned;
  56. s:='';
  57. end;
  58. begin
  59. ende:=false;
  60. s:='';
  61. if assigned(procinfo^.returntype.def) and
  62. is_fpu(procinfo^.returntype.def) then
  63. procinfo^.funcret_state:=vs_assigned;
  64. if assigned(procinfo^.returntype.def) and
  65. (procinfo^.returntype.def<>pdef(voiddef)) then
  66. retstr:=upper(tostr(procinfo^.return_offset)+'('+att_reg2str[procinfo^.framepointer]+')')
  67. else
  68. retstr:='';
  69. c:=current_scanner^.asmgetchar;
  70. code:=new(paasmoutput,init);
  71. while not(ende) do
  72. begin
  73. { wrong placement
  74. current_scanner^.gettokenpos; }
  75. case c of
  76. 'A'..'Z','a'..'z','_' : begin
  77. current_scanner^.gettokenpos;
  78. i:=0;
  79. hs:='';
  80. while ((ord(c)>=ord('A')) and (ord(c)<=ord('Z')))
  81. or ((ord(c)>=ord('a')) and (ord(c)<=ord('z')))
  82. or ((ord(c)>=ord('0')) and (ord(c)<=ord('9')))
  83. or (c='_') do
  84. begin
  85. inc(i);
  86. hs[i]:=c;
  87. c:=current_scanner^.asmgetchar;
  88. end;
  89. hs[0]:=chr(i);
  90. if upper(hs)='END' then
  91. ende:=true
  92. else
  93. begin
  94. if c=':' then
  95. begin
  96. getsym(upper(hs),false);
  97. if srsym<>nil then
  98. if (srsym^.typ = labelsym) then
  99. Begin
  100. hs:=plabelsym(srsym)^.lab^.name;
  101. plabelsym(srsym)^.lab^.is_set:=true;
  102. end
  103. else
  104. Message(asmr_w_using_defined_as_local);
  105. end
  106. else if upper(hs)='FWAIT' then
  107. FwaitWarning
  108. else
  109. { access to local variables }
  110. if assigned(aktprocsym) then
  111. begin
  112. { is the last written character an special }
  113. { char ? }
  114. if (s[length(s)]='%') and
  115. ret_in_acc(procinfo^.returntype.def) and
  116. ((pos('AX',upper(hs))>0) or
  117. (pos('AL',upper(hs))>0)) then
  118. procinfo^.funcret_state:=vs_assigned;
  119. if (s[length(s)]<>'%') and
  120. (s[length(s)]<>'$') and
  121. ((s[length(s)]<>'0') or (hs[1]<>'x')) then
  122. begin
  123. if assigned(aktprocsym^.definition^.localst) and
  124. (lexlevel >= normal_function_level) then
  125. sym:=aktprocsym^.definition^.localst^.search(upper(hs))
  126. else
  127. sym:=nil;
  128. if assigned(sym) then
  129. begin
  130. if (sym^.typ = labelsym) then
  131. Begin
  132. hs:=plabelsym(sym)^.lab^.name;
  133. end
  134. else if sym^.typ=varsym then
  135. begin
  136. {variables set are after a comma }
  137. {like in movl %eax,I }
  138. if pos(',',s) > 0 then
  139. pvarsym(sym)^.varstate:=vs_used
  140. else
  141. if (pos('MOV',upper(s)) > 0) and (pvarsym(sym)^.varstate=vs_declared) then
  142. Message1(sym_n_uninitialized_local_variable,hs);
  143. if (vo_is_external in pvarsym(sym)^.varoptions) then
  144. hs:=pvarsym(sym)^.mangledname
  145. else
  146. hs:='-'+tostr(pvarsym(sym)^.address)+
  147. '('+att_reg2str[procinfo^.framepointer]+')';
  148. end
  149. else
  150. { call to local function }
  151. if (sym^.typ=procsym) and ((pos('CALL',upper(s))>0) or
  152. (pos('LEA',upper(s))>0)) then
  153. begin
  154. hs:=pprocsym(sym)^.definition^.mangledname;
  155. end;
  156. end
  157. else
  158. begin
  159. if assigned(aktprocsym^.definition^.parast) then
  160. sym:=aktprocsym^.definition^.parast^.search(upper(hs))
  161. else
  162. sym:=nil;
  163. if assigned(sym) then
  164. begin
  165. if sym^.typ=varsym then
  166. begin
  167. l:=pvarsym(sym)^.address;
  168. { set offset }
  169. inc(l,aktprocsym^.definition^.parast^.address_fixup);
  170. hs:=tostr(l)+'('+att_reg2str[procinfo^.framepointer]+')';
  171. if pos(',',s) > 0 then
  172. pvarsym(sym)^.varstate:=vs_used;
  173. end;
  174. end
  175. { I added that but it creates a problem in line.ppi
  176. because there is a local label wbuffer and
  177. a static variable WBUFFER ...
  178. what would you decide, florian ?}
  179. else
  180. begin
  181. {$ifndef IGNOREGLOBALVAR}
  182. getsym(upper(hs),false);
  183. sym:=srsym;
  184. if assigned(sym) and (sym^.owner^.symtabletype in [unitsymtable,
  185. globalsymtable,staticsymtable]) then
  186. begin
  187. if (sym^.typ = varsym) or (sym^.typ = typedconstsym) then
  188. begin
  189. Message2(asmr_h_direct_global_to_mangled,hs,sym^.mangledname);
  190. hs:=sym^.mangledname;
  191. if sym^.typ=varsym then
  192. inc(pvarsym(sym)^.refs);
  193. end;
  194. { procs can be called or the address can be loaded }
  195. if (sym^.typ=procsym) and
  196. ((pos('CALL',upper(s))>0) or (pos('LEA',upper(s))>0)) then
  197. begin
  198. if assigned(pprocsym(sym)^.definition^.nextoverloaded) then
  199. Message1(asmr_w_direct_global_is_overloaded_func,hs);
  200. Message2(asmr_h_direct_global_to_mangled,hs,sym^.mangledname);
  201. hs:=sym^.mangledname;
  202. end;
  203. end
  204. else
  205. {$endif TESTGLOBALVAR}
  206. if upper(hs)='__SELF' then
  207. begin
  208. if assigned(procinfo^._class) then
  209. hs:=tostr(procinfo^.selfpointer_offset)+
  210. '('+att_reg2str[procinfo^.framepointer]+')'
  211. else
  212. Message(asmr_e_cannot_use_SELF_outside_a_method);
  213. end
  214. else if upper(hs)='__RESULT' then
  215. begin
  216. if assigned(procinfo^.returntype.def) and
  217. (procinfo^.returntype.def<>pdef(voiddef)) then
  218. hs:=retstr
  219. else
  220. Message(asmr_e_void_function);
  221. end
  222. else if upper(hs)='__OLDEBP' then
  223. begin
  224. { complicate to check there }
  225. { we do it: }
  226. if lexlevel>normal_function_level then
  227. hs:=tostr(procinfo^.framepointer_offset)+
  228. '('+att_reg2str[procinfo^.framepointer]+')'
  229. else
  230. Message(asmr_e_cannot_use_OLDEBP_outside_nested_procedure);
  231. end;
  232. end;
  233. end;
  234. end;
  235. end;
  236. s:=s+hs;
  237. end;
  238. end;
  239. '{',';',#10,#13 : begin
  240. if pos(retstr,s) > 0 then
  241. procinfo^.funcret_state:=vs_assigned;
  242. writeasmline;
  243. c:=current_scanner^.asmgetchar;
  244. end;
  245. #26 : Message(scan_f_end_of_file);
  246. else
  247. begin
  248. current_scanner^.gettokenpos;
  249. inc(byte(s[0]));
  250. s[length(s)]:=c;
  251. c:=current_scanner^.asmgetchar;
  252. end;
  253. end;
  254. end;
  255. writeasmline;
  256. assemble:=genasmnode(code);
  257. end;
  258. end.
  259. {
  260. $Log$
  261. Revision 1.4 2000-09-24 15:06:26 peter
  262. * use defines.inc
  263. Revision 1.3 2000/08/27 16:11:52 peter
  264. * moved some util functions from globals,cobjects to cutils
  265. * splitted files into finput,fmodule
  266. Revision 1.2 2000/07/13 11:32:48 michael
  267. + removed logs
  268. }