mkx86ins.pp 14 KB

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