mkarmins.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. {
  2. Copyright (c) 1998-2005 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. program mkarmins;
  12. const
  13. Version = '0.9';
  14. var
  15. s : string;
  16. i : longint;
  17. x86_64 : boolean;
  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 armins.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,
  179. infile,insfile : text;
  180. { instruction fields }
  181. skip : boolean;
  182. last,
  183. ops : longint;
  184. attopcode,
  185. opcode,
  186. codes,
  187. flags : string;
  188. optypes : array[1..4] of string;
  189. begin
  190. writeln('Narm Instruction Table Converter Version ',Version);
  191. insns:=0;
  192. maxinfolen:=0;
  193. { open dat file }
  194. assign(infile,'../arm/armins.dat');
  195. { create inc files }
  196. openinc(insfile,'armtab.inc');
  197. openinc(opfile,'armop.inc');
  198. assign(nopfile,'armnop.inc');
  199. openinc(attfile,'armatt.inc');
  200. openinc(attsuffile,'armatts.inc');
  201. {
  202. openinc(intfile,'i386int.inc');
  203. openinc(propfile,'i386prop.inc');
  204. }
  205. rewrite(nopfile);
  206. writeln(nopfile,'{ don''t edit, this file is generated from armins.dat }');
  207. reset(infile);
  208. first:=true;
  209. opcode:='';
  210. firstopcode:=true;
  211. while not(eof(infile)) do
  212. begin
  213. { handle comment }
  214. readln(infile,s);
  215. while (s[1]=' ') do
  216. delete(s,1,1);
  217. if (s='') or (s[1]=';') then
  218. continue;
  219. if (s[1]='[') then
  220. begin
  221. i:=pos(',',s);
  222. j:=pos(']',s);
  223. if i=0 then
  224. begin
  225. opcode:='A_'+Copy(s,2,j-2);
  226. attopcode:=Copy(s,2,j-2);
  227. { Conditional }
  228. if (attopcode[length(attopcode)]='c') and
  229. (attopcode[length(attopcode)-1]='c') then
  230. begin
  231. dec(byte(attopcode[0]),2);
  232. dec(byte(opcode[0]),2);
  233. end;
  234. attsuffix:='attsufNONE';
  235. end
  236. else
  237. begin
  238. opcode:='A_'+Copy(s,2,i-2);
  239. { intel conditional }
  240. if (opcode[length(attopcode)]='c') and
  241. (opcode[length(attopcode)-1]='c') then
  242. dec(byte(opcode[0]),2);
  243. attopcode:=Copy(s,i+1,j-i-1);
  244. { att Suffix }
  245. case attopcode[length(attopcode)] of
  246. 'X' :
  247. begin
  248. dec(attopcode[0]);
  249. attsuffix:='attsufINT';
  250. end;
  251. 'F' :
  252. begin
  253. dec(attopcode[0]);
  254. attsuffix:='attsufFPU';
  255. end;
  256. 'R' :
  257. begin
  258. dec(attopcode[0]);
  259. attsuffix:='attsufFPUint';
  260. end;
  261. else
  262. attsuffix:='attsufNONE';
  263. end;
  264. { att Conditional }
  265. if (attopcode[length(attopcode)]='C') and
  266. (attopcode[length(attopcode)-1]='C') then
  267. dec(byte(attopcode[0]),2);
  268. end;
  269. attopcode:=Lower(attopcode);
  270. if firstopcode then
  271. firstopcode:=false
  272. else
  273. begin
  274. writeln(opfile,',');
  275. writeln(attfile,',');
  276. writeln(attsuffile,',');
  277. { writeln(propfile,','); }
  278. end;
  279. write(opfile,opcode);
  280. write(attfile,'''',attopcode,'''');
  281. write(attsuffile,attsuffix);
  282. { read the next line which contains the Change options }
  283. {
  284. repeat
  285. readln(infile,s);
  286. until eof(infile) or ((s<>'') and (s[1]<>';'));
  287. write(propfile,'(Ch: ',s,')');
  288. }
  289. continue;
  290. end;
  291. { we must have an opcode }
  292. if opcode='' then
  293. runerror(234);
  294. { clear }
  295. ops:=0;
  296. optypes[1]:='';
  297. optypes[2]:='';
  298. optypes[3]:='';
  299. optypes[4]:='';
  300. codes:='';
  301. flags:='';
  302. skip:=false;
  303. { ops and optypes }
  304. i:=1;
  305. repeat
  306. hs:=readstr;
  307. if (hs='void') or (hs='ignore') then
  308. break;
  309. inc(ops);
  310. optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
  311. { if s[i]=':' then
  312. begin
  313. inc(i);
  314. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  315. end;}
  316. while s[i]='|' do
  317. begin
  318. inc(i);
  319. optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
  320. end;
  321. if s[i] in [',',':'] then
  322. inc(i)
  323. else
  324. break;
  325. until false;
  326. for j:=1 to 4-ops do
  327. optypes[4-j+1]:='ot_none';
  328. { codes }
  329. skipspace;
  330. j:=0;
  331. last:=0;
  332. if s[i] in ['\','0'..'9'] then
  333. begin
  334. while not(s[i] in [' ',#9]) do
  335. begin
  336. code:=readnumber;
  337. (*
  338. { for some codes we want also to change the optypes, but not
  339. if the last byte was a 1 then this byte belongs to a direct
  340. copy }
  341. if last<>1 then
  342. begin
  343. case code of
  344. 12,13,14 :
  345. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  346. end;
  347. end;
  348. *)
  349. codes:=codes+'#'+tostr(code);
  350. last:=code;
  351. inc(j);
  352. end;
  353. end
  354. else
  355. begin
  356. readstr;
  357. codes:='#0';
  358. end;
  359. if j>maxinfolen then
  360. maxinfolen:=j;
  361. { flags }
  362. skipspace;
  363. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  364. begin
  365. hs:=readstr;
  366. if hs<>'ND' then
  367. begin
  368. if flags<>'' then
  369. flags:=flags+' or ';
  370. flags:=flags+'if_'+lower(hs);
  371. end;
  372. if (s[i]=',') and (i<=length(s)) then
  373. inc(i)
  374. else
  375. break;
  376. end;
  377. { write instruction }
  378. if not skip then
  379. begin
  380. if not(first) then
  381. writeln(insfile,',')
  382. else
  383. first:=false;
  384. writeln(insfile,' (');
  385. writeln(insfile,' opcode : ',opcode,';');
  386. writeln(insfile,' ops : ',ops,';');
  387. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
  388. writeln(insfile,' code : ',codes,';');
  389. writeln(insfile,' flags : ',flags);
  390. write(insfile,' )');
  391. inc(insns);
  392. end;
  393. end;
  394. close(infile);
  395. closeinc(insfile);
  396. closeinc(attfile);
  397. closeinc(attsuffile);
  398. closeinc(opfile);
  399. writeln(nopfile,insns,';');
  400. close(nopfile);
  401. { closeinc(propfile); }
  402. writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
  403. end.