mkx86ins.pp 12 KB

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