mkx86reg.pp 11 KB

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