Browse Source

merge with trunk

git-svn-id: branches/tg74/avx2@28413 -
tg74 11 years ago
parent
commit
60db1d733e
41 changed files with 3971 additions and 775 deletions
  1. 5 1
      .gitattributes
  2. 562 149
      compiler/i8086/cgcpu.pas
  3. 1 0
      compiler/i8086/cpubase.inc
  4. 2 2
      compiler/i8086/cpuinfo.pas
  5. 6 1
      compiler/i8086/cpunode.pas
  6. 22 19
      compiler/i8086/cpupara.pas
  7. 228 22
      compiler/i8086/hlcgcpu.pas
  8. 85 16
      compiler/i8086/i8086att.inc
  9. 82 13
      compiler/i8086/i8086atts.inc
  10. 85 16
      compiler/i8086/i8086int.inc
  11. 1 1
      compiler/i8086/i8086nop.inc
  12. 85 16
      compiler/i8086/i8086op.inc
  13. 148 79
      compiler/i8086/i8086prop.inc
  14. 1003 9
      compiler/i8086/i8086tab.inc
  15. 370 16
      compiler/i8086/n8086add.pas
  16. 35 4
      compiler/i8086/n8086cal.pas
  17. 18 104
      compiler/i8086/n8086cnv.pas
  18. 16 5
      compiler/i8086/n8086con.pas
  19. 138 4
      compiler/i8086/n8086inl.pas
  20. 91 0
      compiler/i8086/n8086ld.pas
  21. 121 100
      compiler/i8086/n8086mat.pas
  22. 46 28
      compiler/i8086/n8086mem.pas
  23. 77 0
      compiler/i8086/n8086tcon.pas
  24. 127 0
      compiler/i8086/n8086util.pas
  25. 8 8
      compiler/i8086/r8086ari.inc
  26. 4 4
      compiler/i8086/r8086att.inc
  27. 22 22
      compiler/i8086/r8086con.inc
  28. 1 1
      compiler/i8086/r8086dwrf.inc
  29. 4 4
      compiler/i8086/r8086int.inc
  30. 8 8
      compiler/i8086/r8086iri.inc
  31. 4 4
      compiler/i8086/r8086nasm.inc
  32. 8 8
      compiler/i8086/r8086nri.inc
  33. 7 7
      compiler/i8086/r8086num.inc
  34. 0 82
      compiler/i8086/r8086op.inc
  35. 3 3
      compiler/i8086/r8086ot.inc
  36. 2 2
      compiler/i8086/r8086rni.inc
  37. 8 8
      compiler/i8086/r8086sri.inc
  38. 4 4
      compiler/i8086/r8086std.inc
  39. 18 5
      compiler/i8086/rgcpu.pas
  40. 458 0
      compiler/i8086/symcpu.pas
  41. 58 0
      compiler/i8086/tgcpu.pas

+ 5 - 1
.gitattributes

@@ -251,8 +251,11 @@ compiler/i8086/n8086cal.pas svneol=native#text/plain
 compiler/i8086/n8086cnv.pas svneol=native#text/plain
 compiler/i8086/n8086cnv.pas svneol=native#text/plain
 compiler/i8086/n8086con.pas svneol=native#text/plain
 compiler/i8086/n8086con.pas svneol=native#text/plain
 compiler/i8086/n8086inl.pas svneol=native#text/plain
 compiler/i8086/n8086inl.pas svneol=native#text/plain
+compiler/i8086/n8086ld.pas svneol=native#text/plain
 compiler/i8086/n8086mat.pas svneol=native#text/plain
 compiler/i8086/n8086mat.pas svneol=native#text/plain
 compiler/i8086/n8086mem.pas svneol=native#text/plain
 compiler/i8086/n8086mem.pas svneol=native#text/plain
+compiler/i8086/n8086tcon.pas svneol=native#text/plain
+compiler/i8086/n8086util.pas svneol=native#text/plain
 compiler/i8086/r8086ari.inc svneol=native#text/plain
 compiler/i8086/r8086ari.inc svneol=native#text/plain
 compiler/i8086/r8086att.inc svneol=native#text/plain
 compiler/i8086/r8086att.inc svneol=native#text/plain
 compiler/i8086/r8086con.inc svneol=native#text/plain
 compiler/i8086/r8086con.inc svneol=native#text/plain
@@ -263,7 +266,6 @@ compiler/i8086/r8086nasm.inc svneol=native#text/plain
 compiler/i8086/r8086nor.inc svneol=native#text/plain
 compiler/i8086/r8086nor.inc svneol=native#text/plain
 compiler/i8086/r8086nri.inc svneol=native#text/plain
 compiler/i8086/r8086nri.inc svneol=native#text/plain
 compiler/i8086/r8086num.inc svneol=native#text/plain
 compiler/i8086/r8086num.inc svneol=native#text/plain
-compiler/i8086/r8086op.inc svneol=native#text/plain
 compiler/i8086/r8086ot.inc svneol=native#text/plain
 compiler/i8086/r8086ot.inc svneol=native#text/plain
 compiler/i8086/r8086rni.inc svneol=native#text/plain
 compiler/i8086/r8086rni.inc svneol=native#text/plain
 compiler/i8086/r8086sri.inc svneol=native#text/plain
 compiler/i8086/r8086sri.inc svneol=native#text/plain
@@ -272,6 +274,8 @@ compiler/i8086/r8086std.inc svneol=native#text/plain
 compiler/i8086/ra8086att.pas svneol=native#text/plain
 compiler/i8086/ra8086att.pas svneol=native#text/plain
 compiler/i8086/ra8086int.pas svneol=native#text/plain
 compiler/i8086/ra8086int.pas svneol=native#text/plain
 compiler/i8086/rgcpu.pas svneol=native#text/plain
 compiler/i8086/rgcpu.pas svneol=native#text/plain
+compiler/i8086/symcpu.pas svneol=native#text/plain
+compiler/i8086/tgcpu.pas svneol=native#text/plain
 compiler/ia64/aasmcpu.pas svneol=native#text/plain
 compiler/ia64/aasmcpu.pas svneol=native#text/plain
 compiler/ia64/cpubase.pas svneol=native#text/plain
 compiler/ia64/cpubase.pas svneol=native#text/plain
 compiler/ia64/cpuinfo.pas svneol=native#text/plain
 compiler/ia64/cpuinfo.pas svneol=native#text/plain

File diff suppressed because it is too large
+ 562 - 149
compiler/i8086/cgcpu.pas


+ 1 - 0
compiler/i8086/cpubase.inc

@@ -157,6 +157,7 @@
       }
       }
       saved_standard_registers : array[0..0] of tsuperregister = (RS_BP);
       saved_standard_registers : array[0..0] of tsuperregister = (RS_BP);
 
 
+      saved_address_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       {# Required parameter alignment when calling a routine declared as
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          stdcall and cdecl. The alignment value should be the one defined

+ 2 - 2
compiler/i8086/cpuinfo.pas

@@ -123,9 +123,9 @@ Const
                                   cs_opt_tailrecursion,cs_opt_nodecse,cs_useebp,
                                   cs_opt_tailrecursion,cs_opt_nodecse,cs_useebp,
 				  cs_opt_reorder_fields,cs_opt_fastmath];
 				  cs_opt_reorder_fields,cs_opt_fastmath];
 
 
-   level1optimizerswitches = genericlevel1optimizerswitches + [cs_opt_peephole];
+   level1optimizerswitches = genericlevel1optimizerswitches;
    level2optimizerswitches = genericlevel2optimizerswitches + level1optimizerswitches +
    level2optimizerswitches = genericlevel2optimizerswitches + level1optimizerswitches +
-     [{cs_opt_regvar,}cs_opt_stackframe,cs_opt_tailrecursion,cs_opt_nodecse];
+     [{cs_opt_regvar,}cs_opt_stackframe,cs_opt_tailrecursion{,cs_opt_nodecse}];
    level3optimizerswitches = genericlevel3optimizerswitches + level2optimizerswitches + [{,cs_opt_loopunroll}];
    level3optimizerswitches = genericlevel3optimizerswitches + level2optimizerswitches + [{,cs_opt_loopunroll}];
    level4optimizerswitches = genericlevel4optimizerswitches + level3optimizerswitches + [cs_useebp];
    level4optimizerswitches = genericlevel4optimizerswitches + level3optimizerswitches + [cs_useebp];
 
 

+ 6 - 1
compiler/i8086/cpunode.pas

@@ -50,11 +50,16 @@ unit cpunode;
        n8086add,
        n8086add,
        n8086cal,
        n8086cal,
        n8086cnv,
        n8086cnv,
+       n8086ld,
        n8086mem{,
        n8086mem{,
        n386set},
        n386set},
        n8086inl,
        n8086inl,
        n8086mat,
        n8086mat,
-       n8086con
+       n8086con,
+       { these are not really nodes }
+       n8086util,n8086tcon,tgcpu,
+       { symtable }
+       symcpu
        ;
        ;
 
 
 end.
 end.

+ 22 - 19
compiler/i8086/cpupara.pas

@@ -67,7 +67,7 @@ unit cpupara;
     uses
     uses
        cutils,
        cutils,
        systems,verbose,
        systems,verbose,
-       symtable,
+       symtable,symcpu,
        defutil;
        defutil;
 
 
       const
       const
@@ -418,13 +418,15 @@ unit cpupara;
         paracgsize : tcgsize;
         paracgsize : tcgsize;
         firstparaloc,
         firstparaloc,
         pushaddr   : boolean;
         pushaddr   : boolean;
+        pushleftright: boolean;
       begin
       begin
         paraalign:=get_para_align(p.proccalloption);
         paraalign:=get_para_align(p.proccalloption);
-        { we push Flags and CS as long
-          to cope with the IRETD
-          and we save 6 register + 4 selectors }
+        { interrupt routines need parameter fixup }
         if po_interrupt in p.procoptions then
         if po_interrupt in p.procoptions then
-          inc(parasize,8+6*4+4*2);
+          if is_proc_far(p) then
+            dec(parasize,6)
+          else
+            dec(parasize,4);
         { Offset is calculated like:
         { Offset is calculated like:
            sub esp,12
            sub esp,12
            mov [esp+8],para3
            mov [esp+8],para3
@@ -434,20 +436,21 @@ unit cpupara;
           That means for pushes the para with the
           That means for pushes the para with the
           highest offset (see para3) needs to be pushed first
           highest offset (see para3) needs to be pushed first
         }
         }
-        if p.proccalloption in pushleftright_pocalls then
+        pushleftright:=(p.proccalloption in pushleftright_pocalls) or (po_interrupt in p.procoptions);
+        if pushleftright then
           i:=paras.count-1
           i:=paras.count-1
         else
         else
           i:=0;
           i:=0;
-        while ((p.proccalloption in pushleftright_pocalls) and (i>=0)) or
-              (not(p.proccalloption in pushleftright_pocalls) and (i<=paras.count-1)) do
+        while (pushleftright and (i>=0)) or
+              (not(pushleftright) and (i<=paras.count-1)) do
           begin
           begin
             hp:=tparavarsym(paras[i]);
             hp:=tparavarsym(paras[i]);
             paradef:=hp.vardef;
             paradef:=hp.vardef;
             pushaddr:=push_addr_param(hp.varspez,paradef,p.proccalloption);
             pushaddr:=push_addr_param(hp.varspez,paradef,p.proccalloption);
             if pushaddr then
             if pushaddr then
               begin
               begin
-                paralen:=sizeof(aint);
-                paracgsize:=OS_ADDR;
+                paralen:=voidpointertype.size;
+                paracgsize:=int_cgsize(voidpointertype.size);
                 paradef:=getpointerdef(paradef);
                 paradef:=getpointerdef(paradef);
               end
               end
             else
             else
@@ -496,7 +499,7 @@ unit cpupara;
                 if side=calleeside then
                 if side=calleeside then
                   begin
                   begin
                     inc(paraloc^.reference.offset,target_info.first_parm_offset);
                     inc(paraloc^.reference.offset,target_info.first_parm_offset);
-                    if po_far in p.procoptions then
+                    if is_proc_far(p) then
                       inc(paraloc^.reference.offset,2);
                       inc(paraloc^.reference.offset,2);
                   end;
                   end;
                 parasize:=align(parasize+paralen,varalign);
                 parasize:=align(parasize+paralen,varalign);
@@ -546,7 +549,7 @@ unit cpupara;
                         else
                         else
                           { return addres }
                           { return addres }
                           inc(paraloc^.reference.offset,2);
                           inc(paraloc^.reference.offset,2);
-                        if po_far in p.procoptions then
+                        if is_proc_far(p) then
                           inc(paraloc^.reference.offset,2);
                           inc(paraloc^.reference.offset,2);
                       end;
                       end;
                     parasize:=align(parasize+l,varalign);
                     parasize:=align(parasize+l,varalign);
@@ -554,7 +557,7 @@ unit cpupara;
                     firstparaloc:=false;
                     firstparaloc:=false;
                   end;
                   end;
               end;
               end;
-            if p.proccalloption in pushleftright_pocalls then
+            if pushleftright then
               dec(i)
               dec(i)
             else
             else
               inc(i);
               inc(i);
@@ -606,8 +609,8 @@ unit cpupara;
                     pushaddr:=push_addr_param(hp.varspez,hp.vardef,p.proccalloption);
                     pushaddr:=push_addr_param(hp.varspez,hp.vardef,p.proccalloption);
                     if pushaddr then
                     if pushaddr then
                       begin
                       begin
-                        paralen:=sizeof(aint);
-                        paracgsize:=OS_ADDR;
+                        paralen:=voidpointertype.size;
+                        paracgsize:=int_cgsize(voidpointertype.size);
                         paradef:=getpointerdef(paradef);
                         paradef:=getpointerdef(paradef);
                       end
                       end
                     else
                     else
@@ -669,7 +672,7 @@ unit cpupara;
                               if side=calleeside then
                               if side=calleeside then
                                 begin
                                 begin
                                   inc(paraloc^.reference.offset,target_info.first_parm_offset);
                                   inc(paraloc^.reference.offset,target_info.first_parm_offset);
-                                  if po_far in p.procoptions then
+                                  if is_proc_far(p) then
                                     inc(paraloc^.reference.offset,2);
                                     inc(paraloc^.reference.offset,2);
                                 end;
                                 end;
                               parasize:=align(parasize+paralen,varalign);
                               parasize:=align(parasize+paralen,varalign);
@@ -692,8 +695,8 @@ unit cpupara;
                                     end
                                     end
                                   else
                                   else
                                     begin
                                     begin
-                                      { We can allocate at maximum 32 bits per location }
-                                      if paralen>sizeof(aint) then
+                                      { We can allocate at maximum 16 bits per location }
+                                      if paralen>=sizeof(aint) then
                                         begin
                                         begin
                                           l:=sizeof(aint);
                                           l:=sizeof(aint);
                                           paraloc^.def:=uinttype;
                                           paraloc^.def:=uinttype;
@@ -714,7 +717,7 @@ unit cpupara;
                                   if side=calleeside then
                                   if side=calleeside then
                                     begin
                                     begin
                                       inc(paraloc^.reference.offset,target_info.first_parm_offset);
                                       inc(paraloc^.reference.offset,target_info.first_parm_offset);
-                                      if po_far in p.procoptions then
+                                      if is_proc_far(p) then
                                         inc(paraloc^.reference.offset,2);
                                         inc(paraloc^.reference.offset,2);
                                     end;
                                     end;
                                   parasize:=align(parasize+l,varalign);
                                   parasize:=align(parasize+l,varalign);

+ 228 - 22
compiler/i8086/hlcgcpu.pas

@@ -29,7 +29,7 @@ unit hlcgcpu;
 interface
 interface
 
 
   uses
   uses
-    globals,
+    globals,globtype,
     aasmdata,
     aasmdata,
     symtype,symdef,parabase,
     symtype,symdef,parabase,
     cgbase,cgutils,
     cgbase,cgutils,
@@ -37,10 +37,43 @@ interface
 
 
 
 
   type
   type
+
+    { thlcgcpu }
+
     thlcgcpu = class(thlcgx86)
     thlcgcpu = class(thlcgx86)
+     private
+      { checks whether the type needs special methodptr-like handling, when stored
+        in a LOC_REGISTER location. This applies to the following types:
+          - i8086 method pointers (incl. 6-byte mixed near + far),
+          - 6-byte records (only in the medium and compact memory model are these
+              loaded in a register)
+          - nested proc ptrs
+        When stored in a LOC_REGISTER tlocation, these types use both register
+        and registerhi with the following sizes:
+
+        register   - cgsize = int_cgsize(voidcodepointertype.size)
+        registerhi - cgsize = int_cgsize(voidpointertype.size) or int_cgsize(parentfpvoidpointertype.size)
+                              (check d.size to determine which one of the two)
+        }
+      function is_methodptr_like_type(d:tdef): boolean;
+
+      { 4-byte records in registers need special handling as well. A record may
+        be located in registerhi:register if it was converted from a procvar or
+        in GetNextReg(register):register if it was converted from a longint.
+        We can tell between the two by checking whether registerhi has been set. }
+      function is_fourbyterecord(d:tdef): boolean;
      protected
      protected
       procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
       procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
      public
      public
+      function getaddressregister(list:TAsmList;size:tdef):Tregister;override;
+
+      procedure reference_reset_base(var ref: treference; regsize: tdef; reg: tregister; offset, alignment: longint); override;
+
+      function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef; weak: boolean): tcgpara;override;
+
+      procedure a_load_loc_ref(list : TAsmList;fromsize, tosize: tdef; const loc: tlocation; const ref : treference);override;
+      procedure a_loadaddr_ref_reg(list : TAsmList;fromsize, tosize : tdef;const ref : treference;r : tregister);override;
+
       procedure g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); override;
       procedure g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); override;
       procedure g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); override;
       procedure g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); override;
 
 
@@ -52,13 +85,37 @@ interface
 implementation
 implementation
 
 
   uses
   uses
-    globtype,verbose,
+    verbose,
     paramgr,
     paramgr,
     cpubase,cpuinfo,tgobj,cgobj,cgcpu,
     cpubase,cpuinfo,tgobj,cgobj,cgcpu,
-    symconst;
+    defutil,
+    symconst,symcpu,
+    procinfo,fmodule,
+    aasmcpu;
 
 
   { thlcgcpu }
   { thlcgcpu }
 
 
+  function thlcgcpu.is_methodptr_like_type(d: tdef): boolean;
+    var
+      is_sixbyterecord,is_methodptr,is_nestedprocptr: Boolean;
+    begin
+      is_sixbyterecord:=(d.typ=recorddef) and (d.size=6);
+      is_methodptr:=(d.typ=procvardef)
+        and (po_methodpointer in tprocvardef(d).procoptions)
+        and not(po_addressonly in tprocvardef(d).procoptions);
+      is_nestedprocptr:=(d.typ=procvardef)
+        and is_nested_pd(tprocvardef(d))
+        and not(po_addressonly in tprocvardef(d).procoptions);
+      result:=is_sixbyterecord or is_methodptr or is_nestedprocptr;
+    end;
+
+
+  function thlcgcpu.is_fourbyterecord(d: tdef): boolean;
+    begin
+      result:=(d.typ=recorddef) and (d.size=4);
+    end;
+
+
   procedure thlcgcpu.gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint);
   procedure thlcgcpu.gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint);
     var
     var
       locsize : tcgsize;
       locsize : tcgsize;
