#
#     Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#

#
# Compiler Configurations common to native Fortran compilers
#


# File suffixes
suffix f is
    string(f for ftn f77 $SITEF77SUFFIX $USERF77SUFFIX)
    help(Fortran fixed-form source: compile, assemble, link);
suffix f90 is
    string(f90 f95 f03 f08 $SITEF90SUFFIX $USERF90SUFFIX)
    help(Fortran source: compile, assemble, link);
suffix F is
    string(F FOR FTN F77 FPP fpp $SITEF77PPSUFFIX $USERF77PPSUFFIX)
    help(Fortran fixed-form source: preprocess, compile, assemble, link);
suffix F90 is
    string(F90 F95 F03 F08 $SITEF90PPSUFFIX $USERF90PPSUFFIX)
    help(Fortran source: preprocess, compile, assemble, link);
suffix cuf is
    string(cuf $SITECUFSUFFIX $USERCUFSUFFIX)
    help(CUDA Fortran: compile, assemble, link);
suffix CUF is
    string(CUF $SITECUFPPSUFFIX $USERCUFPPSUFFIX)
    help(CUDA Fortran: preprocess, compile, assemble, link);
suffix ilm is hide
    string(ilm)
    help(F90 intermediate language macro file);
suffix mlir is hide
    string(mlir fir)
    help(MLIR representation);

append SRCSUFFIX=f f90 F F90 $if($notequal($SYSACCELS,),cuf CUF);

variable F90SUFFIX is   # set by languagerc
    help(Suffixes to be compiled by f90 compiler)
  default(F90 f90 F f);

variable CUFSUFFIX is   # set by languagerc
    help(CUDA Fortran suffixes to be compiled by f90 compiler)
    default(CUF cuf);

variable MLIRSUFFIX is 
    help(MLIR suffixes to be compiled by fortran compiler)
  default(mlir);

variable PERSONALITY is # set by linux .nvcrc
    help(library that resolves gxx_personality_v0 for the -cuda link)
    default ();

variable USERF77SUFFIX is default();
variable USERF77PPSUFFIX is default();
variable USERF90SUFFIX is default();
variable USERF90PPSUFFIX is default();
variable USERCUFSUFFIX is default();
variable USERCUFPPSUFFIX is default();
variable SITEF77SUFFIX is default();
variable SITEF77PPSUFFIX is default();
variable SITEF90SUFFIX is default();
variable SITEF90PPSUFFIX is default();
variable SITECUFSUFFIX is default();
variable SITECUFPPSUFFIX is default();

variable FARGS is               # appended by many switches
    help(Switches to Fortran compiler);

variable F90E is default(f901); # command to be used by -E

variable F90X is default(f90x);
variable CUFX is default(cufx);

variable APPENDMOD is default(1);

variable FCOMPCOMMANDS is
    help(Fortran compile commands)
    default($F90X $CUFX f902);

variable FEXTCOMMANDS is
    help(Fortran extract commands)
    default($if($USEFLANG1,flang1ext,f901ext));

variable FFEARGS is     # appended by many switches
    help(Switches to Fortran Front End);

variable F901 is        # can be changed by targetrc
    help(Name of the Fortran phase 1 module);

variable FLANG1 is    
    help(Name of the Fortran phase 1 module);

variable USEFLANG1 is 
    help(Substituting flang1 to fort1);

variable FLANG1ARGS is    # appended by many switches
    help(Switches passed to nvflang compiler);

variable F902 is        # can be changed by targetrc
    help(Name of the Fortran phase 2 module);

variable F90EXT is      # can be changed by targetrc
    help(Name of the Fortran extractor for inlining);

variable F901ARGS is    # appended by many switches
    help(Switches passed to F90 compiler);

variable F901DEFARGS is # default arguments
    help(More switches passed to F90 compiler)
    default($if($ALLOCATABLE95,-y,-x) 54 1);

variable ALLOCATABLE95 is
    help(Use Fortran 95 allocatable semantics)
    default();

variable F902ARGS is    # appended by many switches
    help(Switches passed to F90 back end);

variable FCGARGS is     # appended by many switches
    help(Switches passed to F90 compiler back end);

