Jelajahi Sumber

+ implemented a new {$ASMCPU XXX} directive, allowing to specify a different
CPU target for inline assembler blocks. In addition to the different CPUs
(as listed under 'Supported CPU instruction sets:' in the output of 'fpc -i'),
it also supports the special values 'ANY' and 'CURRENT'. 'ANY' means no
restrictions (i.e. all instructions are available). 'CURRENT' means the
current CPU target (as specified with the '-Cp' command line option). For
backward compatibility, the default value is 'ANY' for all CPU targets, except
i8086, where it defaults to 'CURRENT'.

This directive requires support for the new asd_cpu directive in the assembler
writer. This is currently implemented only for NASM, but will be supported in
some of the other assembler writers as well (incl. the x86 internal assembler
writer).

git-svn-id: trunk@33138 -

nickysn 9 tahun lalu
induk
melakukan
06b9789928
6 mengubah file dengan 572 tambahan dan 518 penghapusan
  1. 15 1
      compiler/globals.pas
  2. 4 1
      compiler/msg/errore.msg
  3. 3 2
      compiler/msgidx.inc
  4. 514 514
      compiler/msgtxt.inc
  5. 6 0
      compiler/ncgbas.pas
  6. 30 0
      compiler/scandir.pas

+ 15 - 1
compiler/globals.pas

@@ -151,7 +151,8 @@ interface
          maxfpuregisters : shortint;
          maxfpuregisters : shortint;
 
 
          cputype,
          cputype,
-         optimizecputype : tcputype;
+         optimizecputype,
+         asmcputype      : tcputype;
          fputype         : tfputype;
          fputype         : tfputype;
          asmmode         : tasmmode;
          asmmode         : tasmmode;
          interfacetype   : tinterfacetypes;
          interfacetype   : tinterfacetypes;
@@ -417,66 +418,79 @@ interface
 {$ifdef GENERIC_CPU}
 {$ifdef GENERIC_CPU}
         cputype : cpu_none;
         cputype : cpu_none;
         optimizecputype : cpu_none;
         optimizecputype : cpu_none;
+        asmcputype : cpu_none;
         fputype : fpu_none;
         fputype : fpu_none;
 {$else not GENERIC_CPU}
 {$else not GENERIC_CPU}
   {$ifdef i386}
   {$ifdef i386}
         cputype : cpu_Pentium;
         cputype : cpu_Pentium;
         optimizecputype : cpu_Pentium3;
         optimizecputype : cpu_Pentium3;
+        asmcputype : cpu_none;
         fputype : fpu_x87;
         fputype : fpu_x87;
   {$endif i386}
   {$endif i386}
   {$ifdef m68k}
   {$ifdef m68k}
         cputype : cpu_MC68020;
         cputype : cpu_MC68020;
         optimizecputype : cpu_MC68020;
         optimizecputype : cpu_MC68020;
+        asmcputype : cpu_none;
         fputype : fpu_soft;
         fputype : fpu_soft;
   {$endif m68k}
   {$endif m68k}
   {$ifdef powerpc}
   {$ifdef powerpc}
         cputype : cpu_PPC604;
         cputype : cpu_PPC604;
         optimizecputype : cpu_ppc7400;
         optimizecputype : cpu_ppc7400;
+        asmcputype : cpu_none;
         fputype : fpu_standard;
         fputype : fpu_standard;
   {$endif powerpc}
   {$endif powerpc}
   {$ifdef POWERPC64}
   {$ifdef POWERPC64}
         cputype : cpu_PPC970;
         cputype : cpu_PPC970;
         optimizecputype : cpu_ppc970;
         optimizecputype : cpu_ppc970;
+        asmcputype : cpu_none;
         fputype : fpu_standard;
         fputype : fpu_standard;
   {$endif POWERPC64}
   {$endif POWERPC64}
   {$ifdef sparc}
   {$ifdef sparc}
         cputype : cpu_SPARC_V9;
         cputype : cpu_SPARC_V9;
         optimizecputype : cpu_SPARC_V9;
         optimizecputype : cpu_SPARC_V9;
+        asmcputype : cpu_none;
         fputype : fpu_hard;
         fputype : fpu_hard;
   {$endif sparc}
   {$endif sparc}
   {$ifdef arm}
   {$ifdef arm}
         cputype : cpu_armv4;
         cputype : cpu_armv4;
         optimizecputype : cpu_armv4;
         optimizecputype : cpu_armv4;
