mkx86ins.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  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. continue;
  323. end;
  324. { we must have an opcode }
  325. if opcode='' then
  326. runerror(234);
  327. { clear }
  328. ops:=0;
  329. for i:=low(optypes) to high(optypes) do
  330. optypes[i]:='';
  331. codes:='';
  332. flags:='';
  333. skip:=false;
  334. { ops and optypes }
  335. i:=1;
  336. repeat
  337. hs:=readstr;
  338. if (hs='void') or (hs='ignore') then
  339. break;
  340. inc(ops);
  341. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs,false);
  342. while s[i]='|' do
  343. begin
  344. inc(i);
  345. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr,true);
  346. end;
  347. if s[i] in [',',':'] then
  348. inc(i)
  349. else
  350. break;
  351. until false;
  352. for j:=1 to max_operands-ops do
  353. optypes[max_operands-j+1]:='ot_none';
  354. { codes }
  355. skipspace;
  356. j:=0;
  357. literalcount:=0;
  358. if s[i] in ['\','0'..'9'] then
  359. begin
  360. while not(s[i] in [' ',#9]) do
  361. begin
  362. code:=readnumber;
  363. { for some codes we want also to change the optypes, but not
  364. if the code belongs to a literal sequence }
  365. if (literalcount=0) and (code>=1) and (code<=3) then
  366. literalcount:=code
  367. else
  368. begin
  369. if literalcount>0 then
  370. dec(literalcount)
  371. else
  372. begin
  373. case code of
  374. 12,13,14 :
  375. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  376. end;
  377. end;
  378. end;
  379. codes:=codes+'#'+tostr(code);
  380. inc(j);
  381. end;
  382. end
  383. else
  384. begin
  385. readstr;
  386. codes:='#0';
  387. end;
  388. if j>maxinfolen then
  389. maxinfolen:=j;
  390. { flags }
  391. skipspace;
  392. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  393. begin
  394. hs:=readstr;
  395. if x86_64 then
  396. begin
  397. { x86_64 }
  398. if (upcase(hs)='NOX86_64') or (upcase(hs)='16BITONLY') then
  399. skip:=true;
  400. end
  401. else if not i8086 then
  402. begin
  403. { i386 }
  404. if (upcase(hs)='X86_64') or (upcase(hs)='16BITONLY') then
  405. skip:=true;
  406. end
  407. else
  408. begin
  409. { i8086 }
  410. if (upcase(hs)='X86_64') then
  411. skip:=true;
  412. end;
  413. if hs<>'ND' then
  414. begin
  415. if flags<>'' then
  416. flags:=flags+' or ';
  417. flags:=flags+'if_'+lower(hs);
  418. end;
  419. if (s[i]=',') and (i<=length(s)) then
  420. inc(i)
  421. else
  422. break;
  423. end;
  424. { write instruction }
  425. if not skip then
  426. begin
  427. if not instrwritten then
  428. DoWriteInstr;
  429. instrwritten:=true;
  430. if not(first) then
  431. writeln(insfile,',')
  432. else
  433. first:=false;
  434. writeln(insfile,' (');
  435. writeln(insfile,' opcode : ',opcode,';');
  436. writeln(insfile,' ops : ',ops,';');
  437. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
  438. writeln(insfile,' code : ',codes,';');
  439. writeln(insfile,' flags : ',flags);
  440. write(insfile,' )');
  441. inc(insns);
  442. end;
  443. end;
  444. close(infile);
  445. closeinc(insfile);
  446. closeinc(intfile);
  447. closeinc(attfile);
  448. closeinc(attsuffile);
  449. closeinc(opfile);
  450. writeln(nopfile,insns,';');
  451. close(nopfile);
  452. closeinc(propfile);
  453. writeln(insns,' nodes processed (maxinfolen=',maxinfolen,')');
  454. end.