Browse Source

* synchronized cpubase between powerpc and i386
* moved more tables from cpubase to cpuasm
* tai_align_abstract moved to tainst, cpuasm must define
the tai_align class now, which may be empty

peter 23 years ago
parent
commit
f6b3e2e37f

+ 11 - 70
compiler/aasm.pas

@@ -24,8 +24,8 @@
   This unit implements an abstract assembler output class for all processors, these
   are then overriden for each assembler writer to actually write the data in these
   classes to an assembler file.
-}  
-   
+}
+
 unit aasm;
 
 {$i defines.inc}
@@ -68,10 +68,11 @@ interface
           ait_regalloc, { for register,temp allocation debugging }
           ait_tempalloc,
           ait_marker,
-
+{$ifdef alpha}
           { the follow is for the DEC Alpha }
           ait_frame,
           ait_ent,
+{$endif alpha}
 {$ifdef m68k}
           ait_labeled_instruction,
 {$endif m68k}
@@ -205,22 +206,6 @@ interface
        end;
 
 
-       { alignment for operator }
-{$ifdef i386}
-       tai_align_abstract = class(tai)
-{$else i386}
-       tai_align = class(tai)
-{$endif i386}
-          buf       : array[0..63] of char; { buf used for fill }
-          aligntype : byte;   { 1 = no align, 2 = word align, 4 = dword align }
-          fillsize  : byte;   { real size to fill }
-          fillop    : byte;   { value to fill with - optional }
-          use_op    : boolean;
-          constructor Create(b:byte);
-          constructor Create_op(b: byte; _op: byte);
-          function getfillbuf:pchar;
-       end;
-
        { Insert a section/segment directive }
        tai_section = class(tai)
           sec : tsection;
@@ -742,56 +727,6 @@ uses
          inherited Destroy;
       end;
 
-{****************************************************************************
-                              TAI_ALIGN
- ****************************************************************************}
-
-{$ifdef i386}
-     constructor tai_align_abstract.Create(b: byte);
-{$else i386}
-     constructor tai_align.Create(b: byte);
-{$endif i386}
-       begin
-          inherited Create;
-          typ:=ait_align;
-          if b in [1,2,4,8,16,32] then
-            aligntype := b
-          else
-            aligntype := 1;
-          fillsize:=0;
-          fillop:=0;
-          use_op:=false;
-       end;
-
-
-{$ifdef i386}
-     constructor tai_align_abstract.Create_op(b: byte; _op: byte);
-{$else i386}
-     constructor tai_align.Create_op(b: byte; _op: byte);
-{$endif i386}
-       begin
-          inherited Create;
-          typ:=ait_align;
-          if b in [1,2,4,8,16,32] then
-            aligntype := b
-          else
-            aligntype := 1;
-          fillsize:=0;
-          fillop:=_op;
-          use_op:=true;
-          fillchar(buf,sizeof(buf),_op)
-       end;
-
-
-{$ifdef i386}
-     function tai_align_abstract.getfillbuf:pchar;
-{$else i386}
-     function tai_align.getfillbuf:pchar;
-{$endif i386}
-       begin
-         getfillbuf:=@buf;
-       end;
-
 {****************************************************************************
                               TAI_CUT
  ****************************************************************************}
@@ -1135,7 +1070,13 @@ uses
 end.
 {
   $Log$
-  Revision 1.23  2002-04-15 18:54:34  carl
+  Revision 1.24  2002-05-14 17:28:08  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.23  2002/04/15 18:54:34  carl
   - removed tcpuflags
 
   Revision 1.22  2002/04/07 13:18:19  carl

+ 14 - 10
compiler/aoptbase.pas

@@ -91,21 +91,19 @@ uses globals, aoptcpub, cpuinfo;
 
 Function RefsEqual(Const R1, R2: TReference): Boolean;
 Begin
-  If R1.is_immediate Then
-    RefsEqual := R2.is_immediate and (R1.Offset = R2.Offset)
-  Else
-    RefsEqual := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup)
-                 And (R1.Base = R2.Base)
+  RefsEqual := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup)
+               And (R1.Base = R2.Base)
 {$ifdef RefsHaveindex}
-                 And (R1.Index = R2.Index)
+               And (R1.Index = R2.Index)
 {$endif RefsHaveindex}
 {$ifdef RefsHaveScale}
-                 And (R1.ScaleFactor = R2.ScaleFactor)
+               And (R1.ScaleFactor = R2.ScaleFactor)
 {$endif RefsHaveScale}
-                 And (R1.Symbol = R2.Symbol)
+               And (R1.Symbol = R2.Symbol)
 {$ifdef RefsHaveSegment}
-                 And (R1.Segment = R2.Segment)
+               And (R1.Segment = R2.Segment)
 {$endif RefsHaveSegment}
+               ;
 End;
 
 
@@ -263,7 +261,13 @@ End.
 
 {
   $Log$
-  Revision 1.1  2001-08-26 13:36:35  florian
+  Revision 1.2  2002-05-14 17:28:09  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.1  2001/08/26 13:36:35  florian
     * some cg reorganisation
     * some PPC updates
 

+ 162 - 12
compiler/i386/cpuasm.pas

@@ -28,15 +28,6 @@ unit cpuasm;
 
 {$i defines.inc}
 
-{ Optimize addressing and skip already passed nodes }
-{$ifndef NASMDEBUG}
-  {$define OPTEA}
-  {$define PASS2FLAG}
-{$endif ndef NASMDEBUG}
-
-{ Give warnings when an immediate is found in the reference struct }
-{.$define REF_IMMEDIATE_WARN}
-
 interface
 
 uses
@@ -51,6 +42,121 @@ const
                               Instruction table
 *****************************************************************************}
 
