فهرست منبع

+ 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 سال پیش
والد
کامیت
178dab45d3
4فایلهای تغییر یافته به همراه80 افزوده شده و 14 حذف شده
  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  }
         asd_data_region, asd_end_data_region,
         { 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=(
@@ -376,7 +381,8 @@ interface
         'data_region','end_data_region',
         { ARM }
         'thumb_func',
-        'code'
+        'code',
+        'cpu'
       );
       sehdirectivestr : array[TAsmSehDirective] of string[16]=(
         '.seh_proc','.seh_endproc',

+ 6 - 1
compiler/aggas.pas

@@ -1522,7 +1522,12 @@ implementation
 
     procedure TGNUAssembler.WriteDirectiveName(dir: TAsmDirective);
     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;
 
 

+ 3 - 0
compiler/x86/agx86int.pas

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

+ 63 - 11
compiler/x86/agx86nsm.pas

@@ -80,6 +80,37 @@ interface
         {$i r386nasm.inc}
 {$elseif defined(i8086)}
         {$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}
       );
 
@@ -641,6 +672,7 @@ interface
       fixed_opcode: TAsmOp;
       prefix, LastSecName  : string;
       LastAlign : Byte;
+      cpu: tcputype;
     begin
       if not assigned(p) then
        exit;
@@ -1074,21 +1106,41 @@ interface
            ait_directive :
              begin
                case tai_directive(hp).directive of
-                 asd_nasm_import :
-                   writer.AsmWrite('import ');
+                 asd_nasm_import,
                  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
                    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;
                writer.AsmLn;
              end;
            ait_seh_directive :