summaryrefslogtreecommitdiff
path: root/closures/compiler/utils/mkx86ins.pp
diff options
context:
space:
mode:
Diffstat (limited to 'closures/compiler/utils/mkx86ins.pp')
-rw-r--r--closures/compiler/utils/mkx86ins.pp442
1 files changed, 442 insertions, 0 deletions
diff --git a/closures/compiler/utils/mkx86ins.pp b/closures/compiler/utils/mkx86ins.pp
new file mode 100644
index 0000000000..72cbc8b5cb
--- /dev/null
+++ b/closures/compiler/utils/mkx86ins.pp
@@ -0,0 +1,442 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
+
+ Convert i386ins.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 mkx86ins;
+
+const
+ Version = '1.6.0';
+ max_operands = 4;
+var
+ s : string;
+ i : longint;
+ x86_64 : boolean;
+
+ function lower(const s : string) : string;
+ {
+ return lowercased string of s
+ }
+ var
+ i : longint;
+ begin
+ for i:=1 to length(s) do
+ if s[i] in ['A'..'Z'] then
+ lower[i]:=char(byte(s[i])+32)
+ else
+ lower[i]:=s[i];
+ lower[0]:=s[0];
+ end;
+
+ function Replace(var s:string;const s1,s2:string):boolean;
+ var
+ i : longint;
+ begin
+ i:=pos(s1,s);
+ if i>0 then
+ begin
+ Delete(s,i,length(s1));
+ Insert(s2,s,i);
+ Replace:=true;
+ end
+ else
+ Replace:=false;
+ end;
+
+
+function formatop(s:string;allowsizeonly:boolean):string;
+ const
+ replaces=26;
+ replacetab : array[1..replaces,1..2] of string[32]=(
+ (':',' or ot_colon'),
+ ('reg','regnorm'),
+ ('regmem','rm_gpr'),
+ ('rm8','rm_gpr or ot_bits8'),
+ ('rm16','rm_gpr or ot_bits16'),
+ ('rm32','rm_gpr or ot_bits32'),
+ ('rm64','rm_gpr or ot_bits64'),
+ ('rm80','rm_gpr or ot_bits80'),
+ ('mem8','memory or ot_bits8'),
+ ('mem16','memory or ot_bits16'),
+ ('mem32','memory or ot_bits32'),
+ ('mem64','memory or ot_bits64'),
+ ('mem80','memory or ot_bits80'),
+ ('mem','memory'),
+ ('memory_offs','mem_offs'),
+ ('imm8','immediate or ot_bits8'),
+ ('imm16','immediate or ot_bits16'),
+ ('imm32','immediate or ot_bits32'),
+ ('imm64','immediate or ot_bits64'),
+ ('imm80','immediate or ot_bits80'),
+ ('imm','immediate'),
+ ('8','bits8'),
+ ('16','bits16'),
+ ('32','bits32'),
+ ('64','bits64'),
+ ('80','bits80')
+ );
+ var
+ i : longint;
+ begin
+ for i:=1to replaces do
+ begin
+ if s=replacetab[i,1] then
+ begin
+ s:=replacetab[i,2];
+ break;
+ end;
+ end;
+ formatop:=s;
+ end;
+
+
+function readnumber : longint;
+
+ var
+ base : longint;
+ begin
+ result:=0;
+ if s[i]='\' then
+ begin
+ base:=8;
+ inc(i);
+ if s[i]='x' then
+ begin
+ base:=16;
+ inc(i);
+ end;
+ end
+ else
+ base:=10;
+ s[i]:=upcase(s[i]);
+ while s[i] in ['0'..'9','A'..'F'] do
+ begin
+ case s[i] of
+ '0'..'9':
+ result:=result*base+ord(s[i])-ord('0');
+
+ 'A'..'F':
+ result:=result*base+ord(s[i])-ord('A')+10;
+ end;
+ inc(i);
+ end;
+ end;
+
+function tostr(l : longint) : string;
+
+ var
+ hs : string;
+
+ begin
+ str(l,hs);
+ tostr:=hs;
+ end;
+
+function readstr : string;
+
+ begin
+ result:='';
+ while (s[i] in ['0'..'9','A'..'Z','a'..'z','_']) and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ end;
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(out f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from x86ins.dat }');
+ writeln(f,'(');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ writeln(f,');');
+ close(f);
+end;
+
+
+var
+ attsuffix,
+ hs : string;
+ j : longint;
+ firstopcode,
+ first : boolean;
+ maxinfolen,
+ code : byte;
+ insns : longint;
+ attsuffile,propfile,opfile,
+ nopfile,attfile,intfile,
+ infile,insfile : text;
+ { instruction fields }
+ skip : boolean;
+ literalcount,
+ ops : longint;
+ intopcode,
+ attopcode,
+ opcode,
+ codes,
+ flags : string;
+ optypes : array[1..max_operands] of string;
+begin
+ writeln('Nasm Instruction Table Converter Version ',Version);
+ x86_64:=paramstr(1)='x86_64';
+ insns:=0;
+ maxinfolen:=0;
+ { open dat file }
+ assign(infile,'../x86/x86ins.dat');
+ if x86_64 then
+ begin
+ { create inc files }
+ openinc(insfile,'x8664tab.inc');
+ openinc(opfile,'x8664op.inc');
+ assign(nopfile,'x8664nop.inc');
+ openinc(attfile,'x8664att.inc');
+ openinc(attsuffile,'x8664ats.inc');
+ openinc(intfile,'x8664int.inc');
+ openinc(propfile,'x8664pro.inc');
+ end
+ else
+ begin
+ { create inc files }
+ openinc(insfile,'i386tab.inc');
+ openinc(opfile,'i386op.inc');
+ assign(nopfile,'i386nop.inc');
+ openinc(attfile,'i386att.inc');
+ openinc(attsuffile,'i386atts.inc');
+ openinc(intfile,'i386int.inc');
+ openinc(propfile,'i386prop.inc');
+ end;
+ rewrite(nopfile);
+ writeln(nopfile,'{ don''t edit, this file is generated from x86ins.dat }');
+ reset(infile);
+ first:=true;
+ opcode:='';
+ firstopcode:=true;
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+ if (s[1]='[') then
+ begin
+ i:=pos(',',s);
+ j:=pos(']',s);
+ if i=0 then
+ begin
+ opcode:='A_'+Copy(s,2,j-2);
+ intopcode:=Copy(s,2,j-2);
+ { Conditional }
+ if (intopcode[length(intopcode)]='c') and
+ (intopcode[length(intopcode)-1]='c') then
+ dec(byte(intopcode[0]),2);
+ attopcode:=intopcode;
+ attsuffix:='attsufNONE';
+ end
+ else
+ begin
+ opcode:='A_'+Copy(s,2,i-2);
+ intopcode:=Copy(s,2,i-2);
+ { intel conditional }
+ if (intopcode[length(intopcode)]='c') and
+ (intopcode[length(intopcode)-1]='c') then
+ dec(byte(intopcode[0]),2);
+ attopcode:=Copy(s,i+1,j-i-1);
+ { att Suffix }
+ case attopcode[length(attopcode)] of
+ 'X' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufINT';
+ end;
+ 'Y' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufINTdual';
+ end;
+ 'F' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufFPU';
+ end;
+ 'R' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufFPUint';
+ end;
+ else
+ attsuffix:='attsufNONE';
+ end;
+ { att Conditional }
+ if (attopcode[length(attopcode)]='C') and
+ (attopcode[length(attopcode)-1]='C') then
+ dec(byte(attopcode[0]),2);
+ end;
+ intopcode:=Lower(intopcode);
+ attopcode:=Lower(attopcode);
+ if firstopcode then
+ firstopcode:=false
+ else
+ begin
+ writeln(opfile,',');
+ writeln(attfile,',');
+ writeln(attsuffile,',');
+ writeln(intfile,',');
+ writeln(propfile,',');
+ end;
+ write(opfile,opcode);
+ write(intfile,'''',intopcode,'''');
+ write(attfile,'''',attopcode,'''');
+ write(attsuffile,attsuffix);
+ { read the next line which contains the Change options }
+ repeat
+ readln(infile,s);
+ until eof(infile) or ((s<>'') and (s[1]<>';'));
+ write(propfile,'(Ch: ',s,')');
+ continue;
+ end;
+ { we must have an opcode }
+ if opcode='' then
+ runerror(234);
+ { clear }
+ ops:=0;
+ for i:=low(optypes) to high(optypes) do
+ optypes[i]:='';
+ codes:='';
+ flags:='';
+ skip:=false;
+ { ops and optypes }
+ i:=1;
+ repeat
+ hs:=readstr;
+ if (hs='void') or (hs='ignore') then
+ break;
+ inc(ops);
+ optypes[ops]:=optypes[ops]+'ot_'+formatop(hs,false);
+ while s[i]='|' do
+ begin
+ inc(i);
+ optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr,true);
+ end;
+ if s[i] in [',',':'] then
+ inc(i)
+ else
+ break;
+ until false;
+ for j:=1 to max_operands-ops do
+ optypes[max_operands-j+1]:='ot_none';
+ { codes }
+ skipspace;
+ j:=0;
+ literalcount:=0;
+ if s[i] in ['\','0'..'9'] then
+ begin
+ while not(s[i] in [' ',#9]) do
+ begin
+ code:=readnumber;
+ { for some codes we want also to change the optypes, but not
+ if the code belongs to a literal sequence }
+ if (literalcount=0) and (code>=1) and (code<=3) then
+ literalcount:=code
+ else
+ begin
+ if literalcount>0 then
+ dec(literalcount)
+ else
+ begin
+ case code of
+ 12,13,14 :
+ optypes[code-11]:=optypes[code-11]+' or ot_signed';
+ end;
+ end;
+ end;
+ codes:=codes+'#'+tostr(code);
+ inc(j);
+ end;
+ end
+ else
+ begin
+ readstr;
+ codes:='#0';
+ end;
+ if j>maxinfolen then
+ maxinfolen:=j;
+ { flags }
+ skipspace;
+ while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
+ begin
+ hs:=readstr;
+ if x86_64 then
+ begin
+ if (upcase(hs)='NOX86_64') then
+ skip:=true;
+ end
+ else
+ begin
+ if (upcase(hs)='X86_64') then
+ skip:=true;
+ end;
+ if hs<>'ND' then
+ begin
+ if flags<>'' then
+ flags:=flags+' or ';
+ flags:=flags+'if_'+lower(hs);
+ end;
+ if (s[i]=',') and (i<=length(s)) then
+ inc(i)
+ else
+ break;
+ end;
+ { write instruction }
+ if not skip then
+ begin
+ if not(first) then
+ writeln(insfile,',')
+ else
+ first:=false;
+ writeln(insfile,' (');
+ writeln(insfile,' opcode : ',opcode,';');
+ writeln(insfile,' ops : ',ops,';');
+ writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
+ writeln(insfile,' code : ',codes,';');
+ writeln(insfile,' flags : ',flags);
+ write(insfile,' )');
+ inc(insns);
+ end;
+ end;
+ close(infile);
+ closeinc(insfile);
+ closeinc(intfile);
+ closeinc(attfile);
+ closeinc(attsuffile);
+ closeinc(opfile);
+ writeln(nopfile,insns,';');
+ close(nopfile);
+ closeinc(propfile);
+ writeln(insns,' nodes processed (maxinfolen=',maxinfolen,')');
+end.