variable HCOMPDIR is    # set by -Yh
    help(Directory containing the F90 front ends)
    default($DEFCCOMPDIR);

# library containing fortran interface to mpi
variable FORTRANMPI is default(fmpich);

variable VECT is
    help(Vector optimization level)
    default($if($DEFVECT,$DEFVECT,48));

variable NVF_X86AVX is default(
    $if($and($equal($TARGET,linux86-64),$equal($CG,llvm)),
        $if($ISTPHOST,$select($AVX2-$AVX,"1-1","-avx2","0-1","-avx","0-0",""),
            $select($CLTPVAL,"-tp skylake","-avx2","-tp haswell","-avx2","-tp zen","-avx2","-tp zen2","-avx2","-tp sandybridge","-avx"))));

variable PGF90LIB is
    help(Name of f90 runtime libraries)
    default($if($or($equal($TARGET,win64),$equal($TARGET,win64-llvm)),$(IMPSW)nv) $(LIBSSW)nvf);

variable FLANGLIBDIR is default($COMPBASE/$COMPSYS/$COMPVER/$(COMPLIBPREFIX)lib);

variable FLANGF128LIBS is
    help(Linker options to link 128-bit float support libraries)
    default($if($equal($TARGET,linux86-64),
            -lFortranFloat128Math $ASNEEDED -lquadmath $NOASNEEDED));

variable FLANGCUFLIBSSUFFIX is default($if($expr($CUDAXXYY<12000), _cuda_11, _cuda_12));
variable FLANGCUFLIBS is
    help(Linker options to link CUDA Fortran support libraries)
            default($if($ANYCUF, -lCufRuntime$FLANGCUFLIBSSUFFIX));

variable FLANGLIBS is
    help(Name of F18 runtime libraries)
    default($if($isdir($FLANGLIBDIR),$PGISTATICX $FLANGF128LIBS -lFortranRuntime -lFortranDecimal $FLANGCUFLIBS $(LIBSSW)nvfn $PGIUNSTATICX));

# Use F18 runtime CUDA libraries, if -acc is specified.
# The CUDA libraries will be linked on top of the pure
# host versions of the same libraries. So all the host
# references will be resolved to the definitions from
# the pure host libraries, and then only the device references
# will be resolved to the device code inside the CUDA libraries.
# This way we are not linking in any CUDA host setup code
# (such as __cudaRegisterVar calls), and thus we do not need
# to link cudart library to resolve references in this setup code.
# The libraries are built with cuda-11.8 currently.
variable FLANGCUDALIBSSUFFIX is default($if($expr($CUDAXXYY<12000), _cuda_11.8, _cuda_12.0));
variable FLANGCUDALIBS is
    help(Name of F18 CUDA runtime libraries)
    default($if($land($isdir($FLANGLIBDIR),$LNGACC,$expr($CUDAXXYY>=11080),$lor($ISNVNG,$NEEDFLANGLIBS)),-lFortranRuntime$FLANGCUDALIBSSUFFIX -lFortranDecimal$FLANGCUDALIBSSUFFIX));

variable EXPLICITFORM is 
    help(Form is explicitly provided)
    default();

# This variable is set to the value of the CPATH environment variables
# only within the TA environment. This allows to use the new modules
# approach in TA and which set the Fortran modules directory for
# third-party libraries in CPATH environment variable. This feature is
# not exposed to the user, so if a user set the CPATH environment
# variable it will affect only nvc/nvc++ and not nvfortran.
variable FPATH is
    help(Corresponds to CPATH (for internal use only))
    default();

cinclude rcfiles/internalrc;

append F901ARGS=$if($VECT,-vect $VECT) $F901DEFARGS $if($FNEEDCUDA,$foreach(f,$CUDAVERSIONDEFINE, -def $f) -cudaver $CUDAXXYY) $ifn($equal($IEEE,),-ieee $IEEE);
append CGARGS=$if($ANYCUF,$DEFAULTCAPFLAG $TOOLKITFLAG);

# What tools can the driver invoke?
# values:
#   name        common name
#   program     command name or name of a variable giving the command
#   directory   command directory or variable giving the directory
#   arguments   list of variables with arguments to the tool

tool f901 is help(Fortran compiler phase 1)
    program($F901) directory($HCOMPDIR);
