mkx86ins.pp 11 KB

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