@@ -82,10 +139,10 @@ implementation
                      (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
                      (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
                     begin
                     begin
                       cg.g_stackpointer_alloc(list,stacksize);
                       cg.g_stackpointer_alloc(list,stacksize);
-                      reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
+                      reference_reset_base(href,voidstackpointertype,NR_STACK_POINTER_REG,0,voidstackpointertype.size);
                     end
                     end
                   else
                   else
-                    reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
+                    reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
                   cg.a_loadfpu_reg_ref(list,locsize,locsize,l.register,href);
                   cg.a_loadfpu_reg_ref(list,locsize,locsize,l.register,href);
                 end;
                 end;
               LOC_FPUREGISTER:
               LOC_FPUREGISTER:
@@ -127,10 +184,10 @@ implementation
                      (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
                      (cgpara.location^.reference.index=NR_STACK_POINTER_REG) then
                     begin
                     begin
                       cg.g_stackpointer_alloc(list,stacksize);
                       cg.g_stackpointer_alloc(list,stacksize);
-                      reference_reset_base(href,NR_STACK_POINTER_REG,0,sizeof(pint));
+                      reference_reset_base(href,voidstackpointertype,NR_STACK_POINTER_REG,0,voidstackpointertype.size);
                     end
                     end
                   else
                   else
-                    reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
+                    reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
                   cg.a_loadmm_reg_ref(list,locsize,locsize,l.register,href,mms_movescalar);
                   cg.a_loadmm_reg_ref(list,locsize,locsize,l.register,href,mms_movescalar);
                 end;
                 end;
               LOC_FPUREGISTER:
               LOC_FPUREGISTER:
@@ -156,7 +213,7 @@ implementation
                     cg.a_load_ref_cgpara(list,locsize,l.reference,cgpara)
                     cg.a_load_ref_cgpara(list,locsize,l.reference,cgpara)
                   else
                   else
                     begin
                     begin
-                      reference_reset_base(href,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
+                      reference_reset_base(href,voidstackpointertype,cgpara.location^.reference.index,cgpara.location^.reference.offset,cgpara.alignment);
                       cg.g_concatcopy(list,l.reference,href,stacksize);
                       cg.g_concatcopy(list,l.reference,href,stacksize);
                     end;
                     end;
                 end;
                 end;
@@ -174,6 +231,146 @@ implementation
     end;
     end;
 
 
 
 
+  function thlcgcpu.getaddressregister(list: TAsmList; size: tdef): Tregister;
+    begin
+      { implicit pointer types on i8086 follow the default data pointer size for
+        the current memory model }
+      if is_implicit_pointer_object_type(size) or is_implicit_array_pointer(size) then
+        size:=voidpointertype;
+
+      if is_farpointer(size) or is_hugepointer(size) then
+        Result:=cg.getintregister(list,OS_32)
+      else
+        Result:=cg.getintregister(list,OS_16);
+    end;
+
+
+  procedure thlcgcpu.reference_reset_base(var ref: treference; regsize: tdef;
+    reg: tregister; offset, alignment: longint);
+    begin
+      inherited reference_reset_base(ref, regsize, reg, offset, alignment);
+
+      { implicit pointer types on i8086 follow the default data pointer size for
+        the current memory model }
+      if is_implicit_pointer_object_type(regsize) or is_implicit_array_pointer(regsize) then
+        regsize:=voidpointertype;
+
+      if regsize.typ=pointerdef then
+        case tcpupointerdef(regsize).x86pointertyp of
+          x86pt_near:
+            ;
+          x86pt_near_cs:
+            ref.segment:=NR_CS;
+          x86pt_near_ds:
+            ref.segment:=NR_DS;
+          x86pt_near_ss:
+            ref.segment:=NR_SS;
+          x86pt_near_es:
+            ref.segment:=NR_ES;
+          x86pt_near_fs:
+            ref.segment:=NR_FS;
+          x86pt_near_gs:
+            ref.segment:=NR_GS;
+          x86pt_far,
+          x86pt_huge:
+            if reg<>NR_NO then
+              ref.segment:=GetNextReg(reg);
+        end;
+    end;
+
+
+  function thlcgcpu.a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; forceresdef: tdef; weak: boolean): tcgpara;
+    begin
+      if is_proc_far(pd) then
+        begin
+          { far calls to the same module (in $HUGECODE off mode) can be optimized
+            to push cs + call near, because they are in the same segment }
+          if not (cs_huge_code in current_settings.moduleswitches) and
+             pd.owner.iscurrentunit and not (po_external in pd.procoptions) then
+            begin
+              list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_CS));
+              tcg8086(cg).a_call_name_near(list,s,weak);
+            end
+          else
+            tcg8086(cg).a_call_name_far(list,s,weak);
+        end
+      else
+        tcg8086(cg).a_call_name_near(list,s,weak);
+      result:=get_call_result_cgpara(pd,forceresdef);
+    end;
+
+
+  procedure thlcgcpu.a_load_loc_ref(list: TAsmList; fromsize, tosize: tdef; const loc: tlocation; const ref: treference);
+    var
+      tmpref: treference;
+    begin
+      if is_methodptr_like_type(tosize) and (loc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+        begin
+          tmpref:=ref;
+          a_load_reg_ref(list,voidcodepointertype,voidcodepointertype,loc.register,tmpref);
+          inc(tmpref.offset,voidcodepointertype.size);
+          { the second part could be either self or parentfp }
+          if tosize.size=(voidcodepointertype.size+voidpointertype.size) then
+            a_load_reg_ref(list,voidpointertype,voidpointertype,loc.registerhi,tmpref)
+          else if tosize.size=(voidcodepointertype.size+parentfpvoidpointertype.size) then
+            a_load_reg_ref(list,parentfpvoidpointertype,parentfpvoidpointertype,loc.registerhi,tmpref)
+          else
+            internalerror(2014052201);
+        end
+      else if is_fourbyterecord(tosize) and (loc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+        begin
+          tmpref:=ref;
+          cg.a_load_reg_ref(list,OS_16,OS_16,loc.register,tmpref);
+          inc(tmpref.offset,2);
+          if loc.registerhi<>tregister(0) then
+            cg.a_load_reg_ref(list,OS_16,OS_16,loc.registerhi,tmpref)
+          else
+            cg.a_load_reg_ref(list,OS_16,OS_16,GetNextReg(loc.register),tmpref);
+        end
+      else
+        inherited a_load_loc_ref(list, fromsize, tosize, loc, ref);
+    end;
+
+
+  procedure thlcgcpu.a_loadaddr_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; r: tregister);
+    var
+      tmpref,segref: treference;
+    begin
+      { step 1: call the x86 low level code generator to handle the offset;
+        we set the segment to NR_NO to disable the i8086 segment handling code
+        in the low level cg (which can be removed, once all calls to
+        a_loadaddr_ref_reg go through the high level code generator) }
+      tmpref:=ref;
+      tmpref.segment:=NR_NO;
+      cg.a_loadaddr_ref_reg(list, tmpref, r);
+
+      { step 2: if destination is a far pointer, we have to pass a segment as well }
+      if is_farpointer(tosize) or is_hugepointer(tosize) then
+        begin
+          { if a segment register is specified in ref, we use that }
+          if ref.segment<>NR_NO then
+            begin
+              if is_segment_reg(ref.segment) then
+                list.concat(Taicpu.op_reg_reg(A_MOV,S_W,ref.segment,GetNextReg(r)))
+              else
+                cg.a_load_reg_reg(list,OS_16,OS_16,ref.segment,GetNextReg(r));
+            end
+          { references relative to a symbol use the segment of the symbol,
+            which can be obtained by the SEG directive }
+          else if assigned(ref.symbol) then
+            begin
+              reference_reset_symbol(segref,ref.symbol,0,0);
+              segref.refaddr:=addr_seg;
+              cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,GetNextReg(r));
+            end
+          else if ref.base=NR_BP then
+            list.concat(Taicpu.op_reg_reg(A_MOV,S_W,NR_SS,GetNextReg(r)))
+          else
+            internalerror(2014032801);
+        end;
+    end;
+
+
   procedure thlcgcpu.g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister);
   procedure thlcgcpu.g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister);
     begin
     begin
       if paramanager.use_fixed_stack then
       if paramanager.use_fixed_stack then
@@ -200,26 +397,35 @@ implementation
     var
     var
       r,tmpref: treference;
       r,tmpref: treference;
     begin
     begin
-      { handle i8086 6-byte (mixed near + far) method pointers }
-      if (size.typ in [procvardef,recorddef]) and (size.size=6) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+      if is_methodptr_like_type(size) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
         begin
         begin
           tg.gethltemp(list,size,size.size,tt_normal,r);
           tg.gethltemp(list,size,size.size,tt_normal,r);
           tmpref:=r;
           tmpref:=r;
 
 
-          if current_settings.x86memorymodel in x86_far_code_models then
-            begin
-              cg.a_load_reg_ref(list,OS_32,OS_32,l.register,tmpref);
-              inc(tmpref.offset,4);
-            end
+          a_load_reg_ref(list,voidcodepointertype,voidcodepointertype,l.register,tmpref);
+          inc(tmpref.offset,voidcodepointertype.size);
+          { the second part could be either self or parentfp }
+          if size.size=(voidcodepointertype.size+voidpointertype.size) then
+            a_load_reg_ref(list,voidpointertype,voidpointertype,l.registerhi,tmpref)
+          else if size.size=(voidcodepointertype.size+parentfpvoidpointertype.size) then
+            a_load_reg_ref(list,parentfpvoidpointertype,parentfpvoidpointertype,l.registerhi,tmpref)
           else
           else
-            begin
-              cg.a_load_reg_ref(list,OS_16,OS_16,l.register,tmpref);
-              inc(tmpref.offset,2);
-            end;
-          if current_settings.x86memorymodel in x86_far_data_models then
-            cg.a_load_reg_ref(list,OS_32,OS_32,l.registerhi,tmpref)
+            internalerror(2014052202);
+
+          location_reset_ref(l,LOC_REFERENCE,l.size,0);
+          l.reference:=r;
+        end
+      else if is_fourbyterecord(size) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+        begin
+          tg.gethltemp(list,size,size.size,tt_normal,r);
+          tmpref:=r;
+
+          cg.a_load_reg_ref(list,OS_16,OS_16,l.register,tmpref);
+          inc(tmpref.offset,2);
+          if l.registerhi<>tregister(0) then
+            cg.a_load_reg_ref(list,OS_16,OS_16,l.registerhi,tmpref)
           else
           else
-            cg.a_load_reg_ref(list,OS_16,OS_16,l.registerhi,tmpref);
+            cg.a_load_reg_ref(list,OS_16,OS_16,GetNextReg(l.register),tmpref);
 
 
           location_reset_ref(l,LOC_REFERENCE,l.size,0);
           location_reset_ref(l,LOC_REFERENCE,l.size,0);
           l.reference:=r;
           l.reference:=r;

+ 85 - 16
compiler/i8086/i8086att.inc

@@ -161,10 +161,8 @@
 'iret',
 'iret',
 'iret',
 'iret',
 'iretw',
 'iretw',
-'iretq',
 'jcxz',
 'jcxz',
 'jecxz',
 'jecxz',
-'jrcxz',
 'jmp',
 'jmp',
 'lahf',
 'lahf',
 'lar',
 'lar',
@@ -200,7 +198,6 @@
 'movq',
 'movq',
 'movsb',
 'movsb',
 'movsl',
 'movsl',
-'movsq',
 'movsw',
 'movsw',
 'movs',
 'movs',
 'movz',
 'movz',
@@ -272,7 +269,6 @@
 'popf',
 'popf',
 'popfl',
 'popfl',
 'popfw',
 'popfw',
-'popfq',
 'por',
 'por',
 'prefetch',
 'prefetch',
 'prefetchw',
 'prefetchw',
@@ -306,7 +302,6 @@
 'pushf',
 'pushf',
 'pushfl',
 'pushfl',
 'pushfw',
 'pushfw',
-'pushfq',
 'pxor',
 'pxor',
 'rcl',
 'rcl',
 'rcr',
 'rcr',
@@ -334,7 +329,6 @@
 'sbb',
 'sbb',
 'scasb',
 'scasb',
 'scasl',
 'scasl',
-'scasq',
 'scasw',
 'scasw',
 'cs',
 'cs',
 'ds',
 'ds',
@@ -596,10 +590,6 @@
 'xsha256',
 'xsha256',
 'dmint',
 'dmint',
 'rdm',
 'rdm',
-'movabs',
-'movslq',
-'cqto',
-'cmpxchg16b',
 'movntss',
 'movntss',
 'movntsd',
 'movntsd',
 'insertq',
 'insertq',
@@ -637,11 +627,9 @@
 'pcmpeqq',
 'pcmpeqq',
 'pextrb',
 'pextrb',
 'pextrd',
 'pextrd',
-'pextrq',
 'phminposuw',
 'phminposuw',
 'pinsrb',
 'pinsrb',
 'pinsrd',
 'pinsrd',
-'pinsrq',
 'pmaxsb',
 'pmaxsb',
 'pmaxsd',
 'pmaxsd',
 'pmaxud',
 'pmaxud',
@@ -682,9 +670,6 @@
 'aesdeclast',
 'aesdeclast',
 'aesimc',
 'aesimc',
 'aeskeygenassist',
 'aeskeygenassist',
-'stosq',
-'lodsq',
-'cmpsq',
 'vaddpd',
 'vaddpd',
 'vaddps',
 'vaddps',
 'vaddsd',
 'vaddsd',
@@ -946,6 +931,7 @@
 'vzeroupper',
 'vzeroupper',
 'andn',
 'andn',
 'bextr',
 'bextr',
+'tzcnt',
 'rorx',
 'rorx',
 'sarx',
 'sarx',
 'shlx',
 'shlx',
@@ -969,5 +955,88 @@
 'vpsllvq',
 'vpsllvq',
 'vpsravd',
 'vpsravd',
 'vpsrlvd',
 'vpsrlvd',
-'vpsrlvq'
+'vpsrlvq',
+'vgatherdpd',
+'vgatherdps',
+'vgatherqpd',
+'vgatherqps',
+'vpgatherdd',
+'vpgatherdq',
+'vpgatherqd',
+'vpgatherqq',
+'add4s',
+'brkem',
+'clr1',
+'cmp4s',
+'ext',
+'ins',
+'not1',
+'repc',
+'repnc',
+'rol4',
+'ror4',
+'set1',
+'sub4s',
+'test1',
+'vfmadd132pd',
+'vfmadd213pd',
+'vfmadd231pd',
+'vfmaddpd',
+'vfmadd132ps',
+'vfmadd213ps',
+'vfmadd231ps',
+'vfmadd132sd',
+'vfmadd213sd',
+'vfmadd231sd',
+'vfmadd132ss',
+'vfmadd213ss',
+'vfmadd231ss',
+'vfmaddsub132pd',
+'vfmaddsub213pd',
+'vfmaddsub231pd',
+'vfmaddsub132ps',
+'vfmaddsub213ps',
+'vfmaddsub231ps',
+'vfmsubadd132pd',
+'vfmsubadd213pd',
+'vfmsubadd231pd',
+'vfmsubadd132ps',
+'vfmsubadd213ps',
+'vfmsubadd231ps',
+'vfmsub132pd',
+'vfmsub213pd',
+'vfmsub231pd',
+'vfmsub132ps',
+'vfmsub213ps',
+'vfmsub231ps',
+'vfmsub132sd',
+'vfmsub213sd',
+'vfmsub231sd',
+'vfmsub132ss',
+'vfmsub213ss',
+'vfmsub231ss',
+'vfnmadd132pd',
+'vfnmadd213pd',
+'vfnmadd231pd',
+'vfnmadd132ps',
+'vfnmadd213ps',
+'vfnmadd231ps',
+'vfnmadd132sd',
+'vfnmadd213sd',
+'vfnmadd231sd',
+'vfnmadd132ss',
+'vfnmadd213ss',
+'vfnmadd231ss',
+'vfnmsub132pd',
+'vfnmsub213pd',
+'vfnmsub231pd',
+'vfnmsub132ps',
+'vfnmsub213ps',
+'vfnmsub231ps',
+'vfnmsub132sd',
+'vfnmsub213sd',
+'vfnmsub231sd',
+'vfnmsub132ss',
+'vfnmsub213ss',
+'vfnmsub231ss'
 );
 );

+ 82 - 13
compiler/i8086/i8086atts.inc

@@ -163,8 +163,6 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufNONE,
-attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,
 attsufNONE,
 attsufINT,
 attsufINT,
@@ -201,7 +199,6 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufNONE,
 attsufINTdual,
 attsufINTdual,
 attsufINTdual,
 attsufINTdual,
 attsufINT,
 attsufINT,
@@ -273,7 +270,6 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufNONE,
 attsufINT,
 attsufINT,
 attsufINT,
 attsufINT,
 attsufNONE,
 attsufNONE,
@@ -307,7 +303,6 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufNONE,
 attsufINT,
 attsufINT,
 attsufINT,
 attsufINT,
 attsufNONE,
 attsufNONE,
@@ -342,7 +337,6 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufNONE,
 attsufINT,
 attsufINT,
 attsufINT,
 attsufINT,
 attsufINT,
 attsufINT,
@@ -599,17 +593,77 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufINT,
 attsufINT,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufINT,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
@@ -647,6 +701,28 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
+attsufMM,
+attsufMM,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufMM,
+attsufMM,
+attsufNONE,
+attsufNONE,
+attsufMM,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
+attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
@@ -669,13 +745,11 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufINT,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufINT,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
@@ -716,17 +790,12 @@ attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufMM,
-attsufMM,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufMM,
-attsufMM,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
-attsufMM,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,
 attsufNONE,

+ 85 - 16
compiler/i8086/i8086int.inc

@@ -161,10 +161,8 @@
 'iret',
 'iret',
 'iretd',
 'iretd',
 'iretw',
 'iretw',
-'iretq',
 'jcxz',
 'jcxz',
 'jecxz',
 'jecxz',
-'jrcxz',
 'jmp',
 'jmp',
 'lahf',
 'lahf',
 'lar',
 'lar',
@@ -200,7 +198,6 @@
 'movq',
 'movq',
 'movsb',
 'movsb',
 'movsd',
 'movsd',
-'movsq',
 'movsw',
 'movsw',
 'movsx',
 'movsx',
 'movzx',
 'movzx',
@@ -272,7 +269,6 @@
 'popf',
 'popf',
 'popfd',
 'popfd',
 'popfw',
 'popfw',
-'popfq',
 'por',
 'por',
 'prefetch',
 'prefetch',
 'prefetchw',
 'prefetchw',
@@ -306,7 +302,6 @@
 'pushf',
 'pushf',
 'pushfd',
 'pushfd',
 'pushfw',
 'pushfw',
-'pushfq',
 'pxor',
 'pxor',
 'rcl',
 'rcl',
 'rcr',
 'rcr',
@@ -334,7 +329,6 @@
 'sbb',
 'sbb',
 'scasb',
 'scasb',
 'scasd',
 'scasd',
-'scasq',
 'scasw',
 'scasw',
 'segcs',
 'segcs',
 'segds',
 'segds',
@@ -596,10 +590,6 @@
 'xsha256',
 'xsha256',
 'dmint',
 'dmint',
 'rdm',
 'rdm',
-'movabs',
-'movsxd',
-'cqo',
-'cmpxchg16b',
 'movntss',
 'movntss',
 'movntsd',
 'movntsd',
 'insertq',
 'insertq',
@@ -637,11 +627,9 @@
 'pcmpeqq',
 'pcmpeqq',
 'pextrb',
 'pextrb',
 'pextrd',
 'pextrd',
-'pextrq',
 'phminposuw',
 'phminposuw',
 'pinsrb',
 'pinsrb',
 'pinsrd',
 'pinsrd',
-'pinsrq',
 'pmaxsb',
 'pmaxsb',
 'pmaxsd',
 'pmaxsd',
 'pmaxud',
 'pmaxud',
@@ -682,9 +670,6 @@
 'aesdeclast',
 'aesdeclast',
 'aesimc',
 'aesimc',
 'aeskeygenassist',
 'aeskeygenassist',
-'stosq',
-'lodsq',
-'cmpsq',
 'vaddpd',
 'vaddpd',
 'vaddps',
 'vaddps',
 'vaddsd',
 'vaddsd',
@@ -946,6 +931,7 @@
 'vzeroupper',
 'vzeroupper',
 'andn',
 'andn',
 'bextr',
 'bextr',
+'tzcnt',
 'rorx',
 'rorx',
 'sarx',
 'sarx',
 'shlx',
 'shlx',
@@ -969,5 +955,88 @@
 'vpsllvq',
 'vpsllvq',
 'vpsravd',
 'vpsravd',
 'vpsrlvd',
 'vpsrlvd',
-'vpsrlvq'
+'vpsrlvq',
+'vgatherdpd',
+'vgatherdps',
+'vgatherqpd',
+'vgatherqps',
+'vpgatherdd',
+'vpgatherdq',
+'vpgatherqd',
+'vpgatherqq',
+'add4s',
+'brkem',
+'clr1',
+'cmp4s',
+'ext',
+'ins',
+'not1',
+'repc',
+'repnc',
+'rol4',
+'ror4',
+'set1',
+'sub4s',
+'test1',
+'vfmadd132pd',
+'vfmadd213pd',
+'vfmadd231pd',
+'vfmaddpd',
+'vfmadd132ps',
+'vfmadd213ps',
+'vfmadd231ps',
+'vfmadd132sd',
+'vfmadd213sd',
+'vfmadd231sd',
+'vfmadd132ss',
+'vfmadd213ss',
+'vfmadd231ss',
+'vfmaddsub132pd',
+'vfmaddsub213pd',
+'vfmaddsub231pd',
+'vfmaddsub132ps',
+'vfmaddsub213ps',
+'vfmaddsub231ps',
+'vfmsubadd132pd',
+'vfmsubadd213pd',
+'vfmsubadd231pd',
+'vfmsubadd132ps',
+'vfmsubadd213ps',
+'vfmsubadd231ps',
+'vfmsub132pd',
+'vfmsub213pd',
+'vfmsub231pd',
+'vfmsub132ps',
+'vfmsub213ps',
+'vfmsub231ps',
+'vfmsub132sd',
+'vfmsub213sd',
+'vfmsub231sd',
+'vfmsub132ss',
+'vfmsub213ss',
+'vfmsub231ss',
+'vfnmadd132pd',
+'vfnmadd213pd',
+'vfnmadd231pd',
+'vfnmadd132ps',
+'vfnmadd213ps',
+'vfnmadd231ps',
+'vfnmadd132sd',
+'vfnmadd213sd',
+'vfnmadd231sd',
+'vfnmadd132ss',
+'vfnmadd213ss',
+'vfnmadd231ss',
+'vfnmsub132pd',
+'vfnmsub213pd',
+'vfnmsub231pd',
+'vfnmsub132ps',
+'vfnmsub213ps',
+'vfnmsub231ps',
+'vfnmsub132sd',
+'vfnmsub213sd',
+'vfnmsub231sd',
+'vfnmsub132ss',
+'vfnmsub213ss',
+'vfnmsub231ss'
 );
 );

