mkx86ins.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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.6.0';
  14. max_operands = 4;
  15. var
  16. s : string;
  17. i : longint;
  18. x86_64 : boolean;
  19. function lower(const s : string) : string;
  20. {
  21. return lowercased string of s
  22. }
  23. var
  24. i : longint;
  25. begin
  26. for i:=1 to length(s) do
  27. if s[i] in ['A'..'Z'] then
  28. lower[i]:=char(byte(s[i])+32)
  29. else
  30. lower[i]:=s[i];
  31. lower[0]:=s[0];
  32. end;
  33. function Replace(var s:string;const s1,s2:string):boolean;
  34. var
  35. i : longint;
  36. begin
  37. i:=pos(s1,s);
  38. if i>0 then
  39. begin
  40. Delete(s,i,length(s1));
  41. Insert(s2,s,i);
  42. Replace:=true;
  43. end
  44. else
  45. Replace:=false;
  46. end;
  47. function formatop(s:string;allowsizeonly:boolean):string;
  48. const
  49. replaces=26;
  50. replacetab : array[1..replaces,1..2] of string[32]=(
  51. (':',' or ot_colon'),
  52. ('reg','regnorm'),
  53. ('regmem','rm_gpr'),
  54. ('rm8','rm_gpr or ot_bits8'),
  55. ('rm16','rm_gpr or ot_bits16'),
  56. ('rm32','rm_gpr or ot_bits32'),
  57. ('rm64','rm_gpr or ot_bits64'),
  58. ('rm80','rm_gpr or ot_bits80'),
  59. ('mem8','memory or ot_bits8'),
  60. ('mem16','memory or ot_bits16'),
  61. ('mem32','memory or ot_bits32'),
  62. ('mem64','memory or ot_bits64'),
  63. ('mem80','memory or ot_bits80'),
  64. ('mem','memory'),
  65. ('memory_offs','mem_offs'),
  66. ('imm8','immediate or ot_bits8'),
  67. ('imm16','immediate or ot_bits16'),
  68. ('imm32','immediate or ot_bits32'),
  69. ('imm64','immediate or ot_bits64'),
  70. ('imm80','immediate or ot_bits80'),
  71. ('imm','immediate'),
  72. ('8','bits8'),
  73. ('16','bits16'),
  74. ('32','bits32'),
  75. ('64','bits64'),
  76. ('80','bits80')
  77. );
  78. var
  79. i : longint;
  80. begin
  81. for i:=1to replaces do
  82. begin
  83. if s=replacetab[i,1] then
  84. begin
  85. s:=replacetab[i,2];
  86. break;
  87. end;
  88. end;
  89. formatop:=s;
  90. end;
  91. function readnumber : longint;
  92. var
  93. base : longint;
  94. result : 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. readnumber:=result;
  121. end;
  122. function tostr(l : longint) : string;
  123. var
  124. hs : string;
  125. begin
  126. str(l,hs);
  127. tostr:=hs;
  128. end;
  129. function readstr : string;
  130. var
  131. result : 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. readstr:=result;
  140. end;
  141. procedure skipspace;
  142. begin
  143. while (s[i] in [' ',#9]) do
  144. inc(i);
  145. end;
  146. procedure openinc(var f:text;const fn:string);
  147. begin
  148. writeln('creating ',fn);
  149. assign(f,fn);
  150. rewrite(f);
  151. writeln(f,'{ don''t edit, this file is generated from x86ins.dat }');
  152. writeln(f,'(');
  153. end;
  154. procedure closeinc(var f:text);
  155. begin
  156. writeln(f);
  157. writeln(f,');');
  158. close(f);
  159. end;
  160. var
  161. attsuffix,
  162. hs : string;
  163. j : longint;
  164. firstopcode,
  165. first : boolean;
  166. maxinfolen,
  167. code : byte;
  168. insns : longint;
  169. attsuffile,propfile,opfile,
  170. nopfile,attfile,intfile,
  171. infile,insfile : text;
  172. { instruction fields }
  173. skip : boolean;
  174. literalcount,
  175. ops : longint;
  176. intopcode,
  177. attopcode,
  178. opcode,
  179. codes,
  180. flags : string;
  181. optypes : array[1..max_operands] of string;
  182. begin
  183. writeln('Nasm Instruction Table Converter Version ',Version);
  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
  201. begin
  202. { create inc files }
  203. openinc(insfile,'i386tab.inc');
  204. openinc(opfile,'i386op.inc');
  205. assign(nopfile,'i386nop.inc');
  206. openinc(attfile,'i386att.inc');
  207. openinc(attsuffile,'i386atts.inc');
  208. openinc(intfile,'i386int.inc');
  209. openinc(propfile,'i386prop.inc');
  210. end;
  211. rewrite(nopfile);
  212. writeln(nopfile,'{ don''t edit, this file is generated from x86ins.dat }');
  213. reset(infile);
  214. first:=true;
  215. opcode:='';
  216. firstopcode:=true;
  217. while not(eof(infile)) do
  218. begin
  219. { handle comment }
  220. readln(infile,s);
  221. while (s[1]=' ') do
  222. delete(s,1,1);
  223. if (s='') or (s[1]=';') then
  224. continue;
  225. if (s[1]='[') then
  226. begin
  227. i:=pos(',',s);
  228. j:=pos(']',s);
  229. if i=0 then
  230. begin
  231. opcode:='A_'+Copy(s,2,j-2);
  232. intopcode:=Copy(s,2,j-2);
  233. { Conditional }
  234. if (intopcode[length(intopcode)]='c') and
  235. (intopcode[length(intopcode)-1]='c') then
  236. dec(byte(intopcode[0]),2);
  237. attopcode:=intopcode;
  238. attsuffix:='attsufNONE';
  239. end
  240. else
  241. begin
  242. opcode:='A_'+Copy(s,2,i-2);
  243. intopcode:=Copy(s,2,i-2);
  244. { intel conditional }
  245. if (intopcode[length(intopcode)]='c') and
  246. (intopcode[length(intopcode)-1]='c') then
  247. dec(byte(intopcode[0]),2);
  248. attopcode:=Copy(s,i+1,j-i-1);
  249. { att Suffix }
  250. case attopcode[length(attopcode)] of
  251. 'X' :
  252. begin
  253. dec(attopcode[0]);
  254. attsuffix:='attsufINT';
  255. end;
  256. 'Y' :
  257. begin
  258. dec(attopcode[0]);
  259. attsuffix:='attsufINTdual';
  260. end;
  261. 'F' :
  262. begin
  263. dec(attopcode[0]);
  264. attsuffix:='attsufFPU';
  265. end;
  266. 'R' :
  267. begin
  268. dec(attopcode[0]);
  269. attsuffix:='attsufFPUint';
  270. end;
  271. else
  272. attsuffix:='attsufNONE';
  273. end;
  274. { att Conditional }
  275. if (attopcode[length(attopcode)]='C') and
  276. (attopcode[length(attopcode)-1]='C') then
  277. dec(byte(attopcode[0]),2);
  278. end;
  279. intopcode:=Lower(intopcode);
  280. attopcode:=Lower(attopcode);
  281. if firstopcode then
  282. firstopcode:=false
  283. else
  284. begin
  285. writeln(opfile,',');
  286. writeln(attfile,',');
  287. writeln(attsuffile,',');
  288. writeln(intfile,',');
  289. writeln(propfile,',');
  290. end;
  291. write(opfile,opcode);
  292. write(intfile,'''',intopcode,'''');
  293. write(attfile,'''',attopcode,'''');
  294. write(attsuffile,attsuffix);
  295. { read the next line which contains the Change options }
  296. repeat
  297. readln(infile,s);
  298. until eof(infile) or ((s<>'') and (s[1]<>';'));
  299. write(propfile,'(Ch: ',s,')');
  300. continue;
  301. end;
  302. { we must have an opcode }
  303. if opcode='' then
  304. runerror(234);
  305. { clear }
  306. ops:=0;
  307. for i:=low(optypes) to high(optypes) do
  308. optypes[i]:='';
  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 max_operands-ops do
  331. optypes[max_operands-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],',',optypes[4],');');
  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.