nasmconv.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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. 'R' :
  250. begin
  251. dec(attopcode[0]);
  252. attsuffix:='attsufFPUint';
  253. end;
  254. else
  255. attsuffix:='attsufNONE';
  256. end;
  257. { att Conditional }
  258. if (attopcode[length(attopcode)]='C') and
  259. (attopcode[length(attopcode)-1]='C') then
  260. dec(byte(attopcode[0]),2);
  261. end;
  262. intopcode:=Lower(intopcode);
  263. attopcode:=Lower(attopcode);
  264. if firstopcode then
  265. firstopcode:=false
  266. else
  267. begin
  268. writeln(opfile,',');
  269. writeln(attfile,',');
  270. writeln(attsuffile,',');
  271. writeln(intfile,',');
  272. writeln(propfile,',');
  273. end;
  274. write(opfile,opcode);
  275. write(intfile,'''',intopcode,'''');
  276. write(attfile,'''',attopcode,'''');
  277. write(attsuffile,attsuffix);
  278. { read the next line which contains the Change options }
  279. repeat
  280. readln(infile,s);
  281. until eof(infile) or ((s<>'') and (s[1]<>';'));
  282. write(propfile,'(Ch: ',s,')');
  283. continue;
  284. end;
  285. { we must have an opcode }
  286. if opcode='' then
  287. runerror(234);
  288. { clear }
  289. ops:=0;
  290. optypes[1]:='';
  291. optypes[2]:='';
  292. optypes[3]:='';
  293. codes:='';
  294. flags:='';
  295. { ops and optypes }
  296. i:=1;
  297. repeat
  298. hs:=readstr;
  299. if (hs='void') or (hs='ignore') then
  300. break;
  301. inc(ops);
  302. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
  303. if s[i]=':' then
  304. begin
  305. inc(i);
  306. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  307. end;
  308. while s[i]='|' do
  309. begin
  310. inc(i);
  311. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  312. end;
  313. if s[i]=',' then
  314. inc(i)
  315. else
  316. break;
  317. until false;
  318. for j:=1 to 3-ops do
  319. optypes[3-j+1]:='ot_none';
  320. { codes }
  321. skipspace;
  322. j:=0;
  323. last:=0;
  324. if s[i] in ['\','0'..'9'] then
  325. begin
  326. while not(s[i] in [' ',#9]) do
  327. begin
  328. code:=readnumber;
  329. { for some codes we want also to change the optypes, but not
  330. if the last byte was a 1 then this byte belongs to a direct
  331. copy }
  332. if last<>1 then
  333. begin
  334. case code of
  335. 12,13,14 :
  336. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  337. end;
  338. end;
  339. codes:=codes+'#'+tostr(code);
  340. last:=code;
  341. inc(j);
  342. end;
  343. end
  344. else
  345. begin
  346. readstr;
  347. codes:='#0';
  348. end;
  349. if j>maxinfolen then
  350. maxinfolen:=j;
  351. { flags }
  352. skipspace;
  353. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  354. begin
  355. hs:=readstr;
  356. if hs='ignore' then
  357. begin
  358. flags:='0';
  359. break;
  360. end;
  361. if hs<>'ND' then
  362. begin
  363. if flags<>'' then
  364. flags:=flags+' or ';
  365. flags:=flags+'if_'+lower(hs);
  366. end;
  367. if (s[i]=',') and (i<=length(s)) then
  368. inc(i)
  369. else
  370. break;
  371. end;
  372. { write instruction }
  373. if not(first) then
  374. writeln(insfile,',')
  375. else
  376. first:=false;
  377. writeln(insfile,' (');
  378. writeln(insfile,' opcode : ',opcode,';');
  379. writeln(insfile,' ops : ',ops,';');
  380. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],');');
  381. writeln(insfile,' code : ',codes,';');
  382. writeln(insfile,' flags : ',flags);
  383. write(insfile,' )');
  384. inc(insns);
  385. end;
  386. close(infile);
  387. closeinc(insfile);
  388. closeinc(intfile);
  389. closeinc(attfile);
  390. closeinc(attsuffile);
  391. closeinc(opfile);
  392. closeinc(propfile);
  393. writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
  394. end.
  395. {
  396. $Log$
  397. Revision 1.9 2000-04-04 13:44:03 pierre
  398. + R suffix for integer FPU operations
  399. Revision 1.8 2000/02/09 13:23:11 peter
  400. * log truncated
  401. Revision 1.7 2000/01/28 09:41:39 peter
  402. * fixed fpu suffix parsing for att reader
  403. Revision 1.6 2000/01/07 01:15:01 peter
  404. * updated copyright to 2000
  405. Revision 1.5 1999/10/28 09:47:45 peter
  406. * update to use i386ins.dat
  407. Revision 1.4 1999/10/27 16:06:52 peter
  408. * updated for new layout
  409. Revision 1.3 1999/08/12 14:36:09 peter
  410. + KNI instructions
  411. }