+ 1 - 1
compiler/i8086/i8086nop.inc

@@ -1,2 +1,2 @@
 { don't edit, this file is generated from x86ins.dat }
 { don't edit, this file is generated from x86ins.dat }
-1828;
+1970;

+ 85 - 16
compiler/i8086/i8086op.inc

@@ -161,10 +161,8 @@ A_INVLPG,
 A_IRET,
 A_IRET,
 A_IRETD,
 A_IRETD,
 A_IRETW,
 A_IRETW,
-A_IRETQ,
 A_JCXZ,
 A_JCXZ,
 A_JECXZ,
 A_JECXZ,
-A_JRCXZ,
 A_JMP,
 A_JMP,
 A_LAHF,
 A_LAHF,
 A_LAR,
 A_LAR,
@@ -200,7 +198,6 @@ A_MOVD,
 A_MOVQ,
 A_MOVQ,
 A_MOVSB,
 A_MOVSB,
 A_MOVSD,
 A_MOVSD,
-A_MOVSQ,
 A_MOVSW,
 A_MOVSW,
 A_MOVSX,
 A_MOVSX,
 A_MOVZX,
 A_MOVZX,
@@ -272,7 +269,6 @@ A_POPAW,
 A_POPF,
 A_POPF,
 A_POPFD,
 A_POPFD,
 A_POPFW,
 A_POPFW,
-A_POPFQ,
 A_POR,
 A_POR,
 A_PREFETCH,
 A_PREFETCH,
 A_PREFETCHW,
 A_PREFETCHW,
@@ -306,7 +302,6 @@ A_PUSHAW,
 A_PUSHF,
 A_PUSHF,
 A_PUSHFD,
 A_PUSHFD,
 A_PUSHFW,
 A_PUSHFW,
-A_PUSHFQ,
 A_PXOR,
 A_PXOR,
 A_RCL,
 A_RCL,
 A_RCR,
 A_RCR,
@@ -334,7 +329,6 @@ A_SAR,
 A_SBB,
 A_SBB,
 A_SCASB,
 A_SCASB,
 A_SCASD,
 A_SCASD,
-A_SCASQ,
 A_SCASW,
 A_SCASW,
 A_SEGCS,
 A_SEGCS,
 A_SEGDS,
 A_SEGDS,
@@ -596,10 +590,6 @@ A_XSHA1,
 A_XSHA256,
 A_XSHA256,
 A_DMINT,
 A_DMINT,
 A_RDM,
 A_RDM,
-A_MOVABS,
-A_MOVSXD,
-A_CQO,
-A_CMPXCHG16B,
 A_MOVNTSS,
 A_MOVNTSS,
 A_MOVNTSD,
 A_MOVNTSD,
 A_INSERTQ,
 A_INSERTQ,
@@ -637,11 +627,9 @@ A_PBLENDW,
 A_PCMPEQQ,
 A_PCMPEQQ,
 A_PEXTRB,
 A_PEXTRB,
 A_PEXTRD,
 A_PEXTRD,
-A_PEXTRQ,
 A_PHMINPOSUW,
 A_PHMINPOSUW,
 A_PINSRB,
 A_PINSRB,
 A_PINSRD,
 A_PINSRD,
-A_PINSRQ,
 A_PMAXSB,
 A_PMAXSB,
 A_PMAXSD,
 A_PMAXSD,
 A_PMAXUD,
 A_PMAXUD,
@@ -682,9 +670,6 @@ A_AESDEC,
 A_AESDECLAST,
 A_AESDECLAST,
 A_AESIMC,
 A_AESIMC,
 A_AESKEYGENASSIST,
 A_AESKEYGENASSIST,
-A_STOSQ,
-A_LODSQ,
-A_CMPSQ,
 A_VADDPD,
 A_VADDPD,
 A_VADDPS,
 A_VADDPS,
 A_VADDSD,
 A_VADDSD,
@@ -946,6 +931,7 @@ A_VZEROALL,
 A_VZEROUPPER,
 A_VZEROUPPER,
 A_ANDN,
 A_ANDN,
 A_BEXTR,
 A_BEXTR,
+A_TZCNT,
 A_RORX,
 A_RORX,
 A_SARX,
 A_SARX,
 A_SHLX,
 A_SHLX,
@@ -969,5 +955,88 @@ A_VPSLLVD,
 A_VPSLLVQ,
 A_VPSLLVQ,
 A_VPSRAVD,
 A_VPSRAVD,
 A_VPSRLVD,
 A_VPSRLVD,
-A_VPSRLVQ
+A_VPSRLVQ,
+A_VGATHERDPD,
+A_VGATHERDPS,
+A_VGATHERQPD,
+A_VGATHERQPS,
+A_VPGATHERDD,
+A_VPGATHERDQ,
+A_VPGATHERQD,
+A_VPGATHERQQ,
+A_ADD4S,
+A_BRKEM,
+A_CLR1,
+A_CMP4S,
+A_EXT,
+A_INS,
+A_NOT1,
+A_REPC,
+A_REPNC,
+A_ROL4,
+A_ROR4,
+A_SET1,
+A_SUB4S,
+A_TEST1,
+A_VFMADD132PD,
+A_VFMADD213PD,
+A_VFMADD231PD,
+A_VFMADDPD,
+A_VFMADD132PS,
+A_VFMADD213PS,
+A_VFMADD231PS,
+A_VFMADD132SD,
+A_VFMADD213SD,
+A_VFMADD231SD,
+A_VFMADD132SS,
+A_VFMADD213SS,
+A_VFMADD231SS,
+A_VFMADDSUB132PD,
+A_VFMADDSUB213PD,
+A_VFMADDSUB231PD,
+A_VFMADDSUB132PS,
+A_VFMADDSUB213PS,
+A_VFMADDSUB231PS,
+A_VFMSUBADD132PD,
+A_VFMSUBADD213PD,
+A_VFMSUBADD231PD,
+A_VFMSUBADD132PS,
+A_VFMSUBADD213PS,
+A_VFMSUBADD231PS,
+A_VFMSUB132PD,
+A_VFMSUB213PD,
+A_VFMSUB231PD,
+A_VFMSUB132PS,
+A_VFMSUB213PS,
+A_VFMSUB231PS,
+A_VFMSUB132SD,
+A_VFMSUB213SD,
+A_VFMSUB231SD,
+A_VFMSUB132SS,
+A_VFMSUB213SS,
+A_VFMSUB231SS,
+A_VFNMADD132PD,
+A_VFNMADD213PD,
+A_VFNMADD231PD,
+A_VFNMADD132PS,
+A_VFNMADD213PS,
+A_VFNMADD231PS,
+A_VFNMADD132SD,
+A_VFNMADD213SD,
+A_VFNMADD231SD,
+A_VFNMADD132SS,
+A_VFNMADD213SS,
+A_VFNMADD231SS,
+A_VFNMSUB132PD,
+A_VFNMSUB213PD,
+A_VFNMSUB231PD,
+A_VFNMSUB132PS,
+A_VFNMSUB213PS,
+A_VFNMSUB231PS,
+A_VFNMSUB132SD,
+A_VFNMSUB213SD,
+A_VFNMSUB231SD,
+A_VFNMSUB132SS,
+A_VFNMSUB213SS,
+A_VFNMSUB231SS
 );
 );

+ 148 - 79
compiler/i8086/i8086prop.inc

@@ -161,8 +161,6 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_RECX, Ch_None, Ch_None)),
 (Ch: (Ch_RECX, Ch_None, Ch_None)),
 (Ch: (Ch_RECX, Ch_None, Ch_None)),
 (Ch: (Ch_RECX, Ch_None, Ch_None)),
 (Ch: (Ch_RECX, Ch_None, Ch_None)),
 (Ch: (Ch_ROp1, Ch_None, Ch_None)),
 (Ch: (Ch_ROp1, Ch_None, Ch_None)),
@@ -201,7 +199,6 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_RWEAX, Ch_WEDX, Ch_WFlags)),
 (Ch: (Ch_RWEAX, Ch_WEDX, Ch_WFlags)),
@@ -224,8 +221,8 @@
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -272,7 +269,6 @@
 (Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFLAGS, Ch_None)),
 (Ch: (Ch_RWESP, Ch_WFLAGS, Ch_None)),
-(Ch: (Ch_RWESP, Ch_WFlags, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -306,7 +302,6 @@
 (Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFLAGS, Ch_None)),
 (Ch: (Ch_RWESP, Ch_RFLAGS, Ch_None)),
-(Ch: (Ch_RWESP, Ch_RFlags, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_RWFlags)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_RWFlags)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_RWFlags)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_RWFlags)),
@@ -335,7 +330,6 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_None, Ch_None, Ch_None)),
 (Ch: (Ch_None, Ch_None, Ch_None)),
 (Ch: (Ch_None, Ch_None, Ch_None)),
 (Ch: (Ch_None, Ch_None, Ch_None)),
 (Ch: (Ch_None, Ch_None, Ch_None)),
 (Ch: (Ch_None, Ch_None, Ch_None)),
@@ -389,7 +383,7 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_ROp1, Ch_WOp2, Ch_RFLAGS)),
+(Ch: (Ch_ROp1, Ch_RWOp2, Ch_RFLAGS)),
 (Ch: (Ch_RFLAGS, Ch_None, Ch_None)),
 (Ch: (Ch_RFLAGS, Ch_None, Ch_None)),
 (Ch: (Ch_RFLAGS, Ch_WOp1, Ch_None)),
 (Ch: (Ch_RFLAGS, Ch_WOp1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
@@ -489,8 +483,8 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Wop2, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Wop2, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -570,6 +564,7 @@
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Wop2, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -596,13 +591,6 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
-(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
-(Ch: (Ch_MRAX, Ch_WRDX, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -682,9 +670,6 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_RRAX, Ch_WMemEDI, Ch_RWRDI)),
-(Ch: (Ch_WRAX, Ch_RWRSI, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
@@ -730,6 +715,10 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -753,6 +742,12 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -761,28 +756,20 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
@@ -796,7 +783,15 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -859,6 +854,14 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -867,6 +870,24 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -876,15 +897,26 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -893,8 +925,17 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Wop3, Ch_Rop2, Ch_Rop1)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Wop2, Ch_WFlags, Ch_Rop1)),
+(Ch: (Ch_Rop1, Ch_Wop2, Ch_None)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
+(Ch: (Ch_Rop1, Ch_Rop2, Ch_Wop3)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
@@ -925,49 +966,77 @@
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
+(Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
+(Ch: (Ch_RWECX, Ch_RWFlags, Ch_None)),
+(Ch: (Ch_RWECX, Ch_RWFlags, Ch_None)),
+(Ch: (Ch_Mop1, Ch_RWEAX, Ch_None)),
+(Ch: (Ch_Mop1, Ch_RWEAX, Ch_None)),
+(Ch: (Ch_Mop2, Ch_Rop1, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
 (Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_Wop1, Ch_Rop2, Ch_Rop3)),
-(Ch: (Ch_Wop1, Ch_Rop2, Ch_Rop3)),
-(Ch: (Ch_Wop1, Ch_Rop2, Ch_None)),
-(Ch: (Ch_Wop1, Ch_Rop2, Ch_Rop3)),
-(Ch: (Ch_Wop1, Ch_Rop2, Ch_Rop3)),
-(Ch: (Ch_Wop1, Ch_Rop2, Ch_Rop3)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None)),
-(Ch: (Ch_All, Ch_None, Ch_None))
+(Ch: (Ch_WFlags, Ch_Rop1, Ch_Rop2)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1)),
+(Ch: (Ch_Mop3, Ch_Rop2, Ch_Rop1))
 );
 );

+ 1003 - 9
compiler/i8086/i8086tab.inc

@@ -2649,17 +2649,10 @@
   (
   (
     opcode  : A_LEA;
     opcode  : A_LEA;
     ops     : 2;
     ops     : 2;
-    optypes : (ot_reg32 or ot_bits64,ot_memory,ot_none,ot_none);
-    code    : #208#1#141#72;
+    optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_memory,ot_none,ot_none);
+    code    : #193#208#1#141#72;
     flags   : if_8086
     flags   : if_8086
   ),
   ),
-  (
-    opcode  : A_LEA;
-    ops     : 2;
-    optypes : (ot_reg32 or ot_bits64,ot_immediate,ot_none,ot_none);
-    code    : #208#1#141#72;
-    flags   : if_8086 or if_sd
-  ),
   (
   (
     opcode  : A_LEAVE;
     opcode  : A_LEAVE;
     ops     : 0;
     ops     : 0;
@@ -12460,6 +12453,13 @@
     code    : #242#249#1#247#62#72;
     code    : #242#249#1#247#62#72;
     flags   : if_bmi1
     flags   : if_bmi1
   ),
   ),
+  (
+    opcode  : A_TZCNT;
+    ops     : 2;
+    optypes : (ot_reg16 or ot_bits32 or ot_bits64,ot_rm_gpr,ot_none,ot_none);
+    code    : #208#219#2#15#188#72;
+    flags   : if_bmi1 or if_sm
+  ),
   (
   (
     opcode  : A_RORX;
     opcode  : A_RORX;
     ops     : 3;
     ops     : 3;
@@ -12795,5 +12795,999 @@
     optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
     optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
     code    : #241#242#243#249#1#69#61#80;
     code    : #241#242#243#249#1#69#61#80;
     flags   : if_avx2
     flags   : if_avx2
+  ),
+  (
+    opcode  : A_VGATHERDPD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmem64,ot_xmmreg,ot_none);
+    code    : #241#242#243#249#1#146#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VGATHERDPD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_xmem64,ot_ymmreg,ot_none);
+    code    : #241#242#243#244#249#1#146#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VGATHERDPS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmem32,ot_xmmreg,ot_none);
+    code    : #241#242#249#1#146#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VGATHERDPS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymem32,ot_ymmreg,ot_none);
+    code    : #241#242#244#249#1#146#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VGATHERQPD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmem64,ot_xmmreg,ot_none);
+    code    : #241#242#243#249#1#147#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VGATHERQPD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymem64,ot_ymmreg,ot_none);
+    code    : #241#242#243#244#249#1#147#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VGATHERQPS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmem32,ot_xmmreg,ot_none);
+    code    : #241#242#249#1#147#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VGATHERQPS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_ymem32,ot_xmmreg,ot_none);
+    code    : #241#242#244#249#1#147#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VPGATHERDD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmem32,ot_xmmreg,ot_none);
+    code    : #241#242#249#1#144#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VPGATHERDD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymem32,ot_ymmreg,ot_none);
+    code    : #241#242#244#249#1#144#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VPGATHERDQ;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmem64,ot_xmmreg,ot_none);
+    code    : #241#242#243#249#1#144#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VPGATHERDQ;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_xmem64,ot_ymmreg,ot_none);
+    code    : #241#242#243#244#249#1#144#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VPGATHERQD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmem32,ot_xmmreg,ot_none);
+    code    : #241#242#249#1#145#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VPGATHERQD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_ymem32,ot_xmmreg,ot_none);
+    code    : #241#242#244#249#1#145#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VPGATHERQQ;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmem64,ot_xmmreg,ot_none);
+    code    : #241#242#243#249#1#145#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_VPGATHERQQ;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymem64,ot_ymmreg,ot_none);
+    code    : #241#242#243#244#249#1#145#62#72;
+    flags   : if_avx2
+  ),
+  (
+    opcode  : A_ADD4S;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #2#15#32;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_BRKEM;
+    ops     : 1;
+    optypes : (ot_immediate,ot_none,ot_none,ot_none);
+    code    : #2#15#255#20;
+    flags   : if_nec or if_sb or if_16bitonly
+  ),
+  (
+    opcode  : A_CLR1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits8,ot_reg_cl,ot_none,ot_none);
+    code    : #2#15#18#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_CLR1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits16,ot_reg_cl,ot_none,ot_none);
+    code    : #2#15#19#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_CLR1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits8,ot_immediate,ot_none,ot_none);
+    code    : #2#15#26#128#21;
+    flags   : if_nec or if_sb or if_16bitonly
+  ),
+  (
+    opcode  : A_CLR1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits16,ot_immediate,ot_none,ot_none);
+    code    : #2#15#27#128#21;
+    flags   : if_nec or if_sw or if_16bitonly
+  ),
+  (
+    opcode  : A_CMP4S;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #2#15#38;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_EXT;
+    ops     : 2;
+    optypes : (ot_reg8,ot_reg8,ot_none,ot_none);
+    code    : #2#15#51#65;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_EXT;
+    ops     : 2;
+    optypes : (ot_reg8,ot_immediate,ot_none,ot_none);
+    code    : #2#15#59#128#21;
+    flags   : if_nec or if_sb or if_16bitonly
+  ),
+  (
+    opcode  : A_INS;
+    ops     : 2;
+    optypes : (ot_reg8,ot_reg8,ot_none,ot_none);
+    code    : #2#15#49#65;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_INS;
+    ops     : 2;
+    optypes : (ot_reg8,ot_immediate,ot_none,ot_none);
+    code    : #2#15#57#128#21;
+    flags   : if_nec or if_sb or if_16bitonly
+  ),
+  (
+    opcode  : A_NOT1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits8,ot_reg_cl,ot_none,ot_none);
+    code    : #2#15#22#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_NOT1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits16,ot_reg_cl,ot_none,ot_none);
+    code    : #2#15#23#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_NOT1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits8,ot_immediate,ot_none,ot_none);
+    code    : #2#15#30#128#21;
+    flags   : if_nec or if_sb or if_16bitonly
+  ),
+  (
+    opcode  : A_NOT1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits16,ot_immediate,ot_none,ot_none);
+    code    : #2#15#31#128#21;
+    flags   : if_nec or if_sw or if_16bitonly
+  ),
+  (
+    opcode  : A_REPC;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #1#101;
+    flags   : if_nec or if_pre or if_16bitonly
+  ),
+  (
+    opcode  : A_REPNC;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #1#100;
+    flags   : if_nec or if_pre or if_16bitonly
+  ),
+  (
+    opcode  : A_ROL4;
+    ops     : 1;
+    optypes : (ot_rm_gpr or ot_bits8,ot_none,ot_none,ot_none);
+    code    : #2#15#40#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_ROR4;
+    ops     : 1;
+    optypes : (ot_rm_gpr or ot_bits8,ot_none,ot_none,ot_none);
+    code    : #2#15#42#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_SET1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits8,ot_reg_cl,ot_none,ot_none);
+    code    : #2#15#20#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_SET1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits16,ot_reg_cl,ot_none,ot_none);
+    code    : #2#15#21#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_SET1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits8,ot_immediate,ot_none,ot_none);
+    code    : #2#15#28#128#21;
+    flags   : if_nec or if_sb or if_16bitonly
+  ),
+  (
+    opcode  : A_SET1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits16,ot_immediate,ot_none,ot_none);
+    code    : #2#15#29#128#21;
+    flags   : if_nec or if_sw or if_16bitonly
+  ),
+  (
+    opcode  : A_SUB4S;
+    ops     : 0;
+    optypes : (ot_none,ot_none,ot_none,ot_none);
+    code    : #2#15#34;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_TEST1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits8,ot_reg_cl,ot_none,ot_none);
+    code    : #2#15#16#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_TEST1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits16,ot_reg_cl,ot_none,ot_none);
+    code    : #2#15#17#128;
+    flags   : if_nec or if_16bitonly
+  ),
+  (
+    opcode  : A_TEST1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits8,ot_immediate,ot_none,ot_none);
+    code    : #2#15#24#128#21;
+    flags   : if_nec or if_sb or if_16bitonly
+  ),
+  (
+    opcode  : A_TEST1;
+    ops     : 2;
+    optypes : (ot_rm_gpr or ot_bits16,ot_immediate,ot_none,ot_none);
+    code    : #2#15#25#128#21;
+    flags   : if_nec or if_sw or if_16bitonly
+  ),
+  (
+    opcode  : A_VFMADD132PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#152#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD132PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#152#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD213PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#168#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD213PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#168#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD231PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#184#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD231PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#184#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDPD;
+    ops     : 4;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_xmmreg);
+    code    : #241#242#250#1#105#61#80#247;
+    flags   : if_fma4
+  ),
+  (
+    opcode  : A_VFMADDPD;
+    ops     : 4;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmreg,ot_xmmrm);
+    code    : #241#242#250#243#1#105#61#88#246;
+    flags   : if_fma4
+  ),
+  (
+    opcode  : A_VFMADD132PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#152#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD132PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#152#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD213PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#168#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD213PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#168#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD231PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#184#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD231PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#184#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD132SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#153#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD213SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#169#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD231SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#185#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD132SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#153#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD213SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#169#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADD231SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#185#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB132PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#150#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB132PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#150#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB213PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#166#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB213PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#166#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB231PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#182#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB231PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#182#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB132PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#150#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB132PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#150#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB213PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#166#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB213PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#166#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB231PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#182#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMADDSUB231PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#182#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD132PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#151#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD132PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#151#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD213PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#167#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD213PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#167#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD231PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#183#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD231PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#183#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD132PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#151#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD132PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#151#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD213PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#167#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD213PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#167#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD231PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#183#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUBADD231PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#183#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB132PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#154#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB132PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#154#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB213PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#170#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB213PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#170#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB231PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#186#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB231PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#186#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB132PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#154#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB132PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#154#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB213PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#170#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB213PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#170#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB231PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#186#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB231PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#186#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB132SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#155#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB213SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#171#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB231SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#187#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB132SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#155#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB213SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#171#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFMSUB231SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#187#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD132PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#156#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD132PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#156#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD213PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#172#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD213PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#172#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD231PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#188#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD231PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#188#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD132PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#156#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD132PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#156#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD213PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#172#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD213PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#172#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD231PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#188#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD231PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#188#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD132SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#157#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD213SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#173#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD231SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#189#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD132SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#157#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD213SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#173#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMADD231SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#189#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB132PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#158#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB132PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#158#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB213PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#174#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB213PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#174#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB231PD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#190#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB231PD;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#243#1#190#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB132PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#158#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB132PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#158#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB213PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#174#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB213PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#174#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB231PS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#190#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB231PS;
+    ops     : 3;
+    optypes : (ot_ymmreg,ot_ymmreg,ot_ymmrm,ot_none);
+    code    : #241#242#244#249#1#190#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB132SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#159#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB213SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#175#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB231SD;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#243#1#191#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB132SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#159#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB213SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#175#61#80;
+    flags   : if_fma
+  ),
+  (
+    opcode  : A_VFNMSUB231SS;
+    ops     : 3;
+    optypes : (ot_xmmreg,ot_xmmreg,ot_xmmrm,ot_none);
+    code    : #241#242#249#1#191#61#80;
+    flags   : if_fma
   )
   )
 );
 );

