nasmconv.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Peter Vreman and Florian Klaempfl
  4. Convert i386ins.dat from Nasm to a .inc file for usage with
  5. the Free pascal compiler
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. program nasmconv;
  13. const
  14. Version = '0.99.13';
  15. var
  16. s : string;
  17. i : longint;
  18. {$ifndef FPC}
  19. procedure readln(var t:text;var s:string);
  20. var
  21. c : char;
  22. i : longint;
  23. begin
  24. c:=#0;
  25. i:=0;
  26. while (not eof(t)) and (c<>#10) do
  27. begin
  28. read(t,c);
  29. if c<>#10 then
  30. begin
  31. inc(i);
  32. s[i]:=c;
  33. end;
  34. end;
  35. if (i>0) and (s[i]=#13) then
  36. dec(i);
  37. s[0]:=chr(i);
  38. end;
  39. {$endif}
  40. function lower(const s : string) : string;
  41. {
  42. return lowercased string of s
  43. }
  44. var
  45. i : longint;
  46. begin
  47. for i:=1 to length(s) do
  48. if s[i] in ['A'..'Z'] then
  49. lower[i]:=char(byte(s[i])+32)
  50. else
  51. lower[i]:=s[i];
  52. lower[0]:=s[0];
  53. end;
  54. function Replace(var s:string;const s1,s2:string):boolean;
  55. var
  56. i : longint;
  57. begin
  58. i:=pos(s1,s);
  59. if i>0 then
  60. begin
  61. Delete(s,i,length(s1));
  62. Insert(s2,s,i);
  63. Replace:=true;
  64. end
  65. else
  66. Replace:=false;
  67. end;
  68. function formatop(s:string):string;
  69. const
  70. replaces=19;
  71. replacetab : array[1..replaces,1..2] of string[32]=(
  72. (':',' or ot_colon'),
  73. ('mem8','mem or ot_bits8'),
  74. ('mem16','mem or ot_bits16'),
  75. ('mem32','mem or ot_bits32'),
  76. ('mem64','mem or ot_bits64'),
  77. ('mem80','mem or ot_bits80'),
  78. ('mem','memory'),
  79. ('memory_offs','mem_offs'),
  80. ('imm8','imm or ot_bits8'),
  81. ('imm16','imm or ot_bits16'),
  82. ('imm32','imm or ot_bits32'),
  83. ('imm64','imm or ot_bits64'),
  84. ('imm80','imm or ot_bits80'),
  85. ('imm','immediate'),
  86. ('rm8','regmem or ot_bits8'),
  87. ('rm16','regmem or ot_bits16'),
  88. ('rm32','regmem or ot_bits32'),
  89. ('rm64','regmem or ot_bits64'),
  90. ('rm80','regmem or ot_bits80')
  91. );
  92. var
  93. i : longint;
  94. begin
  95. for i:=1to replaces do
  96. replace(s,replacetab[i,1],replacetab[i,2]);
  97. formatop:=s;
  98. end;
  99. function readnumber : longint;
  100. var
  101. base : longint;
  102. result : longint;
  103. begin
  104. result:=0;
  105. if s[i]='\' then
  106. begin
  107. base:=8;
  108. inc(i);
  109. if s[i]='x' then
  110. begin
  111. base:=16;
  112. inc(i);
  113. end;
  114. end
  115. else
  116. base:=10;
  117. s[i]:=upcase(s[i]);
  118. while s[i] in ['0'..'9','A'..'F'] do
  119. begin
  120. case s[i] of
  121. '0'..'9':
  122. result:=result*base+ord(s[i])-ord('0');
  123. 'A'..'F':
  124. result:=result*base+ord(s[i])-ord('A')+10;
  125. end;
  126. inc(i);
  127. end;
  128. readnumber:=result;
  129. end;
  130. function tostr(l : longint) : string;
  131. var
  132. hs : string;
  133. begin
  134. str(l,hs);
  135. tostr:=hs;
  136. end;
  137. function readstr : string;
  138. var
  139. result : string;
  140. begin
  141. result:='';
  142. while (s[i] in ['0'..'9','A'..'Z','a'..'z','_']) and (i<=length(s)) do
  143. begin
  144. result:=result+s[i];
  145. inc(i);
  146. end;
  147. readstr:=result;
  148. end;
  149. procedure skipspace;
  150. begin
  151. while (s[i] in [' ',#9]) do
  152. inc(i);
  153. end;
  154. procedure openinc(var f:text;const fn:string);
  155. begin
  156. writeln('creating ',fn);
  157. assign(f,fn);
  158. rewrite(f);
  159. writeln(f,'{ don''t edit, this file is generated from i386ins.dat }');
  160. writeln(f,'(');
  161. end;
  162. procedure closeinc(var f:text);
  163. begin
  164. writeln(f);
  165. writeln(f,');');
  166. close(f);
  167. end;
  168. var
  169. attsuffix,
  170. hs : string;
  171. j : longint;
  172. firstopcode,
  173. first : boolean;
  174. maxinfolen,
  175. code : byte;
  176. insns : longint;
  177. attsuffile,propfile,opfile,attfile,intfile,
  178. infile,insfile : text;
  179. { instruction fields }
  180. last,
  181. ops : longint;
  182. intopcode,
  183. attopcode,
  184. opcode,
  185. codes,
  186. flags : string;
  187. optypes : array[1..3] of string;
  188. begin
  189. writeln('Nasm Instruction Table Converter Version ',Version);
  190. insns:=0;
  191. maxinfolen:=0;
  192. { open dat file }
  193. assign(infile,'i386ins.dat');
  194. reset(infile);
  195. { create inc files }
  196. openinc(insfile,'i386tab.inc');
  197. openinc(opfile,'i386op.inc');
  198. openinc(attfile,'i386att.inc');
  199. openinc(attsuffile,'i386atts.inc');
  200. openinc(intfile,'i386int.inc');
  201. openinc(propfile,'i386prop.inc');
  202. first:=true;
  203. opcode:='';
  204. firstopcode:=true;
  205. while not(eof(infile)) do
  206. begin
  207. { handle comment }
  208. readln(infile,s);
  209. while (s[1]=' ') do
  210. delete(s,1,1);
  211. if (s='') or (s[1]=';') then
  212. continue;
  213. if (s[1]='[') then
  214. begin
  215. i:=pos(',',s);
  216. j:=pos(']',s);
  217. if i=0 then
  218. begin
  219. opcode:='A_'+Copy(s,2,j-2);
  220. intopcode:=Copy(s,2,j-2);
  221. { Conditional }
  222. if (intopcode[length(intopcode)]='c') and
  223. (intopcode[length(intopcode)-1]='c') then
  224. dec(byte(intopcode[0]),2);
  225. attopcode:=intopcode;
  226. attsuffix:='attsufNONE';
  227. end
  228. else
  229. begin
  230. opcode:='A_'+Copy(s,2,i-2);
  231. intopcode:=Copy(s,2,i-2);
  232. { intel conditional }
  233. if (intopcode[length(intopcode)]='c') and
  234. (intopcode[length(intopcode)-1]='c') then
  235. dec(byte(intopcode[0]),2);
  236. attopcode:=Copy(s,i+1,j-i-1);
  237. { att Suffix }
  238. case attopcode[length(attopcode)] of
  239. 'X' :
  240. begin
  241. dec(attopcode[0]);
  242. attsuffix:='attsufINT';
  243. end;
  244. 'F' :
  245. begin
  246. dec(attopcode[0]);
  247. attsuffix:='attsufFPU';
  248. end;
  249. else
  250. attsuffix:='attsufNONE';
  251. end;
  252. { att Conditional }
  253. if (attopcode[length(attopcode)]='C') and
  254. (attopcode[length(attopcode)-1]='C') then
  255. dec(byte(attopcode[0]),2);
  256. end;
  257. intopcode:=Lower(intopcode);
  258. attopcode:=Lower(attopcode);
  259. if firstopcode then
  260. firstopcode:=false
  261. else
  262. begin
  263. writeln(opfile,',');
  264. writeln(attfile,',');
  265. writeln(attsuffile,',');
  266. writeln(intfile,',');
  267. writeln(propfile,',');
  268. end;
  269. write(opfile,opcode);
  270. write(intfile,'''',intopcode,'''');
  271. write(attfile,'''',attopcode,'''');
  272. write(attsuffile,attsuffix);
  273. { read the next line which contains the Change options }
  274. repeat
  275. readln(infile,s);
  276. until eof(infile) or ((s<>'') and (s[1]<>';'));
  277. write(propfile,'(Ch: ',s,')');
  278. continue;
  279. end;
  280. { we must have an opcode }
  281. if opcode='' then
  282. runerror(234);
  283. { clear }
  284. ops:=0;
  285. optypes[1]:='';
  286. optypes[2]:='';
  287. optypes[3]:='';
  288. codes:='';
  289. flags:='';
  290. { ops and optypes }
  291. i:=1;
  292. repeat
  293. hs:=readstr;
  294. if (hs='void') or (hs='ignore') then
  295. break;
  296. inc(ops);
  297. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
  298. if s[i]=':' then
  299. begin
  300. inc(i);
  301. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  302. end;
  303. while s[i]='|' do
  304. begin
  305. inc(i);
  306. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  307. end;
  308. if s[i]=',' then
  309. inc(i)
  310. else
  311. break;
  312. until false;
  313. for j:=1 to 3-ops do
  314. optypes[3-j+1]:='ot_none';
  315. { codes }
  316. skipspace;
  317. j:=0;
  318. last:=0;
  319. if s[i] in ['\','0'..'9'] then
  320. begin
  321. while not(s[i] in [' ',#9]) do
  322. begin
  323. code:=readnumber;
  324. { for some codes we want also to change the optypes, but not
  325. if the last byte was a 1 then this byte belongs to a direct
  326. copy }
  327. if last<>1 then
  328. begin
  329. case code of
  330. 12,13,14 :
  331. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  332. end;
  333. end;
  334. codes:=codes+'#'+tostr(code);
  335. last:=code;
  336. inc(j);
  337. end;
  338. end
  339. else
  340. begin
  341. readstr;
  342. codes:='#0';
  343. end;
  344. if j>maxinfolen then
  345. maxinfolen:=j;
  346. { flags }
  347. skipspace;
  348. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  349. begin
  350. hs:=readstr;
  351. if hs='ignore' then
  352. begin
  353. flags:='0';
  354. break;
  355. end;
  356. if hs<>'ND' then
  357. begin
  358. if flags<>'' then
  359. flags:=flags+' or ';
  360. flags:=flags+'if_'+lower(hs);
  361. end;
  362. if (s[i]=',') and (i<=length(s)) then
  363. inc(i)
  364. else
  365. break;
  366. end;
  367. { write instruction }
  368. if not(first) then
  369. writeln(insfile,',')
  370. else
  371. first:=false;
  372. writeln(insfile,' (');
  373. writeln(insfile,' opcode : ',opcode,';');
  374. writeln(insfile,' ops : ',ops,';');
  375. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],');');
  376. writeln(insfile,' code : ',codes,';');
  377. writeln(insfile,' flags : ',flags);
  378. write(insfile,' )');
  379. inc(insns);
  380. end;
  381. close(infile);
  382. closeinc(insfile);
  383. closeinc(intfile);
  384. closeinc(attfile);
  385. closeinc(attsuffile);
  386. closeinc(opfile);
  387. closeinc(propfile);
  388. writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
  389. end.
  390. {
  391. $Log$
  392. Revision 1.8 2000-02-09 13:23:11 peter
  393. * log truncated
  394. Revision 1.7 2000/01/28 09:41:39 peter
  395. * fixed fpu suffix parsing for att reader
  396. Revision 1.6 2000/01/07 01:15:01 peter
  397. * updated copyright to 2000
  398. Revision 1.5 1999/10/28 09:47:45 peter
  399. * update to use i386ins.dat
  400. Revision 1.4 1999/10/27 16:06:52 peter
  401. * updated for new layout
  402. Revision 1.3 1999/08/12 14:36:09 peter
  403. + KNI instructions
  404. }