mkx86ins.pp 13 KB

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