+        asmcputype : cpu_none;
         fputype : fpu_fpa;
         fputype : fpu_fpa;
   {$endif arm}
   {$endif arm}
   {$ifdef x86_64}
   {$ifdef x86_64}
         cputype : cpu_athlon64;
         cputype : cpu_athlon64;
         optimizecputype : cpu_athlon64;
         optimizecputype : cpu_athlon64;
+        asmcputype : cpu_none;
         fputype : fpu_sse64;
         fputype : fpu_sse64;
   {$endif x86_64}
   {$endif x86_64}
   {$ifdef avr}
   {$ifdef avr}
         cputype : cpuinfo.cpu_avr5;
         cputype : cpuinfo.cpu_avr5;
         optimizecputype : cpuinfo.cpu_avr5;
         optimizecputype : cpuinfo.cpu_avr5;
+        asmcputype : cpu_none;
         fputype : fpu_none;
         fputype : fpu_none;
   {$endif avr}
   {$endif avr}
   {$ifdef mips}
   {$ifdef mips}
         cputype : cpu_mips2;
         cputype : cpu_mips2;
         optimizecputype : cpu_mips2;
         optimizecputype : cpu_mips2;
+        asmcputype : cpu_none;
         fputype : fpu_mips2;
         fputype : fpu_mips2;
   {$endif mips}
   {$endif mips}
   {$ifdef jvm}
   {$ifdef jvm}
         cputype : cpu_none;
         cputype : cpu_none;
         optimizecputype : cpu_none;
         optimizecputype : cpu_none;
+        asmcputype : cpu_none;
         fputype : fpu_standard;
         fputype : fpu_standard;
   {$endif jvm}
   {$endif jvm}
   {$ifdef aarch64}
   {$ifdef aarch64}
         cputype : cpu_armv8;
         cputype : cpu_armv8;
         optimizecputype : cpu_armv8;
         optimizecputype : cpu_armv8;
+        asmcputype : cpu_none;
         fputype : fpu_vfp;
         fputype : fpu_vfp;
   {$endif aarch64}
   {$endif aarch64}
   {$ifdef i8086}
   {$ifdef i8086}
         cputype : cpu_8086;
         cputype : cpu_8086;
         optimizecputype : cpu_8086;
         optimizecputype : cpu_8086;
+        asmcputype : cpu_8086;
         fputype : fpu_x87;
         fputype : fpu_x87;
   {$endif i8086}
   {$endif i8086}
 {$endif not GENERIC_CPU}
 {$endif not GENERIC_CPU}

+ 4 - 1
compiler/msg/errore.msg

@@ -138,7 +138,7 @@ general_e_exception_raised=01026_E_Compilation raised exception internally
 #
 #
 # Scanner
 # Scanner
 #
 #
-# 02098 is the last used one
+# 02099 is the last used one
 #
 #
 % \section{Scanner messages.}
 % \section{Scanner messages.}
 % This section lists the messages that the scanner emits. The scanner takes
 % This section lists the messages that the scanner emits. The scanner takes
@@ -409,6 +409,9 @@ scan_w_heapmax_lessthan_heapmin=02097_W_The specified HeapMax value is smaller t
 scan_e_illegal_hugepointernormalization=02098_E_Illegal argument for HUGEPOINTERNORMALIZATION
 scan_e_illegal_hugepointernormalization=02098_E_Illegal argument for HUGEPOINTERNORMALIZATION
 % The only allowed values for HUGEPOINTERNORMALIZATION are BORLANDC, MICROSOFTC
 % The only allowed values for HUGEPOINTERNORMALIZATION are BORLANDC, MICROSOFTC
 % and WATCOMC.
 % and WATCOMC.
+scan_e_illegal_asmcpu_specifier=02099_E_Illegal assembler CPU instruction set specified "$1"
+% When you specify an assembler CPU with the \var{\{\$ASMCPU xxx\}} directive,
+% the compiler didn't recognize the CPU you specified.
 % \end{description}
 % \end{description}
 #
 #
 # Parser
 # Parser

+ 3 - 2
compiler/msgidx.inc

@@ -121,6 +121,7 @@ const
   scan_w_invalid_stacksize=02096;
   scan_w_invalid_stacksize=02096;
   scan_w_heapmax_lessthan_heapmin=02097;
   scan_w_heapmax_lessthan_heapmin=02097;
   scan_e_illegal_hugepointernormalization=02098;
   scan_e_illegal_hugepointernormalization=02098;