+ 370 - 16
compiler/i8086/n8086add.pas

@@ -33,11 +33,19 @@ interface
        { ti8086addnode }
        { ti8086addnode }
 
 
        ti8086addnode = class(tx86addnode)
        ti8086addnode = class(tx86addnode)
+         function simplify(forinline: boolean) : tnode;override;
          function use_generic_mul32to64: boolean; override;
          function use_generic_mul32to64: boolean; override;
+         function first_addpointer: tnode; override;
+         function first_addhugepointer: tnode;
+         function first_cmppointer: tnode; override;
+         function first_cmphugepointer: tnode;
+         function first_cmpfarpointer: tnode;
          procedure second_addordinal; override;
          procedure second_addordinal; override;
          procedure second_add64bit;override;
          procedure second_add64bit;override;
+         procedure second_addfarpointer;
          procedure second_cmp64bit;override;
          procedure second_cmp64bit;override;
          procedure second_cmp32bit;
          procedure second_cmp32bit;
+         procedure second_cmpfarpointer;
          procedure second_cmpordinal;override;
          procedure second_cmpordinal;override;
          procedure second_mul(unsigned: boolean);
          procedure second_mul(unsigned: boolean);
        end;
        end;
@@ -46,14 +54,105 @@ interface
 
 
     uses
     uses
       globtype,systems,
       globtype,systems,
-      cutils,verbose,globals,
-      symconst,symdef,paramgr,defutil,
+      cutils,verbose,globals,constexp,pass_1,
+      symconst,symdef,symtype,paramgr,defutil,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       cgbase,procinfo,
       cgbase,procinfo,
-      ncon,nset,cgutils,tgobj,
+      ncal,ncon,nset,cgutils,tgobj,
       cga,ncgutil,cgobj,cg64f32,cgx86,
       cga,ncgutil,cgobj,cg64f32,cgx86,
       hlcgobj;
       hlcgobj;
 
 
+{*****************************************************************************
+                                simplify
+*****************************************************************************}
+
+    function ti8086addnode.simplify(forinline: boolean): tnode;
+      var
+        t    : tnode;
+        lt,rt: tnodetype;
+        rd,ld: tdef;
+        rv,lv,v: tconstexprint;
+      begin
+        { load easier access variables }
+        rd:=right.resultdef;
+        ld:=left.resultdef;
+        rt:=right.nodetype;
+        lt:=left.nodetype;
+
+        if (
+            (lt = pointerconstn) and is_farpointer(ld) and
+            is_constintnode(right) and
+            (nodetype in [addn,subn])
+           ) or
+           (
+            (rt = pointerconstn) and is_farpointer(rd) and
+            is_constintnode(left) and
+            (nodetype=addn)
+           ) then
+          begin
+            t:=nil;
+
+            { load values }
+            case lt of
+              ordconstn:
+                lv:=tordconstnode(left).value;
+              pointerconstn:
+                lv:=tpointerconstnode(left).value;
+              niln:
+                lv:=0;
+              else
+                internalerror(2002080202);
+            end;
+            case rt of
+              ordconstn:
+                rv:=tordconstnode(right).value;
+              pointerconstn:
+                rv:=tpointerconstnode(right).value;
+              niln:
+                rv:=0;
+              else
+                internalerror(2002080203);
+            end;
+
+            case nodetype of
+              addn:
+                begin
+                  v:=lv+rv;
+                  if lt=pointerconstn then
+                    t := cpointerconstnode.create((qword(lv) and $FFFF0000) or word(qword(v)),resultdef)
+                  else if rt=pointerconstn then
+                    t := cpointerconstnode.create((qword(rv) and $FFFF0000) or word(qword(v)),resultdef)
+                  else
+                    internalerror(2014040604);
+                end;
+              subn:
+                begin
+                  v:=lv-rv;
+                  if (lt=pointerconstn) then
+                    { pointer-pointer results in an integer }
+                    if (rt=pointerconstn) then
+                      begin
+                        if not(nf_has_pointerdiv in flags) then
+                          internalerror(2008030101);
+                        { todo: implement pointer-pointer as well }
+                        internalerror(2014040607);
+                        //t := cpointerconstnode.create(qword(v),resultdef);
+                      end
+                    else
+                      t := cpointerconstnode.create((qword(lv) and $FFFF0000) or word(qword(v)),resultdef)
+                  else
+                    internalerror(2014040606);
+                end;
+              else
+                internalerror(2014040605);
+            end;
+            result:=t;
+            exit;
+          end
+        else
+          Result:=inherited simplify(forinline);
+      end;
+
 {*****************************************************************************
 {*****************************************************************************
                                 use_generic_mul32to64
                                 use_generic_mul32to64
 *****************************************************************************}
 *****************************************************************************}
@@ -72,6 +171,8 @@ interface
                 not(is_signed(right.resultdef));
                 not(is_signed(right.resultdef));
       if nodetype=muln then
       if nodetype=muln then
         second_mul(unsigned)
         second_mul(unsigned)
+      else if is_farpointer(left.resultdef) xor is_farpointer(right.resultdef) then
+        second_addfarpointer
       else
       else
         inherited second_addordinal;
         inherited second_addordinal;
     end;
     end;
@@ -213,6 +314,208 @@ interface
       end;
       end;
 
 
 
 
+    function ti8086addnode.first_addpointer: tnode;
+      begin
+        if is_hugepointer(left.resultdef) or is_hugepointer(right.resultdef) then
+          result:=first_addhugepointer
+        else
+          result:=inherited;
+      end;
+
+
+    function ti8086addnode.first_addhugepointer: tnode;
+      var
+        procname:string;
+      begin
+        result:=nil;
+
+        if (nodetype=subn) and is_hugepointer(left.resultdef) and is_hugepointer(right.resultdef) then
+          procname:='fpc_hugeptr_sub_hugeptr'
+        else
+          begin
+            case nodetype of
+              addn:
+                procname:='fpc_hugeptr_add_longint';
+              subn:
+                procname:='fpc_hugeptr_sub_longint';
+              else
+                internalerror(2014070301);
+            end;
+
+            if cs_hugeptr_arithmetic_normalization in current_settings.localswitches then
+              procname:=procname+'_normalized';
+          end;
+
+        if is_hugepointer(left.resultdef) then
+          result := ccallnode.createintern(procname,
+            ccallparanode.create(right,
+            ccallparanode.create(left,nil)))
+        else
+          result := ccallnode.createintern(procname,
+            ccallparanode.create(left,
+            ccallparanode.create(right,nil)));
+        left := nil;
+        right := nil;
+        firstpass(result);
+      end;
+
+
+    function ti8086addnode.first_cmppointer: tnode;
+      begin
+        if is_hugepointer(left.resultdef) or is_hugepointer(right.resultdef) then
+          result:=first_cmphugepointer
+        else if is_farpointer(left.resultdef) or is_farpointer(right.resultdef) then
+          result:=first_cmpfarpointer
+        else
+          result:=inherited;
+      end;
+
+
+    function ti8086addnode.first_cmphugepointer: tnode;
+      var
+        procname:string;
+      begin
+        result:=nil;
+
+        if not (cs_hugeptr_comparison_normalization in current_settings.localswitches) then
+          begin
+            expectloc:=LOC_JUMP;
+            exit;
+          end;
+
+        case nodetype of
+          equaln:
+            procname:='fpc_hugeptr_cmp_normalized_e';
+          unequaln:
+            procname:='fpc_hugeptr_cmp_normalized_ne';
+          ltn:
+            procname:='fpc_hugeptr_cmp_normalized_b';
+          lten:
+            procname:='fpc_hugeptr_cmp_normalized_be';
+          gtn:
+            procname:='fpc_hugeptr_cmp_normalized_a';
+          gten:
+            procname:='fpc_hugeptr_cmp_normalized_ae';
+          else
+            internalerror(2014070401);
+        end;
+
+        result := ccallnode.createintern(procname,
+          ccallparanode.create(right,
+          ccallparanode.create(left,nil)));
+        left := nil;
+        right := nil;
+        firstpass(result);
+      end;
+
+
+    function ti8086addnode.first_cmpfarpointer: tnode;
+      begin
+        { = and <> are handled as a 32-bit comparison }
+        if nodetype in [equaln,unequaln] then
+          begin
+            result:=nil;
+            expectloc:=LOC_JUMP;
+          end
+        else
+          begin
+            result:=nil;
+            expectloc:=LOC_FLAGS;
+          end;
+      end;
+
+
+    procedure ti8086addnode.second_addfarpointer;
+      var
+        tmpreg : tregister;
+        pointernode: tnode;
+      begin
+        pass_left_right;
+        force_reg_left_right(false,true);
+        set_result_location_reg;
+
+        if (left.resultdef.typ=pointerdef) and (right.resultdef.typ<>pointerdef) then
+          pointernode:=left
+        else if (left.resultdef.typ<>pointerdef) and (right.resultdef.typ=pointerdef) then
+          pointernode:=right
+        else
+          internalerror(2014040601);
+
+        if not (nodetype in [addn,subn]) then
+          internalerror(2014040602);
+
+        if nodetype=addn then
+          begin
+            if (right.location.loc<>LOC_CONSTANT) then
+              begin
+                cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_16,
+                   left.location.register,right.location.register,location.register);
+                cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,
+                   GetNextReg(pointernode.location.register),GetNextReg(location.register));
+              end
+            else
+              begin
+                if pointernode=left then
+                  begin
+                    { farptr_reg + int_const }
+                    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_16,
+                       right.location.value,left.location.register,location.register);
+                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,
+                       GetNextReg(left.location.register),GetNextReg(location.register));
+                  end
+                else
+                  begin
+                    { int_reg + farptr_const }
+                    tmpreg:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
+                    hlcg.a_load_const_reg(current_asmdata.CurrAsmList,resultdef,
+                      right.location.value,tmpreg);
+                    cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_16,
+                      left.location.register,tmpreg,location.register);
+                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,
+                       GetNextReg(tmpreg),GetNextReg(location.register));
+                  end;
+              end;
+          end
+        else  { subtract is a special case since its not commutative }
+          begin
+            if (nf_swapped in flags) then
+              swapleftright;
+            { left can only be a pointer in this case, since (int-pointer) is not supported }
+            if pointernode<>left then
+              internalerror(2014040603);
+            if left.location.loc<>LOC_CONSTANT then
+              begin
+                if right.location.loc<>LOC_CONSTANT then
+                  begin
+                    cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_16,
+                        right.location.register,left.location.register,location.register);
+                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,
+                       GetNextReg(pointernode.location.register),GetNextReg(location.register));
+                  end
+                else
+                  begin
+                    { farptr_reg - int_const }
+                    cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_16,
+                       right.location.value,left.location.register,location.register);
+                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,
+                       GetNextReg(left.location.register),GetNextReg(location.register));
+                  end;
+              end
+            else
+              begin
+                { farptr_const - int_reg }
+                tmpreg:=hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
+                hlcg.a_load_const_reg(current_asmdata.CurrAsmList,resultdef,
+                  left.location.value,tmpreg);
+                cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_16,
+                  right.location.register,tmpreg,location.register);
+                cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,
+                   GetNextReg(tmpreg),GetNextReg(location.register));
+              end;
+          end;
+      end;
+
+
     procedure ti8086addnode.second_cmp64bit;
     procedure ti8086addnode.second_cmp64bit;
       var
       var
         hregister,
         hregister,
@@ -508,7 +811,8 @@ interface
         unsigned:=((left.resultdef.typ=orddef) and
         unsigned:=((left.resultdef.typ=orddef) and
                    (torddef(left.resultdef).ordtype=u32bit)) or
                    (torddef(left.resultdef).ordtype=u32bit)) or
                   ((right.resultdef.typ=orddef) and
                   ((right.resultdef.typ=orddef) and
-                   (torddef(right.resultdef).ordtype=u32bit));
+                   (torddef(right.resultdef).ordtype=u32bit)) or
+                  is_hugepointer(left.resultdef);
 
 
         { left and right no register?  }
         { left and right no register?  }
         { then one must be demanded    }
         { then one must be demanded    }
@@ -581,9 +885,60 @@ interface
         location_reset(location,LOC_JUMP,OS_NO)
         location_reset(location,LOC_JUMP,OS_NO)
       end;
       end;
 
 
+
+    procedure ti8086addnode.second_cmpfarpointer;
+      begin
+        { handle = and <> as a 32-bit comparison }
+        if nodetype in [equaln,unequaln] then
+          begin
+            second_cmp32bit;
+            exit;
+          end;
+
+        pass_left_right;
+
+        { <, >, <= and >= compare the 16-bit offset only }
+        if (right.location.loc=LOC_CONSTANT) and
+           (left.location.loc in [LOC_REFERENCE, LOC_CREFERENCE])
+        then
+          begin
+            emit_const_ref(A_CMP, S_W, word(right.location.value), left.location.reference);
+            location_freetemp(current_asmdata.CurrAsmList,left.location);
+          end
+        else
+          begin
+            { left location is not a register? }
+            if left.location.loc<>LOC_REGISTER then
+             begin
+               { if right is register then we can swap the locations }
+               if right.location.loc=LOC_REGISTER then
+                begin
+                  location_swap(left.location,right.location);
+                  toggleflag(nf_swapped);
+                end
+               else
+                begin
+                  { maybe we can reuse a constant register when the
+                    operation is a comparison that doesn't change the
+                    value of the register }
+                  hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,u16inttype,true);
+                end;
+              end;
+
+            emit_generic_code(A_CMP,OS_16,true,false,false);
+            location_freetemp(current_asmdata.CurrAsmList,right.location);
+            location_freetemp(current_asmdata.CurrAsmList,left.location);
+          end;
+        location_reset(location,LOC_FLAGS,OS_NO);
+        location.resflags:=getresflags(true);
+      end;
+
+
     procedure ti8086addnode.second_cmpordinal;
     procedure ti8086addnode.second_cmpordinal;
       begin
       begin
-        if is_32bit(left.resultdef) or is_farpointer(left.resultdef) or is_hugepointer(left.resultdef) then
+        if is_farpointer(left.resultdef) then
+          second_cmpfarpointer
+        else if is_32bit(left.resultdef) or is_hugepointer(left.resultdef) then
           second_cmp32bit
           second_cmp32bit
         else
         else
           inherited second_cmpordinal;
           inherited second_cmpordinal;
@@ -596,15 +951,6 @@ interface
 
 
     procedure ti8086addnode.second_mul(unsigned: boolean);
     procedure ti8086addnode.second_mul(unsigned: boolean);
 
 
-      procedure add_mov(instr: Taicpu);
-        begin
-          { Notify the register allocator that we have written a move instruction so
-            it can try to eliminate it. }
-          if (instr.oper[0]^.reg<>current_procinfo.framepointer) and (instr.oper[0]^.reg<>NR_STACK_POINTER_REG) then
-            tcgx86(cg).add_move_instruction(instr);
-          current_asmdata.CurrAsmList.concat(instr);
-        end;
-
     var reg:Tregister;
     var reg:Tregister;
         ref:Treference;
         ref:Treference;
         use_ref:boolean;
         use_ref:boolean;
@@ -616,6 +962,13 @@ interface
     begin
     begin
       pass_left_right;
       pass_left_right;
 
 
+      { MUL is faster than IMUL on the 8086 & 8088 (and equal in speed on 286+),
+        but it's only safe to use in place of IMUL when overflow checking is off
+        and we're doing a 16-bit>16-bit multiplication }
+      if not (cs_check_overflow in current_settings.localswitches) and
+        (not is_32bitint(resultdef)) then
+        unsigned:=true;
+
       {The location.register will be filled in later (JM)}
       {The location.register will be filled in later (JM)}
       location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
       location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
       { Mul supports registers and references, so if not register/reference,
       { Mul supports registers and references, so if not register/reference,
@@ -661,8 +1014,9 @@ interface
         {Allocate an imaginary 32-bit register, which consists of a pair of
         {Allocate an imaginary 32-bit register, which consists of a pair of
          16-bit registers and store DX:AX into it}
          16-bit registers and store DX:AX into it}
         location.register := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
         location.register := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-        add_mov(Taicpu.Op_reg_reg(A_MOV,S_W,NR_AX,location.register));
-        add_mov(Taicpu.Op_reg_reg(A_MOV,S_W,NR_DX,GetNextReg(location.register)));
+        cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_DX,GetNextReg(location.register));
+        cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_AX);
+        cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_AX,location.register);
       end
       end
       else
       else
       begin
       begin

+ 35 - 4
compiler/i8086/n8086cal.pas

@@ -28,13 +28,15 @@ interface
 { $define AnsiStrRef}
 { $define AnsiStrRef}
 
 
     uses
     uses
-      nx86cal;
+      nx86cal,cgutils;
 
 
     type
     type
        ti8086callnode = class(tx86callnode)
        ti8086callnode = class(tx86callnode)
        protected
        protected
           procedure pop_parasize(pop_size:longint);override;
           procedure pop_parasize(pop_size:longint);override;
           procedure extra_interrupt_code;override;
           procedure extra_interrupt_code;override;
+          procedure extra_call_ref_code(var ref: treference);override;
+          procedure do_call_ref(ref: treference);override;
        end;
        end;
 
 
 
 
@@ -43,11 +45,11 @@ implementation
     uses
     uses
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
-      cgbase,cgutils,
+      cgbase,
       cpubase,paramgr,
       cpubase,paramgr,
       aasmtai,aasmdata,aasmcpu,
       aasmtai,aasmdata,aasmcpu,
       ncal,nbas,nmem,nld,ncnv,
       ncal,nbas,nmem,nld,ncnv,
-      cga,cgobj,cpuinfo;
+      cga,cgobj,cgx86,cpuinfo;
 
 
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -58,7 +60,8 @@ implementation
     procedure ti8086callnode.extra_interrupt_code;
     procedure ti8086callnode.extra_interrupt_code;
       begin
       begin
         emit_none(A_PUSHF,S_W);
         emit_none(A_PUSHF,S_W);
-        emit_reg(A_PUSH,S_W,NR_CS);
+        if current_settings.x86memorymodel in x86_near_code_models then
+          emit_reg(A_PUSH,S_W,NR_CS);
       end;
       end;
 
 
 
 
