mkx86ins.pp 12 KB

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