ソースを参照

* factered WriteInstruction out of TGNUAssembler into its own class
* put Apple-specific GNU assembler stuff in its own class
+ darwin/x86 support to the assembler writer

git-svn-id: trunk@2818 -

Jonas Maebe 19 年 前
コミット
ba6f1e4990

+ 93 - 14
compiler/aggas.pas

@@ -41,29 +41,51 @@ interface
 
 
     type
+      TCPUInstrWriter = class;
       {# This is a derived class which is used to write
          GAS styled assembler.
-
-         The WriteInstruction() method must be overriden
-         to write a single instruction to the assembler
-         file.
       }
       TGNUAssembler=class(texternalassembler)
       protected
         function sectionname(atype:TAsmSectiontype;const aname:string):string;virtual;
         procedure WriteSection(atype:TAsmSectiontype;const aname:string);
         procedure WriteExtraHeader;virtual;
-        procedure WriteInstruction(hp: tai);  virtual; abstract;
-      public
+        procedure WriteInstruction(hp: tai);{$ifdef USEINLINE}inline;{$endif}
+       public
         procedure WriteTree(p:TAAsmoutput);override;
         procedure WriteAsmList;override;
-      private
+        destructor destroy; override;
+       private
         setcount: longint;
         procedure WriteDecodedSleb128(a: aint);
         procedure WriteDecodedUleb128(a: aword);
         function NextSetLabel: string;
+       protected
+        InstrWriter: TCPUInstrWriter;
       end;
 
+
+      {# This is the base class for writing instructions.
+
+         The WriteInstruction() method must be overriden
+         to write a single instruction to the assembler
+         file.
+      }
+      TCPUInstrWriter = class
+        constructor create(_owner: TGNUAssembler);
+        procedure WriteInstruction(hp : tai); virtual; abstract;
+       protected
+        owner: TGNUAssembler;
+      end;
+
+
+      TAppleGNUAssembler=class(TGNUAssembler)
+        function sectionname(atype:TAsmSectiontype;const aname:string):string;override;
+       private
+        debugframecount: aint;
+       end;
+
+
 implementation
 
     uses
@@ -195,6 +217,13 @@ implementation
 {                          GNU Assembler writer                              }
 {****************************************************************************}
 
+    destructor TGNUAssembler.Destroy;
+      begin
+        InstrWriter.free;
+        inherited destroy;
+      end;
+
+
     function TGNUAssembler.NextSetLabel: string;
       begin
         inc(setcount);
@@ -210,7 +239,7 @@ implementation
           '.data',
           '.bss',
           '.threadvar',
-          '__TEXT', { stubs }
+          '', { stubs }
           '.stab',
           '.stabstr',
           '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
@@ -225,7 +254,7 @@ implementation
           '.data.rel',
           '.bss',
           '.threadvar',
-          '__TEXT', { stubs }
+          '', { stubs }
           '.stab',
           '.stabstr',
           '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
@@ -262,13 +291,13 @@ implementation
         AsmLn;
         case target_info.system of
          system_i386_OS2,
-         system_i386_EMX : ;
+         system_i386_EMX: ;
          system_powerpc_darwin,
          system_i386_darwin:
            begin
-             if atype=sec_stub then
+             if (atype = sec_stub) then
                AsmWrite('.section ');
-           end;
+           end
          else
           AsmWrite('.section ');
         end;
@@ -279,8 +308,17 @@ implementation
             AsmWrite(', "a", @progbits');
           sec_stub :
             begin
