Просмотр исходного кода

The compiler inserts ".balign 4" directives before some jump labels, but sometimes the instruction before the align is not a "JMP". In that case we encounter an illegal instruction, because m68k-as does not seem to generate "NOP" instruction in such cases.
So we need to do this manually by changing (in that case) from ".balign" to ".balignw" and passing the opcode of the "NOP" instruction as a argument. The Coldfire manual suggests here to use the "TPF" instruction, but somehow QEMU does not interpret that correctly.

aggas.pas, tgnuassembler.writetree:
* keep track of the last "tai" and pass that to "doalign"
* doalign: do the special handling mentioned above for m68k

git-svn-id: trunk@22799 -

svenbarth 12 лет назад
Родитель
Сommit
a34f28c067
1 измененных файлов с 36 добавлено и 2 удалено
  1. 36 2
      compiler/aggas.pas

+ 36 - 2
compiler/aggas.pas

@@ -108,6 +108,9 @@ implementation
 {$ifdef TEST_WIN64_SEH}
 {$ifdef TEST_WIN64_SEH}
       itcpugas,
       itcpugas,
 {$endif TEST_WIN64_SEH}
 {$endif TEST_WIN64_SEH}
+{$ifdef m68k}
+      cpuinfo,aasmcpu,
+{$endif m68k}
       cpubase;
       cpubase;
 
 
     const
     const
@@ -636,15 +639,40 @@ implementation
         end;
         end;
 
 
 
 
-      procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint);
+      procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint;lasthp:tai);
         var
         var
           i: longint;
           i: longint;
+{$ifdef m68k}
+          instr : string;
+{$endif}
         begin
         begin
           last_align:=alignment;
           last_align:=alignment;
           if alignment>1 then
           if alignment>1 then
             begin
             begin
               if not(target_info.system in (systems_darwin+systems_aix)) then
               if not(target_info.system in (systems_darwin+systems_aix)) then
                 begin
                 begin
+{$ifdef m68k}
+                  if assigned(lasthp) and
+                      (lasthp.typ=ait_instruction) and
+                      (taicpu(lasthp).opcode<>A_JMP) then
+                    begin
+                      if ispowerof2(alignment,i) then
+                        begin
+                          { the Coldfire manual suggests the TBF instruction for
+                            alignments, but somehow QEMU does not interpret that
+                            correctly... }
+                          {if current_settings.cputype=cpu_coldfire then
+                            instr:='0x51fc'
+                          else}
+                            instr:='0x4e71';
+                          AsmWrite(#9'.balignw '+tostr(alignment)+','+instr);
+                        end
+                      else
+                        internalerror(2012102101);
+                    end
+                  else
+                    begin
+{$endif m68k}
                   AsmWrite(#9'.balign '+tostr(alignment));
                   AsmWrite(#9'.balign '+tostr(alignment));
                   if use_op then
                   if use_op then
                     AsmWrite(','+tostr(fillop))
                     AsmWrite(','+tostr(fillop))
@@ -653,6 +681,9 @@ implementation
                   else if LastSecType=sec_code then
                   else if LastSecType=sec_code then
                     AsmWrite(',0x90');
                     AsmWrite(',0x90');
 {$endif x86}
 {$endif x86}
+{$ifdef m68k}
+                    end;
+{$endif m68k}
                 end
                 end
               else
               else
                 begin
                 begin
@@ -668,6 +699,7 @@ implementation
 
 
     var
     var
       ch       : char;
       ch       : char;
+      lasthp,
       hp       : tai;
       hp       : tai;
       constdef : taiconst_type;
       constdef : taiconst_type;
       s,t      : string;
       s,t      : string;
@@ -695,6 +727,7 @@ implementation
       do_line:=(cs_asm_source in current_settings.globalswitches) or
       do_line:=(cs_asm_source in current_settings.globalswitches) or
                ((cs_lineinfo in current_settings.moduleswitches)
                ((cs_lineinfo in current_settings.moduleswitches)
                  and (p=current_asmdata.asmlists[al_procedures]));
                  and (p=current_asmdata.asmlists[al_procedures]));
+      lasthp:=nil;
       hp:=tai(p.first);
       hp:=tai(p.first);
       while assigned(hp) do
       while assigned(hp) do
        begin
        begin
@@ -743,7 +776,7 @@ implementation
 
 
            ait_align :
            ait_align :
              begin
              begin
-               doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align);
+               doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align,lasthp);
              end;
              end;
 
 
            ait_section :
            ait_section :
@@ -1436,6 +1469,7 @@ implementation
            else
            else
              internalerror(2006012201);
              internalerror(2006012201);
          end;
          end;
+         lasthp:=hp;
          hp:=tai(hp.next);
          hp:=tai(hp.next);
        end;
        end;
     end;
     end;