@@ -92,6 +95,34 @@ implementation
       end;
       end;
 
 
 
 
+    procedure ti8086callnode.extra_call_ref_code(var ref: treference);
+      begin
+        if (ref.base<>NR_NO) and (ref.base<>NR_BP) then
+          begin
+            cg.getcpuregister(current_asmdata.CurrAsmList,NR_BX);
+            cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,ref.base,NR_BX);
+            ref.base:=NR_BX;
+            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_BX);
+          end;
+        if ref.index<>NR_NO then
+          begin
+            cg.getcpuregister(current_asmdata.CurrAsmList,NR_SI);
+            cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,ref.index,NR_SI);
+            ref.index:=NR_SI;
+            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_SI);
+          end;
+      end;
+
+
+    procedure ti8086callnode.do_call_ref(ref: treference);
+      begin
+        if current_settings.x86memorymodel in x86_far_code_models then
+          current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_FAR,ref))
+        else
+          current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,ref));
+      end;
+
+
 begin
 begin
    ccallnode:=ti8086callnode;
    ccallnode:=ti8086callnode;
 end.
 end.

+ 18 - 104
compiler/i8086/n8086cnv.pas

@@ -29,10 +29,13 @@ interface
       node,ncgcnv,nx86cnv,defutil,defcmp;
       node,ncgcnv,nx86cnv,defutil,defcmp;
 
 
     type
     type
+
+       { t8086typeconvnode }
+
        t8086typeconvnode = class(tx86typeconvnode)
        t8086typeconvnode = class(tx86typeconvnode)
        protected
        protected
+         function typecheck_proc_to_procvar: tnode;override;
          procedure second_proc_to_procvar;override;
          procedure second_proc_to_procvar;override;
-         procedure second_nil_to_methodprocvar;override;
        end;
        end;
 
 
 
 
@@ -41,120 +44,31 @@ implementation
    uses
    uses
       verbose,systems,globals,globtype,
       verbose,systems,globals,globtype,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       aasmbase,aasmtai,aasmdata,aasmcpu,
-      symconst,symdef,
+      symconst,symdef,symcpu,
       cgbase,cga,procinfo,pass_1,pass_2,
       cgbase,cga,procinfo,pass_1,pass_2,
       ncon,ncal,ncnv,
       ncon,ncal,ncnv,
       cpubase,cpuinfo,
       cpubase,cpuinfo,
       cgutils,cgobj,hlcgobj,cgx86,ncgutil,
       cgutils,cgobj,hlcgobj,cgx86,ncgutil,
       tgobj;
       tgobj;
 
 
-
-    procedure t8086typeconvnode.second_proc_to_procvar;
-      var
-        tmpreg: tregister;
-        tmpref: treference;
+    function t8086typeconvnode.typecheck_proc_to_procvar: tnode;
       begin
       begin
-        if not (po_far in tabstractprocdef(resultdef).procoptions) then
-          begin
-            inherited;
-            exit;
-          end;
-
-        if tabstractprocdef(resultdef).is_addressonly then
-          begin
-            location_reset(location,LOC_REGISTER,OS_32);
-            { only a code pointer? (when taking the address of classtype.method
-              we also only get a code pointer even though the resultdef is a
-              procedure of object, and hence is_addressonly would return false)
-             }
-  	    if left.location.size = OS_32 then
-              begin
-                case left.location.loc of
-                  LOC_REFERENCE,LOC_CREFERENCE:
-                    begin
-                      { the procedure symbol is encoded in reference.symbol -> take address }
-                      location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-                      cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,location.register);
-                      tmpref:=left.location.reference;
-                      tmpref.refaddr:=addr_seg;
-                      cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,tmpref,GetNextReg(location.register));
-                    end;
-                  else
-                    internalerror(2013031501)
-                end;
-              end
-            else
-              begin
-                { conversion from a procedure of object/nested procvar to plain procvar }
-                case left.location.loc of
-                  LOC_REFERENCE,LOC_CREFERENCE:
-                    begin
-                      location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-                      { code field is the first one }
-                      cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,location.register);
-                    end;
-                  LOC_REGISTER,LOC_CREGISTER:
-                    begin
-                      if target_info.endian=endian_little then
-                        location.register:=left.location.register
-                      else
-                        location.register:=left.location.registerhi;
-                    end;
-                  else
-                    internalerror(2013031502)
-                end;
-              end;
-          end
-        else
-          begin
-            { TODO: update for far procs }
-            if not tabstractprocdef(left.resultdef).is_addressonly then
-              location_copy(location,left.location)
-            else
-              begin
-                { assigning a global function to a nested procvar -> create
-                  tmethodpointer record and set the "frame pointer" to nil }
-                if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-                  internalerror(2013031503);
-                location_reset_ref(location,LOC_REFERENCE,int_cgsize(sizeof(pint)*2),sizeof(pint));
-                tg.gethltemp(current_asmdata.CurrAsmList,resultdef,resultdef.size,tt_normal,location.reference);
-                tmpreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
-                cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,tmpreg);
-                cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,tmpreg,location.reference);
-                { setting the frame pointer to nil is not strictly necessary
-                  since the global procedure won't use it, but it can help with
-                  debugging }
-                inc(location.reference.offset,sizeof(pint));
-                cg.a_load_const_ref(current_asmdata.CurrAsmList,OS_ADDR,0,location.reference);
-                dec(location.reference.offset,sizeof(pint));
-              end;
-          end;
+        if (current_settings.x86memorymodel in x86_far_code_models) and
+          not is_proc_far(tabstractprocdef(left.resultdef)) then
+          CGMessage1(type_e_procedure_must_be_far,left.resultdef.GetTypeName);
+        Result:=inherited typecheck_proc_to_procvar;
       end;
       end;
 
 
 
 
-    procedure t8086typeconvnode.second_nil_to_methodprocvar;
+    procedure t8086typeconvnode.second_proc_to_procvar;
       begin
       begin
-        location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
-        if current_settings.x86memorymodel in x86_far_data_models then
-          begin
-            location.registerhi:=cg.getintregister(current_asmdata.currasmlist,OS_32);
-            cg.a_load_const_reg(current_asmdata.currasmlist,OS_32,0,location.registerhi);
-          end
-        else
-          begin
-            location.registerhi:=cg.getaddressregister(current_asmdata.currasmlist);
-            cg.a_load_const_reg(current_asmdata.currasmlist,OS_ADDR,0,location.registerhi);
-          end;
-        if (resultdef.typ=procvardef) and (po_far in tprocvardef(resultdef).procoptions) then
-          begin
-            location.register:=cg.getintregister(current_asmdata.currasmlist,OS_32);
-            cg.a_load_const_reg(current_asmdata.currasmlist,OS_32,0,location.register);
-          end
-        else
-          begin
-            location.register:=cg.getaddressregister(current_asmdata.currasmlist);
-            cg.a_load_const_reg(current_asmdata.currasmlist,OS_ADDR,0,location.register);
-          end;
+        if is_proc_far(tabstractprocdef(resultdef))<>
+           (current_settings.x86memorymodel in x86_far_code_models) then
+          internalerror(2014041302);
+        if is_proc_far(tabstractprocdef(left.resultdef))<>
+           (current_settings.x86memorymodel in x86_far_code_models) then
+          internalerror(2014041303);
+        inherited;
       end;
       end;
 
 
 
 

+ 16 - 5
compiler/i8086/n8086con.pas

@@ -26,21 +26,22 @@ unit n8086con;
 interface
 interface
 
 
     uses
     uses
-       node,ncon,ncgcon,nx86con;
+       globtype,symtype,ncon,ncgcon,nx86con;
 
 
     type
     type
 
 
-      { tcgpointerconstnode }
+      { ti8086pointerconstnode }
 
 
       ti8086pointerconstnode = class(tcgpointerconstnode)
       ti8086pointerconstnode = class(tcgpointerconstnode)
+        constructor create(v : TConstPtrUInt;def:tdef);override;
         procedure pass_generate_code;override;
         procedure pass_generate_code;override;
       end;
       end;
 
 
 implementation
 implementation
 
 
     uses
     uses
-      systems,globals,globtype,
-      symconst,symdef,
+      systems,globals,
+      symconst,symdef,symcpu,
       defutil,
       defutil,
       cpubase,
       cpubase,
       cga,cgx86,cgobj,cgbase,cgutils;
       cga,cgx86,cgobj,cgbase,cgutils;
@@ -49,10 +50,20 @@ implementation
                                T8086POINTERCONSTNODE
                                T8086POINTERCONSTNODE
     *****************************************************************************}
     *****************************************************************************}
 
 
+
+    constructor ti8086pointerconstnode.create(v: TConstPtrUInt; def: tdef);
+      begin
+        { truncate near pointers }
+        if (def.typ<>pointerdef) or not (tcpupointerdef(def).x86pointertyp in [x86pt_far,x86pt_huge]) then
+          v := Word(v);
+        inherited create(v, def);
+      end;
+
+
     procedure ti8086pointerconstnode.pass_generate_code;
     procedure ti8086pointerconstnode.pass_generate_code;
       begin
       begin
         { far pointer? }
         { far pointer? }
-        if (typedef.typ=pointerdef) and (tpointerdef(typedef).x86pointertyp in [x86pt_far,x86pt_huge]) then
+        if (typedef.typ=pointerdef) and (tcpupointerdef(typedef).x86pointertyp in [x86pt_far,x86pt_huge]) then
           begin
           begin
             location_reset(location,LOC_CONSTANT,OS_32);
             location_reset(location,LOC_CONSTANT,OS_32);
             location.value:=longint(value);
             location.value:=longint(value);

+ 138 - 4
compiler/i8086/n8086inl.pas

@@ -36,6 +36,8 @@ interface
          function typecheck_seg: tnode; override;
          function typecheck_seg: tnode; override;
          function first_seg: tnode; override;
          function first_seg: tnode; override;
          procedure second_seg; override;
          procedure second_seg; override;
+         procedure second_get_frame;override;
+         procedure second_incdec;override;
        end;
        end;
 
 
 implementation
 implementation
@@ -45,6 +47,7 @@ implementation
     systems,
     systems,
     globtype,globals,
     globtype,globals,
     cutils,verbose,
     cutils,verbose,
+    constexp,
     symconst,
     symconst,
     defutil,
     defutil,
     aasmbase,aasmtai,aasmdata,aasmcpu,
     aasmbase,aasmtai,aasmdata,aasmcpu,
@@ -54,12 +57,19 @@ implementation
     nbas,ncon,ncal,ncnv,nld,ncgutil,
     nbas,ncon,ncal,ncnv,nld,ncgutil,
     tgobj,
     tgobj,
     cga,cgutils,cgx86,cgobj,hlcgobj,
     cga,cgutils,cgx86,cgobj,hlcgobj,
-    htypechk;
+    htypechk,procinfo;
 
 
      function ti8086inlinenode.typecheck_seg: tnode;
      function ti8086inlinenode.typecheck_seg: tnode;
        begin
        begin
          result := nil;
          result := nil;
          resultdef:=u16inttype;
          resultdef:=u16inttype;
+
+         { don't allow constants }
+         if is_constnode(left) then
+          begin
+            CGMessagePos(left.fileinfo,type_e_no_addr_of_constant);
+            exit;
+          end;
        end;
        end;
 
 
      function ti8086inlinenode.first_seg: tnode;
      function ti8086inlinenode.first_seg: tnode;
@@ -69,10 +79,134 @@ implementation
        end;
        end;
 
 
      procedure ti8086inlinenode.second_seg;
      procedure ti8086inlinenode.second_seg;
+       var
+         segref: treference;
+       begin
+         secondpass(left);
+
+         if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
+           internalerror(2013040101);
+
+         { if a segment register is specified in ref, we use that }
+         if left.location.reference.segment<>NR_NO then
+           begin
+             location_reset(location,LOC_REGISTER,OS_16);
+             if is_segment_reg(left.location.reference.segment) then
+               begin
+                 location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
+                 current_asmdata.CurrAsmList.Concat(Taicpu.op_reg_reg(A_MOV,S_W,left.location.reference.segment,location.register));
+               end
+             else
+               location.register:=left.location.reference.segment;
+           end
+         { references relative to a symbol use the segment of the symbol,
+           which can be obtained by the SEG directive }
+         else if assigned(left.location.reference.symbol) then
+           begin
+             location_reset(location,LOC_REGISTER,OS_16);
+             location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
+             reference_reset_symbol(segref,left.location.reference.symbol,0,0);
+             segref.refaddr:=addr_seg;
+             cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,location.register);
+           end
+         else if left.location.reference.base=NR_BP then
+           begin
+             location_reset(location,LOC_REGISTER,OS_16);
+             location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
+             current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg(A_MOV,S_W,NR_SS,location.register));
+           end
+         else
+           begin
+             location_reset(location,LOC_REGISTER,OS_16);
+             location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
+             current_asmdata.CurrAsmList.Concat(Taicpu.op_reg_reg(A_MOV,S_W,NR_DS,location.register));
+           end;
+       end;
+
+     procedure ti8086inlinenode.second_get_frame;
+       begin
+         if current_settings.x86memorymodel in x86_far_data_models then
+           begin
+             if current_procinfo.framepointer=NR_STACK_POINTER_REG then
+               internalerror(2014030201);
+             location_reset(location,LOC_REGISTER,OS_32);
+             location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+             emit_reg_reg(A_MOV,S_W,current_procinfo.framepointer,location.register);
+             current_asmdata.CurrAsmList.Concat(Taicpu.op_reg_reg(A_MOV,S_W,NR_SS,GetNextReg(location.register)));
+           end
+         else
+           inherited second_get_frame;
+       end;
+
+     procedure ti8086inlinenode.second_incdec;
+       const
+         addsubop:array[in_inc_x..in_dec_x] of TOpCG=(OP_ADD,OP_SUB);
+       var
+         addvalue : TConstExprInt;
+         addconstant : boolean;
+         hregister : tregister;
+         tmploc: tlocation;
        begin
        begin
-         location_reset(location,LOC_REGISTER,OS_16);
-         location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
-         current_asmdata.CurrAsmList.Concat(Taicpu.op_reg_reg(A_MOV,S_W,NR_DS,location.register));
+         if is_farpointer(tcallparanode(left).left.resultdef) then
+           begin
+             { set defaults }
+             addconstant:=true;
+             hregister:=NR_NO;
+
+             { first secondpass second argument, because if the first arg }
+             { is used in that expression then SSL may move it to another }
+             { register                                                   }
+             if assigned(tcallparanode(left).right) then
+               secondpass(tcallparanode(tcallparanode(left).right).left);
+             { load first parameter, must be a reference }
+             secondpass(tcallparanode(left).left);
+             tmploc:=tcallparanode(left).left.location;
+             tmploc.size:=OS_S16;
+             { get addvalue }
+             case tcallparanode(left).left.resultdef.typ of
+               pointerdef :
+                 begin
+                   if is_void(tpointerdef(tcallparanode(left).left.resultdef).pointeddef) then
+                     addvalue:=1
+                   else
+                     addvalue:=tpointerdef(tcallparanode(left).left.resultdef).pointeddef.size;
+                 end;
+               else
+                 internalerror(10081);
+             end;
+             { second_ argument specified?, must be a s16bit in register }
+             if assigned(tcallparanode(left).right) then
+               begin
+                 { when constant, just multiply the addvalue }
+                 if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
+                    addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
+                 else if is_constpointernode(tcallparanode(tcallparanode(left).right).left) then
+                    addvalue:=addvalue*tpointerconstnode(tcallparanode(tcallparanode(left).right).left).value
+                 else
+                   begin
+                     hlcg.location_force_reg(current_asmdata.CurrAsmList,tcallparanode(tcallparanode(left).right).left.location,tcallparanode(tcallparanode(left).right).left.resultdef,s16inttype,addvalue<=1);
+                     hregister:=tcallparanode(tcallparanode(left).right).left.location.register;
+                     { insert multiply with addvalue if its >1 }
+                     if addvalue>1 then
+                       hlcg.a_op_const_reg(current_asmdata.CurrAsmList,OP_IMUL,s16inttype,addvalue.svalue,hregister);
+                     addconstant:=false;
+                   end;
+               end;
+             { write the add instruction }
+             if addconstant then
+               begin
+                 hlcg.a_op_const_loc(current_asmdata.CurrAsmList,addsubop[inlinenumber],s16inttype,
+                   smallint(addvalue.svalue),
+                   tmploc);
+               end
+             else
+               begin
+                 hlcg.a_op_reg_loc(current_asmdata.CurrAsmList,addsubop[inlinenumber],s16inttype,
+                   hregister,tmploc);
+               end;
+           end
+         else
+           inherited second_incdec;
        end;
        end;
 
 
 begin
 begin

+ 91 - 0
compiler/i8086/n8086ld.pas

@@ -0,0 +1,91 @@
+{
+    Copyright (c) 2002-2014 by Florian Klaempfl
+
+    Generate i8086 assembler for load nodes
+
+    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 n8086ld;
+
+{$i fpcdefs.inc}
+
+interface
+
+    uses
+      globtype,
+      symsym,symtype,
+      node,ncgld;
+
+    type
+      ti8086loadnode = class(tcgloadnode)
+         procedure generate_nested_access(vs: tsym); override;
+         procedure generate_absaddr_access(vs: tabsolutevarsym); override;
+      end;
+
+
+implementation
+
+    uses
+      globals,aasmdata,
+      symcpu,
+      nld,
+      cgbase,cgobj,
+      cpubase,cpuinfo;
+
+{*****************************************************************************
+                            TI8086LOADNODE
+*****************************************************************************}
+
+    procedure ti8086loadnode.generate_nested_access(vs: tsym);
+      begin
+        inherited;
+
+        { the parentfp pointer is always a near pointer (this is turbo pascal
+          compatible) regardless of memory model, so we need to set the segment
+          manually.
+
+          todo: once the far data memory models are fully implemented, the
+          parentfp type should be changed to a near 'ss' pointer in all memory
+          models and then this code can be removed. But this can only happen
+          after:
+          1) all calls to a_loadaddr_ref_reg go through the high level code
+             generator
+          2) a_loadaddr_ref_reg in the low level code generator stops using
+             the presence of a segment in the source reference to determine the
+             destination reg size
+          3) make_simple_ref is updated to remove unnecessary segment prefixes
+          4) hlcg.reference_reset_base is updated to set the segment on near_ss
+             pointers }
+        if (left.nodetype=loadparentfpn) and
+           (current_settings.x86memorymodel in x86_far_data_models) then
+          location.reference.segment:=NR_SS;
+      end;
+
+    procedure ti8086loadnode.generate_absaddr_access(vs: tabsolutevarsym);
+      begin
+        if tcpuabsolutevarsym(symtableentry).absseg then
+          begin
+            location.reference.segment:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
+            cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_16,aint(tcpuabsolutevarsym(symtableentry).addrsegment),location.reference.segment);
+          end;
+        inherited;
+      end;
+
+
+begin
+   cloadnode:=ti8086loadnode;
+end.

+ 121 - 100
compiler/i8086/n8086mat.pas

@@ -30,6 +30,8 @@ interface
 
 
     type
     type
       ti8086moddivnode = class(tmoddivnode)
       ti8086moddivnode = class(tmoddivnode)
+         function use_moddiv32bit_helper: boolean;
+         function first_moddivint: tnode; override;
          procedure pass_generate_code;override;
          procedure pass_generate_code;override;
       end;
       end;
 
 
@@ -61,7 +63,26 @@ implementation
                              ti8086moddivnode
                              ti8086moddivnode
 *****************************************************************************}
 *****************************************************************************}
 
 
-    function log2(i : dword) : dword;
+
+    function ti8086moddivnode.use_moddiv32bit_helper: boolean;
+      begin
+        result:=is_32bit(left.resultdef) or
+                is_64bit(left.resultdef) or
+                is_32bit(right.resultdef) or
+                is_64bit(right.resultdef);
+      end;
+
+
+    function ti8086moddivnode.first_moddivint: tnode;
+      begin
+        if use_moddiv32bit_helper then
+          result:=inherited first_moddivint
+        else
+          result:=nil;
+      end;
+
+
+    function log2(i : word) : word;
       begin
       begin
         result:=0;
         result:=0;
         i:=i shr 1;
         i:=i shr 1;
@@ -79,9 +100,9 @@ implementation
         power:longint;
         power:longint;
         hl:Tasmlabel;
         hl:Tasmlabel;
         op:Tasmop;
         op:Tasmop;
-        e : longint;
-        d,l,r,s,m,a,n,t : dword;
-        m_low,m_high,j,k : qword;
+        e : smallint;
+        d,l,r,s,m,a,n,t : word;
+        m_low,m_high,j,k : dword;
       begin
       begin
         secondpass(left);
         secondpass(left);
         if codegenerror then
         if codegenerror then
@@ -90,7 +111,7 @@ implementation
         if codegenerror then
         if codegenerror then
           exit;
           exit;
 
 