tool flang1 is help(nvflang compiler phase 1)
    program($FLANG1) directory($FLANG1COMPDIR);
tool f902 is help(Fortran compiler phase 2)
    program($F902) directory($CCOMPDIR);
tool f90_ex is help(Fortran extractor for inlining)
    program($F90EXT) directory($CCOMPDIR);

# Commands run by the phases
# DEF arguments are generally given in the targetrc file
# the EXTRA arguments are generally given in the .xxrc file

command f901 is
    help(Fortran Compiler phase 1)
    tool(f901)
    suffix($F90SUFFIX $if($notequal($SYSACCELS,),$CUFSUFFIX))
    echo($if($and($ECHONAME,$expr($count($realfiles)>1)),$input:))
    set(ilmfile=$ifn($NOILM,$if($KEEPIL$KEEPTEMP,$basename($input).ilm,$tempfile(ilm))))
    set(ccifile=$if($or($KEEPCCI,$KEEPTEMP),$basename($input).cci,$tempfile(cci)))
    set(inlineonlyfile=$if($or($KEEPINLONLY,$KEEPTEMP),$basename($input).inl,$tempfile(inl)))
    set(stbfile=$if($KEEPSTB$KEEPTEMP,$basename($input).stb,$tempfile(stb)))
    set(ffile=$basename($input)$lowercase($suffix($input)))
    set(ppfile=$if($PREPROCONLY,$if($KEEPPREPRO,$if($equal($ffile,$input),$error(Output would overwrite file $ffile),$ffile),-pp)))
    set(thisoutfile=$if($and($or($COMPILEONLY,$ASMONLY),$OUTFILE),$OUTFILE))
    tempfile($dirname($ilmfile)/$basename($ilmfile).dbg)
    set(appendmod=$if($APPENDMOD,$ifn($IPARECOMPILE,YES)))
    set(doappend=$if($or($appendmod,$IPALINK),YES))
    set(modfile=$if($appendmod,$if($KEEPTEMP,$if($thisoutfile,$dirname($thisoutfile)/$basename($thisoutfile).cmod,$basename($input).cmod),$tempfile(cmod))))
    set(mdxfile=$if($appendmod,$if($KEEPTEMP,$if($thisoutfile,$dirname($thisoutfile)/$basename($thisoutfile).cmdx,$basename($input).cmdx),$tempfile(cmdx))))
    set(ipofile=$if($IPALINK,$if($IPOFILE$KEEPTEMP,$if($thisoutfile,$dirname($thisoutfile)/$basename($thisoutfile).ipo,$basename($input).ipo),$tempfile(ipo))))
    set(ipxfile=$if($IPALINK,$if($KEEPTEMP,$basename($input).ipx,$tempfile(ipx))))
    set(ENABLECUDA=$if($currentsuffix(cuf,CUF),-x 137 1 -x 121 0xc00 -x 180 0x4000000 $TOOLKITFLAG $if($notequal($CUDAROOT,),-cudaroot $CUDAROOT)))
    error($if($and($currentsuffix(cuf,CUF),$equal($USECUDAROOT,)),CUDA version $CUDAXDY is not available in this installation.))
    set(cudadef=$if($currentsuffix(cuf,CUF),_CUDA))
    arguments($input $COMMONARGS $DEFF901ARGS $EXTRAF901ARGS
        $if($STDINC,-stdinc $replace($STDINC,,$INCSEP),-nostdinc)
        $ifn($DRYRUN,-cmdline $quote(+$DRIVERCOMMAND $file $switches))
        $foreach(d,$STDDEF,-def $d )
        $foreach(d,$LOCALDEFS,-def $d )
        $foreach(i,$SITEINC,-idir $i )
        $foreach(i,$USRINC,-idir $i )
        $foreach(i,$USRSTDINC,-idir $i )
        $foreach(i,$replace($USER_INCLUDE_PATH,",", ),-idir $i )
        $foreach(i,$FPATH,-idir $i )
        $foreach(d,$SITEDEF,-def $d )
        $foreach(f,$cudadef,-def $f )
        $USRDEFDEF
        $if($GENCCFF,-ccff)
        $if($currentsuffix(F,F90,CUF),-preprocess)
        $if($currentsuffix(f90,F90,cuf,CUF),-freeform,-nofreeform)
        $ENABLECUDA
        $FARGS $F901ARGS $FINLINEARGS $IPACARGS
        $if($and($IPALINK,$IPAEXPORT),
            -ipacomp $quote($DRIVERNAME)
            -ipacompsw $quote(+"$"n $escape($switches) -c --ZIPAimport "$"f "$"b "$"a -o "$"o)
            -ipaexport $ipxfile
        )
        $if($IPALINK,-ipofile $ipofile)
        $if($PGLLVMTARGET,-stbfile $stbfile)
        $if($appendmod,-modexport $modfile -modindex $mdxfile)
        $if($PREPROCONLY,-es $ppfile,$if($NOILM,-nooutput,-cci $ccifile -inlonly $inlineonlyfile -output $ilmfile)))
    execute(
        status($expr($status==19))
        exit(19)
    )
    execute(
        status($expr($status==234))
        set(RMARGS=-O -O2 -O3 -O4 -Ofast -Mvect -Munroll -Mconcur -Mipa -Mpfi -Mpfo -nfast)
        set(ADDARGS=-O1 -Mrestart)
        set(MUSTRESTART=1)
        set(PRINTRESTARTCMD=1)
        restart($COMPBASE/$COMPSYS/$COMPVER/$COMPBBIN)
    )
    execute(
        condition($notequal($EXTRACTINLINE$EXTRACT,))
        condition($SINGLE_FILE)
        # This is a work around for real inlining bugs in FS#36729.
        condition($equal($currentsuffix(cuf,CUF),))
        input($ilmfile)
        command(f902ext)
    )
    execute(
        condition($equal($PREPROCONLY$ILMONLY$EXTRACTONLY,))
        input($ilmfile)
        command(f902)
    );

