mkx86ins.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  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. {$mode objfpc}
  12. program mkx86ins;
  13. const
  14. Version = '1.6.0';
  15. max_operands = 4;
  16. var
  17. s : string;
  18. i : longint;
  19. i8086 : boolean;
  20. x86_64 : boolean;
  21. function lower(const s : string) : string;
  22. {
  23. return lowercased string of s
  24. }
  25. var
  26. i : longint;
  27. begin
  28. for i:=1 to length(s) do
  29. if s[i] in ['A'..'Z'] then
  30. lower[i]:=char(byte(s[i])+32)
  31. else
  32. lower[i]:=s[i];
  33. lower[0]:=s[0];
  34. end;
  35. function Replace(var s:string;const s1,s2:string):boolean;
  36. var
  37. i : longint;
  38. begin
  39. i:=pos(s1,s);
  40. if i>0 then
  41. begin
  42. Delete(s,i,length(s1));
  43. Insert(s2,s,i);
  44. Replace:=true;
  45. end
  46. else
  47. Replace:=false;
  48. end;
  49. function formatop(s:string;allowsizeonly:boolean):string;
  50. const
  51. replaces=28;
  52. replacetab : array[1..replaces,1..2] of string[32]=(
  53. (':',' or ot_colon'),
  54. ('reg','regnorm'),
  55. ('regmem','rm_gpr'),
  56. ('rm8','rm_gpr or ot_bits8'),
  57. ('rm16','rm_gpr or ot_bits16'),
  58. ('rm32','rm_gpr or ot_bits32'),
  59. ('rm64','rm_gpr or ot_bits64'),
  60. ('rm80','rm_gpr or ot_bits80'),
  61. ('mem8','memory or ot_bits8'),
  62. ('mem16','memory or ot_bits16'),
  63. ('mem32','memory or ot_bits32'),
  64. ('mem64','memory or ot_bits64'),
  65. ('mem128','memory or ot_bits128'),
  66. ('mem256','memory or ot_bits256'),
  67. ('mem80','memory or ot_bits80'),
  68. ('mem','memory'),
  69. ('memory_offs','mem_offs'),
  70. ('imm8','immediate or ot_bits8'),
  71. ('imm16','immediate or ot_bits16'),
  72. ('imm32','immediate or ot_bits32'),
  73. ('imm64','immediate or ot_bits64'),
  74. ('imm80','immediate or ot_bits80'),
  75. ('imm','immediate'),
  76. ('8','bits8'),
  77. ('16','bits16'),
  78. ('32','bits32'),
  79. ('64','bits64'),
  80. ('80','bits80')
  81. );
  82. var
  83. i : longint;
  84. begin
  85. for i:=1to replaces do
  86. begin
  87. if s=replacetab[i,1] then
  88. begin
  89. s:=replacetab[i,2];
  90. break;
  91. end;
  92. end;
  93. formatop:=s;
  94. end;
  95. function readnumber : longint;
  96. var
  97. base : longint;
  98. begin
  99. result:=0;
  100. if s[i]='\' then
  101. begin
  102. base:=8;
  103. inc(i);
  104. if s[i]='x' then
  105. begin
  106. base:=16;
  107. inc(i);
  108. end;
  109. end
  110. else
  111. base:=10;
  112. s[i]:=upcase(s[i]);
  113. while s[i] in ['0'..'9','A'..'F'] do
  114. begin
  115. case s[i] of
  116. '0'..'9':
  117. result:=result*base+ord(s[i])-ord('0');
  118. 'A'..'F':
  119. result:=result*base+ord(s[i])-ord('A')+10;
  120. end;
  121. inc(i);
  122. end;
  123. end;
  124. function tostr(l : longint) : string;
  125. var
  126. hs : string;
  127. begin
  128. str(l,hs);
  129. tostr:=hs;
  130. end;
  131. function readstr : string;
  132. begin
  133. result:='';
  134. while (s[i] in ['0'..'9','A'..'Z','a'..'z','_']) and (i<=length(s)) do
  135. begin
  136. result:=result+s[i];
  137. inc(i);
  138. end;
  139. end;
  140. procedure skipspace;
  141. begin
  142. while (s[i] in [' ',#9]) do
  143. inc(i);
  144. end;
  145. procedure openinc(out f:text;const fn:string);
  146. begin
  147. writeln('creating ',fn);
  148. assign(f,fn);
  149. rewrite(f);
  150. writeln(f,'{ don''t edit, this file is generated from x86ins.dat }');
  151. writeln(f,'(');
  152. end;
  153. procedure closeinc(var f:text);
  154. begin
  155. writeln(f);
  156. writeln(f,');');
  157. close(f);
  158. end;
  159. var
  160. attsuffix,
  161. hs : string;
  162. j : longint;
  163. firstopcode,
  164. first : boolean;
  165. maxinfolen,
  166. code : byte;
  167. insns : longint;
  168. attsuffile,propfile,opfile,
  169. nopfile,attfile,intfile,
  170. infile,insfile : text;
  171. { instruction fields }
  172. skip : boolean;
  173. literalcount,
  174. ops : longint;
  175. intopcode,
  176. attopcode,
  177. opcode,
  178. codes,
  179. flags : string;
  180. optypes : array[1..max_operands] of string;
  181. begin
  182. writeln('Nasm Instruction Table Converter Version ',Version);
  183. i8086:=paramstr(1)='i8086';
  184. x86_64:=paramstr(1)='x86_64';
  185. insns:=0;
  186. maxinfolen:=0;
  187. { open dat file }
  188. assign(infile,'../x86/x86ins.dat');
  189. if x86_64 then
  190. begin
  191. { create inc files }
  192. openinc(insfile,'x8664tab.inc');
  193. openinc(opfile,'x8664op.inc');
  194. assign(nopfile,'x8664nop.inc');
  195. openinc(attfile,'x8664att.inc');
  196. openinc(attsuffile,'x8664ats.inc');
  197. openinc(intfile,'x8664int.inc');
  198. openinc(propfile,'x8664pro.inc');
  199. end
  200. else if i8086 then
  201. begin
  202. { create inc files }
  203. openinc(insfile,'i8086tab.inc');
  204. openinc(opfile,'i8086op.inc');
  205. assign(nopfile,'i8086nop.inc');
  206. openinc(attfile,'i8086att.inc');
  207. openinc(attsuffile,'i8086atts.inc');
  208. openinc(intfile,'i8086int.inc');
  209. openinc(propfile,'i8086prop.inc');
  210. end
  211. else
  212. begin
  213. { create inc files }
  214. openinc(insfile,'i386tab.inc');
  215. openinc(opfile,'i386op.inc');
  216. assign(nopfile,'i386nop.inc');
  217. openinc(attfile,'i386att.inc');
  218. openinc(attsuffile,'i386atts.inc');
  219. openinc(intfile,'i386int.inc');
  220. openinc(propfile,'i386prop.inc');
  221. end;
  222. rewrite(nopfile);
  223. writeln(nopfile,'{ don''t edit, this file is generated from x86ins.dat }');
  224. reset(infile);
  225. first:=true;
  226. opcode:='';
  227. firstopcode:=true;
  228. while not(eof(infile)) do
  229. begin
  230. { handle comment }
  231. readln(infile,s);
  232. while (s[1]=' ') do
  233. delete(s,1,1);
  234. if (s='') or (s[1]=';') then
  235. continue;
  236. if (s[1]='[') then
  237. begin
  238. i:=pos(',',s);
  239. j:=pos(']',s);
  240. if i=0 then
  241. begin
  242. opcode:='A_'+Copy(s,2,j-2);
  243. intopcode:=Copy(s,2,j-2);
  244. { Conditional }
  245. if (intopcode[length(intopcode)]='c') and
  246. (intopcode[length(intopcode)-1]='c') then
  247. dec(byte(intopcode[0]),2);
  248. attopcode:=intopcode;
  249. attsuffix:='attsufNONE';
  250. end
  251. else
  252. begin
  253. opcode:='A_'+Copy(s,2,i-2);
  254. intopcode:=Copy(s,2,i-2);
  255. { intel conditional }
  256. if (intopcode[length(intopcode)]='c') and
  257. (intopcode[length(intopcode)-1]='c') then
  258. dec(byte(intopcode[0]),2);
  259. attopcode:=Copy(s,i+1,j-i-1);
  260. { att Suffix }
  261. case attopcode[length(attopcode)] of
  262. 'M' :
  263. begin
  264. dec(attopcode[0]);
  265. attsuffix:='attsufMM';
  266. end;
  267. 'X' :
  268. begin
  269. dec(attopcode[0]);
  270. attsuffix:='attsufINT';
  271. end;
  272. 'Y' :
  273. begin
  274. dec(attopcode[0]);
  275. attsuffix:='attsufINTdual';
  276. end;
  277. 'F' :
  278. begin
  279. dec(attopcode[0]);
  280. attsuffix:='attsufFPU';
  281. end;
  282. 'R' :
  283. begin
  284. dec(attopcode[0]);
  285. attsuffix:='attsufFPUint';
  286. end;
  287. else
  288. attsuffix:='attsufNONE';
  289. end;
  290. { att Conditional }
  291. if (attopcode[length(attopcode)]='C') and
  292. (attopcode[length(attopcode)-1]='C') then
  293. dec(byte(attopcode[0]),2);
  294. end;
  295. intopcode:=Lower(intopcode);
  296. attopcode:=Lower(attopcode);
  297. if firstopcode then
  298. firstopcode:=false
  299. else
  300. begin
  301. writeln(opfile,',');
  302. writeln(attfile,',');
  303. writeln(attsuffile,',');
  304. writeln(intfile,',');
  305. writeln(propfile,',');
  306. end;
  307. write(opfile,opcode);
  308. write(intfile,'''',intopcode,'''');
  309. write(attfile,'''',attopcode,'''');
  310. write(attsuffile,attsuffix);
  311. { read the next line which contains the Change options }
  312. repeat
  313. readln(infile,s);
  314. until eof(infile) or ((s<>'') and (s[1]<>';'));
  315. write(propfile,'(Ch: ',s,')');
  316. continue;
  317. end;
  318. { we must have an opcode }
  319. if opcode='' then
  320. runerror(234);
  321. { clear }
  322. ops:=0;
  323. for i:=low(optypes) to high(optypes) do
  324. optypes[i]:='';
  325. codes:='';
  326. flags:='';
  327. skip:=false;
  328. { ops and optypes }
  329. i:=1;
  330. repeat
  331. hs:=readstr;
  332. if (hs='void') or (hs='ignore') then
  333. break;
  334. inc(ops);
  335. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs,false);
  336. while s[i]='|' do
  337. begin
  338. inc(i);
  339. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr,true);
  340. end;
  341. if s[i] in [',',':'] then
  342. inc(i)
  343. else
  344. break;
  345. until false;
  346. for j:=1 to max_operands-ops do
  347. optypes[max_operands-j+1]:='ot_none';
  348. { codes }
  349. skipspace;
  350. j:=0;
  351. literalcount:=0;
  352. if s[i] in ['\','0'..'9'] then
  353. begin
  354. while not(s[i] in [' ',#9]) do
  355. begin
  356. code:=readnumber;
  357. { for some codes we want also to change the optypes, but not
  358. if the code belongs to a literal sequence }
  359. if (literalcount=0) and (code>=1) and (code<=3) then
  360. literalcount:=code
  361. else
  362. begin
  363. if literalcount>0 then
  364. dec(literalcount)
  365. else
  366. begin
  367. case code of
  368. 12,13,14 :
  369. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  370. end;
  371. end;
  372. end;
  373. codes:=codes+'#'+tostr(code);
  374. inc(j);
  375. end;
  376. end
  377. else
  378. begin
  379. readstr;
  380. codes:='#0';
  381. end;
  382. if j>maxinfolen then
  383. maxinfolen:=j;
  384. { flags }
  385. skipspace;
  386. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  387. begin
  388. hs:=readstr;
  389. if x86_64 then
  390. begin
  391. if (upcase(hs)='NOX86_64') then
  392. skip:=true;
  393. end
  394. else
  395. begin
  396. if (upcase(hs)='X86_64') then
  397. skip:=true;
  398. end;
  399. if hs<>'ND' then
  400. begin
  401. if flags<>'' then
  402. flags:=flags+' or ';
  403. flags:=flags+'if_'+lower(hs);
  404. end;
  405. if (s[i]=',') and (i<=length(s)) then
  406. inc(i)
  407. else
  408. break;
  409. end;
  410. { write instruction }
  411. if not skip then
  412. begin
  413. if not(first) then
  414. writeln(insfile,',')
  415. else
  416. first:=false;
  417. writeln(insfile,' (');
  418. writeln(insfile,' opcode : ',opcode,';');
  419. writeln(insfile,' ops : ',ops,';');
  420. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
  421. writeln(insfile,' code : ',codes,';');
  422. writeln(insfile,' flags : ',flags);
  423. write(insfile,' )');
  424. inc(insns);
  425. end;
  426. end;
  427. close(infile);
  428. closeinc(insfile);
  429. closeinc(intfile);
  430. closeinc(attfile);
  431. closeinc(attsuffile);
  432. closeinc(opfile);
  433. writeln(nopfile,insns,';');
  434. close(nopfile);
  435. closeinc(propfile);
  436. writeln(insns,' nodes processed (maxinfolen=',maxinfolen,')');
  437. end.