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. {$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=28;
  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. ('mem128','memory or ot_bits128'),
  65. ('mem256','memory or ot_bits256'),
  66. ('mem80','memory or ot_bits80'),
  67. ('mem','memory'),
  68. ('memory_offs','mem_offs'),
  69. ('imm8','immediate or ot_bits8'),
  70. ('imm16','immediate or ot_bits16'),
  71. ('imm32','immediate or ot_bits32'),
  72. ('imm64','immediate or ot_bits64'),
  73. ('imm80','immediate or ot_bits80'),
  74. ('imm','immediate'),
  75. ('8','bits8'),
  76. ('16','bits16'),
  77. ('32','bits32'),
  78. ('64','bits64'),
  79. ('80','bits80')
  80. );
  81. var
  82. i : longint;
  83. begin
  84. for i:=1to replaces do
  85. begin
  86. if s=replacetab[i,1] then
  87. begin
  88. s:=replacetab[i,2];
  89. break;
  90. end;
  91. end;
  92. formatop:=s;
  93. end;
  94. function readnumber : longint;
  95. var
  96. base : longint;
  97. begin
  98. result:=0;
  99. if s[i]='\' then
  100. begin
  101. base:=8;
  102. inc(i);
  103. if s[i]='x' then
  104. begin
  105. base:=16;
  106. inc(i);
  107. end;
  108. end
  109. else
  110. base:=10;
  111. s[i]:=upcase(s[i]);
  112. while s[i] in ['0'..'9','A'..'F'] do
  113. begin
  114. case s[i] of
  115. '0'..'9':
  116. result:=result*base+ord(s[i])-ord('0');
  117. 'A'..'F':
  118. result:=result*base+ord(s[i])-ord('A')+10;
  119. end;
  120. inc(i);
  121. end;
  122. end;
  123. function tostr(l : longint) : string;
  124. var
  125. hs : string;
  126. begin
  127. str(l,hs);
  128. tostr:=hs;
  129. end;
  130. function readstr : 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. end;
  139. procedure skipspace;
  140. begin
  141. while (s[i] in [' ',#9]) do
  142. inc(i);
  143. end;
  144. procedure openinc(out f:text;const fn:string);
  145. begin
  146. writeln('creating ',fn);
  147. assign(f,fn);
  148. rewrite(f);
  149. writeln(f,'{ don''t edit, this file is generated from x86ins.dat }');
  150. writeln(f,'(');
  151. end;
  152. procedure closeinc(var f:text);
  153. begin
  154. writeln(f);
  155. writeln(f,');');
  156. close(f);
  157. end;
  158. var
  159. attsuffix,
  160. hs : string;
  161. j : longint;
  162. firstopcode,
  163. first : boolean;
  164. maxinfolen,
  165. code : byte;
  166. insns : longint;
  167. attsuffile,propfile,opfile,
  168. nopfile,attfile,intfile,
  169. infile,insfile : text;
  170. { instruction fields }
  171. skip : boolean;
  172. literalcount,
  173. ops : longint;
  174. intopcode,
  175. attopcode,
  176. opcode,
  177. codes,
  178. flags : string;
  179. optypes : array[1..max_operands] of string;
  180. begin
  181. writeln('Nasm Instruction Table Converter Version ',Version);
  182. x86_64:=paramstr(1)='x86_64';
  183. insns:=0;
  184. maxinfolen:=0;
  185. { open dat file }
  186. assign(infile,'../x86/x86ins.dat');
  187. if x86_64 then
  188. begin
  189. { create inc files }
  190. openinc(insfile,'x8664tab.inc');
  191. openinc(opfile,'x8664op.inc');
  192. assign(nopfile,'x8664nop.inc');
  193. openinc(attfile,'x8664att.inc');
  194. openinc(attsuffile,'x8664ats.inc');
  195. openinc(intfile,'x8664int.inc');
  196. openinc(propfile,'x8664pro.inc');
  197. end
  198. else
  199. begin
  200. { create inc files }
  201. openinc(insfile,'i386tab.inc');
  202. openinc(opfile,'i386op.inc');
  203. assign(nopfile,'i386nop.inc');
  204. openinc(attfile,'i386att.inc');
  205. openinc(attsuffile,'i386atts.inc');
  206. openinc(intfile,'i386int.inc');
  207. openinc(propfile,'i386prop.inc');
  208. end;
  209. rewrite(nopfile);
  210. writeln(nopfile,'{ don''t edit, this file is generated from x86ins.dat }');
  211. reset(infile);
  212. first:=true;
  213. opcode:='';
  214. firstopcode:=true;
  215. while not(eof(infile)) do
  216. begin
  217. { handle comment }
  218. readln(infile,s);
  219. while (s[1]=' ') do
  220. delete(s,1,1);
  221. if (s='') or (s[1]=';') then
  222. continue;
  223. if (s[1]='[') then
  224. begin
  225. i:=pos(',',s);
  226. j:=pos(']',s);
  227. if i=0 then
  228. begin
  229. opcode:='A_'+Copy(s,2,j-2);
  230. intopcode:=Copy(s,2,j-2);
  231. { Conditional }
  232. if (intopcode[length(intopcode)]='c') and
  233. (intopcode[length(intopcode)-1]='c') then
  234. dec(byte(intopcode[0]),2);
  235. attopcode:=intopcode;
  236. attsuffix:='attsufNONE';
  237. end
  238. else
  239. begin
  240. opcode:='A_'+Copy(s,2,i-2);
  241. intopcode:=Copy(s,2,i-2);
  242. { intel conditional }
  243. if (intopcode[length(intopcode)]='c') and
  244. (intopcode[length(intopcode)-1]='c') then
  245. dec(byte(intopcode[0]),2);
  246. attopcode:=Copy(s,i+1,j-i-1);
  247. { att Suffix }
  248. case attopcode[length(attopcode)] of
  249. 'M' :
  250. begin
  251. dec(attopcode[0]);
  252. attsuffix:='attsufMM';
  253. end;
  254. 'X' :
  255. begin
  256. dec(attopcode[0]);
  257. attsuffix:='attsufINT';
  258. end;
  259. 'Y' :
  260. begin
  261. dec(attopcode[0]);
  262. attsuffix:='attsufINTdual';
  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. for i:=low(optypes) to high(optypes) do
  311. optypes[i]:='';
  312. codes:='';
  313. flags:='';
  314. skip:=false;
  315. { ops and optypes }
  316. i:=1;
  317. repeat
  318. hs:=readstr;
  319. if (hs='void') or (hs='ignore') then
  320. break;
  321. inc(ops);
  322. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs,false);
  323. while s[i]='|' do
  324. begin
  325. inc(i);
  326. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr,true);
  327. end;
  328. if s[i] in [',',':'] then
  329. inc(i)
  330. else
  331. break;
  332. until false;
  333. for j:=1 to max_operands-ops do
  334. optypes[max_operands-j+1]:='ot_none';
  335. { codes }
  336. skipspace;
  337. j:=0;
  338. literalcount:=0;
  339. if s[i] in ['\','0'..'9'] then
  340. begin
  341. while not(s[i] in [' ',#9]) do
  342. begin
  343. code:=readnumber;
  344. { for some codes we want also to change the optypes, but not
  345. if the code belongs to a literal sequence }
  346. if (literalcount=0) and (code>=1) and (code<=3) then
  347. literalcount:=code
  348. else
  349. begin
  350. if literalcount>0 then
  351. dec(literalcount)
  352. else
  353. begin
  354. case code of
  355. 12,13,14 :
  356. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  357. end;
  358. end;
  359. end;
  360. codes:=codes+'#'+tostr(code);
  361. inc(j);
  362. end;
  363. end
  364. else
  365. begin
  366. readstr;
  367. codes:='#0';
  368. end;
  369. if j>maxinfolen then
  370. maxinfolen:=j;
  371. { flags }
  372. skipspace;
  373. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  374. begin
  375. hs:=readstr;
  376. if x86_64 then
  377. begin
  378. if (upcase(hs)='NOX86_64') then
  379. skip:=true;
  380. end
  381. else
  382. begin
  383. if (upcase(hs)='X86_64') then
  384. skip:=true;
  385. end;
  386. if hs<>'ND' then
  387. begin
  388. if flags<>'' then
  389. flags:=flags+' or ';
  390. flags:=flags+'if_'+lower(hs);
  391. end;
  392. if (s[i]=',') and (i<=length(s)) then
  393. inc(i)
  394. else
  395. break;
  396. end;
  397. { write instruction }
  398. if not skip then
  399. begin
  400. if not(first) then
  401. writeln(insfile,',')
  402. else
  403. first:=false;
  404. writeln(insfile,' (');
  405. writeln(insfile,' opcode : ',opcode,';');
  406. writeln(insfile,' ops : ',ops,';');
  407. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
  408. writeln(insfile,' code : ',codes,';');
  409. writeln(insfile,' flags : ',flags);
  410. write(insfile,' )');
  411. inc(insns);
  412. end;
  413. end;
  414. close(infile);
  415. closeinc(insfile);
  416. closeinc(intfile);
  417. closeinc(attfile);
  418. closeinc(attsuffile);
  419. closeinc(opfile);
  420. writeln(nopfile,insns,';');
  421. close(nopfile);
  422. closeinc(propfile);
  423. writeln(insns,' nodes processed (maxinfolen=',maxinfolen,')');
  424. end.