mkarmins.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  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 3-ops do
  327. optypes[3-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. { for some codes we want also to change the optypes, but not
  338. if the last byte was a 1 then this byte belongs to a direct
  339. copy }
  340. if last<>1 then
  341. begin
  342. case code of
  343. 12,13,14 :
  344. optypes[code-11]:=optypes[code-11]+' or ot_signed';
  345. end;
  346. end;
  347. codes:=codes+'#'+tostr(code);
  348. last:=code;
  349. inc(j);
  350. end;
  351. end
  352. else
  353. begin
  354. readstr;
  355. codes:='#0';
  356. end;
  357. if j>maxinfolen then
  358. maxinfolen:=j;
  359. { flags }
  360. skipspace;
  361. while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
  362. begin
  363. hs:=readstr;
  364. if hs<>'ND' then
  365. begin
  366. if flags<>'' then
  367. flags:=flags+' or ';
  368. flags:=flags+'if_'+lower(hs);
  369. end;
  370. if (s[i]=',') and (i<=length(s)) then
  371. inc(i)
  372. else
  373. break;
  374. end;
  375. { write instruction }
  376. if not skip then
  377. begin
  378. if not(first) then
  379. writeln(insfile,',')
  380. else
  381. first:=false;
  382. writeln(insfile,' (');
  383. writeln(insfile,' opcode : ',opcode,';');
  384. writeln(insfile,' ops : ',ops,';');
  385. writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
  386. writeln(insfile,' code : ',codes,';');
  387. writeln(insfile,' flags : ',flags);
  388. write(insfile,' )');
  389. inc(insns);
  390. end;
  391. end;
  392. close(infile);
  393. closeinc(insfile);
  394. closeinc(attfile);
  395. closeinc(attsuffile);
  396. closeinc(opfile);
  397. writeln(nopfile,insns,';');
  398. close(nopfile);
  399. { closeinc(propfile); }
  400. writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
  401. end.