mkx86ins.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. {
  2. Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
  3. Convert i386ins.dat from Nasm to a .inc file for usage with
  4. the Free pascal compiler
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. program mkx86ins;
  12. const
  13. Version = '1.5.0';
  14. var
  15. s : string;
  16. i : longint;
  17. x86_64 : boolean;
  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 x86ins.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,
  178. nopfile,attfile,intfile,
  179. infile,insfile : text;
  180. { instruction fields }
  181. skip : boolean;
  182. last,
  183. ops : longint;
  184. intopcode,
  185. attopcode,
  186. opcode,
  187. codes,
  188. flags : string;
  189. optypes : array[1..3] of string;
  190. begin
  191. writeln('Nasm Instruction Table Converter Version ',Version);
  192. x86_64:=paramstr(1)='x86_64';
  193. insns:=0;
  194. maxinfolen:=0;
  195. { open dat file }
  196. assign(infile,'../x86/x86ins.dat');
  197. if x86_64 then
  198. begin
  199. { create inc files }
  200. openinc(insfile,'x8664tab.inc');
  201. openinc(opfile,'x8664op.inc');
  202. assign(nopfile,'x8664nop.inc');
  203. openinc(attfile,'x8664att.inc');
  204. openinc(attsuffile,'x8664ats.inc');
  205. openinc(intfile,'x8664int.inc');
  206. openinc(propfile,'x8664pro.inc');
  207. end
  208. else
  209. begin
  210. { create inc files }
  211. openinc(insfile,'i386tab.inc');
  212. openinc(opfile,'i386op.inc');
  213. assign(nopfile,'i386nop.inc');
  214. openinc(attfile,'i386att.inc');
  215. openinc(attsuffile,'i386atts.inc');
  216. openinc(intfile,'i386int.inc');
  217. openinc(propfile,'i386prop.inc');
  218. end;
  219. rewrite(nopfile);
  220. writeln(nopfile,'{ don''t edit, this file is generated from x86ins.dat }');
  221. reset(infile);
  222. first:=true;
  223. opcode:='';
  224. firstopcode:=true;
  225. while not(eof(infile)) do
  226. begin
  227. { handle comment }
  228. readln(infile,s);
  229. while (s[1]=' ') do
  230. delete(s,1,1);
  231. if (s='') or (s[1]=';') then
  232. continue;
  233. if (s[1]='[') then
  234. begin
  235. i:=pos(',',s);
  236. j:=pos(']',s);
  237. if i=0 then
  238. begin
  239. opcode:='A_'+Copy(s,2,j-2);
  240. intopcode:=Copy(s,2,j-2);
  241. { Conditional }
  242. if (intopcode[length(intopcode)]='c') and
  243. (intopcode[length(intopcode)-1]='c') then
  244. dec(byte(intopcode[0]),2);
  245. attopcode:=intopcode;
  246. attsuffix:='attsufNONE';
  247. end
  248. else
  249. begin
  250. opcode:='A_'+Copy(s,2,i-2);
  251. intopcode:=Copy(s,2,i-2);
  252. { intel conditional }
  253. if (intopcode[length(intopcode)]='c') and
  254. (intopcode[length(intopcode)-1]='c') then
  255. dec(byte(intopcode[0]),2);
  256. attopcode:=Copy(s,i+1,j-i-1);
  257. { att Suffix }
  258. case attopcode[length(attopcode)] of
  259. 'X' :
  260. begin
  261. dec(attopcode[0]);
  262. attsuffix:='attsufINT';
  263. end;
  264. 'F' :
  265. begin
  266. dec(attopcode[0]);
  267. attsuffix:='attsufFPU';
  268. end;
  269. 'R' :
  270. begin
  271. dec(attopcode[0]);
  272. attsuffix:='attsufFPUint';
  273. end;
  274. else
  275. attsuffix:='attsufNONE';
  276. end;
  277. { att Conditional }
  278. if (attopcode[length(attopcode)]='C') and
  279. (attopcode[length(attopcode)-1]='C') then
  280. dec(byte(attopcode[0]),2);
  281. end;
  282. intopcode:=Lower(intopcode);
  283. attopcode:=Lower(attopcode);
  284. if firstopcode then
  285. firstopcode:=false
  286. else
  287. begin
  288. writeln(opfile,',');
  289. writeln(attfile,',');
  290. writeln(attsuffile,',');
  291. writeln(intfile,',');
  292. writeln(propfile,',');
  293. end;
  294. write(opfile,opcode);
  295. write(intfile,'''',intopcode,'''');
  296. write(attfile,'''',attopcode,'''');
  297. write(attsuffile,attsuffix);
  298. { read the next line which contains the Change options }
  299. repeat
  300. readln(infile,s);
  301. until eof(infile) or ((s<>'') and (s[1]<>';'));
  302. write(propfile,'(Ch: ',s,')');
  303. continue;
  304. end;
  305. { we must have an opcode }
  306. if opcode='' then
  307. runerror(234);
  308. { clear }
  309. ops:=0;
  310. optypes[1]:='';
  311. optypes[2]:='';
  312. optypes[3]:='';
  313. codes:='';
  314. flags:='';
  315. skip:=false;
  316. { ops and optypes }
  317. i:=1;
  318. repeat
  319. hs:=readstr;
  320. if (hs='void') or (hs='ignore') then
  321. break;
  322. inc(ops);
  323. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
  324. { if s[i]=':' then
  325. begin
  326. inc(i);
  327. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  328. end;}
  329. while s[i]='|' do
  330. begin
  331. inc(i);
  332. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  333. end;
  334. if s[i] in [',',':'] then
  335. inc(i)
  336. else
  337. break;
  338. until false;
  339. for j:=1 to 3-ops do
  340. optypes[3-j+1]:='ot_none';
  341. { codes }
  342. skipspace;
  343. j:=0;
  344. last:=0;
  345. if s[i] in ['\','0'..'9'] then
  346. begin
  347. while not(s[i] in [' ',#9]) do
  348. begin
  349. code:=readnumber;
  350. { for some codes we want also to change the optypes, but not
  351. if the last byte was a 1 then this byte belongs to a direct
  352. copy }
  353. if last<>1 then
  354. begin
  355. case code of
  356. 12,13,14 :
  357. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  358. end;
  359. end;
  360. codes:=codes+'#'+tostr(code);
  361. last:=code;
  362. inc(j);
  363. end;
  364. end
  365. else
  366. begin
  367. readstr;
  368. codes:='#0';
  369. end;
  370. if j>maxinfolen then
  371. maxinfolen:=j;
  372. { flags }
  373. skipspace;
  374. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  375. begin
  376. hs:=readstr;
  377. if x86_64 then
  378. begin
  379. if (upcase(hs)='NOX86_64') then
  380. skip:=true;
  381. end
  382. else
  383. begin
  384. if (upcase(hs)='X86_64') then
  385. skip:=true;
  386. end;
  387. if hs<>'ND' then
  388. begin
  389. if flags<>'' then
  390. flags:=flags+' or ';
  391. flags:=flags+'if_'+lower(hs);
  392. end;
  393. if (s[i]=',') and (i<=length(s)) then
  394. inc(i)
  395. else
  396. break;
  397. end;
  398. { write instruction }
  399. if not skip then
  400. begin
  401. if not(first) then
  402. writeln(insfile,',')
  403. else
  404. first:=false;
  405. writeln(insfile,' (');
  406. writeln(insfile,' opcode : ',opcode,';');
  407. writeln(insfile,' ops : ',ops,';');
  408. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],');');
  409. writeln(insfile,' code : ',codes,';');
  410. writeln(insfile,' flags : ',flags);
  411. write(insfile,' )');
  412. inc(insns);
  413. end;
  414. end;
  415. close(infile);
  416. closeinc(insfile);
  417. closeinc(intfile);
  418. closeinc(attfile);
  419. closeinc(attsuffile);
  420. closeinc(opfile);
  421. writeln(nopfile,insns,';');
  422. close(nopfile);
  423. closeinc(propfile);
  424. writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
  425. end.