-        if is_64bitint(resultdef) then
+        if is_64bitint(resultdef) or is_32bitint(resultdef) then
           { should be handled in pass_1 (JM) }
           { should be handled in pass_1 (JM) }
           internalerror(200109052);
           internalerror(200109052);
         { put numerator in register }
         { put numerator in register }
@@ -107,39 +128,39 @@ implementation
                   "Cardinal($ffffffff) div 16" overflows! (JM) }
                   "Cardinal($ffffffff) div 16" overflows! (JM) }
                 if is_signed(left.resultdef) Then
                 if is_signed(left.resultdef) Then
                   begin
                   begin
-                    if (current_settings.optimizecputype <> cpu_386) and
+                    if (current_settings.optimizecputype > cpu_386) and
                        not(cs_opt_size in current_settings.optimizerswitches) then
                        not(cs_opt_size in current_settings.optimizerswitches) then
                       { use a sequence without jumps, saw this in
                       { use a sequence without jumps, saw this in
                         comp.compilers (JM) }
                         comp.compilers (JM) }
                       begin
                       begin
                         { no jumps, but more operations }
                         { no jumps, but more operations }
                         hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                         hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                        emit_reg_reg(A_MOV,S_L,hreg1,hreg2);
-                        {If the left value is signed, hreg2=$ffffffff, otherwise 0.}
-                        emit_const_reg(A_SAR,S_L,31,hreg2);
+                        emit_reg_reg(A_MOV,S_W,hreg1,hreg2);
+                        {If the left value is signed, hreg2=$ffff, otherwise 0.}
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,15,hreg2);
                         {If signed, hreg2=right value-1, otherwise 0.}
                         {If signed, hreg2=right value-1, otherwise 0.}
-                        emit_const_reg(A_AND,S_L,tordconstnode(right).value.svalue-1,hreg2);
+                        emit_const_reg(A_AND,S_W,tordconstnode(right).value.svalue-1,hreg2);
                         { add to the left value }
                         { add to the left value }
-                        emit_reg_reg(A_ADD,S_L,hreg2,hreg1);
+                        emit_reg_reg(A_ADD,S_W,hreg2,hreg1);
                         { do the shift }
                         { do the shift }
-                        emit_const_reg(A_SAR,S_L,power,hreg1);
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,power,hreg1);
                       end
                       end
                     else
                     else
                       begin
                       begin
                         { a jump, but less operations }
                         { a jump, but less operations }
-                        emit_reg_reg(A_TEST,S_L,hreg1,hreg1);
+                        emit_reg_reg(A_TEST,S_W,hreg1,hreg1);
                         current_asmdata.getjumplabel(hl);
                         current_asmdata.getjumplabel(hl);
                         cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NS,hl);
                         cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NS,hl);
                         if power=1 then
                         if power=1 then
-                          emit_reg(A_INC,S_L,hreg1)
+                          emit_reg(A_INC,S_W,hreg1)
                         else
                         else
-                          emit_const_reg(A_ADD,S_L,tordconstnode(right).value.svalue-1,hreg1);
+                          emit_const_reg(A_ADD,S_W,tordconstnode(right).value.svalue-1,hreg1);
                         cg.a_label(current_asmdata.CurrAsmList,hl);
                         cg.a_label(current_asmdata.CurrAsmList,hl);
-                        emit_const_reg(A_SAR,S_L,power,hreg1);
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,power,hreg1);
                       end
                       end
                   end
                   end
                 else
                 else
-                  emit_const_reg(A_SHR,S_L,power,hreg1);
+                  cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,power,hreg1);
                 location.register:=hreg1;
                 location.register:=hreg1;
               end
               end
             else
             else
@@ -148,85 +169,85 @@ implementation
                   begin
                   begin
                     e:=tordconstnode(right).value.svalue;
                     e:=tordconstnode(right).value.svalue;
                     d:=abs(e);
                     d:=abs(e);
-                    { Determine algorithm (a), multiplier (m), and shift factor (s) for 32-bit
+                    { Determine algorithm (a), multiplier (m), and shift factor (s) for 16-bit
                       signed integer division. Based on: Granlund, T.; Montgomery, P.L.:
                       signed integer division. Based on: Granlund, T.; Montgomery, P.L.:
                       "Division by Invariant Integers using Multiplication". SIGPLAN Notices,
                       "Division by Invariant Integers using Multiplication". SIGPLAN Notices,
                       Vol. 29, June 1994, page 61.
                       Vol. 29, June 1994, page 61.
                     }
                     }
 
 
                     l:=log2(d);
                     l:=log2(d);
-                    j:=qword($80000000) mod qword(d);
-                    k:=(qword(1) shl (32+l)) div (qword($80000000-j));
-                    m_low:=((qword(1)) shl (32+l)) div d;
-                    m_high:=(((qword(1)) shl (32+l)) + k) div d;
+                    j:=dword($8000) mod dword(d);
+                    k:=(dword(1) shl (16+l)) div (dword($8000-j));
+                    m_low:=((dword(1)) shl (16+l)) div d;
+                    m_high:=(((dword(1)) shl (16+l)) + k) div d;
                     while ((m_low shr 1) < (m_high shr 1)) and (l > 0) do
                     while ((m_low shr 1) < (m_high shr 1)) and (l > 0) do
                       begin
                       begin
                         m_low:=m_low shr 1;
                         m_low:=m_low shr 1;
                         m_high:=m_high shr 1;
                         m_high:=m_high shr 1;
                         dec(l);
                         dec(l);
                       end;
                       end;
-                    m:=dword(m_high);
+                    m:=word(m_high);
                     s:=l;
                     s:=l;
-                    if (m_high shr 31)<>0 then
+                    if (m_high shr 15)<>0 then
                       a:=1
                       a:=1
                     else
                     else
                       a:=0;
                       a:=0;
-                    cg.getcpuregister(current_asmdata.CurrAsmList,NR_EAX);
-                    emit_const_reg(A_MOV,S_L,aint(m),NR_EAX);
-                    cg.getcpuregister(current_asmdata.CurrAsmList,NR_EDX);
-                    emit_reg(A_IMUL,S_L,hreg1);
-                    emit_reg_reg(A_MOV,S_L,hreg1,NR_EAX);
+                    cg.getcpuregister(current_asmdata.CurrAsmList,NR_AX);
+                    emit_const_reg(A_MOV,S_W,aint(m),NR_AX);
+                    cg.getcpuregister(current_asmdata.CurrAsmList,NR_DX);
+                    emit_reg(A_IMUL,S_W,hreg1);
+                    emit_reg_reg(A_MOV,S_W,hreg1,NR_AX);
                     if a<>0 then
                     if a<>0 then
                       begin
                       begin
-                        emit_reg_reg(A_ADD,S_L,NR_EAX,NR_EDX);
+                        emit_reg_reg(A_ADD,S_W,NR_AX,NR_DX);
                         {
                         {
-                          printf ("; dividend: memory location or register other than EAX or EDX\n");
+                          printf ("; dividend: memory location or register other than AX or DX\n");
                           printf ("\n");
                           printf ("\n");
-                          printf ("MOV EAX, 0%08LXh\n", m);
+                          printf ("MOV AX, 0%08LXh\n", m);
                           printf ("IMUL dividend\n");
                           printf ("IMUL dividend\n");
-                          printf ("MOV EAX, dividend\n");
-                          printf ("ADD EDX, EAX\n");
-                          if (s) printf ("SAR EDX, %d\n", s);
-                          printf ("SHR EAX, 31\n");
-                          printf ("ADD EDX, EAX\n");
-                          if (e < 0) printf ("NEG EDX\n");
+                          printf ("MOV AX, dividend\n");
+                          printf ("ADD DX, AX\n");
+                          if (s) printf ("SAR DX, %d\n", s);
+                          printf ("SHR AX, 15\n");
+                          printf ("ADD DX, AX\n");
+                          if (e < 0) printf ("NEG DX\n");
                           printf ("\n");
                           printf ("\n");
-                          printf ("; quotient now in EDX\n");
+                          printf ("; quotient now in DX\n");
                         }
                         }
                       end;
                       end;
                       {
                       {
-                        printf ("; dividend: memory location of register other than EAX or EDX\n");
+                        printf ("; dividend: memory location of register other than AX or DX\n");
                         printf ("\n");
                         printf ("\n");
-                        printf ("MOV EAX, 0%08LXh\n", m);
+                        printf ("MOV AX, 0%08LXh\n", m);
                         printf ("IMUL dividend\n");
                         printf ("IMUL dividend\n");
-                        printf ("MOV EAX, dividend\n");
-                        if (s) printf ("SAR EDX, %d\n", s);
-                        printf ("SHR EAX, 31\n");
-                        printf ("ADD EDX, EAX\n");
-                        if (e < 0) printf ("NEG EDX\n");
+                        printf ("MOV AX, dividend\n");
+                        if (s) printf ("SAR DX, %d\n", s);
+                        printf ("SHR AX, 15\n");
+                        printf ("ADD DX, AX\n");
+                        if (e < 0) printf ("NEG DX\n");
                         printf ("\n");
                         printf ("\n");
-                        printf ("; quotient now in EDX\n");
+                        printf ("; quotient now in DX\n");
                       }
                       }
                     if s<>0 then
                     if s<>0 then
-                      emit_const_reg(A_SAR,S_L,s,NR_EDX);
-                    emit_const_reg(A_SHR,S_L,31,NR_EAX);
-                    emit_reg_reg(A_ADD,S_L,NR_EAX,NR_EDX);
+                      cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,s,NR_DX);
+                    cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,15,NR_AX);
+                    emit_reg_reg(A_ADD,S_W,NR_AX,NR_DX);
                     if e<0 then
                     if e<0 then
-                      emit_reg(A_NEG,S_L,NR_EDX);
-                    cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EDX);
-                    cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EAX);
+                      emit_reg(A_NEG,S_W,NR_DX);
+                    cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_DX);
+                    cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_AX);
                     location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                     location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_EDX,location.register)
+                    cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_DX,location.register)
                   end
                   end
                 else
                 else
                   begin
                   begin
                     d:=tordconstnode(right).value.svalue;
                     d:=tordconstnode(right).value.svalue;
-                    if d>=$80000000 then
+                    if d>=$8000 then
                       begin
                       begin
-                        emit_const_reg(A_CMP,S_L,aint(d),hreg1);
+                        emit_const_reg(A_CMP,S_W,aint(d),hreg1);
                         location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                         location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                        emit_const_reg(A_MOV,S_L,0,location.register);
-                        emit_const_reg(A_SBB,S_L,-1,location.register);
+                        emit_const_reg(A_MOV,S_W,0,location.register);
+                        emit_const_reg(A_SBB,S_W,-1,location.register);
                       end
                       end
                     else
                     else
                       begin
                       begin
@@ -243,19 +264,19 @@ implementation
                         SIGPLAN Notices, Vol. 29, June 1994, page 61.
                         SIGPLAN Notices, Vol. 29, June 1994, page 61.
                         }
                         }
                         l:=log2(t)+1;
                         l:=log2(t)+1;
-                        j:=qword($ffffffff) mod qword(t);
-                        k:=(qword(1) shl (32+l)) div (qword($ffffffff-j));
-                        m_low:=((qword(1)) shl (32+l)) div t;
-                        m_high:=(((qword(1)) shl (32+l)) + k) div t;
+                        j:=dword($ffff) mod dword(t);
+                        k:=(dword(1) shl (16+l)) div (dword($ffff-j));
+                        m_low:=((dword(1)) shl (16+l)) div t;
+                        m_high:=(((dword(1)) shl (16+l)) + k) div t;
                         while ((m_low shr 1) < (m_high shr 1)) and (l>0) do
                         while ((m_low shr 1) < (m_high shr 1)) and (l>0) do
                           begin
                           begin
                             m_low:=m_low shr 1;
                             m_low:=m_low shr 1;
                             m_high:=m_high shr 1;
                             m_high:=m_high shr 1;
                             l:=l-1;
                             l:=l-1;
                           end;
                           end;
-                        if (m_high shr 32)=0 then
+                        if (m_high shr 16)=0 then
                           begin
                           begin
-                            m:=dword(m_high);
+                            m:=word(m_high);
                             s:=l;
                             s:=l;
                             a:=0;
                             a:=0;
                           end
                           end
@@ -267,12 +288,12 @@ implementation
                         else
                         else
                           begin
                           begin
                             s:=log2(t);
                             s:=log2(t);
-                            m_low:=(qword(1) shl (32+s)) div qword(t);
-                            r:=dword(((qword(1)) shl (32+s)) mod qword(t));
+                            m_low:=(dword(1) shl (16+s)) div dword(t);
+                            r:=word(((dword(1)) shl (16+s)) mod dword(t));
                             if (r < ((t>>1)+1)) then
                             if (r < ((t>>1)+1)) then
-                              m:=dword(m_low)
+                              m:=word(m_low)
                             else
                             else
-                              m:=dword(m_low)+1;
+                              m:=word(m_low)+1;
                             a:=1;
                             a:=1;
                           end;
                           end;
                         { Reduce multiplier for either algorithm to smallest possible }
                         { Reduce multiplier for either algorithm to smallest possible }
@@ -283,72 +304,72 @@ implementation
                           end;
                           end;
                         { Adjust multiplier for reduction of even divisors }
                         { Adjust multiplier for reduction of even divisors }
                         inc(s,n);
                         inc(s,n);
-                        cg.getcpuregister(current_asmdata.CurrAsmList,NR_EAX);
-                        emit_const_reg(A_MOV,S_L,aint(m),NR_EAX);
-                        cg.getcpuregister(current_asmdata.CurrAsmList,NR_EDX);
-                        emit_reg(A_MUL,S_L,hreg1);
+                        cg.getcpuregister(current_asmdata.CurrAsmList,NR_AX);
+                        emit_const_reg(A_MOV,S_W,aint(m),NR_AX);
+                        cg.getcpuregister(current_asmdata.CurrAsmList,NR_DX);
+                        emit_reg(A_MUL,S_W,hreg1);
                         if a<>0 then
                         if a<>0 then
                           begin
                           begin
                             {
                             {
-                            printf ("; dividend: register other than EAX or memory location\n");
+                            printf ("; dividend: register other than AX or memory location\n");
                             printf ("\n");
                             printf ("\n");
-                            printf ("MOV EAX, 0%08lXh\n", m);
+                            printf ("MOV AX, 0%08lXh\n", m);
                             printf ("MUL dividend\n");
                             printf ("MUL dividend\n");
-                            printf ("ADD EAX, 0%08lXh\n", m);
-                            printf ("ADC EDX, 0\n");
-                            if (s) printf ("SHR EDX, %d\n", s);
+                            printf ("ADD AX, 0%08lXh\n", m);
+                            printf ("ADC DX, 0\n");
+                            if (s) printf ("SHR DX, %d\n", s);
                             printf ("\n");
                             printf ("\n");
-                            printf ("; quotient now in EDX\n");
+                            printf ("; quotient now in DX\n");
                             }
                             }
-                            emit_const_reg(A_ADD,S_L,aint(m),NR_EAX);
-                            emit_const_reg(A_ADC,S_L,0,NR_EDX);
+                            emit_const_reg(A_ADD,S_W,aint(m),NR_AX);
+                            emit_const_reg(A_ADC,S_W,0,NR_DX);
                           end;
                           end;
                         if s<>0 then
                         if s<>0 then
-                          emit_const_reg(A_SHR,S_L,aint(s),NR_EDX);
-                        cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EDX);
-                        cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EAX);
+                          cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,aint(s),NR_DX);
+                        cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_DX);
+                        cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_AX);
                         location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                         location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
-                        cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_EDX,location.register)
+                        cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_DX,location.register)
                       end;
                       end;
                   end
                   end
               end
               end
           end
           end
         else
         else
           begin
           begin
-            cg.getcpuregister(current_asmdata.CurrAsmList,NR_EAX);
-            emit_reg_reg(A_MOV,S_L,hreg1,NR_EAX);
-            cg.getcpuregister(current_asmdata.CurrAsmList,NR_EDX);
+            cg.getcpuregister(current_asmdata.CurrAsmList,NR_AX);
+            emit_reg_reg(A_MOV,S_W,hreg1,NR_AX);
+            cg.getcpuregister(current_asmdata.CurrAsmList,NR_DX);
             {Sign extension depends on the left type.}
             {Sign extension depends on the left type.}
-            if torddef(left.resultdef).ordtype=u32bit then
-              emit_reg_reg(A_XOR,S_L,NR_EDX,NR_EDX)
+            if torddef(left.resultdef).ordtype=u16bit then
+              emit_reg_reg(A_XOR,S_W,NR_DX,NR_DX)
             else
             else
-              emit_none(A_CDQ,S_NO);
+              emit_none(A_CWD,S_NO);
 
 
             {Division depends on the right type.}
             {Division depends on the right type.}
-            if Torddef(right.resultdef).ordtype=u32bit then
+            if Torddef(right.resultdef).ordtype=u16bit then
               op:=A_DIV
               op:=A_DIV
             else
             else
               op:=A_IDIV;
               op:=A_IDIV;
 
 
             if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
             if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
-              emit_ref(op,S_L,right.location.reference)
+              emit_ref(op,S_W,right.location.reference)
             else if right.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
             else if right.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
-              emit_reg(op,S_L,right.location.register)
+              emit_reg(op,S_W,right.location.register)
             else
             else
               begin
               begin
                 hreg1:=cg.getintregister(current_asmdata.CurrAsmList,right.location.size);
                 hreg1:=cg.getintregister(current_asmdata.CurrAsmList,right.location.size);
-                hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,right.resultdef,u32inttype,right.location,hreg1);
-                emit_reg(op,S_L,hreg1);
+                hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,right.resultdef,u16inttype,right.location,hreg1);
+                emit_reg(op,S_W,hreg1);
               end;
               end;
 
 
-            {Copy the result into a new register. Release EAX & EDX.}
-            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EDX);
-            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_EAX);
+            {Copy the result into a new register. Release AX & DX.}
+            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_DX);
+            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_AX);
             location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
             location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
             if nodetype=divn then
             if nodetype=divn then
-              cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_EAX,location.register)
+              cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_AX,location.register)
             else
             else
-              cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_EDX,location.register);
+              cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,NR_DX,location.register);
           end;
           end;
       end;
       end;
 
 

+ 46 - 28
compiler/i8086/n8086mem.pas

@@ -28,23 +28,30 @@ interface
     uses
     uses
       globtype,
       globtype,
       cgbase,cpuinfo,cpubase,
       cgbase,cpuinfo,cpubase,
-      node,nmem,ncgmem,nx86mem;
+      node,nmem,ncgmem,nx86mem,ni86mem;
 
 
     type
     type
-       ti8086addrnode = class(tcgaddrnode)
-         procedure pass_generate_code;override;
+       ti8086addrnode = class(ti86addrnode)
+        protected
+         procedure set_absvarsym_resultdef; override;
+         function typecheck_non_proc(realsource: tnode; out res: tnode): boolean; override;
        end;
        end;
 
 
        ti8086derefnode = class(tx86derefnode)
        ti8086derefnode = class(tx86derefnode)
          procedure pass_generate_code;override;
          procedure pass_generate_code;override;
        end;
        end;
 
 
+       { tx86vecnode doesn't work for i8086, so we inherit tcgvecnode }
+       ti8086vecnode = class(tcgvecnode)
+         procedure update_reference_reg_mul(maybe_const_reg:tregister;l:aint);override;
+       end;
+
 implementation
 implementation
 
 
     uses
     uses
       systems,globals,
       systems,globals,
       cutils,verbose,
       cutils,verbose,
-      symbase,symconst,symdef,symtable,symtype,symsym,
+      symbase,symconst,symdef,symtable,symtype,symsym,symcpu,
       parabase,paramgr,
       parabase,paramgr,
       aasmtai,aasmdata,
       aasmtai,aasmdata,
       nld,ncon,nadd,
       nld,ncon,nadd,
@@ -56,34 +63,31 @@ implementation
                              TI8086ADDRNODE
                              TI8086ADDRNODE
 *****************************************************************************}
 *****************************************************************************}
 
 
-    procedure ti8086addrnode.pass_generate_code;
-      var
-        segref: treference;
+    procedure ti8086addrnode.set_absvarsym_resultdef;
       begin
       begin
-        if (current_settings.x86memorymodel in x86_far_code_models) and
-           (left.nodetype=loadn) and
-           (tloadnode(left).symtableentry.typ=labelsym) then
-          begin
-            secondpass(left);
-
-            location_reset(location,LOC_REGISTER,OS_32);
-            location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-            if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
-              internalerror(2013091801);
+        if not(nf_typedaddr in flags) then
+          resultdef:=voidfarpointertype
+        else
+          resultdef:=tcpupointerdefclass(cpointerdef).createx86(left.resultdef,x86pt_far);
+      end;
 
 
-            { load offset }
-            cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,location.register);
 
 
-            { load segment }
-            segref:=left.location.reference;
-            segref.refaddr:=addr_seg;
-            cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,GetNextReg(location.register));
+    function ti8086addrnode.typecheck_non_proc(realsource: tnode; out res: tnode): boolean;
+      begin
+        res:=nil;
+        if (realsource.nodetype=loadn) and
+           (tloadnode(realsource).symtableentry.typ=labelsym) then
+          begin
+            if current_settings.x86memorymodel in x86_far_code_models then
+              resultdef:=voidfarpointertype
+            else
+              resultdef:=voidnearpointertype;
+            result:=true
           end
           end
         else
         else
