mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 13:39:39 +01:00 
			
		
		
		
	http://svn.freepascal.org/svn/fpc/branches/linker/compiler ........ r2908 | peter | 2006-03-13 13:35:48 +0100 (Mon, 13 Mar 2006) | 2 lines * merge trunk upto r2907 ........ r2911 | peter | 2006-03-13 18:08:00 +0100 (Mon, 13 Mar 2006) | 2 lines * rename values to make room for operand size codes ........ ........ ........ r2915 | peter | 2006-03-14 13:51:35 +0100 (Tue, 14 Mar 2006) | 2 lines * check aktcputype ........ r2916 | peter | 2006-03-14 15:06:32 +0100 (Tue, 14 Mar 2006) | 3 lines * merge 300 opcodes * more 64bit versions of opcodes ........ r2917 | peter | 2006-03-14 17:34:03 +0100 (Tue, 14 Mar 2006) | 3 lines * x86_64 tables * convert movq with normal registers to mov ........ git-svn-id: trunk@2931 -
		
			
				
	
	
		
			440 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			440 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    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.
 | 
						|
 | 
						|
 **********************************************************************}
 | 
						|
program mkx86ins;
 | 
						|
 | 
						|
const
 | 
						|
  Version = '1.5.1';
 | 
						|
 | 
						|
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','regmem'),
 | 
						|
       ('rm8','regmem or ot_bits8'),
 | 
						|
       ('rm16','regmem or ot_bits16'),
 | 
						|
       ('rm32','regmem or ot_bits32'),
 | 
						|
       ('rm64','regmem or ot_bits64'),
 | 
						|
       ('rm80','regmem 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;
 | 
						|
     result : 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;
 | 
						|
     readnumber:=result;
 | 
						|
  end;
 | 
						|
 | 
						|
function tostr(l : longint) : string;
 | 
						|
 | 
						|
  var
 | 
						|
     hs : string;
 | 
						|
 | 
						|
  begin
 | 
						|
     str(l,hs);
 | 
						|
     tostr:=hs;
 | 
						|
  end;
 | 
						|
 | 
						|
function readstr : string;
 | 
						|
 | 
						|
  var
 | 
						|
     result : 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;
 | 
						|
     readstr:=result;
 | 
						|
  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 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;
 | 
						|
   last,
 | 
						|
   ops    : longint;
 | 
						|
   intopcode,
 | 
						|
   attopcode,
 | 
						|
   opcode,
 | 
						|
   codes,
 | 
						|
   flags   : string;
 | 
						|
   optypes : array[1..3] 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;
 | 
						|
                '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;
 | 
						|
        optypes[1]:='';
 | 
						|
        optypes[2]:='';
 | 
						|
        optypes[3]:='';
 | 
						|
        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 3-ops do
 | 
						|
          optypes[3-j+1]:='ot_none';
 | 
						|
        { codes }
 | 
						|
        skipspace;
 | 
						|
        j:=0;
 | 
						|
        last:=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 last byte was a 1 then this byte belongs to a direct
 | 
						|
                   copy }
 | 
						|
                 if last<>1 then
 | 
						|
                  begin
 | 
						|
                    case code of
 | 
						|
                      12,13,14 :
 | 
						|
                        optypes[code-11]:=optypes[code-11]+' or ot_signed';
 | 
						|
                    end;
 | 
						|
                  end;
 | 
						|
                 codes:=codes+'#'+tostr(code);
 | 
						|
                 last:=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],');');
 | 
						|
            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 procesed (maxinfolen=',maxinfolen,')');
 | 
						|
end.
 |