mkx86reg.pp 10 KB

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