+const
+{ Operand types }
+  OT_NONE      = $00000000;
+
+  OT_BITS8     = $00000001;  { size, and other attributes, of the operand  }
+  OT_BITS16    = $00000002;
+  OT_BITS32    = $00000004;
+  OT_BITS64    = $00000008;  { FPU only  }
+  OT_BITS80    = $00000010;
+  OT_FAR       = $00000020;  { this means 16:16 or 16:32, like in CALL/JMP }
+  OT_NEAR      = $00000040;
+  OT_SHORT     = $00000080;
+
+  OT_SIZE_MASK = $000000FF;  { all the size attributes  }
+  OT_NON_SIZE  = longint(not OT_SIZE_MASK);
+
+  OT_SIGNED    = $00000100;  { the operand need to be signed -128-127 }
+
+  OT_TO        = $00000200;  { operand is followed by a colon  }
+                             { reverse effect in FADD, FSUB &c  }
+  OT_COLON     = $00000400;
+
+  OT_REGISTER  = $00001000;
+  OT_IMMEDIATE = $00002000;
+  OT_IMM8      = $00002001;
+  OT_IMM16     = $00002002;
+  OT_IMM32     = $00002004;
+  OT_IMM64     = $00002008;
+  OT_IMM80     = $00002010;
+  OT_REGMEM    = $00200000;  { for r/m, ie EA, operands  }
+  OT_REGNORM   = $00201000;  { 'normal' reg, qualifies as EA  }
+  OT_REG8      = $00201001;
+  OT_REG16     = $00201002;
+  OT_REG32     = $00201004;
+  OT_MMXREG    = $00201008;  { MMX registers  }
+  OT_XMMREG    = $00201010;  { Katmai registers  }
+  OT_MEMORY    = $00204000;  { register number in 'basereg'  }
+  OT_MEM8      = $00204001;
+  OT_MEM16     = $00204002;
+  OT_MEM32     = $00204004;
+  OT_MEM64     = $00204008;
+  OT_MEM80     = $00204010;
+  OT_FPUREG    = $01000000;  { floating point stack registers  }
+  OT_FPU0      = $01000800;  { FPU stack register zero  }
+  OT_REG_SMASK = $00070000;  { special register operands: these may be treated differently  }
+                             { a mask for the following  }
+  OT_REG_ACCUM = $00211000;  { accumulator: AL, AX or EAX  }
+  OT_REG_AL    = $00211001;    { REG_ACCUM | BITSxx  }
+  OT_REG_AX    = $00211002;    { ditto  }
+  OT_REG_EAX   = $00211004;    { and again  }
+  OT_REG_COUNT = $00221000;  { counter: CL, CX or ECX  }
+  OT_REG_CL    = $00221001;    { REG_COUNT | BITSxx  }
+  OT_REG_CX    = $00221002;    { ditto  }
+  OT_REG_ECX   = $00221004;    { another one  }
+  OT_REG_DX    = $00241002;
+
+  OT_REG_SREG  = $00081002;  { any segment register  }
+  OT_REG_CS    = $01081002;  { CS  }
+  OT_REG_DESS  = $02081002;  { DS, ES, SS (non-CS 86 registers)  }
+  OT_REG_FSGS  = $04081002;  { FS, GS (386 extended registers)  }
+
+  OT_REG_CDT   = $00101004;  { CRn, DRn and TRn  }
+  OT_REG_CREG  = $08101004;  { CRn  }
+  OT_REG_CR4   = $08101404;  { CR4 (Pentium only)  }
+  OT_REG_DREG  = $10101004;  { DRn  }
+  OT_REG_TREG  = $20101004;  { TRn  }
+
+  OT_MEM_OFFS  = $00604000;  { special type of EA  }
+                             { simple [address] offset  }
+  OT_ONENESS   = $00800000;  { special type of immediate operand  }
+                             { so UNITY == IMMEDIATE | ONENESS  }
+  OT_UNITY     = $00802000;  { for shift/rotate instructions  }
+
+{Instruction flags }
+  IF_NONE   = $00000000;
+  IF_SM     = $00000001;        { size match first two operands  }
+  IF_SM2    = $00000002;
+  IF_SB     = $00000004;  { unsized operands can't be non-byte  }
+  IF_SW     = $00000008;  { unsized operands can't be non-word  }
+  IF_SD     = $00000010;  { unsized operands can't be nondword  }
+  IF_AR0    = $00000020;  { SB, SW, SD applies to argument 0  }
+  IF_AR1    = $00000040;  { SB, SW, SD applies to argument 1  }
+  IF_AR2    = $00000060;  { SB, SW, SD applies to argument 2  }
+  IF_ARMASK = $00000060;  { mask for unsized argument spec  }
+  IF_PRIV   = $00000100;  { it's a privileged instruction  }
+  IF_SMM    = $00000200;  { it's only valid in SMM  }
+  IF_PROT   = $00000400;  { it's protected mode only  }
+  IF_UNDOC  = $00001000;  { it's an undocumented instruction  }
+  IF_FPU    = $00002000;  { it's an FPU instruction  }
+  IF_MMX    = $00004000;  { it's an MMX instruction  }
+  IF_3DNOW  = $00008000;  { it's a 3DNow! instruction  }
+  IF_SSE    = $00010000;  { it's a SSE (KNI, MMX2) instruction  }
+  IF_PMASK  =
+     longint($FF000000);  { the mask for processor types  }
+  IF_PFMASK =
+     longint($F001FF00);  { the mask for disassembly "prefer"  }
+  IF_8086   = $00000000;  { 8086 instruction  }
+  IF_186    = $01000000;  { 186+ instruction  }
+  IF_286    = $02000000;  { 286+ instruction  }
+  IF_386    = $03000000;  { 386+ instruction  }
+  IF_486    = $04000000;  { 486+ instruction  }
+  IF_PENT   = $05000000;  { Pentium instruction  }
+  IF_P6     = $06000000;  { P6 instruction  }
+  IF_KATMAI = $07000000;  { Katmai instructions  }
+  IF_CYRIX  = $10000000;  { Cyrix-specific instruction  }
+  IF_AMD    = $20000000;  { AMD-specific instruction  }
+  { added flags }
+  IF_PRE    = $40000000;  { it's a prefix instruction }
+  IF_PASS2  =
+     longint($80000000);  { if the instruction can change in a second pass }
+
+  { Size of the instruction table converted by nasmconv.pas }
+  instabentries = {$i i386nop.inc}
+  maxinfolen    = 8;
+
 type
   tinsentry=packed record
     opcode  : tasmop;
@@ -79,10 +185,10 @@ type
      reg       : tregister;
      constructor create(b:byte);
      constructor create_op(b: byte; _op: byte);
-     function getfillbuf:pchar;
+     function getfillbuf:pchar;override;
   end;
 
-  taicpu = class(tainstruction)
+  taicpu = class(taicpu_abstract)
      opsize    : topsize;
      constructor op_none(op : tasmop;_size : topsize);
 
@@ -159,6 +265,44 @@ uses
   ogbase,
   ag386att;
 
+const
+  { Intel style operands ! }
+  opsize_2_type:array[0..2,topsize] of longint=(
+    (OT_NONE,
+     OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
+     OT_BITS16,OT_BITS32,OT_BITS64,
+     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
+     OT_NEAR,OT_FAR,OT_SHORT
+    ),
+    (OT_NONE,
+     OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
+     OT_BITS16,OT_BITS32,OT_BITS64,
+     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
+     OT_NEAR,OT_FAR,OT_SHORT
+    ),
+    (OT_NONE,
+     OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
+     OT_BITS16,OT_BITS32,OT_BITS64,
+     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
+     OT_NEAR,OT_FAR,OT_SHORT
+    )
+  );
+
+  { Convert reg to operand type }
+  reg2type : array[firstreg..lastreg] of longint = (OT_NONE,
+    OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
+    OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
+    OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
+    OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
+    OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
+    OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
+    OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
+    OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
+    OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
+    OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
+  );
+
+
 {****************************************************************************
                               TAI_ALIGN
  ****************************************************************************}
@@ -1663,7 +1807,13 @@ end;
 end.
 {
   $Log$
-  Revision 1.21  2002-05-12 16:53:16  peter
+  Revision 1.22  2002-05-14 17:28:09  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.21  2002/05/12 16:53:16  peter
     * moved entry and exitcode to ncgutil and cgobj
     * foreach gets extra argument for passing local data to the
       iterator function

+ 304 - 503
compiler/i386/cpubase.pas

@@ -4,10 +4,6 @@
 
     Contains the base types for the i386
 
-    * This code was inspired by the NASM sources
-      The Netwide Assembler is copyright (C) 1996 Simon Tatham and
-      Julian Hall. All rights reserved.
-
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
@@ -37,555 +33,365 @@ interface
 uses
   globals,cutils,cclasses,aasm,cpuinfo,cginfo;
 
-const
-{ Size of the instruction table converted by nasmconv.pas }
-  instabentries = {$i i386nop.inc}
-  maxinfolen    = 8;
-
-{ By default we want everything }
-{$define ATTOP}
-{$define INTELOP}
-{$define ITTABLE}
-
-{ We Don't need the intel style opcodes if we don't have a intel
-  reader or generator }
-{$ifdef NORA386INT}
-  {$ifdef NOAG386NSM}
-    {$ifdef NOAG386INT}
-      {$undef INTELOP}
-    {$endif}
-  {$endif}
-{$endif}
-
-{ We Don't need the AT&T style opcodes if we don't have a AT&T
-  reader or generator }
-{$ifdef NORA386ATT}
-  {$ifdef NOAG386ATT}
-    {$undef ATTOP}
-    {$ifdef NOAG386DIR}
-       {$undef ATTREG}
-    {$endif}
-  {$endif}
-{$endif}
-
-{ We need the AT&T suffix table for both asm readers and AT&T writer }
-{$define ATTSUF}
-{$ifdef NORA386INT}
-  {$ifdef NORA386ATT}
-    {$ifdef NOAG386ATT}
-      {$undef ATTSUF}
-    {$endif}
-  {$endif}
-{$endif}
-
-const
-{ Operand types }
-  OT_NONE      = $00000000;
-
-  OT_BITS8     = $00000001;  { size, and other attributes, of the operand  }
-  OT_BITS16    = $00000002;
-  OT_BITS32    = $00000004;
-  OT_BITS64    = $00000008;  { FPU only  }
-  OT_BITS80    = $00000010;
-  OT_FAR       = $00000020;  { this means 16:16 or 16:32, like in CALL/JMP }
-  OT_NEAR      = $00000040;
-  OT_SHORT     = $00000080;
-
-  OT_SIZE_MASK = $000000FF;  { all the size attributes  }
-  OT_NON_SIZE  = longint(not OT_SIZE_MASK);
-
-  OT_SIGNED    = $00000100;  { the operand need to be signed -128-127 }
-
-  OT_TO        = $00000200;  { operand is followed by a colon  }
-                             { reverse effect in FADD, FSUB &c  }
-  OT_COLON     = $00000400;
-
-  OT_REGISTER  = $00001000;
-  OT_IMMEDIATE = $00002000;
-  OT_IMM8      = $00002001;
-  OT_IMM16     = $00002002;
-  OT_IMM32     = $00002004;
-  OT_IMM64     = $00002008;
-  OT_IMM80     = $00002010;
-  OT_REGMEM    = $00200000;  { for r/m, ie EA, operands  }
-  OT_REGNORM   = $00201000;  { 'normal' reg, qualifies as EA  }
-  OT_REG8      = $00201001;
-  OT_REG16     = $00201002;
-  OT_REG32     = $00201004;
-  OT_MMXREG    = $00201008;  { MMX registers  }
-  OT_XMMREG    = $00201010;  { Katmai registers  }
-  OT_MEMORY    = $00204000;  { register number in 'basereg'  }
-  OT_MEM8      = $00204001;
-  OT_MEM16     = $00204002;
-  OT_MEM32     = $00204004;
-  OT_MEM64     = $00204008;
-  OT_MEM80     = $00204010;
-  OT_FPUREG    = $01000000;  { floating point stack registers  }
-  OT_FPU0      = $01000800;  { FPU stack register zero  }
-  OT_REG_SMASK = $00070000;  { special register operands: these may be treated differently  }
-                             { a mask for the following  }
-  OT_REG_ACCUM = $00211000;  { accumulator: AL, AX or EAX  }
-  OT_REG_AL    = $00211001;    { REG_ACCUM | BITSxx  }
-  OT_REG_AX    = $00211002;    { ditto  }
-  OT_REG_EAX   = $00211004;    { and again  }
-  OT_REG_COUNT = $00221000;  { counter: CL, CX or ECX  }
-  OT_REG_CL    = $00221001;    { REG_COUNT | BITSxx  }
-  OT_REG_CX    = $00221002;    { ditto  }
-  OT_REG_ECX   = $00221004;    { another one  }
-  OT_REG_DX    = $00241002;
-
-  OT_REG_SREG  = $00081002;  { any segment register  }
-  OT_REG_CS    = $01081002;  { CS  }
-  OT_REG_DESS  = $02081002;  { DS, ES, SS (non-CS 86 registers)  }
-  OT_REG_FSGS  = $04081002;  { FS, GS (386 extended registers)  }
-
-  OT_REG_CDT   = $00101004;  { CRn, DRn and TRn  }
-  OT_REG_CREG  = $08101004;  { CRn  }
-  OT_REG_CR4   = $08101404;  { CR4 (Pentium only)  }
-  OT_REG_DREG  = $10101004;  { DRn  }
-  OT_REG_TREG  = $20101004;  { TRn  }
-
-  OT_MEM_OFFS  = $00604000;  { special type of EA  }
-                             { simple [address] offset  }
-  OT_ONENESS   = $00800000;  { special type of immediate operand  }
-                             { so UNITY == IMMEDIATE | ONENESS  }
-  OT_UNITY     = $00802000;  { for shift/rotate instructions  }
-
-{Instruction flags }
-  IF_NONE   = $00000000;
-  IF_SM     = $00000001;        { size match first two operands  }
-  IF_SM2    = $00000002;
-  IF_SB     = $00000004;  { unsized operands can't be non-byte  }
-  IF_SW     = $00000008;  { unsized operands can't be non-word  }
-  IF_SD     = $00000010;  { unsized operands can't be nondword  }
-  IF_AR0    = $00000020;  { SB, SW, SD applies to argument 0  }
-  IF_AR1    = $00000040;  { SB, SW, SD applies to argument 1  }
-  IF_AR2    = $00000060;  { SB, SW, SD applies to argument 2  }
-  IF_ARMASK = $00000060;  { mask for unsized argument spec  }
-  IF_PRIV   = $00000100;  { it's a privileged instruction  }
-  IF_SMM    = $00000200;  { it's only valid in SMM  }
-  IF_PROT   = $00000400;  { it's protected mode only  }
-  IF_UNDOC  = $00001000;  { it's an undocumented instruction  }
-  IF_FPU    = $00002000;  { it's an FPU instruction  }
-  IF_MMX    = $00004000;  { it's an MMX instruction  }
-  IF_3DNOW  = $00008000;  { it's a 3DNow! instruction  }
-  IF_SSE    = $00010000;  { it's a SSE (KNI, MMX2) instruction  }
-  IF_PMASK  =
-     longint($FF000000);  { the mask for processor types  }
-  IF_PFMASK =
-     longint($F001FF00);  { the mask for disassembly "prefer"  }
-  IF_8086   = $00000000;  { 8086 instruction  }
-  IF_186    = $01000000;  { 186+ instruction  }
-  IF_286    = $02000000;  { 286+ instruction  }
-  IF_386    = $03000000;  { 386+ instruction  }
-  IF_486    = $04000000;  { 486+ instruction  }
-  IF_PENT   = $05000000;  { Pentium instruction  }
-  IF_P6     = $06000000;  { P6 instruction  }
-  IF_KATMAI = $07000000;  { Katmai instructions  }
-  IF_CYRIX  = $10000000;  { Cyrix-specific instruction  }
-  IF_AMD    = $20000000;  { AMD-specific instruction  }
-  { added flags }
-  IF_PRE    = $40000000;  { it's a prefix instruction }
-  IF_PASS2  =
-     longint($80000000);  { if the instruction can change in a second pass }
-
-type
-
-  TAsmOp={$i i386op.inc}
-
-  {# This should define the array of instructions as string }
-  op2strtable=array[tasmop] of string[11];
-
-Const
-
-  {# First value of opcode enumeration }
-  firstop = low(tasmop);
-  {# Last value of opcode enumeration  }
-  lastop  = high(tasmop);
-
 
 {*****************************************************************************
-                                Operand Sizes
+                                Assembler Opcodes
 *****************************************************************************}
 
-type
-  topsize = (S_NO,
-    S_B,S_W,S_L,S_BW,S_BL,S_WL,
-    S_IS,S_IL,S_IQ,
-    S_FS,S_FL,S_FX,S_D,S_Q,S_FV,
-    S_NEAR,S_FAR,S_SHORT
-  );
-
-const
-  { Intel style operands ! }
-  opsize_2_type:array[0..2,topsize] of longint=(
-    (OT_NONE,
-     OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS16,OT_BITS32,OT_BITS32,
-     OT_BITS16,OT_BITS32,OT_BITS64,
-     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
-     OT_NEAR,OT_FAR,OT_SHORT
-    ),
-    (OT_NONE,
-     OT_BITS8,OT_BITS16,OT_BITS32,OT_BITS8,OT_BITS8,OT_BITS16,
-     OT_BITS16,OT_BITS32,OT_BITS64,
-     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
-     OT_NEAR,OT_FAR,OT_SHORT
-    ),
-    (OT_NONE,
-     OT_BITS8,OT_BITS16,OT_BITS32,OT_NONE,OT_NONE,OT_NONE,
-     OT_BITS16,OT_BITS32,OT_BITS64,
-     OT_BITS32,OT_BITS64,OT_BITS80,OT_BITS64,OT_BITS64,OT_BITS64,
-     OT_NEAR,OT_FAR,OT_SHORT
-    )
-  );
+    type
+      TAsmOp={$i i386op.inc}
 
+      {# This should define the array of instructions as string }
+      op2strtable=array[tasmop] of string[11];
 
+    Const
+      {# First value of opcode enumeration }
+      firstop = low(tasmop);
+      {# Last value of opcode enumeration  }
+      lastop  = high(tasmop);
 
 {*****************************************************************************
-                                Conditions
+                                Operand Sizes
 *****************************************************************************}
 
-type
-  TAsmCond=(C_None,
-    C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
-    C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
-    C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
-  );
-
-const
-  cond2str:array[TAsmCond] of string[3]=('',
-    'a','ae','b','be','c','e','g','ge','l','le','na','nae',
-    'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
-    'ns','nz','o','p','pe','po','s','z'
-  );
-  inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
-    C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
-    C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
-    C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
-  );
-
+    type
+      topsize = (S_NO,
+        S_B,S_W,S_L,S_BW,S_BL,S_WL,
+        S_IS,S_IL,S_IQ,
+        S_FS,S_FL,S_FX,S_D,S_Q,S_FV,
+        S_NEAR,S_FAR,S_SHORT
+      );
 
 {*****************************************************************************
                                   Registers
 *****************************************************************************}
 
-type
-  {# Enumeration for all possible registers for cpu. It
-    is to note that all registers of the same type
-    (for example all FPU registers), should be grouped
-    together.
-  }
-  { don't change the order }
-  { it's used by the register size conversions        }
-  tregister = (R_NO,
-    R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
-    R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
-    R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
-    R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
-    R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
-    R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
-    R_CR0,R_CR2,R_CR3,R_CR4,
-    R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
-    R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
-    R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
-  );
-
-  {# Set type definition for registers }
-  tregisterset = set of tregister;
-
-  {# Type definition for the array of string of register nnames }
-  reg2strtable = array[tregister] of string[6];
-
-const
-  {# First register in the tregister enumeration }
-  firstreg = low(tregister);
-  {# Last register in the tregister enumeration }
-  lastreg  = high(tregister);
-
-  firstsreg = R_CS;
-  lastsreg  = R_GS;
-
-  regset8bit  : tregisterset = [R_AL..R_DH];
-  regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
-  regset32bit : tregisterset = [R_EAX..R_EDI];
-
-  { Convert reg to opsize }
-  reg2opsize : array[firstreg..lastreg] of topsize = (S_NO,
-    S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
-    S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
-    S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
-    S_W,S_W,S_W,S_W,S_W,S_W,
-    S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
-    S_L,S_L,S_L,S_L,S_L,S_L,
-    S_L,S_L,S_L,S_L,
-    S_L,S_L,S_L,S_L,S_L,
-    S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
-    S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
-  );
-
-  { Convert reg to operand type }
-  reg2type : array[firstreg..lastreg] of longint = (OT_NONE,
-    OT_REG_EAX,OT_REG_ECX,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,OT_REG32,
-    OT_REG_AX,OT_REG_CX,OT_REG_DX,OT_REG16,OT_REG16,OT_REG16,OT_REG16,OT_REG16,
-    OT_REG_AL,OT_REG_CL,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,OT_REG8,
-    OT_REG_CS,OT_REG_DESS,OT_REG_DESS,OT_REG_DESS,OT_REG_FSGS,OT_REG_FSGS,
-    OT_FPU0,OT_FPU0,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,OT_FPUREG,
-    OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,OT_REG_DREG,
-    OT_REG_CREG,OT_REG_CREG,OT_REG_CREG,OT_REG_CR4,
-    OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,OT_REG_TREG,
-    OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,OT_MMXREG,
-    OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG,OT_XMMREG
-  );
-
-  {# Standard opcode string table (for each tasmop enumeration). The
-     opcode strings should conform to the names as defined by the
-     processor manufacturer.
-  }
-  std_op2str:op2strtable={$i i386int.inc}
-
-  {# Standard register table (for each tregister enumeration). The
-     register strings should conform to the the names as defined
-     by the processor manufacturer
-  }
-  std_reg2str : reg2strtable = ('',
-    'eax','ecx','edx','ebx','esp','ebp','esi','edi',
-    'ax','cx','dx','bx','sp','bp','si','di',
-    'al','cl','dl','bl','ah','ch','bh','dh',
-    'cs','ds','es','ss','fs','gs',
-    'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
-    'dr0','dr1','dr2','dr3','dr6','dr7',
-    'cr0','cr2','cr3','cr4',
-    'tr3','tr4','tr5','tr6','tr7',
-    'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
-    'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
-  );
+    type
+      {# Enumeration for all possible registers for cpu. It
+        is to note that all registers of the same type
+        (for example all FPU registers), should be grouped
+        together.
+      }
+      { don't change the order }
+      { it's used by the register size conversions        }
+      tregister = (R_NO,
+        R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
+        R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
+        R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
+        R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
+        R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
+        R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
+        R_CR0,R_CR2,R_CR3,R_CR4,
+        R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
+        R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
+        R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
+      );
+
+      {# Set type definition for registers }
+      tregisterset = set of tregister;
+
+      {# Type definition for the array of string of register nnames }
+      reg2strtable = array[tregister] of string[6];
 
+    const
+      {# First register in the tregister enumeration }
+      firstreg = low(tregister);
+      {# Last register in the tregister enumeration }
+      lastreg  = high(tregister);
+
+      firstsreg = R_CS;
+      lastsreg  = R_GS;
+
+      regset8bit  : tregisterset = [R_AL..R_DH];
+      regset16bit : tregisterset = [R_AX..R_DI,R_CS..R_SS];
+      regset32bit : tregisterset = [R_EAX..R_EDI];
+
+      { Convert reg to opsize }
+      reg2opsize : array[firstreg..lastreg] of topsize = (S_NO,
+        S_L,S_L,S_L,S_L,S_L,S_L,S_L,S_L,
+        S_W,S_W,S_W,S_W,S_W,S_W,S_W,S_W,
+        S_B,S_B,S_B,S_B,S_B,S_B,S_B,S_B,
+        S_W,S_W,S_W,S_W,S_W,S_W,
+        S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,S_FL,
+        S_L,S_L,S_L,S_L,S_L,S_L,
+        S_L,S_L,S_L,S_L,
+        S_L,S_L,S_L,S_L,S_L,
+        S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D,
+        S_D,S_D,S_D,S_D,S_D,S_D,S_D,S_D
+      );
+
+      {# Standard opcode string table (for each tasmop enumeration). The
+         opcode strings should conform to the names as defined by the
+         processor manufacturer.
+      }
+      std_op2str:op2strtable={$i i386int.inc}
+
+      {# Standard register table (for each tregister enumeration). The
+         register strings should conform to the the names as defined
+         by the processor manufacturer
+      }
+      std_reg2str : reg2strtable = ('',
+        'eax','ecx','edx','ebx','esp','ebp','esi','edi',
+        'ax','cx','dx','bx','sp','bp','si','di',
+        'al','cl','dl','bl','ah','ch','bh','dh',
+        'cs','ds','es','ss','fs','gs',
+        'st','st(0)','st(1)','st(2)','st(3)','st(4)','st(5)','st(6)','st(7)',
+        'dr0','dr1','dr2','dr3','dr6','dr7',
+        'cr0','cr2','cr3','cr4',
+        'tr3','tr4','tr5','tr6','tr7',
+        'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
+        'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
+      );
 
 {*****************************************************************************
-                                   Flags
+                                Conditions
 *****************************************************************************}
 
-type
-  TResFlags = (F_E,F_NE,F_G,F_L,F_GE,F_LE,F_C,F_NC,F_A,F_AE,F_B,F_BE);
+    type
+      TAsmCond=(C_None,
+        C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
+        C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
+        C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
+      );
+
+    const
+      cond2str:array[TAsmCond] of string[3]=('',
+        'a','ae','b','be','c','e','g','ge','l','le','na','nae',
+        'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
+        'ns','nz','o','p','pe','po','s','z'
+      );
+
+      inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
+        C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
+        C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
+        C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
+      );
 
 {*****************************************************************************
-                                Reference
+                                   Flags
 *****************************************************************************}
 
-type
-  trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
-
-type
-  { immediate/reference record }
-  poperreference = ^treference;
-  treference = packed record
-     segment,
-     base,
-     index       : tregister;
-     scalefactor : byte;
-     offset      : longint;
-     symbol      : tasmsymbol;
-     offsetfixup : longint;
-     options     : trefoptions;
-  end;
+    type
+      TResFlags = (F_E,F_NE,F_G,F_L,F_GE,F_LE,F_C,F_NC,F_A,F_AE,F_B,F_BE);
 
 {*****************************************************************************
-                                Operands
+                                Reference
 *****************************************************************************}
 
-       { Types of operand }
-        toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
-
-        toper=record
-          ot  : longint;
-          case typ : toptype of
-           top_none   : ();
-           top_reg    : (reg:tregister);
-           top_ref    : (ref:poperreference);
-           top_const  : (val:aword);
-           top_symbol : (sym:tasmsymbol;symofs:longint);
-        end;
-
-
+    type
+      trefoptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
+
+      { reference record }
+      preference = ^treference;
+      treference = packed record
+         segment,
+         base,
+         index       : tregister;
+         scalefactor : byte;
+         offset      : longint;
+         symbol      : tasmsymbol;
+         offsetfixup : longint;
+         options     : trefoptions;
+      end;
 
 {*****************************************************************************
-                             Argument Classification
+                                Operands
 *****************************************************************************}
 
+      { Types of operand }
+      toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
+
+      toper=record
+        ot  : longint;
+        case typ : toptype of
+         top_none   : ();
+         top_reg    : (reg:tregister);
+         top_ref    : (ref:preference);
+         top_const  : (val:aword);
+         top_symbol : (sym:tasmsymbol;symofs:longint);
+      end;
 
 {*****************************************************************************
                                Generic Location
 *****************************************************************************}
 
-type
-  TLoc=(
-    LOC_INVALID,      { added for tracking problems}
-    LOC_CONSTANT,     { constant value }
-    LOC_JUMP,         { boolean results only, jump to false or true label }
-    LOC_FLAGS,        { boolean results only, flags are set }
-    LOC_CREFERENCE,   { in memory constant value reference (cannot change) }
-    LOC_REFERENCE,    { in memory value }
-    LOC_REGISTER,     { in a processor register }
-    LOC_CREGISTER,    { Constant register which shouldn't be modified }
-    LOC_FPUREGISTER,  { FPU stack }
-    LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack }
-    LOC_MMXREGISTER,  { MMX register }
-    LOC_CMMXREGISTER, { MMX register variable }
-    LOC_SSEREGISTER,
-    LOC_CSSEREGISTER
-  );
-
-  plocation = ^tlocation;
-  tlocation = packed record
-     loc  : TLoc;
-     size : TCGSize;
-     case TLoc of
-        LOC_FLAGS : (resflags : tresflags);
-        LOC_CONSTANT : (
-          case longint of
-            1 : (value : AWord);
-            2 : (valuelow, valuehigh:AWord);
-          );
-        LOC_CREFERENCE,
-        LOC_REFERENCE : (reference : treference);
-        { segment in reference at the same place as in loc_register }
-        LOC_REGISTER,LOC_CREGISTER : (
-          case longint of
-            1 : (register,segment,registerhigh : tregister);
-            { overlay a registerlow }
-            2 : (registerlow : tregister);
-          );
-        { it's only for better handling }
-        LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
-  end;
+    type
+      TLoc=(
+        LOC_INVALID,      { added for tracking problems}
+        LOC_CONSTANT,     { constant value }
+        LOC_JUMP,         { boolean results only, jump to false or true label }
+        LOC_FLAGS,        { boolean results only, flags are set }
+        LOC_CREFERENCE,   { in memory constant value reference (cannot change) }
+        LOC_REFERENCE,    { in memory value }
+        LOC_REGISTER,     { in a processor register }
+        LOC_CREGISTER,    { Constant register which shouldn't be modified }
+        LOC_FPUREGISTER,  { FPU stack }
+        LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack }
+        LOC_MMXREGISTER,  { MMX register }
+        LOC_CMMXREGISTER, { MMX register variable }
+        LOC_SSEREGISTER,
+        LOC_CSSEREGISTER
+      );
+
+      tlocation = packed record
+         loc  : TLoc;
+         size : TCGSize;
+         case TLoc of
+            LOC_FLAGS : (resflags : tresflags);
+            LOC_CONSTANT : (
+              case longint of
+                1 : (value : AWord);
+                2 : (valuelow, valuehigh:AWord);
+              );
+            LOC_CREFERENCE,
+            LOC_REFERENCE : (reference : treference);
+            { segment in reference at the same place as in loc_register }
+            LOC_REGISTER,LOC_CREGISTER : (
+              case longint of
+                1 : (register,segment,registerhigh : tregister);
+                { overlay a registerlow }
+                2 : (registerlow : tregister);
+              );
+            { it's only for better handling }
+            LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
+      end;
 
 {*****************************************************************************
                                  Constants
 *****************************************************************************}
 
-const
-  general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
-
-  {# Table of registers which can be allocated by the code generator
-     internally, when generating the code.
-  }
-  { legend:                                                                }
-  { xxxregs = set of all possibly used registers of that type in the code  }
-  {           generator                                                    }
-  { usableregsxxx = set of all 32bit components of registers that can be   }
-  {           possible allocated to a regvar or using getregisterxxx (this }
-  {           excludes registers which can be only used for parameter      }
-  {           passing on ABI's that define this)                           }
-  { c_countusableregsxxx = amount of registers in the usableregsxxx set    }
-
-  intregs = [R_EAX..R_BL];
-  usableregsint = general_registers;
-  c_countusableregsint = 4;
-
-  fpuregs = [R_ST0..R_ST7];
-  usableregsfpu = [];
-  c_countusableregsfpu = 0;
-
-  mmregs = [R_MM0..R_MM7];
-  usableregsmm = [R_MM0..R_MM7];
-  c_countusableregsmm  = 8;
-
-  firstsaveintreg = R_EAX;
-  lastsaveintreg = R_EBX;
-  firstsavefpureg = R_NO;
-  lastsavefpureg = R_NO;
-  firstsavemmreg = R_MM0;
-  lastsavemmreg = R_MM7;
-
-  {# Constant defining possibly all registers which might require saving }
-  ALL_REGISTERS = [firstreg..lastreg];
-
-  lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
-    LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
+    const
+      max_operands = 3;
+
+      lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
+        LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
+
+      {# Constant defining possibly all registers which might require saving }
+      ALL_REGISTERS = [firstreg..lastreg];
+
+      general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
+
+      {# low and high of the available maximum width integer general purpose }
+      { registers                                                            }
+      LoGPReg = R_EAX;
+      HiGPReg = R_EDX;
+
+      {# low and high of every possible width general purpose register (same as }
+      { above on most architctures apart from the 80x86)                        }
+      LoReg = R_EAX;
+      HiReg = R_DH;
+
+      {# Table of registers which can be allocated by the code generator
+         internally, when generating the code.
+      }
+      { legend:                                                                }
+      { xxxregs = set of all possibly used registers of that type in the code  }
+      {           generator                                                    }
+      { usableregsxxx = set of all 32bit components of registers that can be   }
+      {           possible allocated to a regvar or using getregisterxxx (this }
+      {           excludes registers which can be only used for parameter      }
+      {           passing on ABI's that define this)                           }
+      { c_countusableregsxxx = amount of registers in the usableregsxxx set    }
+
+      maxintregs = 4;
+      intregs = [R_EAX..R_BL];
+      usableregsint = [R_EAX,R_EBX,R_ECX,R_EDX];
+      c_countusableregsint = 4;
+
+      maxfpuregs = 8;
+      fpuregs = [R_ST0..R_ST7];
+      usableregsfpu = [];
+      c_countusableregsfpu = 0;
+
+      mmregs = [R_MM0..R_MM7];
+      usableregsmm = [R_MM0..R_MM7];
+      c_countusableregsmm  = 8;
+
+      firstsaveintreg = R_EAX;
+      lastsaveintreg  = R_EBX;
+      firstsavefpureg = R_NO;
+      lastsavefpureg  = R_NO;
+      firstsavemmreg  = R_MM0;
+      lastsavemmreg   = R_MM7;
+
+      maxvarregs = 4;
+      varregs : array[1..maxvarregs] of tregister =
+         (R_EBX,R_EDX,R_ECX,R_EAX);
+
+      maxfpuvarregs = 8;
+
+      {# Registers which are defined as scratch and no need to save across
+         routine calls or in assembler blocks.
+      }
+      max_scratch_regs = 1;
+      scratch_regs : array[1..max_scratch_regs] of tregister = (R_EDI);
 
 {*****************************************************************************
                           Default generic sizes
 *****************************************************************************}
-   {# Defines the default address size for a processor, }
-   OS_ADDR = OS_32;
-   {# the natural int size for a processor,             }
-   OS_INT = OS_32;
-   {# the maximum float size for a processor,           }
-   OS_FLOAT = OS_F80;
-   {# the size of a vector register for a processor     }
-   OS_VECTOR = OS_M64;
+
+      {# Defines the default address size for a processor, }
+      OS_ADDR = OS_32;
+      {# the natural int size for a processor,             }
+      OS_INT = OS_32;
+      {# the maximum float size for a processor,           }
+      OS_FLOAT = OS_F80;
+      {# the size of a vector register for a processor     }
+      OS_VECTOR = OS_M64;
 
 {*****************************************************************************
                           Generic Register names
 *****************************************************************************}
 
-  {# Stack pointer register }
-  stack_pointer_reg = R_ESP;
-  {# Frame pointer register }
-  frame_pointer_reg = R_EBP;
-  {# Self pointer register : contains the instance address of an
-     object or class. }
-  self_pointer_reg  = R_ESI;
-  {# Register for addressing absolute data in a position independant way,
-     such as in PIC code. The exact meaning is ABI specific }
-  pic_offset_reg = R_EBX;
-  {# Results are returned in this register (32-bit values) }
-  accumulator   = R_EAX;
-  {# Hi-Results are returned in this register (64-bit value high register) }
-  accumulatorhigh = R_EDX;
-  { WARNING: don't change to R_ST0!! See comments above implementation of }
-  { a_loadfpu* methods in rgcpu (JM)                                      }
-  fpuresultreg = R_ST;
-  mmresultreg = R_MM0;
-
-  {# Registers which are defined as scratch and no need to save across
-     routine calls or in assembler blocks.
-  }
-  scratch_regs : array[1..1] of tregister = (R_EDI);
-
-
+      {# Stack pointer register }
+      stack_pointer_reg = R_ESP;
+      {# Frame pointer register }
+      frame_pointer_reg = R_EBP;
+      {# Self pointer register : contains the instance address of an
+         object or class. }
+      self_pointer_reg  = R_ESI;
+      {# Register for addressing absolute data in a position independant way,
+         such as in PIC code. The exact meaning is ABI specific }
+      pic_offset_reg = R_EBX;
+      {# Results are returned in this register (32-bit values) }
+      accumulator   = R_EAX;
+      {# Hi-Results are returned in this register (64-bit value high register) }
+      accumulatorhigh = R_EDX;
+      { WARNING: don't change to R_ST0!! See comments above implementation of }
+      { a_loadfpu* methods in rgcpu (JM)                                      }
+      fpuresultreg = R_ST;
+      mmresultreg = R_MM0;
 
 {*****************************************************************************
                        GCC /ABI linking information
 *****************************************************************************}
 
-  {# Registers which must be saved when calling a routine declared as
-     cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
-     saved should be the ones as defined in the target ABI and / or GCC.
-
-     This value can be deduced from the CALLED_USED_REGISTERS array in the
-     GCC source.
-  }
-  std_saved_registers = [R_ESI,R_EDI,R_EBX];
-  {# Required parameter alignment when calling a routine declared as
-     stdcall and cdecl. The alignment value should be the one defined
-     by GCC or the target ABI.
-
-     The value of this constant is equal to the constant
-     PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
-  }
-  std_param_align = 4;
-
-
-
+    const
+      {# Registers which must be saved when calling a routine declared as
+         cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
+         saved should be the ones as defined in the target ABI and / or GCC.
+
+         This value can be deduced from the CALLED_USED_REGISTERS array in the
+         GCC source.
+      }
+      std_saved_registers = [R_ESI,R_EDI,R_EBX];
+      {# Required parameter alignment when calling a routine declared as
+         stdcall and cdecl. The alignment value should be the one defined
+         by GCC or the target ABI.
+
+         The value of this constant is equal to the constant
+         PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
+      }
+      std_param_align = 4;
 
+{*****************************************************************************
+                            CPU Dependent Constants
+*****************************************************************************}
 
 {*****************************************************************************
                                   Helpers
 *****************************************************************************}
 
-    const
-       maxvarregs = 4;
-       varregs : array[1..maxvarregs] of tregister =
-         (R_EBX,R_EDX,R_ECX,R_EAX);
-
-       maxfpuvarregs = 8;
-       max_operands = 3;
-
-       maxintregs = maxvarregs;
-       maxfpuregs = maxfpuvarregs;
-
-
     function is_calljmp(o:tasmop):boolean;
 
     function flags_to_cond(const f: TResFlags) : TAsmCond;
@@ -593,17 +399,10 @@ const
 
 implementation
 
-{$ifdef heaptrc}
-  uses
-      ppheap;
-{$endif heaptrc}
-
-
 {*****************************************************************************
                                   Helpers
 *****************************************************************************}
 
-
     function is_calljmp(o:tasmop):boolean;
       begin
         case o of
@@ -624,9 +423,6 @@ implementation
       end;
 
 
-
-
-
     function flags_to_cond(const f: TResFlags) : TAsmCond;
       const
         flags_2_cond : array[TResFlags] of TAsmCond =
@@ -635,11 +431,16 @@ implementation
         result := flags_2_cond[f];
       end;
 
-
 end.
 {
   $Log$
-  Revision 1.19  2002-05-12 16:53:16  peter
+  Revision 1.20  2002-05-14 17:28:09  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.19  2002/05/12 16:53:16  peter
     * moved entry and exitcode to ncgutil and cgobj
     * foreach gets extra argument for passing local data to the
       iterator function

+ 8 - 2
compiler/i386/daopt386.pas

@@ -1616,7 +1616,7 @@ Begin
 End;
 
 
-Procedure ReadRef(p: PTaiProp; Const Ref: POperReference);
+Procedure ReadRef(p: PTaiProp; Const Ref: PReference);
 Begin
   If Ref^.Base <> R_NO Then
     ReadReg(p, Ref^.Base);
@@ -2591,7 +2591,13 @@ End.
 
 {
   $Log$
-  Revision 1.34  2002-05-12 16:53:16  peter
+  Revision 1.35  2002-05-14 17:28:09  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.34  2002/05/12 16:53:16  peter
     * moved entry and exitcode to ncgutil and cgobj
     * foreach gets extra argument for passing local data to the
       iterator function

+ 50 - 44
compiler/powerpc/cgcpu.pas

@@ -228,14 +228,16 @@ const
 
     procedure tcgppc.a_call_name(list : taasmoutput;const s : string);
 
+      var
+        href : treference;
       begin
  { save our RTOC register value. Only necessary when doing pointer based    }
  { calls or cross TOC calls, but currently done always                      }
-         list.concat(taicpu.op_reg_ref(A_STW,R_RTOC,
-           new_reference(STACK_POINTER_REG,LA_RTOC)));
+         reference_reset_base(href,STACK_POINTER_REG,LA_RTOC);
+         list.concat(taicpu.op_reg_ref(A_STW,R_TOC,href));
          list.concat(taicpu.op_sym(A_BL,newasmsymbol(s)));
-         list.concat(taicpu.op_reg_ref(A_LWZ,R_RTOC,
-           new_reference(STACK_POINTER_REG,LA_RTOC)));
+         reference_reset_base(href,STACK_POINTER_REG,LA_RTOC);
+         list.concat(taicpu.op_reg_ref(A_LWZ,R_TOC,href));
       end;
 
 {********************** load instructions ********************}
@@ -302,19 +304,14 @@ const
          ref2, tmpref: treference;
 
        begin
-         if ref.is_immediate then
-           a_load_const_reg(list,size,ref.offset,reg)
-         else
-           begin
-             ref2 := ref;
-             fixref(list,ref2);
-             op := loadinstr[size,ref2.index<>R_NO,false];
-             a_load_store(list,op,reg,ref2);
-             { sign extend shortint if necessary, since there is no }
-             { load instruction that does that automatically (JM)   }
-             if size = OS_S8 then
-               list.concat(taicpu.op_reg_reg(A_EXTSB,reg,reg));
-          end;
+          ref2 := ref;
+          fixref(list,ref2);
+          op := loadinstr[size,ref2.index<>R_NO,false];
+          a_load_store(list,op,reg,ref2);
+          { sign extend shortint if necessary, since there is no }
+          { load instruction that does that automatically (JM)   }
+          if size = OS_S8 then
+            list.concat(taicpu.op_reg_reg(A_EXTSB,reg,reg));
        end;
 
 
@@ -701,6 +698,7 @@ const
  { combined size of ALL the parameters of a procedure called by the current }
  { one                                                                      }
      var regcounter: TRegister;
+         href : treference;
 
       begin
         if (localsize mod 8) <> 0 then internalerror(58991);
@@ -716,7 +714,8 @@ const
         { save return address... }
         list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_LR));
         { ... in caller's frame }
-        list.concat(taicpu.op_reg_ref(A_STW,R_0,new_reference(STACK_POINTER_REG,4)));
+        reference_reset_base(href,STACK_POINTER_REG,4);
+        list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
         a_reg_dealloc(list,R_0);
         a_reg_alloc(list,R_11);
         { save end of fpr save area }
@@ -761,6 +760,7 @@ const
  { combined size of ALL the parameters of a procedure called by the current }
  { one                                                                      }
      var regcounter: TRegister;
+         href : treference;
 
       begin
         if (localsize mod 8) <> 0 then internalerror(58991);
@@ -776,19 +776,21 @@ const
         { save return address... }
         list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_LR));
         { ... in caller's frame }
-        list.concat(taicpu.op_reg_ref(A_STW,R_0,new_reference(STACK_POINTER_REG,8)));
+        reference_reset_base(href,STACK_POINTER_REG,8);
+        list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
         a_reg_dealloc(list,R_0);
         { save floating-point registers }
         { !!! has to be optimized: only save registers that are used }
         list.concat(taicpu.op_sym_ofs(A_BL,newasmsymbol('_savef14'),0));
         { save gprs in gpr save area }
         { !!! has to be optimized: only save registers that are used }
-        list.concat(taicpu.op_reg_ref(A_STMW,R_13,new_reference(STACK_POINTER_REG,-220)));
+        reference_reset_base(href,STACK_POINTER_REG,-220);
+        list.concat(taicpu.op_reg_ref(A_STMW,R_13,href));
         { save the CR if necessary ( !!! always done currently ) }
         a_reg_alloc(list,R_0);
         list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_CR));
-        list.concat(taicpu.op_reg_ref(A_STW,R_0,
-          new_reference(stack_pointer_reg,LA_CR)));
+        reference_reset_base(href,stack_pointer_reg,LA_CR);
+        list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
         a_reg_dealloc(list,R_0);
         { save pointer to incoming arguments }
         list.concat(taicpu.op_reg_reg_const(A_ORI,R_31,STACK_POINTER_REG,0));
@@ -840,22 +842,20 @@ const
            { reference doesn't have a base, create one                       }
            begin
              tmpreg := get_scratch_reg(list);
-             reset_reference(tmpref);
+             reference_reset(tmpref);
              tmpref.symbol := ref2.symbol;
              tmpref.symaddr := refs_ha;
-             tmpref.is_immediate := true;
+//             tmpref.is_immediate := true;
              if ref2.base <> R_NO then
                list.concat(taicpu.op_reg_reg_ref(A_ADDIS,tmpreg,
-                 ref2.base,newreference(tmpref)))
+                 ref2.base,tmpref))
              else
-               list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,
-                  newreference(tmpref)));
+               list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,tmpref));
              ref2.base := tmpreg;
              ref2.symaddr := refs_l;
              { can be folded with one of the next instructions by the }
              { optimizer probably                                     }
-             list.concat(taicpu.op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,
-                newreference(tmpref)));
+             list.concat(taicpu.op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,tmpref));
            end;
          if ref2.offset <> 0 Then
            if ref2.base <> R_NO then
@@ -890,8 +890,8 @@ const
         fixref(list,src);
         dst := dest;
         fixref(list,dst);
-        reset_reference(src);
-        reset_reference(dst);
+        reference_reset(src);
+        reference_reset(dst);
         { load the address of source into src.base }
         src.base := get_scratch_reg(list);
         if loadref then
@@ -922,10 +922,9 @@ const
             a_reg_alloc(list,R_0);
             getlabel(lab);
             a_label(list, lab);
-            list.concat(taicpu.op_reg_ref(A_LWZU,tempreg,
-              newreference(src)));
+            list.concat(taicpu.op_reg_ref(A_LWZU,tempreg,src));
             list.concat(taicpu.op_reg_reg_const(A_CMPI,R_CR0,countreg,0));
-            list.concat(taicpu.op_reg_ref(A_STWU,tempreg,newreference(dst)));
+            list.concat(taicpu.op_reg_ref(A_STWU,tempreg,dst));
             list.concat(taicpu.op_reg_reg_const(A_SUBI,countreg,countreg,1));
             a_jmp(list,A_BC,C_NE,0,lab);
             free_scratch_reg(list,countreg);
@@ -1012,7 +1011,7 @@ const
 
       var
         regcounter: TRegister;
-
+        href : treference;
       begin
         { release parameter registers }
         for regcounter := R_3 to R_10 do
@@ -1022,9 +1021,11 @@ const
         { restore SP }
         list.concat(taicpu.op_reg_reg_const(A_ORI,STACK_POINTER_REG,R_31,0));
         { restore gprs }
-        list.concat(taicpu.op_reg_ref(A_LMW,R_13,new_reference(STACK_POINTER_REG,-220)));
+        reference_reset_base(href,STACK_POINTER_REG,-220);
+        list.concat(taicpu.op_reg_ref(A_LMW,R_13,href));
         { restore return address ... }
-        list.concat(taicpu.op_reg_ref(A_LWZ,R_0,new_reference(STACK_POINTER_REG,8)));
+        reference_reset_base(href,STACK_POINTER_REG,8);
+        list.concat(taicpu.op_reg_ref(A_LWZ,R_0,href));
         { ... and return from _restf14 }
         list.concat(taicpu.op_sym_ofs(A_B,newasmsymbol('_restf14'),0));
       end;
@@ -1137,20 +1138,19 @@ const
         if assigned(ref.symbol) then
           begin
             tmpreg := get_scratch_reg(list);
-            reset_reference(tmpref);
+            reference_reset(tmpref);
             tmpref.symbol := ref.symbol;
             tmpref.symaddr := refs_ha;
-            tmpref.is_immediate := true;
+//            tmpref.is_immediate := true;
             if ref.base <> R_NO then
               list.concat(taicpu.op_reg_reg_ref(A_ADDIS,tmpreg,
-                ref.base,newreference(tmpref)))
+                ref.base,tmpref))
             else
-              list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,
-                 newreference(tmpref)));
+              list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,tmpref));
             ref.base := tmpreg;
             ref.symaddr := refs_l;
           end;
-        list.concat(taicpu.op_reg_ref(op,reg,newreference(ref)));
+        list.concat(taicpu.op_reg_ref(op,reg,ref));
         if assigned(ref.symbol) then
           free_scratch_reg(list,tmpreg);
       end;
@@ -1173,7 +1173,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.14  2002-05-13 19:52:46  peter
+  Revision 1.15  2002-05-14 17:28:10  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.14  2002/05/13 19:52:46  peter
     * a ppcppc can be build again
 
   Revision 1.13  2002/04/20 21:41:51  carl

+ 44 - 127
compiler/powerpc/cpuasm.pas

@@ -31,54 +31,52 @@ uses
   aasm,globals,verbose,
   cpubase;
 
-type
+    type
+      taicpu = class(taicpu_abstract)
+         constructor op_none(op : tasmop);
 
-  taicpu = class(tainstruction)
-     constructor op_none(op : tasmop);
+         constructor op_reg(op : tasmop;_op1 : tregister);
+         constructor op_const(op : tasmop;_op1 : longint);
 
-     constructor op_reg(op : tasmop;_op1 : tregister);
-     constructor op_const(op : tasmop;_op1 : longint);
+         constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
+         constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
+         constructor op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
+         constructor op_const_reg(op:tasmop; _op1: longint; _op2: tregister);
 
-     constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
-     constructor op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
-     constructor op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
-     constructor op_const_reg(op:tasmop; _op1: longint; _op2: tregister);
+         constructor op_const_const(op : tasmop;_op1,_op2 : longint);
 
-     constructor op_const_const(op : tasmop;_op1,_op2 : longint);
+         constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
+         constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
+         constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
+         constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
+         constructor op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister);
+         constructor op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint);
 
-     constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
-     constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
-     constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
-     constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; _op3: preference);
-     constructor op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister);
-     constructor op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint);
+         constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
+         constructor op_reg_bool_reg_reg(op : tasmop;_op1: tregister;_op2:boolean;_op3,_op4:tregister);
+         constructor op_reg_bool_reg_const(op : tasmop;_op1: tregister;_op2:boolean;_op3:tregister;_op4: longint);
 
-     constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
-     constructor op_reg_bool_reg_reg(op : tasmop;_op1: tregister;_op2:boolean;_op3,_op4:tregister);
-     constructor op_reg_bool_reg_const(op : tasmop;_op1: tregister;_op2:boolean;_op3:tregister;_op4: longint);
+         constructor op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : Longint);
 
-     constructor op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : Longint);
 
+         { this is for Jmp instructions }
+         constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
+         constructor op_const_const_sym(op : tasmop;_op1,_op2 : longint;_op3: tasmsymbol);
 
-     { this is for Jmp instructions }
-     constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
-     constructor op_const_const_sym(op : tasmop;_op1,_op2 : longint;_op3: tasmsymbol);
 
+         constructor op_sym(op : tasmop;_op1 : tasmsymbol);
+         constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
+         constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
+         constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
 
-     constructor op_sym(op : tasmop;_op1 : tasmsymbol);
-     constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
-     constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
-     constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;_op2 : preference);
+         procedure loadbool(opidx:longint;_b:boolean);
 
-     procedure loadbool(opidx:longint;_b:boolean);
-     procedure loadconst(opidx:longint;l:longint);
-     procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
-     procedure loadref(opidx:longint;p:preference);
-     procedure loadreg(opidx:longint;r:tregister);
-     procedure loadoper(opidx:longint;o:toper);
+         destructor destroy;override;
+      end;
 
-     destructor destroy;override;
-  end;
+      tai_align = class(tai_align_abstract)
+        { nothing to add }
+      end;
 
     procedure InitAsm;
     procedure DoneAsm;
@@ -90,93 +88,6 @@ implementation
                                  taicpu Constructors
 *****************************************************************************}
 
-    procedure taicpu.loadconst(opidx:longint;l:longint);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        with oper[opidx] do
-         begin
-           if typ=top_ref then
-            disposereference(ref);
-           val:=l;
-           typ:=top_const;
-         end;
-      end;
-
-
-    procedure taicpu.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        with oper[opidx] do
-         begin
-           if typ=top_ref then
-            disposereference(ref);
-           sym:=s;
-           symofs:=sofs;
-           typ:=top_symbol;
-         end;
-        { Mark the symbol as used }
-        if assigned(s) then
-         inc(s.refs);
-      end;
-
-
-    procedure taicpu.loadref(opidx:longint;p:preference);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        with oper[opidx] do
-         begin
-           if typ=top_ref then
-            disposereference(ref);
-           if p^.is_immediate then
-             begin
-{$ifdef REF_IMMEDIATE_WARN}
-               Comment(V_Warning,'Reference immediate');
-{$endif}
-               val:=p^.offset;
-               disposereference(p);
-               typ:=top_const;
-             end
-           else
-             begin
-               ref:=p;
-               typ:=top_ref;
-               { mark symbol as used }
-               if assigned(ref^.symbol) then
-                 inc(ref^.symbol.refs);
-             end;
-         end;
-      end;
-
-
-    procedure taicpu.loadreg(opidx:longint;r:tregister);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        with oper[opidx] do
-         begin
-           if typ=top_ref then
-            disposereference(ref);
-           reg:=r;
-           typ:=top_reg;
-         end;
-      end;
-
-    procedure taicpu.loadoper(opidx:longint;o:toper);
-      begin
-        if opidx>=ops then
-         ops:=opidx+1;
-        if oper[opidx].typ=top_ref then
-          disposereference(oper[opidx].ref);
-        oper[opidx]:=o;
-        { copy also the reference }
-        if oper[opidx].typ=top_ref then
-         oper[opidx].ref:=newreference(o.ref^);
-      end;
-
-
     procedure taicpu.loadbool(opidx:longint;_b:boolean);
       begin
         if opidx>=ops then
@@ -184,7 +95,7 @@ implementation
         with oper[opidx] do
          begin
            if typ=top_ref then
-            disposereference(ref);
+            dispose(ref);
            b:=_b;
            typ:=top_bool;
          end;
@@ -238,7 +149,7 @@ implementation
       end;
 
 
-    constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
+    constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
       begin
          inherited create(op);
          ops:=2;
@@ -283,7 +194,7 @@ implementation
          loadsymbol(0,_op3,_op3ofs);
       end;
 
-     constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister;  _op3: preference);
+     constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
        begin
          inherited create(op);
          ops:=3;
@@ -395,7 +306,7 @@ implementation
       end;
 
 
-    constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;_op2 : preference);
+    constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
       begin
          inherited create(op);
          ops:=2;
@@ -426,7 +337,13 @@ implementation
 end.
 {
   $Log$
-  Revision 1.4  2002-05-13 19:52:46  peter
+  Revision 1.5  2002-05-14 17:28:10  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.4  2002/05/13 19:52:46  peter
     * a ppcppc can be build again
 
   Revision 1.3  2001/12/29 15:28:58  jonas

File diff suppressed because it is too large
+ 436 - 508
compiler/powerpc/cpubase.pas


+ 17 - 86
compiler/powerpc/nppcmat.pas

@@ -80,7 +80,7 @@ implementation
          maybe_save(exprasmlist,right.registers32,left.location,saved);
          secondpass(right);
          maybe_restore(exprasmlist,left.location,saved);
-         set_location(location,left.location);
+         location_copy(location,left.location);
 
          resultreg := R_NO;
          { put numerator in register }
@@ -386,36 +386,8 @@ implementation
          secondpass(left);
          if is_64bitint(left.resulttype.def) then
            begin
-              clear_location(location);
-              location.loc:=LOC_REGISTER;
-              case left.location.loc of
-                LOC_REGISTER, LOC_CREGISTER :
-                  begin
-                    src1 := left.location.registerlow;
-                    src2 := left.location.registerhigh;
-                    if left.location.loc = LOC_REGISTER then
-                      begin
-                        location.registerlow:=src1;
-                        location.registerhigh:=src2;
-                      end
-                    else
-                      begin
-                        location.registerlow := rg.getregisterint(exprasmlist);
-                        location.registerhigh := rg.getregisterint(exprasmlist);
-                      end;
-                  end;
-                LOC_REFERENCE,LOC_CREFERENCE :
-                  begin
-                    reference_release(exprasmlist,left.location.reference);
-                    location.registerlow:=rg.getregisterint(exprasmlist);
-                    src1 := location.registerlow;
-                    location.registerhigh:=rg.getregisterint(exprasmlist);
-                    src2 := location.registerhigh;
-                    tcg64f32(cg).a_load64_ref_reg(exprasmlist,left.location.reference,
-                      location.registerlow,
-                      location.registerhigh);
-                  end;
-              end;
+             location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
+             location_copy(location,left.location);
              exprasmlist.concat(taicpu.op_reg_reg(A_NEG,location.registerlow,
                src1));
              cg.a_op_reg_reg(exprasmlist,OP_NOT,OS_32,src2,location.registerhigh);
@@ -546,36 +518,8 @@ implementation
          else if is_64bitint(left.resulttype.def) then
            begin
              secondpass(left);
-             clear_location(location);
-             location.loc:=LOC_REGISTER;
-             { make sure left is in a register and set the dest register }
-             case left.location.loc of
-               LOC_REFERENCE, LOC_CREFERENCE, LOC_CREGISTER:
-                 begin
-                   location.registerlow := rg.getregisterint(exprasmlist);
-                   location.registerhigh := rg.getregisterint(exprasmlist);
-                   if left.location.loc <> LOC_CREGISTER then
-                     begin
-                       tcg64f32(cg).a_load64_ref_reg(exprasmlist,
-                         left.location.reference,location.registerlow,
-                         location.registerhigh);
-                       regl := location.registerlow;
-                       regh := location.registerhigh;
-                     end
-                   else
-                     begin
-                       regl := left.location.registerlow;
-                       regh := left.location.registerhigh;
-                     end;
-                 end;
-               LOC_REGISTER:
-                 begin
-                   regl := left.location.registerlow;
-                   location.registerlow := regl;
-                   regh := left.location.registerhigh;
-                   location.registerhigh := regh;
-                 end;
-             end;
+             location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
+             location_copy(location,left.location);
              { perform the NOT operation }
              exprasmlist.concat(taicpu.op_reg_reg(A_NOT,location.registerhigh,
                regh));
@@ -585,32 +529,13 @@ implementation
          else
            begin
              secondpass(left);
-             clear_location(location);
-             location.loc:=LOC_REGISTER;
-             { make sure left is in a register and set the dest register }
-             case left.location.loc of
-               LOC_REFERENCE, LOC_CREFERENCE, LOC_CREGISTER:
-                 begin
-                   location.register := rg.getregisterint(exprasmlist);
-                   if left.location.loc <> LOC_CREGISTER then
-                     begin
-                       cg.a_load_ref_reg(exprasmlist,
-                         def_cgsize(left.resulttype.def),
-                         left.location.reference,location.register);
-                       regl := location.register;
-                     end
-                   else
-                     regl := left.location.register;
-                 end;
-               LOC_REGISTER:
-                 regl := left.location.register;
-             end;
+             location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
+             location_copy(location,left.location);
+             if location.loc=LOC_CREGISTER then
+              location.register := rg.getregisterint(exprasmlist);
              { perform the NOT operation }
              exprasmlist.concat(taicpu.op_reg_reg(A_NOT,location.register,
-               regl));
-             { release the source reg if it wasn't reused }
-             if regl <> location.register then
-               rg.ungetregisterint(exprasmlist,regl);
+               left.location.register));
           end;
       end;
 
@@ -622,7 +547,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.5  2002-05-13 19:52:46  peter
+  Revision 1.6  2002-05-14 17:28:10  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.5  2002/05/13 19:52:46  peter
     * a ppcppc can be build again
 
   Revision 1.4  2002/04/21 15:48:39  carl

+ 14 - 2
compiler/rautils.pas

@@ -716,7 +716,13 @@ begin
       2 : size:=S_W{ could be S_IS};
       4 : size:=S_L{ could be S_IL or S_FS};
       8 : size:=S_IQ{ could be S_D or S_FL};
-      extended_size : size:=S_FX;
+     else
+      begin
+        { extended_size can also be 8, resulting in a
+          duplicate label }
+        if _size=extended_size then
+          size:=S_FX;
+      end;
      end;
    end;
 end;
@@ -1585,7 +1591,13 @@ end;
 end.
 {
   $Log$
-  Revision 1.31  2002-05-12 16:53:10  peter
+  Revision 1.32  2002-05-14 17:28:09  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.31  2002/05/12 16:53:10  peter
     * moved entry and exitcode to ncgutil and cgobj
     * foreach gets extra argument for passing local data to the
       iterator function

+ 103 - 47
compiler/tainst.pas

@@ -26,36 +26,49 @@ Unit tainst;
 
 interface
 
-  Uses aasm,cpubase,cpuinfo,cclasses;
-
-Type
-
-  tairegalloc = class(tai)
-     allocation : boolean;
-     reg        : tregister;
-     constructor alloc(r : tregister);
-     constructor dealloc(r : tregister);
-  end;
-
-  tainstruction = class(tai)
-    condition : TAsmCond;
-    ops       : longint;
-    oper      : array[0..max_operands-1] of toper;
-    opcode    : tasmop;
+    Uses
+      cpuinfo,cpubase,aasm,cclasses;
+
+    Type
+      tairegalloc = class(tai)
+         allocation : boolean;
+         reg        : tregister;
+         constructor alloc(r : tregister);
+         constructor dealloc(r : tregister);
+      end;
+
+      taicpu_abstract = class(tai)
+        condition : TAsmCond;
+        ops       : longint;
+        oper      : array[0..max_operands-1] of toper;
+        opcode    : tasmop;
 {$ifdef i386}
-    segprefix : tregister;
+        segprefix : tregister;
 {$endif i386}
-    is_jmp    : boolean; { is this instruction a jump? (needed for optimizer) }
-    Constructor Create(op : tasmop);
-    Destructor Destroy;override;
-    function getcopy:tlinkedlistitem;override;
-    procedure loadconst(opidx:longint;l:aword);
-    procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
-    procedure loadref(opidx:longint;const r:treference);
-    procedure loadreg(opidx:longint;r:tregister);
-    procedure loadoper(opidx:longint;o:toper);
-    procedure SetCondition(const c:TAsmCond);
-  end;
+        is_jmp    : boolean; { is this instruction a jump? (needed for optimizer) }
+        Constructor Create(op : tasmop);
+        Destructor Destroy;override;
+        function getcopy:tlinkedlistitem;override;
+        procedure loadconst(opidx:longint;l:aword);
+        procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
+        procedure loadref(opidx:longint;const r:treference);
+        procedure loadreg(opidx:longint;r:tregister);
+        procedure loadoper(opidx:longint;o:toper);
+        procedure SetCondition(const c:TAsmCond);
+      end;
+
+      { alignment for operator }
+      tai_align_abstract = class(tai)
+         buf       : array[0..63] of char; { buf used for fill }
+         aligntype : byte;   { 1 = no align, 2 = word align, 4 = dword align }
+         fillsize  : byte;   { real size to fill }
+         fillop    : byte;   { value to fill with - optional }
+         use_op    : boolean;
+         constructor Create(b:byte);
+         constructor Create_op(b: byte; _op: byte);
+         function getfillbuf:pchar;virtual;
+      end;
+
 
 implementation
 
@@ -84,13 +97,12 @@ implementation
         reg:=r;
       end;
 
-{ ---------------------------------------------------------------------
-    TaInstruction Constructor/Destructor
-  ---------------------------------------------------------------------}
-
 
+{*****************************************************************************
+                               TaiInstruction
+*****************************************************************************}
 
-    constructor Tainstruction.Create(op : tasmop);
+    constructor taicpu_abstract.Create(op : tasmop);
 
       begin
          inherited create;
@@ -104,7 +116,7 @@ implementation
 
 
 
-    destructor Tainstruction.Destroy;
+    destructor taicpu_abstract.Destroy;
 
       var
         i : longint;
@@ -127,7 +139,7 @@ implementation
 
 
 
-    procedure tainstruction.loadconst(opidx:longint;l:aword);
+    procedure taicpu_abstract.loadconst(opidx:longint;l:aword);
       begin
         if opidx>=ops then
          ops:=opidx+1;
@@ -142,7 +154,7 @@ implementation
 
 
 
-    procedure tainstruction.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
+    procedure taicpu_abstract.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
       begin
         if not assigned(s) then
          internalerror(200204251);
@@ -161,7 +173,7 @@ implementation
 
 
 
-    procedure tainstruction.loadref(opidx:longint;const r:treference);
+    procedure taicpu_abstract.loadref(opidx:longint;const r:treference);
       begin
         if opidx>=ops then
          ops:=opidx+1;
@@ -185,7 +197,7 @@ implementation
 
 
 
-    procedure tainstruction.loadreg(opidx:longint;r:tregister);
+    procedure taicpu_abstract.loadreg(opidx:longint;r:tregister);
       begin
         if opidx>=ops then
          ops:=opidx+1;
@@ -200,7 +212,7 @@ implementation
 
 
 
-    procedure tainstruction.loadoper(opidx:longint;o:toper);
+    procedure taicpu_abstract.loadoper(opidx:longint;o:toper);
       begin
         if opidx>=ops then
          ops:=opidx+1;
@@ -220,13 +232,13 @@ implementation
     Miscellaneous methods.
   ---------------------------------------------------------------------}
 
-    procedure tainstruction.SetCondition(const c:TAsmCond);
+    procedure taicpu_abstract.SetCondition(const c:TAsmCond);
       begin
          condition:=c;
       end;
 
 
-    Function tainstruction.getcopy:tlinkedlistitem;
+    Function taicpu_abstract.getcopy:tlinkedlistitem;
       var
         i : longint;
         p : tlinkedlistitem;
@@ -234,19 +246,63 @@ implementation
         p:=inherited getcopy;
         { make a copy of the references }
         for i:=1 to ops do
-         if (tainstruction(p).oper[i-1].typ=top_ref) then
+         if (taicpu_abstract(p).oper[i-1].typ=top_ref) then
           begin
-            new(tainstruction(p).oper[i-1].ref);
-            tainstruction(p).oper[i-1].ref^:=oper[i-1].ref^;
+            new(taicpu_abstract(p).oper[i-1].ref);
+            taicpu_abstract(p).oper[i-1].ref^:=oper[i-1].ref^;
           end;
         getcopy:=p;
       end;
 
+{****************************************************************************
+                              tai_align_abstract
+ ****************************************************************************}
+
+     constructor tai_align_abstract.Create(b: byte);
+       begin
+          inherited Create;
+          typ:=ait_align;
+          if b in [1,2,4,8,16,32] then
+            aligntype := b
+          else
+            aligntype := 1;
+          fillsize:=0;
+          fillop:=0;
+          use_op:=false;
+       end;
+
+
+     constructor tai_align_abstract.Create_op(b: byte; _op: byte);
+       begin
+          inherited Create;
+          typ:=ait_align;
+          if b in [1,2,4,8,16,32] then
+            aligntype := b
+          else
+            aligntype := 1;
+          fillsize:=0;
+          fillop:=_op;
+          use_op:=true;
+          fillchar(buf,sizeof(buf),_op)
+       end;
+
+
+     function tai_align_abstract.getfillbuf:pchar;
+       begin
+         getfillbuf:=@buf;
+       end;
+
 end.
 
 {
   $Log$
-  Revision 1.5  2002-04-25 20:16:39  peter
+  Revision 1.6  2002-05-14 17:28:09  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.5  2002/04/25 20:16:39  peter
     * moved more routines from cga/n386util
 
   Revision 1.4  2002/04/02 17:11:32  peter
@@ -288,13 +344,13 @@ end.
       because on powerpc it's a record now
 
   Revision 1.3  1999/08/26 14:52:59  jonas
-    * added segprefix field for i386 in tainstruction object
+    * added segprefix field for i386 in taicpu_abstract object
 
   Revision 1.2  1999/08/06 16:38:37  jonas
     * declared getcopy virtual, since it's already declared as such
       in cobjects.pas (FPC doesn't error on that, TP does)
 
   Revision 1.1  1999/08/06 16:04:05  michael
-  + introduced tainstruction
+  + introduced taicpu_abstract
 
 }

+ 68 - 13
compiler/targets/t_linux.pas

@@ -3,7 +3,7 @@
     Copyright (c) 1998-2000 by Peter Vreman
 
     This unit implements support import,export,link routines
-    for the (i386) Linux target
+    for the Linux targets
 
     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
@@ -64,7 +64,11 @@ implementation
     cutils,cclasses,
     verbose,systems,globtype,globals,
     symconst,script,
-    fmodule,aasm,cpuasm,cpubase,symsym;
+    fmodule,symsym
+{$ifdef i386}
+    ,aasm,cpuasm,cpubase
+{$endif i386}
+    ;
 
 {*****************************************************************************
                                TIMPORTLIBLINUX
@@ -588,8 +592,23 @@ end;
             res          : res_none;
             script       : script_unix;
             endian       : endian_big;
-            stackalignment : 2;
-            maxCrecordalignment : 32;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 4;
+                varalignmin     : 0;
+                varalignmax     : 4;
+                localalignmin   : 0;
+                localalignmax   : 4;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
+            first_parm_offset : 8;
             heapsize     : 128*1024;
             stacksize    : 32*1024*1024;
             DllScanSupported:false;
@@ -605,7 +624,6 @@ end;
             shortname    : 'linuxppc';
             flags        : [];
             cpu          : cpu_powerpc;
-            short_name   : 'LINUX';
             unit_env     : '';
             extradefines : 'UNIX';
             sourceext    : '.pp';
@@ -633,13 +651,30 @@ end;
             dirsep       : '/';
             files_case_relevent : true;
             assem        : as_powerpc_as;
-            assemsrc     : as_powerpc_as;
-            ar           : ar_powerpc_ar;
+            assemextern  : as_powerpc_as;
+            link         : ld_powerpc_linux;
+            linkextern   : ld_powerpc_linux;
+            ar           : ar_gnu_ar;
             res          : res_none;
             script       : script_unix;
             endian       : endian_big;
-            stackalignment : 8;
-            maxCrecordalignment : 32;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 4;
+                varalignmin     : 0;
+                varalignmax     : 4;
+                localalignmin   : 0;
+                localalignmax   : 4;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
+            first_parm_offset : 8;
             heapsize     : 256*1024;
             stacksize    : 32*1024*1024;
             DllScanSupported:false;
@@ -690,9 +725,23 @@ end;
             res          : res_none;
             script       : script_unix;
             endian       : endian_little;
-            stackalignment : 8;
-            maxCrecordalignment : 32;
-            size_of_longint : 4;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                constalignmin   : 0;
+                constalignmax   : 4;
+                varalignmin     : 0;
+                varalignmax     : 4;
+                localalignmin   : 0;
+                localalignmax   : 4;
+                paraalign       : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 2;
+                maxCrecordalign : 4
+              );
+            first_parm_offset : 8;
             heapsize     : 256*1024;
             stacksize    : 32*1024*1024;
             DllScanSupported:false;
@@ -800,7 +849,13 @@ initialization
 end.
 {
   $Log$
-  Revision 1.22  2002-05-06 19:46:36  carl
+  Revision 1.23  2002-05-14 17:28:10  peter
+    * synchronized cpubase between powerpc and i386
+    * moved more tables from cpubase to cpuasm
+    * tai_align_abstract moved to tainst, cpuasm must define
+      the tai_align class now, which may be empty
+
+  Revision 1.22  2002/05/06 19:46:36  carl
   + added more patches from Mazen for SPARC port
 
   Revision 1.21  2002/04/22 18:19:22  carl

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