+ 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 -
This commit is contained in:
nickysn 2016-02-29 22:25:25 +00:00
parent d0d940f119
commit 06b9789928
6 changed files with 770 additions and 716 deletions

View File

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

View File

@ -138,7 +138,7 @@ general_e_exception_raised=01026_E_Compilation raised exception internally
#
# Scanner
#
# 02098 is the last used one
# 02099 is the last used one
#
% \section{Scanner messages.}
% 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
% The only allowed values for HUGEPOINTERNORMALIZATION are BORLANDC, MICROSOFTC
% 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}
#
# Parser

View File

@ -121,6 +121,7 @@ const
scan_w_invalid_stacksize=02096;
scan_w_heapmax_lessthan_heapmin=02097;
scan_e_illegal_hugepointernormalization=02098;
scan_e_illegal_asmcpu_specifier=02099;
parser_e_syntax_error=03000;
parser_e_dont_nest_interrupt=03004;
parser_w_proc_directive_ignored=03005;
@ -1026,9 +1027,9 @@ const
option_info=11024;
option_help_pages=11025;
MsgTxtSize = 76752;
MsgTxtSize = 76872;
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
);

File diff suppressed because it is too large Load Diff

View File

@ -73,6 +73,7 @@ interface
nflw,pass_2,ncgutil,
cgbase,cgobj,hlcgobj,
procinfo,
cpuinfo,
tgobj
;
@ -253,6 +254,8 @@ interface
currenttai:=tai(current_asmdata.CurrAsmList.last);
exit;
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 }
{ has_registerlist=true means that registers are specified and already allocated }
@ -348,6 +351,9 @@ interface
{ Release register used in the assembler block }
if (not has_registerlist) then
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;

View File

@ -195,6 +195,35 @@ unit scandir;
current_settings.packrecords:=8;
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;
var
s : string;
@ -1707,6 +1736,7 @@ unit scandir;
AddDirective('APPNAME',directive_all, @dir_appname);
{$endif m68k}
AddDirective('APPTYPE',directive_all, @dir_apptype);
AddDirective('ASMCPU',directive_all, @dir_asmcpu);
AddDirective('ASMMODE',directive_all, @dir_asmmode);
AddDirective('ASSERTIONS',directive_all, @dir_assertions);
AddDirective('BOOLEVAL',directive_all, @dir_booleval);