Pārlūkot izejas kodu

+ added new asm directive 'asd_cpu' (specifies the CPU's instruction set) in the
compiler's internal assembly representation. It is not yet generated by the
compiler and is only implemented properly in the NASM writer (but will
eventually be implemented in the other assembler writers as well, including
the internal assembler). In the future, it is intended to allow:
1) catching instructions, generated by the compiler and not supported by the
target CPU, due to a bug in the code generator
2) allowing a different instruction set to be used in inline asm blocks (I'm
planning a new directive for that - {$asmcpu XXX}), because the code
generator will be able to switch target CPU in the middle of the asm output
stream

git-svn-id: trunk@33121 -

nickysn 9 gadi atpakaļ
vecāks
revīzija
178dab45d3
4 mainītis faili ar 80 papildinājumiem un 14 dzēšanām
  1. 8 2
      compiler/aasmtai.pas
  2. 6 1
      compiler/aggas.pas
  3. 3 0
      compiler/x86/agx86int.pas
  4. 63 11
      compiler/x86/agx86nsm.pas

+ 8 - 2
compiler/aasmtai.pas

@@ -340,7 +340,12 @@ interface
         { supported by recent clang-based assemblers for data-in-code  }
         { supported by recent clang-based assemblers for data-in-code  }
         asd_data_region, asd_end_data_region,
         asd_data_region, asd_end_data_region,
         { ARM }
         { ARM }
-        asd_thumb_func,asd_code
+        asd_thumb_func,asd_code,
+        { restricts the assembler only to those instructions, which are
+          available on the specified CPU; this represents directives such as
+          NASM's 'CPU 686' or MASM/TASM's '.686p'. Might not be supported by
+          all assemblers. }
+        asd_cpu
       );
       );
 
 
       TAsmSehDirective=(
       TAsmSehDirective=(
@@ -376,7 +381,8 @@ interface
         'data_region','end_data_region',
         'data_region','end_data_region',
         { ARM }
         { ARM }
         'thumb_func',
         'thumb_func',
-        'code'
+        'code',
+        'cpu'
       );
       );
       sehdirectivestr : array[TAsmSehDirective] of string[16]=(
       sehdirectivestr : array[TAsmSehDirective] of string[16]=(
         '.seh_proc','.seh_endproc',
         '.seh_proc','.seh_endproc',

+ 6 - 1
compiler/aggas.pas

@@ -1522,7 +1522,12 @@ implementation
 
 
     procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
     procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
     begin
     begin
-      writer.AsmWrite('.'+directivestr[dir]+' ');
+      { TODO: implement asd_cpu for GAS => usually .arch or .cpu, but the CPU
+        name has to be translated as well }
+      if dir=asd_cpu then
+        writer.AsmWrite(asminfo^.comment+' CPU ')
+      else
+        writer.AsmWrite('.'+directivestr[dir]+' ');
     end;
     end;
 
 
 
 

+ 3 - 0
compiler/x86/agx86int.pas

@@ -859,6 +859,9 @@ implementation
                    writer.AsmWrite('import ');
                    writer.AsmWrite('import ');
                  asd_extern :
                  asd_extern :
                    writer.AsmWrite('EXTRN ');
                    writer.AsmWrite('EXTRN ');
+                 asd_cpu :
+                   { TODO: implement this properly for TASM/MASM/WASM (.686p, etc.) }
+                   writer.AsmWrite(asminfo^.comment+' CPU ');
                  else
                  else
                    internalerror(200509192);
                    internalerror(200509192);
                end;
                end;

+ 63 - 11
compiler/x86/agx86nsm.pas

@@ -80,6 +80,37 @@ interface
         {$i r386nasm.inc}
         {$i r386nasm.inc}
 {$elseif defined(i8086)}
 {$elseif defined(i8086)}
         {$i r8086nasm.inc}
         {$i r8086nasm.inc}
+{$endif}
+      );
+      nasm_cpu_name : array[tcputype] of string = (
+{$if defined(x86_64)}
+        '',            // cpu_none,
+        'X64',         // cpu_athlon64,
+        'X64',         // cpu_core_i,
+        'X64',         // cpu_core_avx,
+        'X64'          // cpu_core_avx2
+{$elseif defined(i386)}
+        '',         // cpu_none,
+        '386',      // cpu_386,
+        'PENTIUM',  // cpu_Pentium,
+        'P2',       // cpu_Pentium2,
+        'P3',       // cpu_Pentium3,
+        'P4',       // cpu_Pentium4,
+        'P4',       // cpu_PentiumM,
+        'PRESCOTT', // cpu_core_i,
+        'PRESCOTT', // cpu_core_avx,
+        'PRESCOTT'  // cpu_core_avx2
+{$elseif defined(i8086)}
+        '',        // cpu_none
+        '8086',    // cpu_8086
+        '186',     // cpu_186
+        '286',     // cpu_286
+        '386',     // cpu_386
+        'PENTIUM', // cpu_Pentium
+        'P2',      // cpu_Pentium2
+        'P3',      // cpu_Pentium3
+        'P4',      // cpu_Pentium4
+        'P4'       // cpu_PentiumM
 {$endif}
 {$endif}
       );
       );
 
 
@@ -641,6 +672,7 @@ interface
       fixed_opcode: TAsmOp;
       fixed_opcode: TAsmOp;
       prefix, LastSecName  : string;
       prefix, LastSecName  : string;
       LastAlign : Byte;
       LastAlign : Byte;
+      cpu: tcputype;
     begin
     begin
       if not assigned(p) then
       if not assigned(p) then
        exit;
        exit;
@@ -1074,21 +1106,41 @@ interface
            ait_directive :
            ait_directive :
              begin
              begin
                case tai_directive(hp).directive of
                case tai_directive(hp).directive of
-                 asd_nasm_import :
-                   writer.AsmWrite('import ');
+                 asd_nasm_import,
                  asd_extern :
                  asd_extern :
-                   writer.AsmWrite('EXTERN ');
+                   begin
+                     case tai_directive(hp).directive of
+                       asd_nasm_import :
+                         writer.AsmWrite('import ');
+                       asd_extern :
+                         writer.AsmWrite('EXTERN ');
+                       else
+                         internalerror(200509191);
+                     end;
+                     if tai_directive(hp).name<>'' then
+                       begin
+
+                         if SmartAsm then
+                           AddSymbol(tai_directive(hp).name,false);
+
+                         writer.AsmWrite(tai_directive(hp).name);
+                       end;
+                   end;
+                 asd_cpu :
+                   begin
+                     writer.AsmWrite('CPU ');
+                     for cpu:=low(tcputype) to high(tcputype) do
+                       begin
+                         if tai_directive(hp).name=CPUTypeStr[CPU] then
+                           begin
+                             writer.AsmWriteLn(nasm_cpu_name[cpu]);
+                             break;
+                           end;
+                       end;
+                   end;
                  else
                  else
                    internalerror(200509191);
                    internalerror(200509191);
                end;
                end;
-               if tai_directive(hp).name<>'' then
-                 begin
-
-                   if SmartAsm then
-                     AddSymbol(tai_directive(hp).name,false);
-
-                   writer.AsmWrite(tai_directive(hp).name);
-                 end;
                writer.AsmLn;
                writer.AsmLn;
              end;
              end;
            ait_seh_directive :
            ait_seh_directive :