command flang1 is
    help(Fortran Compiler phase 1)
    tool(flang1)
    suffix($F90SUFFIX $MLIRSUFFIX $if($notequal($SYSACCELS,),$CUFSUFFIX))
    echo($if($and($ECHONAME,$expr($count($realfiles)>1)),$input:))
    set(ilmfile=$ifn($NOILM,$if($KEEPIL$KEEPTEMP,$if($ILMONLY,$if($notequal($OUTFILE,),$OUTFILE,$basename($input).ilm),$basename($input).ilm),$tempfile(ilm))))
    set(firfile=$if($FIRONLY,$if($notequal($OUTFILE,),$OUTFILE,$basename($input).fir),$basename($input).fir))
    set(llfile_global=$if($KEEPIL$KEEPTEMP,$basename($input)_globals.ll,$tempfile(ll)))
    set(GPU_GLOBAL_FILE=$if($KEEPIL$KEEPTEMP,$basename($input)_globals.gpu,$tempfile(gpu)))
    set(stbfile=$if($KEEPSTB$KEEPTEMP,$basename($input).stb,$tempfile(stb)))
    set(ffile=$basename($input)$lowercase($suffix($input)))
    set(ppfile=$if($PREPROCONLY,$if($KEEPPREPRO,$if($equal($ffile,$input),$error(Output would overwrite file $ffile),-o $ffile),-pp)))
    set(thisoutfile=$if($and($or($COMPILEONLY,$ASMONLY),$OUTFILE),$OUTFILE))
    tempfile($dirname($ilmfile)/$basename($ilmfile).dbg)
    set(ENABLECUDA=$if($currentsuffix(cuf,CUF),-x 137 1 -x 121 0xc00 -x 180 0x4000000 $TOOLKITFLAG $if($notequal($CUDAROOT,),-cudaroot $CUDAROOT)))
    arguments($input 
        $foreach(d,$STDDEF,-def $d )
        $foreach(d,$LOCALDEFS,-def $d )
        $foreach(i,$SITEINC,-I $i )
        $foreach(i,$USRINC,-I $i )
        $foreach(i,$USRSTDINC,-J $i )
        $foreach(i,$replace($USER_INCLUDE_PATH,",", ),-idir $i )
        $foreach(i,$FPATH,-I $i )
        $foreach(d,$SITEDEF,-def $d )
        $foreach(f,$cudadef,-def $f )
        $if($ACCFEFLAGS, -fopenacc)
        $USRDEFDEF
        $if($currentsuffix(F,F90,CUF),-preprocess)
        $if($currentsuffix(cuf,CUF),-fcuda)
        $ifn($EXPLICITFORM,$if($currentsuffix(f90,F90,cuf,CUF),-Mfree,-Mfixed))
        $FARGS $FLANG1ARGS
        $if($PGLLVMTARGET,-stbfile $stbfile)
        -intrinsic-module-directory $FLANGMODULEDIR
        -builtin-include-dirs $FLANGINCLUDEDIR
        -gbl $llfile_global
        -gpugbl $GPU_GLOBAL_FILE
        $if($PREPROCONLY,-es $ppfile,$if($FIRONLY,-o $firfile,-o $ilmfile)))
    execute(
        condition($notequal($EXTRACTINLINE$EXTRACT,))
        input($ilmfile)
        command(f902ext)
    )
    execute(
        condition($equal($PREPROCONLY$ILMONLY$FIRONLY$SYNTAXONLY$EXTRACTONLY,))
        input($ilmfile)
        command(f902)
    );

