diff options
Diffstat (limited to 'compiler/utils/mkmpsreg.pp')
-rw-r--r-- | compiler/utils/mkmpsreg.pp | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/compiler/utils/mkmpsreg.pp b/compiler/utils/mkmpsreg.pp new file mode 100644 index 0000000000..b8130bb511 --- /dev/null +++ b/compiler/utils/mkmpsreg.pp @@ -0,0 +1,349 @@ +{ + Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl + + Convert mipsreg.dat to several .inc files for usage with + the Free pascal compiler + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} +program mkmipsreg; + +const Version = '1.00'; + max_regcount = 200; + +var s : string; + i : longint; + line : longint; + regcount:byte; + regcount_bsstart:byte; + names, + regtypes, + supregs, + numbers, + stdnames, + gasnames, + dwarfs, + stabs : array[0..max_regcount-1] of string[63]; + regnumber_index, + std_regname_index, + gas_regname_index, + mot_regname_index : array[0..max_regcount-1] of byte; + +{$ifndef FPC} + procedure readln(var t:text;var s:string); + var + c : char; + i : longint; + begin + c:=#0; + i:=0; + while (not eof(t)) and (c<>#10) do + begin + read(t,c); + if c<>#10 then + begin + inc(i); + s[i]:=c; + end; + end; + if (i>0) and (s[i]=#13) then + dec(i); + s[0]:=chr(i); + end; +{$endif} + +function tostr(l : longint) : string; + +begin + str(l,tostr); +end; + +function readstr : string; + + var + result : string; + + begin + result:=''; + while (s[i]<>',') and (i<=length(s)) do + begin + result:=result+s[i]; + inc(i); + end; + readstr:=result; + end; + + +procedure readcomma; + begin + if s[i]<>',' then + begin + writeln('Missing "," at line ',line); + writeln('Line: "',s,'"'); + halt(1); + end; + inc(i); + end; + + +procedure skipspace; + + begin + while (s[i] in [' ',#9]) do + inc(i); + end; + +procedure openinc(var f:text;const fn:string); +begin + writeln('creating ',fn); + assign(f,fn); + rewrite(f); + writeln(f,'{ don''t edit, this file is generated from mipsreg.dat }'); +end; + + +procedure closeinc(var f:text); +begin + writeln(f); + close(f); +end; + +procedure build_regnum_index; + +var h,i,j,p,t:byte; + +begin + {Build the registernumber2regindex index. + Step 1: Fill.} + for i:=0 to regcount-1 do + regnumber_index[i]:=i; + {Step 2: Sort. We use a Shell-Metzner sort.} + p:=regcount_bsstart; + repeat + for h:=0 to regcount-p-1 do + begin + i:=h; + repeat + j:=i+p; + if numbers[regnumber_index[j]]>=numbers[regnumber_index[i]] then + break; + t:=regnumber_index[i]; + regnumber_index[i]:=regnumber_index[j]; + regnumber_index[j]:=t; + if i<p then + break; + dec(i,p); + until false; + end; + p:=p shr 1; + until p=0; +end; + +procedure build_std_regname_index; + +var h,i,j,p,t:byte; + +begin + {Build the registernumber2regindex index. + Step 1: Fill.} + for i:=0 to regcount-1 do + std_regname_index[i]:=i; + {Step 2: Sort. We use a Shell-Metzner sort.} + p:=regcount_bsstart; + repeat + for h:=0 to regcount-p-1 do + begin + i:=h; + repeat + j:=i+p; + if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then + break; + t:=std_regname_index[i]; + std_regname_index[i]:=std_regname_index[j]; + std_regname_index[j]:=t; + if i<p then + break; + dec(i,p); + until false; + end; + p:=p shr 1; + until p=0; +end; + + +procedure build_gas_regname_index; + +var h,i,j,p,t:byte; + +begin + {Build the registernumber2regindex index. + Step 1: Fill.} + for i:=0 to regcount-1 do + gas_regname_index[i]:=i; + {Step 2: Sort. We use a Shell-Metzner sort.} + p:=regcount_bsstart; + repeat + for h:=0 to regcount-p-1 do + begin + i:=h; + repeat + j:=i+p; + if gasnames[gas_regname_index[j]]>=gasnames[gas_regname_index[i]] then + break; + t:=gas_regname_index[i]; + gas_regname_index[i]:=gas_regname_index[j]; + gas_regname_index[j]:=t; + if i<p then + break; + dec(i,p); + until false; + end; + p:=p shr 1; + until p=0; +end; + + +procedure read_mipsreg_file; + +var infile:text; + +begin + { open dat file } + assign(infile,'mipsreg.dat'); + reset(infile); + while not(eof(infile)) do + begin + { handle comment } + readln(infile,s); + inc(line); + while (s[1]=' ') do + delete(s,1,1); + if (s='') or (s[1]=';') then + continue; + + i:=1; + names[regcount]:=readstr; + readcomma; + regtypes[regcount]:=readstr; + readcomma; + supregs[regcount]:=readstr; + readcomma; + stdnames[regcount]:=readstr; + readcomma; + gasnames[regcount]:=readstr; + readcomma; + stabs[regcount]:=readstr; + readcomma; + dwarfs[regcount]:=readstr; + { Create register number } + if supregs[regcount][1]<>'$' then + begin + writeln('Missing $ before number, at line ',line); + writeln('Line: "',s,'"'); + halt(1); + end; + numbers[regcount]:=regtypes[regcount]+'0000'+copy(supregs[regcount],2,255); + if i<length(s) then + begin + writeln('Extra chars at end of line, at line ',line); + writeln('Line: "',s,'"'); + halt(1); + end; + inc(regcount); + if regcount>max_regcount then + begin + writeln('Error: Too much registers, please increase maxregcount in source'); + halt(2); + end; + end; + close(infile); +end; + +procedure write_inc_files; + +var + norfile,stdfile,supfile, + numfile,stabfile,confile,gasfile,dwarffile, + rnifile,srifile,mrifile,grifile : text; + first:boolean; + +begin + { create inc files } + openinc(confile,'rmipscon.inc'); + openinc(supfile,'rmipssup.inc'); + openinc(numfile,'rmipsnum.inc'); + openinc(stdfile,'rmipsstd.inc'); + openinc(gasfile,'rmipsgas.inc'); + openinc(stabfile,'rmipssta.inc'); + openinc(dwarffile,'rmipsdwf.inc'); + openinc(norfile,'rmipsnor.inc'); + openinc(rnifile,'rmipsrni.inc'); + openinc(srifile,'rmipssri.inc'); + openinc(grifile,'rmipsgri.inc'); + openinc(mrifile,'rmipsmri.inc'); + first:=true; + for i:=0 to regcount-1 do + begin + if not first then + begin + writeln(numfile,','); + writeln(stdfile,','); + writeln(gasfile,','); + writeln(stabfile,','); + writeln(dwarffile,','); + writeln(rnifile,','); + writeln(srifile,','); + writeln(grifile,','); + writeln(mrifile,','); + end + else + first:=false; + writeln(supfile,'RS_',names[i],' = ',supregs[i],';'); + writeln(confile,'NR_'+names[i],' = ','tregister(',numbers[i],')',';'); + write(numfile,'tregister(',numbers[i],')'); + write(stdfile,'''',stdnames[i],''''); + write(gasfile,'''',gasnames[i],''''); + write(stabfile,stabs[i]); + write(dwarffile,dwarfs[i]); + write(rnifile,regnumber_index[i]); + write(srifile,std_regname_index[i]); + write(grifile,gas_regname_index[i]); + write(mrifile,mot_regname_index[i]); + end; + write(norfile,regcount); + close(confile); + close(supfile); + closeinc(numfile); + closeinc(stdfile); + closeinc(gasfile); + closeinc(stabfile); + closeinc(dwarffile); + closeinc(norfile); + closeinc(rnifile); + closeinc(srifile); + closeinc(grifile); + closeinc(mrifile); + writeln('Done!'); + writeln(regcount,' registers procesed'); +end; + + +begin + writeln('Register Table Converter Version ',Version); + line:=0; + regcount:=0; + read_mipsreg_file; + regcount_bsstart:=1; + while 2*regcount_bsstart<regcount do + regcount_bsstart:=regcount_bsstart*2; + build_regnum_index; + build_std_regname_index; + build_gas_regname_index; + write_inc_files; +end. |