Pārlūkot izejas kodu

* factored out the output file handling (mostly writing data) from the
external assembler writer, so we can reuse the archtecture-specific
writers to write inline assembly in LLVM IR files

git-svn-id: trunk@31625 -

Jonas Maebe 10 gadi atpakaļ
vecāks
revīzija
b3d0197f98

+ 1 - 1
compiler/aarch64/agcpugas.pas

@@ -278,7 +278,7 @@ unit agcpugas;
                  sep:=',';
               end;
           end;
-        owner.AsmWriteLn(s);
+        owner.writer.AsmWriteLn(s);
       end;
 
 

+ 221 - 223
compiler/aggas.pas

@@ -437,7 +437,7 @@ implementation
       var
         s : string;
       begin
-        AsmLn;
+        writer.AsmLn;
         case target_info.system of
          system_i386_OS2,
          system_i386_EMX,
@@ -454,17 +454,17 @@ implementation
          system_powerpc64_aix:
            begin
              if (atype in [sec_stub,sec_objc_data,sec_objc_const,sec_data_coalesced]) then
-               AsmWrite('.section ');
+               writer.AsmWrite('.section ');
            end
          else
-          AsmWrite('.section ');
+          writer.AsmWrite('.section ');
         end;
         s:=sectionname(atype,aname,aorder);
-        AsmWrite(s);
+        writer.AsmWrite(s);
         case atype of
           sec_fpc :
             if aname = 'resptrs' then
-              AsmWrite(', "a", @progbits');
+              writer.AsmWrite(', "a", @progbits');
           sec_stub :
             begin
               case target_info.system of
@@ -474,17 +474,17 @@ implementation
                 system_powerpc_darwin,
                 system_powerpc64_darwin:
                   if (cs_create_pic in current_settings.moduleswitches) then
-                    AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
+                    writer.AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
                   else
-                    AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
+                    writer.AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
                 system_i386_darwin,
                 system_i386_iphonesim:
-                  AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
+                  writer.AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
                 system_arm_darwin:
                   if (cs_create_pic in current_settings.moduleswitches) then
-                    AsmWriteln('__TEXT,__picsymbolstub4,symbol_stubs,none,16')
+                    writer.AsmWriteln('__TEXT,__picsymbolstub4,symbol_stubs,none,16')
                   else
-                    AsmWriteln('__TEXT,__symbol_stub4,symbol_stubs,none,12')
+                    writer.AsmWriteln('__TEXT,__symbol_stub4,symbol_stubs,none,12')
                 { darwin/(x86-64/AArch64) uses PC-based GOT addressing, no
                   explicit symbol stubs }
                 else
@@ -503,16 +503,16 @@ implementation
             begin
               s:=sectionattrs_coff(atype);
               if (s<>'') then
-                AsmWrite(',"'+s+'"');
+                writer.AsmWrite(',"'+s+'"');
             end
          else if target_info.system in systems_aix then
            begin
              s:=sectionalignment_aix(atype,secalign);
              if s<>'' then
-               AsmWrite(','+s);
+               writer.AsmWrite(','+s);
            end;
         end;
-        AsmLn;
+        writer.AsmLn;
         LastSecType:=atype;
       end;
 
@@ -526,8 +526,8 @@ implementation
         for i:=0 to len-1 do
           begin
             if (i > 0) then
-              AsmWrite(',');
-            AsmWrite(tostr(buf[i]));
+              writer.AsmWrite(',');
+            writer.AsmWrite(tostr(buf[i]));
           end;
       end;
 
@@ -541,8 +541,8 @@ implementation
         for i:=0 to len-1 do
           begin
             if (i > 0) then
-              AsmWrite(',');
-            AsmWrite(tostr(buf[i]));
+              writer.AsmWrite(',');
+            writer.AsmWrite(tostr(buf[i]));
           end;
       end;
 
@@ -585,18 +585,18 @@ implementation
                         instr:='0x51fc'
                       else}
                         instr:='0x4e71';