-              if (target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
-                AsmWrite(',__symbol_stub1,symbol_stubs,pure_instructions,16');
+              case target_info.system of
+                { there are processor-independent shortcuts available    }
+                { for this, namely .symbol_stub and .picsymbol_stub, but }
+                { they don't work and gcc doesn't use them either...     }
+                system_powerpc_darwin:
+                  AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
+                system_i386_darwin:
+                  AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
+                else
+                  internalerror(2006031101);
+              end;
             end;
         end;
         AsmLn;
@@ -958,10 +996,16 @@ implementation
 
 
     procedure TGNUAssembler.WriteExtraHeader;
+      begin
+      end;
+
 
+    procedure TGNUAssembler.WriteInstruction(hp: tai);{$ifdef USEINLINE}inline;{$endif}
       begin
+        InstrWriter.WriteInstruction(hp);
       end;
 
+
     procedure TGNUAssembler.WriteAsmList;
     var
       p:dirstr;
@@ -1014,4 +1058,39 @@ implementation
 {$endif EXTDEBUG}
     end;
 
+
+{****************************************************************************}
+{                        Apple/GNU Assembler writer                          }
+{****************************************************************************}
+
+    function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string):string;
+      begin
+        if (target_info.system in [system_powerpc_darwin,system_i386_darwin]) then
+          case atype of
+            sec_bss:
+              { all bss (lcomm) symbols are automatically put in the right }
+              { place by using the lcomm assembler directive               }
+              atype := sec_none;
+            sec_debug_frame,
+            sec_eh_frame:
+              begin
+                result := '.section __DWARFA,__debug_frame,coalesced,no_toc+strip_static_syms'#10'EH_frame'+tostr(debugframecount)+':';
+                inc(debugframecount);
+                exit;
+              end;
+          end;
+        result := inherited sectionname(atype,aname);
+      end;
+
+
+{****************************************************************************}
+{                        Abstract Instruction Writer                         }
+{****************************************************************************}
+
+     constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
+       begin
+         inherited create;
+         owner := _owner;
+       end;
+
 end.

+ 36 - 16
compiler/arm/agarmgas.pas

@@ -34,11 +34,15 @@ unit agarmgas;
        cpubase;
 
     type
-      PARMGNUAssembler=^TARMGNUAssembler;
       TARMGNUAssembler=class(TGNUassembler)
-        procedure WriteInstruction(hp : tai);override;
+        constructor create(smart: boolean); override;
       end;
 
+     TArmInstrWriter=class(TCPUInstrWriter)
+        procedure WriteInstruction(hp : tai);override;
+     end;
+
+
     const
       gas_shiftmode2str : array[tshiftmode] of string[3] = (
         '','lsl','lsr','asr','ror','rrx');
@@ -53,19 +57,20 @@ unit agarmgas;
        itcpugas,
        cgbase,cgutils;
 
-    const
-       as_arm_gas_info : tasminfo =
-          (
-            id     : as_gas;
+{****************************************************************************}
+{                         GNU Arm Assembler writer                           }
+{****************************************************************************}
 
-            idtxt  : 'AS';
-            asmbin : 'as';
-            asmcmd : '-o $OBJ $ASM';
-            supported_target : system_any;
-            flags : [af_allowdirect,af_needar,af_smartlink_sections];
-            labelprefix : '.L';
-            comment : '# ';
-          );
+    constructor TArmGNUAssembler.create(smart: boolean);
+      begin
+        inherited create(smart);
+        InstrWriter := TArmInstrWriter.create(self);
+      end;
+
+
+{****************************************************************************}
+{                  Helper routines for Instruction Writer                    }
+{****************************************************************************}
 
     function getreferencestring(var ref : treference) : string;
       var
@@ -179,7 +184,7 @@ unit agarmgas;
       end;
 
 
-    Procedure TARMGNUAssembler.WriteInstruction(hp : tai);
+    Procedure TArmInstrWriter.WriteInstruction(hp : tai);
     var op: TAsmOp;
         s: string;
         i: byte;
@@ -228,10 +233,25 @@ unit agarmgas;
                sep:=',';
             end;
         end;
-      AsmWriteLn(s);
+      owner.AsmWriteLn(s);
     end;
 
 
