nasmconv.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 nasmconv;
  13. const
  14. Version = '0.99.13';
  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 i386ins.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. hs : string;
  170. j : longint;
  171. firstopcode,attsuffix,
  172. first : boolean;
  173. maxinfolen,
  174. code : byte;
  175. insns : longint;
  176. attsuffile,propfile,opfile,attfile,intfile,
  177. infile,insfile : text;
  178. { instruction fields }
  179. last,
  180. ops : longint;
  181. intopcode,
  182. attopcode,
  183. opcode,
  184. codes,
  185. flags : string;
  186. optypes : array[1..3] of string;
  187. begin
  188. writeln('Nasm Instruction Table Converter Version ',Version);
  189. insns:=0;
  190. maxinfolen:=0;
  191. { open dat file }
  192. assign(infile,'i386ins.dat');
  193. reset(infile);
  194. { create inc files }
  195. openinc(insfile,'i386tab.inc');
  196. openinc(opfile,'i386op.inc');
  197. openinc(attfile,'i386att.inc');
  198. openinc(attsuffile,'i386atts.inc');
  199. openinc(intfile,'i386int.inc');
  200. openinc(propfile,'i386prop.inc');
  201. first:=true;
  202. opcode:='';
  203. firstopcode:=true;
  204. while not(eof(infile)) do
  205. begin
  206. { handle comment }
  207. readln(infile,s);
  208. while (s[1]=' ') do
  209. delete(s,1,1);
  210. if (s='') or (s[1]=';') then
  211. continue;
  212. if (s[1]='[') then
  213. begin
  214. i:=pos(',',s);
  215. j:=pos(']',s);
  216. if i=0 then
  217. begin
  218. opcode:='A_'+Copy(s,2,j-2);
  219. intopcode:=Copy(s,2,j-2);
  220. { Conditional }
  221. if (intopcode[length(intopcode)]='c') and
  222. (intopcode[length(intopcode)-1]='c') then
  223. dec(byte(intopcode[0]),2);
  224. attopcode:=intopcode;
  225. attsuffix:=false;
  226. end
  227. else
  228. begin
  229. opcode:='A_'+Copy(s,2,i-2);
  230. intopcode:=Copy(s,2,i-2);
  231. { intel conditional }
  232. if (intopcode[length(intopcode)]='c') and
  233. (intopcode[length(intopcode)-1]='c') then
  234. dec(byte(intopcode[0]),2);
  235. attopcode:=Copy(s,i+1,j-i-1);
  236. { att Suffix }
  237. if attopcode[length(attopcode)]='X' then
  238. begin
  239. dec(attopcode[0]);
  240. attsuffix:=true;
  241. end
  242. else
  243. attsuffix:=false;
  244. { att Conditional }
  245. if (attopcode[length(attopcode)]='C') and
  246. (attopcode[length(attopcode)-1]='C') then
  247. dec(byte(attopcode[0]),2);
  248. end;
  249. intopcode:=Lower(intopcode);
  250. attopcode:=Lower(attopcode);
  251. if firstopcode then
  252. firstopcode:=false
  253. else
  254. begin
  255. writeln(opfile,',');
  256. writeln(attfile,',');
  257. writeln(attsuffile,',');
  258. writeln(intfile,',');
  259. writeln(propfile,',');
  260. end;
  261. write(opfile,opcode);
  262. write(intfile,'''',intopcode,'''');
  263. write(attfile,'''',attopcode,'''');
  264. if attsuffix then
  265. write(attsuffile,'true')
  266. else
  267. write(attsuffile,'false');
  268. { read the next line which contains the Change options }
  269. repeat
  270. readln(infile,s);
  271. until eof(infile) or ((s<>'') and (s[1]<>';'));
  272. write(propfile,'(Ch: ',s,')');
  273. continue;
  274. end;
  275. { we must have an opcode }
  276. if opcode='' then
  277. runerror(234);
  278. { clear }
  279. ops:=0;
  280. optypes[1]:='';
  281. optypes[2]:='';
  282. optypes[3]:='';
  283. codes:='';
  284. flags:='';
  285. { ops and optypes }
  286. i:=1;
  287. repeat
  288. hs:=readstr;
  289. if (hs='void') or (hs='ignore') then
  290. break;
  291. inc(ops);
  292. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
  293. if s[i]=':' then
  294. begin
  295. inc(i);
  296. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  297. end;
  298. while s[i]='|' do
  299. begin
  300. inc(i);
  301. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  302. end;
  303. if s[i]=',' then
  304. inc(i)
  305. else
  306. break;
  307. until false;
  308. for j:=1 to 3-ops do
  309. optypes[3-j+1]:='ot_none';
  310. { codes }
  311. skipspace;
  312. j:=0;
  313. last:=0;
  314. if s[i] in ['\','0'..'9'] then
  315. begin
  316. while not(s[i] in [' ',#9]) do
  317. begin
  318. code:=readnumber;
  319. { for some codes we want also to change the optypes, but not
  320. if the last byte was a 1 then this byte belongs to a direct
  321. copy }
  322. if last<>1 then
  323. begin
  324. case code of
  325. 12,13,14 :
  326. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  327. end;
  328. end;
  329. codes:=codes+'#'+tostr(code);
  330. last:=code;
  331. inc(j);
  332. end;
  333. end
  334. else
  335. begin
  336. readstr;
  337. codes:='#0';
  338. end;
  339. if j>maxinfolen then
  340. maxinfolen:=j;
  341. { flags }
  342. skipspace;
  343. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  344. begin
  345. hs:=readstr;
  346. if hs='ignore' then
  347. begin
  348. flags:='0';
  349. break;
  350. end;
  351. if hs<>'ND' then
  352. begin
  353. if flags<>'' then
  354. flags:=flags+' or ';
  355. flags:=flags+'if_'+lower(hs);
  356. end;
  357. if (s[i]=',') and (i<=length(s)) then
  358. inc(i)
  359. else
  360. break;
  361. end;
  362. { write instruction }
  363. if not(first) then
  364. writeln(insfile,',')
  365. else
  366. first:=false;
  367. writeln(insfile,' (');
  368. writeln(insfile,' opcode : ',opcode,';');
  369. writeln(insfile,' ops : ',ops,';');
  370. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],');');
  371. writeln(insfile,' code : ',codes,';');
  372. writeln(insfile,' flags : ',flags);
  373. write(insfile,' )');
  374. inc(insns);
  375. end;
  376. close(infile);
  377. closeinc(insfile);
  378. closeinc(intfile);
  379. closeinc(attfile);
  380. closeinc(attsuffile);
  381. closeinc(opfile);
  382. closeinc(propfile);
  383. writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
  384. end.
  385. {
  386. $Log$
  387. Revision 1.6 2000-01-07 01:15:01 peter
  388. * updated copyright to 2000
  389. Revision 1.5 1999/10/28 09:47:45 peter
  390. * update to use i386ins.dat
  391. Revision 1.4 1999/10/27 16:06:52 peter
  392. * updated for new layout
  393. Revision 1.3 1999/08/12 14:36:09 peter
  394. + KNI instructions
  395. Revision 1.2 1999/05/23 18:42:24 florian
  396. * better error recovering in typed constants
  397. * some problems with arrays of const fixed, some problems
  398. due my previous
  399. - the location type of array constructor is now LOC_MEM
  400. - the pushing of high fixed
  401. - parameter copying fixed
  402. - zero temp. allocation removed
  403. * small problem in the assembler writers fixed:
  404. ref to nil wasn't written correctly
  405. Revision 1.1 1999/05/12 16:17:10 peter
  406. * init
  407. Revision 1.1 1999/05/12 16:08:27 peter
  408. + moved compiler utils
  409. }