-                      AsmWrite(#9'.balignw '+tostr(alignment)+','+instr);
+                      writer.AsmWrite(#9'.balignw '+tostr(alignment)+','+instr);
                     end
                   else
                     begin
 {$endif m68k}
-                  AsmWrite(#9'.balign '+tostr(alignment));
+                  writer.AsmWrite(#9'.balign '+tostr(alignment));
                   if use_op then
-                    AsmWrite(','+tostr(fillop))
+                    writer.AsmWrite(','+tostr(fillop))
 {$ifdef x86}
                   { force NOP as alignment op code }
                   else if LastSecType=sec_code then
-                    AsmWrite(',0x90');
+                    writer.AsmWrite(',0x90');
 {$endif x86}
 {$ifdef m68k}
                     end;
@@ -607,10 +607,10 @@ implementation
                   { darwin and aix as only support .align }
                   if not ispowerof2(alignment,i) then
                     internalerror(2003010305);
-                  AsmWrite(#9'.align '+tostr(i));
+                  writer.AsmWrite(#9'.align '+tostr(i));
                   last_align:=i;
                 end;
-              AsmLn;
+              writer.AsmLn;
             end;
         end;
 
@@ -661,27 +661,27 @@ implementation
 
            ait_comment :
              Begin
-               AsmWrite(target_asm.comment);
-               AsmWritePChar(tai_comment(hp).str);
-               AsmLn;
+               writer.AsmWrite(target_asm.comment);
+               writer.AsmWritePChar(tai_comment(hp).str);
+               writer.AsmLn;
              End;
 
            ait_regalloc :
              begin
                if (cs_asm_regalloc in current_settings.globalswitches) then
                  begin
-                   AsmWrite(#9+target_asm.comment+'Register ');
+                   writer.AsmWrite(#9+target_asm.comment+'Register ');
                    repeat
-                     AsmWrite(std_regname(Tai_regalloc(hp).reg));
+                     writer.AsmWrite(std_regname(Tai_regalloc(hp).reg));
                      if (hp.next=nil) or
                         (tai(hp.next).typ<>ait_regalloc) or
                         (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
                        break;
                      hp:=tai(hp.next);
-                     AsmWrite(',');
+                     writer.AsmWrite(',');
                    until false;
-                   AsmWrite(' ');
-                   AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
+                   writer.AsmWrite(' ');
+                   writer.AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
                  end;
              end;
 
@@ -706,8 +706,8 @@ implementation
                else
                  begin
 {$ifdef EXTDEBUG}
-                   AsmWrite(target_asm.comment);
-                   AsmWriteln(' sec_none');
+                   writer.AsmWrite(target_asm.comment);
+                   writer.AsmWriteln(' sec_none');
 {$endif EXTDEBUG}
                 end;
              end;
@@ -724,45 +724,45 @@ implementation
                    }
                    if tai_datablock(hp).is_global then
                      begin
-                       asmwrite('.globl ');
-                       asmwriteln(tai_datablock(hp).sym.name);
-                       asmwriteln('.data');
-                       asmwrite('.zerofill __DATA, __common, ');
-                       asmwrite(tai_datablock(hp).sym.name);
-                       asmwriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
+                       writer.AsmWrite('.globl ');
+                       writer.AsmWriteln(tai_datablock(hp).sym.name);
+                       writer.AsmWriteln('.data');
+                       writer.AsmWrite('.zerofill __DATA, __common, ');
+                       writer.AsmWrite(tai_datablock(hp).sym.name);
+                       writer.AsmWriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
                        if not(LastSecType in [sec_data,sec_none]) then
                          writesection(LastSecType,'',secorder_default,1 shl last_align);
                      end
                    else
                      begin
-                       asmwrite(#9'.lcomm'#9);
-                       asmwrite(tai_datablock(hp).sym.name);
-                       asmwrite(','+tostr(tai_datablock(hp).size));
-                       asmwrite(','+tostr(last_align));
-                       asmln;
+                       writer.AsmWrite(#9'.lcomm'#9);
+                       writer.AsmWrite(tai_datablock(hp).sym.name);
+                       writer.AsmWrite(','+tostr(tai_datablock(hp).size));
+                       writer.AsmWrite(','+tostr(last_align));
+                       writer.AsmLn;
                      end;
                  end
                else if target_info.system in systems_aix then
                  begin
                    if tai_datablock(hp).is_global then
                      begin
-                       asmwrite(#9'.globl ');
-                       asmwriteln(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
-                       asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
-                       asmwriteln(':');
-                       asmwrite(#9'.space ');
-                       asmwriteln(tostr(tai_datablock(hp).size));
+                       writer.AsmWrite(#9'.globl ');
+                       writer.AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
+                       writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
+                       writer.AsmWriteln(':');
+                       writer.AsmWrite(#9'.space ');
+                       writer.AsmWriteln(tostr(tai_datablock(hp).size));
                        if not(LastSecType in [sec_data,sec_none]) then
                          writesection(LastSecType,'',secorder_default,1 shl last_align);
                      end
                    else
                      begin
-                       asmwrite(#9'.lcomm ');
-                       asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
-                       asmwrite(',');
-                       asmwrite(tostr(tai_datablock(hp).size)+',');
-                       asmwrite('_data.bss_,');
-                       asmwriteln(tostr(last_align));
+                       writer.AsmWrite(#9'.lcomm ');
+                       writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
+                       writer.AsmWrite(',');
+                       writer.AsmWrite(tostr(tai_datablock(hp).size)+',');
+                       writer.AsmWrite('_data.bss_,');
+                       writer.AsmWriteln(tostr(last_align));
                      end;
                  end
                else
@@ -776,25 +776,25 @@ implementation
                          program (PFV) }
                        if tai_datablock(hp).is_global then
                          begin
-                           asmwrite(#9'.comm'#9);
+                           writer.AsmWrite(#9'.comm'#9);
                            if replaceforbidden then
-                             asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name))
+                             writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name))
                            else
-                             asmwrite(tai_datablock(hp).sym.name);
-                           asmwrite(','+tostr(tai_datablock(hp).size));
-                           asmwrite(','+tostr(last_align));
-                           asmln;
+                             writer.AsmWrite(tai_datablock(hp).sym.name);
+                           writer.AsmWrite(','+tostr(tai_datablock(hp).size));
+                           writer.AsmWrite(','+tostr(last_align));
+                           writer.AsmLn;
                          end
                        else
                          begin
-                           asmwrite(#9'.lcomm'#9);
+                           writer.AsmWrite(#9'.lcomm'#9);
                            if replaceforbidden then
-                             asmwrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
+                             writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_datablock(hp).sym.name));
                            else
-                             asmwrite(tai_datablock(hp).sym.name);
-                           asmwrite(','+tostr(tai_datablock(hp).size));
-                           asmwrite(','+tostr(last_align));
-                           asmln;
+                             writer.AsmWrite(tai_datablock(hp).sym.name);
+                           writer.AsmWrite(','+tostr(tai_datablock(hp).size));
+                           writer.AsmWrite(','+tostr(last_align));
+                           writer.AsmLn;
                          end
                      end
                    else
@@ -802,11 +802,11 @@ implementation
                      begin
                        if Tai_datablock(hp).is_global then
                          begin
-                           asmwrite(#9'.globl ');
+                           writer.AsmWrite(#9'.globl ');
                            if replaceforbidden then
-                             asmwriteln(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
+                             writer.AsmWriteln(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
                            else
-                             asmwriteln(Tai_datablock(hp).sym.name);
+                             writer.AsmWriteln(Tai_datablock(hp).sym.name);
                          end;
                        if ((target_info.system <> system_arm_linux) and (target_info.system <> system_arm_android)) then
                          sepChar := '@'
@@ -815,21 +815,21 @@ implementation
                        if replaceforbidden then
                          begin
                            if (tf_needs_symbol_type in target_info.flags) then
-                             asmwriteln(#9'.type '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+sepChar+'object');
+                             writer.AsmWriteln(#9'.type '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+sepChar+'object');
                            if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
-                              asmwriteln(#9'.size '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+tostr(Tai_datablock(hp).size));
-                           asmwrite(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
+                              writer.AsmWriteln(#9'.size '+ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name)+','+tostr(Tai_datablock(hp).size));
+                           writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(Tai_datablock(hp).sym.name))
                          end
                        else
                          begin
                            if (tf_needs_symbol_type in target_info.flags) then
-                             asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
+                             writer.AsmWriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
                            if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
-                             asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
-                           asmwrite(Tai_datablock(hp).sym.name);
+                             writer.AsmWriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
+                           writer.AsmWrite(Tai_datablock(hp).sym.name);
                          end;
-                       asmwriteln(':');
-                       asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
+                       writer.AsmWriteln(':');
+                       writer.AsmWriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
                      end;
                  end;
              end;
@@ -850,29 +850,29 @@ implementation
                         internalerror(200404292);
                       if not(target_info.system in systems_aix) then
                         begin
-                          AsmWrite(ait_const2str[aitconst_32bit]);
+                          writer.AsmWrite(ait_const2str[aitconst_32bit]);
                           if target_info.endian = endian_little then
                             begin
-                              AsmWrite(tostr(longint(lo(tai_const(hp).value))));
-                              AsmWrite(',');
-                              AsmWrite(tostr(longint(hi(tai_const(hp).value))));
+                              writer.AsmWrite(tostr(longint(lo(tai_const(hp).value))));
+                              writer.AsmWrite(',');
+                              writer.AsmWrite(tostr(longint(hi(tai_const(hp).value))));
                             end
                           else
                             begin
-                              AsmWrite(tostr(longint(hi(tai_const(hp).value))));
-                              AsmWrite(',');
-                              AsmWrite(tostr(longint(lo(tai_const(hp).value))));
+                              writer.AsmWrite(tostr(longint(hi(tai_const(hp).value))));
+                              writer.AsmWrite(',');
+                              writer.AsmWrite(tostr(longint(lo(tai_const(hp).value))));
                             end;
                         end
                       else
                         WriteAixIntConst(tai_const(hp));
-                      AsmLn;
+                      writer.AsmLn;
                     end;
 {$endif cpu64bitaddr}
                  aitconst_got:
                    begin
-                     AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
-                     Asmln;
+                     writer.AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
+                     writer.AsmLn;
                    end;
 
                  aitconst_gotoff_symbol:
@@ -883,21 +883,21 @@ implementation
 
                        cpu_mipseb,cpu_mipsel:
                          begin
-                           AsmWrite(#9'.gpword'#9);
-                           AsmWrite(tai_const(hp).sym.name);
+                           writer.AsmWrite(#9'.gpword'#9);
+                           writer.AsmWrite(tai_const(hp).sym.name);
                          end;
 
                        cpu_i386:
                          begin
-                           AsmWrite(ait_const2str[aitconst_32bit]);
-                           AsmWrite(tai_const(hp).sym.name);
+                           writer.AsmWrite(ait_const2str[aitconst_32bit]);
+                           writer.AsmWrite(tai_const(hp).sym.name);
                          end;
                      else
                        InternalError(2014022602);
                      end;
                      if (tai_const(hp).value<>0) then
-                       AsmWrite(tostr_with_plus(tai_const(hp).value));
-                     Asmln;
+                       writer.AsmWrite(tostr_with_plus(tai_const(hp).value));
+                     writer.AsmLn;
                    end;
 
                  aitconst_uleb128bit,
@@ -934,7 +934,7 @@ implementation
                      else if (target_info.system in systems_darwin) and
                         (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
                        begin
-                         AsmWrite(ait_const2str[aitconst_8bit]);
+                         writer.AsmWrite(ait_const2str[aitconst_8bit]);
                          case tai_const(hp).consttype of
                            aitconst_uleb128bit:
                              WriteDecodedUleb128(qword(tai_const(hp).value));
@@ -946,17 +946,17 @@ implementation
                        begin
                          if (constdef in ait_unaligned_consts) and
                             (target_info.system in use_ua_sparc_systems) then
-                           AsmWrite(ait_ua_sparc_const2str[constdef])
+                           writer.AsmWrite(ait_ua_sparc_const2str[constdef])
                          else if (constdef in ait_unaligned_consts) and
                                  (target_info.system in use_ua_elf_systems) then
-                           AsmWrite(ait_ua_elf_const2str[constdef])
+                           writer.AsmWrite(ait_ua_elf_const2str[constdef])
                          { we can also have unaligned pointers in packed record
                            constants, which don't get translated into
                            unaligned tai -> always use vbyte }
                          else if target_info.system in systems_aix then
-                            AsmWrite(#9'.vbyte'#9+tostr(tai_const(hp).size)+',')
+                            writer.AsmWrite(#9'.vbyte'#9+tostr(tai_const(hp).size)+',')
                          else
-                           AsmWrite(ait_const2str[constdef]);
+                           writer.AsmWrite(ait_const2str[constdef]);
                          l:=0;
                          t := '';
                          repeat
@@ -991,7 +991,7 @@ implementation
                            if constdef = aitconst_gs then
                              s:='gs('+s+')';
 
-                           AsmWrite(s);
+                           writer.AsmWrite(s);
                            inc(l,length(s));
                            { Values with symbols are written on a single line to improve
                              reading of the .s file (PFV) }
@@ -1004,15 +1004,15 @@ implementation
                               assigned(tai_const(hp.next).sym) then
                              break;
                            hp:=tai(hp.next);
-                           AsmWrite(',');
+                           writer.AsmWrite(',');
                          until false;
                          if (t <> '') then
                            begin
-                             AsmLn;
-                             AsmWrite(t);
+                             writer.AsmLn;
+                             writer.AsmWrite(t);
                            end;
                        end;
-                      AsmLn;
+                      writer.AsmLn;
                    end;
                  else
                    internalerror(200704251);
@@ -1033,7 +1033,7 @@ implementation
                     begin
                       if pos=0 then
                        begin
-                         AsmWrite(#9'.ascii'#9'"');
+                         writer.AsmWrite(#9'.ascii'#9'"');
                          pos:=20;
                        end;
                       ch:=tai_string(hp).str[i-1];
@@ -1046,11 +1046,11 @@ implementation
                       else
                         s:=ch;
                       end;
-                      AsmWrite(s);
+                      writer.AsmWrite(s);
                       inc(pos,length(s));
                       if (pos>line_length) or (i=tai_string(hp).len) then
                        begin
-                         AsmWriteLn('"');
+                         writer.AsmWriteLn('"');
                          pos:=0;
                        end;
                     end;
@@ -1065,27 +1065,27 @@ implementation
                 begin
                   if (tai_label(hp).labsym.bind=AB_PRIVATE_EXTERN) then
                     begin
-                      AsmWrite(#9'.private_extern ');
-                      AsmWriteln(tai_label(hp).labsym.name);
+                      writer.AsmWrite(#9'.private_extern ');
+                      writer.AsmWriteln(tai_label(hp).labsym.name);
                     end;
                   if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
                    begin
 {$ifdef arm}
                      { do no change arm mode accidently, .globl seems to reset the mode }
                      if GenerateThumbCode or GenerateThumb2Code then
-                       AsmWriteln(#9'.thumb_func'#9);
+                       writer.AsmWriteln(#9'.thumb_func'#9);
 {$endif arm}
-                     AsmWrite('.globl'#9);
+                     writer.AsmWrite('.globl'#9);
                      if replaceforbidden then
-                       AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
+                       writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
                      else
-                       AsmWriteLn(tai_label(hp).labsym.name);
+                       writer.AsmWriteLn(tai_label(hp).labsym.name);
                    end;
                   if replaceforbidden then
-                    AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
+                    writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
                   else
-                    AsmWrite(tai_label(hp).labsym.name);
-                  AsmWriteLn(':');
+                    writer.AsmWrite(tai_label(hp).labsym.name);
+                  writer.AsmWriteLn(':');
                 end;
              end;
 
@@ -1093,40 +1093,40 @@ implementation
              begin
                if (tai_symbol(hp).sym.bind=AB_PRIVATE_EXTERN) then
                  begin
-                   AsmWrite(#9'.private_extern ');
+                   writer.AsmWrite(#9'.private_extern ');
                    if replaceforbidden then
-                     AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
+                     writer.AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
                    else
-                     AsmWriteln(tai_symbol(hp).sym.name);
+                     writer.AsmWriteln(tai_symbol(hp).sym.name);
                  end;
                if (target_info.system=system_powerpc64_linux) and
                   (tai_symbol(hp).sym.typ=AT_FUNCTION) and
                   (cs_profile in current_settings.moduleswitches) then
-                 AsmWriteLn('.globl _mcount');
+                 writer.AsmWriteLn('.globl _mcount');
 
                if tai_symbol(hp).is_global then
                 begin
-                  AsmWrite('.globl'#9);
+                  writer.AsmWrite('.globl'#9);
                   if replaceforbidden then
-                    AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
+                    writer.AsmWriteln(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
                   else
-                    AsmWriteln(tai_symbol(hp).sym.name);
+                    writer.AsmWriteln(tai_symbol(hp).sym.name);
                 end;
                if (target_info.system=system_powerpc64_linux) and
                   use_dotted_functions and
                  (tai_symbol(hp).sym.typ=AT_FUNCTION) then
                  begin
-                   AsmWriteLn('.section ".opd", "aw"');
-                   AsmWriteLn('.align 3');
-                   AsmWriteLn(tai_symbol(hp).sym.name + ':');
-                   AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
-                   AsmWriteLn('.previous');
-                   AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
+                   writer.AsmWriteLn('.section ".opd", "aw"');
+                   writer.AsmWriteLn('.align 3');
+                   writer.AsmWriteLn(tai_symbol(hp).sym.name + ':');
+                   writer.AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
+                   writer.AsmWriteLn('.previous');
+                   writer.AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
                    if (tai_symbol(hp).is_global) then
-                     AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
-                   AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
+                     writer.AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
+                   writer.AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
                    { the dotted name is the name of the actual function entry }
-                   AsmWrite('.');
+                   writer.AsmWrite('.');
                  end
                else if (target_info.system in systems_aix) and
                   (tai_symbol(hp).sym.typ = AT_FUNCTION) then
@@ -1141,16 +1141,16 @@ implementation
                        s:=#9'.llong .';
                        ch:='3';
                      end;
-                   AsmWriteLn(#9'.csect '+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+'[DS],'+ch);
-                   AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+':');
-                   AsmWriteln(s+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+', TOC[tc0], 0');
-                   AsmWriteln(#9'.csect .text[PR]');
+                   writer.AsmWriteLn(#9'.csect '+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+'[DS],'+ch);
+                   writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+':');
+                   writer.AsmWriteln(s+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name)+', TOC[tc0], 0');
+                   writer.AsmWriteln(#9'.csect .text[PR]');
                    if (tai_symbol(hp).is_global) then
-                     AsmWriteLn('.globl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
+                     writer.AsmWriteLn('.globl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name))
                    else
-                     AsmWriteLn('.lglobl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name));
+                     writer.AsmWriteLn('.lglobl .'+ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name));
                    { the dotted name is the name of the actual function entry }
-                   AsmWrite('.');
+                   writer.AsmWrite('.');
                  end
                else
                  begin
@@ -1160,28 +1160,28 @@ implementation
                      sepChar := '#';
                    if (tf_needs_symbol_type in target_info.flags) then
                      begin
-                       AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
+                       writer.AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
                        if (needsObject(tai_symbol(hp))) then
-                         AsmWriteLn(',' + sepChar + 'object')
+                         writer.AsmWriteLn(',' + sepChar + 'object')
                        else
-                         AsmWriteLn(',' + sepChar + 'function');
+                         writer.AsmWriteLn(',' + sepChar + 'function');
                      end;
                  end;
                if replaceforbidden then
                  if not(tai_symbol(hp).has_value) then
-                   AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + ':'))
+                   writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + ':'))
                  else
-                   AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value)))
+                   writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value)))
                else if not(tai_symbol(hp).has_value) then
-                 AsmWriteLn(tai_symbol(hp).sym.name + ':')
+                 writer.AsmWriteLn(tai_symbol(hp).sym.name + ':')
                else
-                 AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
+                 writer.AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
              end;
            ait_symbolpair:
              begin
-               AsmWrite(#9);
-               AsmWrite(symbolpairkindstr[tai_symbolpair(hp).kind]);
-               AsmWrite(' ');
+               writer.AsmWrite(#9);
+               writer.AsmWrite(symbolpairkindstr[tai_symbolpair(hp).kind]);
+               writer.AsmWrite(' ');
                if tai_symbolpair(hp).kind<>spk_localentry then
                  s:=', '
                else
@@ -1191,22 +1191,22 @@ implementation
                if replaceforbidden then
                  begin
                    { avoid string truncation }
-                   AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbolpair(hp).sym^)+s);
-                   AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbolpair(hp).value^));
+                   writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbolpair(hp).sym^)+s);
+                   writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbolpair(hp).value^));
                  end
                else
                  begin
                    { avoid string truncation }
-                   AsmWrite(tai_symbolpair(hp).sym^+s);
-                   AsmWriteLn(tai_symbolpair(hp).value^);
+                   writer.AsmWrite(tai_symbolpair(hp).sym^+s);
+                   writer.AsmWriteLn(tai_symbolpair(hp).value^);
                  end;
              end;
            ait_weak:
              begin
                if replaceforbidden then
-                 AsmWriteLn(#9'.weak '+ReplaceForbiddenAsmSymbolChars(tai_weak(hp).sym^))
+                 writer.AsmWriteLn(#9'.weak '+ReplaceForbiddenAsmSymbolChars(tai_weak(hp).sym^))
                else
-                 AsmWriteLn(#9'.weak '+tai_weak(hp).sym^);
+                 writer.AsmWriteLn(#9'.weak '+tai_weak(hp).sym^);
              end;
            ait_symbol_end :
              begin
@@ -1214,25 +1214,25 @@ implementation
                 begin
                   s:=target_asm.labelprefix+'e'+tostr(symendcount);
                   inc(symendcount);
-                  AsmWriteLn(s+':');
-                  AsmWrite(#9'.size'#9);
+                  writer.AsmWriteLn(s+':');
+                  writer.AsmWrite(#9'.size'#9);
                   if (target_info.system=system_powerpc64_linux) and
                      use_dotted_functions and
                      (tai_symbol_end(hp).sym.typ=AT_FUNCTION) then
-                    AsmWrite('.');
+                    writer.AsmWrite('.');
                   if replaceforbidden then
-                    AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
+                    writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
                   else
-                    AsmWrite(tai_symbol_end(hp).sym.name);
-                  AsmWrite(', '+s+' - ');
+                    writer.AsmWrite(tai_symbol_end(hp).sym.name);
+                  writer.AsmWrite(', '+s+' - ');
                   if (target_info.system=system_powerpc64_linux) and
                      use_dotted_functions and
                      (tai_symbol_end(hp).sym.typ=AT_FUNCTION) then
-                    AsmWrite('.');
+                    writer.AsmWrite('.');
                   if replaceforbidden then
-                    AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
+                    writer.AsmWriteLn(ReplaceForbiddenAsmSymbolChars(tai_symbol_end(hp).sym.name))
                   else
-                    AsmWriteLn(tai_symbol_end(hp).sym.name);
+                    writer.AsmWriteLn(tai_symbol_end(hp).sym.name);
                 end;
              end;
 
@@ -1245,9 +1245,9 @@ implementation
              begin
                if assigned(tai_stab(hp).str) then
                  begin
-                   AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
-                   AsmWritePChar(tai_stab(hp).str);
-                   AsmLn;
+                   writer.AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
+                   writer.AsmWritePChar(tai_stab(hp).str);
+                   writer.AsmLn;
                  end;
              end;
 
@@ -1256,25 +1256,23 @@ implementation
              begin
 {$ifdef DEBUG_AGGAS}
                WriteStr(s,hp.typ);
-               AsmWriteLn('# '+s);
+               writer.AsmWriteLn('# '+s);
 {$endif DEBUG_AGGAS}
              end;
 
            ait_cutobject :
              begin
 {$ifdef DEBUG_AGGAS}
-               AsmWriteLn('# ait_cutobject');
+               writer.AsmWriteLn('# ait_cutobject');
 {$endif DEBUG_AGGAS}
                if SmartAsm then
                 begin
                 { only reset buffer if nothing has changed }
-                  if AsmSize=AsmStartSize then
-                   AsmClear
-                  else
+                  if not(writer.ClearIfEmpty) then
                    begin
-                     AsmClose;
+                     writer.AsmClose;
                      DoAssemble;
-                     AsmCreate(tai_cutobject(hp).place);
+                     writer.AsmCreate(tai_cutobject(hp).place);
                    end;
                 { avoid empty files }
                   while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
@@ -1285,7 +1283,7 @@ implementation
                    end;
                   if LastSecType<>sec_none then
                     WriteSection(LastSecType,'',secorder_default,last_align);
-                  AsmStartSize:=AsmSize;
+                  writer.MarkEmpty;
                 end;
              end;
 
@@ -1293,7 +1291,7 @@ implementation
              begin
 {$ifdef DEBUG_AGGAS}
                WriteStr(s,tai_marker(hp).Kind);
-               AsmWriteLn('# ait_marker, kind: '+s);
+               writer.AsmWriteLn('# ait_marker, kind: '+s);
 {$endif DEBUG_AGGAS}
                if tai_marker(hp).kind=mark_NoLineInfoStart then
                  inc(InlineLevel)
@@ -1307,48 +1305,48 @@ implementation
                if tai_directive(hp).name <>'' then
                  begin
                    if replaceforbidden then
-                     AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_directive(hp).name))
+                     writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_directive(hp).name))
                    else
-                     AsmWrite(tai_directive(hp).name);
+                     writer.AsmWrite(tai_directive(hp).name);
                  end;
-               AsmLn;
+               writer.AsmLn;
              end;
 
            ait_seh_directive :
              begin
 {$ifndef DISABLE_WIN64_SEH}
-               AsmWrite(sehdirectivestr[tai_seh_directive(hp).kind]);
+               writer.AsmWrite(sehdirectivestr[tai_seh_directive(hp).kind]);
                case tai_seh_directive(hp).datatype of
                  sd_none:;
                  sd_string:
                    begin
-                     AsmWrite(' '+tai_seh_directive(hp).data.name^);
+                     writer.AsmWrite(' '+tai_seh_directive(hp).data.name^);
                      if (tai_seh_directive(hp).data.flags and 1)<>0 then
-                       AsmWrite(',@except');
+                       writer.AsmWrite(',@except');
                      if (tai_seh_directive(hp).data.flags and 2)<>0 then
-                       AsmWrite(',@unwind');
+                       writer.AsmWrite(',@unwind');
                    end;
                  sd_reg:
-                   AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg));
+                   writer.AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg));
                  sd_offset:
-                   AsmWrite(' '+tostr(tai_seh_directive(hp).data.offset));
+                   writer.AsmWrite(' '+tostr(tai_seh_directive(hp).data.offset));
                  sd_regoffset:
-                   AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg)+', '+
+                   writer.AsmWrite(' '+gas_regname(tai_seh_directive(hp).data.reg)+', '+
                      tostr(tai_seh_directive(hp).data.offset));
                end;
-               AsmLn;
+               writer.AsmLn;
 {$endif DISABLE_WIN64_SEH}
              end;
 
            ait_varloc:
              begin
                if tai_varloc(hp).newlocationhi<>NR_NO then
-                 AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
+                 writer.AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
                    std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation)))
                else
-                 AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
+                 writer.AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
                    std_regname(tai_varloc(hp).newlocation)));
-               AsmLn;
+               writer.AsmLn;
              end;
            else
              internalerror(2006012201);
@@ -1377,7 +1375,7 @@ implementation
 
     procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
       begin
-        AsmWriteLn(#9'.weak '+s.name);
+        writer.AsmWriteLn(#9'.weak '+s.name);
       end;
 
 
@@ -1397,11 +1395,11 @@ implementation
           case terminationkind of
             term_none: ;
             term_string:
-              AsmWriteLn('"');
+              writer.AsmWriteLn('"');
             term_nostring:
-              AsmLn;
+              writer.AsmLn;
           end;
-          AsmWrite(#9'.byte'#9);
+          writer.AsmWrite(#9'.byte'#9);
           pos:=20;
           instring:=false;
         end;
@@ -1446,14 +1444,14 @@ implementation
                 else
                   s:=ch;
             end;
-            AsmWrite(s);
+            writer.AsmWrite(s);
             inc(pos,length(s));
             if (pos>line_length) or (i=tai_string(hp).len) then
               begin
                 if instring then
-                  AsmWriteLn('"')
+                  writer.AsmWriteLn('"')
                 else
-                  AsmLn;
+                  writer.AsmLn;
                 pos:=0;
               end;
          end;
@@ -1472,17 +1470,17 @@ implementation
         size:=tai_const(hp).size;
         while pos<(size-4) do
           begin
-            AsmWrite(#9'.vbyte'#9'4, ');
-            AsmWriteln(tostr(longint(tai_const(hp).value shr ((size-pos-4)*8))));
+            writer.AsmWrite(#9'.vbyte'#9'4, ');
+            writer.AsmWriteln(tostr(longint(tai_const(hp).value shr ((size-pos-4)*8))));
             inc(pos,4);
          end;
-        AsmWrite(#9'.vbyte'#9);
-        AsmWrite(tostr(size-pos));
-        AsmWrite(', ');
+        writer.AsmWrite(#9'.vbyte'#9);
+        writer.AsmWrite(tostr(size-pos));
+        writer.AsmWrite(', ');
         case size-pos of
-          1: AsmWrite(tostr(byte(tai_const(hp).value)));
-          2: AsmWrite(tostr(word(tai_const(hp).value)));
-          4: AsmWrite(tostr(longint(tai_const(hp).value)));
+          1: writer.AsmWrite(tostr(byte(tai_const(hp).value)));
+          2: writer.AsmWrite(tostr(word(tai_const(hp).value)));
+          4: writer.AsmWrite(tostr(longint(tai_const(hp).value)));
           else
             internalerror(2012010402);
         end;
@@ -1493,18 +1491,18 @@ implementation
         pos, size: longint;
       begin
         size:=tai_const(hp).size;
-        AsmWrite(#9'.byte'#9);
+        writer.AsmWrite(#9'.byte'#9);
         if target_info.endian=endian_big then
           begin
             pos:=size-1;
             while pos>=0 do
               begin
-                AsmWrite(tostr((tai_const(hp).value shr (pos*8)) and $ff));
+                writer.AsmWrite(tostr((tai_const(hp).value shr (pos*8)) and $ff));
                 dec(pos);
                 if pos>=0 then
-                  AsmWrite(', ')
+                  writer.AsmWrite(', ')
                 else
-                  AsmLn;
+                  writer.AsmLn;
               end;
           end
         else
@@ -1512,21 +1510,21 @@ implementation
             pos:=0;
             while pos<size do
               begin
-                AsmWriteln(tostr((tai_const(hp).value shr (pos*8)) and $ff));
+                writer.AsmWriteln(tostr((tai_const(hp).value shr (pos*8)) and $ff));
                 inc(pos);
                 if pos<=size then
-                  AsmWrite(', ')
+                  writer.AsmWrite(', ')
                 else
-                  AsmLn;
+                  writer.AsmLn;
               end;
           end;
-        AsmLn;
+        writer.AsmLn;
       end;
 
 
     procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
     begin
-      AsmWrite('.'+directivestr[dir]+' ');
+      writer.AsmWrite('.'+directivestr[dir]+' ');
     end;
 
 
@@ -1550,19 +1548,19 @@ implementation
         TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
       }
       if not(target_info.system in systems_darwin) then
-        AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
+        writer.AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
 
       WriteExtraHeader;
-      AsmStartSize:=AsmSize;
+      writer.MarkEmpty;
       symendcount:=0;
 
       for hal:=low(TasmlistType) to high(TasmlistType) do
         begin
           if not (current_asmdata.asmlists[hal].empty) then
             begin
-              AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
+              writer.AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
               writetree(current_asmdata.asmlists[hal]);
-              AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
+              writer.AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
             end;
         end;
 
@@ -1573,17 +1571,17 @@ implementation
 
       if create_smartlink_sections and
          (target_info.system in systems_darwin) then
-        AsmWriteLn(#9'.subsections_via_symbols');
+        writer.AsmWriteLn(#9'.subsections_via_symbols');
 
       { "no executable stack" marker }
       { TODO: used by OpenBSD/NetBSD as well? }
       if (target_info.system in (systems_linux + systems_android + systems_freebsd + systems_dragonfly)) and
          not(cs_executable_stack in current_settings.moduleswitches) then
         begin
-          AsmWriteLn('.section .note.GNU-stack,"",%progbits');
+          writer.AsmWriteLn('.section .note.GNU-stack,"",%progbits');
         end;
 
-      AsmLn;
+      writer.AsmLn;
       WriteExtraFooter;
 {$ifdef EXTDEBUG}
       if current_module.mainsource<>'' then
@@ -1800,7 +1798,7 @@ implementation
 
     procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
       begin
-        AsmWriteLn(#9'.weak_reference '+s.name);
+        writer.AsmWriteLn(#9'.weak_reference '+s.name);
       end;
 
 

+ 2 - 2
compiler/arm/agarmgas.pas

@@ -128,7 +128,7 @@ unit agarmgas;
       begin
         inherited WriteExtraHeader;
         if GenerateThumb2Code then
-          AsmWriteLn(#9'.syntax unified');
+          writer.AsmWriteLn(#9'.syntax unified');
       end;
 
 {****************************************************************************}
@@ -376,7 +376,7 @@ unit agarmgas;
                sep:=',';
             end;
         end;
-      owner.AsmWriteLn(s);
+      owner.writer.AsmWriteLn(s);
     end;
 
 

+ 385 - 309
compiler/assemble.pas

@@ -60,21 +60,67 @@ interface
         procedure MakeObject;virtual;abstract;
       end;
 
+      TExternalAssembler = class;
+
+      TExternalAssemblerOutputFile=class
+      protected
+        owner: TExternalAssembler;
+      {outfile}
+        AsmSize,
+        AsmStartSize,
+        outcnt   : longint;
+        outbuf   : array[0..AsmOutSize-1] of char;
+        outfile  : file;
+        fioerror : boolean;
+
+        Procedure AsmClear;
+      public
+        Constructor Create(_owner: TExternalAssembler);
+
+        Procedure RemoveAsm;virtual;
+        Procedure AsmFlush;
+
+        { mark the current output as the "empty" state (i.e., it only contains
+          headers/directives etc }
+        Procedure MarkEmpty;
+        { clears the assembler output if nothing was added since it was marked
+          as empty, and returns whether it was empty }
+        function ClearIfEmpty: boolean;
+
+        {# Write a string to the assembler file }
+        Procedure AsmWrite(const c:char);
+        Procedure AsmWrite(const s:string);
+        Procedure AsmWrite(const s:ansistring);
+
+        {# Write a string to the assembler file }
+        Procedure AsmWritePChar(p:pchar);
+
+        {# Write a string to the assembler file followed by a new line }
+        Procedure AsmWriteLn(const c:char);
+        Procedure AsmWriteLn(const s:string);
+        Procedure AsmWriteLn(const s:ansistring);
+
+        {# Write a new line to the assembler file }
+        Procedure AsmLn; virtual;
+
+        procedure AsmCreate(Aplace:tcutplace);
+        procedure AsmClose;
+
+        property ioerror: boolean read fioerror;
+      end;
+
       {# This is the base class which should be overridden for each each
          assembler writer. It is used to actually assembler a file,
          and write the output to the assembler file.
       }
       TExternalAssembler=class(TAssembler)
       private
+       { output writer }
+        fwriter: TExternalAssemblerOutputFile;
+        ffreewriter: boolean;
+
         procedure CreateSmartLinkPath(const s:TPathStr);
       protected
-      {outfile}
-        AsmSize,
-        AsmStartSize,
-        outcnt   : longint;
-        outbuf   : array[0..AsmOutSize-1] of char;
-        outfile  : file;
-        ioerror : boolean;
       {input source info}
         lastfileinfo : tfileposinfo;
         infile,
@@ -89,6 +135,7 @@ interface
         function extended2str(e : extended) : string; virtual;
         Function DoPipe:boolean;
       public
+
         {# Returns the complete path and executable name of the assembler
            program.
 
@@ -103,28 +150,6 @@ interface
         Function  CallAssembler(const command:string; const para:TCmdStr):Boolean;
 
         Function  DoAssemble:boolean;virtual;
-        Procedure RemoveAsm;virtual;
-        Procedure AsmFlush;
-        Procedure AsmClear;
-
-        {# Write a string to the assembler file }
-        Procedure AsmWrite(const c:char);
-        Procedure AsmWrite(const s:string);
-        Procedure AsmWrite(const s:ansistring);
-
-        {# Write a string to the assembler file }
-        Procedure AsmWritePChar(p:pchar);
-
-        {# Write a string to the assembler file followed by a new line }
-        Procedure AsmWriteLn(const c:char);
-        Procedure AsmWriteLn(const s:string);
-        Procedure AsmWriteLn(const s:ansistring);
-
-        {# Write a new line to the assembler file }
-        Procedure AsmLn; virtual;
-
-        procedure AsmCreate(Aplace:tcutplace);
-        procedure AsmClose;
 
         {# This routine should be overridden for each assembler, it is used
            to actually write the abstract assembler stream to file.}
@@ -139,8 +164,13 @@ interface
         function MakeCmdLine: TCmdStr; virtual;
       public
         Constructor Create(smart:boolean);override;
+        Constructor CreateWithWriter(wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
         procedure MakeObject;override;
+        destructor Destroy; override;
+
+        property writer: TExternalAssemblerOutputFile read fwriter;
       end;
+      TExternalAssemblerClass = class of TExternalAssembler;
 
       { TInternalAssembler }
 
@@ -262,22 +292,295 @@ Implementation
               inc(SmartHeaderCount);
               s:=asmprefix+tostr(SmartHeaderCount)+'h';
             end;
-          cut_normal :
-            s:=asmprefix+tostr(SmartHeaderCount)+'s';
-          cut_end :
-            s:=asmprefix+tostr(SmartHeaderCount)+'t';
-        end;
-        AsmFileName:=Path+FixFileName(s+tostr(SmartFilesCount)+target_info.asmext);
-        ObjFileName:=Path+FixFileName(s+tostr(SmartFilesCount)+target_info.objext);
-        { insert in container so it can be cleared after the linking }
-        SmartLinkOFiles.Insert(ObjFileName);
+          cut_normal :
+            s:=asmprefix+tostr(SmartHeaderCount)+'s';
+          cut_end :
+            s:=asmprefix+tostr(SmartHeaderCount)+'t';
+        end;
+        AsmFileName:=Path+FixFileName(s+tostr(SmartFilesCount)+target_info.asmext);
+        ObjFileName:=Path+FixFileName(s+tostr(SmartFilesCount)+target_info.objext);
+        { insert in container so it can be cleared after the linking }
+        SmartLinkOFiles.Insert(ObjFileName);
+      end;
+
+
+
+
+{*****************************************************************************
+                                 TAssemblerOutputFile
+*****************************************************************************}
+
+    procedure TExternalAssemblerOutputFile.RemoveAsm;
+      var
+        g : file;
+      begin
+        if cs_asm_leave in current_settings.globalswitches then
+         exit;
+        if cs_asm_extern in current_settings.globalswitches then
+         AsmRes.AddDeleteCommand(owner.AsmFileName)
+        else
+         begin
+           assign(g,owner.AsmFileName);
+           {$push} {$I-}
+            erase(g);
+           {$pop}
+           if ioresult<>0 then;
+         end;
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmFlush;
+      begin
+        if outcnt>0 then
+         begin
+           { suppress i/o error }
+           {$push} {$I-}
+           BlockWrite(outfile,outbuf,outcnt);
+           {$pop}
+           fioerror:=fioerror or (ioresult<>0);
+           outcnt:=0;
+         end;
+      end;
+
+    procedure TExternalAssemblerOutputFile.MarkEmpty;
+      begin
+        AsmStartSize:=AsmSize
+      end;
+
+
+    function TExternalAssemblerOutputFile.ClearIfEmpty: boolean;
+      begin
+        result:=AsmSize=AsmStartSize;
+        if result then
+         AsmClear;
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmClear;
+      begin
+        outcnt:=0;
+      end;
+
+
+    constructor TExternalAssemblerOutputFile.Create(_owner: TExternalAssembler);
+      begin
+        owner:=_owner;
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmWrite(const c: char);
+      begin
+        if OutCnt+1>=AsmOutSize then
+         AsmFlush;
+        OutBuf[OutCnt]:=c;
+        inc(OutCnt);
+        inc(AsmSize);
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmWrite(const s:string);
+      begin
+        if OutCnt+length(s)>=AsmOutSize then
+         AsmFlush;
+        Move(s[1],OutBuf[OutCnt],length(s));
+        inc(OutCnt,length(s));
+        inc(AsmSize,length(s));
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmWrite(const s:ansistring);
+      var
+        StartIndex, ToWrite: longint;
+      begin
+        if s='' then
+          exit;
+        if OutCnt+length(s)>=AsmOutSize then
+         AsmFlush;
+        StartIndex:=1;
+        ToWrite:=length(s);
+        while ToWrite>AsmOutSize do
+          begin
+            Move(s[StartIndex],OutBuf[OutCnt],AsmOutSize);
+            inc(OutCnt,AsmOutSize);
+            inc(AsmSize,AsmOutSize);
+            AsmFlush;
+            inc(StartIndex,AsmOutSize);
+            dec(ToWrite,AsmOutSize);
+          end;
+        Move(s[StartIndex],OutBuf[OutCnt],ToWrite);
+        inc(OutCnt,ToWrite);
+        inc(AsmSize,ToWrite);
+      end;
+
+
+    procedure TExternalAssemblerOutputFile.AsmWriteLn(const c: char);
+      begin
+        AsmWrite(c);
+        AsmLn;
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmWriteLn(const s:string);
+      begin
+        AsmWrite(s);
+        AsmLn;
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmWriteLn(const s: ansistring);
+      begin
+        AsmWrite(s);
+        AsmLn;
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmWritePChar(p:pchar);
+      var
+        i,j : longint;
+      begin
+        i:=StrLen(p);
+        j:=i;
+        while j>0 do
+         begin
+           i:=min(j,AsmOutSize);
+           if OutCnt+i>=AsmOutSize then
+            AsmFlush;
+           Move(p[0],OutBuf[OutCnt],i);
+           inc(OutCnt,i);
+           inc(AsmSize,i);
+           dec(j,i);
+           p:=pchar(@p[i]);
+         end;
+      end;
+
+
+    Procedure TExternalAssemblerOutputFile.AsmLn;
+      begin
+        if OutCnt>=AsmOutSize-2 then
+         AsmFlush;
+        if (cs_link_on_target in current_settings.globalswitches) then
+          begin
+            OutBuf[OutCnt]:=target_info.newline[1];
+            inc(OutCnt);
+            inc(AsmSize);
+            if length(target_info.newline)>1 then
+             begin
+               OutBuf[OutCnt]:=target_info.newline[2];
+               inc(OutCnt);
+               inc(AsmSize);
+             end;
+          end
+        else
+          begin
+            OutBuf[OutCnt]:=source_info.newline[1];
+            inc(OutCnt);
+            inc(AsmSize);
+            if length(source_info.newline)>1 then
+             begin
+               OutBuf[OutCnt]:=source_info.newline[2];
+               inc(OutCnt);
+               inc(AsmSize);
+             end;
+          end;
+      end;
+
+
+    procedure TExternalAssemblerOutputFile.AsmCreate(Aplace:tcutplace);
+{$ifdef hasamiga}
+      var
+        tempFileName: TPathStr;
+{$endif}
+      begin
+        if owner.SmartAsm then
+         owner.NextSmartName(Aplace);
+{$ifdef hasamiga}
+        { on Amiga/MorphOS try to redirect .s files to the T: assign, which is
+          for temp files, and usually (default setting) located in the RAM: drive.
+          This highly improves assembling speed for complex projects like the
+          compiler itself, especially on hardware with slow disk I/O.
+          Consider this as a poor man's pipe on Amiga, because real pipe handling
+          would be much more complex and error prone to implement. (KB) }
+        if (([cs_asm_extern,cs_asm_leave,cs_link_on_target] * current_settings.globalswitches) = []) then
+         begin
+          { try to have an unique name for the .s file }
+          tempFileName:=HexStr(GetProcessID shr 4,7)+ExtractFileName(owner.AsmFileName);
+{$ifndef morphos}
+          { old Amiga RAM: handler only allows filenames up to 30 char }
+          if Length(tempFileName) < 30 then
+{$endif}
+          owner.AsmFileName:='T:'+tempFileName;
+         end;
+{$endif}
+{$ifdef hasunix}
+        if owner.DoPipe then
+         begin
+           if owner.SmartAsm then
+            begin
+              if (owner.SmartFilesCount<=1) then
+               Message1(exec_i_assembling_smart,owner.name);
+            end
+           else
+             Message1(exec_i_assembling_pipe,owner.AsmFileName);
+           POpen(outfile,maybequoted(owner.FindAssembler)+' '+owner.MakeCmdLine,'W');
+         end
+        else
+{$endif}
+         begin
+           Assign(outfile,owner.AsmFileName);
+           {$push} {$I-}
+           Rewrite(outfile,1);
+           {$pop}
+           if ioresult<>0 then
+             begin
+               fioerror:=true;
+               Message1(exec_d_cant_create_asmfile,owner.AsmFileName);
+             end;
+         end;
+        outcnt:=0;
+        AsmSize:=0;
+        AsmStartSize:=0;
+      end;
+
+
+    procedure TExternalAssemblerOutputFile.AsmClose;
+      var
+        f : file;
+        FileAge : longint;
+      begin
+        AsmFlush;
+{$ifdef hasunix}
+        if owner.DoPipe then
+          begin
+            if PClose(outfile) <> 0 then
+              GenerateError;
+          end
+        else
+{$endif}
+         begin
+         {Touch Assembler time to ppu time is there is a ppufilename}
+           if owner.ppufilename<>'' then
+            begin
+              Assign(f,owner.ppufilename);
+              {$push} {$I-}
+              reset(f,1);
+              {$pop}
+              if ioresult=0 then
+               begin
+                 FileAge := FileGetDate(GetFileHandle(f));
+                 close(f);
+                 reset(outfile,1);
+                 FileSetDate(GetFileHandle(outFile),FileAge);
+               end;
+            end;
+           close(outfile);
+         end;
       end;
 
-
 {*****************************************************************************
                                  TExternalAssembler
 *****************************************************************************}
 
+
     function TExternalAssembler.single2str(d : single) : string;
       var
          hs : string;
@@ -322,13 +625,25 @@ Implementation
 
     Constructor TExternalAssembler.Create(smart:boolean);
       begin
-        inherited Create(smart);
+        inherited create(smart);
+        if not assigned(fwriter) then
+          begin
+            fwriter:=TExternalAssemblerOutputFile.Create(self);
+            ffreewriter:=true;
+          end;
         if SmartAsm then
-         begin
-           path:=FixPath(ChangeFileExt(AsmFileName,target_info.smartext),false);
-           CreateSmartLinkPath(path);
-         end;
-        Outcnt:=0;
+          begin
+            path:=FixPath(ChangeFileExt(AsmFileName,target_info.smartext),false);
+            CreateSmartLinkPath(path);
+          end;
+      end;
+
+
+    constructor TExternalAssembler.CreateWithWriter(wr: TExternalAssemblerOutputFile; freewriter,smart: boolean);
+      begin
+        fwriter:=wr;
+        ffreewriter:=freewriter;
+        Create(smart);
       end;
 
 
@@ -438,25 +753,6 @@ Implementation
       end;
 
 
-    procedure TExternalAssembler.RemoveAsm;
-      var
-        g : file;
-      begin
-        if cs_asm_leave in current_settings.globalswitches then
-         exit;
-        if cs_asm_extern in current_settings.globalswitches then
-         AsmRes.AddDeleteCommand(AsmFileName)
-        else
-         begin
-           assign(g,AsmFileName);
-           {$push} {$I-}
-            erase(g);
-           {$pop}
-           if ioresult<>0 then;
-         end;
-      end;
-
-
     Function TExternalAssembler.DoAssemble:boolean;
       begin
         DoAssemble:=true;
@@ -474,7 +770,7 @@ Implementation
          end;
 
         if CallAssembler(FindAssembler,MakeCmdLine) then
-         RemoveAsm
+         writer.RemoveAsm
         else
          begin
             DoAssemble:=false;
@@ -483,143 +779,6 @@ Implementation
       end;
 
 
-    Procedure TExternalAssembler.AsmFlush;
-      begin
-        if outcnt>0 then
-         begin
-           { suppress i/o error }
-           {$push} {$I-}
-           BlockWrite(outfile,outbuf,outcnt);
-           {$pop}
-           ioerror:=ioerror or (ioresult<>0);
-           outcnt:=0;
-         end;
-      end;
-
-
-    Procedure TExternalAssembler.AsmClear;
-      begin
-        outcnt:=0;
-      end;
-
-
-    Procedure TExternalAssembler.AsmWrite(const c: char);
-      begin
-        if OutCnt+1>=AsmOutSize then
-         AsmFlush;
-        OutBuf[OutCnt]:=c;
-        inc(OutCnt);
-        inc(AsmSize);
-      end;
-
-
-    Procedure TExternalAssembler.AsmWrite(const s:string);
-      begin
-        if OutCnt+length(s)>=AsmOutSize then
-         AsmFlush;
-        Move(s[1],OutBuf[OutCnt],length(s));
-        inc(OutCnt,length(s));
-        inc(AsmSize,length(s));
-      end;
-
-
-    Procedure TExternalAssembler.AsmWrite(const s:ansistring);
-      var
-        StartIndex, ToWrite: longint;
-      begin
-        if s='' then
-          exit;
-        if OutCnt+length(s)>=AsmOutSize then
-         AsmFlush;
-        StartIndex:=1;
-        ToWrite:=length(s);
-        while ToWrite>AsmOutSize do
-          begin
-            Move(s[StartIndex],OutBuf[OutCnt],AsmOutSize);
-            inc(OutCnt,AsmOutSize);
-            inc(AsmSize,AsmOutSize);
-            AsmFlush;
-            inc(StartIndex,AsmOutSize);
-            dec(ToWrite,AsmOutSize);
-          end;
-        Move(s[StartIndex],OutBuf[OutCnt],ToWrite);
-        inc(OutCnt,ToWrite);
-        inc(AsmSize,ToWrite);
-      end;
-
-
-    procedure TExternalAssembler.AsmWriteLn(const c: char);
-      begin
-        AsmWrite(c);
-        AsmLn;
-      end;
-
-
-    Procedure TExternalAssembler.AsmWriteLn(const s:string);
-      begin
-        AsmWrite(s);
-        AsmLn;
-      end;
-
-
-    Procedure TExternalAssembler.AsmWriteLn(const s: ansistring);
-      begin
-        AsmWrite(s);
-        AsmLn;
-      end;
-
-
-    Procedure TExternalAssembler.AsmWritePChar(p:pchar);
-      var
-        i,j : longint;
-      begin
-        i:=StrLen(p);
-        j:=i;
-        while j>0 do
-         begin
-           i:=min(j,AsmOutSize);
-           if OutCnt+i>=AsmOutSize then
-            AsmFlush;
-           Move(p[0],OutBuf[OutCnt],i);
-           inc(OutCnt,i);
-           inc(AsmSize,i);
-           dec(j,i);
-           p:=pchar(@p[i]);
-         end;
-      end;
-
-
-    Procedure TExternalAssembler.AsmLn;
-      begin
-        if OutCnt>=AsmOutSize-2 then
-         AsmFlush;
-        if (cs_link_on_target in current_settings.globalswitches) then
-          begin
-            OutBuf[OutCnt]:=target_info.newline[1];
-            inc(OutCnt);
-            inc(AsmSize);
-            if length(target_info.newline)>1 then
-             begin
-               OutBuf[OutCnt]:=target_info.newline[2];
-               inc(OutCnt);
-               inc(AsmSize);
-             end;
-          end
-        else
-          begin
-            OutBuf[OutCnt]:=source_info.newline[1];
-            inc(OutCnt);
-            inc(AsmSize);
-            if length(source_info.newline)>1 then
-             begin
-               OutBuf[OutCnt]:=source_info.newline[2];
-               inc(OutCnt);
-               inc(AsmSize);
-             end;
-          end;
-      end;
-
-
     function TExternalAssembler.MakeCmdLine: TCmdStr;
       begin
         result:=target_asm.asmcmd;
@@ -654,97 +813,6 @@ Implementation
       end;
 
 
-    procedure TExternalAssembler.AsmCreate(Aplace:tcutplace);
-{$ifdef hasamiga}
-      var
-        tempFileName: TPathStr;
-{$endif}
-      begin
-        if SmartAsm then
-         NextSmartName(Aplace);
-{$ifdef hasamiga}
-        { on Amiga/MorphOS try to redirect .s files to the T: assign, which is
-          for temp files, and usually (default setting) located in the RAM: drive.
-          This highly improves assembling speed for complex projects like the
-          compiler itself, especially on hardware with slow disk I/O.
-          Consider this as a poor man's pipe on Amiga, because real pipe handling
-          would be much more complex and error prone to implement. (KB) }
-        if (([cs_asm_extern,cs_asm_leave,cs_link_on_target] * current_settings.globalswitches) = []) then
-         begin
-          { try to have an unique name for the .s file }
-          tempFileName:=HexStr(GetProcessID shr 4,7)+ExtractFileName(AsmFileName);
-{$ifndef morphos}
-          { old Amiga RAM: handler only allows filenames up to 30 char }
-          if Length(tempFileName) < 30 then
-{$endif}
-          AsmFileName:='T:'+tempFileName;
-         end;
-{$endif}
-{$ifdef hasunix}
-        if DoPipe then
-         begin
-           if SmartAsm then
-            begin
-              if (SmartFilesCount<=1) then
-               Message1(exec_i_assembling_smart,name);
-            end
-           else
-             Message1(exec_i_assembling_pipe,AsmFileName);
-           POpen(outfile,maybequoted(FindAssembler)+' '+MakeCmdLine,'W');
-         end
-        else
-{$endif}
-         begin
-           Assign(outfile,AsmFileName);
-           {$push} {$I-}
-           Rewrite(outfile,1);
-           {$pop}
-           if ioresult<>0 then
-             begin
-               ioerror:=true;
-               Message1(exec_d_cant_create_asmfile,AsmFileName);
-             end;
-         end;
-        outcnt:=0;
-        AsmSize:=0;
-        AsmStartSize:=0;
-      end;
-
-
-    procedure TExternalAssembler.AsmClose;
-      var
-        f : file;
-        FileAge : longint;
-      begin
-        AsmFlush;
-{$ifdef hasunix}
-        if DoPipe then
-          begin
-            if PClose(outfile) <> 0 then
-              GenerateError;
-          end
-        else
-{$endif}
-         begin
-         {Touch Assembler time to ppu time is there is a ppufilename}
-           if ppufilename<>'' then
-            begin
-              Assign(f,ppufilename);
-              {$push} {$I-}
-              reset(f,1);
-              {$pop}
-              if ioresult=0 then
-               begin
-                 FileAge := FileGetDate(GetFileHandle(f));
-                 close(f);
-                 reset(outfile,1);
-                 FileSetDate(GetFileHandle(outFile),FileAge);
-               end;
-            end;
-           close(outfile);
-         end;
-      end;
-
     procedure TExternalAssembler.WriteSourceLine(hp: tailineinfo);
       var
         module : tmodule;
@@ -782,7 +850,7 @@ Implementation
           begin
             if (infile<>lastinfile) then
               begin
-                AsmWriteLn(target_asm.comment+'['+infile.name+']');
+                writer.AsmWriteLn(target_asm.comment+'['+infile.name+']');
                 if assigned(lastinfile) then
                   lastinfile.close;
               end;
@@ -791,7 +859,7 @@ Implementation
               begin
                 if (hp.fileinfo.line<>0) and
                   (infile.linebuf^[hp.fileinfo.line]>=0) then
-                  AsmWriteLn(target_asm.comment+'['+tostr(hp.fileinfo.line)+'] '+
+                  writer.AsmWriteLn(target_asm.comment+'['+tostr(hp.fileinfo.line)+'] '+
                   fixline(infile.GetLineStr(hp.fileinfo.line)));
                 { set it to a negative value !
                   to make that is has been read already !! PM }
@@ -807,11 +875,11 @@ Implementation
       begin
 {$ifdef EXTDEBUG}
         if assigned(hp.problem) then
-          AsmWriteLn(target_asm.comment+'Temp '+tostr(hp.temppos)+','+
+          writer.AsmWriteLn(target_asm.comment+'Temp '+tostr(hp.temppos)+','+
           tostr(hp.tempsize)+' '+hp.problem^)
         else
 {$endif EXTDEBUG}
-          AsmWriteLn(target_asm.comment+'Temp '+tostr(hp.temppos)+','+
+          writer.AsmWriteLn(target_asm.comment+'Temp '+tostr(hp.temppos)+','+
             tostr(hp.tempsize)+' '+tempallocstr[hp.allocation]);
       end;
 
@@ -831,21 +899,21 @@ Implementation
           begin
             case tai_realconst(hp).realtyp of
               aitrealconst_s32bit:
-                AsmWriteLn(target_asm.comment+'value: '+single2str(tai_realconst(hp).value.s32val));
+                writer.AsmWriteLn(target_asm.comment+'value: '+single2str(tai_realconst(hp).value.s32val));
               aitrealconst_s64bit:
-                AsmWriteLn(target_asm.comment+'value: '+double2str(tai_realconst(hp).value.s64val));
+                writer.AsmWriteLn(target_asm.comment+'value: '+double2str(tai_realconst(hp).value.s64val));
 {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
               { can't write full 80 bit floating point constants yet on non-x86 }
               aitrealconst_s80bit:
-                AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s80val));
+                writer.AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s80val));
 {$endif cpuextended}
               aitrealconst_s64comp:
-                AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s64compval));
+                writer.AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s64compval));
               else
                 internalerror(2014050604);
             end;
           end;
-        AsmWrite(dbdir);
+        writer.AsmWrite(dbdir);
         { generic float writing code: get start address of value, then write
           byte by byte. Can't use fields directly, because e.g ts64comp is
           defined as extended on x86 }
@@ -905,16 +973,16 @@ Implementation
 {$endif ARM}
           swapmask:=0;
         repeat
-          AsmWrite(tostr(pdata[index xor swapmask]));
+          writer.AsmWrite(tostr(pdata[index xor swapmask]));
           inc(index,step);
           dec(count);
           if count<>0 then
-            AsmWrite(',');
+            writer.AsmWrite(',');
         until count=0;
         { padding }
         for count:=tai_realconst(hp).datasize+1 to tai_realconst(hp).savesize do
-          AsmWrite(',0');
-        AsmLn;
+          writer.AsmWrite(',0');
+        writer.AsmLn;
       end;
 
 
@@ -930,18 +998,26 @@ Implementation
 
     procedure TExternalAssembler.MakeObject;
       begin
-        AsmCreate(cut_normal);
+        writer.AsmCreate(cut_normal);
         FillChar(lastfileinfo, sizeof(lastfileinfo), 0);
         lastfileinfo.line := -1;
         lastinfile := nil;
         lastsectype := sec_none;
         WriteAsmList;
-        AsmClose;
-        if not(ioerror) then
+        writer.AsmClose;
+        if not(writer.ioerror) then
           DoAssemble;
       end;
 
 
+    destructor TExternalAssembler.Destroy;
+      begin
+        if ffreewriter then
+          writer.Free;
+        inherited;
+      end;
+
+
 {*****************************************************************************
                                   TInternalAssembler
 *****************************************************************************}

+ 1 - 1
compiler/avr/agavrgas.pas

@@ -188,7 +188,7 @@ unit agavrgas;
               sep:=',';
             end;
         end;
-      owner.AsmWriteLn(s);
+      owner.writer.AsmWriteLn(s);
     end;
 
 

+ 121 - 114
compiler/jvm/agjasmin.pas

@@ -35,6 +35,10 @@ interface
       assemble;
 
     type
+      TJasminAssemblerOutputFile=class(TExternalAssemblerOutputFile)
+        procedure RemoveAsm; override;
+      end;
+
       TJasminInstrWriter = class;
       {# This is a derived class which is used to write
          Jasmin-styled assembler.
@@ -70,7 +74,6 @@ interface
         function MakeCmdLine: TCmdStr;override;
         procedure WriteTree(p:TAsmList);override;
         procedure WriteAsmList;override;
-        procedure RemoveAsm; override;
         destructor destroy; override;
        protected
         InstrWriter: TJasminInstrWriter;
@@ -244,6 +247,34 @@ implementation
        result:='0dx'+result;
       end;
 
+
+{****************************************************************************}
+{                       Jasmin Output File                                   }
+{****************************************************************************}
+
+    procedure TJasminAssemblerOutputFile.RemoveAsm;
+      var
+        g : file;
+      begin
+        inherited;
+        if cs_asm_leave in current_settings.globalswitches then
+         exit;
+        while not TJasminAssembler(owner).asmfiles.empty do
+          begin
+            if cs_asm_extern in current_settings.globalswitches then
+             AsmRes.AddDeleteCommand(TJasminAssembler(owner).asmfiles.GetFirst)
+            else
+             begin
+               assign(g,TJasminAssembler(owner).asmfiles.GetFirst);
+               {$I-}
+                erase(g);
+               {$I+}
+               if ioresult<>0 then;
+             end;
+          end;
+      end;
+
+
 {****************************************************************************}
 {                       Jasmin Assembler writer                              }
 {****************************************************************************}
@@ -305,7 +336,7 @@ implementation
                    begin
                      if (infile<>lastinfile) then
                        begin
-                         AsmWriteLn(target_asm.comment+'['+infile.name+']');
+                         writer.AsmWriteLn(target_asm.comment+'['+infile.name+']');
                          if assigned(lastinfile) then
                            lastinfile.close;
                        end;
@@ -314,7 +345,7 @@ implementation
                        begin
                          if (hp1.fileinfo.line<>0) and
                             ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
-                           AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
+                           writer.AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
                              fixline(infile.GetLineStr(hp1.fileinfo.line)));
                          { set it to a negative value !
                          to make that is has been read already !! PM }
@@ -331,27 +362,27 @@ implementation
 
              ait_comment :
                Begin
-                 AsmWrite(target_asm.comment);
-                 AsmWritePChar(tai_comment(hp).str);
-                 AsmLn;
+                 writer.AsmWrite(target_asm.comment);
+                 writer.AsmWritePChar(tai_comment(hp).str);
+                 writer.AsmLn;
                End;
 
              ait_regalloc :
                begin
                  if (cs_asm_regalloc in current_settings.globalswitches) then
                    begin
-                     AsmWrite(#9+target_asm.comment+'Register ');
+                     writer.AsmWrite(#9+target_asm.comment+'Register ');
                      repeat
-                       AsmWrite(std_regname(Tai_regalloc(hp).reg));
+                       writer.AsmWrite(std_regname(Tai_regalloc(hp).reg));
                        if (hp.next=nil) or
                           (tai(hp.next).typ<>ait_regalloc) or
                           (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
                          break;
                        hp:=tai(hp.next);
-                       AsmWrite(',');
+                       writer.AsmWrite(',');
                      until false;
-                     AsmWrite(' ');
-                     AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
+                     writer.AsmWrite(' ');
+                     writer.AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
                    end;
                end;
 
@@ -361,11 +392,11 @@ implementation
                    begin
   {$ifdef EXTDEBUG}
                      if assigned(tai_tempalloc(hp).problem) then
-                       AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
+                       writer.AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
                          tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
                      else
   {$endif EXTDEBUG}
-                       AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
+                       writer.AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
                          tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
                    end;
                end;
@@ -387,7 +418,7 @@ implementation
 
              ait_const:
                begin
-                 AsmWriteln('constant');
+                 writer.AsmWriteln('constant');
 //                 internalerror(2010122702);
                end;
 
@@ -403,7 +434,7 @@ implementation
                    begin
                      if pos=0 then
                       begin
-                        AsmWrite(#9'strconst: '#9'"');
+                        writer.AsmWrite(#9'strconst: '#9'"');
                         pos:=20;
                       end;
                      ch:=tai_string(hp).str[i-1];
@@ -416,11 +447,11 @@ implementation
                      else
                       s:=ch;
                      end;
-                     AsmWrite(s);
+                     writer.AsmWrite(s);
                      inc(pos,length(s));
                      if (pos>line_length) or (i=tai_string(hp).len) then
                       begin
-                        AsmWriteLn('"');
+                        writer.AsmWriteLn('"');
                         pos:=0;
                       end;
                    end;
@@ -430,8 +461,8 @@ implementation
                begin
                  if (tai_label(hp).labsym.is_used) then
                   begin
-                    AsmWrite(tai_label(hp).labsym.name);
-                    AsmWriteLn(':');
+                    writer.AsmWrite(tai_label(hp).labsym.name);
+                    writer.AsmWriteLn(':');
                   end;
                end;
 
@@ -442,8 +473,8 @@ implementation
                     end
                   else
                    begin
-                     AsmWrite('data symbol: ');
-                     AsmWriteln(tai_symbol(hp).sym.name);
+                     writer.AsmWrite('data symbol: ');
+                     writer.AsmWriteln(tai_symbol(hp).sym.name);
 //                     internalerror(2010122706);
                    end;
                end;
@@ -471,34 +502,34 @@ implementation
 
              ait_directive :
                begin
-                 AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
+                 writer.AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
                  if tai_directive(hp).name<>'' then
-                   AsmWrite(tai_directive(hp).name);
-                 AsmLn;
+                   writer.AsmWrite(tai_directive(hp).name);
+                 writer.AsmLn;
                end;
 
              ait_jvar:
                begin
-                 AsmWrite('.var ');
-                 AsmWrite(tostr(tai_jvar(hp).stackslot));
-                 AsmWrite(' is ');
-                 AsmWrite(tai_jvar(hp).desc^);
-                 AsmWrite(' from ');
-                 AsmWrite(tai_jvar(hp).startlab.name);
-                 AsmWrite(' to ');
-                 AsmWriteLn(tai_jvar(hp).stoplab.name);
+                 writer.AsmWrite('.var ');
+                 writer.AsmWrite(tostr(tai_jvar(hp).stackslot));
+                 writer.AsmWrite(' is ');
+                 writer.AsmWrite(tai_jvar(hp).desc^);
+                 writer.AsmWrite(' from ');
+                 writer.AsmWrite(tai_jvar(hp).startlab.name);
+                 writer.AsmWrite(' to ');
+                 writer.AsmWriteLn(tai_jvar(hp).stoplab.name);
                end;
 
              ait_jcatch:
                begin
-                 AsmWrite('.catch ');
-                 AsmWrite(tai_jcatch(hp).name^);
-                 AsmWrite(' from ');
-                 AsmWrite(tai_jcatch(hp).startlab.name);
-                 AsmWrite(' to ');
-                 AsmWrite(tai_jcatch(hp).stoplab.name);
-                 AsmWrite(' using ');
-                 AsmWriteLn(tai_jcatch(hp).handlerlab.name);
+                 writer.AsmWrite('.catch ');
+                 writer.AsmWrite(tai_jcatch(hp).name^);
+                 writer.AsmWrite(' from ');
+                 writer.AsmWrite(tai_jcatch(hp).startlab.name);
+                 writer.AsmWrite(' to ');
+                 writer.AsmWrite(tai_jcatch(hp).stoplab.name);
+                 writer.AsmWrite(' using ');
+                 writer.AsmWriteLn(tai_jcatch(hp).handlerlab.name);
                end;
              else
                internalerror(2010122707);
@@ -519,14 +550,14 @@ implementation
         superclass:=nil;
 
         { JVM 1.5+ }
-        AsmWriteLn('.bytecode 49.0');
+        writer.AsmWriteLn('.bytecode 49.0');
         // include files are not support by Java, and the directory of the main
         // source file must not be specified
         if current_module.mainsource<>'' then
           n:=ExtractFileName(current_module.mainsource)
         else
           n:=InputFileName;
-        AsmWriteLn('.source '+ExtractFileName(n));
+        writer.AsmWriteLn('.source '+ExtractFileName(n));
 
         { class/interface name }
         if not assigned(obj) then
@@ -534,11 +565,11 @@ implementation
             { fake class type for unit -> name=unitname and
               superclass=java.lang.object, make final so you cannot descend
               from it }
-            AsmWrite('.class final public ');
+            writer.AsmWrite('.class final public ');
             if assigned(current_module.namespace) then
-              AsmWrite(current_module.namespace^+'.');
-            AsmWriteln(current_module.realmodulename^);
-            AsmWriteLn('.super java/lang/Object');
+              writer.AsmWrite(current_module.namespace^+'.');
+            writer.AsmWriteln(current_module.realmodulename^);
+            writer.AsmWriteLn('.super java/lang/Object');
           end
         else
           begin
@@ -549,10 +580,10 @@ implementation
               recorddef:
                 begin
                   { can't inherit from records }
-                  AsmWrite('.class final ');
+                  writer.AsmWrite('.class final ');
                   if toplevelowner.symtabletype=globalsymtable then
-                    AsmWrite('public ');
-                  AsmWriteln(obj.jvm_full_typename(true));
+                    writer.AsmWrite('public ');
+                  writer.AsmWriteln(obj.jvm_full_typename(true));
                   superclass:=java_fpcbaserecordtype;
                 end;
               objectdef:
@@ -560,25 +591,25 @@ implementation
                   case tobjectdef(obj).objecttype of
                     odt_javaclass:
                       begin
-                        AsmWrite('.class ');
+                        writer.AsmWrite('.class ');
                         if oo_is_sealed in tobjectdef(obj).objectoptions then
-                          AsmWrite('final ');
+                          writer.AsmWrite('final ');
                         if (oo_is_abstract in tobjectdef(obj).objectoptions) or
                            (tobjectdef(obj).abstractcnt<>0) then
-                          AsmWrite('abstract ');
+                          writer.AsmWrite('abstract ');
                         if toplevelowner.symtabletype=globalsymtable then
-                          AsmWrite('public ');
+                          writer.AsmWrite('public ');
                         if (oo_is_enum_class in tobjectdef(obj).objectoptions) then
-                          AsmWrite('enum ');
-                        AsmWriteln(obj.jvm_full_typename(true));
+                          writer.AsmWrite('enum ');
+                        writer.AsmWriteln(obj.jvm_full_typename(true));
                         superclass:=tobjectdef(obj).childof;
                       end;
                     odt_interfacejava:
                       begin
-                        AsmWrite('.interface abstract ');
+                        writer.AsmWrite('.interface abstract ');
                         if toplevelowner.symtabletype=globalsymtable then
-                          AsmWrite('public ');
-                        AsmWriteLn(obj.jvm_full_typename(true));
+                          writer.AsmWrite('public ');
+                        writer.AsmWriteLn(obj.jvm_full_typename(true));
                         { interfaces must always specify Java.lang.object as
                           superclass }
                         superclass:=java_jlobject;
@@ -591,10 +622,10 @@ implementation
             { superclass }
             if assigned(superclass) then
               begin
-                AsmWrite('.super ');
+                writer.AsmWrite('.super ');
                 if assigned(superclass.import_lib) then
-                  AsmWrite(superclass.import_lib^+'/');
-                AsmWriteln(superclass.objextname^);
+                  writer.AsmWrite(superclass.import_lib^+'/');
+                writer.AsmWriteln(superclass.objextname^);
               end;
             { implemented interfaces }
             if (obj.typ=objectdef) and
@@ -603,26 +634,26 @@ implementation
                 for i:=0 to tobjectdef(obj).ImplementedInterfaces.count-1 do
                   begin
                     intf:=TImplementedInterface(tobjectdef(obj).ImplementedInterfaces[i]).IntfDef;
-                    AsmWrite('.implements ');
-                    AsmWriteLn(intf.jvm_full_typename(true));
+                    writer.AsmWrite('.implements ');
+                    writer.AsmWriteLn(intf.jvm_full_typename(true));
                   end;
               end;
             { signature for enum classes (must come after superclass and
               implemented interfaces) }
             if (obj.typ=objectdef) and
                (oo_is_enum_class in tobjectdef(obj).objectoptions) then
-              AsmWriteln('.signature "Ljava/lang/Enum<L'+obj.jvm_full_typename(true)+';>;"');
+              writer.AsmWriteln('.signature "Ljava/lang/Enum<L'+obj.jvm_full_typename(true)+';>;"');
             { in case of nested class: relation to parent class }
             if obj.owner.symtabletype in [objectsymtable,recordsymtable] then
-              AsmWriteln(InnerStructDef(obj));
+              writer.AsmWriteln(InnerStructDef(obj));
             { add all nested classes }
             for i:=0 to obj.symtable.deflist.count-1 do
               if (is_java_class_or_interface(tdef(obj.symtable.deflist[i])) or
                   (tdef(obj.symtable.deflist[i]).typ=recorddef)) and
                  not(df_generic in tdef(obj.symtable.deflist[i]).defoptions) then
-                AsmWriteln(InnerStructDef(tabstractrecorddef(obj.symtable.deflist[i])));
+                writer.AsmWriteln(InnerStructDef(tabstractrecorddef(obj.symtable.deflist[i])));
           end;
-        AsmLn;
+        writer.AsmLn;
       end;
 
 
@@ -686,17 +717,15 @@ implementation
 
    procedure TJasminAssembler.NewAsmFileForStructDef(obj: tabstractrecorddef);
       begin
-        if AsmSize<>AsmStartSize then
+        if not writer.ClearIfEmpty then
           begin
-            AsmClose;
+            writer.AsmClose;
             asmfiles.Concat(AsmFileName);
-          end
-        else
-          AsmClear;
+          end;
 
         AsmFileName:=obj.jvm_full_typename(false);
         AsmFileName:=Path+FixFileName(AsmFileName)+target_info.asmext;
-        AsmCreate(cut_normal);
+        writer.AsmCreate(cut_normal);
       end;
 
 
@@ -912,17 +941,17 @@ implementation
            (not is_javainterface(pd.struct) or
             (pd.proctypeoption in [potype_unitinit,potype_unitfinalize])) then
           exit;
-        AsmWrite('.method ');
-        AsmWriteln(MethodDefinition(pd));
+        writer.AsmWrite('.method ');
+        writer.AsmWriteln(MethodDefinition(pd));
         if jvmtypeneedssignature(pd) then
           begin
-            AsmWrite('.signature "');
-            AsmWrite(tcpuprocdef(pd).jvmmangledbasename(true));
-            AsmWriteln('"');
+            writer.AsmWrite('.signature "');
+            writer.AsmWrite(tcpuprocdef(pd).jvmmangledbasename(true));
+            writer.AsmWriteln('"');
           end;
         WriteTree(tcpuprocdef(pd).exprasmlist);
-        AsmWriteln('.end method');
-        AsmLn;
+        writer.AsmWriteln('.end method');
+        writer.AsmLn;
       end;
 
 
@@ -935,15 +964,15 @@ implementation
         { external or threadvar definition -> no definition here }
         if ([vo_is_external,vo_is_thread_var]*sym.varoptions)<>[] then
           exit;
-        AsmWrite('.field ');
-        AsmWriteln(FieldDefinition(sym));
+        writer.AsmWrite('.field ');
+        writer.AsmWriteln(FieldDefinition(sym));
       end;
 
 
     procedure TJasminAssembler.WriteConstSym(sym: tconstsym);
       begin
-        AsmWrite('.field ');
-        AsmWriteln(ConstDefinition(sym));
+        writer.AsmWrite('.field ');
+        writer.AsmWriteln(ConstDefinition(sym));
       end;
 
 
@@ -1042,7 +1071,7 @@ implementation
             NewAsmFileForStructDef(obj);
             WriteExtraHeader(obj);
             WriteSymtableVarSyms(obj.symtable);
-            AsmLn;
+            writer.AsmLn;
             WriteSymtableProcDefs(obj.symtable);
             WriteSymtableStructDefs(obj.symtable);
           end;
@@ -1051,7 +1080,7 @@ implementation
 
     constructor TJasminAssembler.Create(smart: boolean);
       begin
-        inherited create(smart);
+        inherited CreateWithWriter(TJasminAssemblerOutputFile.Create(self),true,smart);
         InstrWriter:=TJasminInstrWriter.Create(self);
         asmfiles:=TCmdStrList.Create;
       end;
@@ -1064,20 +1093,20 @@ implementation
        Comment(V_Debug,'Start writing Jasmin-styled assembler output for '+current_module.mainsource);
 {$endif}
 
-      AsmStartSize:=AsmSize;
+      writer.MarkEmpty;
       WriteExtraHeader(nil);
 (*
       for hal:=low(TasmlistType) to high(TasmlistType) do
         begin
-          AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
+          writer.AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
           writetree(current_asmdata.asmlists[hal]);
-          AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
+          writer.AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
         end;
 *)
       { print all global variables }
       WriteSymtableVarSyms(current_module.globalsymtable);
       WriteSymtableVarSyms(current_module.localsymtable);
-      AsmLn;
+      writer.AsmLn;
       { print all global procedures/functions }
       WriteSymtableProcdefs(current_module.globalsymtable);
       WriteSymtableProcdefs(current_module.localsymtable);
@@ -1085,7 +1114,7 @@ implementation
       WriteSymtableStructDefs(current_module.globalsymtable);
       WriteSymtableStructDefs(current_module.localsymtable);
 
-      AsmLn;
+      writer.AsmLn;
 {$ifdef EXTDEBUG}
       if assigned(current_module.mainsource) then
        Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource);
@@ -1093,28 +1122,6 @@ implementation
     end;
 
 
-    procedure TJasminAssembler.RemoveAsm;
-      var
-        g : file;
-      begin
-        inherited;
-        if cs_asm_leave in current_settings.globalswitches then
-         exit;
-        while not asmfiles.empty do
-          begin
-            if cs_asm_extern in current_settings.globalswitches then
-             AsmRes.AddDeleteCommand(asmfiles.GetFirst)
-            else
-             begin
-               assign(g,asmfiles.GetFirst);
-               {$I-}
-                erase(g);
-               {$I+}
-               if ioresult<>0 then;
-             end;
-          end;
-      end;
-
 {****************************************************************************}
 {                         Jasmin Instruction Writer                          }
 {****************************************************************************}
@@ -1205,7 +1212,7 @@ implementation
                  sep:=' ';
               end;
           end;
-        owner.AsmWriteLn(s);
+        owner.writer.AsmWriteLn(s);
       end;
 
 {****************************************************************************}

+ 128 - 132
compiler/llvm/agllvm.pas

@@ -32,7 +32,6 @@ interface
 
     type
       TLLVMInstrWriter = class;
-      { TLLVMAssember }
 
       TLLVMAssember=class(texternalassembler)
       protected
@@ -48,7 +47,6 @@ interface
         procedure WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
        public
         constructor create(smart: boolean); override;
-        procedure AsmLn; override;
         function MakeCmdLine: TCmdStr; override;
         procedure WriteTree(p:TAsmList);override;
         procedure WriteAsmList;override;
@@ -316,7 +314,7 @@ implementation
              tmpinline:=1;
              tmpasmblock:=false;
              hp:=o.ai;
-             owner.AsmWrite(fstr);
+             owner.writer.AsmWrite(fstr);
              fstr:='';
              owner.WriteTai(false,false,tmpinline,tmpasmblock,hp);
              result:='';
@@ -349,7 +347,7 @@ implementation
         (and their output must come after everything that was processed in this
          instruction, such as its opcode or previous operands) }
       if owner.fdecllevel=0 then
-        owner.AsmWrite(#9);
+        owner.writer.AsmWrite(#9);
       sep:=' ';
       done:=false;
       opstart:=0;
@@ -357,9 +355,9 @@ implementation
       case op of
         la_type:
            begin
-             owner.asmwrite(llvmtypeidentifier(taillvm(hp).oper[0]^.def));
-             owner.asmwrite(' = type ');
-             owner.asmwrite(llvmencodetypedecl(taillvm(hp).oper[0]^.def));
+             owner.writer.AsmWrite(llvmtypeidentifier(taillvm(hp).oper[0]^.def));
+             owner.writer.AsmWrite(' = type ');
+             owner.writer.AsmWrite(llvmencodetypedecl(taillvm(hp).oper[0]^.def));
              done:=true;
            end;
         la_ret, la_br, la_switch, la_indirectbr,
@@ -375,13 +373,13 @@ implementation
         la_call:
           begin
             if taillvm(hp).oper[1]^.reg<>NR_NO then
-              owner.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
+              owner.writer.AsmWrite(getregisterstring(taillvm(hp).oper[1]^.reg)+' = ');
             sep:=' ';
             opstart:=2;
           end;
         la_alloca:
           begin
-            owner.AsmWrite(getreferencestring(taillvm(hp).oper[0]^.ref^,false)+' = ');
+            owner.writer.AsmWrite(getreferencestring(taillvm(hp).oper[0]^.ref^,false)+' = ');
             sep:=' ';
             opstart:=1;
           end;
@@ -394,27 +392,27 @@ implementation
               data initialisers }
             if (taillvm(hp).oper[0]^.typ<>top_reg) or
                (taillvm(hp).oper[0]^.reg<>NR_NO) then
-              owner.AsmWrite(getopstr(taillvm(hp).oper[0]^,false)+' = ')
+              owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,false)+' = ')
             else
               nested:=true;
-            owner.AsmWrite(llvm_op2str[op]);
+            owner.writer.AsmWrite(llvm_op2str[op]);
             if not nested then
-              owner.AsmWrite(' ')
+              owner.writer.AsmWrite(' ')
             else
-              owner.AsmWrite(' (');
-            owner.AsmWrite(getopstr(taillvm(hp).oper[1]^,false));
+              owner.writer.AsmWrite(' (');
+            owner.writer.AsmWrite(getopstr(taillvm(hp).oper[1]^,false));
             { if there's a tai operand, its def is used instead of an
               explicit def operand }
             if taillvm(hp).ops=4 then
               begin
-                owner.AsmWrite(' ');
-                owner.AsmWrite(getopstr(taillvm(hp).oper[2]^,false));
+                owner.writer.AsmWrite(' ');
+                owner.writer.AsmWrite(getopstr(taillvm(hp).oper[2]^,false));
                 opstart:=3;
               end
             else
               opstart:=2;
-            owner.AsmWrite(' to ');
-            owner.AsmWrite(getopstr(taillvm(hp).oper[opstart]^,false));
+            owner.writer.AsmWrite(' to ');
+            owner.writer.AsmWrite(getopstr(taillvm(hp).oper[opstart]^,false));
             done:=true;
           end
         else
@@ -422,7 +420,7 @@ implementation
             if (taillvm(hp).oper[0]^.typ<>top_reg) or
                (taillvm(hp).oper[0]^.reg<>NR_NO) then
               begin
-                owner.AsmWrite(getopstr(taillvm(hp).oper[0]^,true)+' = ');
+                owner.writer.AsmWrite(getopstr(taillvm(hp).oper[0]^,true)+' = ');
               end
             else
               nested:=true;
@@ -433,15 +431,15 @@ implementation
       { process operands }
       if not done then
         begin
-          owner.AsmWrite(llvm_op2str[op]);
+          owner.writer.AsmWrite(llvm_op2str[op]);
           if nested then
-            owner.AsmWrite(' (');
+            owner.writer.AsmWrite(' (');
           if taillvm(hp).ops<>0 then
             begin
               for i:=opstart to taillvm(hp).ops-1 do
                 begin
-                   owner.AsmWrite(sep);
-                   owner.AsmWrite(getopstr(taillvm(hp).oper[i]^,op in [la_load,la_store]));
+                   owner.writer.AsmWrite(sep);
+                   owner.writer.AsmWrite(getopstr(taillvm(hp).oper[i]^,op in [la_load,la_store]));
                    if (taillvm(hp).oper[i]^.typ in [top_def,top_cond,top_fpcond]) or
                       (op=la_call) then
                      sep :=' '
@@ -451,13 +449,14 @@ implementation
             end;
         end;
       if op=la_alloca then
-        owner.AsmWrite(getreferencealignstring(taillvm(hp).oper[0]^.ref^));
+        owner.writer.AsmWrite(getreferencealignstring(taillvm(hp).oper[0]^.ref^));
       if nested then
-        owner.AsmWrite(')')
-      else
-        owner.AsmLn;
+        owner.writer.AsmWrite(')')
+      else if owner.fdecllevel=0 then
+        owner.writer.AsmLn;
     end;
 
+
 {****************************************************************************}
 {                          LLVM Assembler writer                              }
 {****************************************************************************}
@@ -548,12 +547,12 @@ implementation
 
     procedure TLLVMAssember.WriteExtraHeader;
       begin
-        AsmWrite('target datalayout = "');
-        AsmWrite(target_info.llvmdatalayout);
-        AsmWriteln('"');
-        AsmWrite('target triple = "');
-        AsmWrite(llvm_target_name);
-        AsmWriteln('"');
+        writer.AsmWrite('target datalayout = "');
+        writer.AsmWrite(target_info.llvmdatalayout);
+        writer.AsmWriteln('"');
+        writer.AsmWrite('target triple = "');
+        writer.AsmWrite(llvm_target_name);
+        writer.AsmWriteln('"');
       end;
 
 
@@ -581,32 +580,32 @@ implementation
           begin
             case tai_realconst(hp).realtyp of
               aitrealconst_s32bit:
-                AsmWriteLn(target_asm.comment+'value: '+single2str(tai_realconst(hp).value.s32val));
+                writer.AsmWriteLn(target_asm.comment+'value: '+single2str(tai_realconst(hp).value.s32val));
               aitrealconst_s64bit:
-                AsmWriteLn(target_asm.comment+'value: '+double2str(tai_realconst(hp).value.s64val));
+                writer.AsmWriteLn(target_asm.comment+'value: '+double2str(tai_realconst(hp).value.s64val));
 {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
               { can't write full 80 bit floating point constants yet on non-x86 }
               aitrealconst_s80bit:
-                AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s80val));
+                writer.AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s80val));
 {$endif cpuextended}
               aitrealconst_s64comp:
-                AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s64compval));
+                writer.AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_realconst(hp).value.s64compval));
               else
                 internalerror(2014050604);
             end;
           end;
         case hp.realtyp of
           aitrealconst_s32bit:
-            AsmWriteln(llvmdoubletostr(hp.value.s32val));
+            writer.AsmWriteln(llvmdoubletostr(hp.value.s32val));
           aitrealconst_s64bit:
-            AsmWriteln(llvmdoubletostr(hp.value.s64val));
+            writer.AsmWriteln(llvmdoubletostr(hp.value.s64val));
 {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
           aitrealconst_s80bit:
-            AsmWriteln(llvmextendedtostr(hp.value.s80val));
+            writer.AsmWriteln(llvmextendedtostr(hp.value.s80val));
 {$endif defined(cpuextended)}
           aitrealconst_s64comp:
             { handled as int64 most of the time in llvm }
-            AsmWriteln(tostr(round(hp.value.s64compval)));
+            writer.AsmWriteln(tostr(round(hp.value.s64compval)));
           else
             internalerror(2014062401);
         end;
@@ -618,7 +617,7 @@ implementation
         consttyp: taiconst_type;
       begin
         if fdecllevel=0 then
-          asmwrite(target_asm.comment+' const ');
+          writer.AsmWrite(target_asm.comment+' const ');
         consttyp:=hp.consttype;
         case consttyp of
           aitconst_got,
@@ -642,26 +641,27 @@ implementation
           aitconst_64bit_unaligned:
             begin
               if fdecllevel=0 then
-                AsmWrite(target_asm.comment);
+                writer.AsmWrite(target_asm.comment);
               { can't have compile-time differences between symbols; these are
                 normally for PIC, but llvm takes care of that for us }
               if assigned(hp.endsym) then
                 internalerror(2014052902);
               if assigned(hp.sym) then
                 begin
-                  AsmWrite(LlvmAsmSymName(hp.sym));
+                  writer.AsmWrite(LlvmAsmSymName(hp.sym));
                   { can't have offsets }
                   if hp.value<>0 then
                     if fdecllevel<>0 then
                       internalerror(2014052903)
                     else
-                      asmwrite(' -- symbol offset: ' + tostr(hp.value));
+                      writer.AsmWrite(' -- symbol offset: ' + tostr(hp.value));
                 end
               else if hp.value=0 then
-                AsmWrite('zeroinitializer')
+                writer.AsmWrite('zeroinitializer')
               else
-                AsmWrite(tostr(hp.value));
-              AsmLn;
+                writer.AsmWrite(tostr(hp.value));
+              if fdecllevel=0 then
+                writer.AsmLn;
             end;
           else
             internalerror(200704251);
@@ -683,38 +683,38 @@ implementation
           case hp.adetyp of
             tck_record:
               begin
-                AsmWrite(defstr);
-                AsmWrite(' ');
+                writer.AsmWrite(defstr);
+                writer.AsmWrite(' ');
                 if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
-                  AsmWrite('<{')
+                  writer.AsmWrite('<{')
                 else
-                  AsmWrite('{');
+                  writer.AsmWrite('{');
                 first:=true;
                 for p in tai_aggregatetypedconst(hp) do
                   begin
                     if not first then
-                      AsmWrite(', ')
+                      writer.AsmWrite(', ')
                     else
                       first:=false;
                     WriteTypedConstData(p);
                   end;
                 if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
-                  AsmWrite('}>')
+                  writer.AsmWrite('}>')
                 else
-                  AsmWrite('}');
+                  writer.AsmWrite('}');
               end;
             tck_array:
               begin
-                AsmWrite(defstr);
+                writer.AsmWrite(defstr);
                 first:=true;
                 gotstring:=false;
                 for p in tai_aggregatetypedconst(hp) do
                   begin
                     if not first then
-                      AsmWrite(',')
+                      writer.AsmWrite(',')
                     else
                       begin
-                        AsmWrite(' ');
+                        writer.AsmWrite(' ');
                         if (tai_abstracttypedconst(p).adetyp=tck_simple) and
                            (tai_simpletypedconst(p).val.typ=ait_string) then
                           begin
@@ -722,7 +722,7 @@ implementation
                           end
                         else
                           begin
-                            AsmWrite('[');
+                            writer.AsmWrite('[');
                           end;
                         first:=false;
                       end;
@@ -734,15 +734,15 @@ implementation
                     WriteTypedConstData(p);
                   end;
                 if not gotstring then
-                  AsmWrite(']');
+                  writer.AsmWrite(']');
               end;
             tck_simple:
               begin
                 pval:=tai_simpletypedconst(hp).val;
                 if pval.typ<>ait_string then
                   begin
-                    AsmWrite(defstr);
-                    AsmWrite(' ');
+                    writer.AsmWrite(defstr);
+                    writer.AsmWrite(' ');
                   end;
                 WriteTai(replaceforbidden,do_line,InlineLevel,asmblock,pval);
               end;
@@ -758,27 +758,29 @@ implementation
         case hp.typ of
           ait_comment :
             begin
-              AsmWrite(target_asm.comment);
-              AsmWritePChar(tai_comment(hp).str);
-              AsmLn;
+              writer.AsmWrite(target_asm.comment);
+              writer.AsmWritePChar(tai_comment(hp).str);
+              if fdecllevel<>0 then
+                internalerror(2015090601);
+              writer.AsmLn;
             end;
 
           ait_regalloc :
             begin
               if (cs_asm_regalloc in current_settings.globalswitches) then
                 begin
-                  AsmWrite(#9+target_asm.comment+'Register ');
+                  writer.AsmWrite(#9+target_asm.comment+'Register ');
                   repeat
-                    AsmWrite(std_regname(Tai_regalloc(hp).reg));
+                    writer.AsmWrite(std_regname(Tai_regalloc(hp).reg));
                      if (hp.next=nil) or
                        (tai(hp.next).typ<>ait_regalloc) or
                        (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
                       break;
                     hp:=tai(hp.next);
-                    AsmWrite(',');
+                    writer.AsmWrite(',');
                   until false;
-                  AsmWrite(' ');
-                  AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
+                  writer.AsmWrite(' ');
+                  writer.AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
                 end;
             end;
 
@@ -798,8 +800,8 @@ implementation
 
           ait_datablock :
             begin
-              AsmWrite(target_asm.comment);
-              AsmWriteln('datablock');
+              writer.AsmWrite(target_asm.comment);
+              writer.AsmWriteln('datablock');
             end;
 
           ait_const:
@@ -815,8 +817,8 @@ implementation
           ait_string :
             begin
               if fdecllevel=0 then
-                AsmWrite(target_asm.comment);
-              AsmWrite('c"');
+                writer.AsmWrite(target_asm.comment);
+              writer.AsmWrite('c"');
               for i:=1 to tai_string(hp).len do
                begin
                  ch:=tai_string(hp).str[i-1];
@@ -829,9 +831,9 @@ implementation
                  else
                    s:=ch;
                  end;
-                 AsmWrite(s);
+                 writer.AsmWrite(s);
                end;
-              AsmWriteLn('"');
+              writer.AsmWriteLn('"');
             end;
 
           ait_label :
@@ -848,21 +850,21 @@ implementation
                    begin
                      { should be emitted as part of the variable/function def }
                      //internalerror(2013010704);
-                     AsmWriteln(target_asm.comment+'global/privateextern label: '+tai_label(hp).labsym.name);
+                     writer.AsmWriteln(target_asm.comment+'global/privateextern label: '+tai_label(hp).labsym.name);
                    end;
                  if replaceforbidden then
-                   AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
+                   writer.AsmWrite(ReplaceForbiddenAsmSymbolChars(tai_label(hp).labsym.name))
                  else
-                   AsmWrite(tai_label(hp).labsym.name);
-                 AsmWriteLn(':');
+                   writer.AsmWrite(tai_label(hp).labsym.name);
+                 writer.AsmWriteLn(':');
                end;
             end;
 
           ait_symbol :
             begin
               if fdecllevel=0 then
-                AsmWrite(target_asm.comment);
-              AsmWriteln(LlvmAsmSymName(tai_symbol(hp).sym));
+                writer.AsmWrite(target_asm.comment);
+              writer.AsmWriteln(LlvmAsmSymName(tai_symbol(hp).sym));
               { todo }
               if tai_symbol(hp).has_value then
                 internalerror(2014062402);
@@ -873,48 +875,48 @@ implementation
                 begin
                   if taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL] then
                     begin
-                      asmwrite('declare');
-                      asmwriteln(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), taillvmdecl(hp).namesym.name, lpd_decl));
+                      writer.AsmWrite('declare');
+                      writer.AsmWriteln(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), taillvmdecl(hp).namesym.name, lpd_decl));
                     end
                   else
                     begin
-                      asmwrite('define');
-                      asmwrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), '', lpd_decl));
-                      asmwriteln(' {');
+                      writer.AsmWrite('define');
+                      writer.AsmWrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), '', lpd_decl));
+                      writer.AsmWriteln(' {');
                     end;
                 end
               else
                 begin
-                  asmwrite(LlvmAsmSymName(taillvmdecl(hp).namesym));
+                  writer.AsmWrite(LlvmAsmSymName(taillvmdecl(hp).namesym));
                   case taillvmdecl(hp).namesym.bind of
                     AB_EXTERNAL:
-                      asmwrite(' = external ');
+                      writer.AsmWrite(' = external ');
                     AB_COMMON:
-                      asmwrite(' = common ');
+                      writer.AsmWrite(' = common ');
                     AB_LOCAL:
-                      asmwrite(' = internal ');
+                      writer.AsmWrite(' = internal ');
                     AB_GLOBAL:
-                      asmwrite(' = ');
+                      writer.AsmWrite(' = ');
                     AB_WEAK_EXTERNAL:
-                      asmwrite(' = extern_weak ');
+                      writer.AsmWrite(' = extern_weak ');
                     AB_PRIVATE_EXTERN:
-                      asmwrite('= linker_private ');
+                      writer.AsmWrite('= linker_private ');
                     else
                       internalerror(2014020104);
                   end;
                   if taillvmdecl(hp).tls then
-                    asmwrite('thread_local ');
+                    writer.AsmWrite('thread_local ');
                   { todo: handle more different section types (mainly
                       Objective-C }
                   if taillvmdecl(hp).sec in [sec_rodata,sec_rodata_norel] then
-                    asmwrite('unnamed_addr constant ')
+                    writer.AsmWrite('unnamed_addr constant ')
                   else
-                    asmwrite('global ');
+                    writer.AsmWrite('global ');
                   if not assigned(taillvmdecl(hp).initdata) then
                     begin
-                      asmwrite(llvmencodetypename(taillvmdecl(hp).def));
+                      writer.AsmWrite(llvmencodetypename(taillvmdecl(hp).def));
                       if not(taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL]) then
-                        asmwrite(' zeroinitializer');
+                        writer.AsmWrite(' zeroinitializer');
                     end
                   else
                     begin
@@ -933,32 +935,32 @@ implementation
                       dec(fdecllevel);
                     end;
                   { alignment }
-                  asmwrite(', align ');
-                  asmwriteln(tostr(taillvmdecl(hp).alignment));
+                  writer.AsmWrite(', align ');
+                  writer.AsmWriteln(tostr(taillvmdecl(hp).alignment));
                 end;
             end;
           ait_llvmalias:
             begin
-              asmwrite(LlvmAsmSymName(taillvmalias(hp).newsym));
-              asmwrite(' = alias ');
+              writer.AsmWrite(LlvmAsmSymName(taillvmalias(hp).newsym));
+              writer.AsmWrite(' = alias ');
               if taillvmalias(hp).linkage<>lll_default then
                 begin
                   str(taillvmalias(hp).linkage, s);
-                  asmwrite(copy(s, length('lll_')+1, 255));
-                  asmwrite(' ');
+                  writer.AsmWrite(copy(s, length('lll_')+1, 255));
+                  writer.AsmWrite(' ');
                 end;
               if taillvmalias(hp).vis<>llv_default then
                 begin
                   str(taillvmalias(hp).vis, s);
-                  asmwrite(copy(s, length('llv_')+1, 255));
-                  asmwrite(' ');
+                  writer.AsmWrite(copy(s, length('llv_')+1, 255));
+                  writer.AsmWrite(' ');
                 end;
               if taillvmalias(hp).def.typ=procdef then
-                asmwrite(llvmencodeproctype(tabstractprocdef(taillvmalias(hp).def), '', lpd_alias))
+                writer.AsmWrite(llvmencodeproctype(tabstractprocdef(taillvmalias(hp).def), '', lpd_alias))
               else
-                asmwrite(llvmencodetypename(taillvmalias(hp).def));
-              asmwrite('* ');
-              asmwriteln(LlvmAsmSymName(taillvmalias(hp).oldsym));
+                writer.AsmWrite(llvmencodetypename(taillvmalias(hp).def));
+              writer.AsmWrite('* ');
+              writer.AsmWriteln(LlvmAsmSymName(taillvmalias(hp).oldsym));
             end;
           ait_symbolpair:
             begin
@@ -975,9 +977,9 @@ implementation
           ait_symbol_end :
             begin
               if tai_symbol_end(hp).sym.typ=AT_FUNCTION then
-                asmwriteln('}')
+                writer.AsmWriteln('}')
               else
-                asmwriteln('; ait_symbol_end error, should not be generated');
+                writer.AsmWriteln('; ait_symbol_end error, should not be generated');
 //                internalerror(2013010711);
             end;
 
@@ -1022,8 +1024,10 @@ implementation
             begin
               WriteDirectiveName(tai_directive(hp).directive);
               if tai_directive(hp).name <>'' then
-                AsmWrite(tai_directive(hp).name);
-              AsmLn;
+                writer.AsmWrite(tai_directive(hp).name);
+              if fdecllevel<>0 then
+                internalerror(2015090602);
+              writer.AsmLn;
             end;
 
           ait_seh_directive :
@@ -1033,12 +1037,14 @@ implementation
           ait_varloc:
             begin
               if tai_varloc(hp).newlocationhi<>NR_NO then
-                AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
+                writer.AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
                   std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation)))
               else
-                AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
+                writer.AsmWrite(strpnew('Var '+tai_varloc(hp).varsym.realname+' located in register '+
                   std_regname(tai_varloc(hp).newlocation)));
-              AsmLn;
+              if fdecllevel<>0 then
+                internalerror(2015090603);
+              writer.AsmLn;
             end;
            ait_typedconst:
              begin
@@ -1057,18 +1063,9 @@ implementation
       end;
 
 
-    procedure TLLVMAssember.AsmLn;
-      begin
-        { don't write newlines in the middle of declarations }
-        if fdecllevel=0 then
-          inherited AsmLn;
-      end;
-
-
-
     procedure TLLVMAssember.WriteDirectiveName(dir: TAsmDirective);
       begin
-        AsmWrite('.'+directivestr[dir]+' ');
+        writer.AsmWrite('.'+directivestr[dir]+' ');
       end;
 
 
@@ -1078,16 +1075,15 @@ implementation
         i: longint;
       begin
         WriteExtraHeader;
-        AsmStartSize:=AsmSize;
 
         for hal:=low(TasmlistType) to high(TasmlistType) do
           begin
-            AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
+            writer.AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
             writetree(current_asmdata.asmlists[hal]);
-            AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
+            writer.AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
           end;
 
-        AsmLn;
+        writer.AsmLn;
       end;
 
 

+ 2 - 2
compiler/m68k/ag68kgas.pas

@@ -281,7 +281,7 @@ interface
              { quick hack to overcome a problem with manglednames=255 chars }
              if calljmp then
                 begin
-                  owner.AsmWrite(s+#9);
+                  owner.writer.AsmWrite(s+#9);
                   s:=getopstr_jmp(taicpu(hp).oper[0]^);
                   { dbcc dx,<sym> has two operands! (KB) }
                   if (taicpu(hp).ops>1) then
@@ -310,7 +310,7 @@ interface
                     end;
                 end;
            end;
-           owner.AsmWriteLn(s);
+           owner.writer.AsmWriteLn(s);
        end;
 
 

+ 15 - 15
compiler/mips/cpugas.pas

@@ -248,42 +248,42 @@ unit cpugas;
         case op of
           A_P_SET_NOMIPS16:
             begin
-              owner.AsmWriteLn(#9'.set'#9'nomips16');
+              owner.writer.AsmWriteLn(#9'.set'#9'nomips16');
             end;
           A_P_MASK,
           A_P_FMASK:
             begin
               s := #9 + gas_op2str[op] + #9'0x' + hexstr(taicpu(hp).oper[0]^.val,8)+ ',' + getopstr(taicpu(hp).oper[1]^) ;
-              owner.AsmWriteLn(s);
+              owner.writer.AsmWriteLn(s);
             end;
           A_P_SET_MACRO:
             begin
-              owner.AsmWriteLn(#9'.set'#9'macro');
+              owner.writer.AsmWriteLn(#9'.set'#9'macro');
               TMIPSGNUAssembler(owner).nomacro:=false;
             end;
           A_P_SET_REORDER:
             begin
-              owner.AsmWriteLn(#9'.set'#9'reorder');
+              owner.writer.AsmWriteLn(#9'.set'#9'reorder');
               TMIPSGNUAssembler(owner).noreorder:=false;
             end;
           A_P_SET_NOMACRO:
             begin
-              owner.AsmWriteLn(#9'.set'#9'nomacro');
+              owner.writer.AsmWriteLn(#9'.set'#9'nomacro');
               TMIPSGNUAssembler(owner).nomacro:=true;
             end;
           A_P_SET_NOREORDER:
             begin
-              owner.AsmWriteLn(#9'.set'#9'noreorder');
+              owner.writer.AsmWriteLn(#9'.set'#9'noreorder');
               TMIPSGNUAssembler(owner).noreorder:=true;
             end;
           A_P_SET_NOAT:
             begin
-              owner.AsmWriteln(#9'.set'#9'noat');
+              owner.writer.AsmWriteln(#9'.set'#9'noat');
               TMIPSGNUAssembler(owner).noat:=true;
             end;
           A_P_SET_AT:
             begin
-              owner.AsmWriteln(#9'.set'#9'at');
+              owner.writer.AsmWriteln(#9'.set'#9'at');
               TMIPSGNUAssembler(owner).noat:=false;
             end;
           A_LDC1:
@@ -297,7 +297,7 @@ unit cpugas;
                 begin
                   tmpfpu := getopstr(taicpu(hp).oper[0]^);
                   s := #9 + gas_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
-                  owner.AsmWriteLn(s);
+                  owner.writer.AsmWriteLn(s);
 
 { bug if $f9/$f19
               tmpfpu_len := length(tmpfpu);
@@ -309,7 +309,7 @@ unit cpugas;
                   tmpfpu := asm_regname(r);
                   s := #9 + gas_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
                 end;
-              owner.AsmWriteLn(s);
+              owner.writer.AsmWriteLn(s);
             end;
           A_SDC1:
             begin
@@ -322,7 +322,7 @@ unit cpugas;
                 begin
                   tmpfpu := getopstr(taicpu(hp).oper[0]^);
                   s := #9 + gas_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
-                  owner.AsmWriteLn(s);
+                  owner.writer.AsmWriteLn(s);
 
 {
               tmpfpu_len := length(tmpfpu);
@@ -333,12 +333,12 @@ unit cpugas;
                   tmpfpu := asm_regname(r);
                   s := #9 + gas_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
                 end;
-              owner.AsmWriteLn(s);
+              owner.writer.AsmWriteLn(s);
             end;
           else
             begin
               if is_macro_instruction(taicpu(hp)) and TMIPSGNUAssembler(owner).nomacro then
-                owner.AsmWriteln(#9'.set'#9'macro');
+                owner.writer.AsmWriteln(#9'.set'#9'macro');
               s := #9 + gas_op2str[op] + cond2str[taicpu(hp).condition];
               if taicpu(hp).delayslot_annulled then
                 s := s + ',a';
@@ -348,9 +348,9 @@ unit cpugas;
                 for i := 1 to taicpu(hp).ops - 1 do
                   s := s + ',' + getopstr(taicpu(hp).oper[i]^);
               end;
-              owner.AsmWriteLn(s);
+              owner.writer.AsmWriteLn(s);
               if is_macro_instruction(taicpu(hp)) and TMIPSGNUAssembler(owner).nomacro then
-                owner.AsmWriteln(#9'.set'#9'nomacro');
+                owner.writer.AsmWriteln(#9'.set'#9'nomacro');
             end;
         end;
       end;

+ 167 - 167
compiler/powerpc/agppcmpw.pas

@@ -392,7 +392,7 @@ interface
             begin
               { first write the current contents of s, because the symbol }
               { may be 255 characters                                     }
-              asmwrite(s);
+              writer.AsmWrite(s);
               s:=getopstr_jmp(taicpu(hp).oper[0]^);
             end;
         end
@@ -410,7 +410,7 @@ interface
                  end;
             end;
         end;
-      AsmWriteLn(s);
+      writer.AsmWriteLn(s);
     end;
 
     {*** Until here is copyed from agppcgas.pp. ***}
@@ -523,41 +523,41 @@ interface
 
         if not use_PR then
           begin
-            AsmWrite(#9'export'#9'.');
-            AsmWrite(s);
+            writer.AsmWrite(#9'export'#9'.');
+            writer.AsmWrite(s);
             if replaced then
               begin
-                AsmWrite(' => ''.');
-                AsmWrite(tai_symbol(hp).sym.name);
-                AsmWrite('''');
+                writer.AsmWrite(' => ''.');
+                writer.AsmWrite(tai_symbol(hp).sym.name);
+                writer.AsmWrite('''');
               end;
-            AsmLn;
+            writer.AsmLn;
           end;
 
-        AsmWrite(#9'export'#9);
-        AsmWrite(s);
-        AsmWrite('[DS]');
+        writer.AsmWrite(#9'export'#9);
+        writer.AsmWrite(s);
+        writer.AsmWrite('[DS]');
         if replaced then
           begin
-            AsmWrite(' => ''');
-            AsmWrite(tai_symbol(hp).sym.name);
-            AsmWrite('[DS]''');
+            writer.AsmWrite(' => ''');
+            writer.AsmWrite(tai_symbol(hp).sym.name);
+            writer.AsmWrite('[DS]''');
           end;
-        AsmLn;
+        writer.AsmLn;
 
         {Entry in transition vector: }
-        AsmWrite(#9'csect'#9); AsmWrite(s); AsmWriteLn('[DS]');
+        writer.AsmWrite(#9'csect'#9); writer.AsmWrite(s); writer.AsmWriteLn('[DS]');
 
-        AsmWrite(#9'dc.l'#9'.'); AsmWriteLn(s);
+        writer.AsmWrite(#9'dc.l'#9'.'); writer.AsmWriteLn(s);
 
-        AsmWriteln(#9'dc.l'#9'TOC[tc0]');
+        writer.AsmWriteln(#9'dc.l'#9'TOC[tc0]');
 
         {Entry in TOC: }
-        AsmWriteLn(#9'toc');
+        writer.AsmWriteLn(#9'toc');
 
-        AsmWrite(#9'tc'#9);
-        AsmWrite(s); AsmWrite('[TC],');
-        AsmWrite(s); AsmWriteln('[DS]');
+        writer.AsmWrite(#9'tc'#9);
+        writer.AsmWrite(s); writer.AsmWrite('[TC],');
+        writer.AsmWrite(s); writer.AsmWriteln('[DS]');
       end;
 
     function GetAdjacentTaiSymbol(var hp:tai):Boolean;
@@ -576,7 +576,7 @@ interface
             hp:=tai(hp.next);
           else
             begin
-              //AsmWriteln('  ;#*#*# ' + tostr(Ord(tai(hp.next).typ)));
+              //writer.AsmWriteln('  ;#*#*# ' + tostr(Ord(tai(hp.next).typ)));
               Break;
             end;
         end;
@@ -603,32 +603,32 @@ interface
 
       if use_PR then
         begin
-          AsmWrite(#9'export'#9'.'); AsmWrite(s); AsmWrite('[PR]');
+          writer.AsmWrite(#9'export'#9'.'); writer.AsmWrite(s); writer.AsmWrite('[PR]');
           if replaced then
             begin
-              AsmWrite(' => ''.');
-              AsmWrite(tai_symbol(last).sym.name);
-              AsmWrite('[PR]''');
+              writer.AsmWrite(' => ''.');
+              writer.AsmWrite(tai_symbol(last).sym.name);
+              writer.AsmWrite('[PR]''');
             end;
-          AsmLn;
+          writer.AsmLn;
         end;
 
       {Starts the section: }
-      AsmWrite(#9'csect'#9'.');
-      AsmWrite(s);
-      AsmWriteLn('[PR]');
+      writer.AsmWrite(#9'csect'#9'.');
+      writer.AsmWrite(s);
+      writer.AsmWriteLn('[PR]');
 
       {Info for the debugger: }
-      AsmWrite(#9'function'#9'.');
-      AsmWrite(s);
-      AsmWriteLn('[PR]');
+      writer.AsmWrite(#9'function'#9'.');
+      writer.AsmWrite(s);
+      writer.AsmWriteLn('[PR]');
 
       {Write all labels: }
       hp:= first;
       repeat
         s:= tai_symbol(hp).sym.name;
         ReplaceForbiddenChars(s);
-        AsmWrite('.'); AsmWrite(s); AsmWriteLn(':');
+        writer.AsmWrite('.'); writer.AsmWrite(s); writer.AsmWriteLn(':');
       until not GetAdjacentTaiSymbol(hp);
     end;
 
@@ -644,49 +644,49 @@ interface
 
       if isExported then
         begin
-          AsmWrite(#9'export'#9);
-          AsmWrite(s);
+          writer.AsmWrite(#9'export'#9);
+          writer.AsmWrite(s);
           if isConst then
-            AsmWrite(const_storage_class)
+            writer.AsmWrite(const_storage_class)
           else
-            AsmWrite(var_storage_class);
+            writer.AsmWrite(var_storage_class);
           if replaced then
               begin
-                AsmWrite(' => ''');
-                AsmWrite(sym);
-                AsmWrite('''');
+                writer.AsmWrite(' => ''');
+                writer.AsmWrite(sym);
+                writer.AsmWrite('''');
               end;
-          AsmLn;
+          writer.AsmLn;
         end;
 
       if not macos_direct_globals then
         begin
           {The actual section is here interrupted, by inserting a "tc" entry}
-          AsmWriteLn(#9'toc');
+          writer.AsmWriteLn(#9'toc');
 
-          AsmWrite(#9'tc'#9);
-          AsmWrite(s);
-          AsmWrite('[TC], ');
-          AsmWrite(s);
+          writer.AsmWrite(#9'tc'#9);
+          writer.AsmWrite(s);
+          writer.AsmWrite('[TC], ');
+          writer.AsmWrite(s);
           if isConst then
-            AsmWrite(const_storage_class)
+            writer.AsmWrite(const_storage_class)
           else
-            AsmWrite(var_storage_class);
-          AsmLn;
+            writer.AsmWrite(var_storage_class);
+          writer.AsmLn;
 
           {The interrupted section is here continued.}
-          AsmWrite(#9'csect'#9);
-          AsmWriteln(cur_CSECT_name+cur_CSECT_class);
-          AsmWrite(PadTabs(s+':',#0));
+          writer.AsmWrite(#9'csect'#9);
+          writer.AsmWriteln(cur_CSECT_name+cur_CSECT_class);
+          writer.AsmWrite(PadTabs(s+':',#0));
         end
       else
         begin
-          AsmWrite(#9'csect'#9);
-          AsmWrite(s);
-          AsmWrite('[TC]');
+          writer.AsmWrite(#9'csect'#9);
+          writer.AsmWrite(s);
+          writer.AsmWrite('[TC]');
         end;
 
-      AsmLn;
+      writer.AsmLn;
     end;
 
     const
@@ -734,9 +734,9 @@ interface
          case hp.typ of
             ait_comment:
               begin
-                 AsmWrite(target_asm.comment);
-                 AsmWritePChar(tai_comment(hp).str);
-                 AsmLn;
+                 writer.AsmWrite(target_asm.comment);
+                 writer.AsmWritePChar(tai_comment(hp).str);
+                 writer.AsmLn;
               end;
             ait_regalloc,
             ait_tempalloc:
@@ -744,7 +744,7 @@ interface
             ait_section:
               begin
                  {if LastSecType<>sec_none then
-                  AsmWriteLn('_'+target_asm.secnames[LastSecType]+#9#9'ENDS');}
+                  writer.AsmWriteLn('_'+target_asm.secnames[LastSecType]+#9#9'ENDS');}
 
                  if tai_section(hp).sectype<>sec_none then
                   begin
@@ -761,17 +761,17 @@ interface
                     ReplaceForbiddenChars(s);
                     cur_CSECT_name:= s;
 
-                    AsmLn;
-                    AsmWriteLn(#9+secnames[tai_section(hp).sectype]+' '+cur_CSECT_name+cur_CSECT_class);
+                    writer.AsmLn;
+                    writer.AsmWriteLn(#9+secnames[tai_section(hp).sectype]+' '+cur_CSECT_name+cur_CSECT_class);
                   end;
                  LastSecType:=tai_section(hp).sectype;
                end;
             ait_align:
               begin
                  case tai_align(hp).aligntype of
-                   1:AsmWriteLn(#9'align 0');
-                   2:AsmWriteLn(#9'align 1');
-                   4:AsmWriteLn(#9'align 2');
+                   1:writer.AsmWriteLn(#9'align 0');
+                   2:writer.AsmWriteLn(#9'align 1');
+                   4:writer.AsmWriteLn(#9'align 2');
                    otherwise internalerror(2002110302);
                  end;
               end;
@@ -782,11 +782,11 @@ interface
                  WriteDataHeader(s, tai_datablock(hp).is_global, false);
                  if not macos_direct_globals then
                    begin
-                     AsmWriteLn(#9'ds.b '+tostr(tai_datablock(hp).size));
+                     writer.AsmWriteLn(#9'ds.b '+tostr(tai_datablock(hp).size));
                    end
                  else
                    begin
-                     AsmWriteLn(PadTabs(s+':',#0)+'ds.b '+tostr(tai_datablock(hp).size));
+                     writer.AsmWriteLn(PadTabs(s+':',#0)+'ds.b '+tostr(tai_datablock(hp).size));
                      {TODO: ? PadTabs(s,#0) }
                    end;
               end;
@@ -803,20 +803,20 @@ interface
                       begin
                         if assigned(tai_const(hp).sym) then
                           internalerror(200404292);
-                        AsmWrite(ait_const2str[aitconst_32bit]);
+                        writer.AsmWrite(ait_const2str[aitconst_32bit]);
                         if target_info.endian = endian_little then
                           begin
-                            AsmWrite(tostr(longint(lo(tai_const(hp).value))));
-                            AsmWrite(',');
-                            AsmWrite(tostr(longint(hi(tai_const(hp).value))));
+                            writer.AsmWrite(tostr(longint(lo(tai_const(hp).value))));
+                            writer.AsmWrite(',');
+                            writer.AsmWrite(tostr(longint(hi(tai_const(hp).value))));
                           end
                         else
                           begin
-                            AsmWrite(tostr(longint(hi(tai_const(hp).value))));
-                            AsmWrite(',');
-                            AsmWrite(tostr(longint(lo(tai_const(hp).value))));
+                            writer.AsmWrite(tostr(longint(hi(tai_const(hp).value))));
+                            writer.AsmWrite(',');
+                            writer.AsmWrite(tostr(longint(lo(tai_const(hp).value))));
                           end;
-                        AsmLn;
+                        writer.AsmLn;
                       end;
 
                    aitconst_uleb128bit,
@@ -826,7 +826,7 @@ interface
                    aitconst_8bit,
                    aitconst_rva_symbol :
                      begin
-                       AsmWrite(ait_const2str[consttype]);
+                       writer.AsmWrite(ait_const2str[consttype]);
                        l:=0;
                        repeat
                          if assigned(tai_const(hp).sym) then
@@ -834,39 +834,39 @@ interface
                              if assigned(tai_const(hp).endsym) then
                                begin
                                  if (tai_const(hp).endsym.typ = AT_FUNCTION) and use_PR then
-                                   AsmWrite('.');
+                                   writer.AsmWrite('.');
 
                                  s:=tai_const(hp).endsym.name;
                                  ReplaceForbiddenChars(s);
-                                 AsmWrite(s);
+                                 writer.AsmWrite(s);
                                  inc(l,length(s));
 
                                  if tai_const(hp).endsym.typ = AT_FUNCTION then
                                    begin
                                      if use_PR then
-                                       AsmWrite('[PR]')
+                                       writer.AsmWrite('[PR]')
                                      else
-                                       AsmWrite('[DS]');
+                                       writer.AsmWrite('[DS]');
                                    end;
 
-                                 AsmWrite('-');
+                                 writer.AsmWrite('-');
                                  inc(l,5); {Approx 5 extra, no need to be exactly}
                                end;
 
                              if (tai_const(hp).sym.typ = AT_FUNCTION) and use_PR then
-                               AsmWrite('.');
+                               writer.AsmWrite('.');
 
                              s:= tai_const(hp).sym.name;
                              ReplaceForbiddenChars(s);
-                             AsmWrite(s);
+                             writer.AsmWrite(s);
                              inc(l,length(s));
 
                              if tai_const(hp).sym.typ = AT_FUNCTION then
                                begin
                                  if use_PR then
-                                   AsmWrite('[PR]')
+                                   writer.AsmWrite('[PR]')
                                  else
-                                   AsmWrite('[DS]');
+                                   writer.AsmWrite('[DS]');
                                end;
                              inc(l,5); {Approx 5 extra, no need to be exactly}
 
@@ -878,14 +878,14 @@ interface
                                s:= '';
                              if s<>'' then
                                begin
-                                 AsmWrite(s);
+                                 writer.AsmWrite(s);
                                  inc(l,length(s));
                                end;
                            end
                          else
                            begin
                              s:= tostr(tai_const(hp).value);
-                             AsmWrite(s);
+                             writer.AsmWrite(s);
                              inc(l,length(s));
                            end;
 
@@ -895,9 +895,9 @@ interface
                             (tai_const(hp.next).consttype<>consttype) then
                            break;
                          hp:=tai(hp.next);
-                         AsmWrite(',');
+                         writer.AsmWrite(',');
                        until false;
-                       AsmLn;
+                       writer.AsmLn;
                      end;
                 end;
               end;
@@ -911,38 +911,38 @@ interface
 (*
             ait_real_64bit :
               begin
-                AsmWriteLn(target_asm.comment+'value: '+double2str(tai_real_64bit(hp).value));
+                writer.AsmWriteLn(target_asm.comment+'value: '+double2str(tai_real_64bit(hp).value));
                 d:=tai_real_64bit(hp).value;
                 { swap the values to correct endian if required }
                 if source_info.endian <> target_info.endian then
                   swap64bitarray(t64bitarray(d));
-                AsmWrite(#9'dc.b'#9);
+                writer.AsmWrite(#9'dc.b'#9);
                   begin
                     for i:=0 to 7 do
                       begin
                         if i<>0 then
-                          AsmWrite(',');
-                        AsmWrite(tostr(t64bitarray(d)[i]));
+                          writer.AsmWrite(',');
+                        writer.AsmWrite(tostr(t64bitarray(d)[i]));
                       end;
                   end;
-                AsmLn;
+                writer.AsmLn;
               end;
 
             ait_real_32bit :
               begin
-                AsmWriteLn(target_asm.comment+'value: '+single2str(tai_real_32bit(hp).value));
+                writer.AsmWriteLn(target_asm.comment+'value: '+single2str(tai_real_32bit(hp).value));
                 sin:=tai_real_32bit(hp).value;
                 { swap the values to correct endian if required }
                 if source_info.endian <> target_info.endian then
                   swap32bitarray(t32bitarray(sin));
-                AsmWrite(#9'dc.b'#9);
+                writer.AsmWrite(#9'dc.b'#9);
                 for i:=0 to 3 do
                   begin
                     if i<>0 then
-                      AsmWrite(',');
-                    AsmWrite(tostr(t32bitarray(sin)[i]));
+                      writer.AsmWrite(',');
+                    writer.AsmWrite(tostr(t32bitarray(sin)[i]));
                   end;
-                AsmLn;
+                writer.AsmLn;
               end;
 *)
             ait_string:
@@ -959,7 +959,7 @@ interface
                   begin
                     for j := 0 to lines-1 do
                       begin
-                        AsmWrite(#9'dc.b'#9);
+                        writer.AsmWrite(#9'dc.b'#9);
                         quoted:=false;
                         for i:=counter to counter+line_length-1 do
                           begin
@@ -972,30 +972,30 @@ interface
                                 if not(quoted) then
                                     begin
                                       if i>counter then
-                                        AsmWrite(',');
-                                      AsmWrite('''');
+                                        writer.AsmWrite(',');
+                                      writer.AsmWrite('''');
                                     end;
-                                AsmWrite(tai_string(hp).str[i]);
+                                writer.AsmWrite(tai_string(hp).str[i]);
                                 quoted:=true;
                               end { if > 31 and < 128 and ord('"') }
                             else
                               begin
                                   if quoted then
-                                      AsmWrite('''');
+                                      writer.AsmWrite('''');
                                   if i>counter then
-                                      AsmWrite(',');
+                                      writer.AsmWrite(',');
                                   quoted:=false;
-                                  AsmWrite(tostr(ord(tai_string(hp).str[i])));
+                                  writer.AsmWrite(tostr(ord(tai_string(hp).str[i])));
                               end;
                           end; { end for i:=0 to... }
-                        if quoted then AsmWrite('''');
-                        AsmLn;
+                        if quoted then writer.AsmWrite('''');
+                        writer.AsmLn;
                         counter := counter+line_length;
                       end; { end for j:=0 ... }
 
                   { do last line of lines }
                   if counter < tai_string(hp).len then
-                    AsmWrite(#9'dc.b'#9);
+                    writer.AsmWrite(#9'dc.b'#9);
                   quoted:=false;
                   for i:=counter to tai_string(hp).len-1 do
                     begin
@@ -1008,26 +1008,26 @@ interface
                           if not(quoted) then
                             begin
                               if i>counter then
-                                AsmWrite(',');
-                              AsmWrite('''');
+                                writer.AsmWrite(',');
+                              writer.AsmWrite('''');
                             end;
-                          AsmWrite(tai_string(hp).str[i]);
+                          writer.AsmWrite(tai_string(hp).str[i]);
                           quoted:=true;
                         end { if > 31 and < 128 and " }
                       else
                         begin
                           if quoted then
-                            AsmWrite('''');
+                            writer.AsmWrite('''');
                           if i>counter then
-                            AsmWrite(',');
+                            writer.AsmWrite(',');
                           quoted:=false;
-                          AsmWrite(tostr(ord(tai_string(hp).str[i])));
+                          writer.AsmWrite(tostr(ord(tai_string(hp).str[i])));
                         end;
                     end; { end for i:=0 to... }
                   if quoted then
-                    AsmWrite('''');
+                    writer.AsmWrite('''');
                 end;
-                AsmLn;
+                writer.AsmLn;
               end;
             ait_label:
               begin
@@ -1038,7 +1038,7 @@ interface
                       begin
                         ReplaceForbiddenChars(s);
                         //Local labels:
-                        AsmWriteLn(s+':')
+                        writer.AsmWriteLn(s+':')
                       end
                     else
                       begin
@@ -1050,10 +1050,10 @@ interface
                         else
                           begin
                             ReplaceForbiddenChars(s);
-                            AsmWrite(#9'csect'#9); AsmWrite(s);
-                            AsmWriteLn('[TC]');
+                            writer.AsmWrite(#9'csect'#9); writer.AsmWrite(s);
+                            writer.AsmWriteLn('[TC]');
 
-                            AsmWriteLn(PadTabs(s+':',#0));
+                            writer.AsmWriteLn(PadTabs(s+':',#0));
                           end;
                       end;
                   end;
@@ -1068,8 +1068,8 @@ interface
                        WriteDataHeader(s, tai_symbol(hp).is_global, true);
                        if macos_direct_globals then
                          begin
-                           AsmWrite(s);
-                           AsmWriteLn(':');
+                           writer.AsmWrite(s);
+                           writer.AsmWriteLn(':');
                          end;
                     end
                   else
@@ -1120,60 +1120,60 @@ interface
               case tasmsymbol(p).typ of
                 AT_FUNCTION:
                   begin
-                    AsmWrite(#9'import'#9'.');
-                    AsmWrite(s);
+                    writer.AsmWrite(#9'import'#9'.');
+                    writer.AsmWrite(s);
                     if use_PR then
-                     AsmWrite('[PR]');
+                     writer.AsmWrite('[PR]');
 
                     if replaced then
                      begin
-                       AsmWrite(' <= ''.');
-                       AsmWrite(p.name);
+                       writer.AsmWrite(' <= ''.');
+                       writer.AsmWrite(p.name);
                        if use_PR then
-                         AsmWrite('[PR]''')
+                         writer.AsmWrite('[PR]''')
                        else
-                         AsmWrite('''');
+                         writer.AsmWrite('''');
                      end;
-                    AsmLn;
+                    writer.AsmLn;
 
-                    AsmWrite(#9'import'#9);
-                    AsmWrite(s);
-                    AsmWrite('[DS]');
+                    writer.AsmWrite(#9'import'#9);
+                    writer.AsmWrite(s);
+                    writer.AsmWrite('[DS]');
                     if replaced then
                      begin
-                       AsmWrite(' <= ''');
-                       AsmWrite(p.name);
-                       AsmWrite('[DS]''');
+                       writer.AsmWrite(' <= ''');
+                       writer.AsmWrite(p.name);
+                       writer.AsmWrite('[DS]''');
                      end;
-                    AsmLn;
+                    writer.AsmLn;
 
-                    AsmWriteLn(#9'toc');
+                    writer.AsmWriteLn(#9'toc');
 
-                    AsmWrite(#9'tc'#9);
-                    AsmWrite(s);
-                    AsmWrite('[TC],');
-                    AsmWrite(s);
-                    AsmWriteLn('[DS]');
+                    writer.AsmWrite(#9'tc'#9);
+                    writer.AsmWrite(s);
+                    writer.AsmWrite('[TC],');
+                    writer.AsmWrite(s);
+                    writer.AsmWriteLn('[DS]');
                   end;
                 AT_DATA:
                   begin
-                    AsmWrite(#9'import'#9);
-                    AsmWrite(s);
-                    AsmWrite(var_storage_class);
+                    writer.AsmWrite(#9'import'#9);
+                    writer.AsmWrite(s);
+                    writer.AsmWrite(var_storage_class);
                     if replaced then
                       begin
-                        AsmWrite(' <= ''');
-                        AsmWrite(p.name);
-                        AsmWrite('''');
+                        writer.AsmWrite(' <= ''');
+                        writer.AsmWrite(p.name);
+                        writer.AsmWrite('''');
                       end;
-                    AsmLn;
-
-                    AsmWriteLn(#9'toc');
-                    AsmWrite(#9'tc'#9);
-                    AsmWrite(s);
-                    AsmWrite('[TC],');
-                    AsmWrite(s);
-                    AsmWriteLn(var_storage_class);
+                    writer.AsmLn;
+
+                    writer.AsmWriteLn(#9'toc');
+                    writer.AsmWrite(#9'tc'#9);
+                    writer.AsmWrite(s);
+                    writer.AsmWrite('[TC],');
+                    writer.AsmWrite(s);
+                    writer.AsmWriteLn(var_storage_class);
                   end
                 else
                   InternalError(2003090901);
@@ -1202,9 +1202,9 @@ interface
     procedure TPPCMPWAssembler.WriteAsmFileHeader;
 
     begin
-      AsmWriteLn(#9'string asis');  {Interpret strings just to be the content between the quotes.}
-      AsmWriteLn(#9'aligning off'); {We do our own aligning.}
-      AsmLn;
+      writer.AsmWriteLn(#9'string asis');  {Interpret strings just to be the content between the quotes.}
+      writer.AsmWriteLn(#9'aligning off'); {We do our own aligning.}
+      writer.AsmLn;
     end;
 
     procedure TPPCMPWAssembler.WriteAsmList;
@@ -1221,13 +1221,13 @@ interface
 
       for hal:=low(TasmlistType) to high(TasmlistType) do
         begin
-          AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmListTypeStr[hal]);
+          writer.AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmListTypeStr[hal]);
           writetree(current_asmdata.asmlists[hal]);
-          AsmWriteLn(target_asm.comment+'End asmlist '+AsmListTypeStr[hal]);
+          writer.AsmWriteLn(target_asm.comment+'End asmlist '+AsmListTypeStr[hal]);
         end;
 
-      AsmWriteLn(#9'end');
-      AsmLn;
+      writer.AsmWriteLn(#9'end');
+      writer.AsmLn;
 
 {$ifdef EXTDEBUG}
       if assigned(current_module.mainsource) then

+ 2 - 2
compiler/powerpc/agppcvasm.pas

@@ -324,7 +324,7 @@ unit agppcvasm;
             begin
               { first write the current contents of s, because the symbol }
               { may be 255 characters                                     }
-              owner.asmwrite(s);
+              owner.writer.AsmWrite(s);
               s:=getopstr_jmp(taicpu(hp).oper[0]^);
             end;
         end
@@ -350,7 +350,7 @@ unit agppcvasm;
                 end;
             end;
         end;
-      owner.AsmWriteLn(s);
+      owner.writer.AsmWriteLn(s);
     end;
 
 

+ 14 - 14
compiler/ppcgen/agppcgas.pas

@@ -366,7 +366,7 @@ unit agppcgas;
             begin
               { first write the current contents of s, because the symbol }
               { may be 255 characters                                     }
-              owner.asmwrite(s);
+              owner.writer.AsmWrite(s);
               s:=getopstr_jmp(taicpu(hp).oper[0]^);
             end;
         end
@@ -392,7 +392,7 @@ unit agppcgas;
                 end;
             end;
         end;
-      owner.AsmWriteLn(s);
+      owner.writer.AsmWriteLn(s);
     end;
 
 
@@ -412,11 +412,11 @@ unit agppcgas;
          i : longint;
       begin
         if target_info.abi = abi_powerpc_elfv2 then
-          AsmWriteln(#9'.abiversion 2');
+          writer.AsmWriteln(#9'.abiversion 2');
         for i:=0 to 31 do
-          AsmWriteln(#9'.set'#9'r'+tostr(i)+','+tostr(i));
+          writer.AsmWriteln(#9'.set'#9'r'+tostr(i)+','+tostr(i));
         for i:=0 to 31 do
-          AsmWriteln(#9'.set'#9'f'+tostr(i)+','+tostr(i));
+          writer.AsmWriteln(#9'.set'#9'f'+tostr(i)+','+tostr(i));
       end;
 
 
@@ -467,13 +467,13 @@ unit agppcgas;
         inherited WriteExtraHeader;
         { map cr registers to plain numbers }
         for i:=0 to 7 do
-          AsmWriteln(#9'.set'#9'cr'+tostr(i)+','+tostr(i));
+          writer.AsmWriteln(#9'.set'#9'cr'+tostr(i)+','+tostr(i));
         { make sure we always have a code and toc section, the linker expects
           that }
-        AsmWriteln(#9'.csect .text[PR]');
+        writer.AsmWriteln(#9'.csect .text[PR]');
         { set _text_s, to be used by footer below } 
-        AsmWriteln(#9'_text_s:');
-        AsmWriteln(#9'.toc');
+        writer.AsmWriteln(#9'_text_s:');
+        writer.AsmWriteln(#9'.toc');
       end;
 
 
@@ -481,11 +481,11 @@ unit agppcgas;
       begin
         inherited WriteExtraFooter;
         { link between data and text section }
-        AsmWriteln(#9'.csect .data[RW],4');
+        writer.AsmWriteln(#9'.csect .data[RW],4');
 {$ifdef cpu64bitaddr}
-        AsmWriteln('text_pos:'#9'.llong _text_s')
+        writer.AsmWriteln('text_pos:'#9'.llong _text_s')
 {$else cpu64bitaddr}
-        AsmWriteln('text_pos:'#9'.long _text_s')
+        writer.AsmWriteln('text_pos:'#9'.long _text_s')
 {$endif cpu64bitaddr}
       end;
 
@@ -494,10 +494,10 @@ unit agppcgas;
       begin
         case dir of
           asd_reference:
-            AsmWrite('.ref ');
+            writer.AsmWrite('.ref ');
           asd_weak_reference,
           asd_weak_definition:
-            AsmWrite('.weak ');
+            writer.AsmWrite('.weak ');
           else
             inherited WriteDirectiveName(dir);
         end;

+ 3 - 3
compiler/sparc/cpugas.pas

@@ -168,11 +168,11 @@ implementation
              (taicpu(hp).oper[1]^.typ<>top_reg) then
             internalerror(200401045);
           { Fxxxs %f<even>,%f<even> }
-          owner.AsmWriteln(#9+std_op2str[opc]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^));
+          owner.writer.AsmWriteln(#9+std_op2str[opc]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^));
           { FMOVs %f<odd>,%f<odd> }
           inc(taicpu(hp).oper[0]^.reg);
           inc(taicpu(hp).oper[1]^.reg);
-          owner.AsmWriteln(#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^));
+          owner.writer.AsmWriteln(#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);
         end;
@@ -211,7 +211,7 @@ implementation
                   for i:=1 to taicpu(hp).ops-1 do
                     s:=s+','+getopstr(taicpu(hp).oper[i]^);
                 end;
-              owner.AsmWriteLn(s);
+              owner.writer.AsmWriteLn(s);
             end;
         end;
       end;

+ 45 - 45
compiler/x86/agx86att.pas

@@ -157,11 +157,11 @@ interface
            { should be replaced by coding the segment override  }
            { directly! - DJGPP FAQ                              }
            if segment<>NR_NO then
-             owner.AsmWrite(gas_regname(segment)+':');
+             owner.writer.AsmWrite(gas_regname(segment)+':');
            if assigned(symbol) then
-             owner.AsmWrite(symbol.name);
+             owner.writer.AsmWrite(symbol.name);
            if assigned(relsymbol) then
-             owner.AsmWrite('-'+relsymbol.name);
+             owner.writer.AsmWrite('-'+relsymbol.name);
            if ref.refaddr=addr_pic then
              begin
                { @GOT and @GOTPCREL references are only allowed for symbol alone,
@@ -171,50 +171,50 @@ interface
 {$ifdef x86_64}
                if (base<>NR_RIP) then
                  InternalError(2015011802);
-               owner.AsmWrite('@GOTPCREL');
+               owner.writer.AsmWrite('@GOTPCREL');
 {$else x86_64}
-               owner.AsmWrite('@GOT');
+               owner.writer.AsmWrite('@GOT');
 {$endif x86_64}
              end;
            if offset<0 then
-             owner.AsmWrite(tostr(offset))
+             owner.writer.AsmWrite(tostr(offset))
            else
             if (offset>0) then
              begin
                if assigned(symbol) then
-                owner.AsmWrite('+'+tostr(offset))
+                owner.writer.AsmWrite('+'+tostr(offset))
                else
-                owner.AsmWrite(tostr(offset));
+                owner.writer.AsmWrite(tostr(offset));
              end
            else if (index=NR_NO) and (base=NR_NO) and (not assigned(symbol)) then
-             owner.AsmWrite('0');
+             owner.writer.AsmWrite('0');
            if (index<>NR_NO) and (base=NR_NO) then
             begin
               if scalefactor in [0,1] then
                 { Switching index to base position gives shorter
                   assembler instructions }
                 begin
-                  owner.AsmWrite('('+gas_regname(index)+')');
+                  owner.writer.AsmWrite('('+gas_regname(index)+')');
                 end
               else
                 begin
-                  owner.AsmWrite('(,'+gas_regname(index));
+                  owner.writer.AsmWrite('(,'+gas_regname(index));
                   if scalefactor<>0 then
-                   owner.AsmWrite(','+tostr(scalefactor)+')')
+                   owner.writer.AsmWrite(','+tostr(scalefactor)+')')
                   else
-                   owner.AsmWrite(')');
+                   owner.writer.AsmWrite(')');
                 end;
             end
            else
             if (index=NR_NO) and (base<>NR_NO) then
-              owner.AsmWrite('('+gas_regname(base)+')')
+              owner.writer.AsmWrite('('+gas_regname(base)+')')
             else
              if (index<>NR_NO) and (base<>NR_NO) then
               begin
-                owner.AsmWrite('('+gas_regname(base)+','+gas_regname(index));
+                owner.writer.AsmWrite('('+gas_regname(base)+','+gas_regname(index));
                 if scalefactor<>0 then
-                 owner.AsmWrite(','+tostr(scalefactor));
-                owner.AsmWrite(')');
+                 owner.writer.AsmWrite(','+tostr(scalefactor));
+                owner.writer.AsmWrite(')');
               end;
          end;
       end;
@@ -224,26 +224,26 @@ interface
       begin
         case o.typ of
           top_reg :
-            owner.AsmWrite(gas_regname(o.reg));
+            owner.writer.AsmWrite(gas_regname(o.reg));
           top_ref :
             if o.ref^.refaddr in [addr_no,addr_pic,addr_pic_no_got] then
               WriteReference(o.ref^)
             else
               begin
-                owner.AsmWrite('$');
+                owner.writer.AsmWrite('$');
                 if assigned(o.ref^.symbol) then
-                 owner.AsmWrite(o.ref^.symbol.name);
+                 owner.writer.AsmWrite(o.ref^.symbol.name);
                 if o.ref^.offset>0 then
-                 owner.AsmWrite('+'+tostr(o.ref^.offset))
+                 owner.writer.AsmWrite('+'+tostr(o.ref^.offset))
                 else
                  if o.ref^.offset<0 then
-                  owner.AsmWrite(tostr(o.ref^.offset))
+                  owner.writer.AsmWrite(tostr(o.ref^.offset))
                 else
                  if not(assigned(o.ref^.symbol)) then
-                   owner.AsmWrite('0');
+                   owner.writer.AsmWrite('0');
               end;
           top_const :
-              owner.AsmWrite('$'+tostr(o.val));
+              owner.writer.AsmWrite('$'+tostr(o.val));
           else
             internalerror(10001);
         end;
@@ -254,28 +254,28 @@ interface
       begin
         case o.typ of
           top_reg :
-            owner.AsmWrite('*'+gas_regname(o.reg));
+            owner.writer.AsmWrite('*'+gas_regname(o.reg));
           top_ref :
             begin
               if o.ref^.refaddr in [addr_no,addr_pic_no_got] then
                 begin
-                  owner.AsmWrite('*');
+                  owner.writer.AsmWrite('*');
                   WriteReference(o.ref^);
                 end
               else
                 begin
-                  owner.AsmWrite(o.ref^.symbol.name);
+                  owner.writer.AsmWrite(o.ref^.symbol.name);
                   if o.ref^.refaddr=addr_pic then
-                    owner.AsmWrite('@PLT');
+                    owner.writer.AsmWrite('@PLT');
                   if o.ref^.offset>0 then
-                   owner.AsmWrite('+'+tostr(o.ref^.offset))
+                   owner.writer.AsmWrite('+'+tostr(o.ref^.offset))
                   else
                    if o.ref^.offset<0 then
-                    owner.AsmWrite(tostr(o.ref^.offset));
+                    owner.writer.AsmWrite(tostr(o.ref^.offset));
                 end;
             end;
           top_const :
-            owner.AsmWrite(tostr(o.val));
+            owner.writer.AsmWrite(tostr(o.val));
           else
             internalerror(10001);
         end;
@@ -333,14 +333,14 @@ interface
                 taicpu(hp).opcode:=op;
               end;
           end;
-        owner.AsmWrite(#9);
+        owner.writer.AsmWrite(#9);
         { movsd should not be translated to movsl when there
           are (xmm) arguments }
         if (op=A_MOVSD) and (taicpu(hp).ops>0) then
-          owner.AsmWrite('movsd')
+          owner.writer.AsmWrite('movsd')
         else
-          owner.AsmWrite(gas_op2str[op]);
-        owner.AsmWrite(cond2str[taicpu(hp).condition]);
+          owner.writer.AsmWrite(gas_op2str[op]);
+        owner.writer.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
@@ -371,30 +371,30 @@ interface
               begin
                 case taicpu(hp).oper[i]^.ot and OT_SIZE_MASK of
                    OT_BITS32: begin
-                                owner.AsmWrite(gas_opsize2str[S_L]);
+                                owner.writer.AsmWrite(gas_opsize2str[S_L]);
                                 break;
                               end;
                    OT_BITS64: begin
-                                owner.AsmWrite(gas_opsize2str[S_Q]);
+                                owner.writer.AsmWrite(gas_opsize2str[S_Q]);
                                 break;
                               end;
                   OT_BITS128: begin
-                                owner.AsmWrite(gas_opsize2str[S_XMM]);
+                                owner.writer.AsmWrite(gas_opsize2str[S_XMM]);
                                 break;
                               end;
                   OT_BITS256: begin
-                                owner.AsmWrite(gas_opsize2str[S_YMM]);
+                                owner.writer.AsmWrite(gas_opsize2str[S_YMM]);
                                 break;
                               end;
                            0: begin
-                                owner.AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
+                                owner.writer.AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
                                 break;
                               end;
                 end;
               end;
             end;
           end
-          else owner.AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
+          else owner.writer.AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
         end;
 
         { process operands }
@@ -402,7 +402,7 @@ interface
           begin
             if calljmp then
              begin
-               owner.AsmWrite(#9);
+               owner.writer.AsmWrite(#9);
                WriteOper_jmp(taicpu(hp).oper[0]^);
              end
             else
@@ -410,14 +410,14 @@ interface
                for i:=0 to taicpu(hp).ops-1 do
                  begin
                    if i=0 then
-                     owner.AsmWrite(#9)
+                     owner.writer.AsmWrite(#9)
                    else
-                     owner.AsmWrite(',');
+                     owner.writer.AsmWrite(',');
                    WriteOper(taicpu(hp).oper[i]^);
                  end;
              end;
           end;
-        owner.AsmLn;
+        owner.writer.AsmLn;
       end;
 
 

+ 140 - 142
compiler/x86/agx86int.pas

@@ -251,53 +251,53 @@ implementation
          begin
            first:=true;
            if segment<>NR_NO then
-            AsmWrite(masm_regname(segment)+':[')
+            writer.AsmWrite(masm_regname(segment)+':[')
            else
-            AsmWrite('[');
+            writer.AsmWrite('[');
            if assigned(symbol) then
             begin
               if (target_asm.id = as_i386_tasm) then
-                AsmWrite('dword ptr ');
-              AsmWrite(symbol.name);
+                writer.AsmWrite('dword ptr ');
+              writer.AsmWrite(symbol.name);
               first:=false;
             end;
            if (base<>NR_NO) then
             begin
               if not(first) then
-               AsmWrite('+')
+               writer.AsmWrite('+')
               else
                first:=false;
 {$ifdef x86_64}
               { ml64 needs [$+foo] instead of [rip+foo] }
               if (base=NR_RIP) and (target_asm.id=as_x86_64_masm) then
-               AsmWrite('$')
+               writer.AsmWrite('$')
               else
 {$endif x86_64}
-               AsmWrite(masm_regname(base));
+               writer.AsmWrite(masm_regname(base));
             end;
            if (index<>NR_NO) then
             begin
               if not(first) then
-               AsmWrite('+')
+               writer.AsmWrite('+')
               else
                first:=false;
-              AsmWrite(masm_regname(index));
+              writer.AsmWrite(masm_regname(index));
               if scalefactor<>0 then
-               AsmWrite('*'+tostr(scalefactor));
+               writer.AsmWrite('*'+tostr(scalefactor));
             end;
                if offset<0 then
                 begin
-                  AsmWrite(tostr(offset));
+                  writer.AsmWrite(tostr(offset));
                   first:=false;
                 end
                else if (offset>0) then
                 begin
-                  AsmWrite('+'+tostr(offset));
+                  writer.AsmWrite('+'+tostr(offset));
                   first:=false;
                 end;
            if first then
-             AsmWrite('0');
-           AsmWrite(']');
+             writer.AsmWrite('0');
+           writer.AsmWrite(']');
          end;
       end;
 
@@ -306,9 +306,9 @@ implementation
       begin
         case o.typ of
           top_reg :
-            AsmWrite(masm_regname(o.reg));
+            writer.AsmWrite(masm_regname(o.reg));
           top_const :
-            AsmWrite(tostr(o.val));
+            writer.AsmWrite(tostr(o.val));
           top_ref :
             begin
               if o.ref^.refaddr in [addr_no,addr_pic,addr_pic_no_got] then
@@ -321,44 +321,44 @@ implementation
                       ) then
                    Begin
                      case s of
-                      S_B : AsmWrite('byte ptr ');
-                      S_W : AsmWrite('word ptr ');
-                      S_L : AsmWrite('dword ptr ');
-                      S_Q : AsmWrite('qword ptr ');
-                     S_IS : AsmWrite('word ptr ');
-                     S_IL : AsmWrite('dword ptr ');
-                     S_IQ : AsmWrite('qword ptr ');
-                     S_FS : AsmWrite('dword ptr ');
-                     S_FL : AsmWrite('qword ptr ');
+                      S_B : writer.AsmWrite('byte ptr ');
+                      S_W : writer.AsmWrite('word ptr ');
+                      S_L : writer.AsmWrite('dword ptr ');
+                      S_Q : writer.AsmWrite('qword ptr ');
+                     S_IS : writer.AsmWrite('word ptr ');
+                     S_IL : writer.AsmWrite('dword ptr ');
+                     S_IQ : writer.AsmWrite('qword ptr ');
+                     S_FS : writer.AsmWrite('dword ptr ');
+                     S_FL : writer.AsmWrite('qword ptr ');
                      S_T,
-                     S_FX : AsmWrite('tbyte ptr ');
+                     S_FX : writer.AsmWrite('tbyte ptr ');
                      S_BW : if dest then
-                             AsmWrite('word ptr ')
+                             writer.AsmWrite('word ptr ')
                             else
-                             AsmWrite('byte ptr ');
+                             writer.AsmWrite('byte ptr ');
                      S_BL : if dest then
-                             AsmWrite('dword ptr ')
+                             writer.AsmWrite('dword ptr ')
                             else
-                             AsmWrite('byte ptr ');
+                             writer.AsmWrite('byte ptr ');
                      S_WL : if dest then
-                             AsmWrite('dword ptr ')
+                             writer.AsmWrite('dword ptr ')
                             else
-                             AsmWrite('word ptr ');
-                     S_XMM: AsmWrite('xmmword ptr ');
-                     S_YMM: AsmWrite('ymmword ptr ');
+                             writer.AsmWrite('word ptr ');
+                     S_XMM: writer.AsmWrite('xmmword ptr ');
+                     S_YMM: writer.AsmWrite('ymmword ptr ');
 {$ifdef x86_64}
                      S_BQ : if dest then
-                             AsmWrite('qword ptr ')
+                             writer.AsmWrite('qword ptr ')
                             else
-                             AsmWrite('byte ptr ');
+                             writer.AsmWrite('byte ptr ');
                      S_WQ : if dest then
-                             AsmWrite('qword ptr ')
+                             writer.AsmWrite('qword ptr ')
                             else
-                             AsmWrite('word ptr ');
+                             writer.AsmWrite('word ptr ');
                      S_LQ : if dest then
-                             AsmWrite('qword ptr ')
+                             writer.AsmWrite('qword ptr ')
                             else
-                             AsmWrite('dword ptr ');
+                             writer.AsmWrite('dword ptr ');
 
 {$endif x86_64}
                      end;
@@ -367,17 +367,17 @@ implementation
                 end
               else
                 begin
-                  AsmWrite('offset ');
+                  writer.AsmWrite('offset ');
                   if assigned(o.ref^.symbol) then
-                    AsmWrite(o.ref^.symbol.name);
+                    writer.AsmWrite(o.ref^.symbol.name);
                   if o.ref^.offset>0 then
-                   AsmWrite('+'+tostr(o.ref^.offset))
+                   writer.AsmWrite('+'+tostr(o.ref^.offset))
                   else
                    if o.ref^.offset<0 then
-                    AsmWrite(tostr(o.ref^.offset))
+                    writer.AsmWrite(tostr(o.ref^.offset))
                   else
                    if not(assigned(o.ref^.symbol)) then
-                     AsmWrite('0');
+                     writer.AsmWrite('0');
                 end;
             end;
           else
@@ -390,9 +390,9 @@ implementation
     begin
       case o.typ of
         top_reg :
-          AsmWrite(masm_regname(o.reg));
+          writer.AsmWrite(masm_regname(o.reg));
         top_const :
-          AsmWrite(tostr(o.val));
+          writer.AsmWrite(tostr(o.val));
         top_ref :
           { what about lcall or ljmp ??? }
           begin
@@ -401,24 +401,24 @@ implementation
                 if (target_asm.id <> as_i386_tasm) then
                   begin
                     if s=S_FAR then
-                      AsmWrite('far ptr ')
+                      writer.AsmWrite('far ptr ')
                     else
 {$ifdef x86_64}
-                      AsmWrite('qword ptr ');
+                      writer.AsmWrite('qword ptr ');
 {$else x86_64}
-                      AsmWrite('dword ptr ');
+                      writer.AsmWrite('dword ptr ');
 {$endif x86_64}
                   end;
                 WriteReference(o.ref^);
               end
             else
               begin
-                AsmWrite(o.ref^.symbol.name);
+                writer.AsmWrite(o.ref^.symbol.name);
                 if o.ref^.offset>0 then
-                 AsmWrite('+'+tostr(o.ref^.offset))
+                 writer.AsmWrite('+'+tostr(o.ref^.offset))
                 else
                  if o.ref^.offset<0 then
-                  AsmWrite(tostr(o.ref^.offset));
+                  writer.AsmWrite(tostr(o.ref^.offset));
               end;
           end;
         else
@@ -491,15 +491,15 @@ implementation
          case hp.typ of
            ait_comment :
              Begin
-               AsmWrite(target_asm.comment);
-               AsmWritePChar(tai_comment(hp).str);
-               AsmLn;
+               writer.AsmWrite(target_asm.comment);
+               writer.AsmWritePChar(tai_comment(hp).str);
+               writer.AsmLn;
              End;
 
            ait_regalloc :
              begin
                if (cs_asm_regalloc in current_settings.globalswitches) then
-                 AsmWriteLn(target_asm.comment+'Register '+masm_regname(tai_regalloc(hp).reg)+
+                 writer.AsmWriteLn(target_asm.comment+'Register '+masm_regname(tai_regalloc(hp).reg)+
                    regallocstr[tai_regalloc(hp).ratype]);
              end;
 
@@ -516,16 +516,16 @@ implementation
                   if target_asm.id=as_x86_64_masm then
                     begin
                       if LasTSecType<>sec_none then
-                        AsmWriteLn(secnamesml64[LasTSecType]+#9#9'ENDS');
-                      AsmLn;
-                      AsmWriteLn(secnamesml64[tai_section(hp).sectype]+#9+'SEGMENT')
+                        writer.AsmWriteLn(secnamesml64[LasTSecType]+#9#9'ENDS');
+                      writer.AsmLn;
+                      writer.AsmWriteLn(secnamesml64[tai_section(hp).sectype]+#9+'SEGMENT')
                     end
                   else
                     begin
                       if LasTSecType<>sec_none then
-                        AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');
-                      AsmLn;
-                      AsmWriteLn('_'+secnames[tai_section(hp).sectype]+#9#9+
+                        writer.AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');
+                      writer.AsmLn;
+                      writer.AsmWriteLn('_'+secnames[tai_section(hp).sectype]+#9#9+
                                  'SEGMENT'#9+alignstr(tai_section(hp).secalign)+' PUBLIC USE32 '''+
                                  secnames[tai_section(hp).sectype]+'''');
                     end;
@@ -538,13 +538,13 @@ implementation
                { SEGMENT DEFINITION SHOULD MATCH TYPE OF ALIGN }
                { HERE UNDER TASM!                              }
                  if tai_align_abstract(hp).aligntype>1 then
-                   AsmWriteLn(#9'ALIGN '+tostr(tai_align_abstract(hp).aligntype));
+                   writer.AsmWriteLn(#9'ALIGN '+tostr(tai_align_abstract(hp).aligntype));
                end;
            ait_datablock :
              begin
                if tai_datablock(hp).is_global then
-                 AsmWriteLn(#9'PUBLIC'#9+tai_datablock(hp).sym.name);
-               AsmWriteLn(PadTabs(tai_datablock(hp).sym.name,#0)+'DB'#9+tostr(tai_datablock(hp).size)+' DUP(?)');
+                 writer.AsmWriteLn(#9'PUBLIC'#9+tai_datablock(hp).sym.name);
+               writer.AsmWriteLn(PadTabs(tai_datablock(hp).sym.name,#0)+'DB'#9+tostr(tai_datablock(hp).size)+' DUP(?)');
              end;
            ait_const:
              begin
@@ -560,7 +560,7 @@ implementation
                  aitconst_rva_symbol,
                  aitconst_secrel32_symbol :
                    begin
-                     AsmWrite(ait_const2str[consttype]);
+                     writer.AsmWrite(ait_const2str[consttype]);
                      l:=0;
                      repeat
                        if assigned(tai_const(hp).sym) then
@@ -574,7 +574,7 @@ implementation
                          end
                        else
                          s:=tostr(tai_const(hp).value);
-                       AsmWrite(s);
+                       writer.AsmWrite(s);
                        inc(l,length(s));
                        if (l>line_length) or
                           (hp.next=nil) or
@@ -582,12 +582,12 @@ implementation
                           (tai_const(hp.next).consttype<>consttype) then
                          break;
                        hp:=tai(hp.next);
-                       AsmWrite(',');
+                       writer.AsmWrite(',');
                      until false;
                      { Substract section start for secrel32 type }
                      if consttype=aitconst_secrel32_symbol then
-                       AsmWrite(' - $$');
-                     AsmLn;
+                       writer.AsmWrite(' - $$');
+                     writer.AsmLn;
                    end;
                  else
                    internalerror(200704253);
@@ -598,13 +598,13 @@ implementation
              begin
                case tai_realconst(hp).realtyp of
                  aitrealconst_s32bit:
-                   AsmWriteLn(#9#9'DD'#9+single2str(tai_realconst(hp).value.s32val));
+                   writer.AsmWriteLn(#9#9'DD'#9+single2str(tai_realconst(hp).value.s32val));
                  aitrealconst_s64bit:
-                   AsmWriteLn(#9#9'DQ'#9+double2str(tai_realconst(hp).value.s64val));
+                   writer.AsmWriteLn(#9#9'DQ'#9+double2str(tai_realconst(hp).value.s64val));
                  aitrealconst_s80bit:
-                   AsmWriteLn(#9#9'DT'#9+extended2str(tai_realconst(hp).value.s80val));
+                   writer.AsmWriteLn(#9#9'DT'#9+extended2str(tai_realconst(hp).value.s80val));
                  aitrealconst_s64comp:
-                   AsmWriteLn(#9#9'DQ'#9+extended2str(tai_realconst(hp).value.s64compval));
+                   writer.AsmWriteLn(#9#9'DQ'#9+extended2str(tai_realconst(hp).value.s64compval));
                  else
                    internalerror(2014050604);
                end;
@@ -618,7 +618,7 @@ implementation
                 Begin
                   for j := 0 to lines-1 do
                    begin
-                     AsmWrite(#9#9'DB'#9);
+                     writer.AsmWrite(#9#9'DB'#9);
                      quoted:=false;
                      for i:=counter to counter+line_length-1 do
                         begin
@@ -630,29 +630,29 @@ implementation
                                 if not(quoted) then
                                     begin
                                       if i>counter then
-                                        AsmWrite(',');
-                                      AsmWrite('"');
+                                        writer.AsmWrite(',');
+                                      writer.AsmWrite('"');
                                     end;
-                                AsmWrite(tai_string(hp).str[i]);
+                                writer.AsmWrite(tai_string(hp).str[i]);
                                 quoted:=true;
                               end { if > 31 and < 128 and ord('"') }
                           else
                               begin
                                   if quoted then
-                                      AsmWrite('"');
+                                      writer.AsmWrite('"');
                                   if i>counter then
-                                      AsmWrite(',');
+                                      writer.AsmWrite(',');
                                   quoted:=false;
-                                  AsmWrite(tostr(ord(tai_string(hp).str[i])));
+                                  writer.AsmWrite(tostr(ord(tai_string(hp).str[i])));
                               end;
                        end; { end for i:=0 to... }
-                     if quoted then AsmWrite('"');
-                       AsmWrite(target_info.newline);
+                     if quoted then writer.AsmWrite('"');
+                       writer.AsmWrite(target_info.newline);
                      counter := counter+line_length;
                   end; { end for j:=0 ... }
                 { do last line of lines }
                 if counter<tai_string(hp).len then
-                  AsmWrite(#9#9'DB'#9);
+                  writer.AsmWrite(#9#9'DB'#9);
                 quoted:=false;
                 for i:=counter to tai_string(hp).len-1 do
                   begin
@@ -664,35 +664,35 @@ implementation
                           if not(quoted) then
                               begin
                                 if i>counter then
-                                  AsmWrite(',');
-                                AsmWrite('"');
+                                  writer.AsmWrite(',');
+                                writer.AsmWrite('"');
                               end;
-                          AsmWrite(tai_string(hp).str[i]);
+                          writer.AsmWrite(tai_string(hp).str[i]);
                           quoted:=true;
                         end { if > 31 and < 128 and " }
                     else
                         begin
                           if quoted then
-                            AsmWrite('"');
+                            writer.AsmWrite('"');
                           if i>counter then
-                              AsmWrite(',');
+                              writer.AsmWrite(',');
                           quoted:=false;
-                          AsmWrite(tostr(ord(tai_string(hp).str[i])));
+                          writer.AsmWrite(tostr(ord(tai_string(hp).str[i])));
                         end;
                   end; { end for i:=0 to... }
                 if quoted then
-                  AsmWrite('"');
+                  writer.AsmWrite('"');
                 end;
-               AsmLn;
+               writer.AsmLn;
              end;
            ait_label :
              begin
                if tai_label(hp).labsym.is_used then
                 begin
-                  AsmWrite(tai_label(hp).labsym.name);
+                  writer.AsmWrite(tai_label(hp).labsym.name);
                   if assigned(hp.next) and not(tai(hp.next).typ in
                      [ait_const,ait_realconst,ait_string]) then
-                   AsmWriteLn(':')
+                   writer.AsmWriteLn(':')
                   else
                    DoNotSplitLine:=true;
                 end;
@@ -702,11 +702,11 @@ implementation
                if tai_symbol(hp).has_value then
                  internalerror(2009090802);
                if tai_symbol(hp).is_global then
-                 AsmWriteLn(#9'PUBLIC'#9+tai_symbol(hp).sym.name);
-               AsmWrite(tai_symbol(hp).sym.name);
+                 writer.AsmWriteLn(#9'PUBLIC'#9+tai_symbol(hp).sym.name);
+               writer.AsmWrite(tai_symbol(hp).sym.name);
                if assigned(hp.next) and not(tai(hp.next).typ in
                   [ait_const,ait_realconst,ait_string]) then
-                AsmWriteLn(':')
+                writer.AsmWriteLn(':')
              end;
            ait_symbol_end :
              begin
@@ -730,7 +730,7 @@ implementation
                     (taicpu(hp).oper[0]^.typ=top_reg) and
                     is_segment_reg(taicpu(hp).oper[0]^.reg)
                    ) then
-                 AsmWriteln(#9#9'DB'#9'066h');
+                 writer.AsmWriteln(#9#9'DB'#9'066h');
 
                { added prefix instructions, must be on same line as opcode }
                if (taicpu(hp).ops = 0) and
@@ -750,16 +750,16 @@ implementation
                   { this is theorically impossible... }
                   if hp=nil then
                    begin
-                     AsmWriteLn(#9#9+prefix);
+                     writer.AsmWriteLn(#9#9+prefix);
                      break;
                    end;
                   { nasm prefers prefix on a line alone
-                  AsmWriteln(#9#9+prefix); but not masm PM
+                  writer.AsmWriteln(#9#9+prefix); but not masm PM
                   prefix:=''; }
                   if target_asm.id in [as_i386_nasmcoff,as_i386_nasmwin32,as_i386_nasmwdosx,
                     as_i386_nasmelf,as_i386_nasmobj,as_i386_nasmbeos,as_i386_nasmhaiku] then
                      begin
-                       AsmWriteln(prefix);
+                       writer.AsmWriteln(prefix);
                        prefix:='';
                      end;
                 end
@@ -770,19 +770,19 @@ implementation
                  (fixed_opcode=A_PUSH) and
                  (taicpu(hp).oper[0]^.typ=top_const) then
                  begin
-                   AsmWriteln(#9#9'DB 66h,68h ; pushw imm16');
-                   AsmWrite(#9#9'DW');
+                   writer.AsmWriteln(#9#9'DB 66h,68h ; pushw imm16');
+                   writer.AsmWrite(#9#9'DW');
                  end
                else if (target_asm.id=as_x86_64_masm) and
                  (fixed_opcode=A_MOVQ) then
-                 AsmWrite(#9#9'mov')
+                 writer.AsmWrite(#9#9'mov')
                else
-                 AsmWrite(#9#9+prefix+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]+suffix);
+                 writer.AsmWrite(#9#9+prefix+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]+suffix);
                if taicpu(hp).ops<>0 then
                 begin
                   if is_calljmp(fixed_opcode) then
                    begin
-                     AsmWrite(#9);
+                     writer.AsmWrite(#9);
                      WriteOper_jmp(taicpu(hp).oper[0]^,taicpu(hp).opsize);
                    end
                   else
@@ -790,14 +790,14 @@ implementation
                      for i:=0to taicpu(hp).ops-1 do
                       begin
                         if i=0 then
-                         AsmWrite(#9)
+                         writer.AsmWrite(#9)
                         else
-                         AsmWrite(',');
+                         writer.AsmWrite(',');
                         WriteOper(taicpu(hp).oper[i]^,taicpu(hp).opsize,fixed_opcode,(i=2));
                       end;
                    end;
                 end;
-               AsmLn;
+               writer.AsmLn;
              end;
 
            ait_stab,
@@ -807,17 +807,15 @@ implementation
            ait_cutobject :
              begin
                { only reset buffer if nothing has changed }
-                 if AsmSize=AsmStartSize then
-                  AsmClear
-                 else
+                 if not writer.ClearIfEmpty then
                   begin
                     if LasTSecType<>sec_none then
-                     AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');
-                    AsmLn;
-                    AsmWriteLn(#9'END');
-                    AsmClose;
+                     writer.AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');
+                    writer.AsmLn;
+                    writer.AsmWriteLn(#9'END');
+                    writer.AsmClose;
                     DoAssemble;
-                    AsmCreate(tai_cutobject(hp).place);
+                    writer.AsmCreate(tai_cutobject(hp).place);
                   end;
                { avoid empty files }
                  while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
@@ -826,20 +824,20 @@ implementation
                       lasTSecType:=tai_section(hp.next).sectype;
                     hp:=tai(hp.next);
                   end;
-                 AsmWriteLn(#9'.386p');
+                 writer.AsmWriteLn(#9'.386p');
 {$ifdef i8086}
-                 AsmWriteLn('DGROUP'#9'GROUP'#9'_BSS,_DATA');
-                 AsmWriteLn(#9'ASSUME'#9'CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP');
+                 writer.AsmWriteLn('DGROUP'#9'GROUP'#9'_BSS,_DATA');
+                 writer.AsmWriteLn(#9'ASSUME'#9'CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP');
 {$endif i8086}
                  { I was told that this isn't necesarry because }
                  { the labels generated by FPC are unique (FK)  }
-                 { AsmWriteLn(#9'LOCALS '+target_asm.labelprefix); }
+                 { writer.AsmWriteLn(#9'LOCALS '+target_asm.labelprefix); }
                  { TODO: PARA is incorrect, must use actual section align }
                  if lasTSectype<>sec_none then
-                    AsmWriteLn('_'+secnames[lasTSectype]+#9#9+
+                    writer.AsmWriteLn('_'+secnames[lasTSectype]+#9#9+
                                'SEGMENT'#9'PARA PUBLIC USE32 '''+
                                secnames[lasTSectype]+'''');
-                 AsmStartSize:=AsmSize;
+                 writer.MarkEmpty;
                end;
            ait_marker :
              begin
@@ -853,14 +851,14 @@ implementation
              begin
                case tai_directive(hp).directive of
                  asd_nasm_import :
-                   AsmWrite('import ');
+                   writer.AsmWrite('import ');
                  asd_extern :
-                   AsmWrite('EXTRN ');
+                   writer.AsmWrite('EXTRN ');
                  else
                    internalerror(200509192);
                end;
-               AsmWrite(tai_directive(hp).name);
-               AsmLn;
+               writer.AsmWrite(tai_directive(hp).name);
+               writer.AsmLn;
              end;
            ait_seh_directive :
              { Ignore for now };
@@ -885,11 +883,11 @@ implementation
                 case target_asm.id of
                   as_i386_masm,
                   as_i386_wasm :
-                    AsmWriteln(#9'EXTRN'#9+sym.name+': NEAR');
+                    writer.AsmWriteln(#9'EXTRN'#9+sym.name+': NEAR');
                   as_x86_64_masm :
-                    AsmWriteln(#9'EXTRN'#9+sym.name+': PROC');
+                    writer.AsmWriteln(#9'EXTRN'#9+sym.name+': PROC');
                   else
-                    AsmWriteln(#9'EXTRN'#9+sym.name);
+                    writer.AsmWriteln(#9'EXTRN'#9+sym.name);
                 end;
               end;
           end;
@@ -927,26 +925,26 @@ implementation
 {$endif}
       if target_asm.id<>as_x86_64_masm then
         begin
-          AsmWriteLn(#9'.386p');
+          writer.AsmWriteLn(#9'.386p');
           { masm 6.11 does not seem to like LOCALS PM }
           if (target_asm.id = as_i386_tasm) then
             begin
-              AsmWriteLn(#9'LOCALS '+target_asm.labelprefix);
+              writer.AsmWriteLn(#9'LOCALS '+target_asm.labelprefix);
             end;
 {$ifdef i8086}
-          AsmWriteLn('DGROUP'#9'GROUP'#9'_BSS,_DATA');
-          AsmWriteLn(#9'ASSUME'#9'CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP');
+          writer.AsmWriteLn('DGROUP'#9'GROUP'#9'_BSS,_DATA');
+          writer.AsmWriteLn(#9'ASSUME'#9'CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP');
 {$endif i8086}
-          AsmLn;
+          writer.AsmLn;
         end;
 
       WriteExternals;
 
       for hal:=low(TasmlistType) to high(TasmlistType) do
         begin
-          AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmListTypeStr[hal]);
+          writer.AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmListTypeStr[hal]);
           writetree(current_asmdata.asmlists[hal]);
-          AsmWriteLn(target_asm.comment+'End asmlist '+AsmListTypeStr[hal]);
+          writer.AsmWriteLn(target_asm.comment+'End asmlist '+AsmListTypeStr[hal]);
         end;
 
       { better do this at end of WriteTree, but then there comes a trouble with
@@ -955,14 +953,14 @@ implementation
       if LastSecType <> sec_none then
         begin
           if target_asm.id=as_x86_64_masm then
-            AsmWriteLn(secnamesml64[LasTSecType]+#9#9'ENDS')
+            writer.AsmWriteLn(secnamesml64[LasTSecType]+#9#9'ENDS')
           else
-            AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');
+            writer.AsmWriteLn('_'+secnames[LasTSecType]+#9#9'ENDS');
         end;
       LastSecType := sec_none;
 
-      AsmWriteLn(#9'END');
-      AsmLn;
+      writer.AsmWriteLn(#9'END');
+      writer.AsmLn;
 
 {$ifdef EXTDEBUG}
       if current_module.mainsource<>'' then

+ 151 - 153
compiler/x86/agx86nsm.pas

@@ -300,23 +300,23 @@ interface
       begin
         with ref do
          begin
-           AsmWrite('[');
+           writer.AsmWrite('[');
            first:=true;
            base_done:=false;
            if (segment<>NR_NO) then
-             AsmWrite(nasm_regname(segment)+':');
+             writer.AsmWrite(nasm_regname(segment)+':');
 {$ifdef x86_64}
           if (base=NR_RIP) then
             begin
               { nasm RIP is implicit for pic }
               if not (ref.refaddr in [addr_pic,addr_pic_no_got]) and not using_relative then
-                AsmWrite('$ + ');
+                writer.AsmWrite('$ + ');
               base_done:=true;
             end;
 {$endif x86_64}
            if assigned(symbol) then
             begin
-              AsmWrite(symbol.name);
+              writer.AsmWrite(symbol.name);
               if SmartAsm then
                 AddSymbol(symbol.name,false);
               first:=false;
@@ -324,34 +324,34 @@ interface
            if (base<>NR_NO) and not base_done then
             begin
               if not(first) then
-               AsmWrite('+')
+               writer.AsmWrite('+')
               else
                first:=false;
-              AsmWrite(nasm_regname(base))
+              writer.AsmWrite(nasm_regname(base))
             end;
            if (index<>NR_NO) then
              begin
                if not(first) then
-                 AsmWrite('+')
+                 writer.AsmWrite('+')
                else
                  first:=false;
-               AsmWrite(nasm_regname(index));
+               writer.AsmWrite(nasm_regname(index));
                if scalefactor<>0 then
-                 AsmWrite('*'+tostr(scalefactor));
+                 writer.AsmWrite('*'+tostr(scalefactor));
              end;
            if offset<0 then
              begin
-               AsmWrite(tostr(offset));
+               writer.AsmWrite(tostr(offset));
                first:=false;
              end
            else if (offset>0) then
              begin
-               AsmWrite('+'+tostr(offset));
+               writer.AsmWrite('+'+tostr(offset));
                first:=false;
              end;
            if first then
-             AsmWrite('0');
-           AsmWrite(']');
+             writer.AsmWrite('0');
+           writer.AsmWrite(']');
          end;
        end;
 
@@ -360,12 +360,12 @@ interface
       begin
         case o.typ of
           top_reg :
-            AsmWrite(nasm_regname(o.reg));
+            writer.AsmWrite(nasm_regname(o.reg));
           top_const :
             begin
               if (ops=1) and (opcode<>A_RET) then
-               AsmWrite(sizestr(s,dest));
-              AsmWrite(tostr(longint(o.val)));
+               writer.AsmWrite(sizestr(s,dest));
+              writer.AsmWrite(tostr(longint(o.val)));
             end;
           top_ref :
             begin
@@ -379,47 +379,47 @@ interface
                          // (opcode = A_SHR) or (opcode = A_SHL) or
                          // (opcode = A_SAR) or (opcode = A_SAL) or
                           (opcode = A_OUT) or (opcode = A_IN)) then
-                    AsmWrite(sizestr(s,dest));
+                    writer.AsmWrite(sizestr(s,dest));
                   WriteReference(o.ref^);
                 end
 {$ifdef i8086}
               else if o.ref^.refaddr=addr_dgroup then
                 begin
-                  AsmWrite('DGROUP');
+                  writer.AsmWrite('DGROUP');
                 end
               else if o.ref^.refaddr=addr_fardataseg then
                 begin
-                  AsmWrite(current_module.modulename^+'_DATA');
+                  writer.AsmWrite(current_module.modulename^+'_DATA');
                 end
 {$endif i8086}
               else
                 begin
 {$ifdef x86_64}
                   if s=S_L then
-                    asmwrite('dword ')
+                    writer.AsmWrite('dword ')
                   else
-                    asmwrite('qword ');
+                    writer.AsmWrite('qword ');
 {$endif}
 {$ifdef i386}
-                  asmwrite('dword ');
+                  writer.AsmWrite('dword ');
 {$endif i386}
 {$ifdef i8086}
                   if o.ref^.refaddr=addr_seg then
-                    asmwrite('SEG ')
+                    writer.AsmWrite('SEG ')
                   else
-                    asmwrite('word ');
+                    writer.AsmWrite('word ');
 {$endif i8086}
                   if assigned(o.ref^.symbol) then
                    begin
                     if SmartAsm then
                       AddSymbol(o.ref^.symbol.name,false);
-                    asmwrite(o.ref^.symbol.name);
+                    writer.AsmWrite(o.ref^.symbol.name);
                     if o.ref^.offset=0 then
                       exit;
                    end;
                   if o.ref^.offset>0 then
-                   asmwrite('+');
-                  asmwrite(tostr(o.ref^.offset));
+                   writer.AsmWrite('+');
+                  writer.AsmWrite(tostr(o.ref^.offset));
                 end;
             end;
           else
@@ -432,33 +432,33 @@ interface
       begin
         case o.typ of
           top_reg :
-            AsmWrite(nasm_regname(o.reg));
+            writer.AsmWrite(nasm_regname(o.reg));
           top_ref :
             if o.ref^.refaddr=addr_no then
               begin
                 if ai.opsize=S_FAR then
-                  AsmWrite('far ');
+                  writer.AsmWrite('far ');
                 WriteReference(o.ref^);
               end
             else
               begin
                 if ai.opsize=S_FAR then
-                  AsmWrite('far ');
+                  writer.AsmWrite('far ');
                 { else
-                   AsmWrite('near ') just disables short branches, increasing code size. 
+                   writer.AsmWrite('near ') just disables short branches, increasing code size. 
                    Omitting it does not cause any bad effects, tested with nasm 2.11. }
 
-                AsmWrite(o.ref^.symbol.name);
+                writer.AsmWrite(o.ref^.symbol.name);
                 if SmartAsm then
                   AddSymbol(o.ref^.symbol.name,false);
                 if o.ref^.offset>0 then
-                 AsmWrite('+'+tostr(o.ref^.offset))
+                 writer.AsmWrite('+'+tostr(o.ref^.offset))
                 else
                  if o.ref^.offset<0 then
-                  AsmWrite(tostr(o.ref^.offset));
+                  writer.AsmWrite(tostr(o.ref^.offset));
               end;
           top_const :
-            AsmWrite(tostr(aint(o.val)));
+            writer.AsmWrite(tostr(aint(o.val)));
           else
             internalerror(10001);
         end;
@@ -535,19 +535,19 @@ interface
       var
         secname: string;
       begin
-        AsmLn;
-        AsmWrite('SECTION ');
+        writer.AsmLn;
+        writer.AsmWrite('SECTION ');
         { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
           Thus, data which normally goes into .rodata and .rodata_norel sections must
           end up in .data section }
         if (atype in [sec_rodata,sec_rodata_norel]) and
           (target_info.system=system_i386_go32v2) then
-          AsmWrite('.data')
+          writer.AsmWrite('.data')
         else if (atype=sec_user) then
-          AsmWrite(aname)
+          writer.AsmWrite(aname)
         else if (atype=sec_threadvar) and
           (target_info.system in (systems_windows+systems_wince)) then
-          AsmWrite('.tls'#9'bss')
+          writer.AsmWrite('.tls'#9'bss')
         else if target_info.system in [system_i8086_msdos,system_i8086_win16] then
           begin
             if secnames[atype]='.text' then
@@ -556,18 +556,18 @@ interface
               secname:=current_module.modulename^ + '_DATA'
             else
               secname:=omf_secnames[atype];
-            AsmWrite(secname);
+            writer.AsmWrite(secname);
             { first use of this section in the object file? }
             if FSectionsUsed.FindIndexOf(secname)=-1 then
               begin
                 { yes -> write the section attributes as well }
                 if atype=sec_stack then
-                  AsmWrite(' stack');
+                  writer.AsmWrite(' stack');
                 if atype in [sec_debug_frame,sec_debug_info,sec_debug_line,sec_debug_abbrev] then
-                  AsmWrite(' use32')
+                  writer.AsmWrite(' use32')
                 else
-                  AsmWrite(' use16');
-                AsmWrite(' class='+omf_segclass(atype)+
+                  writer.AsmWrite(' use16');
+                writer.AsmWrite(' class='+omf_segclass(atype)+
                   ' align='+tostr(omf_sectiontype2align(atype)));
                 FSectionsUsed.Add(secname,Pointer(self));
                 if section_belongs_to_dgroup(atype) then
@@ -575,23 +575,23 @@ interface
               end;
           end
         else if secnames[atype]='.text' then
-          AsmWrite(CodeSectionName(aname))
+          writer.AsmWrite(CodeSectionName(aname))
         else
-          AsmWrite(secnames[atype]);
+          writer.AsmWrite(secnames[atype]);
         if create_smartlink_sections and
            (atype<>sec_bss) and
            (aname<>'') then
           begin
-            AsmWrite('.');
-            AsmWrite(aname);
+            writer.AsmWrite('.');
+            writer.AsmWrite(aname);
             if atype in [sec_init, sec_fini, sec_stub, sec_code] then
-              AsmWrite(' code align='+tostr(alignment))
+              writer.AsmWrite(' code align='+tostr(alignment))
             else if  atype in [sec_rodata, sec_rodata_norel] then
-              AsmWrite(' rdata align='+tostr(alignment))
+              writer.AsmWrite(' rdata align='+tostr(alignment))
             else
-              AsmWrite(' data align='+tostr(alignment))
+              writer.AsmWrite(' data align='+tostr(alignment))
           end;
-        AsmLn;
+        writer.AsmLn;
         LastSecType:=atype;
       end;
 
@@ -612,11 +612,11 @@ interface
           begin
             if current_settings.x86memorymodel=mm_huge then
               WriteSection(sec_data,'',2);
-            AsmLn;
-            AsmWrite('GROUP DGROUP');
+            writer.AsmLn;
+            writer.AsmWrite('GROUP DGROUP');
             for i:=0 to FSectionsInDGROUP.Count-1 do
-              AsmWrite(' '+FSectionsInDGROUP.NameOfIndex(i));
-            AsmLn;
+              writer.AsmWrite(' '+FSectionsInDGROUP.NameOfIndex(i));
+            writer.AsmLn;
           end;
 {$endif i8086}
       end;
@@ -668,15 +668,15 @@ interface
          case hp.typ of
            ait_comment :
              Begin
-               AsmWrite(target_asm.comment);
-               AsmWritePChar(tai_comment(hp).str);
-               AsmLn;
+               writer.AsmWrite(target_asm.comment);
+               writer.AsmWritePChar(tai_comment(hp).str);
+               writer.AsmLn;
              End;
 
            ait_regalloc :
              begin
                if (cs_asm_regalloc in current_settings.globalswitches) then
-                 AsmWriteLn(#9#9+target_asm.comment+'Register '+nasm_regname(tai_regalloc(hp).reg)+' '+
+                 writer.AsmWriteLn(#9#9+target_asm.comment+'Register '+nasm_regname(tai_regalloc(hp).reg)+' '+
                    regallocstr[tai_regalloc(hp).ratype]);
              end;
 
@@ -701,13 +701,13 @@ interface
                       (LastSecType=sec_threadvar) and
                       (target_info.system in (systems_windows+systems_wince))
                      ) then
-                      AsmWriteLn(#9'ALIGNB '+tostr(tai_align(hp).aligntype))
+                      writer.AsmWriteLn(#9'ALIGNB '+tostr(tai_align(hp).aligntype))
                     else if tai_align_abstract(hp).use_op then
-                      AsmWriteLn(#9'ALIGN '+tostr(tai_align(hp).aligntype)+',DB '+tostr(tai_align_abstract(hp).fillop))
+                      writer.AsmWriteLn(#9'ALIGN '+tostr(tai_align(hp).aligntype)+',DB '+tostr(tai_align_abstract(hp).fillop))
                     else if LastSecType in [sec_code,sec_stub,sec_init,sec_fini] then
-                      AsmWriteLn(#9'ALIGN '+tostr(tai_align(hp).aligntype))
+                      writer.AsmWriteLn(#9'ALIGN '+tostr(tai_align(hp).aligntype))
                     else
-                      AsmWriteLn(#9'ALIGN '+tostr(tai_align(hp).aligntype)+',DB 0');
+                      writer.AsmWriteLn(#9'ALIGN '+tostr(tai_align(hp).aligntype)+',DB 0');
                  end;
              end;
 
@@ -715,13 +715,13 @@ interface
              begin
                if tai_datablock(hp).is_global or SmartAsm then
                 begin
-                  AsmWrite(#9'GLOBAL ');
-                  AsmWriteLn(tai_datablock(hp).sym.name);
+                  writer.AsmWrite(#9'GLOBAL ');
+                  writer.AsmWriteLn(tai_datablock(hp).sym.name);
                 end;
-               AsmWrite(PadTabs(tai_datablock(hp).sym.name,':'));
+               writer.AsmWrite(PadTabs(tai_datablock(hp).sym.name,':'));
                if SmartAsm then
                  AddSymbol(tai_datablock(hp).sym.name,true);
-               AsmWriteLn('RESB'#9+tostr(tai_datablock(hp).size));
+               writer.AsmWriteLn('RESB'#9+tostr(tai_datablock(hp).size));
              end;
 
            ait_const:
@@ -733,39 +733,39 @@ interface
                     begin
                       if assigned(tai_const(hp).sym) then
                         internalerror(200404292);
-                      AsmWrite(ait_const2str[aitconst_32bit]);
-                      AsmWrite(tostr(longint(lo(tai_const(hp).value))));
-                      AsmWrite(',');
-                      AsmWrite(tostr(longint(hi(tai_const(hp).value))));
-                      AsmLn;
+                      writer.AsmWrite(ait_const2str[aitconst_32bit]);
+                      writer.AsmWrite(tostr(longint(lo(tai_const(hp).value))));
+                      writer.AsmWrite(',');
+                      writer.AsmWrite(tostr(longint(hi(tai_const(hp).value))));
+                      writer.AsmLn;
                     end;
                  aitconst_uleb128bit,
                  aitconst_sleb128bit,
                  aitconst_128bit:
                     begin
-                      AsmWriteLn(target_asm.comment+'Unsupported const type '+
+                      writer.AsmWriteLn(target_asm.comment+'Unsupported const type '+
                         ait_const2str[consttype]);
                     end;
 {$ifdef i8086}
                  aitconst_farptr:
                    begin
-                     AsmWrite(ait_const2str[aitconst_16bit]);
+                     writer.AsmWrite(ait_const2str[aitconst_16bit]);
                      if assigned(tai_const(hp).sym) then
                        begin
                          if SmartAsm then
                            AddSymbol(tai_const(hp).sym.name,false);
-                         AsmWrite(tai_const(hp).sym.name);
+                         writer.AsmWrite(tai_const(hp).sym.name);
                          if tai_const(hp).value<>0 then
-                           AsmWrite(tostr_with_plus(tai_const(hp).value));
-                         AsmLn;
-                         AsmWrite(ait_const2str[aitconst_16bit]);
-                         AsmWrite('SEG ');
-                         AsmWrite(tai_const(hp).sym.name);
+                           writer.AsmWrite(tostr_with_plus(tai_const(hp).value));
+                         writer.AsmLn;
+                         writer.AsmWrite(ait_const2str[aitconst_16bit]);
+                         writer.AsmWrite('SEG ');
+                         writer.AsmWrite(tai_const(hp).sym.name);
                        end
                      else
-                       AsmWrite(tostr(lo(longint(tai_const(hp).value)))+','+
+                       writer.AsmWrite(tostr(lo(longint(tai_const(hp).value)))+','+
                                 tostr(hi(longint(tai_const(hp).value))));
-                     AsmLn;
+                     writer.AsmLn;
                    end;
 {$endif i8086}
                  aitconst_32bit,
@@ -776,7 +776,7 @@ interface
                  aitconst_16bit_unaligned,
                  aitconst_32bit_unaligned:
                    begin
-                     AsmWrite(ait_const2str[tai_const(hp).consttype]);
+                     writer.AsmWrite(ait_const2str[tai_const(hp).consttype]);
                      l:=0;
                      repeat
                        if assigned(tai_const(hp).sym) then
@@ -796,7 +796,7 @@ interface
                          end
                        else
                          s:=tostr(tai_const(hp).value);
-                       AsmWrite(s);
+                       writer.AsmWrite(s);
                        inc(l,length(s));
                        if (l>line_length) or
                           (hp.next=nil) or
@@ -804,9 +804,9 @@ interface
                           (tai_const(hp.next).consttype<>consttype) then
                          break;
                        hp:=tai(hp.next);
-                       AsmWrite(',');
+                       writer.AsmWrite(',');
                      until false;
-                     AsmLn;
+                     writer.AsmLn;
                    end;
                  else
                    internalerror(200704252);
@@ -827,7 +827,7 @@ interface
                 Begin
                   for j := 0 to lines-1 do
                    begin
-                     AsmWrite(#9#9'DB'#9);
+                     writer.AsmWrite(#9#9'DB'#9);
                      quoted:=false;
                      for i:=counter to counter+line_length-1 do
                         begin
@@ -839,29 +839,29 @@ interface
                                 if not(quoted) then
                                     begin
                                       if i>counter then
-                                        AsmWrite(',');
-                                      AsmWrite('"');
+                                        writer.AsmWrite(',');
+                                      writer.AsmWrite('"');
                                     end;
-                                AsmWrite(tai_string(hp).str[i]);
+                                writer.AsmWrite(tai_string(hp).str[i]);
                                 quoted:=true;
                               end { if > 31 and < 128 and ord('"') }
                           else
                               begin
                                   if quoted then
-                                      AsmWrite('"');
+                                      writer.AsmWrite('"');
                                   if i>counter then
-                                      AsmWrite(',');
+                                      writer.AsmWrite(',');
                                   quoted:=false;
-                                  AsmWrite(tostr(ord(tai_string(hp).str[i])));
+                                  writer.AsmWrite(tostr(ord(tai_string(hp).str[i])));
                               end;
                        end; { end for i:=0 to... }
-                     if quoted then AsmWrite('"');
-                       AsmWrite(target_info.newline);
+                     if quoted then writer.AsmWrite('"');
+                       writer.AsmWrite(target_info.newline);
                      inc(counter,line_length);
                   end; { end for j:=0 ... }
                 { do last line of lines }
                 if counter<tai_string(hp).len then
-                  AsmWrite(#9#9'DB'#9);
+                  writer.AsmWrite(#9#9'DB'#9);
                 quoted:=false;
                 for i:=counter to tai_string(hp).len-1 do
                   begin
@@ -873,26 +873,26 @@ interface
                           if not(quoted) then
                               begin
                                 if i>counter then
-                                  AsmWrite(',');
-                                AsmWrite('"');
+                                  writer.AsmWrite(',');
+                                writer.AsmWrite('"');
                               end;
-                          AsmWrite(tai_string(hp).str[i]);
+                          writer.AsmWrite(tai_string(hp).str[i]);
                           quoted:=true;
                         end { if > 31 and < 128 and " }
                     else
                         begin
                           if quoted then
-                            AsmWrite('"');
+                            writer.AsmWrite('"');
                           if i>counter then
-                              AsmWrite(',');
+                              writer.AsmWrite(',');
                           quoted:=false;
-                          AsmWrite(tostr(ord(tai_string(hp).str[i])));
+                          writer.AsmWrite(tostr(ord(tai_string(hp).str[i])));
                         end;
                   end; { end for i:=0 to... }
                 if quoted then
-                  AsmWrite('"');
+                  writer.AsmWrite('"');
                 end;
-               AsmLn;
+               writer.AsmLn;
              end;
 
            ait_label :
@@ -901,10 +901,10 @@ interface
                  begin
                    if SmartAsm and (tai_label(hp).labsym.bind=AB_GLOBAL) then
                      begin
-                       AsmWrite(#9'GLOBAL ');
-                       AsmWriteLn(tai_label(hp).labsym.name);
+                       writer.AsmWrite(#9'GLOBAL ');
+                       writer.AsmWriteLn(tai_label(hp).labsym.name);
                      end;
-                   AsmWriteLn(tai_label(hp).labsym.name+':');
+                   writer.AsmWriteLn(tai_label(hp).labsym.name+':');
                  end;
                if SmartAsm then
                  AddSymbol(tai_label(hp).labsym.name,true);
@@ -916,15 +916,15 @@ interface
                  internalerror(2009090803);
                if tai_symbol(hp).is_global or SmartAsm then
                 begin
-                  AsmWrite(#9'GLOBAL ');
-                  AsmWriteLn(tai_symbol(hp).sym.name);
+                  writer.AsmWrite(#9'GLOBAL ');
+                  writer.AsmWriteLn(tai_symbol(hp).sym.name);
                 end;
-               AsmWrite(tai_symbol(hp).sym.name);
+               writer.AsmWrite(tai_symbol(hp).sym.name);
                if SmartAsm then
                  AddSymbol(tai_symbol(hp).sym.name,true);
                if assigned(hp.next) and not(tai(hp.next).typ in
                   [ait_const,ait_realconst,ait_string]) then
-                AsmWriteLn(':')
+                writer.AsmWriteLn(':')
              end;
 
            ait_symbol_end : ;
@@ -963,12 +963,12 @@ interface
                       assigned(taicpu(hp).oper[1]^.ref^.symbol) and
                       (taicpu(hp).oper[1]^.ref^.base=NR_NO)) then
                     begin
-                      AsmWrite(target_asm.comment);
-                      AsmWriteln('Converting LEA to MOV instruction');
+                      writer.AsmWrite(target_asm.comment);
+                      writer.AsmWriteln('Converting LEA to MOV instruction');
                       taicpu(hp).opcode:=A_MOV;
                     end;
                if fixed_opcode=A_FWAIT then
-                AsmWriteln(#9#9'DB'#9'09bh')
+                writer.AsmWriteln(#9#9'DB'#9'09bh')
                else
                 begin
                   prefix:='';
@@ -981,14 +981,14 @@ interface
                       (fixed_opcode=A_POP)) and
                       (taicpu(hp).oper[0]^.typ=top_reg) and
                       (is_segment_reg(taicpu(hp).oper[0]^.reg)) then
-                    AsmWriteln(#9#9'DB'#9'066h');
+                    writer.AsmWriteln(#9#9'DB'#9'066h');
 {$endif not i8086}
-                  AsmWrite(#9#9+prefix+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]);
+                  writer.AsmWrite(#9#9+prefix+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]);
                   if taicpu(hp).ops<>0 then
                    begin
                      if is_calljmp(fixed_opcode) then
                       begin
-                        AsmWrite(#9);
+                        writer.AsmWrite(#9);
                         WriteOper_jmp(taicpu(hp).oper[0]^,taicpu(hp));
                       end
                      else
@@ -996,15 +996,15 @@ interface
                         for i:=0 to taicpu(hp).ops-1 do
                          begin
                            if i=0 then
-                            AsmWrite(#9)
+                            writer.AsmWrite(#9)
                            else
-                            AsmWrite(',');
+                            writer.AsmWrite(',');
                            WriteOper(taicpu(hp).oper[i]^,taicpu(hp).opsize,fixed_opcode,taicpu(hp).ops,(i=2));
                          end;
                       end;
                    end;
                   if not SkipNewLine then
-                    AsmLn;
+                    writer.AsmLn;
                 end;
              end;
 
@@ -1017,9 +1017,7 @@ interface
                if SmartAsm then
                 begin
                  { only reset buffer if nothing has changed }
-                 if AsmSize=AsmStartSize then
-                  AsmClear
-                 else
+                 if not writer.ClearIfEmpty then
                   begin
                     if SmartAsm then
                       begin
@@ -1027,9 +1025,9 @@ interface
                         FreeExternChainList;
                       end;
                     WriteGroups;
-                    AsmClose;
+                    writer.AsmClose;
                     DoAssemble;
-                    AsmCreate(tai_cutobject(hp).place);
+                    writer.AsmCreate(tai_cutobject(hp).place);
                     ResetSectionsList;
                     WriteHeader;
                   end;
@@ -1049,7 +1047,7 @@ interface
                   end;
                  if LastSecType<>sec_none then
                    WriteSection(LastSecType,LastSecName,LastAlign);
-                 AsmStartSize:=AsmSize;
+                 writer.MarkEmpty;
                end;
              end;
 
@@ -1063,9 +1061,9 @@ interface
              begin
                case tai_directive(hp).directive of
                  asd_nasm_import :
-                   AsmWrite('import ');
+                   writer.AsmWrite('import ');
                  asd_extern :
-                   AsmWrite('EXTERN ');
+                   writer.AsmWrite('EXTERN ');
                  else
                    internalerror(200509191);
                end;
@@ -1075,19 +1073,19 @@ interface
                    if SmartAsm then
                      AddSymbol(tai_directive(hp).name,false);
 
-                   AsmWrite(tai_directive(hp).name);
+                   writer.AsmWrite(tai_directive(hp).name);
                  end;
-               AsmLn;
+               writer.AsmLn;
              end;
            ait_seh_directive :
              { Ignore for now };
            ait_varloc:
              begin
                if tai_varloc(hp).newlocationhi<>NR_NO then
-                 AsmWriteLn(target_asm.comment+'Var '+tai_varloc(hp).varsym.realname+' located in register '+
+                 writer.AsmWriteLn(target_asm.comment+'Var '+tai_varloc(hp).varsym.realname+' located in register '+
                    std_regname(tai_varloc(hp).newlocationhi)+':'+std_regname(tai_varloc(hp).newlocation))
                else
-                 AsmWriteLn(target_asm.comment+'Var '+tai_varloc(hp).varsym.realname+' located in register '+
+                 writer.AsmWriteLn(target_asm.comment+'Var '+tai_varloc(hp).varsym.realname+' located in register '+
                    std_regname(tai_varloc(hp).newlocation));
              end;
            else
@@ -1107,7 +1105,7 @@ interface
           begin
             sym:=TAsmSymbol(current_asmdata.AsmSymbolDict[i]);
             if sym.bind=AB_EXTERNAL then
-              AsmWriteln('EXTERN'#9+sym.name);
+              writer.AsmWriteln('EXTERN'#9+sym.name);
           end;
       end;
 
@@ -1119,7 +1117,7 @@ interface
         while assigned(EC) do
           begin
             if not EC^.is_defined then
-              AsmWriteln('EXTERN'#9+EC^.psym^);
+              writer.AsmWriteln('EXTERN'#9+EC^.psym^);
             EC:=EC^.next;
           end;
       end;
@@ -1127,26 +1125,26 @@ interface
     procedure TX86NasmAssembler.WriteHeader;
       begin
 {$if defined(i8086)}
-      AsmWriteLn('BITS 16');
+      writer.AsmWriteLn('BITS 16');
       case current_settings.cputype of
-        cpu_8086: AsmWriteLn('CPU 8086');
-        cpu_186: AsmWriteLn('CPU 186');
-        cpu_286: AsmWriteLn('CPU 286');
-        cpu_386: AsmWriteLn('CPU 386');
-        cpu_Pentium: AsmWriteLn('CPU PENTIUM');
-        cpu_Pentium2: AsmWriteLn('CPU P2');
-        cpu_Pentium3: AsmWriteLn('CPU P3');
-        cpu_Pentium4: AsmWriteLn('CPU P4');
-        cpu_PentiumM: AsmWriteLn('CPU P4');
+        cpu_8086: writer.AsmWriteLn('CPU 8086');
+        cpu_186: writer.AsmWriteLn('CPU 186');
+        cpu_286: writer.AsmWriteLn('CPU 286');
+        cpu_386: writer.AsmWriteLn('CPU 386');
+        cpu_Pentium: writer.AsmWriteLn('CPU PENTIUM');
+        cpu_Pentium2: writer.AsmWriteLn('CPU P2');
+        cpu_Pentium3: writer.AsmWriteLn('CPU P3');
+        cpu_Pentium4: writer.AsmWriteLn('CPU P4');
+        cpu_PentiumM: writer.AsmWriteLn('CPU P4');
         else
           internalerror(2013050101);
       end;
 {$elseif defined(i386)}
-      AsmWriteLn('BITS 32');
+      writer.AsmWriteLn('BITS 32');
       using_relative:=false;
 {$elseif defined(x86_64)}
-      AsmWriteLn('BITS 64');
-      AsmWriteLn('default rel');
+      writer.AsmWriteLn('BITS 64');
+      writer.AsmWriteLn('default rel');
       using_relative:=true;
 {$endif}
       end;
@@ -1162,7 +1160,7 @@ interface
 {$endif}
       ResetSectionsList;
       WriteHeader;
-      AsmLn;
+      writer.AsmLn;
 
       WriteExternals;
 
@@ -1170,13 +1168,13 @@ interface
         begin
           if not (current_asmdata.asmlists[hal].empty) then
             begin
-              AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmListTypeStr[hal]);
+              writer.AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmListTypeStr[hal]);
               writetree(current_asmdata.asmlists[hal]);
-              AsmWriteLn(target_asm.comment+'End asmlist '+AsmListTypeStr[hal]);
+              writer.AsmWriteLn(target_asm.comment+'End asmlist '+AsmListTypeStr[hal]);
             end;
         end;
 
-      AsmLn;
+      writer.AsmLn;
       if SmartAsm then
         begin
           WriteSmartExternals;