mkx86ins.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
  4. Convert i386ins.dat from Nasm to a .inc file for usage with
  5. the Free pascal compiler
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. program mkx86ins;
  13. const
  14. Version = '1.5.0';
  15. var
  16. s : string;
  17. i : longint;
  18. x86_64 : boolean;
  19. {$ifndef FPC}
  20. procedure readln(var t:text;var s:string);
  21. var
  22. c : char;
  23. i : longint;
  24. begin
  25. c:=#0;
  26. i:=0;
  27. while (not eof(t)) and (c<>#10) do
  28. begin
  29. read(t,c);
  30. if c<>#10 then
  31. begin
  32. inc(i);
  33. s[i]:=c;
  34. end;
  35. end;
  36. if (i>0) and (s[i]=#13) then
  37. dec(i);
  38. s[0]:=chr(i);
  39. end;
  40. {$endif}
  41. function lower(const s : string) : string;
  42. {
  43. return lowercased string of s
  44. }
  45. var
  46. i : longint;
  47. begin
  48. for i:=1 to length(s) do
  49. if s[i] in ['A'..'Z'] then
  50. lower[i]:=char(byte(s[i])+32)
  51. else
  52. lower[i]:=s[i];
  53. lower[0]:=s[0];
  54. end;
  55. function Replace(var s:string;const s1,s2:string):boolean;
  56. var
  57. i : longint;
  58. begin
  59. i:=pos(s1,s);
  60. if i>0 then
  61. begin
  62. Delete(s,i,length(s1));
  63. Insert(s2,s,i);
  64. Replace:=true;
  65. end
  66. else
  67. Replace:=false;
  68. end;
  69. function formatop(s:string):string;
  70. const
  71. replaces=19;
  72. replacetab : array[1..replaces,1..2] of string[32]=(
  73. (':',' or ot_colon'),
  74. ('mem8','mem or ot_bits8'),
  75. ('mem16','mem or ot_bits16'),
  76. ('mem32','mem or ot_bits32'),
  77. ('mem64','mem or ot_bits64'),
  78. ('mem80','mem or ot_bits80'),
  79. ('mem','memory'),
  80. ('memory_offs','mem_offs'),
  81. ('imm8','imm or ot_bits8'),
  82. ('imm16','imm or ot_bits16'),
  83. ('imm32','imm or ot_bits32'),
  84. ('imm64','imm or ot_bits64'),
  85. ('imm80','imm or ot_bits80'),
  86. ('imm','immediate'),
  87. ('rm8','regmem or ot_bits8'),
  88. ('rm16','regmem or ot_bits16'),
  89. ('rm32','regmem or ot_bits32'),
  90. ('rm64','regmem or ot_bits64'),
  91. ('rm80','regmem or ot_bits80')
  92. );
  93. var
  94. i : longint;
  95. begin
  96. for i:=1to replaces do
  97. replace(s,replacetab[i,1],replacetab[i,2]);
  98. formatop:=s;
  99. end;
  100. function readnumber : longint;
  101. var
  102. base : longint;
  103. result : longint;
  104. begin
  105. result:=0;
  106. if s[i]='\' then
  107. begin
  108. base:=8;
  109. inc(i);
  110. if s[i]='x' then
  111. begin
  112. base:=16;
  113. inc(i);
  114. end;
  115. end
  116. else
  117. base:=10;
  118. s[i]:=upcase(s[i]);
  119. while s[i] in ['0'..'9','A'..'F'] do
  120. begin
  121. case s[i] of
  122. '0'..'9':
  123. result:=result*base+ord(s[i])-ord('0');
  124. 'A'..'F':
  125. result:=result*base+ord(s[i])-ord('A')+10;
  126. end;
  127. inc(i);
  128. end;
  129. readnumber:=result;
  130. end;
  131. function tostr(l : longint) : string;
  132. var
  133. hs : string;
  134. begin
  135. str(l,hs);
  136. tostr:=hs;
  137. end;
  138. function readstr : string;
  139. var
  140. result : string;
  141. begin
  142. result:='';
  143. while (s[i] in ['0'..'9','A'..'Z','a'..'z','_']) and (i<=length(s)) do
  144. begin
  145. result:=result+s[i];
  146. inc(i);
  147. end;
  148. readstr:=result;
  149. end;
  150. procedure skipspace;
  151. begin
  152. while (s[i] in [' ',#9]) do
  153. inc(i);
  154. end;
  155. procedure openinc(var f:text;const fn:string);
  156. begin
  157. writeln('creating ',fn);
  158. assign(f,fn);
  159. rewrite(f);
  160. writeln(f,'{ don''t edit, this file is generated from x86ins.dat }');
  161. writeln(f,'(');
  162. end;
  163. procedure closeinc(var f:text);
  164. begin
  165. writeln(f);
  166. writeln(f,');');
  167. close(f);
  168. end;
  169. var
  170. attsuffix,
  171. hs : string;
  172. j : longint;
  173. firstopcode,
  174. first : boolean;
  175. maxinfolen,
  176. code : byte;
  177. insns : longint;
  178. attsuffile,propfile,opfile,
  179. nopfile,attfile,intfile,
  180. infile,insfile : text;
  181. { instruction fields }
  182. skip : boolean;
  183. last,
  184. ops : longint;
  185. intopcode,
  186. attopcode,
  187. opcode,
  188. codes,
  189. flags : string;
  190. optypes : array[1..3] of string;
  191. begin
  192. writeln('Nasm Instruction Table Converter Version ',Version);
  193. x86_64:=paramstr(1)='x86_64';
  194. insns:=0;
  195. maxinfolen:=0;
  196. { open dat file }
  197. assign(infile,'../x86/x86ins.dat');
  198. if x86_64 then
  199. begin
  200. { create inc files }
  201. openinc(insfile,'x8664tab.inc');
  202. openinc(opfile,'x8664op.inc');
  203. assign(nopfile,'x8664nop.inc');
  204. openinc(attfile,'x8664att.inc');
  205. openinc(attsuffile,'x8664ats.inc');
  206. openinc(intfile,'x8664int.inc');
  207. openinc(propfile,'x8664pro.inc');
  208. end
  209. else
  210. begin
  211. { create inc files }
  212. openinc(insfile,'i386tab.inc');
  213. openinc(opfile,'i386op.inc');
  214. assign(nopfile,'i386nop.inc');
  215. openinc(attfile,'i386att.inc');
  216. openinc(attsuffile,'i386atts.inc');
  217. openinc(intfile,'i386int.inc');
  218. openinc(propfile,'i386prop.inc');
  219. end;
  220. rewrite(nopfile);
  221. writeln(nopfile,'{ don''t edit, this file is generated from x86ins.dat }');
  222. reset(infile);
  223. first:=true;
  224. opcode:='';
  225. firstopcode:=true;
  226. while not(eof(infile)) do
  227. begin
  228. { handle comment }
  229. readln(infile,s);
  230. while (s[1]=' ') do
  231. delete(s,1,1);
  232. if (s='') or (s[1]=';') then
  233. continue;
  234. if (s[1]='[') then
  235. begin
  236. i:=pos(',',s);
  237. j:=pos(']',s);
  238. if i=0 then
  239. begin
  240. opcode:='A_'+Copy(s,2,j-2);
  241. intopcode:=Copy(s,2,j-2);
  242. { Conditional }
  243. if (intopcode[length(intopcode)]='c') and
  244. (intopcode[length(intopcode)-1]='c') then
  245. dec(byte(intopcode[0]),2);
  246. attopcode:=intopcode;
  247. attsuffix:='attsufNONE';
  248. end
  249. else
  250. begin
  251. opcode:='A_'+Copy(s,2,i-2);
  252. intopcode:=Copy(s,2,i-2);
  253. { intel conditional }
  254. if (intopcode[length(intopcode)]='c') and
  255. (intopcode[length(intopcode)-1]='c') then
  256. dec(byte(intopcode[0]),2);
  257. attopcode:=Copy(s,i+1,j-i-1);
  258. { att Suffix }
  259. case attopcode[length(attopcode)] of
  260. 'X' :
  261. begin
  262. dec(attopcode[0]);
  263. attsuffix:='attsufINT';
  264. end;
  265. 'F' :
  266. begin
  267. dec(attopcode[0]);
  268. attsuffix:='attsufFPU';
  269. end;
  270. 'R' :
  271. begin
  272. dec(attopcode[0]);
  273. attsuffix:='attsufFPUint';
  274. end;
  275. else
  276. attsuffix:='attsufNONE';
  277. end;
  278. { att Conditional }
  279. if (attopcode[length(attopcode)]='C') and
  280. (attopcode[length(attopcode)-1]='C') then
  281. dec(byte(attopcode[0]),2);
  282. end;
  283. intopcode:=Lower(intopcode);
  284. attopcode:=Lower(attopcode);
  285. if firstopcode then
  286. firstopcode:=false
  287. else
  288. begin
  289. writeln(opfile,',');
  290. writeln(attfile,',');
  291. writeln(attsuffile,',');
  292. writeln(intfile,',');
  293. writeln(propfile,',');
  294. end;
  295. write(opfile,opcode);
  296. write(intfile,'''',intopcode,'''');
  297. write(attfile,'''',attopcode,'''');
  298. write(attsuffile,attsuffix);
  299. { read the next line which contains the Change options }
  300. repeat
  301. readln(infile,s);
  302. until eof(infile) or ((s<>'') and (s[1]<>';'));
  303. write(propfile,'(Ch: ',s,')');
  304. continue;
  305. end;
  306. { we must have an opcode }
  307. if opcode='' then
  308. runerror(234);
  309. { clear }
  310. ops:=0;
  311. optypes[1]:='';
  312. optypes[2]:='';
  313. optypes[3]:='';
  314. codes:='';
  315. flags:='';
  316. skip:=false;
  317. { ops and optypes }
  318. i:=1;
  319. repeat
  320. hs:=readstr;
  321. if (hs='void') or (hs='ignore') then
  322. break;
  323. inc(ops);
  324. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
  325. if s[i]=':' then
  326. begin
  327. inc(i);
  328. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  329. end;
  330. while s[i]='|' do
  331. begin
  332. inc(i);
  333. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  334. end;
  335. if s[i]=',' then
  336. inc(i)
  337. else
  338. break;
  339. until false;
  340. for j:=1 to 3-ops do
  341. optypes[3-j+1]:='ot_none';
  342. { codes }
  343. skipspace;
  344. j:=0;
  345. last:=0;
  346. if s[i] in ['\','0'..'9'] then
  347. begin
  348. while not(s[i] in [' ',#9]) do
  349. begin
  350. code:=readnumber;
  351. { for some codes we want also to change the optypes, but not
  352. if the last byte was a 1 then this byte belongs to a direct
  353. copy }
  354. if last<>1 then
  355. begin
  356. case code of
  357. 12,13,14 :
  358. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  359. end;
  360. end;
  361. codes:=codes+'#'+tostr(code);
  362. last:=code;
  363. inc(j);
  364. end;
  365. end
  366. else
  367. begin
  368. readstr;
  369. codes:='#0';
  370. end;
  371. if j>maxinfolen then
  372. maxinfolen:=j;
  373. { flags }
  374. skipspace;
  375. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  376. begin
  377. hs:=readstr;
  378. if x86_64 then
  379. begin
  380. if (upcase(hs)='NOX86_64') then
  381. skip:=true;
  382. end
  383. else
  384. begin
  385. if (upcase(hs)='X86_64') then
  386. skip:=true;
  387. end;
  388. if hs<>'ND' then
  389. begin
  390. if flags<>'' then
  391. flags:=flags+' or ';
  392. flags:=flags+'if_'+lower(hs);
  393. end;
  394. if (s[i]=',') and (i<=length(s)) then
  395. inc(i)
  396. else
  397. break;
  398. end;
  399. { write instruction }
  400. if not skip then
  401. begin
  402. if not(first) then
  403. writeln(insfile,',')
  404. else
  405. first:=false;
  406. writeln(insfile,' (');
  407. writeln(insfile,' opcode : ',opcode,';');
  408. writeln(insfile,' ops : ',ops,';');
  409. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],');');
  410. writeln(insfile,' code : ',codes,';');
  411. writeln(insfile,' flags : ',flags);
  412. write(insfile,' )');
  413. inc(insns);
  414. end;
  415. end;
  416. close(infile);
  417. closeinc(insfile);
  418. closeinc(intfile);
  419. closeinc(attfile);
  420. closeinc(attsuffile);
  421. closeinc(opfile);
  422. writeln(nopfile,insns,';');
  423. close(nopfile);
  424. closeinc(propfile);
  425. writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
  426. end.
  427. {
  428. $Log$
  429. Revision 1.6 2004-02-09 20:30:48 peter
  430. * support X86_64 and NOX86_64 flags
  431. Revision 1.5 2004/02/03 16:50:51 peter
  432. * linux path separators
  433. Revision 1.4 2004/01/15 14:01:32 florian
  434. + x86 instruction tables for x86-64 extended
  435. Revision 1.3 2003/09/09 12:54:45 florian
  436. * x86 instruction table updated to nasm 0.98.37:
  437. - sse3 aka prescott support
  438. - small fixes
  439. Revision 1.2 2003/09/03 15:55:02 peter
  440. * NEWRA branch merged
  441. Revision 1.1.2.1 2003/08/27 19:13:10 peter
  442. * new tools
  443. Revision 1.5 2002/05/18 13:34:27 peter
  444. * readded missing revisions
  445. Revision 1.4 2002/05/16 19:46:54 carl
  446. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  447. + try to fix temp allocation (still in ifdef)
  448. + generic constructor calls
  449. + start of tassembler / tmodulebase class cleanup
  450. }