+    const
+       as_arm_gas_info : tasminfo =
+          (
+            id     : as_gas;
+
+            idtxt  : 'AS';
+            asmbin : 'as';
+            asmcmd : '-o $OBJ $ASM';
+            supported_target : system_any;
+            flags : [af_allowdirect,af_needar,af_smartlink_sections];
+            labelprefix : '.L';
+            comment : '# ';
+          );
+
+
 begin
   RegisterAssembler(as_arm_gas_info,TARMGNUAssembler);
 end.

+ 80 - 63
compiler/powerpc/agppcgas.pas

@@ -36,15 +36,20 @@ unit agppcgas;
        globtype;
 
     type
-      PPPCGNUAssembler=^TPPCGNUAssembler;
       TPPCGNUAssembler=class(TGNUassembler)
-        function sectionname(atype:TAsmSectiontype;const aname:string):string;override;
+        constructor create(smart: boolean); override;
         procedure WriteExtraHeader;override;
-        procedure WriteInstruction(hp : tai);override;
-       private
-        debugframecount: aint;
       end;
 
+      TPPCAppleGNUAssembler=class(TAppleGNUassembler)
+        constructor create(smart: boolean); override;
+      end;
+
+
+     TPPCInstrWriter=class(TCPUInstrWriter)
+        procedure WriteInstruction(hp : tai);override;
+     end;
+
 
   implementation
 
@@ -55,71 +60,46 @@ unit agppcgas;
        itcpugas,
        aasmcpu;
 
+{****************************************************************************}
+{                         GNU PPC Assembler writer                           }
+{****************************************************************************}
+
+    constructor TPPCGNUAssembler.create(smart: boolean);
+      begin
+        inherited create(smart);
+        InstrWriter := TPPCInstrWriter.create(self);
+      end;
+
+
     procedure TPPCGNUAssembler.WriteExtraHeader;
       var
          i : longint;
       begin