command f902 is
    help(Fortran Compiler phase 2)
    tool(f902)
    suffix(ilm)
    set(asmfile=$ifn($NOASM,$if($and($COMPILEONLY,$notequal($OUTFILE,)),$OUTFILE,$ifn($KEEPTEMP$KEEPASM,$tempfile($ASMSUFFIX),$if($and($ASMONLY,$notequal($OUTFILE,)),$dirname($OUTFILE)/$basename($OUTFILE).s,$basename($file).$ASMSUFFIX)))))
    set(llfile=$ifn($NOASM,$if($and($COMPILEONLY,$notequal($OUTFILE,)),$OUTFILE,$ifn($KEEPTEMP$KEEPLL,$tempfile(ll),$if($and($ASMONLY,$notequal($OUTFILE,)),$dirname($OUTFILE)/$basename($OUTFILE).ll,$basename($file).ll)))))
    set(ppfile=$if($PREPROCONLY,$if($KEEPPREPRO,$if($equal($ffile,$file),$error(Output would overwrite file $ffile),$ffile),-pp)))
    # .ipn file holds -Mipa=inline information
    set(ipnfile=$if($IPAINLINE,$if($KEEPTEMP,$basename($input).ipn,$tempfile(ipn))))
    # .ipm file holds -Mipa=inline index information
    set(ipmfile=$if($IPAINLINE,$if($KEEPTEMP,$basename($input).ipm,$tempfile(ipm))))
    # .inl file holds -Minline inlining information for IPA
    set(inlfile=$if($IPAINLINE,$if($KEEPTEMP,$basename($input).ipk,$tempfile(ipk))))
    # If phase 1 has not been run (e.g. input.ilm file was directly passed
    # to the compiler driver), the files produced by phase 1
    # still have to be provided to guarantee correct phase 2 work.
    # Assume that the files have been saved with -Mkeep during phase 1
    # that was run manually. The affected variables are:
    # GPU_GLOBAL_FILE, llfile_global, stbfile.
    set(GPU_GLOBAL_FILE=$if($equal($GPU_GLOBAL_FILE,),$basename($input)_globals.gpu,$GPU_GLOBAL_FILE))
    set(llfile_global=$if($equal($llfile_global,),$basename($input)_globals.ll,$llfile_global))
    set(stbfile=$if($equal($stbfile,),$basename($input).stb,$stbfile))
    append(F902ARGS=$if($PGLLVMTARGET, $PGLLVMVFP $LLVMVERFLAGS))
    append(F902ARGS=-x 68 0x20)
    set(DONTINSTRFILE=$if($foreach(d,$NOINSTRFILELIST,$if($contains($file, $d),1)),-y 129 0x800))
    arguments($input -fn $file $COMMONARGS $DEFF902ARGS $EXTRAF902ARGS
        $COMMONCGARGS $INLINEARGS $INLINECARGS $NOINSTRFUNCS
        $ENABLECUDA $FCGARGS $F902ARGS $CGARGS $DONTINSTRFILE $IPAC2ARGS
        $ifn($USEFLANG1,-cci $ccifile)
        $if($USEFLANG1,-noquad) #FS 33023
        $ifn($DRYRUN,-cmdline $quote(+$DRIVERCOMMAND $file $switches))
        $if($ipnfile,-exfile $ipnfile -exifile $ipmfile)
        $if($inlfile,-inlfile $inlfile)
        $if($PGLLVMTARGET,-stbfile $stbfile)
        $if($NOASM,-noasm,-asm $if($PGLLVMTARGET, $llfile, $asmfile))
        $if($USEFLANG1,-gpuglobalfile $GPU_GLOBAL_FILE))
    execute(
        condition($USEFLANG1)
        # If it is a dry run, the files are not present. Do not run the action. 
        # Echo the command in the log instead so it is replayable
        action($if($equal($DRYRUN,0), merge_func_and_global_llvm($path($llfile),$path($llfile_global))))
        echo($if($or($DRYRUN,$VERBOSE), cat $path($llfile_global) >> $path($llfile)))
    )
	execute(
	    condition($USEBITCODERT)
 	    condition($equal($PGLLVMTARGET,yes))
	    input($llfile)
	    command($LLVMAS)
	)
    execute(
	    condition($not($USEBITCODERT))
        condition($equal($PGLLVMTARGET,yes))
        condition($equal($NOASM,))
        condition($equal($LLONLY,))
        input($llfile)
        command($if($USENVBE,$NVBE,$if($USECLANG,$CLANGCMD,$LLCCMD)))
    )
    execute(
        condition($equal($NOASM$COMPILEONLY,))
        condition($equal($PGLLVMTARGET,))
        input($asmfile)
        command(Nasm)
    );

