mkx86reg.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
  4. Convert i386reg.dat to several .inc files 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. {$mode objfpc}
  13. {$i+}
  14. program mkx86reg;
  15. const Version = '1.00';
  16. max_regcount = 128;
  17. var s : string;
  18. i : longint;
  19. line : longint;
  20. regcount:byte;
  21. regcount_bsstart:byte;
  22. names,numbers,stdnames,intnames,nasmnames,attnames,stabs,ots,ops:
  23. array[0..max_regcount-1] of string[63];
  24. regnumber_index,std_regname_index,int_regname_index,att_regname_index,
  25. nasm_regname_index:array[0..max_regcount-1] of byte;
  26. x86_64 : boolean;
  27. fileprefix : string;
  28. {$ifndef FPC}
  29. procedure readln(var t:text;var s:string);
  30. var
  31. c : char;
  32. i : longint;
  33. begin
  34. c:=#0;
  35. i:=0;
  36. while (not eof(t)) and (c<>#10) do
  37. begin
  38. read(t,c);
  39. if c<>#10 then
  40. begin
  41. inc(i);
  42. s[i]:=c;
  43. end;
  44. end;
  45. if (i>0) and (s[i]=#13) then
  46. dec(i);
  47. s[0]:=chr(i);
  48. end;
  49. {$endif}
  50. function tostr(l : longint) : string;
  51. begin
  52. str(l,tostr);
  53. end;
  54. function readstr : string;
  55. begin
  56. result:='';
  57. while (s[i]<>',') and (i<=length(s)) do
  58. begin
  59. result:=result+s[i];
  60. inc(i);
  61. end;
  62. readstr:=result;
  63. end;
  64. procedure readcomma;
  65. begin
  66. if s[i]<>',' then
  67. begin
  68. writeln('Missing "," at line ',line);
  69. writeln('Line: "',s,'"');
  70. halt(1);
  71. end;
  72. inc(i);
  73. end;
  74. procedure skipspace;
  75. begin
  76. while (s[i] in [' ',#9]) do
  77. inc(i);
  78. end;
  79. procedure openinc(var f:text;const fn:string);
  80. begin
  81. writeln('creating ',fn);
  82. assign(f,fn);
  83. rewrite(f);
  84. writeln(f,'{ don''t edit, this file is generated from x86reg.dat }');
  85. end;
  86. procedure closeinc(var f:text);
  87. begin
  88. writeln(f);
  89. close(f);
  90. end;
  91. procedure build_regnum_index;
  92. var h,i,j,p,t:byte;
  93. begin
  94. {Build the registernumber2regindex index.
  95. Step 1: Fill.}
  96. for i:=0 to regcount-1 do
  97. regnumber_index[i]:=i;
  98. {Step 2: Sort. We use a Shell-Metzner sort.}
  99. p:=regcount_bsstart;
  100. repeat
  101. for h:=0 to regcount-p-1 do
  102. begin
  103. i:=h;
  104. repeat
  105. j:=i+p;
  106. if numbers[regnumber_index[j]]>=numbers[regnumber_index[i]] then
  107. break;
  108. t:=regnumber_index[i];
  109. regnumber_index[i]:=regnumber_index[j];
  110. regnumber_index[j]:=t;
  111. if i<p then
  112. break;
  113. dec(i,p);
  114. until false;
  115. end;
  116. p:=p shr 1;
  117. until p=0;
  118. end;
  119. procedure build_std_regname_index;
  120. var h,i,j,p,t:byte;
  121. begin
  122. {Build the registernumber2regindex index.
  123. Step 1: Fill.}
  124. for i:=0 to regcount-1 do
  125. std_regname_index[i]:=i;
  126. {Step 2: Sort. We use a Shell-Metzner sort.}
  127. p:=regcount_bsstart;
  128. repeat
  129. for h:=0 to regcount-p-1 do
  130. begin
  131. i:=h;
  132. repeat
  133. j:=i+p;
  134. if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then
  135. break;
  136. t:=std_regname_index[i];
  137. std_regname_index[i]:=std_regname_index[j];
  138. std_regname_index[j]:=t;
  139. if i<p then
  140. break;
  141. dec(i,p);
  142. until false;
  143. end;
  144. p:=p shr 1;
  145. until p=0;
  146. end;
  147. procedure build_int_regname_index;
  148. var h,i,j,p,t:byte;
  149. begin
  150. {Build the registernumber2regindex index.
  151. Step 1: Fill.}
  152. for i:=0 to regcount-1 do
  153. int_regname_index[i]:=i;
  154. {Step 2: Sort. We use a Shell-Metzner sort.}
  155. p:=regcount_bsstart;
  156. repeat
  157. for h:=0 to regcount-p-1 do
  158. begin
  159. i:=h;
  160. repeat
  161. j:=i+p;
  162. if intnames[int_regname_index[j]]>=intnames[int_regname_index[i]] then
  163. break;
  164. t:=int_regname_index[i];
  165. int_regname_index[i]:=int_regname_index[j];
  166. int_regname_index[j]:=t;
  167. if i<p then
  168. break;
  169. dec(i,p);
  170. until false;
  171. end;
  172. p:=p shr 1;
  173. until p=0;
  174. end;
  175. procedure build_att_regname_index;
  176. var h,i,j,p,t:byte;
  177. begin
  178. {Build the registernumber2regindex index.
  179. Step 1: Fill.}
  180. for i:=0 to regcount-1 do
  181. att_regname_index[i]:=i;
  182. {Step 2: Sort. We use a Shell-Metzner sort.}
  183. p:=regcount_bsstart;
  184. repeat
  185. for h:=0 to regcount-p-1 do
  186. begin
  187. i:=h;
  188. repeat
  189. j:=i+p;
  190. if attnames[att_regname_index[j]]>=attnames[att_regname_index[i]] then
  191. break;
  192. t:=att_regname_index[i];
  193. att_regname_index[i]:=att_regname_index[j];
  194. att_regname_index[j]:=t;
  195. if i<p then
  196. break;
  197. dec(i,p);
  198. until false;
  199. end;
  200. p:=p shr 1;
  201. until p=0;
  202. end;
  203. procedure build_nasm_regname_index;
  204. var h,i,j,p,t:byte;
  205. begin
  206. {Build the registernumber2regindex index.
  207. Step 1: Fill.}
  208. for i:=0 to regcount-1 do
  209. nasm_regname_index[i]:=i;
  210. {Step 2: Sort. We use a Shell-Metzner sort.}
  211. p:=regcount_bsstart;
  212. repeat
  213. for h:=0 to regcount-p-1 do
  214. begin
  215. i:=h;
  216. repeat
  217. j:=i+p;
  218. if nasmnames[nasm_regname_index[j]]>=nasmnames[nasm_regname_index[i]] then
  219. break;
  220. t:=nasm_regname_index[i];
  221. nasm_regname_index[i]:=nasm_regname_index[j];
  222. nasm_regname_index[j]:=t;
  223. if i<p then
  224. break;
  225. dec(i,p);
  226. until false;
  227. end;
  228. p:=p shr 1;
  229. until p=0;
  230. end;
  231. procedure read_x86reg_file;
  232. var infile:text;
  233. cpustr:string;
  234. begin
  235. { open dat file }
  236. assign(infile,'x86reg.dat');
  237. reset(infile);
  238. while not(eof(infile)) do
  239. begin
  240. { handle comment }
  241. readln(infile,s);
  242. inc(line);
  243. while (s[1]=' ') do
  244. delete(s,1,1);
  245. if (s='') or (s[1]=';') then
  246. continue;
  247. i:=1;
  248. names[regcount]:=readstr;
  249. readcomma;
  250. numbers[regcount]:=readstr;
  251. readcomma;
  252. stdnames[regcount]:=readstr;
  253. readcomma;
  254. attnames[regcount]:=readstr;
  255. readcomma;
  256. intnames[regcount]:=readstr;
  257. readcomma;
  258. nasmnames[regcount]:=readstr;
  259. readcomma;
  260. stabs[regcount]:=readstr;
  261. readcomma;
  262. ots[regcount]:=readstr;
  263. readcomma;
  264. ops[regcount]:=readstr;
  265. if s[i]=',' then
  266. begin
  267. readcomma;
  268. cpustr:=readstr;
  269. end
  270. else
  271. cpustr:='';
  272. if i<length(s) then
  273. begin
  274. writeln('Extra chars at end of line, at line ',line);
  275. writeln('Line: "',s,'"');
  276. halt(1);
  277. end;
  278. if (cpustr<>'64') or x86_64 then
  279. begin
  280. inc(regcount);
  281. if regcount>max_regcount then
  282. begin
  283. writeln('Error: Too much registers, please increase maxregcount in source');
  284. halt(2);
  285. end;
  286. end;
  287. end;
  288. close(infile);
  289. end;
  290. procedure write_inc_files;
  291. var attfile,intfile,otfile,opfile,
  292. norfile,nasmfile,stdfile,
  293. numfile,stabfile,confile,
  294. rnifile,irifile,srifile,
  295. arifile,nrifile:text;
  296. first:boolean;
  297. begin
  298. { create inc files }
  299. openinc(confile,fileprefix+'con.inc');
  300. openinc(numfile,fileprefix+'num.inc');
  301. openinc(stdfile,fileprefix+'std.inc');
  302. openinc(attfile,fileprefix+'att.inc');
  303. if not(x86_64) then
  304. begin
  305. openinc(intfile,fileprefix+'int.inc');
  306. openinc(nasmfile,fileprefix+'nasm.inc');
  307. end;
  308. openinc(stabfile,fileprefix+'stab.inc');
  309. openinc(otfile,fileprefix+'ot.inc');
  310. openinc(opfile,fileprefix+'op.inc');
  311. openinc(norfile,fileprefix+'nor.inc');
  312. openinc(rnifile,fileprefix+'rni.inc');
  313. openinc(srifile,fileprefix+'sri.inc');
  314. openinc(arifile,fileprefix+'ari.inc');
  315. if not(x86_64) then
  316. begin
  317. openinc(nrifile,fileprefix+'nri.inc');
  318. openinc(irifile,fileprefix+'iri.inc');
  319. end;
  320. first:=true;
  321. for i:=0 to regcount-1 do
  322. begin
  323. if not first then
  324. begin
  325. writeln(numfile,',');
  326. writeln(stdfile,',');
  327. writeln(attfile,',');
  328. if not(x86_64) then
  329. begin
  330. writeln(intfile,',');
  331. writeln(nasmfile,',');
  332. end;
  333. writeln(stabfile,',');
  334. writeln(otfile,',');
  335. writeln(opfile,',');
  336. writeln(rnifile,',');
  337. writeln(srifile,',');
  338. writeln(arifile,',');
  339. if not(x86_64) then
  340. begin
  341. writeln(irifile,',');
  342. writeln(nrifile,',');
  343. end;
  344. end
  345. else
  346. first:=false;
  347. writeln(confile,names[i],' = ','tregister(',numbers[i],')',';');
  348. write(numfile,'tregister(',numbers[i],')');
  349. write(stdfile,'''',stdnames[i],'''');
  350. write(attfile,'''',attnames[i],'''');
  351. if not(x86_64) then
  352. begin
  353. write(intfile,'''',intnames[i],'''');
  354. write(nasmfile,'''',nasmnames[i],'''');
  355. end;
  356. write(stabfile,stabs[i]);
  357. write(otfile,ots[i]);
  358. write(opfile,ops[i]);
  359. write(rnifile,regnumber_index[i]);
  360. write(srifile,std_regname_index[i]);
  361. write(arifile,att_regname_index[i]);
  362. if not(x86_64) then
  363. begin
  364. write(irifile,int_regname_index[i]);
  365. write(nrifile,nasm_regname_index[i]);
  366. end;
  367. end;
  368. write(norfile,regcount);
  369. close(confile);
  370. closeinc(numfile);
  371. closeinc(attfile);
  372. closeinc(stdfile);
  373. if not(x86_64) then
  374. begin
  375. closeinc(intfile);
  376. closeinc(nasmfile);
  377. end;
  378. closeinc(stabfile);
  379. closeinc(otfile);
  380. closeinc(opfile);
  381. closeinc(norfile);
  382. closeinc(rnifile);
  383. closeinc(srifile);
  384. closeinc(arifile);
  385. if not(x86_64) then
  386. begin
  387. closeinc(nrifile);
  388. closeinc(irifile);
  389. end;
  390. writeln('Done!');
  391. writeln(regcount,' registers procesed');
  392. end;
  393. begin
  394. writeln('Register Table Converter Version ',Version);
  395. x86_64:=paramstr(1)='x86_64';
  396. if x86_64 then
  397. fileprefix:='r8664'
  398. else
  399. fileprefix:='r386';
  400. line:=0;
  401. regcount:=0;
  402. read_x86reg_file;
  403. regcount_bsstart:=1;
  404. while 2*regcount_bsstart<regcount do
  405. regcount_bsstart:=regcount_bsstart*2;
  406. build_regnum_index;
  407. if not(x86_64) then
  408. begin
  409. build_int_regname_index;
  410. build_nasm_regname_index;
  411. end;
  412. build_std_regname_index;
  413. build_att_regname_index;
  414. write_inc_files;
  415. end.
  416. {
  417. $Log$
  418. Revision 1.4 2003-12-15 21:25:49 peter
  419. * reg allocations for imaginary register are now inserted just
  420. before reg allocation
  421. * tregister changed to enum to allow compile time check
  422. * fixed several tregister-tsuperregister errors
  423. Revision 1.3 2003/09/24 17:11:33 florian
  424. * x86_64 support; turn on by passing x86_64
  425. Revision 1.2 2003/09/03 15:55:02 peter
  426. * NEWRA branch merged
  427. Revision 1.1.2.4 2003/08/31 18:46:57 peter
  428. * removed warning
  429. Revision 1.1.2.3 2003/08/29 09:41:25 daniel
  430. * Further mkx86reg development
  431. Revision 1.1.2.2 2003/08/27 20:30:46 peter
  432. * updated for opcode
  433. Revision 1.1.2.1 2003/08/27 19:13:10 peter
  434. * new tools
  435. }