-          inherited;
+          result:=inherited;
       end;
       end;
 
 
-
 {*****************************************************************************
 {*****************************************************************************
                              TI8086DEREFNODE
                              TI8086DEREFNODE
 *****************************************************************************}
 *****************************************************************************}
@@ -96,7 +100,7 @@ implementation
         st : tsymtable;
         st : tsymtable;
         tmpref: treference;
         tmpref: treference;
       begin
       begin
-        if tpointerdef(left.resultdef).x86pointertyp in [x86pt_far,x86pt_huge] then
+        if tcpupointerdef(left.resultdef).x86pointertyp in [x86pt_far,x86pt_huge] then
           begin
           begin
             secondpass(left);
             secondpass(left);
             { assume natural alignment, except for packed records }
             { assume natural alignment, except for packed records }
@@ -111,7 +115,7 @@ implementation
                LOC_CREGISTER,
                LOC_CREGISTER,
                LOC_REGISTER:
                LOC_REGISTER:
                  begin
                  begin
-                   maybechangeloadnodereg(current_asmdata.CurrAsmList,left,true);
+                   hlcg.maybe_change_load_node_reg(current_asmdata.CurrAsmList,left,true);
                    location.reference.base := left.location.register;
                    location.reference.base := left.location.register;
                    location.reference.segment := GetNextReg(left.location.register);
                    location.reference.segment := GetNextReg(left.location.register);
                  end;
                  end;
@@ -138,7 +142,7 @@ implementation
                (cs_checkpointer in current_settings.localswitches) and
                (cs_checkpointer in current_settings.localswitches) and
                not(cs_compilesystem in current_settings.moduleswitches) and
                not(cs_compilesystem in current_settings.moduleswitches) and
    {$ifdef x86}
    {$ifdef x86}
-               (tpointerdef(left.resultdef).x86pointertyp = default_x86_data_pointer_type) and
+               (tcpupointerdef(left.resultdef).x86pointertyp = tcpupointerdefclass(cpointerdef).default_x86_data_pointer_type) and
    {$endif x86}
    {$endif x86}
                not(nf_no_checkpointer in flags) and
                not(nf_no_checkpointer in flags) and
                { can be NR_NO in case of LOC_CONSTANT }
                { can be NR_NO in case of LOC_CONSTANT }
@@ -162,8 +166,22 @@ implementation
           inherited pass_generate_code;
           inherited pass_generate_code;
       end;
       end;
 
 
+{*****************************************************************************
+                             TI8086VECNODE
+*****************************************************************************}
+
+    procedure ti8086vecnode.update_reference_reg_mul(maybe_const_reg:tregister;l:aint);
+      var
+        saveseg: TRegister;
+      begin
+        saveseg:=location.reference.segment;
+        location.reference.segment:=NR_NO;
+        inherited update_reference_reg_mul(maybe_const_reg,l);
+        location.reference.segment:=saveseg;
+      end;
 
 
 begin
 begin
   caddrnode:=ti8086addrnode;
   caddrnode:=ti8086addrnode;
   cderefnode:=ti8086derefnode;
   cderefnode:=ti8086derefnode;
+  cvecnode:=ti8086vecnode;
 end.
 end.

+ 77 - 0
compiler/i8086/n8086tcon.pas