-         if (target_info.system <> system_powerpc_darwin) then
-           begin
-             for i:=0 to 31 do
-               AsmWriteln(#9'.set'#9'r'+tostr(i)+','+tostr(i));
-             for i:=0 to 31 do
-               AsmWriteln(#9'.set'#9'f'+tostr(i)+','+tostr(i));
-           end;
+        for i:=0 to 31 do
+          AsmWriteln(#9'.set'#9'r'+tostr(i)+','+tostr(i));
+        for i:=0 to 31 do
+          AsmWriteln(#9'.set'#9'f'+tostr(i)+','+tostr(i));
       end;
 
-    const
-       as_ppc_gas_info : tasminfo =
-          (
-            id     : as_gas;
-
-            idtxt  : 'AS';
-            asmbin : 'as';
-            asmcmd : '-o $OBJ $ASM';
-            supported_target : system_any;
-            flags : [af_allowdirect,af_needar,af_smartlink_sections];
-            labelprefix : '.L';
-            comment : '# ';
-          );
-
-
-       as_ppc_gas_darwin_powerpc_info : tasminfo =
-          (
-            id     : as_darwin;
-
-            idtxt  : 'AS-Darwin';
-            asmbin : 'as';
-            asmcmd : '-o $OBJ $ASM -arch ppc';
-            supported_target : system_any;
-            flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
-            labelprefix : 'L';
-            comment : '# ';
-          );
 
+{****************************************************************************}
+{                      GNU/Apple PPC Assembler writer                        }
+{****************************************************************************}
 
-       refaddr2str: array[trefaddr] of string[3] = ('','','@ha','@l','');
-       refaddr2str_darwin: array[trefaddr] of string[4] = ('','','ha16','lo16','');
+    constructor TPPCAppleGNUAssembler.create(smart: boolean);
+      begin
+        inherited create(smart);
+        InstrWriter := TPPCInstrWriter.create(self);
+      end;
 
 
+{****************************************************************************}
+{                  Helper routines for Instruction Writer                    }
+{****************************************************************************}
 
-    function TPPCGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string):string;
-      begin
-        if (target_info.system = system_powerpc_darwin) then
-          case atype of
-            sec_bss:
-              { all bss (lcomm) symbols are automatically put in the right }
-              { place by using the lcomm assembler directive               }
-              atype := sec_none;
-            sec_debug_frame,
-            sec_eh_frame:
-              begin
-                result := '.section __DWARFA,__debug_frame,coalesced,no_toc+strip_static_syms'#10'EH_frame'+tostr(debugframecount)+':';
-                inc(debugframecount);
-                exit;
-              end;
-          end;
-        result := inherited sectionname(atype,aname);
-      end;
+  const
+    refaddr2str: array[trefaddr] of string[3] = ('','','@ha','@l','');
+    refaddr2str_darwin: array[trefaddr] of string[4] = ('','','ha16','lo16','');
 
 
     function getreferencestring(var ref : treference) : string;
@@ -322,7 +302,12 @@ unit agppcgas;
       end;
     end;
 
-    Procedure TPPCGNUAssembler.WriteInstruction(hp : tai);
+
+{****************************************************************************}
+{                        PowerPC Instruction Writer                          }
+{****************************************************************************}
+
+    Procedure TPPCInstrWriter.WriteInstruction(hp : tai);
     var op: TAsmOp;
         s: string;
         i: byte;
@@ -350,7 +335,7 @@ unit agppcgas;
             begin
               { first write the current contents of s, because the symbol }
               { may be 255 characters                                     }
-              asmwrite(s);
+              owner.asmwrite(s);
               s:=getopstr_jmp(taicpu(hp).oper[0]^);
             end;
         end
@@ -376,10 +361,42 @@ unit agppcgas;
                 end;
             end;
         end;
-      AsmWriteLn(s);
+      owner.AsmWriteLn(s);
     end;
 
+{*****************************************************************************
+                                  Initialize
+*****************************************************************************}
+
+    const
+       as_ppc_gas_info : tasminfo =
+          (
+            id     : as_gas;
+
+            idtxt  : 'AS';
+            asmbin : 'as';
+            asmcmd : '-o $OBJ $ASM';
+            supported_target : system_any;
+            flags : [af_allowdirect,af_needar,af_smartlink_sections];
+            labelprefix : '.L';
+            comment : '# ';
+          );
+
+
+       as_ppc_gas_darwin_powerpc_info : tasminfo =
+          (
+            id     : as_darwin;
+
+            idtxt  : 'AS-Darwin';
+            asmbin : 'as';
+            asmcmd : '-o $OBJ $ASM -arch ppc';
+            supported_target : system_any;
+            flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
+            labelprefix : 'L';
+            comment : '# ';
+          );
+
 begin
   RegisterAssembler(as_ppc_gas_info,TPPCGNUAssembler);
-  RegisterAssembler(as_ppc_gas_darwin_powerpc_info,TPPCGNUAssembler);
+  RegisterAssembler(as_ppc_gas_darwin_powerpc_info,TPPCAppleGNUAssembler);
 end.

+ 43 - 17
compiler/powerpc64/agppcgas.pas

@@ -35,13 +35,17 @@ uses
   cpubase;
 
 type
-  PPPCGNUAssembler = ^TPPCGNUAssembler;
   TPPCGNUAssembler = class(TGNUassembler)
   public
+    constructor create(smart: boolean); override;
     procedure WriteExtraHeader; override;
+  end;
+
+  TPPCInstrWriter = class(TCPUInstrWriter)
     procedure WriteInstruction(hp: tai); override;
   end;
 
+
 implementation
 
 uses
@@ -52,6 +56,17 @@ uses
   aasmcpu;
 
 
+{****************************************************************************}
+{                         GNU PPC Assembler writer                           }
+{****************************************************************************}
+
+constructor TPPCGNUAssembler.create(smart: boolean);
+  begin
+    inherited create(smart);
+    InstrWriter := TPPCInstrWriter.create(self);
+  end;
+
+
 procedure TPPCGNUAssembler.WriteExtraHeader;
 var
   i: longint;
@@ -62,20 +77,11 @@ begin
     AsmWriteln(#9'.set'#9'f' + tostr(i) + ',' + tostr(i));
 end;
 
-const
-  as_ppc_gas_info: tasminfo =
-  (
-    id: as_gas;
-
-    idtxt: 'AS';
-    asmbin: 'as';
-    asmcmd: '-a64 -o $OBJ $ASM';
-    supported_target: system_any;
-    flags: [af_allowdirect, af_needar, af_smartlink_sections];
-    labelprefix: '.L';
-    comment: '# ';
-    );
+{****************************************************************************}
+{                  Helper routines for Instruction Writer                    }
+{****************************************************************************}
 
+const
   refaddr2str: array[trefaddr] of string[9] = ('', '', '', '@l', '@h', '@higher', '@highest', '@ha', '@highera', '@highesta');
 
 function getreferencestring(var ref: treference): string;
@@ -273,7 +279,12 @@ begin
   end;
 end;
 
-procedure TPPCGNUAssembler.WriteInstruction(hp: tai);
+
+{****************************************************************************}
+{                        PowerPC Instruction Writer                          }
+{****************************************************************************}
+
+procedure TPPCInstrWriter.WriteInstruction(hp: tai);
 var
   op: TAsmOp;
   s: string;
@@ -304,7 +315,7 @@ begin
     begin
       { first write the current contents of s, because the symbol }
       { may be 255 characters                                     }
-      asmwrite(s);
+      owner.AsmWrite(s);
       s := getopstr_jmp(taicpu(hp).oper[0]^);
     end;
   end
@@ -330,10 +341,25 @@ begin
       end;
     end;
   end;
-  AsmWriteLn(s);
+  owner.AsmWriteLn(s);
 end;
 
 
+const
+  as_ppc_gas_info: tasminfo =
+  (
+    id: as_gas;
+
+    idtxt: 'AS';
+    asmbin: 'as';
+    asmcmd: '-a64 -o $OBJ $ASM';
+    supported_target: system_any;
+    flags: [af_allowdirect, af_needar, af_smartlink_sections];
+    labelprefix: '.L';
+    comment: '# ';
+    );
+
+
 begin
   RegisterAssembler(as_ppc_gas_info, TPPCGNUAssembler);
 end.

+ 22 - 7
compiler/sparc/cpugas.pas

@@ -31,9 +31,13 @@ interface
 
     type
       TGasSPARC=class(TGnuAssembler)
-        procedure WriteInstruction(hp:Tai);override;
+        constructor create(smart: boolean); override;
       end;
 
+     TSPARCInstrWriter=class(TCPUInstrWriter)
+       procedure WriteInstruction(hp:Tai);override;
+     end;
+
 implementation
 
     uses
@@ -41,6 +45,17 @@ implementation
       verbose,itcpugas,cgbase,cgutils;
 
 
+{****************************************************************************}
+{                         GNU PPC Assembler writer                           }
+{****************************************************************************}
+
+    constructor TGasSPARC.create(smart: boolean);
+      begin
+        inherited create(smart);
+        InstrWriter := TSPARCInstrWriter.create(self);
+      end;
+
+
     function GetReferenceString(var ref:TReference):string;
       begin
         GetReferenceString:='';
@@ -123,7 +138,7 @@ implementation
         end;
 
 
-    procedure TGasSPARC.WriteInstruction(hp:Tai);
+    procedure TSPARCInstrWriter.WriteInstruction(hp:Tai);
       var
         Op:TAsmOp;
         s:String;
@@ -143,14 +158,14 @@ implementation
                 internalerror(200401045);
               { FABSs %f<even>,%f<even> }
               s:=#9+std_op2str[A_FABSs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
-              AsmWriteLn(s);
+              owner.AsmWriteLn(s);
               { FMOVs %f<odd>,%f<odd> }
               inc(taicpu(hp).oper[0]^.reg);
               inc(taicpu(hp).oper[1]^.reg);
               s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
               dec(taicpu(hp).oper[0]^.reg);
               dec(taicpu(hp).oper[1]^.reg);
-              AsmWriteLn(s);
+              owner.AsmWriteLn(s);
             end;
           A_FMOVd:
             begin
@@ -160,14 +175,14 @@ implementation
                 internalerror(200401045);
               { FMOVs %f<even>,%f<even> }
               s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
-              AsmWriteLn(s);
+              owner.AsmWriteLn(s);
               { FMOVs %f<odd>,%f<odd> }
               inc(taicpu(hp).oper[0]^.reg);
               inc(taicpu(hp).oper[1]^.reg);
               s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
               dec(taicpu(hp).oper[0]^.reg);
               dec(taicpu(hp).oper[1]^.reg);
-              AsmWriteLn(s);
+              owner.AsmWriteLn(s);
             end
           else
             begin
@@ -181,7 +196,7 @@ implementation
                   for i:=1 to taicpu(hp).ops-1 do
                     s:=s+','+getopstr(taicpu(hp).oper[i]^);
                 end;
-              AsmWriteLn(s);
+              owner.AsmWriteLn(s);
             end;
         end;
       end;

+ 93 - 47
compiler/x86/agx86att.pas

@@ -34,14 +34,24 @@ interface
 
     type
       Tx86ATTAssembler=class(TGNUassembler)
-      private
+        constructor create(smart: boolean); override;
+      end;
+
+      Tx86AppleGNUAssembler=class(TAppleGNUassembler)
+        constructor create(smart: boolean); override;
+      end;
+
+
+     Tx86InstrWriter=class(TCPUInstrWriter)
+       private
         procedure WriteReference(var ref : treference);
         procedure WriteOper(const o:toper);
         procedure WriteOper_jmp(const o:toper);
-      public
+       public
         procedure WriteInstruction(hp: tai);override;
-      end;
+     end;
 
+      
 
   implementation
 
@@ -54,125 +64,145 @@ interface
 
 
 {****************************************************************************
-                            TX86ATTASMOUTPUT
+                            Tx86ATTAssembler
  ****************************************************************************}
 
-    procedure Tx86AttAssembler.WriteReference(var ref : treference);
+    constructor Tx86ATTAssembler.create(smart: boolean);
+      begin
+        inherited create(smart);
+        InstrWriter := Tx86InstrWriter.create(self);
+      end;
+
+{****************************************************************************
+                          Tx86AppleGNUAssembler
+ ****************************************************************************}
+
+    constructor Tx86AppleGNUAssembler.create(smart: boolean);
+      begin
+        inherited create(smart);
+        InstrWriter := Tx86InstrWriter.create(self);
+      end;
+
+{****************************************************************************
+                            Tx86InstrWriter
+ ****************************************************************************}
+
+    procedure Tx86InstrWriter.WriteReference(var ref : treference);
       begin
         with ref do
          begin
-           { have we a segment prefix ? }
+           { do we have a segment prefix ? }
            { These are probably not correctly handled under GAS }
            { should be replaced by coding the segment override  }
            { directly! - DJGPP FAQ                              }
            if segment<>NR_NO then
-             AsmWrite(gas_regname(segment)+':');
+             owner.AsmWrite(gas_regname(segment)+':');
            if assigned(symbol) then
-             AsmWrite(symbol.name);
+             owner.AsmWrite(symbol.name);
            if ref.refaddr=addr_pic then
 {$ifdef x86_64}
-             AsmWrite('@GOTPCREL');
+             owner.AsmWrite('@GOTPCREL');
 {$else x86_64}
-             AsmWrite('@GOT');
+             owner.AsmWrite('@GOT');
 {$endif x86_64}
            if offset<0 then
-             AsmWrite(tostr(offset))
+             owner.AsmWrite(tostr(offset))
            else
             if (offset>0) then
              begin
                if assigned(symbol) then
-                AsmWrite('+'+tostr(offset))
+                owner.AsmWrite('+'+tostr(offset))
                else
-                AsmWrite(tostr(offset));
+                owner.AsmWrite(tostr(offset));
              end
            else if (index=NR_NO) and (base=NR_NO) and (not assigned(symbol)) then
-             AsmWrite('0');
+             owner.AsmWrite('0');
            if (index<>NR_NO) and (base=NR_NO) then
             begin
-              AsmWrite('(,'+gas_regname(index));
+              owner.AsmWrite('(,'+gas_regname(index));
               if scalefactor<>0 then
-               AsmWrite(','+tostr(scalefactor)+')')
+               owner.AsmWrite(','+tostr(scalefactor)+')')
               else
-               AsmWrite(')');
+               owner.AsmWrite(')');
             end
            else
             if (index=NR_NO) and (base<>NR_NO) then
-              AsmWrite('('+gas_regname(base)+')')
+              owner.AsmWrite('('+gas_regname(base)+')')
             else
              if (index<>NR_NO) and (base<>NR_NO) then
               begin
-                AsmWrite('('+gas_regname(base)+','+gas_regname(index));
+                owner.AsmWrite('('+gas_regname(base)+','+gas_regname(index));
                 if scalefactor<>0 then
-                 AsmWrite(','+tostr(scalefactor));
-                AsmWrite(')');
+                 owner.AsmWrite(','+tostr(scalefactor));
+                owner.AsmWrite(')');
               end;
          end;
       end;
 
 
-    procedure Tx86AttAssembler.WriteOper(const o:toper);
+    procedure Tx86InstrWriter.WriteOper(const o:toper);
       begin
         case o.typ of
           top_reg :
-            AsmWrite(gas_regname(o.reg));
+            owner.AsmWrite(gas_regname(o.reg));
           top_ref :
             if o.ref^.refaddr in [addr_no,addr_pic] then
               WriteReference(o.ref^)
             else
               begin
-                AsmWrite('$');
+                owner.AsmWrite('$');
                 if assigned(o.ref^.symbol) then
-                 AsmWrite(o.ref^.symbol.name);
+                 owner.AsmWrite(o.ref^.symbol.name);
                 if o.ref^.offset>0 then
-                 AsmWrite('+'+tostr(o.ref^.offset))
+                 owner.AsmWrite('+'+tostr(o.ref^.offset))
                 else
                  if o.ref^.offset<0 then
-                  AsmWrite(tostr(o.ref^.offset))
+                  owner.AsmWrite(tostr(o.ref^.offset))
                 else
                  if not(assigned(o.ref^.symbol)) then
-                   AsmWrite('0');
+                   owner.AsmWrite('0');
               end;
           top_const :
-              AsmWrite('$'+tostr(o.val));
+              owner.AsmWrite('$'+tostr(o.val));
           else
             internalerror(10001);
         end;
       end;
 
 
-    procedure Tx86AttAssembler.WriteOper_jmp(const o:toper);
+    procedure Tx86InstrWriter.WriteOper_jmp(const o:toper);
       begin
         case o.typ of
           top_reg :
-            AsmWrite('*'+gas_regname(o.reg));
+            owner.AsmWrite('*'+gas_regname(o.reg));
           top_ref :
             begin
               if o.ref^.refaddr=addr_no then
                 begin
-                  AsmWrite('*');
+                  owner.AsmWrite('*');
                   WriteReference(o.ref^);
                 end
               else
                 begin
-                  AsmWrite(o.ref^.symbol.name);
+                  owner.AsmWrite(o.ref^.symbol.name);
                   if o.ref^.refaddr=addr_pic then
-                    AsmWrite('@PLT');
+                    owner.AsmWrite('@PLT');
                   if o.ref^.offset>0 then
-                   AsmWrite('+'+tostr(o.ref^.offset))
+                   owner.AsmWrite('+'+tostr(o.ref^.offset))
                   else
                    if o.ref^.offset<0 then
-                    AsmWrite(tostr(o.ref^.offset));
+                    owner.AsmWrite(tostr(o.ref^.offset));
                 end;
             end;
           top_const :
-            AsmWrite(tostr(o.val));
+            owner.AsmWrite(tostr(o.val));
           else
             internalerror(10001);
         end;
       end;
 
 
-    procedure Tx86AttAssembler.WriteInstruction(hp: tai);
+    procedure Tx86InstrWriter.WriteInstruction(hp: tai);
       var
        op       : tasmop;
        calljmp  : boolean;
@@ -183,14 +213,14 @@ interface
         taicpu(hp).SetOperandOrder(op_att);
         op:=taicpu(hp).opcode;
         calljmp:=is_calljmp(op);
-        AsmWrite(#9);
+        owner.AsmWrite(#9);
         { movsd should not be translated to movsl when there
           are (xmm) arguments }
         if (op=A_MOVSD) and (taicpu(hp).ops>0) then
-          AsmWrite('movsd')
+          owner.AsmWrite('movsd')
         else
-          AsmWrite(gas_op2str[op]);
-        AsmWrite(cond2str[taicpu(hp).condition]);
+          owner.AsmWrite(gas_op2str[op]);
+        owner.AsmWrite(cond2str[taicpu(hp).condition]);
         { suffix needed ?  fnstsw,fldcw don't support suffixes
           with binutils 2.9.5 under linux }
 {        if (Taicpu(hp).oper[0]^.typ=top_reg) and
@@ -209,13 +239,13 @@ interface
                (taicpu(hp).oper[0]^.typ=top_reg) and
                (getregtype(taicpu(hp).oper[0]^.reg)=R_FPUREGISTER)
               ) then
-          AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
+          owner.AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
         { process operands }
         if taicpu(hp).ops<>0 then
           begin
             if calljmp then
              begin
-               AsmWrite(#9);
+               owner.AsmWrite(#9);
                WriteOper_jmp(taicpu(hp).oper[0]^);
              end
             else
@@ -223,14 +253,14 @@ interface
                for i:=0 to taicpu(hp).ops-1 do
                  begin
                    if i=0 then
-                     AsmWrite(#9)
+                     owner.AsmWrite(#9)
                    else
-                     AsmWrite(',');
+                     owner.AsmWrite(',');
                    WriteOper(taicpu(hp).oper[i]^);
                  end;
              end;
           end;
-        AsmLn;
+        owner.AsmLn;
       end;
 
 {*****************************************************************************
@@ -263,6 +293,7 @@ interface
             comment : '# ';
           );
 
+
        as_i386_as_aout_info : tasminfo =
           (
             id           : as_i386_as_aout;
@@ -274,6 +305,20 @@ interface
             labelprefix : 'L';
             comment : '# ';
           );
+
+
+       as_i386_gas_darwin_info : tasminfo =
+          (
+            id     : as_darwin;
+            idtxt  : 'AS-Darwin';
+            asmbin : 'as';
+            asmcmd : '-o $OBJ $ASM -arch i386';
+            supported_target : system_any;
+            flags : [af_allowdirect,af_needar,af_smartlink_sections,af_supports_dwarf];
+            labelprefix : 'L';
+            comment : '# ';
+          );
+
 {$endif x86_64}
 
 initialization
@@ -281,6 +326,7 @@ initialization
   RegisterAssembler(as_x86_64_as_info,Tx86ATTAssembler);
 {$else x86_64}
   RegisterAssembler(as_i386_as_info,Tx86ATTAssembler);
+  RegisterAssembler(as_i386_gas_darwin_info,Tx86AppleGNUAssembler);
   RegisterAssembler(as_i386_as_aout_info,Tx86ATTAssembler);
 {$endif x86_64}
 end.