Browse Source

- removed i386asm.pas and i386base.pas

florian 26 years ago
parent
commit
defd66af97
2 changed files with 0 additions and 2718 deletions
  1. 0 1630
      compiler/i386asm.pas
  2. 0 1088
      compiler/i386base.pas

+ 0 - 1630
compiler/i386asm.pas

@@ -1,1630 +0,0 @@
-{
-    $Id$
-    Copyright (c) 1999 by Florian Klaempfl
-
-    Contains the assembler object for the i386
-
-    * This code was inspired by the NASM sources
-      The Netwide Assembler is copyright (C) 1996 Simon Tatham and
-      Julian Hall. All rights reserved.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    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.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit i386asm;
-interface
-
-uses
-  cobjects,
-  aasm,globals,verbose,
-  i386base;
-
-{$ifndef NASMDEBUG}
-  {$define OPTEA}
-  {$define PASS2FLAG}
-{$endif ndef NASMDEBUG}
-
-{$ifndef TP}
-  {$define ASMDEBUG}
-{$endif}
-
-const
-  MaxPrefixes=4;
-
-type
-  pairegalloc = ^tairegalloc;
-  tairegalloc = object(tai)
-     allocation : boolean;
-     reg        : tregister;
-     constructor alloc(r : tregister);
-     constructor dealloc(r : tregister);
-  end;
-
-
-  pai386 = ^tai386;
-  tai386 = object(tai)
-     is_jmp    : boolean; { is this instruction a jump? (needed for optimizer) }
-     opcode    : tasmop;
-     opsize    : topsize;
-     condition : TAsmCond;
-     ops       : longint;
-     oper      : array[0..2] of toper;
-     constructor op_none(op : tasmop;_size : topsize);
-
-     constructor op_reg(op : tasmop;_size : topsize;_op1 : tregister);
-     constructor op_const(op : tasmop;_size : topsize;_op1 : longint);
-     constructor op_ref(op : tasmop;_size : topsize;_op1 : preference);
-
-     constructor op_reg_reg(op : tasmop;_size : topsize;_op1,_op2 : tregister);
-     constructor op_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;_op2 : preference);
-     constructor op_reg_const(op:tasmop; _size: topsize; _op1: tregister; _op2: longint);
-
-     constructor op_const_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister);
-     constructor op_const_const(op : tasmop;_size : topsize;_op1,_op2 : longint);
-     constructor op_const_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : preference);
-
-     constructor op_ref_reg(op : tasmop;_size : topsize;_op1 : preference;_op2 : tregister);
-     { this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
-     constructor op_ref_ref(op : tasmop;_size : topsize;_op1,_op2 : preference);
-
-     constructor op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
-     constructor op_const_reg_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : tregister);
-     constructor op_const_ref_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : preference;_op3 : tregister);
-     constructor op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister; _op3 : preference);
-     constructor op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : preference);
-
-     { this is for Jmp instructions }
-     constructor op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : pasmsymbol);
-
-     constructor op_sym(op : tasmop;_size : topsize;_op1 : pasmsymbol);
-     constructor op_sym_ofs(op : tasmop;_size : topsize;_op1 : pasmsymbol;_op1ofs:longint);
-     constructor op_sym_ofs_reg(op : tasmop;_size : topsize;_op1 : pasmsymbol;_op1ofs:longint;_op2 : tregister);
-     constructor op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : pasmsymbol;_op1ofs:longint;_op2 : preference);
-
-     procedure loadconst(opidx:longint;l:longint);
-     procedure loadsymbol(opidx:longint;s:pasmsymbol;sofs:longint);
-     procedure loadref(opidx:longint;p:preference);
-     procedure loadreg(opidx:longint;r:tregister);
-     procedure loadoper(opidx:longint;o:toper);
-     procedure changeopsize(siz:topsize);
-     procedure SetCondition(c:TAsmCond);
-
-     destructor done;virtual;
-     function  getcopy:plinkedlist_item;virtual;
-     function  GetString:string;
-     procedure SwapOperands;
-  private
-     segprefix : tregister;
-     procedure init(op : tasmop;_size : topsize); { this need to be called by all constructor }
-{$ifndef NOAG386BIN}
-  public
-     function  Pass1(offset:longint):longint;virtual;
-     procedure Pass2;virtual;
-  private
-     { next fields are filled in pass1, so pass2 is faster }
-     insentry  : PInsEntry;
-     LastInsOffset,
-     insoffset,
-     inssize   : longint;
-     function  InsEnd:longint;
-     procedure create_ot;
-     function  Matches(p:PInsEntry):longint;
-     function  calcsize(p:PInsEntry):longint;
-     procedure gencode;
-     function  NeedAddrPrefix(opidx:byte):boolean;
-{$endif NOAG386BIN}
-  end;
-
-
-implementation
-uses
-  og386;
-
-{*****************************************************************************
-                                 TaiRegAlloc
-*****************************************************************************}
-
-    constructor tairegalloc.alloc(r : tregister);
-      begin
-        inherited init;
-        typ:=ait_regalloc;
-        allocation:=true;
-        reg:=r;
-      end;
-
-
-    constructor tairegalloc.dealloc(r : tregister);
-      begin
-        inherited init;
-        typ:=ait_regalloc;
-        allocation:=false;
-        reg:=r;
-      end;
-
-
-{*****************************************************************************
-                                 Tai386 Constructors
-*****************************************************************************}
-
-    procedure tai386.loadconst(opidx:longint;l:longint);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        with oper[opidx] do
-         begin
-           if typ=top_ref then
-            disposereference(ref);
-           val:=l;
-           typ:=top_const;
-         end;
-      end;
-
-    procedure tai386.loadsymbol(opidx:longint;s:pasmsymbol;sofs:longint);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        with oper[opidx] do
-         begin
-           if typ=top_ref then
-            disposereference(ref);
-           sym:=s;
-           symofs:=sofs;
-           typ:=top_symbol;
-         end;
-        { Mark the symbol as used }
-        if assigned(s) then
-         inc(s^.refs);
-      end;
-
-    procedure tai386.loadref(opidx:longint;p:preference);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        with oper[opidx] do
-         begin
-           if typ=top_ref then
-            disposereference(ref);
-           if p^.is_immediate then
-             begin
-{$ifdef ASMDEBUG1}
-               Comment(V_Warning,'Reference immediate');
-{$endif}
-               val:=p^.offset;
-               disposereference(p);
-               typ:=top_const;
-             end
-           else
-             begin
-               ref:=p;
-               if not(ref^.segment in [R_DS,R_NO]) then
-                 segprefix:=ref^.segment;
-               typ:=top_ref;
-               { mark symbol as used }
-               if assigned(ref^.symbol) then
-                 inc(ref^.symbol^.refs);
-             end;
-         end;
-      end;
-
-    procedure tai386.loadreg(opidx:longint;r:tregister);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        with oper[opidx] do
-         begin
-           if typ=top_ref then
-            disposereference(ref);
-           reg:=r;
-           typ:=top_reg;
-         end;
-      end;
-
-    procedure tai386.loadoper(opidx:longint;o:toper);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        if oper[opidx].typ=top_ref then
-          disposereference(oper[opidx].ref);
-        oper[opidx]:=o;
-        { copy also the reference }
-        if oper[opidx].typ=top_ref then
-         oper[opidx].ref:=newreference(o.ref^);
-      end;
-
-
-    procedure tai386.changeopsize(siz:topsize);
-      begin
-        opsize:=siz;
-      end;
-
-
-    procedure tai386.init(op : tasmop;_size : topsize);
-      begin
-         typ:=ait_instruction;
-         is_jmp:=false;
-         segprefix:=R_NO;
-         opcode:=op;
-         opsize:=_size;
-         ops:=0;
-         condition:=c_none;
-         fillchar(oper,sizeof(oper),0);
-{$ifndef NOAG386BIN}
-         insentry:=nil;
-         LastInsOffset:=-1;
-         InsOffset:=0;
-{$endif}
-      end;
-
-    constructor tai386.op_none(op : tasmop;_size : topsize);
-      begin
-         inherited init;
-         init(op,_size);
-      end;
-
-
-    constructor tai386.op_reg(op : tasmop;_size : topsize;_op1 : tregister);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=1;
-         loadreg(0,_op1);
-      end;
-
-
-    constructor tai386.op_const(op : tasmop;_size : topsize;_op1 : longint);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=1;
-         loadconst(0,_op1);
-      end;
-
-
-    constructor tai386.op_ref(op : tasmop;_size : topsize;_op1 : preference);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=1;
-         loadref(0,_op1);
-      end;
-
-
-    constructor tai386.op_reg_reg(op : tasmop;_size : topsize;_op1,_op2 : tregister);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadreg(0,_op1);
-         loadreg(1,_op2);
-      end;
-
-
-    constructor tai386.op_reg_const(op:tasmop; _size: topsize; _op1: tregister; _op2: longint);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadreg(0,_op1);
-         loadconst(1,_op2);
-      end;
-
-
-    constructor tai386.op_reg_ref(op : tasmop;_size : topsize;_op1 : tregister;_op2 : preference);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadreg(0,_op1);
-         loadref(1,_op2);
-      end;
-
-
-    constructor tai386.op_const_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadconst(0,_op1);
-         loadreg(1,_op2);
-      end;
-
-
-    constructor tai386.op_const_const(op : tasmop;_size : topsize;_op1,_op2 : longint);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadconst(0,_op1);
-         loadconst(1,_op2);
-      end;
-
-
-    constructor tai386.op_const_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : preference);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadconst(0,_op1);
-         loadref(1,_op2);
-      end;
-
-    constructor tai386.op_ref_reg(op : tasmop;_size : topsize;_op1 : preference;_op2 : tregister);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadref(0,_op1);
-         loadreg(1,_op2);
-      end;
-
-
-    constructor tai386.op_ref_ref(op : tasmop;_size : topsize;_op1,_op2 : preference);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadref(0,_op1);
-         loadref(1,_op2);
-      end;
-
-
-    constructor tai386.op_reg_reg_reg(op : tasmop;_size : topsize;_op1,_op2,_op3 : tregister);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=3;
-         loadreg(0,_op1);
-         loadreg(1,_op2);
-         loadreg(2,_op3);
-      end;
-
-    constructor tai386.op_const_reg_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : tregister);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=3;
-         loadconst(0,_op1);
-         loadreg(1,_op2);
-         loadreg(2,_op3);
-      end;
-
-     constructor tai386.op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister;_op3 : preference);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=3;
-         loadreg(0,_op1);
-         loadreg(1,_op2);
-         loadref(2,_op3);
-      end;
-
-     constructor tai386.op_const_ref_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : preference;_op3 : tregister);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=3;
-         loadconst(0,_op1);
-         loadref(1,_op2);
-         loadreg(2,_op3);
-      end;
-
-     constructor tai386.op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : preference);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=3;
-         loadconst(0,_op1);
-         loadreg(1,_op2);
-         loadref(2,_op3);
-      end;
-
-
-    constructor tai386.op_cond_sym(op : tasmop;cond:TAsmCond;_size : topsize;_op1 : pasmsymbol);
-      begin
-         inherited init;
-         init(op,_size);
-         condition:=cond;
-         ops:=1;
-         loadsymbol(0,_op1,0);
-      end;
-
-
-    constructor tai386.op_sym(op : tasmop;_size : topsize;_op1 : pasmsymbol);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=1;
-         loadsymbol(0,_op1,0);
-      end;
-
-
-    constructor tai386.op_sym_ofs(op : tasmop;_size : topsize;_op1 : pasmsymbol;_op1ofs:longint);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=1;
-         loadsymbol(0,_op1,_op1ofs);
-      end;
-
-
-    constructor tai386.op_sym_ofs_reg(op : tasmop;_size : topsize;_op1 : pasmsymbol;_op1ofs:longint;_op2 : tregister);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadsymbol(0,_op1,_op1ofs);
-         loadreg(1,_op2);
-      end;
-
-
-    constructor tai386.op_sym_ofs_ref(op : tasmop;_size : topsize;_op1 : pasmsymbol;_op1ofs:longint;_op2 : preference);
-      begin
-         inherited init;
-         init(op,_size);
-         ops:=2;
-         loadsymbol(0,_op1,_op1ofs);
-         loadref(1,_op2);
-      end;
-
-    destructor tai386.done;
-      var
-        i : longint;
-      begin
-{$ifndef nojmpfix}
-        if is_jmp then
-          dec(PasmLabel(oper[0].sym)^.refs)
-        else
-{$endif nojmpfix}
-          for i:=1 to ops do
-            if (oper[i-1].typ=top_ref) then
-              dispose(oper[i-1].ref);
-        inherited done;
-      end;
-
-    function tai386.getcopy:plinkedlist_item;
-      var
-        i : longint;
-        p : plinkedlist_item;
-      begin
-        p:=inherited getcopy;
-        { make a copy of the references }
-        for i:=1 to ops do
-         if (pai386(p)^.oper[i-1].typ=top_ref) then
-          begin
-            new(pai386(p)^.oper[i-1].ref);
-            pai386(p)^.oper[i-1].ref^:=oper[i-1].ref^;
-          end;
-        getcopy:=p;
-      end;
-
-
-    procedure tai386.SetCondition(c:TAsmCond);
-      begin
-         condition:=c;
-      end;
-
-
-    function tai386.GetString:string;
-{$ifdef ASMDEBUG}
-      var
-        i : longint;
-        s : string;
-{$endif}
-      begin
-{$ifdef ASMDEBUG}
-        s:='['+int_op2str[opcode];
-        for i:=1to ops do
-         begin
-           if i=1 then
-            s:=s+' '
-           else
-            s:=s+',';
-           { type }
-           if (oper[i-1].ot and OT_REGISTER)<>0 then
-             s:=s+'reg'
-           else
-            if (oper[i-1].ot and OT_IMMEDIATE)<>0 then
-             s:=s+'imm'
-           else
-            if (oper[i-1].ot and OT_MEMORY)<>0 then
-             s:=s+'mem'
-           else
-             s:=s+'???';
-           { size }
-           if (oper[i-1].ot and OT_BITS8)<>0 then
-             s:=s+'8'
-           else
-            if (oper[i-1].ot and OT_BITS16)<>0 then
-             s:=s+'16'
-           else
-            if (oper[i-1].ot and OT_BITS32)<>0 then
-             s:=s+'32'
-           else
-             s:=s+'??';
-           { signed }
-           if (oper[i-1].ot and OT_SIGNED)<>0 then
-             s:=s+'s';
-         end;
-        GetString:=s+']';
-{$else}
-        GetString:='';
-{$endif ASMDEBUG}
-      end;
-
-
-procedure tai386.SwapOperands;
-var
-  p : TOper;
-begin
-  { Fix the operands which are in AT&T style and we need them in Intel style }
-  case ops of
-    2 : begin
-          { 0,1 -> 1,0 }
-          p:=oper[0];
-          oper[0]:=oper[1];
-          oper[1]:=p;
-        end;
-    3 : begin
-          { 0,1,2 -> 2,1,0 }
-          p:=oper[0];
-          oper[0]:=oper[2];
-          oper[2]:=p;
-        end;
-  end;
-end;
-
-
-{*****************************************************************************
-                                Assembler
-*****************************************************************************}
-
-{$ifndef NOAG386BIN}
-
-type
-  ea=packed record
-    sib_present : boolean;
-    bytes : byte;
-    size  : byte;
-    modrm : byte;
-    sib   : byte;
-  end;
-
-procedure tai386.create_ot;
-{
-  this function will also fix some other fields which only needs to be once
-}
-var
-  i,l,relsize : longint;
-begin
-  if ops=0 then
-   exit;
-  { update oper[].ot field }
-  for i:=0 to ops-1 do
-   with oper[i] do
-    begin
-      case typ of
-        top_reg :
-          ot:=reg_2_type[reg];
-        top_ref :
-          begin
-          { create ot field }
-            ot:=OT_MEMORY or opsize_2_type[i,opsize];
-            if (ref^.base=R_NO) and (ref^.index=R_NO) then
-              ot:=ot or OT_MEM_OFFS;
-          { handle also the offsetfixup }
-            inc(ref^.offset,ref^.offsetfixup);
-            ref^.offsetfixup:=0;
-          { fix scalefactor }
-            if (ref^.index=R_NO) then
-             ref^.scalefactor:=0
-            else
-             if (ref^.scalefactor=0) then
-              ref^.scalefactor:=1;
-          end;
-        top_const :
-          begin
-            if (opsize<>S_W) and (val>=-128) and (val<=127) then
-              ot:=OT_IMM8 or OT_SIGNED
-            else
-              ot:=OT_IMMEDIATE or opsize_2_type[i,opsize];
-          end;
-        top_symbol :
-          begin
-            if LastInsOffset=-1 then
-             l:=0
-            else
-             l:=InsOffset-LastInsOffset;
-            inc(l,symofs);
-            if assigned(sym) then
-             inc(l,sym^.address);
-            { instruction size will then always become 2 (PFV) }
-            relsize:=InsOffset+2-l;
-            if (not assigned(sym) or
-                ((sym^.typ<>AS_EXTERNAL) and (sym^.address<>0))) and
-               (relsize>=-128) and (relsize<=127) then
-             ot:=OT_IMM32 or OT_SHORT
-            else
-             ot:=OT_IMM32 or OT_NEAR;
-          end;
-      end;
-    end;
-end;
-
-
-function tai386.InsEnd:longint;
-begin
-  InsEnd:=InsOffset+InsSize;
-end;
-
-
-function tai386.Matches(p:PInsEntry):longint;
-{ * IF_SM stands for Size Match: any operand whose size is not
- * explicitly specified by the template is `really' intended to be
- * the same size as the first size-specified operand.
- * Non-specification is tolerated in the input instruction, but
- * _wrong_ specification is not.
- *
- * IF_SM2 invokes Size Match on only the first _two_ operands, for
- * three-operand instructions such as SHLD: it implies that the
- * first two operands must match in size, but that the third is
- * required to be _unspecified_.
- *
- * IF_SB invokes Size Byte: operands with unspecified size in the
- * template are really bytes, and so no non-byte specification in
- * the input instruction will be tolerated. IF_SW similarly invokes
- * Size Word, and IF_SD invokes Size Doubleword.
- *
- * (The default state if neither IF_SM nor IF_SM2 is specified is
- * that any operand with unspecified size in the template is
- * required to have unspecified size in the instruction too...)
-}
-var
-  i,siz,oprs : longint;
-begin
-  Matches:=100;
-
-  { Check the opcode and operands }
-  if (p^.opcode<>opcode) or (p^.ops<>ops) then
-   begin
-     Matches:=0;
-     exit;
-   end;
-
-  { Check that no spurious colons or TOs are present }
-  for i:=0 to p^.ops-1 do
-   if (oper[i].ot and (not p^.optypes[i]) and (OT_COLON or OT_TO))<>0 then
-    begin
-      Matches:=0;
-      exit;
-    end;
-
-  { Check that the operand flags all match up }
-  for i:=0 to p^.ops-1 do
-   begin
-     if (p^.optypes[i] and (not oper[i].ot) or
-         ((p^.optypes[i] and OT_SIZE_MASK) and
-          ((p^.optypes[i] xor oper[i].ot) and OT_SIZE_MASK)))<>0 then
-      begin
-        if ((p^.optypes[i] and (not oper[i].ot) and OT_NON_SIZE) or
-            (oper[i].ot and OT_SIZE_MASK))<>0 then
-         begin
-           Matches:=0;
-           exit;
-         end
-        else
-         Matches:=1;
-      end;
-   end;
-
-{ Check operand sizes }
-  { as default an untyped size can get all the sizes, this is different
-    from nasm, but else we need to do a lot checking which opcodes want
-    size or not with the automatic size generation }
-  siz:=$ffffffff;
-  if (p^.flags and IF_SB)<>0 then
-    siz:=OT_BITS8
-  else if (p^.flags and IF_SW)<>0 then
-    siz:=OT_BITS16
-  else if (p^.flags and IF_SD)<>0 then
-    siz:=OT_BITS32
-  else if (p^.flags and (IF_SM or IF_SM2))<>0 then
-   begin
-     if (p^.flags and IF_SM2)<>0 then
-      oprs:=2
-     else
-      oprs:=p^.ops;
-     for i:=0 to oprs-1 do
-      if ((p^.optypes[i] and OT_SIZE_MASK) <> 0) then
-       begin
-         siz:=p^.optypes[i] and OT_SIZE_MASK;
-         break;
-       end;
-    end;
-
-  { Check operand sizes }
-  for i:=0to p^.ops-1 do
-   begin
-     if ((p^.optypes[i] and OT_SIZE_MASK)=0) and
-        ((oper[i].ot and OT_SIZE_MASK and (not siz))<>0) and
-        { Immediates can always include smaller size }
-        ((oper[i].ot and OT_IMMEDIATE)=0) and
-         (((p^.optypes[i] and OT_SIZE_MASK) or siz)<(oper[i].ot and OT_SIZE_MASK)) then
-      Matches:=2;
-   end;
-end;
-
-
-function tai386.Pass1(offset:longint):longint;
-var
-  m,i,size_prob : longint;
-begin
-  Pass1:=0;
-{ Save the old offset and set the new offset }
-  InsOffset:=Offset;
-{ Things which may only be done once, not when a second pass is done to
-  optimize }
-  if Insentry=nil then
-   begin
-     { Check if error last time then InsSize=-1 }
-     if InsSize=-1 then
-      exit;
-     { We need intel style operands }
-     SwapOperands;
-     { create the .ot fields }
-     create_ot;
-     { set the file postion }
-     aktfilepos:=fileinfo;
-   end
-  else
-   begin
-{$ifdef PASS2FLAG}
-     { we are here in a second pass, check if the instruction can be optimized }
-     if (InsEntry^.flags and IF_PASS2)=0 then
-      begin
-        Pass1:=InsSize;
-        exit;
-      end;
-     { update the .ot fields, some top_const can be updated }
-     create_ot;
-{$endif}
-   end;
-{ Lookup opcode in the table }
-  InsSize:=-1;
-  size_prob:=0;
-  i:=instabcache^[opcode];
-  if i=-1 then
-   begin
-{$ifdef TP}
-     Message1(asmw_e_opcode_not_in_table,'');
-{$else}
-     Message1(asmw_e_opcode_not_in_table,att_op2str[opcode]);
-{$endif}
-     exit;
-   end;
-  insentry:=@instab[i];
-  while (insentry^.opcode=opcode) do
-   begin
-     m:=matches(insentry);
-     if m=100 then
-      begin
-        InsSize:=calcsize(insentry);
-        if (segprefix<>R_NO) then
-         inc(InsSize);
-        Pass1:=InsSize;
-        LastInsOffset:=InsOffset;
-        exit;
-      end;
-     inc(i);
-     insentry:=@instab[i];
-   end;
-  if insentry^.opcode<>opcode then
-   Message1(asmw_e_invalid_opcode_and_operands,GetString);
-{ No instruction found, set insentry to nil and inssize to -1 }
-  insentry:=nil;
-  inssize:=-1;
-  LastInsOffset:=-1;
-end;
-
-
-procedure tai386.Pass2;
-var
-  c : longint;
-begin
-  { error in pass1 ? }
-  if insentry=nil then
-   exit;
-  aktfilepos:=fileinfo;
-  { Segment override }
-  if (segprefix<>R_NO) then
-   begin
-     case segprefix of
-       R_CS : c:=$2e;
-       R_DS : c:=$3e;
-       R_ES : c:=$26;
-       R_FS : c:=$64;
-       R_GS : c:=$65;
-       R_SS : c:=$36;
-     end;
-     objectoutput^.writebytes(c,1);
-     { fix the offset for GenNode }
-     inc(InsOffset);
-   end;
-  { Generate the instruction }
-  GenCode;
-end;
-
-
-function tai386.NeedAddrPrefix(opidx:byte):boolean;
-var
-  i,b : tregister;
-begin
-  if (OT_MEMORY and (not oper[opidx].ot))=0 then
-   begin
-     i:=oper[opidx].ref^.index;
-     b:=oper[opidx].ref^.base;
-     if not(i in [R_NO,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]) or
-        not(b in [R_NO,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]) then
-      begin
-        NeedAddrPrefix:=true;
-        exit;
-      end;
-   end;
-  NeedAddrPrefix:=false;
-end;
-
-
-function regval(r:tregister):byte;
-begin
-  case r of
-    R_EAX,R_AX,R_AL,R_ES,R_CR0,R_DR0,R_ST,R_ST0,R_MM0 :
-      regval:=0;
-    R_ECX,R_CX,R_CL,R_CS,R_DR1,R_ST1,R_MM1 :
-      regval:=1;
-    R_EDX,R_DX,R_DL,R_SS,R_CR2,R_DR2,R_ST2,R_MM2 :
-      regval:=2;
-    R_EBX,R_BX,R_BL,R_DS,R_CR3,R_DR3,R_TR3,R_ST3,R_MM3 :
-      regval:=3;
-    R_ESP,R_SP,R_AH,R_FS,R_CR4,R_TR4,R_ST4,R_MM4 :
-      regval:=4;
-    R_EBP,R_BP,R_CH,R_GS,R_TR5,R_ST5,R_MM5 :
-      regval:=5;
-    R_ESI,R_SI,R_DH,R_DR6,R_TR6,R_ST6,R_MM6 :
-      regval:=6;
-    R_EDI,R_DI,R_BH,R_DR7,R_TR7,R_ST7,R_MM7 :
-      regval:=7;
-    else
-      begin
-        internalerror(777001);
-        regval:=0;
-      end;
-  end;
-end;
-
-
-function process_ea(const input:toper;var output:ea;rfield:longint):boolean;
-const
-  regs : array[0..31] of tregister=(
-    R_MM0, R_EAX, R_AX, R_AL, R_MM1, R_ECX, R_CX, R_CL,
-    R_MM2, R_EDX, R_DX, R_DL, R_MM3, R_EBX, R_BX, R_BL,
-    R_MM4, R_ESP, R_SP, R_AH, R_MM5, R_EBP, R_BP, R_CH,
-    R_MM6, R_ESI, R_SI, R_DH, R_MM7, R_EDI, R_DI, R_BH
-  );
-var
-  j     : longint;
-  i,b   : tregister;
-  sym   : pasmsymbol;
-  md,s  : byte;
-  base,index,scalefactor,
-  o     : longint;
-begin
-  process_ea:=false;
-{ register ? }
-  if (input.typ=top_reg) then
-   begin
-     j:=0;
-     while (j<=high(regs)) do
-      begin
-        if input.reg=regs[j] then
-         break;
-        inc(j);
-      end;
-     if j<=high(regs) then
-      begin
-        output.sib_present:=false;
-        output.bytes:=0;
-        output.modrm:=$c0 or (rfield shl 3) or (j shr 2);
-        output.size:=1;
-        process_ea:=true;
-      end;
-     exit;
-   end;
-{ memory reference }
-  i:=input.ref^.index;
-  b:=input.ref^.base;
-  s:=input.ref^.scalefactor;
-  o:=input.ref^.offset;
-  sym:=input.ref^.symbol;
-{ it's direct address }
-  if (b=R_NO) and (i=R_NO) then
-   begin
-     { it's a pure offset }
-     output.sib_present:=false;
-     output.bytes:=4;
-     output.modrm:=5 or (rfield shl 3);
-   end
-  else
-  { it's an indirection }
-   begin
-     { 16 bit address? }
-     if not((i in [R_NO,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]) and
-            (b in [R_NO,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI])) then
-      Message(asmw_e_16bit_not_supported);
-{$ifdef OPTEA}
-     { make single reg base }
-     if (b=R_NO) and (s=1) then
-      begin
-        b:=i;
-        i:=R_NO;
-      end;
-     { convert [3,5,9]*EAX to EAX+[2,4,8]*EAX }
-     if (b=R_NO) and
-        (((s=2) and (i<>R_ESP)) or
-          (s=3) or (s=5) or (s=9)) then
-      begin
-        b:=i;
-        dec(s);
-      end;
-     { swap ESP into base if scalefactor is 1 }
-     if (s=1) and (i=R_ESP) then
-      begin
-        i:=b;
-        b:=R_ESP;
-      end;
-{$endif}
-     { wrong, for various reasons }
-     if (i=R_ESP) or ((s<>1) and (s<>2) and (s<>4) and (s<>8) and (i<>R_NO)) then
-      exit;
-     { base }
-     case b of
-       R_EAX : base:=0;
-       R_ECX : base:=1;
-       R_EDX : base:=2;
-       R_EBX : base:=3;
-       R_ESP : base:=4;
-       R_NO,
-       R_EBP : base:=5;
-       R_ESI : base:=6;
-       R_EDI : base:=7;
-     else
-       exit;
-     end;
-     { index }
-     case i of
-       R_EAX : index:=0;
-       R_ECX : index:=1;
-       R_EDX : index:=2;
-       R_EBX : index:=3;
-       R_NO  : index:=4;
-       R_EBP : index:=5;
-       R_ESI : index:=6;
-       R_EDI : index:=7;
-     else
-       exit;
-     end;
-     case s of
-      0,
-      1 : scalefactor:=0;
-      2 : scalefactor:=1;
-      4 : scalefactor:=2;
-      8 : scalefactor:=3;
-     else
-      exit;
-     end;
-     if (b=R_NO) or
-        ((b<>R_EBP) and (o=0) and (sym=nil)) then
-      md:=0
-     else
-      if ((o>=-128) and (o<=127) and (sym=nil)) then
-       md:=1
-      else
-       md:=2;
-     if (b=R_NO) or (md=2) then
-      output.bytes:=4
-     else
-      output.bytes:=md;
-     { SIB needed ? }
-     if (i=R_NO) and (b<>R_ESP) then
-      begin
-        output.sib_present:=false;
-        output.modrm:=(md shl 6) or (rfield shl 3) or base;
-      end
-     else
-      begin
-        output.sib_present:=true;
-        output.modrm:=(md shl 6) or (rfield shl 3) or 4;
-        output.sib:=(scalefactor shl 6) or (index shl 3) or base;
-      end;
-   end;
-  if output.sib_present then
-   output.size:=2+output.bytes
-  else
-   output.size:=1+output.bytes;
-  process_ea:=true;
-end;
-
-
-function tai386.calcsize(p:PInsEntry):longint;
-var
-  codes : pchar;
-  c     : byte;
-  len     : longint;
-  ea_data : ea;
-begin
-  len:=0;
-  codes:=@p^.code;
-  repeat
-    c:=ord(codes^);
-    inc(codes);
-    case c of
-      0 :
-        break;
-      1,2,3 :
-        begin
-          inc(codes,c);
-          inc(len,c);
-        end;
-      8,9,10 :
-        begin
-          inc(codes);
-          inc(len);
-        end;
-      4,5,6,7,
-      15,
-      12,13,14,
-      16,17,18,
-      20,21,22,
-      40,41,42 :
-        inc(len);
-      24,25,26,
-      31,
-      48,49,50 :
-        inc(len,2);
-      28,29,30, { we don't have 16 bit immediates code }
-      32,33,34,
-      52,53,54,
-      56,57,58 :
-        inc(len,4);
-      192,193,194 :
-        if NeedAddrPrefix(c-192) then
-         inc(len);
-      208 :
-        inc(len);
-      200,
-      201,
-      202,
-      209,
-      210 : ;
-      216 :
-        begin
-          inc(codes);
-          inc(len);
-        end;
-      224,225,226 :
-        begin
-          InternalError(777002);
-        end;
-      else
-        begin
-          if (c>=64) and (c<=191) then
-           begin
-             if not process_ea(oper[(c shr 3) and 7], ea_data, 0) then
-              Message(asmw_e_invalid_effective_address)
-             else
-              inc(len,ea_data.size);
-           end
-          else
-           InternalError(777003);
-        end;
-    end;
-  until false;
-  calcsize:=len;
-end;
-
-
-procedure tai386.GenCode;
-{
- * the actual codes (C syntax, i.e. octal):
- * \0            - terminates the code. (Unless it's a literal of course.)
- * \1, \2, \3    - that many literal bytes follow in the code stream
- * \4, \6        - the POP/PUSH (respectively) codes for CS, DS, ES, SS
- *                 (POP is never used for CS) depending on operand 0
- * \5, \7        - the second byte of POP/PUSH codes for FS, GS, depending
- *                 on operand 0
- * \10, \11, \12 - a literal byte follows in the code stream, to be added
- *                 to the register value of operand 0, 1 or 2
- * \17           - encodes the literal byte 0. (Some compilers don't take
- *                 kindly to a zero byte in the _middle_ of a compile time
- *                 string constant, so I had to put this hack in.)
- * \14, \15, \16 - a signed byte immediate operand, from operand 0, 1 or 2
- * \20, \21, \22 - a byte immediate operand, from operand 0, 1 or 2
- * \24, \25, \26 - an unsigned byte immediate operand, from operand 0, 1 or 2
- * \30, \31, \32 - a word immediate operand, from operand 0, 1 or 2
- * \34, \35, \36 - select between \3[012] and \4[012] depending on 16/32 bit
- *                 assembly mode or the address-size override on the operand
- * \37           - a word constant, from the _segment_ part of operand 0
- * \40, \41, \42 - a long immediate operand, from operand 0, 1 or 2
- * \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
- * \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
- * \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
- *                 assembly mode or the address-size override on the operand
- * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2
- * \1ab          - a ModRM, calculated on EA in operand a, with the spare
- *                 field the register value of operand b.
- * \2ab          - a ModRM, calculated on EA in operand a, with the spare
- *                 field equal to digit b.
- * \30x          - might be an 0x67 byte, depending on the address size of
- *                 the memory reference in operand x.
- * \310          - indicates fixed 16-bit address size, i.e. optional 0x67.
- * \311          - indicates fixed 32-bit address size, i.e. optional 0x67.
- * \320          - indicates fixed 16-bit operand size, i.e. optional 0x66.
- * \321          - indicates fixed 32-bit operand size, i.e. optional 0x66.
- * \322          - indicates that this instruction is only valid when the
- *                 operand size is the default (instruction to disassembler,
- *                 generates no code in the assembler)
- * \330          - a literal byte follows in the code stream, to be added
- *                 to the condition code value of the instruction.
- * \340          - reserve <operand 0> bytes of uninitialised storage.
- *                 Operand 0 had better be a segmentless constant.
-}
-
-var
-  currval : longint;
-  currsym : pasmsymbol;
-
-  procedure getvalsym(opidx:longint);
-  begin
-    case oper[opidx].typ of
-      top_ref :
-        begin
-          currval:=oper[opidx].ref^.offset;
-          currsym:=oper[opidx].ref^.symbol;
-        end;
-      top_const :
-        begin
-          currval:=oper[opidx].val;
-          currsym:=nil;
-        end;
-      top_symbol :
-        begin
-          currval:=oper[opidx].symofs;
-          currsym:=oper[opidx].sym;
-        end;
-      else
-        Message(asmw_e_immediate_or_reference_expected);
-    end;
-  end;
-
-const
-  CondVal:array[TAsmCond] of byte=($0,
-   $7, $3, $2, $6, $2, $4, $F, $D, $C, $E, $6, $2,
-   $3, $7, $3, $5, $E, $C, $D, $F, $1, $B, $9, $5,
-   $0, $A, $A, $B, $8, $4);
-var
-  c : byte;
-  pb,
-  codes : pchar;
-  bytes : array[0..3] of byte;
-  rfield,
-  data,s,opidx : longint;
-  ea_data : ea;
-begin
-  codes:=insentry^.code;
-  repeat
-    c:=ord(codes^);
-    inc(codes);
-    case c of
-      0 :
-        break;
-      1,2,3 :
-        begin
-          objectoutput^.writebytes(codes^,c);
-          inc(codes,c);
-        end;
-      4,6 :
-        begin
-          case oper[0].reg of
-            R_CS :
-              begin
-                if c=4 then
-                 bytes[0]:=$f
-                else
-                 bytes[0]:=$e;
-              end;
-            R_NO,
-            R_DS :
-              begin
-                if c=4 then
-                 bytes[0]:=$1f
-                else
-                 bytes[0]:=$1e;
-              end;
-            R_ES :
-              begin
-                if c=4 then
-                 bytes[0]:=$7
-                else
-                 bytes[0]:=$6;
-              end;
-            R_SS :
-              begin
-                if c=4 then
-                 bytes[0]:=$17
-                else
-                 bytes[0]:=$16;
-              end;
-            else
-              InternalError(777004);
-          end;
-          objectoutput^.writebytes(bytes,1);
-        end;
-      5,7 :
-        begin
-          case oper[0].reg of
-            R_FS :
-              begin
-                if c=5 then
-                 bytes[0]:=$a1
-                else
-                 bytes[0]:=$a0;
-              end;
-            R_GS :
-              begin
-                if c=5 then
-                 bytes[0]:=$a9
-                else
-                 bytes[0]:=$a8;
-              end;
-            else
-              InternalError(777005);
-          end;
-          objectoutput^.writebytes(bytes,1);
-        end;
-      8,9,10 :
-        begin
-          bytes[0]:=ord(codes^)+regval(oper[c-8].reg);
-          inc(codes);
-          objectoutput^.writebytes(bytes,1);
-        end;
-      15 :
-        begin
-          bytes[0]:=0;
-          objectoutput^.writebytes(bytes,1);
-        end;
-      12,13,14 :
-        begin
-          getvalsym(c-12);
-          if (currval<-128) or (currval>127) then
-           Message2(asmw_e_value_exceeds_bounds,'signed byte',tostr(currval));
-          if assigned(currsym) then
-            objectoutput^.writereloc(currval,1,currsym,relative_false)
-          else
-            objectoutput^.writebytes(currval,1);
-        end;
-      16,17,18 :
-        begin
-          getvalsym(c-16);
-          if (currval<-256) or (currval>255) then
-           Message2(asmw_e_value_exceeds_bounds,'byte',tostr(currval));
-          if assigned(currsym) then
-           objectoutput^.writereloc(currval,1,currsym,relative_false)
-          else
-           objectoutput^.writebytes(currval,1);
-        end;
-      20,21,22 :
-        begin
-          getvalsym(c-20);
-          if (currval<0) or (currval>255) then
-           Message2(asmw_e_value_exceeds_bounds,'unsigned byte',tostr(currval));
-          if assigned(currsym) then
-           objectoutput^.writereloc(currval,1,currsym,relative_false)
-          else
-           objectoutput^.writebytes(currval,1);
-        end;
-      24,25,26 :
-        begin
-          getvalsym(c-24);
-          if (currval<-65536) or (currval>65535) then
-           Message2(asmw_e_value_exceeds_bounds,'word',tostr(currval));
-          if assigned(currsym) then
-           objectoutput^.writereloc(currval,2,currsym,relative_false)
-          else
-           objectoutput^.writebytes(currval,2);
-        end;
-      28,29,30 :
-        begin
-          getvalsym(c-28);
-          if assigned(currsym) then
-           objectoutput^.writereloc(currval,4,currsym,relative_false)
-          else
-           objectoutput^.writebytes(currval,4);
-        end;
-      32,33,34 :
-        begin
-          getvalsym(c-32);
-          if assigned(currsym) then
-           objectoutput^.writereloc(currval,4,currsym,relative_false)
-          else
-           objectoutput^.writebytes(currval,4);
-        end;
-      40,41,42 :
-        begin
-          getvalsym(c-40);
-          data:=currval-insend;
-          if assigned(currsym) then
-           inc(data,currsym^.address);
-          if (data>127) or (data<-128) then
-           Message1(asmw_e_short_jmp_out_of_range,tostr(data));
-          objectoutput^.writebytes(data,1);
-        end;
-      52,53,54 :
-        begin
-          getvalsym(c-52);
-          if assigned(currsym) then
-           objectoutput^.writereloc(currval,4,currsym,relative_true)
-          else
-           objectoutput^.writereloc(currval-insend,4,nil,relative_false)
-        end;
-      56,57,58 :
-        begin
-          getvalsym(c-56);
-          if assigned(currsym) then
-           objectoutput^.writereloc(currval,4,currsym,relative_true)
-          else
-           objectoutput^.writereloc(currval-insend,4,nil,relative_false)
-        end;
-      192,193,194 :
-        begin
-          if NeedAddrPrefix(c-192) then
-           begin
-             bytes[0]:=$67;
-             objectoutput^.writebytes(bytes,1);
-           end;
-        end;
-      200 :
-        begin
-          bytes[0]:=$67;
-          objectoutput^.writebytes(bytes,1);
-        end;
-      208 :
-        begin
-          bytes[0]:=$66;
-          objectoutput^.writebytes(bytes,1);
-        end;
-      216 :
-        begin
-          bytes[0]:=ord(codes^)+condval[condition];
-          inc(codes);
-          objectoutput^.writebytes(bytes,1);
-        end;
-      201,
-      202,
-      209,
-      210 :
-        begin
-        end;
-      31,
-      48,49,50,
-      224,225,226 :
-        begin
-          InternalError(777006);
-        end
-      else
-        begin
-          if (c>=64) and (c<=191) then
-           begin
-             if (c<127) then
-              begin
-                if (oper[c and 7].typ=top_reg) then
-                  rfield:=regval(oper[c and 7].reg)
-                else
-                  rfield:=regval(oper[c and 7].ref^.base);
-              end
-             else
-              rfield:=c and 7;
-             opidx:=(c shr 3) and 7;
-             if not process_ea(oper[opidx], ea_data, rfield) then
-              Message(asmw_e_invalid_effective_address);
-
-             pb:=@bytes;
-             pb^:=chr(ea_data.modrm);
-             inc(pb);
-             if ea_data.sib_present then
-              begin
-                pb^:=chr(ea_data.sib);
-                inc(pb);
-              end;
-
-             s:=pb-pchar(@bytes);
-             objectoutput^.writebytes(bytes,s);
-
-             case ea_data.bytes of
-               0 : ;
-               1 :
-                 begin
-                   if (oper[opidx].ot and OT_MEMORY)=OT_MEMORY then
-                    objectoutput^.writereloc(oper[opidx].ref^.offset,1,oper[opidx].ref^.symbol,relative_false)
-                   else
-                    begin
-                      bytes[0]:=oper[opidx].ref^.offset;
-                      objectoutput^.writebytes(bytes,1);
-                    end;
-                   inc(s);
-                 end;
-               2,4 :
-                 begin
-                   objectoutput^.writereloc(oper[opidx].ref^.offset,ea_data.bytes,
-                     oper[opidx].ref^.symbol,relative_false);
-                   inc(s,ea_data.bytes);
-                 end;
-             end;
-           end
-          else
-           InternalError(777007);
-        end;
-    end;
-  until false;
-end;
-{$endif NOAG386BIN}
-
-end.
-{
-  $Log$
-  Revision 1.17  1999-08-01 23:55:53  michael
-  * Moved taitempalloc
-
-  Revision 1.16  1999/07/05 20:25:32  peter
-    * merged
-
-  Revision 1.15  1999/07/05 11:56:55  jonas
-    * merged
-
-  Revision 1.12.2.4  1999/07/05 20:03:30  peter
-    * removed warning/notes
-
-  Revision 1.12.2.3  1999/07/04 23:55:50  jonas
-    * changed $ifdef jmpfix to $ifndef nojmpfix
-
-  Revision 1.14  1999/07/04 21:59:31  jonas
-    * merged
-
-  Revision 1.12.2.2  1999/07/04 21:50:16  jonas
-    * everything between $ifdef jmpfix:
-      * when a jxx instruction is disposed, decrease the refcount of the label
-        it referenced
-      * for jmp instructions to a label, set is_jmp also to true (was only done
-        for Jcc instructions)
-
-  Revision 1.13  1999/06/28 19:30:06  peter
-    * merged
-
-  Revision 1.12.2.1  1999/06/28 19:18:53  peter
-    * fixed loadsym with sym=nil
-
-  Revision 1.12  1999/06/14 11:15:01  pierre
-   * -O2 real multiplication bug correction
-
-  Revision 1.11  1999/05/30 11:57:43  peter
-    * moved swapoperands out of the define
-
-  Revision 1.10  1999/05/27 19:44:33  peter
-    * removed oldasm
-    * plabel -> pasmlabel
-    * -a switches to source writing automaticly
-    * assembler readers OOPed
-    * asmsymbol automaticly external
-    * jumptables and other label fixes for asm readers
-
-  Revision 1.9  1999/05/21 13:55:02  peter
-    * NEWLAB for label as symbol
-
-  Revision 1.8  1999/05/17 21:57:09  florian
-    * new temporary ansistring handling
-
-  Revision 1.7  1999/05/16 17:00:45  peter
-    * fixed sym_ofs_ref op loading
-
-  Revision 1.6  1999/05/12 00:19:50  peter
-    * removed R_DEFAULT_SEG
-    * uniform float names
-
-  Revision 1.5  1999/05/11 16:29:59  peter
-    * more noag386bin defines, so tp7 can compile at least
-
-  Revision 1.4  1999/05/05 22:21:51  peter
-    * updated messages
-
-  Revision 1.3  1999/05/02 22:41:53  peter
-    * moved section names to systems
-    * fixed nasm,intel writer
-
-  Revision 1.2  1999/05/02 21:33:52  florian
-    * several bugs regarding -Or fixed
-
-  Revision 1.1  1999/05/01 13:24:23  peter
-    * merged nasm compiler
-    * old asm moved to oldasm/
-
-  Revision 1.18  1999/04/16 11:49:51  peter
-    + tempalloc
-    + -at to show temp alloc info in .s file
-
-  Revision 1.17  1999/04/16 09:35:11  pierre
-   + tai constructors needed for SHRD and IMUL added
-
-  Revision 1.16  1999/04/01 21:58:21  peter
-    * small fixes for proces_ea
-
-  Revision 1.15  1999/03/31 13:55:32  peter
-    * assembler inlining working for ag386bin
-
-  Revision 1.14  1999/03/29 16:05:49  peter
-    * optimizer working for ag386bin
-
-  Revision 1.13  1999/03/26 00:01:11  peter
-    * first things for optimizer (compiles but cycle crashes)
-
-  Revision 1.12  1999/03/12 00:20:04  pierre
-   + win32 output working !
-
-  Revision 1.11  1999/03/10 13:41:08  pierre
-   + partial implementation for win32 !
-     winhello works but pp still does not !
-
-  Revision 1.10  1999/03/09 19:25:24  peter
-    * only pass jmp's a second time in pass1
-
-  Revision 1.9  1999/03/08 14:51:06  peter
-    + smartlinking for ag386bin
-
-  Revision 1.8  1999/03/06 17:24:19  peter
-    * rewritten intel parser a lot, especially reference reading
-    * size checking added for asm parsers
-
-  Revision 1.7  1999/03/02 02:56:19  peter
-    + stabs support for binary writers
-    * more fixes and missing updates from the previous commit :(
-
-  Revision 1.6  1999/03/01 15:46:21  peter
-    * ag386bin finally make cycles correct
-    * prefixes are now also normal opcodes
-
-  Revision 1.5  1999/02/26 00:48:28  peter
-    * assembler writers fixed for ag386bin
-
-  Revision 1.4  1999/02/25 21:03:02  peter
-    * ag386bin updates
-    + coff writer
-
-  Revision 1.3  1999/02/22 02:44:17  peter
-    * ag386bin doesn't use i386.pas anymore
-
-  Revision 1.2  1999/02/22 02:16:02  peter
-    * updates for ag386bin
-
-  Revision 1.1  1999/02/16 17:59:37  peter
-    + initial files
-
-}

+ 0 - 1088
compiler/i386base.pas

@@ -1,1088 +0,0 @@
-{
-    $Id$
-    Copyright (c) 1999 by Florian Klaempfl
-
-    Contains the base types for the i386
-
-    * This code was inspired by the NASM sources
-      The Netwide Assembler is copyright (C) 1996 Simon Tatham and
-      Julian Hall. All rights reserved.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    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.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
-}
-unit i386base;
-interface
-{$ifdef TP}
-  {$L-,Y-}
-{$endif}
-
-uses
-  strings,cobjects,aasm;
-
-const
-{ Size of the instruction table converted by nasmconv.pas }
-  instabentries = 1103;
-  maxinfolen    = 7;
-
-{ By default we want everything }
-{$define ATTOP}
-{$define ATTREG}
-{$define INTELOP}
-{$define ITTABLE}
-
-{ For TP we can't use asmdebug due the table sizes }
-{$ifndef TP}
-  {$define ASMDEBUG}
-{$endif}
-
-{ We Don't need the intel style opcodes if we don't have a intel
-  reader or generator }
-{$ifndef ASMDEBUG}
-{$ifdef NORA386INT}
-  {$ifdef NOAG386NSM}
-    {$ifdef NOAG386INT}
-      {$undef INTELOP}
-    {$endif}
-  {$endif}
-{$endif}
-{$endif}
-
-{ We Don't need the AT&T style opcodes if we don't have a AT&T
-  reader or generator }
-{$ifdef NORA386ATT}
-  {$ifdef NOAG386ATT}
-    {$undef ATTOP}
-    {$ifdef NOAG386DIR}
-       {$undef ATTREG}
-    {$endif}
-  {$endif}
-{$endif}
-
-const
-{ Operand types }
-  OT_NONE      = $00000000;
-
-  OT_BITS8     = $00000001;  { size, and other attributes, of the operand  }
-  OT_BITS16    = $00000002;
-  OT_BITS32    = $00000004;
-  OT_BITS64    = $00000008;  { FPU only  }
-  OT_BITS80    = $00000010;
-  OT_FAR       = $00000020;  { this means 16:16 or 16:32, like in CALL/JMP }
-  OT_NEAR      = $00000040;
-  OT_SHORT     = $00000080;
-
-  OT_SIZE_MASK = $000000FF;  { all the size attributes  }
-  OT_NON_SIZE  = not OT_SIZE_MASK;
-
-  OT_SIGNED    = $00000100;  { the operand need to be signed -128-127 }
-
-  OT_TO        = $00000200;  { operand is followed by a colon  }
-                             { reverse effect in FADD, FSUB &c  }
-  OT_COLON     = $00000400;
-
-  OT_REGISTER  = $00001000;
-  OT_IMMEDIATE = $00002000;
-  OT_IMM8      = $00002001;
-  OT_IMM16     = $00002002;
-  OT_IMM32     = $00002004;
-  OT_IMM64     = $00002008;
-  OT_IMM80     = $00002010;
-  OT_REGMEM    = $00200000;  { for r/m, ie EA, operands  }
-  OT_REGNORM   = $00201000;  { 'normal' reg, qualifies as EA  }
-  OT_REG8      = $00201001;
-  OT_REG16     = $00201002;
-  OT_REG32     = $00201004;
-  OT_MMXREG    = $00201008;  { MMX registers  }
-  OT_MEMORY    = $00204000;  { register number in 'basereg'  }
-  OT_MEM8      = $00204001;
-  OT_MEM16     = $00204002;
-  OT_MEM32     = $00204004;
-  OT_MEM64     = $00204008;
-  OT_MEM80     = $00204010;
-  OT_FPUREG    = $01000000;  { floating point stack registers  }
-  OT_FPU0      = $01000800;  { FPU stack register zero  }
-  OT_REG_SMASK = $00070000;  { special register operands: these may be treated differently  }
-                             { a mask for the following  }
-  OT_REG_ACCUM = $00211000;  { accumulator: AL, AX or EAX  }
-  OT_REG_AL    = $00211001;    { REG_ACCUM | BITSxx  }
-  OT_REG_AX    = $00211002;    { ditto  }
-  OT_REG_EAX   = $00211004;    { and again  }
-  OT_REG_COUNT = $00221000;  { counter: CL, CX or ECX  }
-  OT_REG_CL    = $00221001;    { REG_COUNT | BITSxx  }
-  OT_REG_CX    = $00221002;    { ditto  }
-  OT_REG_ECX   = $00221004;    { another one  }
-  OT_REG_DX    = $00241002;
-
-  OT_REG_SREG  = $00081002;  { any segment register  }
-  OT_REG_CS    = $01081002;  { CS  }
-  OT_REG_DESS  = $02081002;  { DS, ES, SS (non-CS 86 registers)  }
-  OT_REG_FSGS  = $04081002;  { FS, GS (386 extended registers)  }
-
-  OT_REG_CDT   = $00101004;  { CRn, DRn and TRn  }
-  OT_REG_CREG  = $08101004;  { CRn  }
-  OT_REG_CR4   = $08101404;  { CR4 (Pentium only)  }
-  OT_REG_DREG  = $10101004;  { DRn  }
-  OT_REG_TREG  = $20101004;  { TRn  }
-
-  OT_MEM_OFFS  = $00604000;  { special type of EA  }
-                             { simple [address] offset  }
-  OT_ONENESS   = $00800000;  { special type of immediate operand  }
-                             { so UNITY == IMMEDIATE | ONENESS  }
-  OT_UNITY     = $00802000;  { for shift/rotate instructions  }
-
-{ Instruction flags }
-  IF_SM    = $0001;  { size match first operand  }
-  IF_SM2   = $0002;  { size match first two operands  }
-  IF_SB    = $0004;  { unsized operands can't be non-byte  }
-  IF_SW    = $0008;  { unsized operands can't be non-word  }
-  IF_SD    = $0010;  { unsized operands can't be nondword  }
-  IF_8086  = $0000;  { 8086 instruction  }
-  IF_186   = $0100;  { 186+ instruction  }
-  IF_286   = $0200;  { 286+ instruction  }
-  IF_386   = $0300;  { 386+ instruction  }
-  IF_486   = $0400;  { 486+ instruction  }
-  IF_PENT  = $0500;  { Pentium instruction  }
-  IF_P6    = $0600;  { P6 instruction  }
-  IF_CYRIX = $0800;  { Cyrix-specific instruction  }
-  IF_PMASK = $0F00;  { the mask for processor types  }
-  IF_PRIV  = $1000;  { it's a privileged instruction  }
-  IF_UNDOC = $2000;  { it's an undocumented instruction  }
-  IF_FPU   = $4000;  { it's an FPU instruction  }
-  IF_MMX   = $8000;  { it's an MMX instruction  }
-  { added flags }
-  IF_PRE   = $10000; { it's a prefix instruction }
-  IF_PASS2 = $20000; { if the instruction can change in a second pass }
-
-type
-  TAsmOp=(A_None,
-    { prefixes }
-    A_LOCK,A_REP,A_REPE,A_REPNE,A_REPNZ,A_REPZ,
-    A_CS,A_ES,A_DS,A_FS,A_GS,A_SS,
-    { normal }
-    A_AAA, A_AAD, A_AAM, A_AAS, A_ADC, A_ADD, A_AND, A_ARPL,
-    A_BOUND, A_BSF, A_BSR, A_BSWAP, A_BT, A_BTC, A_BTR, A_BTS,
-    A_CALL, A_CBW, A_CDQ, A_CLC, A_CLD, A_CLI, A_CLTS, A_CMC, A_CMP,
-    A_CMPSB, A_CMPSD, A_CMPSW, A_CMPXCHG, A_CMPXCHG486, A_CMPXCHG8B,
-    A_CPUID, A_CWD, A_CWDE, A_DAA, A_DAS, A_DEC, A_DIV,
-    A_EMMS, A_ENTER, A_EQU, A_F2XM1, A_FABS,
-    A_FADD, A_FADDP, A_FBLD, A_FBSTP, A_FCHS, A_FCLEX, A_FCMOVB,
-    A_FCMOVBE, A_FCMOVE, A_FCMOVNB, A_FCMOVNBE, A_FCMOVNE,
-    A_FCMOVNU, A_FCMOVU, A_FCOM, A_FCOMI, A_FCOMIP, A_FCOMP,
-    A_FCOMPP, A_FCOS, A_FDECSTP, A_FDISI, A_FDIV, A_FDIVP, A_FDIVR,
-    A_FDIVRP, A_FEMMS,
-    A_FENI, A_FFREE, A_FIADD, A_FICOM, A_FICOMP, A_FIDIV,
-    A_FIDIVR, A_FILD, A_FIMUL, A_FINCSTP, A_FINIT, A_FIST, A_FISTP,
-    A_FISUB, A_FISUBR, A_FLD, A_FLD1, A_FLDCW, A_FLDENV, A_FLDL2E,
-    A_FLDL2T, A_FLDLG2, A_FLDLN2, A_FLDPI, A_FLDZ, A_FMUL, A_FMULP,
-    A_FNCLEX, A_FNDISI, A_FNENI, A_FNINIT, A_FNOP, A_FNSAVE,
-    A_FNSTCW, A_FNSTENV, A_FNSTSW, A_FPATAN, A_FPREM, A_FPREM1,
-    A_FPTAN, A_FRNDINT, A_FRSTOR, A_FSAVE, A_FSCALE, A_FSETPM,
-    A_FSIN, A_FSINCOS, A_FSQRT, A_FST, A_FSTCW, A_FSTENV, A_FSTP,
-    A_FSTSW, A_FSUB, A_FSUBP, A_FSUBR, A_FSUBRP, A_FTST, A_FUCOM,
-    A_FUCOMI, A_FUCOMIP, A_FUCOMP, A_FUCOMPP, A_FWAIT,A_FXAM, A_FXCH,
-    A_FXTRACT, A_FYL2X, A_FYL2XP1, A_HLT, A_IBTS, A_ICEBP, A_IDIV,
-    A_IMUL, A_IN, A_INC, A_INSB, A_INSD, A_INSW, A_INT,
-    A_INT01, A_INT1, A_INT3, A_INTO, A_INVD, A_INVLPG, A_IRET,
-    A_IRETD, A_IRETW, A_JCXZ, A_JECXZ, A_JMP, A_LAHF, A_LAR, A_LDS,
-    A_LEA, A_LEAVE, A_LES, A_LFS, A_LGDT, A_LGS, A_LIDT, A_LLDT,
-    A_LMSW, A_LOADALL, A_LOADALL286, A_LODSB, A_LODSD, A_LODSW,
-    A_LOOP, A_LOOPE, A_LOOPNE, A_LOOPNZ, A_LOOPZ, A_LSL, A_LSS,
-    A_LTR, A_MOV, A_MOVD, A_MOVQ, A_MOVSB, A_MOVSD, A_MOVSW,
-    A_MOVSX, A_MOVZX, A_MUL, A_NEG, A_NOP, A_NOT, A_OR, A_OUT,
-    A_OUTSB, A_OUTSD, A_OUTSW, A_PACKSSDW, A_PACKSSWB, A_PACKUSWB,
-    A_PADDB, A_PADDD, A_PADDSB, A_PADDSIW, A_PADDSW, A_PADDUSB,
-    A_PADDUSW, A_PADDW, A_PAND, A_PANDN, A_PAVEB,
-    A_PAVGUSB, A_PCMPEQB, A_PCMPEQD, A_PCMPEQW, A_PCMPGTB, A_PCMPGTD,
-    A_PCMPGTW, A_PDISTIB,
-    A_PF2ID, A_PFACC, A_PFADD, A_PFCMPEQ, A_PFCMPGE, A_PFCMPGT,
-    A_PFMAX, A_PFMIN, A_PFMUL, A_PFRCP, A_PFRCPIT1, A_PFRCPIT2,
-    A_PFRSQIT1, A_PFRSQRT, A_PFSUB, A_PFSUBR, A_PI2FD,
-    A_PMACHRIW, A_PMADDWD, A_PMAGW,  A_PMULHRIW, A_PMULHRWA,
-    A_PMULHRWC, A_PMULHW, A_PMULLW, A_PMVGEZB, A_PMVLZB, A_PMVNZB,
-    A_PMVZB, A_POP, A_POPA, A_POPAD, A_POPAW, A_POPF, A_POPFD,
-    A_POPFW, A_POR, A_PREFETCH, A_PREFETCHW,
-    A_PSLLD, A_PSLLQ, A_PSLLW, A_PSRAD, A_PSRAW,
-    A_PSRLD, A_PSRLQ, A_PSRLW, A_PSUBB, A_PSUBD, A_PSUBSB,
-    A_PSUBSIW, A_PSUBSW, A_PSUBUSB, A_PSUBUSW, A_PSUBW, A_PUNPCKHBW,
-    A_PUNPCKHDQ, A_PUNPCKHWD, A_PUNPCKLBW, A_PUNPCKLDQ, A_PUNPCKLWD,
-    A_PUSH, A_PUSHA, A_PUSHAD, A_PUSHAW, A_PUSHF, A_PUSHFD,
-    A_PUSHFW, A_PXOR, A_RCL, A_RCR, A_RDMSR, A_RDPMC, A_RDTSC,
-    A_RESB, A_RET, A_RETF, A_RETN,
-    A_ROL, A_ROR, A_RSM, A_SAHF, A_SAL, A_SALC, A_SAR, A_SBB,
-    A_SCASB, A_SCASD, A_SCASW, A_SGDT, A_SHL, A_SHLD, A_SHR, A_SHRD,
-    A_SIDT, A_SLDT, A_SMI, A_SMSW, A_STC, A_STD, A_STI, A_STOSB,
-    A_STOSD, A_STOSW, A_STR, A_SUB, A_TEST, A_UMOV, A_VERR, A_VERW,
-    A_WAIT, A_WBINVD, A_WRMSR, A_XADD, A_XBTS, A_XCHG, A_XLAT, A_XLATB,
-    A_XOR, A_CMOVcc, A_Jcc, A_SETcc
-  );
-
-  op2strtable=array[tasmop] of string[10];
-
-const
-  firstop = low(tasmop);
-  lastop  = high(tasmop);
-
-  AsmPrefixes = 6;
-  AsmPrefix : array[0..AsmPrefixes-1] of TasmOP =(
-    A_LOCK,A_REP,A_REPE,A_REPNE,A_REPNZ,A_REPZ
-  );
-
-  AsmOverrides = 6;
-  AsmOverride : array[0..AsmOverrides-1] of TasmOP =(
-    A_CS,A_ES,A_DS,A_FS,A_GS,A_SS
-  );
-
-
-{$ifdef INTELOP}
-  int_op2str:op2strtable=('<none>',
-    { prefixes }
-    'lock','rep','repe','repne','repnz','repz',
-    'segcs','seges','segds','segfs','seggs','segss',
-    { normal }
-    'aaa', 'aad', 'aam', 'aas', 'adc', 'add', 'and', 'arpl',
-    'bound', 'bsf', 'bsr', 'bswap', 'bt', 'btc', 'btr', 'bts',
-    'call', 'cbw', 'cdq', 'clc', 'cld', 'cli', 'clts', 'cmc', 'cmp',
-    'cmpsb', 'cmpsd', 'cmpsw', 'cmpxchg', 'cmpxchg486', 'cmpxchg8b',
-    'cpuid', 'cwd', 'cwde', 'daa', 'das', 'dec', 'div', 'emms',
-    'enter', 'equ', 'f2xm1', 'fabs',
-    'fadd', 'faddp', 'fbld', 'fbstp', 'fchs', 'fclex', 'fcmovb',
-    'fcmovbe', 'fcmove', 'fcmovnb', 'fcmovnbe', 'fcmovne',
-    'fcmovnu', 'fcmovu', 'fcom', 'fcomi', 'fcomip', 'fcomp',
-    'fcompp', 'fcos', 'fdecstp', 'fdisi', 'fdiv', 'fdivp', 'fdivr',
-    'fdivrp',
-    'femms',
-    'feni', 'ffree', 'fiadd', 'ficom', 'ficomp', 'fidiv',
-    'fidivr', 'fild', 'fimul', 'fincstp', 'finit', 'fist', 'fistp',
-    'fisub', 'fisubr', 'fld', 'fld1', 'fldcw', 'fldenv', 'fldl2e',
-    'fldl2t', 'fldlg2', 'fldln2', 'fldpi', 'fldz', 'fmul', 'fmulp',
-    'fnclex', 'fndisi', 'fneni', 'fninit', 'fnop', 'fnsave',
-    'fnstcw', 'fnstenv', 'fnstsw', 'fpatan', 'fprem', 'fprem1',
-    'fptan', 'frndint', 'frstor', 'fsave', 'fscale', 'fsetpm',
-    'fsin', 'fsincos', 'fsqrt', 'fst', 'fstcw', 'fstenv', 'fstp',
-    'fstsw', 'fsub', 'fsubp', 'fsubr', 'fsubrp', 'ftst', 'fucom',
-    'fucomi', 'fucomip', 'fucomp', 'fucompp', 'fwait', 'fxam', 'fxch',
-    'fxtract', 'fyl2x', 'fyl2xp1', 'hlt', 'ibts', 'icebp', 'idiv',
-    'imul', 'in', 'inc', 'insb', 'insd', 'insw', 'int',
-    'int01', 'int1', 'int3', 'into', 'invd', 'invlpg', 'iret',
-    'iretd', 'iretw', 'jcxz', 'jecxz', 'jmp', 'lahf', 'lar', 'lds',
-    'lea', 'leave', 'les', 'lfs', 'lgdt', 'lgs', 'lidt', 'lldt',
-    'lmsw', 'loadall', 'loadall286', 'lodsb', 'lodsd', 'lodsw',
-    'loop', 'loope', 'loopne', 'loopnz', 'loopz', 'lsl', 'lss',
-    'ltr', 'mov', 'movd', 'movq', 'movsb', 'movsd', 'movsw',
-    'movsx', 'movzx', 'mul', 'neg', 'nop', 'not', 'or', 'out',
-    'outsb', 'outsd', 'outsw', 'packssdw', 'packsswb', 'packuswb',
-    'paddb', 'paddd', 'paddsb', 'paddsiw', 'paddsw', 'paddusb',
-    'paddusw', 'paddw', 'pand', 'pandn', 'paveb',
-    'pavgusb', 'pcmpeqb',
-    'pcmpeqd', 'pcmpeqw', 'pcmpgtb', 'pcmpgtd', 'pcmpgtw',
-    'pdistib',
-    'pf2id', 'pfacc', 'pfadd', 'pfcmpeq', 'pfcmpge', 'pfcmpgt',
-    'pfmax', 'pfmin', 'pfmul', 'pfrcp', 'pfrcpit1', 'pfrcpit2',
-    'pfrsqit1', 'pfrsqrt', 'pfsub', 'pfsubr', 'pi2fd',
-    'pmachriw', 'pmaddwd', 'pmagw', 'pmulhriw', 'pmulhrwa', 'pmulhrwc',
-    'pmulhw', 'pmullw', 'pmvgezb', 'pmvlzb', 'pmvnzb',
-    'pmvzb', 'pop', 'popa', 'popad', 'popaw', 'popf', 'popfd',
-    'popfw', 'por',
-    'prefetch', 'prefetchw', 'pslld', 'psllq', 'psllw', 'psrad', 'psraw',
-    'psrld', 'psrlq', 'psrlw', 'psubb', 'psubd', 'psubsb',
-    'psubsiw', 'psubsw', 'psubusb', 'psubusw', 'psubw', 'punpckhbw',
-    'punpckhdq', 'punpckhwd', 'punpcklbw', 'punpckldq', 'punpcklwd',
-    'push', 'pusha', 'pushad', 'pushaw', 'pushf', 'pushfd',
-    'pushfw', 'pxor', 'rcl', 'rcr', 'rdmsr', 'rdpmc', 'rdtsc',
-    'resb', 'ret', 'retf', 'retn',
-    'rol', 'ror', 'rsm', 'sahf', 'sal', 'salc', 'sar', 'sbb',
-    'scasb', 'scasd', 'scasw', 'sgdt', 'shl', 'shld', 'shr', 'shrd',
-    'sidt', 'sldt', 'smi', 'smsw', 'stc', 'std', 'sti', 'stosb',
-    'stosd', 'stosw', 'str', 'sub', 'test', 'umov', 'verr', 'verw',
-    'wait', 'wbinvd', 'wrmsr', 'xadd', 'xbts', 'xchg', 'xlat', 'xlatb',
-    'xor','cmov','j','set'
-  );
-{$endif INTELOP}
-
-{$ifdef ATTOP}
-  att_op2str:op2strtable=('<none>',
-    { prefixes }
-    'lock','rep','repe','repne','repnz','repz',
-    'cs','es','ds','fs','gs','ss',
-    { normal }
-    'aaa', 'aad', 'aam', 'aas', 'adc', 'add', 'and', 'arpl',
-    'bound', 'bsf', 'bsr', 'bswap', 'bt', 'btc', 'btr', 'bts',
-    'call', 'cbtw', 'cltd', 'clc', 'cld', 'cli', 'clts', 'cmc', 'cmp',
-    'cmpsb', 'cmpsl', 'cmpsw', 'cmpxchg', 'cmpxchg486', 'cmpxchg8b',
-    'cpuid', 'cwtd', 'cwtl', 'daa', 'das', 'dec', 'div',
-    'emms', 'enter', 'equ', 'f2xm1', 'fabs',
-    'fadd', 'faddp', 'fbld', 'fbstp', 'fchs', 'fclex', 'fcmovb',
-    'fcmovbe', 'fcmove', 'fcmovnb', 'fcmovnbe', 'fcmovne',
-    'fcmovnu', 'fcmovu', 'fcom', 'fcomi', 'fcomip', 'fcomp',
-    'fcompp', 'fcos', 'fdecstp', 'fdisi', 'fdiv', 'fdivp', 'fdivr',
-    'fdivrp', 'femms',
-    'feni', 'ffree', 'fiadd', 'ficom', 'ficomp', 'fidiv',
-    'fidivr', 'fild', 'fimul', 'fincstp', 'finit', 'fist', 'fistp',
-    'fisub', 'fisubr', 'fld', 'fld1', 'fldcw', 'fldenv', 'fldl2e',
-    'fldl2t', 'fldlg2', 'fldln2', 'fldpi', 'fldz', 'fmul', 'fmulp',
-    'fnclex', 'fndisi', 'fneni', 'fninit', 'fnop', 'fnsave',
-    'fnstcw', 'fnstenv', 'fnstsw', 'fpatan', 'fprem', 'fprem1',
-    'fptan', 'frndint', 'frstor', 'fsave', 'fscale', 'fsetpm',
-    'fsin', 'fsincos', 'fsqrt', 'fst', 'fstcw', 'fstenv', 'fstp',
-    'fstsw', 'fsub', 'fsubp', 'fsubr', 'fsubrp', 'ftst', 'fucom',
-    'fucomi', 'fucomip', 'fucomp', 'fucompp', 'fwait', 'fxam', 'fxch',
-    'fxtract', 'fyl2x', 'fyl2xp1', 'hlt', 'ibts', 'icebp', 'idiv',
-    'imul', 'in', 'inc', 'insb', 'insl', 'insw', 'int',
-    'int01', 'int1', 'int3', 'into', 'invd', 'invlpg', 'iret',
-    'iretd', 'iretw', 'jcxz', 'jecxz', 'jmp', 'lahf', 'lar', 'lds',
-    'lea', 'leave', 'les', 'lfs', 'lgdt', 'lgs', 'lidt', 'lldt',
-    'lmsw', 'loadall', 'loadall286', 'lodsb', 'lodsl', 'lodsw',
-    'loop', 'loope', 'loopne', 'loopnz', 'loopz', 'lsl', 'lss',
-    'ltr', 'mov', 'movd', 'movq', 'movsb', 'movsl', 'movsw',
-    'movs', 'movz', 'mul', 'neg', 'nop', 'not', 'or', 'out',
-    'outsb', 'outsl', 'outsw', 'packssd', 'packssw', 'packusw',
-    'paddb', 'paddd', 'paddsb', 'paddsiw', 'paddsw', 'paddusb',
-    'paddusw', 'paddw', 'pand', 'pandn', 'paveb',
-    'pavgusb', 'pcmpeqb',
-    'pcmpeqd', 'pcmpeqw', 'pcmpgtb', 'pcmpgtd', 'pcmpgtw',
-    'pdistib',
-    'pf2id', 'pfacc', 'pfadd', 'pfcmpeq', 'pfcmpge', 'pfcmpgt',
-    'pfmax', 'pfmin', 'pfmul', 'pfrcp', 'pfrcpit1', 'pfrcpit2',
-    'pfrsqit1', 'pfrsqrt', 'pfsub', 'pfsubr', 'pi2fd',
-    'pmachriw', 'pmaddwd', 'pmagw', 'pmulhriw', 'pmulhrwa', 'pmulhrwc',
-    'pmulhw', 'pmullw', 'pmvgezb', 'pmvlzb', 'pmvnzb',
-    'pmvzb', 'pop', 'popa', 'popal', 'popaw', 'popf', 'popfl',
-    'popfw', 'por',
-    'prefetch', 'prefetchw', 'pslld', 'psllq', 'psllw', 'psrad', 'psraw',
-    'psrld', 'psrlq', 'psrlw', 'psubb', 'psubd', 'psubsb',
-    'psubsiw', 'psubsw', 'psubusb', 'psubusw', 'psubw', 'punpckhbw',
-    'punpckhdq', 'punpckhwd', 'punpcklbw', 'punpckldq', 'punpcklwd',
-    'push', 'pusha', 'pushal', 'pushaw', 'pushf', 'pushfl',
-    'pushfw', 'pxor', 'rcl', 'rcr', 'rdmsr', 'rdpmc', 'rdtsc',
-    'resb', 'ret', 'retf', 'retn',
-    'rol', 'ror', 'rsm', 'sahf', 'sal', 'salc', 'sar', 'sbb',
-    'scasb', 'scasl', 'scasw', 'sgdt', 'shl', 'shld', 'shr', 'shrd',
-    'sidt', 'sldt', 'smi', 'smsw', 'stc', 'std', 'sti', 'stosb',
-    'stosl', 'stosw', 'str', 'sub', 'test', 'umov', 'verr', 'verw',
-    'wait', 'wbinvd', 'wrmsr', 'xadd', 'xbts', 'xchg', 'xlat', 'xlatb',
-    'xor','cmov','j','set'
-  );
-
-  att_nosuffix:array[tasmop] of boolean=(
-    { 0 }
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    { 100 }
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    { 200 }
-    false,true,true,true,true,true,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    true,true,true,true,true,true,true,true,true,true,
-    true,true,true,true,true,true,true,true,true,true,
-    true,true,true,true,true,true,true,true,true,true,
-    true,true,true,true,true,true,true,true,true,true,
-    true,true,true,true,true,true,true,true,false,false,
-    false,false,false,false,false,false,false,false,true,true,
-    true,true,true,true,true,true,true,true,true,true,
-    true,true,true,true,true,true,true,true,true,true,
-    { 300 }
-    false,false,true,true,false,true,true,true,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false,false,false,false,false,false,false,false,false,false,
-    false
-  );
-
-{$endif ATTOP}
-
-
-{*****************************************************************************
-                                Operand Sizes
-*****************************************************************************}
-
-type
-  topsize = (S_NO,
-    S_B,S_W,S_L,S_BW,S_BL,S_WL,
-    S_IS,S_IL,S_IQ,
-    S_FS,S_FL,S_FX,S_D,S_Q,S_FV
-  );
-
-const
-  { Intel style operands ! }
-  opsize_2_type:array[0..2,topsize] of longint=(
-    (OT_NONE,
-     OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
-     OT_BITS16,OT_BITS32,OT_BITS64,
-     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
-    ),
-    (OT_NONE,
-     OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
-     OT_BITS16,OT_BITS32,OT_BITS64,
-     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
-    ),
-    (OT_NONE,
-     OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
-     OT_BITS16,OT_BITS32,OT_BITS64,
-     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64
-    )
-  );
-
-{$ifdef ATTOP}
-  att_opsize2str : array[topsize] of string[2] = ('',
-    'b','w','l','bw','bl','wl',
-    's','l','q',
-    's','l','t','d','q','v'
-  );
-{$endif}
-
-
-{*****************************************************************************
-                                Conditions
-*****************************************************************************}
-
-type
-  TAsmCond=(C_None,
-    C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
-    C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
-    C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
-  );
-
-const
-  cond2str:array[TAsmCond] of string[3]=('',
-    'a', 'ae', 'b', 'be', 'c', 'e', 'g', 'ge', 'l', 'le', 'na', 'nae',
-    'nb', 'nbe', 'nc', 'ne', 'ng', 'nge', 'nl', 'nle', 'no', 'np',
-    'ns', 'nz', 'o', 'p', 'pe', 'po', 's', 'z'
-  );
-  inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
-    C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
-    C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
-    C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
-  );
-
-const
-  CondAsmOps=3;
-  CondAsmOp:array[0..CondAsmOps-1] of TasmOp=(
-    A_CMOVcc, A_Jcc, A_SETcc
-  );
-  CondAsmOpStr:array[0..CondAsmOps-1] of string[4]=(
-    'CMOV','J','SET'
-  );
-
-
-{*****************************************************************************
-                                  Registers
-*****************************************************************************}
-
-type
-  { enumeration for registers, don't change the order }
-  { it's used by the register size conversions        }
-  tregister = (R_NO,
-    R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
-    R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
-    R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
-    R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
-    R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
-    R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
-    R_CR0,R_CR2,R_CR3,R_CR4,
-    R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
-    R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
-    R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
-  );
-
-  tregisterset = set of tregister;
-
-  reg2strtable = array[tregister] of string[6];
-
-const
-  firstreg = low(tregister);
-  lastreg  = high(tregister);
-
-  firstsreg = R_CS;
-  lastsreg  = R_GS;
-
-  regset8bit  : tregisterset = [R_AL..R_DH];
-  regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
-  regset32bit : tregisterset = [R_EAX..R_EDI];
-
-  { Convert reg to opsize }
-  reg_2_opsize:array[firstreg..lastreg] of topsize = (S_NO,
-    S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
-    S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
-    S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
-    S_W,S_W,S_W,S_W,S_W,S_W,
-    S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
-    S_L,S_L,S_L,S_L,S_L,S_L,
-    S_L,S_L,S_L,S_L,
-    S_L,S_L,S_L,S_L,S_L,
-    S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
-    S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
-  );
-
-  { Convert reg to operand type }
-  reg_2_type:array[firstreg..lastreg] of longint = (OT_NONE,
-    OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
-    OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
-    OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
-    OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
-    OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
-    OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
-    OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
-    OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
-    OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
-    OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG
-  );
-
-{$ifdef INTELOP}
-  int_reg2str : reg2strtable = ('',
-    'eax','ecx','edx','ebx','esp','ebp','esi','edi',
-    'ax','cx','dx','bx','sp','bp','si','di',
-    'al','cl','dl','bl','ah','ch','bh','dh',
-    'cs','ds','es','ss','fs','gs',
-    'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
-    'dr0','dr1','dr2','dr3','dr6','dr7',
-    'cr0','cr2','cr3','cr4',
-    'tr3','tr4','tr5','tr6','tr7',
-    'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
-    'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
-  );
-
-  int_nasmreg2str : reg2strtable = ('',
-    'eax','ecx','edx','ebx','esp','ebp','esi','edi',
-    'ax','cx','dx','bx','sp','bp','si','di',
-    'al','cl','dl','bl','ah','ch','bh','dh',
-    'cs','ds','es','ss','fs','gs',
-    'st0','st0','st1','st2','st3','st4','st5','st6','st7',
-    'dr0','dr1','dr2','dr3','dr6','dr7',
-    'cr0','cr2','cr3','cr4',
-    'tr3','tr4','tr5','tr6','tr7',
-    'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
-    'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
-  );
-{$endif}
-
-{$ifdef ATTREG}
-  att_reg2str : reg2strtable = ('',
-    '%eax','%ecx','%edx','%ebx','%esp','%ebp','%esi','%edi',
-    '%ax','%cx','%dx','%bx','%sp','%bp','%si','%di',
-    '%al','%cl','%dl','%bl','%ah','%ch','%bh','%dh',
-    '%cs','%ds','%es','%ss','%fs','%gs',
-    '%st','%st(0)','%st(1)','%st(2)','%st(3)','%st(4)','%st(5)','%st(6)','%st(7)',
-    '%dr0','%dr1','%dr2','%dr3','%dr6','%dr7',
-    '%cr0','%cr2','%cr3','%cr4',
-    '%tr3','%tr4','%tr5','%tr6','%tr7',
-    '%mm0','%mm1','%mm2','%mm3','%mm4','%mm5','%mm6','%mm7',
-    '%xmm0','%xmm1','%xmm2','%xmm3','%xmm4','%xmm5','%xmm6','%xmm7'
-  );
-{$endif ATTREG}
-
-
-{*****************************************************************************
-                                   Flags
-*****************************************************************************}
-
-type
-  TResFlags = (F_E,F_NE,F_G,F_L,F_GE,F_LE,F_C,F_NC,F_A,F_AE,F_B,F_BE);
-
-const
-  { arrays for boolean location conversions }
-  flag_2_cond : array[TResFlags] of TAsmCond =
-     (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
-
-
-{*****************************************************************************
-                                Reference
-*****************************************************************************}
-
-type
-  trefoptions=(ref_none,ref_parafixup,ref_localfixup);
-
-  { immediate/reference record }
-  preference = ^treference;
-  treference = packed record
-     is_immediate : boolean; { is this used as reference or immediate }
-     segment,
-     base,
-     index       : tregister;
-     scalefactor : byte;
-     offset      : longint;
-     symbol      : pasmsymbol;
-     offsetfixup : longint;
-     options     : trefoptions;
-  end;
-
-{*****************************************************************************
-                                Operands
-*****************************************************************************}
-
-       { Types of operand }
-        toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
-
-        toper=record
-          ot  : longint;
-          case typ : toptype of
-           top_none   : ();
-           top_reg    : (reg:tregister);
-           top_ref    : (ref:preference);
-           top_const  : (val:longint);
-           top_symbol : (sym:pasmsymbol;symofs:longint);
-        end;
-
-{*****************************************************************************
-                               Generic Location
-*****************************************************************************}
-
-type
-  TLoc=(
-    LOC_INVALID,     { added for tracking problems}
-    LOC_FPU,         { FPU stack }
-    LOC_REGISTER,    { in a processor register }
-    LOC_MEM,         { in memory }
-    LOC_REFERENCE,   { like LOC_MEM, but lvalue }
-    LOC_JUMP,        { boolean results only, jump to false or true label }
-    LOC_FLAGS,       { boolean results only, flags are set }
-    LOC_CREGISTER,   { Constant register which shouldn't be modified }
-    LOC_MMXREGISTER, { MMX register }
-    LOC_CMMXREGISTER { Constant MMX register }
-  );
-
-  plocation = ^tlocation;
-  tlocation = packed record
-     case loc : tloc of
-        LOC_MEM,LOC_REFERENCE : (reference : treference);
-        LOC_FPU : ();
-        LOC_JUMP : ();
-        LOC_FLAGS : (resflags : tresflags);
-        LOC_INVALID : ();
-
-        { it's only for better handling }
-        LOC_MMXREGISTER : (mmxreg : tregister);
-        { segment in reference at the same place as in loc_register }
-        LOC_REGISTER,LOC_CREGISTER : (
-        case longint of
-          1 : (register,segment,registerhigh : tregister);
-          { overlay a registerlow }
-          2 : (registerlow : tregister);
-        );
-  end;
-
-
-{*****************************************************************************
-                                 Constants
-*****************************************************************************}
-
-type
-  tcpuflags = (cf_registers64);
-
-const
-  general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
-
-  intregs = general_registers;
-  fpuregs = [];
-  mmregs = [R_MM0..R_MM7];
-
-  registers_saved_on_cdecl = [R_ESI,R_EDI,R_EBX];
-
-  { generic register names }
-  stack_pointer = R_ESP;
-  frame_pointer = R_EBP;
-  self_pointer  = R_ESI;
-  accumulator   = R_EAX;
-
-  cpuflags : set of tcpuflags = [];
-
-  { sizes }
-  pointersize   = 4;
-  extended_size = 10;
-  sizepostfix_pointer = S_L;
-
-
-{*****************************************************************************
-                              Instruction table
-*****************************************************************************}
-
-{$ifndef NOAG386BIN}
-type
-  tinsentry=packed record
-    opcode  : tasmop;
-    ops     : byte;
-    optypes : array[0..2] of longint;
-    code    : array[0..maxinfolen] of char;
-    flags   : longint;
-  end;
-  pinsentry=^tinsentry;
-
-  TInsTabCache=array[TasmOp] of longint;
-  PInsTabCache=^TInsTabCache;
-
-const
-  InsTab:array[0..instabentries-1] of TInsEntry=
-{$i i386tab.inc}
-
-var
-  InsTabCache : PInsTabCache;
-{$endif NOAG386BIN}
-
-
-{*****************************************************************************
-                                  Helpers
-*****************************************************************************}
-
-    const
-       maxvarregs = 4;
-       varregs : array[1..maxvarregs] of tregister =
-         (R_EBX,R_EDX,R_ECX,R_EAX);
-
-    function imm_2_type(l:longint):longint;
-
-    { the following functions allow to convert registers }
-    { for example reg8toreg32(R_AL) returns R_EAX        }
-    { for example reg16toreg32(R_AL) gives an undefined  }
-    { result                                             }
-    { these functions expects that the turn of           }
-    { tregister isn't changed                            }
-    function reg8toreg16(reg : tregister) : tregister;
-    function reg8toreg32(reg : tregister) : tregister;
-    function reg16toreg8(reg : tregister) : tregister;
-    function reg32toreg8(reg : tregister) : tregister;
-    function reg32toreg16(reg : tregister) : tregister;
-    function reg16toreg32(reg : tregister) : tregister;
-
-    { these procedures must be defined by all target cpus }
-    function regtoreg8(reg : tregister) : tregister;
-    function regtoreg16(reg : tregister) : tregister;
-    function regtoreg32(reg : tregister) : tregister;
-
-    { can be ignored on 32 bit systems }
-    function regtoreg64(reg : tregister) : tregister;
-
-    { returns the operand prefix for a given register }
-    function regsize(reg : tregister) : topsize;
-
-    { resets all values of ref to defaults }
-    procedure reset_reference(var ref : treference);
-    { set mostly used values of a new reference }
-    function new_reference(base : tregister;offset : longint) : preference;
-
-    function newreference(const r : treference) : preference;
-    procedure disposereference(var r : preference);
-
-    function reg2str(r : tregister) : string;
-
-    function is_calljmp(o:tasmop):boolean;
-
-
-implementation
-
-{$ifdef heaptrc}
-  uses
-      ppheap;
-{$endif heaptrc}
-
-{*****************************************************************************
-                                  Helpers
-*****************************************************************************}
-
-    function imm_2_type(l:longint):longint;
-      begin
-        if (l>=-128) and (l<=127) then
-         imm_2_type:=OT_IMM8 or OT_SIGNED
-        else
-         if (l>=-255) and (l<=255) then
-          imm_2_type:=OT_IMM8
-        else
-         if (l>=-32768) and (l<=32767) then
-          imm_2_type:=OT_IMM16 or OT_SIGNED
-        else
-         if (l>=-65536) and (l<=65535) then
-          imm_2_type:=OT_IMM16 or OT_SIGNED
-         else
-          imm_2_type:=OT_IMM32;
-      end;
-
-    function reg2str(r : tregister) : string;
-      const
-         a : array[R_NO..R_BL] of string[3] =
-          ('','EAX','ECX','EDX','EBX','ESP','EBP','ESI','EDI',
-           'AX','CX','DX','BX','SP','BP','SI','DI',
-           'AL','CL','DL','BL');
-      begin
-         reg2str:=a[r];
-      end;
-
-
-    function is_calljmp(o:tasmop):boolean;
-      begin
-        case o of
-          A_CALL,
-          A_JCXZ,
-          A_JECXZ,
-          A_JMP,
-          A_LOOP,
-          A_Jcc :
-            is_calljmp:=true;
-          else
-            is_calljmp:=false;
-        end;
-      end;
-
-
-    procedure disposereference(var r : preference);
-      begin
-         dispose(r);
-         r:=nil;
-      end;
-
-
-    function newreference(const r : treference) : preference;
-      var
-         p : preference;
-      begin
-         new(p);
-         p^:=r;
-         newreference:=p;
-      end;
-
-
-    function reg8toreg16(reg : tregister) : tregister;
-
-      begin
-         reg8toreg16:=reg32toreg16(reg8toreg32(reg));
-      end;
-
-    function reg16toreg8(reg : tregister) : tregister;
-
-      begin
-         reg16toreg8:=reg32toreg8(reg16toreg32(reg));
-      end;
-
-    function reg16toreg32(reg : tregister) : tregister;
-
-      begin
-         reg16toreg32:=tregister(byte(reg)-byte(R_EDI));
-      end;
-
-    function reg32toreg16(reg : tregister) : tregister;
-
-      begin
-         reg32toreg16:=tregister(byte(reg)+byte(R_EDI));
-      end;
-
-    function reg32toreg8(reg : tregister) : tregister;
-
-      begin
-         reg32toreg8:=tregister(byte(reg)+byte(R_DI));
-      end;
-
-    function reg8toreg32(reg : tregister) : tregister;
-
-      begin
-         reg8toreg32:=tregister(byte(reg)-byte(R_DI));
-      end;
-
-    function regtoreg8(reg : tregister) : tregister;
-
-     begin
-        regtoreg8:=reg32toreg8(reg);
-     end;
-
-    function regtoreg16(reg : tregister) : tregister;
-
-     begin
-        regtoreg16:=reg32toreg16(reg);
-     end;
-
-    function regtoreg32(reg : tregister) : tregister;
-
-     begin
-        regtoreg32:=reg;
-     end;
-
-    function regtoreg64(reg : tregister) : tregister;
-
-     begin
-        { to avoid warning }
-        regtoreg64:=R_NO;
-     end;
-
-function regsize(reg : tregister) : topsize;
-begin
-   if reg in regset8bit then
-     regsize:=S_B
-   else if reg in regset16bit then
-     regsize:=S_W
-   else if reg in regset32bit then
-     regsize:=S_L;
-end;
-
-
-procedure reset_reference(var ref : treference);
-begin
-  FillChar(ref,sizeof(treference),0);
-end;
-
-
-function new_reference(base : tregister;offset : longint) : preference;
-var
-  r : preference;
-begin
-  new(r);
-  FillChar(r^,sizeof(treference),0);
-  r^.base:=base;
-  r^.offset:=offset;
-  new_reference:=r;
-end;
-
-
-{*****************************************************************************
-                              Instruction table
-*****************************************************************************}
-
-var
-  saveexit : pointer;
-
-procedure FreeInsTabCache;{$ifndef FPC}far;{$endif}
-begin
-  exitproc:=saveexit;
-{$ifndef NOAG386BIN}
-  dispose(instabcache);
-{$endif NOAG386BIN}
-end;
-
-
-procedure BuildInsTabCache;
-{$ifndef NOAG386BIN}
-var
-  i : longint;
-{$endif}
-begin
-{$ifndef NOAG386BIN}
-  new(instabcache);
-  FillChar(instabcache^,sizeof(tinstabcache),$ff);
-  i:=0;
-  while (i<InsTabEntries) do
-   begin
-     if InsTabCache^[InsTab[i].OPcode]=-1 then
-      InsTabCache^[InsTab[i].OPcode]:=i;
-     inc(i);
-   end;
-{$endif NOAG386BIN}
-  saveexit:=exitproc;
-  exitproc:=@FreeInsTabCache;
-end;
-
-
-begin
-  BuildInsTabCache;
-end.
-{
-  $Log$
-  Revision 1.10  1999-08-02 21:28:58  florian
-    * the main branch psub.pas is now used for
-      newcg compiler
-
-  Revision 1.9  1999/08/02 21:01:45  michael
-  * Moved toperand type back =(
-
-  Revision 1.8  1999/08/02 20:45:49  michael
-  * Moved toperand type to aasm
-
-  Revision 1.7  1999/08/02 17:17:09  florian
-    * small changes for the new code generator
-
-  Revision 1.6  1999/06/06 15:53:15  peter
-    * suffix adding can be turned of for some tasmops in att_nosuffix array
-
-  Revision 1.5  1999/05/27 19:44:34  peter
-    * removed oldasm
-    * plabel -> pasmlabel
-    * -a switches to source writing automaticly
-    * assembler readers OOPed
-    * asmsymbol automaticly external
-    * jumptables and other label fixes for asm readers
-
-  Revision 1.4  1999/05/17 14:33:50  pierre
-   uses heaptrc need for extrainfo with heaptrc
-
-  Revision 1.3  1999/05/12 00:19:51  peter
-    * removed R_DEFAULT_SEG
-    * uniform float names
-
-  Revision 1.2  1999/05/11 16:30:00  peter
-    * more noag386bin defines, so tp7 can compile at least
-
-  Revision 1.1  1999/05/01 13:24:23  peter
-    * merged nasm compiler
-    * old asm moved to oldasm/
-
-  Revision 1.13  1999/04/14 09:07:43  peter
-    * asm reader improvements
-
-  Revision 1.12  1999/04/10 16:14:09  peter
-    * fixed optimizer
-
-  Revision 1.11  1999/03/31 13:55:33  peter
-    * assembler inlining working for ag386bin
-
-  Revision 1.10  1999/03/29 16:05:50  peter
-    * optimizer working for ag386bin
-
-  Revision 1.9  1999/03/26 00:01:14  peter
-    * first things for optimizer (compiles but cycle crashes)
-
-  Revision 1.8  1999/03/06 17:24:21  peter
-    * rewritten intel parser a lot, especially reference reading
-    * size checking added for asm parsers
-
-  Revision 1.7  1999/03/02 02:56:20  peter
-    + stabs support for binary writers
-    * more fixes and missing updates from the previous commit :(
-
-  Revision 1.6  1999/03/01 15:46:22  peter
-    * ag386bin finally make cycles correct
-    * prefixes are now also normal opcodes
-
-  Revision 1.5  1999/02/26 00:48:29  peter
-    * assembler writers fixed for ag386bin
-
-  Revision 1.4  1999/02/25 21:03:04  peter
-    * ag386bin updates
-    + coff writer
-
-  Revision 1.3  1999/02/22 02:44:18  peter
-    * ag386bin doesn't use i386.pas anymore
-
-  Revision 1.2  1999/02/22 02:16:03  peter
-    * updates for ag386bin
-
-  Revision 1.1  1999/02/16 17:59:38  peter
-    + initial files
-
-}