mkx86ins.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  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','regmem'),
  53. ('rm8','regmem or ot_bits8'),
  54. ('rm16','regmem or ot_bits16'),
  55. ('rm32','regmem or ot_bits32'),
  56. ('rm64','regmem or ot_bits64'),
  57. ('rm80','regmem 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. last,
  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. 'F' :
  256. begin
  257. dec(attopcode[0]);
  258. attsuffix:='attsufFPU';
  259. end;
  260. 'R' :
  261. begin
  262. dec(attopcode[0]);
  263. attsuffix:='attsufFPUint';
  264. end;
  265. else
  266. attsuffix:='attsufNONE';
  267. end;
  268. { att Conditional }
  269. if (attopcode[length(attopcode)]='C') and
  270. (attopcode[length(attopcode)-1]='C') then
  271. dec(byte(attopcode[0]),2);
  272. end;
  273. intopcode:=Lower(intopcode);
  274. attopcode:=Lower(attopcode);
  275. if firstopcode then
  276. firstopcode:=false
  277. else
  278. begin
  279. writeln(opfile,',');
  280. writeln(attfile,',');
  281. writeln(attsuffile,',');
  282. writeln(intfile,',');
  283. writeln(propfile,',');
  284. end;
  285. write(opfile,opcode);
  286. write(intfile,'''',intopcode,'''');
  287. write(attfile,'''',attopcode,'''');
  288. write(attsuffile,attsuffix);
  289. { read the next line which contains the Change options }
  290. repeat
  291. readln(infile,s);
  292. until eof(infile) or ((s<>'') and (s[1]<>';'));
  293. write(propfile,'(Ch: ',s,')');
  294. continue;
  295. end;
  296. { we must have an opcode }
  297. if opcode='' then
  298. runerror(234);
  299. { clear }
  300. ops:=0;
  301. optypes[1]:='';
  302. optypes[2]:='';
  303. optypes[3]:='';
  304. codes:='';
  305. flags:='';
  306. skip:=false;
  307. { ops and optypes }
  308. i:=1;
  309. repeat
  310. hs:=readstr;
  311. if (hs='void') or (hs='ignore') then
  312. break;
  313. inc(ops);
  314. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs,false);
  315. while s[i]='|' do
  316. begin
  317. inc(i);
  318. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr,true);
  319. end;
  320. if s[i] in [',',':'] then
  321. inc(i)
  322. else
  323. break;
  324. until false;
  325. for j:=1 to 3-ops do
  326. optypes[3-j+1]:='ot_none';
  327. { codes }
  328. skipspace;
  329. j:=0;
  330. last:=0;
  331. if s[i] in ['\','0'..'9'] then
  332. begin
  333. while not(s[i] in [' ',#9]) do
  334. begin
  335. code:=readnumber;
  336. { for some codes we want also to change the optypes, but not
  337. if the last byte was a 1 then this byte belongs to a direct
  338. copy }
  339. if last<>1 then
  340. begin
  341. case code of
  342. 12,13,14 :
  343. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  344. end;
  345. end;
  346. codes:=codes+'#'+tostr(code);
  347. last:=code;
  348. inc(j);
  349. end;
  350. end
  351. else
  352. begin
  353. readstr;
  354. codes:='#0';
  355. end;
  356. if j>maxinfolen then
  357. maxinfolen:=j;
  358. { flags }
  359. skipspace;
  360. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  361. begin
  362. hs:=readstr;
  363. if x86_64 then
  364. begin
  365. if (upcase(hs)='NOX86_64') then
  366. skip:=true;
  367. end
  368. else
  369. begin
  370. if (upcase(hs)='X86_64') then
  371. skip:=true;
  372. end;
  373. if hs<>'ND' then
  374. begin
  375. if flags<>'' then
  376. flags:=flags+' or ';
  377. flags:=flags+'if_'+lower(hs);
  378. end;
  379. if (s[i]=',') and (i<=length(s)) then
  380. inc(i)
  381. else
  382. break;
  383. end;
  384. { write instruction }
  385. if not skip then
  386. begin
  387. if not(first) then
  388. writeln(insfile,',')
  389. else
  390. first:=false;
  391. writeln(insfile,' (');
  392. writeln(insfile,' opcode : ',opcode,';');
  393. writeln(insfile,' ops : ',ops,';');
  394. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],');');
  395. writeln(insfile,' code : ',codes,';');
  396. writeln(insfile,' flags : ',flags);
  397. write(insfile,' )');
  398. inc(insns);
  399. end;
  400. end;
  401. close(infile);
  402. closeinc(insfile);
  403. closeinc(intfile);
  404. closeinc(attfile);
  405. closeinc(attsuffile);
  406. closeinc(opfile);
  407. writeln(nopfile,insns,';');
  408. close(nopfile);
  409. closeinc(propfile);
  410. writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
  411. end.