@@ -0,0 +1,77 @@
+{
+    Copyright (c) 1998-2011 by Florian Klaempfl, Jonas Maebe
+
+    Generates i8086 assembler for typed constant declarations
+
+    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 n8086tcon;
+
+{$i fpcdefs.inc}
+
+interface
+
+    uses
+      node,symdef,ngtcon;
+
+
+    type
+
+      { ti8086typedconstbuilder }
+
+      ti8086typedconstbuilder = class(tasmlisttypedconstbuilder)
+       protected
+        procedure tc_emit_pointerdef(def: tpointerdef; var node: tnode);override;
+      end;
+
+
+implementation
+
+uses
+  ncnv,defcmp,defutil,aasmtai;
+
+    { ti8086typedconstbuilder }
+
+    procedure ti8086typedconstbuilder.tc_emit_pointerdef(def: tpointerdef; var node: tnode);
+      var
+        hp: tnode;
+      begin
+        { remove equal typecasts for pointer/nil addresses }
+        if (node.nodetype=typeconvn) then
+          with Ttypeconvnode(node) do
+            if (left.nodetype in [addrn,niln]) and equal_defs(def,node.resultdef) then
+              begin
+                hp:=left;
+                left:=nil;
+                node.free;
+                node:=hp;
+              end;
+        if node.nodetype=niln then
+          begin
+            if is_farpointer(def) or is_hugepointer(def) then
+              list.concat(Tai_const.Create_32bit(0))
+            else
+              list.concat(Tai_const.Create_16bit(0));
+          end
+        else
+          inherited tc_emit_pointerdef(def, node);
+      end;
+
+begin
+  ctypedconstbuilder:=ti8086typedconstbuilder;
+end.
+

+ 127 - 0
compiler/i8086/n8086util.pas

@@ -0,0 +1,127 @@
+{
+    Copyright (c) 2014 by Nikolay Nikolov
+
+    i8086 version of some node tree helper routines
+
+    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 n8086util;
+
+{$i fpcdefs.inc}
+
+interface
+
+  uses
+    ngenutil;
+
+
+  type
+    ti8086nodeutils = class(tnodeutils)
+      class procedure InsertMemorySizes; override;
+      class procedure InsertStackSegment;
+      class procedure InsertHeapSegment;
+      class procedure InsertStackPlusHeapSize;
+    end;
+
+
+implementation
+
+  uses
+    sysutils,cutils,
+    globtype,globals,cpuinfo,
+    aasmbase,aasmdata,aasmtai;
+
+
+  class procedure ti8086nodeutils.InsertMemorySizes;
+    begin
+      inherited;
+      if current_settings.x86memorymodel<>mm_tiny then
+        InsertStackSegment;
+      InsertHeapSegment;
+      if current_settings.x86memorymodel in x86_near_data_models then
+        InsertStackPlusHeapSize;
+    end;
+
+
+  class procedure ti8086nodeutils.InsertStackSegment;
+    var
+      stacksizeleft,stackblock: LongInt;
+      i: Integer;
+    begin
+      maybe_new_object_file(current_asmdata.asmlists[al_globals]);
+      new_section(current_asmdata.asmlists[al_globals],sec_stack,'__stack', 16);
+      current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___stack', AT_DATA, stacksize));
+      { HACK: since tai_datablock's size parameter is aint, which cannot be
+        larger than 32767 on i8086, but we'd like to support stack size of
+        up to 64kb, we may need to use several tai_datablocks to reserve
+        the stack segment }
+      i:=0;
+      stacksizeleft:=stacksize;
+      while stacksizeleft>0 do
+        begin
+          stackblock:=min(stacksizeleft,high(aint));
+          current_asmdata.asmlists[al_globals].concat(tai_datablock.Create('___stackblock'+IntToStr(i),stackblock));
+          dec(stacksizeleft,stackblock);
+          inc(i);
+        end;
+      current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___stacktop',AT_DATA,0));
+    end;
+
+
+  class procedure ti8086nodeutils.InsertHeapSegment;
+    var
+      heapsizeleft,heapblock: LongInt;
+      i: Integer;
+    begin
+      maybe_new_object_file(current_asmdata.asmlists[al_globals]);
+      new_section(current_asmdata.asmlists[al_globals],sec_heap,'__heap', 16);
+      current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___heap', AT_DATA, heapsize));
+      { HACK: since tai_datablock's size parameter is aint, which cannot be
+        larger than 32767 on i8086, but we'd like to support heap size of
+        up to 640kb, we may need to use several tai_datablocks to reserve
+        the heap segment }
+      i:=0;
+      heapsizeleft:=heapsize;
+      while heapsizeleft>0 do
+        begin
+          heapblock:=min(heapsizeleft,high(aint));
+          current_asmdata.asmlists[al_globals].concat(tai_datablock.Create('___heapblock'+IntToStr(i),heapblock));
+          dec(heapsizeleft,heapblock);
+          inc(i);
+        end;
+      current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___heaptop',AT_DATA,0));
+    end;
+
+
+  class procedure ti8086nodeutils.InsertStackPlusHeapSize;
+    var
+      maxheapsize_para: Word;
+      stacksize_para: Word;
+    begin
+      maxheapsize_para:=(maxheapsize+15) div 16;
+      stacksize_para:=(stacksize+15) div 16;
+
+      maybe_new_object_file(current_asmdata.asmlists[al_globals]);
+      new_section(current_asmdata.asmlists[al_globals],sec_data,'__fpc_stackplusmaxheap_in_para',sizeof(pint));
+      current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__fpc_stackplusmaxheap_in_para',AT_DATA,4));
+      current_asmdata.asmlists[al_globals].concat(Tai_const.Create_16bit(min($1000,stacksize_para+maxheapsize_para)));
+    end;
+
+
+begin
+  cnodeutils:=ti8086nodeutils;
+end.

+ 8 - 8
compiler/i8086/r8086ari.inc

@@ -8,22 +8,22 @@
 15,
 15,
 6,
 6,
 5,
 5,
-38,
 39,
 39,
 40,
 40,
 41,
 41,
+42,
 26,
 26,
 7,
 7,
 10,
 10,
 19,
 19,
 9,
 9,
-32,
 33,
 33,
 34,
 34,
 35,
 35,
 36,
 36,
 37,
 37,
-27,
+38,
+28,
 11,
 11,
 4,
 4,
 22,
 22,
@@ -31,13 +31,13 @@
 8,
 8,
 20,
 20,
 12,
 12,
+32,
 25,
 25,
-28,
 18,
 18,
 24,
 24,
-47,
-30,
 31,
 31,
+29,
+30,
 57,
 57,
 58,
 58,
 59,
 59,
@@ -48,7 +48,7 @@
 64,
 64,
 17,
 17,
 23,
 23,
-29,
+27,
 56,
 56,
 48,
 48,
 49,
 49,
@@ -58,11 +58,11 @@
 53,
 53,
 54,
 54,
 55,
 55,
-42,
 43,
 43,
 44,
 44,
 45,
 45,
 46,
 46,
+47,
 65,
 65,
 66,
 66,
 67,
 67,

+ 4 - 4
compiler/i8086/r8086att.inc

@@ -24,13 +24,14 @@
 '%ebp',
 '%ebp',
 '%sp',
 '%sp',
 '%esp',
 '%esp',
-'%eip',
-'%cs',
-'%ds',
 '%es',
 '%es',
+'%cs',
 '%ss',
 '%ss',
+'%ds',
 '%fs',
 '%fs',
 '%gs',
 '%gs',
+'%flags',
+'%eip',
 '%dr0',
 '%dr0',
 '%dr1',
 '%dr1',
 '%dr2',
 '%dr2',
@@ -46,7 +47,6 @@
 '%tr5',
 '%tr5',
 '%tr6',
 '%tr6',
 '%tr7',
 '%tr7',
-'%flags',
 '%st(0)',
 '%st(0)',
 '%st(1)',
 '%st(1)',
 '%st(2)',
 '%st(2)',

+ 22 - 22
compiler/i8086/r8086con.inc

@@ -24,29 +24,29 @@ NR_BP = tregister($01030006);
 NR_EBP = tregister($01040006);
 NR_EBP = tregister($01040006);
 NR_SP = tregister($01030007);
 NR_SP = tregister($01030007);
 NR_ESP = tregister($01040007);
 NR_ESP = tregister($01040007);
-NR_EIP = tregister($05040000);
+NR_ES = tregister($05000000);
 NR_CS = tregister($05000001);
 NR_CS = tregister($05000001);
-NR_DS = tregister($05000002);
-NR_ES = tregister($05000003);
-NR_SS = tregister($05000004);
-NR_FS = tregister($05000005);
-NR_GS = tregister($05000006);
-NR_DR0 = tregister($05000007);
-NR_DR1 = tregister($05000008);
-NR_DR2 = tregister($05000009);
-NR_DR3 = tregister($0500000a);
-NR_DR6 = tregister($0500000b);
-NR_DR7 = tregister($0500000c);
-NR_CR0 = tregister($0500000d);
-NR_CR2 = tregister($0500000e);
-NR_CR3 = tregister($0500000f);
-NR_CR4 = tregister($05000010);
-NR_TR3 = tregister($05000011);
-NR_TR4 = tregister($05000012);
-NR_TR5 = tregister($05000013);
-NR_TR6 = tregister($05000014);
-NR_TR7 = tregister($05000015);
-NR_FLAGS = tregister($05000016);
+NR_SS = tregister($05000002);
+NR_DS = tregister($05000003);
+NR_FS = tregister($05000004);
+NR_GS = tregister($05000005);
+NR_FLAGS = tregister($05000006);
+NR_EIP = tregister($05040007);
+NR_DR0 = tregister($05000008);
+NR_DR1 = tregister($05000009);
+NR_DR2 = tregister($0500000a);
+NR_DR3 = tregister($0500000b);
+NR_DR6 = tregister($0500000d);
+NR_DR7 = tregister($0500000e);
+NR_CR0 = tregister($05000010);
+NR_CR2 = tregister($05000012);
+NR_CR3 = tregister($05000013);
+NR_CR4 = tregister($05000014);
+NR_TR3 = tregister($0500001b);
+NR_TR4 = tregister($0500001c);
+NR_TR5 = tregister($0500001d);
+NR_TR6 = tregister($0500001e);
+NR_TR7 = tregister($0500001f);
 NR_ST0 = tregister($02000000);
 NR_ST0 = tregister($02000000);
 NR_ST1 = tregister($02000001);
 NR_ST1 = tregister($02000001);
 NR_ST2 = tregister($02000002);
 NR_ST2 = tregister($02000002);

+ 1 - 1
compiler/i8086/r8086dwrf.inc

@@ -24,7 +24,6 @@
 5,
 5,
 4,
 4,
 4,
 4,
-8,
 -1,
 -1,
 -1,
 -1,
 -1,
 -1,
@@ -32,6 +31,7 @@
 -1,
 -1,
 -1,
 -1,
 -1,
 -1,
+8,
 -1,
 -1,
 -1,
 -1,
 -1,
 -1,

+ 4 - 4
compiler/i8086/r8086int.inc

@@ -24,13 +24,14 @@
 'ebp',
 'ebp',
 'sp',
 'sp',
 'esp',
 'esp',
-'eip',
-'cs',
-'ds',
 'es',
 'es',
+'cs',
 'ss',
 'ss',
+'ds',
 'fs',
 'fs',
 'gs',
 'gs',
+'flags',
+'eip',
 'dr0',
 'dr0',
 'dr1',
 'dr1',
 'dr2',
 'dr2',
@@ -46,7 +47,6 @@
 'tr5',
 'tr5',
 'tr6',
 'tr6',
 'tr7',
 'tr7',
-'flags',
 'st(0)',
 'st(0)',
 'st(1)',
 'st(1)',
 'st(2)',
 'st(2)',

+ 8 - 8
compiler/i8086/r8086iri.inc

@@ -9,22 +9,22 @@
 15,
 15,
 6,
 6,
 5,
 5,
-38,
 39,
 39,
 40,
 40,
 41,
 41,
+42,
 26,
 26,
 7,
 7,
 10,
 10,
 19,
 19,
 9,
 9,
-32,
 33,
 33,
 34,
 34,
 35,
 35,
 36,
 36,
 37,
 37,
-27,
+38,
+28,
 11,
 11,
 4,
 4,
 22,
 22,
@@ -32,13 +32,13 @@
 8,
 8,
 20,
 20,
 12,
 12,
+32,
 25,
 25,
-28,
 18,
 18,
 24,
 24,
-47,
-30,
 31,
 31,
+29,
+30,
 57,
 57,
 58,
 58,
 59,
 59,
@@ -49,7 +49,7 @@
 64,
 64,
 17,
 17,
 23,
 23,
-29,
+27,
 56,
 56,
 48,
 48,
 49,
 49,
@@ -59,11 +59,11 @@
 53,
 53,
 54,
 54,
 55,
 55,
-42,
 43,
 43,
 44,
 44,
 45,
 45,
 46,
 46,
+47,
 65,
 65,
 66,
 66,
 67,
 67,

+ 4 - 4
compiler/i8086/r8086nasm.inc

@@ -24,13 +24,14 @@
 'ebp',
 'ebp',
 'sp',
 'sp',
 'esp',
 'esp',
-'eip',
-'cs',
-'ds',
 'es',
 'es',
+'cs',
 'ss',
 'ss',
+'ds',
 'fs',
 'fs',
 'gs',
 'gs',
+'flags',
+'eip',
 'dr0',
 'dr0',
 'dr1',
 'dr1',
 'dr2',
 'dr2',
@@ -46,7 +47,6 @@
 'tr5',
 'tr5',
 'tr6',
 'tr6',
 'tr7',
 'tr7',
-'flags',
 'st0',
 'st0',
 'st1',
 'st1',
 'st2',
 'st2',

+ 8 - 8
compiler/i8086/r8086nri.inc

@@ -9,22 +9,22 @@
 15,
 15,
 6,
 6,
 5,
 5,
-38,
 39,
 39,
 40,
 40,
 41,
 41,
+42,
 26,
 26,
 7,
 7,
 10,
 10,
 19,
 19,
 9,
 9,
-32,
 33,
 33,
 34,
 34,
 35,
 35,
 36,
 36,
 37,
 37,
-27,
+38,
+28,
 11,
 11,
 4,
 4,
 22,
 22,
@@ -32,13 +32,13 @@
 8,
 8,
 20,
 20,
 12,
 12,
+32,
 25,
 25,
-28,
 18,
 18,
 24,
 24,
-47,
-30,
 31,
 31,
+29,
+30,
 57,
 57,
 58,
 58,
 59,
 59,
@@ -49,7 +49,7 @@
 64,
 64,
 17,
 17,
 23,
 23,
-29,
+27,
 56,
 56,
 48,
 48,
 49,
 49,
@@ -59,11 +59,11 @@
 53,
 53,
 54,
 54,
 55,
 55,
-42,
 43,
 43,
 44,
 44,
 45,
 45,
 46,
 46,
+47,
 65,
 65,
 66,
 66,
 67,
 67,

+ 7 - 7
compiler/i8086/r8086num.inc

@@ -24,29 +24,29 @@ tregister($01030006),
 tregister($01040006),
 tregister($01040006),
 tregister($01030007),
 tregister($01030007),
 tregister($01040007),
 tregister($01040007),
-tregister($05040000),
+tregister($05000000),
 tregister($05000001),
 tregister($05000001),
 tregister($05000002),
 tregister($05000002),
 tregister($05000003),
 tregister($05000003),
 tregister($05000004),
 tregister($05000004),
 tregister($05000005),
 tregister($05000005),
 tregister($05000006),
 tregister($05000006),
-tregister($05000007),
+tregister($05040007),
 tregister($05000008),
 tregister($05000008),
 tregister($05000009),
 tregister($05000009),
 tregister($0500000a),
 tregister($0500000a),
 tregister($0500000b),
 tregister($0500000b),
-tregister($0500000c),
 tregister($0500000d),
 tregister($0500000d),
 tregister($0500000e),
 tregister($0500000e),
-tregister($0500000f),
 tregister($05000010),
 tregister($05000010),
-tregister($05000011),
 tregister($05000012),
 tregister($05000012),
 tregister($05000013),
 tregister($05000013),
 tregister($05000014),
 tregister($05000014),
-tregister($05000015),
-tregister($05000016),
+tregister($0500001b),
+tregister($0500001c),
+tregister($0500001d),
+tregister($0500001e),
+tregister($0500001f),
 tregister($02000000),
 tregister($02000000),
 tregister($02000001),
 tregister($02000001),
 tregister($02000002),
 tregister($02000002),

+ 0 - 82
compiler/i8086/r8086op.inc

@@ -1,82 +0,0 @@
-{ don't edit, this file is generated from x86reg.dat }
-0,
-0,
-4,
-0,
-0,
-1,
-5,
-1,
-1,
-2,
-6,
-2,
-2,
-3,
-7,
-3,
-3,
-6,
-6,
-7,
-7,
-5,
-5,
-4,
-4,
-0,
-1,
-3,
-0,
-2,
-4,
-5,
-0,
-1,
-2,
-3,
-6,
-7,
-0,
-2,
-3,
-4,
-3,
-4,
-5,
-6,
-7,
-0,
-0,
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-0,
-0,
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-0,
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-0,
-1,
-2,
-3,
-4,
-5,
-6,
-7

+ 3 - 3
compiler/i8086/r8086ot.inc

@@ -24,13 +24,14 @@ OT_REG16,
 OT_REG32,
 OT_REG32,
 OT_REG16,
 OT_REG16,
 OT_REG32,
 OT_REG32,
-OT_NONE,
-OT_REG_CS,
 OT_REG_DESS,
 OT_REG_DESS,
+OT_REG_CS,
 OT_REG_DESS,
 OT_REG_DESS,
 OT_REG_DESS,
 OT_REG_DESS,
 OT_REG_FSGS,
 OT_REG_FSGS,
 OT_REG_FSGS,
 OT_REG_FSGS,
+OT_NONE,
+OT_NONE,
 OT_REG_DREG,
 OT_REG_DREG,
 OT_REG_DREG,
 OT_REG_DREG,
 OT_REG_DREG,
 OT_REG_DREG,
@@ -46,7 +47,6 @@ OT_REG_TREG,
 OT_REG_TREG,
 OT_REG_TREG,
 OT_REG_TREG,
 OT_REG_TREG,
 OT_REG_TREG,
 OT_REG_TREG,
-OT_NONE,
 OT_FPU0,
 OT_FPU0,
 OT_FPUREG,
 OT_FPUREG,
 OT_FPUREG,
 OT_FPUREG,

+ 2 - 2
compiler/i8086/r8086rni.inc

@@ -57,13 +57,13 @@
 78,
 78,
 79,
 79,
 80,
 80,
+25,
 26,
 26,
 27,
 27,
 28,
 28,
 29,
 29,
 30,
 30,
 31,
 31,
-32,
 33,
 33,
 34,
 34,
 35,
 35,
@@ -79,4 +79,4 @@
 45,
 45,
 46,
 46,
 47,
 47,
-25
+32

+ 8 - 8
compiler/i8086/r8086sri.inc

@@ -9,22 +9,22 @@
 15,
 15,
 6,
 6,
 5,
 5,
-38,
 39,
 39,
 40,
 40,
 41,
 41,
+42,
 26,
 26,
 7,
 7,
 10,
 10,
 19,
 19,
 9,
 9,
-32,
 33,
 33,
 34,
 34,
 35,
 35,
 36,
 36,
 37,
 37,
-27,
+38,
+28,
 11,
 11,
 4,
 4,
 22,
 22,
@@ -32,13 +32,13 @@
 8,
 8,
 20,
 20,
 12,
 12,
+32,
 25,
 25,
-28,
 18,
 18,
 24,
 24,
-47,
-30,
 31,
 31,
+29,
+30,
 57,
 57,
 58,
 58,
 59,
 59,
@@ -49,7 +49,7 @@
 64,
 64,
 17,
 17,
 23,
 23,
-29,
+27,
 56,
 56,
 48,
 48,
 49,
 49,
@@ -59,11 +59,11 @@
 53,
 53,
 54,
 54,
 55,
 55,
-42,
 43,
 43,
 44,
 44,
 45,
 45,
 46,
 46,
+47,
 65,
 65,
 66,
 66,
 67,
 67,

+ 4 - 4
compiler/i8086/r8086std.inc

@@ -24,13 +24,14 @@
 'ebp',
 'ebp',
 'sp',
 'sp',
 'esp',
 'esp',
-'eip',
-'cs',
-'ds',
 'es',
 'es',
+'cs',
 'ss',
 'ss',
+'ds',
 'fs',
 'fs',
 'gs',
 'gs',
+'flags',
+'eip',
 'dr0',
 'dr0',
 'dr1',
 'dr1',
 'dr2',
 'dr2',
@@ -46,7 +47,6 @@
 'tr5',
 'tr5',
 'tr6',
 'tr6',
 'tr7',
 'tr7',
-'flags',
 'st(0)',
 'st(0)',
 'st(1)',
 'st(1)',
 'st(2)',
 'st(2)',

+ 18 - 5
compiler/i8086/rgcpu.pas

@@ -30,11 +30,15 @@ unit rgcpu;
     uses
     uses
       cpubase,
       cpubase,
       cpuinfo,
       cpuinfo,
-      aasmbase,aasmtai,aasmdata,
-      cclasses,globtype,cgbase,rgobj,rgx86;
+      aasmbase,aasmtai,aasmdata,aasmcpu,
+      cclasses,globtype,cgbase,cgutils,rgobj,rgx86;
 
 
     type
     type
+
+       { trgcpu }
+
        trgcpu = class(trgx86)
        trgcpu = class(trgx86)
+          function  do_spill_replace(list:TAsmList;instr:taicpu;orgreg:tsuperregister;const spilltemp:treference):boolean;override;
           procedure add_constraints(reg:Tregister);override;
           procedure add_constraints(reg:Tregister);override;
        end;
        end;
 
 
@@ -47,9 +51,7 @@ implementation
 
 
     uses
     uses
       systems,
       systems,
-      verbose,
-      aasmcpu,
-      cgutils;
+      verbose;
 
 
     const
     const
        { This value is used in tsaved. If the array value is equal
        { This value is used in tsaved. If the array value is equal
@@ -60,6 +62,17 @@ implementation
                                  trgcpu
                                  trgcpu
 *************************************************************************}
 *************************************************************************}
 
 
+    function trgcpu.do_spill_replace(list: TAsmList; instr: taicpu; orgreg: tsuperregister; const spilltemp: treference): boolean;
+      var
+        spilltemp2: treference;
+      begin
+        spilltemp2:=spilltemp;
+        if spilltemp2.segment=NR_SS then
+          spilltemp2.segment:=NR_NO;
+        Result:=inherited do_spill_replace(list, instr, orgreg, spilltemp2);
+      end;
+
+
     procedure trgcpu.add_constraints(reg:Tregister);
     procedure trgcpu.add_constraints(reg:Tregister);
       var
       var
         supreg : tsuperregister;
         supreg : tsuperregister;

+ 458 - 0
compiler/i8086/symcpu.pas

@@ -0,0 +1,458 @@
+{
+    Copyright (c) 2014 by Florian Klaempfl
+
+    Symbol table overrides for i8086
+
+    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 symcpu;
+
+{$i fpcdefs.inc}
+
+interface
+
+uses
+  globtype,
+  symconst,symtype,symdef,symsym,symx86,symi86;
+
+type
+  { defs }
+  tcpufiledef = class(tfiledef)
+  end;
+  tcpufiledefclass = class of tcpufiledef;
+
+  tcpuvariantdef = class(tvariantdef)
+  end;
+  tcpuvariantdefclass = class of tcpuvariantdef;
+
+  tcpuformaldef = class(tformaldef)
+  end;
+  tcpuformaldefclass = class of tcpuformaldef;
+
+  tcpuforwarddef = class(tforwarddef)
+  end;
+  tcpuforwarddefclass = class of tcpuforwarddef;
+
+  tcpuundefineddef = class(tundefineddef)
+  end;
+  tcpuundefineddefclass = class of tcpuundefineddef;
+
+  tcpuerrordef = class(terrordef)
+  end;
+  tcpuerrordefclass = class of tcpuerrordef;
+
+  tcpupointerdef = class(tx86pointerdef)
+    class function default_x86_data_pointer_type: tx86pointertyp; override;
+    function pointer_arithmetic_int_type:tdef; override;
+    function pointer_subtraction_result_type:tdef; override;
+  end;
+  tcpupointerdefclass = class of tcpupointerdef;
+
+  tcpurecorddef = class(trecorddef)
+  end;
+  tcpurecorddefclass = class of tcpurecorddef;
+
+  tcpuimplementedinterface = class(timplementedinterface)
+  end;
+  tcpuimplementedinterfaceclass = class of tcpuimplementedinterface;
+
+  tcpuobjectdef = class(tobjectdef)
+  end;
+  tcpuobjectdefclass = class of tcpuobjectdef;
+
+  tcpuclassrefdef = class(tclassrefdef)
+  end;
+  tcpuclassrefdefclass = class of tcpuclassrefdef;
+
+  { tcpuarraydef }
+
+  tcpuarraydef = class(tarraydef)
+   private
+    huge: Boolean;
+   protected
+    procedure ppuload_platform(ppufile: tcompilerppufile); override;
+    procedure ppuwrite_platform(ppufile: tcompilerppufile); override;
+   public
+    constructor create_from_pointer(def:tpointerdef);override;
+    function getcopy: tstoreddef; override;
+    function GetTypeName:string;override;
+    property is_huge: Boolean read huge write huge;
+  end;
+  tcpuarraydefclass = class of tcpuarraydef;
+
+  tcpuorddef = class(torddef)
+  end;
+  tcpuorddefclass = class of tcpuorddef;
+
+  tcpufloatdef = class(tfloatdef)
+  end;
+  tcpufloatdefclass = class of tcpufloatdef;
+
+  { tcpuprocvardef }
+
+  tcpuprocvardef = class(ti86procvardef)
+    constructor create(level:byte);override;
+    function is_far:boolean;
+  end;
+  tcpuprocvardefclass = class of tcpuprocvardef;
+
+  { tcpuprocdef }
+
+  tcpuprocdef = class(ti86procdef)
+   private
+    { returns whether the function is far by default, i.e. whether it would be
+      far if _all_ of the following conditions are true:
+      - we're in a far code memory model
+      - it has no 'near' or 'far' specifiers
+      - it is compiled in a $F- state }
+    function default_far:boolean;
+   public
+    constructor create(level:byte);override;
+    function address_type:tdef;override;
+    procedure declared_far;override;
+    procedure declared_near;override;
+    function is_far:boolean;
+  end;
+  tcpuprocdefclass = class of tcpuprocdef;
+
+  tcpustringdef = class(tstringdef)
+  end;
+  tcpustringdefclass = class of tcpustringdef;
+
+  tcpuenumdef = class(tenumdef)
+  end;
+  tcpuenumdefclass = class of tcpuenumdef;
+
+  tcpusetdef = class(tsetdef)
+  end;
+  tcpusetdefclass = class of tcpusetdef;
+
+  { syms }
+  tcpulabelsym = class(tlabelsym)
+  end;
+  tcpulabelsymclass = class of tcpulabelsym;
+
+  tcpuunitsym = class(tunitsym)
+  end;
+  tcpuunitsymclass = class of tcpuunitsym;
+
+  tcpunamespacesym = class(tnamespacesym)
+  end;
+  tcpunamespacesymclass = class of tcpunamespacesym;
+
+  tcpuprocsym = class(tprocsym)
+  end;
+  tcpuprocsymclass = class of tcpuprocsym;
+
+  tcputypesym = class(ttypesym)
+  end;
+  tcpuypesymclass = class of tcputypesym;
+
+  tcpufieldvarsym = class(tfieldvarsym)
+  end;
+  tcpufieldvarsymclass = class of tcpufieldvarsym;
+
+  tcpulocalvarsym = class(tlocalvarsym)
+  end;
+  tcpulocalvarsymclass = class of tcpulocalvarsym;
+
+  tcpuparavarsym = class(tparavarsym)
+  end;
+  tcpuparavarsymclass = class of tcpuparavarsym;
+
+  tcpustaticvarsym = class(tstaticvarsym)
+  end;
+  tcpustaticvarsymclass = class of tcpustaticvarsym;
+
+  tcpuabsolutevarsym = class(ti86absolutevarsym)
+   protected
+    procedure ppuload_platform(ppufile: tcompilerppufile); override;
+    procedure ppuwrite_platform(ppufile: tcompilerppufile); override;
+   public
+    addrsegment : aword;
+  end;
+  tcpuabsolutevarsymclass = class of tcpuabsolutevarsym;
+
+  tcpupropertysym = class(tpropertysym)
+  end;
+  tcpupropertysymclass = class of tcpupropertysym;
+
+  tcpuconstsym = class(tconstsym)
+  end;
+  tcpuconstsymclass = class of tcpuconstsym;
+
+  tcpuenumsym = class(tenumsym)
+  end;
+  tcpuenumsymclass = class of tcpuenumsym;
+
+  tcpusyssym = class(tsyssym)
+  end;
+  tcpusyssymclass = class of tcpusyssym;
+
+
+const
+   pbestrealtype : ^tdef = @s80floattype;
+
+
+  function is_proc_far(p: tabstractprocdef): boolean;
+
+
+implementation
+
+  uses
+    globals, cpuinfo, verbose;
+
+
+  function is_proc_far(p: tabstractprocdef): boolean;
+  begin
+    if p is tcpuprocdef then
+      result:=tcpuprocdef(p).is_far
+    else if p is tcpuprocvardef then
+      result:=tcpuprocvardef(p).is_far
+    else
+      internalerror(2014041301);
+  end;
+
+
+{****************************************************************************
+                               tcpuarraydef
+****************************************************************************}
+
+  constructor tcpuarraydef.create_from_pointer(def: tpointerdef);
+    begin
+      if tcpupointerdef(def).x86pointertyp=x86pt_huge then
+        begin
+          huge:=true;
+          { use -1 so that the elecount will not overflow }
+          self.create(0,high(asizeint)-1,s32inttype);
+          arrayoptions:=[ado_IsConvertedPointer];
+          setelementdef(def.pointeddef);
+        end
+      else
+        begin
+          huge:=false;
+          inherited create_from_pointer(def);
+        end;
+    end;
+
+
+  function tcpuarraydef.getcopy: tstoreddef;
+    begin
+      result:=inherited;
+      tcpuarraydef(result).huge:=huge;
+    end;
+
+
+  function tcpuarraydef.GetTypeName: string;
+    begin
+      Result:=inherited;
+      if is_huge then
+        Result:='Huge '+Result;
+    end;
+
+
+  procedure tcpuarraydef.ppuload_platform(ppufile: tcompilerppufile);
+    begin
+      inherited;
+      huge:=(ppufile.getbyte<>0);
+    end;
+
+
+  procedure tcpuarraydef.ppuwrite_platform(ppufile: tcompilerppufile);
+    begin
+      inherited;
+      ppufile.putbyte(byte(huge));
+    end;
+
+
+{****************************************************************************
+                             tcpuprocdef
+****************************************************************************}
+
+  constructor tcpuprocdef.create(level: byte);
+    begin
+      inherited create(level);
+      if (current_settings.x86memorymodel in x86_far_code_models) and
+         ((cs_huge_code in current_settings.moduleswitches) or
+          (cs_force_far_calls in current_settings.localswitches)) then
+        procoptions:=procoptions+[po_far];
+    end;
+
+
+  function tcpuprocdef.address_type: tdef;
+    begin
+      if is_far then
+        result:=voidfarpointertype
+      else
+        result:=voidnearpointertype;
+    end;
+
+
+  procedure tcpuprocdef.declared_far;
+    begin
+      if current_settings.x86memorymodel in x86_far_code_models then
+        include(procoptions,po_far)
+      else
+        inherited declared_far;
+    end;
+
+
+  procedure tcpuprocdef.declared_near;
+    begin
+      if (current_settings.x86memorymodel in x86_far_code_models) and
+         not (cs_huge_code in current_settings.moduleswitches) then
+        exclude(procoptions,po_far)
+      else
+        inherited declared_near;
+    end;
+
+
+  function tcpuprocdef.default_far: boolean;
+    begin
+      if proctypeoption in [potype_proginit,potype_unitinit,potype_unitfinalize,
+                            potype_constructor,potype_destructor,
+                            potype_class_constructor,potype_class_destructor,
+                            potype_propgetter,potype_propsetter] then
+        exit(true);
+      if (procoptions*[po_classmethod,po_virtualmethod,po_abstractmethod,
+                       po_finalmethod,po_staticmethod,po_overridingmethod,
+                       po_external,po_public,po_interrupt])<>[] then
+        exit(true);
+      if is_methodpointer then
+        exit(true);
+      result:=not (visibility in [vis_private,vis_hidden]);
+    end;
+
+
+  function tcpuprocdef.is_far: boolean;
+    begin
+      result:=(current_settings.x86memorymodel in x86_far_code_models) and
+        ((po_far in procoptions) or default_far);
+    end;
+
+{****************************************************************************
+                             tcpuprocvardef
+****************************************************************************}
+
+  constructor tcpuprocvardef.create(level: byte);
+    begin
+      inherited create(level);
+      { procvars are always far in the far code memory models }
+      if current_settings.x86memorymodel in x86_far_code_models then
+        procoptions:=procoptions+[po_far];
+    end;
+
+
+  function tcpuprocvardef.is_far: boolean;
+    begin
+      { procvars are always far in the far code memory models }
+      result:=current_settings.x86memorymodel in x86_far_code_models;
+    end;
+
+{****************************************************************************
+                             tcpupointerdef
+****************************************************************************}
+
+    class function tcpupointerdef.default_x86_data_pointer_type: tx86pointertyp;
+      begin
+        if current_settings.x86memorymodel in x86_far_data_models then
+          result:=x86pt_far
+        else
+          result:=inherited;
+      end;
+
+
+    function tcpupointerdef.pointer_arithmetic_int_type:tdef;
+      begin
+        if x86pointertyp=x86pt_huge then
+          result:=s32inttype
+        else
+          result:=inherited;
+      end;
+
+
+    function tcpupointerdef.pointer_subtraction_result_type:tdef;
+      begin
+        case x86pointertyp of
+          x86pt_huge:
+            result:=s32inttype;
+          x86pt_far:
+            result:=u16inttype;
+          else
+            result:=inherited;
+        end;
+      end;
+
+
+{****************************************************************************
+                             tcpuabsolutevarsym
+****************************************************************************}
+
+  procedure tcpuabsolutevarsym.ppuload_platform(ppufile: tcompilerppufile);
+    begin
+      inherited;
+      if absseg then
+        addrsegment:=ppufile.getaword;
+    end;
+
+
+  procedure tcpuabsolutevarsym.ppuwrite_platform(ppufile: tcompilerppufile);
+    begin
+      inherited;
+      if absseg then
+        ppufile.putaword(addrsegment);
+    end;
+
+begin
+  { used tdef classes }
+  cfiledef:=tcpufiledef;
+  cvariantdef:=tcpuvariantdef;
+  cformaldef:=tcpuformaldef;
+  cforwarddef:=tcpuforwarddef;
+  cundefineddef:=tcpuundefineddef;
+  cerrordef:=tcpuerrordef;
+  cpointerdef:=tcpupointerdef;
+  crecorddef:=tcpurecorddef;
+  cimplementedinterface:=tcpuimplementedinterface;
+  cobjectdef:=tcpuobjectdef;
+  cclassrefdef:=tcpuclassrefdef;
+  carraydef:=tcpuarraydef;
+  corddef:=tcpuorddef;
+  cfloatdef:=tcpufloatdef;
+  cprocvardef:=tcpuprocvardef;
+  cprocdef:=tcpuprocdef;
+  cstringdef:=tcpustringdef;
+  cenumdef:=tcpuenumdef;
+  csetdef:=tcpusetdef;
+
+  { used tsym classes }
+  clabelsym:=tcpulabelsym;
+  cunitsym:=tcpuunitsym;
+  cnamespacesym:=tcpunamespacesym;
+  cprocsym:=tcpuprocsym;
+  ctypesym:=tcputypesym;
+  cfieldvarsym:=tcpufieldvarsym;
+  clocalvarsym:=tcpulocalvarsym;
+  cparavarsym:=tcpuparavarsym;
+  cstaticvarsym:=tcpustaticvarsym;
+  cabsolutevarsym:=tcpuabsolutevarsym;
+  cpropertysym:=tcpupropertysym;
+  cconstsym:=tcpuconstsym;
+  cenumsym:=tcpuenumsym;
+  csyssym:=tcpusyssym;
+end.
+

+ 58 - 0
compiler/i8086/tgcpu.pas

@@ -0,0 +1,58 @@
+{
+    Copyright (C) 1998-2000 by Florian Klaempfl
+
+    This unit handles the temporary variables stuff for i8086
+
+    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.
+
+ ****************************************************************************
+}
+{
+  This unit handles the temporary variables stuff for i8086.
+}
+unit tgcpu;
+
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+      tgobj,globtype,aasmdata,cgutils,symtype;
+
+    type
+
+      { ttgi8086 }
+
+      ttgi8086 = class(ttgobj)
+      protected
+        procedure alloctemp(list: TAsmList; size,alignment : longint; temptype : ttemptype; def:tdef; out ref: treference);override;
+      end;
+
+implementation
+
+uses
+  cpubase;
+
+{ ttgi8086 }
+
+procedure ttgi8086.alloctemp(list: TAsmList; size, alignment: longint; temptype: ttemptype; def: tdef; out ref: treference);
+  begin
+    inherited;
+    ref.segment:=NR_SS;
+  end;
+
+begin
+  tgobjclass:=ttgi8086;
+end.

Some files were not shown because too many files changed in this diff