command f901ext is
    help(Fortran Compiler phase 1)
    tool(f901)
    # This is a typo but fixing it causes issues with `-Minline`.
    suffix($F90SUFFIX $if($notequal($SYSACCEL,),$CUFSUFFIX))
    echo($if($and($ECHONAME,$expr($count($realfiles)>1)),$input:))
    set(ilmfile=$ifn($NOILM,$if($KEEPIL$KEEPTEMP,$basename($input).ilm,$tempfile(ilm))))
    set(stbfile=$if($KEEPSTB$KEEPTEMP,$basename($input).stb,$tempfile(stb)))
    set(inlineonlyfile=$if($or($KEEPINLONLY,$KEEPTEMP),$basename($input).inl,$tempfile(inl)))
    set(ffile=$basename($input)$lowercase($suffix($input)))
    set(ppfile=$if($PREPROCONLY,$if($KEEPPREPRO,$if($equal($ffile,$input),$error(Output would overwrite file $ffile),$ffile),-pp)))
    set(thisoutfile=$if($and($or($COMPILEONLY,$ASMONLY),$OUTFILE),$OUTFILE))
    tempfile($dirname($ilmfile)/$basename($ilmfile).dbg)
    set(ENABLECUDA=$if($currentsuffix(cuf,CUF),-x 137 1 -x 121 0xc00 -x 180 0x4000000))
    set(cudadef=$if($currentsuffix(cuf,CUF),_CUDA))
    arguments($input $COMMONARGS $DEFF901ARGS $EXTRAF901ARGS
        $if($STDINC,-stdinc $replace($STDINC,,$INCSEP),-nostdinc)
        $foreach(d,$STDDEF,-def $d )
        $foreach(d,$LOCALDEFS,-def $d )
        $foreach(i,$SITEINC,-idir $i )
        $foreach(i,$USRINC,-idir $i )
        $foreach(i,$USRSTDINC,-idir $i )
        $foreach(i,$replace($USER_INCLUDE_PATH,",", ),-idir $i )
        $foreach(i,$FPATH,-idir $i )
        $foreach(d,$SITEDEF,-def $d )
        $foreach(f,$cudadef,-def $f )
        $USRDEFDEF
        $ifn($DRYRUN,-cmdline $quote(+$DRIVERCOMMAND $file $switches))
        $if($currentsuffix(F,F90,CUF),-preprocess)
        $if($currentsuffix(f90,F90,cuf,CUF),-freeform,-nofreeform)
        $ENABLECUDA
        $FARGS $F901ARGS -y 89 0x42
        $if($PGLLVMTARGET,-stbfile $stbfile)
        $if($USEINLONLYFILE,-inlonly $inlineonlyfile)
        $if($EXTRACTINLINE, -x 13 0x08)
        $if($PREPROCONLY,-es $ppfile,$if($NOILM,-nooutput,-output $ilmfile)))
    execute(
        status($expr($status==19))
        exit(19)
    )
    execute(
        input($ilmfile)
        command(f902ext)
    );