+  scan_e_illegal_asmcpu_specifier=02099;
   parser_e_syntax_error=03000;
   parser_e_syntax_error=03000;
   parser_e_dont_nest_interrupt=03004;
   parser_e_dont_nest_interrupt=03004;
   parser_w_proc_directive_ignored=03005;
   parser_w_proc_directive_ignored=03005;
@@ -1026,9 +1027,9 @@ const
   option_info=11024;
   option_info=11024;
   option_help_pages=11025;
   option_help_pages=11025;
 
 
-  MsgTxtSize = 76752;
+  MsgTxtSize = 76872;
 
 
   MsgIdxMax : array[1..20] of longint=(
   MsgIdxMax : array[1..20] of longint=(
-    27,99,345,124,96,58,130,33,208,64,
+    27,100,345,124,96,58,130,33,208,64,
     58,20,1,1,1,1,1,1,1,1
     58,20,1,1,1,1,1,1,1,1
   );
   );

File diff ditekan karena terlalu besar
+ 514 - 514
compiler/msgtxt.inc


+ 6 - 0
compiler/ncgbas.pas

@@ -73,6 +73,7 @@ interface
       nflw,pass_2,ncgutil,
       nflw,pass_2,ncgutil,
       cgbase,cgobj,hlcgobj,
       cgbase,cgobj,hlcgobj,
       procinfo,
       procinfo,
+      cpuinfo,
       tgobj
       tgobj
       ;
       ;
 
 
@@ -253,6 +254,8 @@ interface
              currenttai:=tai(current_asmdata.CurrAsmList.last);
              currenttai:=tai(current_asmdata.CurrAsmList.last);
              exit;
              exit;
            end;
            end;
+         { Switch to the CPU instruction set, specified by the $ASMCPU directive }
+         current_asmdata.CurrAsmList.Concat(tai_directive.create(asd_cpu,cputypestr[current_settings.asmcputype]));
 
 
          { Allocate registers used in the assembler block }
          { Allocate registers used in the assembler block }
          { has_registerlist=true means that registers are specified and already allocated }
          { has_registerlist=true means that registers are specified and already allocated }
@@ -348,6 +351,9 @@ interface
          { Release register used in the assembler block }
          { Release register used in the assembler block }
          if (not has_registerlist) then
          if (not has_registerlist) then
            cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
            cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+
+         { Switch back to the CPU instruction set of the target CPU }
+         current_asmdata.CurrAsmList.Concat(tai_directive.create(asd_cpu,cputypestr[current_settings.cputype]));
        end;
        end;
 
 
 
 

+ 30 - 0
compiler/scandir.pas

@@ -195,6 +195,35 @@ unit scandir;
         current_settings.packrecords:=8;
         current_settings.packrecords:=8;
       end;
       end;
 
 
+    procedure dir_asmcpu;
+      var
+        s : string;
+        cpu: tcputype;
+        found: Boolean;
+      begin
+        current_scanner.skipspace;
+        s:=current_scanner.readid;
+        If Inside_asm_statement then
+          Message1(scan_w_no_asm_reader_switch_inside_asm,s);
+        if s='ANY' then
+          current_settings.asmcputype:=cpu_none
+        else if s='CURRENT' then
+          current_settings.asmcputype:=current_settings.cputype
+        else
+          begin
+            found:=false;
+            for cpu:=succ(low(tcputype)) to high(tcputype) do
+              if s=cputypestr[cpu] then
+                begin
+                  found:=true;
+                  current_settings.asmcputype:=cpu;
+                  break;
+                end;
+            if not found then
+              Message1(scan_e_illegal_asmcpu_specifier,s);
+          end;
+      end;
+
     procedure dir_asmmode;
     procedure dir_asmmode;
       var
       var
         s : string;
         s : string;
@@ -1707,6 +1736,7 @@ unit scandir;
         AddDirective('APPNAME',directive_all, @dir_appname);
         AddDirective('APPNAME',directive_all, @dir_appname);
 {$endif m68k}
 {$endif m68k}
         AddDirective('APPTYPE',directive_all, @dir_apptype);
         AddDirective('APPTYPE',directive_all, @dir_apptype);
+        AddDirective('ASMCPU',directive_all, @dir_asmcpu);
         AddDirective('ASMMODE',directive_all, @dir_asmmode);
         AddDirective('ASMMODE',directive_all, @dir_asmmode);
         AddDirective('ASSERTIONS',directive_all, @dir_assertions);
         AddDirective('ASSERTIONS',directive_all, @dir_assertions);
         AddDirective('BOOLEVAL',directive_all, @dir_booleval);
         AddDirective('BOOLEVAL',directive_all, @dir_booleval);

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini