mkx86ins.pp 14 KB

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