command flang1ext is
    help(Fortran Compiler phase 1)
    tool(flang1)
    suffix($F90SUFFIX $MLIRSUFFIX $if($notequal($SYSACCELS,),$CUFSUFFIX))
    echo($if($and($ECHONAME,$expr($count($realfiles)>1)),$input:))
    set(ilmfile=$ifn($NOILM,$if($KEEPIL$KEEPTEMP,$if($ILMONLY,$if($notequal($OUTFILE,),$OUTFILE,$basename($input).ilm),$basename($input).ilm),$tempfile(ilm))))
    set(firfile=$if($FIRONLY,$if($notequal($OUTFILE,),$OUTFILE,$basename($input).fir),$basename($input).fir))
    set(llfile_global=$ifn($NOILM,$if($KEEPIL$KEEPTEMP,$basename($input)_globals.ll,$tempfile(ll))))
    set(gpufile_global=$ifn($NOILM,$if($KEEPIL$KEEPTEMP,$basename($input)_globals.gpu,$tempfile(gpu))))
    set(stbfile=$if($KEEPSTB$KEEPTEMP,$basename($input).stb,$tempfile(stb)))
    set(ffile=$basename($input)$lowercase($suffix($input)))
    set(ppfile=$if($PREPROCONLY,$if($KEEPPREPRO,$if($equal($ffile,$input),$error(Output would overwrite file $ffile),-o $ffile),-pp)))
    set(thisoutfile=$if($and($or($COMPILEONLY,$ASMONLY),$OUTFILE),$OUTFILE))
    tempfile($dirname($ilmfile)/$basename($ilmfile).dbg)
    arguments($input 
        $foreach(d,$STDDEF,-def $d )
        $foreach(d,$LOCALDEFS,-def $d )
        $foreach(i,$SITEINC,-I $i )
        $foreach(i,$USRINC,-I $i )
        $foreach(i,$USRSTDINC,-J $i )
        $foreach(i,$replace($USER_INCLUDE_PATH,",", ),-idir $i )
        $foreach(d,$SITEDEF,-def $d )
        $foreach(f,$cudadef,-def $f )
        $if($ACCFEFLAGS, -fopenacc)
        $USRDEFDEF
        $if($currentsuffix(F,F90,CUF),-preprocess)
        $ifn($EXPLICITFORM,$if($currentsuffix(f90,F90,cuf,CUF),-Mfree,-Mfixed))
        $FARGS $FLANG1ARGS
        $if($PGLLVMTARGET,-stbfile $stbfile)
        -intrinsic-module-directory $FLANGMODULEDIR
        -builtin-include-dirs $FLANGINCLUDEDIR
        -gbl $llfile_global
        -gpugbl $gpufile_global
        $if($PREPROCONLY,-es $ppfile,$if($FIRONLY,-o $firfile,-o $ilmfile)))
    execute(
        condition($equal($PREPROCONLY$ILMONLY$FIRONLY,))
        input($ilmfile)
        command(f902ext)
    );

command f902ext is
    help(Fortran Extractor)
    tool(f90_ex)
    arguments($input -fn $file $COMMONARGS $DEFF902ARGS $EXTRAF902ARGS
        $COMMONCGARGS
        $if($STDINC,-stdinc $replace($STDINC,,$INCSEP),-nostdinc)
        $foreach(d,$STDDEF,-def $d )
        $foreach(d,$LOCALDEFS,-def $d )
        $foreach(i,$SITEINC,-idir $i )
        $foreach(i,$USRINC,-idir $i )
        $foreach(i,$USRSTDINC,-idir $i )
        $foreach(i,$replace($USER_INCLUDE_PATH,",", ),-idir $i )
        $foreach(d,$SITEDEF,-def $d )
        $USRDEFDEF
        $ENABLECUDA
        -exlib $EXTRACTLIB
        $if($USEINLONLYFILE,-inlonly $inlineonlyfile)
	$if($USEFLANG1,-x 54 0x400)
        $FCGARGS $CGARGS $CEXTARGS);

