mkx86reg.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  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,dwarf32,dwarf64,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. dwarf32[regcount]:=readstr;
  263. readcomma;
  264. dwarf64[regcount]:=readstr;
  265. readcomma;
  266. ots[regcount]:=readstr;
  267. readcomma;
  268. ops[regcount]:=readstr;
  269. if s[i]=',' then
  270. begin
  271. readcomma;
  272. cpustr:=readstr;
  273. end
  274. else
  275. cpustr:='';
  276. if i<length(s) then
  277. begin
  278. writeln('Extra chars at end of line, at line ',line);
  279. writeln('Line: "',s,'"');
  280. halt(1);
  281. end;
  282. if (cpustr<>'64') or x86_64 then
  283. begin
  284. inc(regcount);
  285. if regcount>max_regcount then
  286. begin
  287. writeln('Error: Too much registers, please increase maxregcount in source');
  288. halt(2);
  289. end;
  290. end;
  291. end;
  292. close(infile);
  293. end;
  294. procedure write_inc_files;
  295. var attfile,intfile,otfile,opfile,
  296. norfile,nasmfile,stdfile,
  297. numfile,stabfile,dwrffile,confile,
  298. rnifile,irifile,srifile,
  299. arifile,nrifile:text;
  300. first:boolean;
  301. begin
  302. { create inc files }
  303. openinc(confile,fileprefix+'con.inc');
  304. openinc(numfile,fileprefix+'num.inc');
  305. openinc(stdfile,fileprefix+'std.inc');
  306. openinc(attfile,fileprefix+'att.inc');
  307. if not(x86_64) then
  308. begin
  309. openinc(intfile,fileprefix+'int.inc');
  310. openinc(nasmfile,fileprefix+'nasm.inc');
  311. end;
  312. openinc(stabfile,fileprefix+'stab.inc');
  313. openinc(dwrffile,fileprefix+'dwrf.inc');
  314. openinc(otfile,fileprefix+'ot.inc');
  315. openinc(opfile,fileprefix+'op.inc');
  316. openinc(norfile,fileprefix+'nor.inc');
  317. openinc(rnifile,fileprefix+'rni.inc');
  318. openinc(srifile,fileprefix+'sri.inc');
  319. openinc(arifile,fileprefix+'ari.inc');
  320. if not(x86_64) then
  321. begin
  322. openinc(nrifile,fileprefix+'nri.inc');
  323. openinc(irifile,fileprefix+'iri.inc');
  324. end;
  325. first:=true;
  326. for i:=0 to regcount-1 do
  327. begin
  328. if not first then
  329. begin
  330. writeln(numfile,',');
  331. writeln(stdfile,',');
  332. writeln(attfile,',');
  333. if not(x86_64) then
  334. begin
  335. writeln(intfile,',');
  336. writeln(nasmfile,',');
  337. end;
  338. writeln(stabfile,',');
  339. writeln(dwrffile,',');
  340. writeln(otfile,',');
  341. writeln(opfile,',');
  342. writeln(rnifile,',');
  343. writeln(srifile,',');
  344. writeln(arifile,',');
  345. if not(x86_64) then
  346. begin
  347. writeln(irifile,',');
  348. writeln(nrifile,',');
  349. end;
  350. end
  351. else
  352. first:=false;
  353. writeln(confile,names[i],' = ','tregister(',numbers[i],')',';');
  354. write(numfile,'tregister(',numbers[i],')');
  355. write(stdfile,'''',stdnames[i],'''');
  356. write(attfile,'''',attnames[i],'''');
  357. if not(x86_64) then
  358. begin
  359. write(intfile,'''',intnames[i],'''');
  360. write(nasmfile,'''',nasmnames[i],'''');
  361. end;
  362. write(stabfile,stabs[i]);
  363. if x86_64 then
  364. write(dwrffile,dwarf64[i])
  365. else
  366. write(dwrffile,dwarf32[i]);
  367. write(otfile,ots[i]);
  368. write(opfile,ops[i]);
  369. write(rnifile,regnumber_index[i]);
  370. write(srifile,std_regname_index[i]);
  371. write(arifile,att_regname_index[i]);
  372. if not(x86_64) then
  373. begin
  374. write(irifile,int_regname_index[i]);
  375. write(nrifile,nasm_regname_index[i]);
  376. end;
  377. end;
  378. write(norfile,regcount);
  379. close(confile);
  380. closeinc(numfile);
  381. closeinc(attfile);
  382. closeinc(stdfile);
  383. if not(x86_64) then
  384. begin
  385. closeinc(intfile);
  386. closeinc(nasmfile);
  387. end;
  388. closeinc(stabfile);
  389. closeinc(dwrffile);
  390. closeinc(otfile);
  391. closeinc(opfile);
  392. closeinc(norfile);
  393. closeinc(rnifile);
  394. closeinc(srifile);
  395. closeinc(arifile);
  396. if not(x86_64) then
  397. begin
  398. closeinc(nrifile);
  399. closeinc(irifile);
  400. end;
  401. writeln('Done!');
  402. writeln(regcount,' registers procesed');
  403. end;
  404. begin
  405. writeln('Register Table Converter Version ',Version);
  406. x86_64:=paramstr(1)='x86_64';
  407. if x86_64 then
  408. fileprefix:='r8664'
  409. else
  410. fileprefix:='r386';
  411. line:=0;
  412. regcount:=0;
  413. read_x86reg_file;
  414. regcount_bsstart:=1;
  415. while 2*regcount_bsstart<regcount do
  416. regcount_bsstart:=regcount_bsstart*2;
  417. build_regnum_index;
  418. if not(x86_64) then
  419. begin
  420. build_int_regname_index;
  421. build_nasm_regname_index;
  422. end;
  423. build_std_regname_index;
  424. build_att_regname_index;
  425. write_inc_files;
  426. end.
  427. {
  428. $Log$
  429. Revision 1.5 2004-06-16 20:07:11 florian
  430. * dwarf branch merged
  431. Revision 1.4.2.1 2004/04/12 19:34:46 peter
  432. * basic framework for dwarf CFI
  433. Revision 1.4 2003/12/15 21:25:49 peter
  434. * reg allocations for imaginary register are now inserted just
  435. before reg allocation
  436. * tregister changed to enum to allow compile time check
  437. * fixed several tregister-tsuperregister errors
  438. Revision 1.3 2003/09/24 17:11:33 florian
  439. * x86_64 support; turn on by passing x86_64
  440. Revision 1.2 2003/09/03 15:55:02 peter
  441. * NEWRA branch merged
  442. Revision 1.1.2.4 2003/08/31 18:46:57 peter
  443. * removed warning
  444. Revision 1.1.2.3 2003/08/29 09:41:25 daniel
  445. * Further mkx86reg development
  446. Revision 1.1.2.2 2003/08/27 20:30:46 peter
  447. * updated for opcode
  448. Revision 1.1.2.1 2003/08/27 19:13:10 peter
  449. * new tools
  450. }