{ Copyright (C) 2022 Loongson Technology Corporation Limited. Convert loongarchins.dat from Nasm to a .inc file 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. **********************************************************************} {$mode objfpc} program mkloongarch64ins; const Version = '1.0'; var insfile,opfile,nopfile,attfile : text; type topcodes = array[1..64] of string; procedure bug(errormsg : string); begin writeln(errormsg); close(insfile); close(opfile); close(nopfile); close(attfile); halt; end; procedure copy_present_opcodes(start,len : longint; var ops : topcodes); var i : longint; begin for i:=start to start+len-1 do ops[i]:=ops[1+i-start]; end; procedure set_suffix(start,len : longint; var ops : topcodes; suffix : string); var i : longint; begin for i:=start to start+len-1 do ops[i]:=ops[i]+suffix; end; function decode_format(format,prefix : string; var ops : topcodes) : longint; var i,j,nr_comma,last_comma,nr_op : longint; suffixs : string; begin nr_op:=1; ops[1]:=prefix; i:=1; while (format[i]<>'0') do begin case format[i] of 'a': suffixs:='W,D'; 'b': suffixs:='W'; 'c': suffixs:='D'; 'd': suffixs:='W,WU,D'; 'e': suffixs:='W,WU,D,DU'; 'f': suffixs:='W,WU'; 'g': suffixs:='B,H'; 'h': suffixs:='2H,4H,2W,D'; 'i': suffixs:='2W,D'; 'j': suffixs:='4B,8B,W,D'; 'k': suffixs:='B,H,W,D'; 'l': suffixs:='BU,HU,WU'; 'm': suffixs:='S,D'; 'n': suffixs:='CAF,CUN,CEQ,CUEQ,CLT,CULT,CUGT,CLE,CULE,CUGE,CNE,COR,CUNE,SAF,SUN,SEQ,SUEQ,SLT,SGT,SULT,SLE,SGE,SULE,SNE,SOR,SUNE'; 'o': suffixs:='S'; 'p': suffixs:='D'; 'q': suffixs:='L,W'; 'r': suffixs:='GLOBAL,LOCAL,ABS,PCREL,GOT,TLE#LE,TLS#IE,TLS#LD,TLS#GD'; else bug('Error Format'); end; i:=i+1; { For each comma, add suffix for present opcodes } nr_comma:=1; last_comma:=length(suffixs)+1; for j:=length(suffixs) downto 0 do begin if (j=0) then set_suffix(1,nr_op,ops,'#'+copy(suffixs,1,last_comma-1)); if (suffixs[j]<>',') then continue; copy_present_opcodes(nr_comma*nr_op+1, nr_op, ops); set_suffix(nr_comma*nr_op+1,nr_op,ops,'#'+copy(suffixs,j+1,last_comma-j-1)); last_comma:=j; nr_comma:=nr_comma+1; end; nr_op:=nr_comma*nr_op; end; result:=nr_op; end; procedure writeop(op : string); var i : longint; s : string; begin for i:=1 to length(op) do if op[i]='#' then s[i]:='_' else s[i]:=op[i]; s[0]:=op[0]; write(opfile, 'A_', s); end; procedure writeatt(op : string); var i : longint; s : string; begin for i:=1 to length(op) do if op[i] in ['A'..'Z'] then s[i]:=char(byte(op[i])+32) else if op[i]='#' then s[i]:='.' else s[i]:=op[i]; s[0]:=op[0]; write(attfile, '''', s, ''''); end; var i,j,all_op,nr_op : longint; s : string; opcode : string; opcodes : topcodes; is_not_first_op : boolean; begin writeln('FPC Instruction Table Converter Version ',Version); assign(insfile,'../loongarch64/loongarchins.dat'); reset(insfile); assign(opfile,'../loongarch64/loongarch64op.inc'); rewrite(opfile); writeln(opfile,'{ don''t edit, this file is generated from loongarchins.dat }'); writeln(opfile,'('); assign(nopfile,'../loongarch64/loongarch64nop.inc'); rewrite(nopfile); writeln(nopfile,'{ don''t edit, this file is generated from loongarchins.dat }'); assign(attfile,'../loongarch64/loongarch64att.inc'); rewrite(attfile); writeln(attfile,'{ don''t edit, this file is generated from loongarchins.dat }'); writeln(attfile,'('); all_op:=0; is_not_first_op:=false; while not(eof(insfile)) do begin readln(insfile,s); if (s='') or (s[1]=';') then continue; if (s[1]<>'[') then continue; i:=pos(']',s); opcode:=copy(s,2,i-2); i:=pos('(',s); j:=pos(')',s); nr_op:=decode_format(copy(s,i+1,j-i-1),opcode,opcodes); for i:=1 to nr_op do begin if is_not_first_op then begin writeln(opfile,','); writeln(attfile,','); end; writeop(opcodes[i]); if opcodes[i]='BXX' then writeatt('B') else writeatt(opcodes[i]); is_not_first_op:=true; end; all_op:=all_op+nr_op; end; writeln(opfile); write(opfile,');'); writeln(attfile); write(attfile,');'); write(nopfile, all_op, ';'); close(insfile); close(opfile); close(nopfile); close(attfile); end.