command f90x is
    suffix($F90SUFFIX)
    error(Fortran files must be compiled with $(PFX)fortran: $input);

command cufx is
    suffix($CUFSUFFIX)
    error($if($notequal($SYSACCELS,),CUDA Fortran files must be compiled with $(PFX)fortran: $input))
    error($if($equal($SYSACCELS,),CUDA Fortran is no longer supported for $PGSYS-$PGLEN systems));

switch -Mminus0 is
    helpgroup(opt)
    helpname(-M[no]minus0)
    help(Use Fortran 95 SIGN semantics)
    append(CGARGS=-x 73 1);

switch -Mnominus0 is hide
    helpgroup(opt)
    help(Use Fortran 90 SIGN semantics)
    append(CGARGS=-x 73 2);

switch -Mnomod is
    hide
    help(Do not append module information to object files)
    helpgroup(language)
    set(APPENDMOD=);

variable OLDBINDCMANGLING is
    hide
    help(Revert to previous behavior of including module name in link name of bind(C) routine)
    default(-x 58 0x200000);

variable FNEEDCUDA is default($ANYCUF);
variable FBLANKCUDALIB is default($and($equal($CUDALIBDIR,),$FNEEDCUDA));
variable FBADCUDALIB is default($if($notequal($CUDALIBDIR,),$if($not($isdir($CUDALIBDIR)),$FNEEDCUDA)));
error($if($and($FBLANKCUDALIB,$notequal($REQCUDAVERSION,)),CUDA version $CUDAXDY is not available in this installation.));
error($if($and($FBADCUDALIB,$notequal($REQCUDAVERSION,)),CUDA version $CUDAXDY is not available in this installation.));

variable ACCEXTRACTLIB is # set by -Mextract=lib:
    default();
variable ACCEXTRACTLIBSW is default();
variable ACCEXTRACTLIBSET is default();
variable ACCEXTRACTTOC is
    default($if($ACCEXTRACTLIBSET,$mkfile($ACCEXTRACTLIB/TOC)));

error($if($and($suffixused(cuf,CUF),$foreach(a,$ACCELS,$ifn($index($a,tesla,host,multicore),1))),CUDA Fortran may only be used with tesla target accelerators:$foreach(a,$ACCELS,$ifn($index($a,tesla,host,multicore),"" $a))));
error($if($and($KNL,$ANYCUF),CUDA Fortran is not supported on Knights Landing host systems));

switch -x is
  help(Specify the language for any following input files, instead of letting the compiler choose based on suffix. Turn off with -x none)
  helpgroup(overall)
  keyword(
    c( set(OVERRIDESUFFIX=c) )
    f( set(OVERRIDESUFFIX=f) )
    f77=f
    F( set(OVERRIDESUFFIX=F) )
    "f77-cpp-input"=F
    f90( set(OVERRIDESUFFIX=f90) )
    f95=f90
    F90( set(OVERRIDESUFFIX=F90) )
    "f95-cpp-input"=F90
    asm( set(OVERRIDESUFFIX=asm) )
    assembler=asm
    ASM( set(OVERRIDESUFFIX=ASM) )
    "assembler-with-cpp"=ASM
    none( set(OVERRIDESUFFIX=) )
  )
  onekeyword;

switch -Msyntax-only is
        help(Perform only syntax checking, semantic checking, and Fortran module (.mod) file generation.)
        helpgroup(language)
        set(ILMONLY=YES)
        stopafter(Compile);

switch -Mm128 is hide
	help(C only, in Fortran for compatibility)
	helpgroup(language)
	helpname(-M[no]m128);

switch -Mnom128 is hide
	help(C only, in Fortran for compatibility)
	helpgroup(language);

switch -Mint128 is hide
	help(C/C++ only, in Fortran for compatibility)
	helpgroup(language)
	helpname(-M[no]int128);

switch -Mnoint128 is hide
	help(C/C++ only, in Fortran for compatibility)
	helpgroup(language);
