mkloongarch64ins.pp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. {
  2. Copyright (C) 2022 Loongson Technology Corporation Limited.
  3. Convert loongarchins.dat from Nasm to a .inc file 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. program mkloongarch64ins;
  13. const
  14. Version = '1.0';
  15. var
  16. insfile,opfile,nopfile,attfile : text;
  17. type
  18. topcodes = array[1..64] of string;
  19. procedure bug(errormsg : string);
  20. begin
  21. writeln(errormsg);
  22. close(insfile);
  23. close(opfile);
  24. close(nopfile);
  25. close(attfile);
  26. halt;
  27. end;
  28. procedure copy_present_opcodes(start,len : longint; var ops : topcodes);
  29. var
  30. i : longint;
  31. begin
  32. for i:=start to start+len-1 do
  33. ops[i]:=ops[1+i-start];
  34. end;
  35. procedure set_suffix(start,len : longint; var ops : topcodes; suffix : string);
  36. var
  37. i : longint;
  38. begin
  39. for i:=start to start+len-1 do
  40. ops[i]:=ops[i]+suffix;
  41. end;
  42. function decode_format(format,prefix : string; var ops : topcodes) : longint;
  43. var
  44. i,j,nr_comma,last_comma,nr_op : longint;
  45. suffixs : string;
  46. begin
  47. nr_op:=1;
  48. ops[1]:=prefix;
  49. i:=1;
  50. while (format[i]<>'0') do
  51. begin
  52. case format[i] of
  53. 'a': suffixs:='W,D';
  54. 'b': suffixs:='W';
  55. 'c': suffixs:='D';
  56. 'd': suffixs:='W,WU,D';
  57. 'e': suffixs:='W,WU,D,DU';
  58. 'f': suffixs:='W,WU';
  59. 'g': suffixs:='B,H';
  60. 'h': suffixs:='2H,4H,2W,D';
  61. 'i': suffixs:='2W,D';
  62. 'j': suffixs:='4B,8B,W,D';
  63. 'k': suffixs:='B,H,W,D';
  64. 'l': suffixs:='BU,HU,WU';
  65. 'm': suffixs:='S,D';
  66. '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';
  67. 'o': suffixs:='S';
  68. 'p': suffixs:='D';
  69. 'q': suffixs:='L,W';
  70. 'r': suffixs:='GLOBAL,LOCAL,ABS,PCREL,GOT,TLE#LE,TLS#IE,TLS#LD,TLS#GD';
  71. else
  72. bug('Error Format');
  73. end;
  74. i:=i+1;
  75. { For each comma, add suffix for present opcodes }
  76. nr_comma:=1;
  77. last_comma:=length(suffixs)+1;
  78. for j:=length(suffixs) downto 0 do
  79. begin
  80. if (j=0) then
  81. set_suffix(1,nr_op,ops,'#'+copy(suffixs,1,last_comma-1));
  82. if (suffixs[j]<>',') then
  83. continue;
  84. copy_present_opcodes(nr_comma*nr_op+1, nr_op, ops);
  85. set_suffix(nr_comma*nr_op+1,nr_op,ops,'#'+copy(suffixs,j+1,last_comma-j-1));
  86. last_comma:=j;
  87. nr_comma:=nr_comma+1;
  88. end;
  89. nr_op:=nr_comma*nr_op;
  90. end;
  91. result:=nr_op;
  92. end;
  93. procedure writeop(op : string);
  94. var
  95. i : longint;
  96. s : string;
  97. begin
  98. for i:=1 to length(op) do
  99. if op[i]='#' then
  100. s[i]:='_'
  101. else
  102. s[i]:=op[i];
  103. s[0]:=op[0];
  104. write(opfile, 'A_', s);
  105. end;
  106. procedure writeatt(op : string);
  107. var
  108. i : longint;
  109. s : string;
  110. begin
  111. for i:=1 to length(op) do
  112. if op[i] in ['A'..'Z'] then
  113. s[i]:=char(byte(op[i])+32)
  114. else if op[i]='#' then
  115. s[i]:='.'
  116. else
  117. s[i]:=op[i];
  118. s[0]:=op[0];
  119. write(attfile, '''', s, '''');
  120. end;
  121. var
  122. i,j,all_op,nr_op : longint;
  123. s : string;
  124. opcode : string;
  125. opcodes : topcodes;
  126. is_not_first_op : boolean;
  127. begin
  128. writeln('FPC Instruction Table Converter Version ',Version);
  129. assign(insfile,'../loongarch64/loongarchins.dat');
  130. reset(insfile);
  131. assign(opfile,'../loongarch64/loongarch64op.inc');
  132. rewrite(opfile);
  133. writeln(opfile,'{ don''t edit, this file is generated from loongarchins.dat }');
  134. writeln(opfile,'(');
  135. assign(nopfile,'../loongarch64/loongarch64nop.inc');
  136. rewrite(nopfile);
  137. writeln(nopfile,'{ don''t edit, this file is generated from loongarchins.dat }');
  138. assign(attfile,'../loongarch64/loongarch64att.inc');
  139. rewrite(attfile);
  140. writeln(attfile,'{ don''t edit, this file is generated from loongarchins.dat }');
  141. writeln(attfile,'(');
  142. all_op:=0;
  143. is_not_first_op:=false;
  144. while not(eof(insfile)) do
  145. begin
  146. readln(insfile,s);
  147. if (s='') or (s[1]=';') then
  148. continue;
  149. if (s[1]<>'[') then
  150. continue;
  151. i:=pos(']',s);
  152. opcode:=copy(s,2,i-2);
  153. i:=pos('(',s);
  154. j:=pos(')',s);
  155. nr_op:=decode_format(copy(s,i+1,j-i-1),opcode,opcodes);
  156. for i:=1 to nr_op do
  157. begin
  158. if is_not_first_op then
  159. begin
  160. writeln(opfile,',');
  161. writeln(attfile,',');
  162. end;
  163. writeop(opcodes[i]);
  164. if opcodes[i]='BXX' then
  165. writeatt('B')
  166. else
  167. writeatt(opcodes[i]);
  168. is_not_first_op:=true;
  169. end;
  170. all_op:=all_op+nr_op;
  171. end;
  172. writeln(opfile);
  173. write(opfile,');');
  174. writeln(attfile);
  175. write(attfile,');');
  176. write(nopfile, all_op, ';');
  177. close(insfile);
  178. close(opfile);
  179. close(nopfile);
  180. close(attfile);
  181. end.