/* file "commands.def" */

/*  Copyright (c) 1994 Stanford University

    All rights reserved.

    This software is provided under the terms described in
    the "suif_copyright.h" include file. */

#include <suif_copyright.h>

/*  This file contains the descriptions of all of the compiler passes.
    The fields for each pass are extracted in various ways by redefining
    the PASS macro and then including this file.  The passes must be listed
    in ascending order of output suffix, with the exception of passes that
    produce an s_tmp suffix.  The s_tmp passes may appear anywhere except in
    between passes with the same output suffix.  The fields for each pass are:

	TAG  -- a unique name for the pass which must not conflict with
		any variables in the scc code, since it is used as a member
		of an enumeration.

        COUNTS -- whether this pass works on input files one at a time
		(ONE_IN_ONE_OUT), all at once to produce one output file
		(MANY_IN_ONE_OUT), or all at once to produce an output file
		for every input file (MANY_IN_MANY_OUT).

	SFX  -- output suffix (see comment above about pass ordering).

        OUTFORM -- the format of the output file or files of this
                pass, either OUTPUT_SUIF (meaning new SUIF only) or
                OUTPUT_NOT_SUIF.  Scc needs to know if the file is a
                SUIF file or not if it is to do checking on SUIF files
                (the ``-checkwarn'' or ``-checkfail'' options).

	DIR  -- directory containing the binary for the pass.  This field
		contains an expression that is evaluated after reading the
		command line flags.  If it is set to NULL, the default
		SUIF path will be used.

	NAME -- the name of the executable file

	FMT  -- the command format string.  This field describes the command-
		line arguments used to execute command.  There are four types
		of fields within this format string:
		    %i: input file(s)
		    %o: output file (optional)
		    %a: alternate input and output files (as opposed
			to %i %o, which would give first all the input
			then all the output files)
		    %p: pass options (specified on the scc command line)
		    %f: flag (up to MAX_FLAGS of these are allowed)
		If the output file field is not present, it is assumed that
		the output file name is the same as the input file with the
		suffix set to the output suffix for the pass.

	EXEC -- execution predicate.  This field is a boolean expression
		that is evaluated after reading the command line flags.
		The pass will be executed if it evaluates to TRUE.

	FLAGS-- code to set the pass flags.  Each entry in the pass table
		contains an array (flags) of MAX_FLAGS pointers to String
		objects.  The Nth array element replaces the Nth %f field
		in the command format string.  Initially, all of the flags
		are set to NULL, but the code in this field can be used to
		set them to arbitrary Strings.  The pass table entry can
		be accessed through the "p" variable; thus, flag 0 can be
		set with "p->flags[0] = new String".  The code is put into
		a function that is evaluated after reading the command
		line options.
*/

PASS(	SF2C,
        ONE_IN_ONE_OUT,
	s_c,
	OUTPUT_NOT_SUIF,
	NULL,
	"sf2c", "%f -g -w -quiet -lab %p %i -o %o",
	TRUE,
	p->flags[0] = new String("");
	if (automatic_flag)
	    *p->flags[0] += "-a";
	; )

PASS(	CPP,
        ONE_IN_ONE_OUT,
	s_i,
	OUTPUT_NOT_SUIF,
	NULL,
	"cpp", "%f %p %f %i %o",
	TRUE,
	p->flags[0] = new String("-D__SCC__");
	if (pp_deps)
	    *p->flags[0] += " -M";
	String predefined_path(suif_top);
	predefined_path += '/';
	predefined_path += target_machine;
	predefined_path += "/predefined.txt";
	*p->flags[0] += " ";
	string_from_file(predefined_path.string(), p->flags[0]);
	if (strcmp(target_machine, "sparc-sun-sunos4") == 0) {
	    *p->flags[0] += " -D__BUILTIN_VA_ARG_INCR";
	}
	p->flags[1] = new String(" -I");
	*p->flags[1] += suif_include;
	if (strstr(target_machine, "linux") == 0) {
	    *p->flags[1] += " -nostdinc -I/usr/include";
	} else {
	    *p->flags[1] += " -undef -U__GNUC__ -U__GNUC_MINOR__";
        } )

PASS(	SNOOT,
        ONE_IN_ONE_OUT,
	s_snt,
	OUTPUT_NOT_SUIF,
	NULL,
	"snoot", "%f %p %i %o",
	TRUE,
	p->flags[0] = new String("");
        /* If the machine needs built-in identifiers, the target name
         * must be passed explicitly to snoot, but it cannot be passed
         * explicitly in general, since in general snoot will not
         * recognize the target name.  So here we hard-code the
         * targets for which snoot has hard-coded (in config.h) lists
         * of built-in identifiers. */
	if ((strcmp(target_machine, scc_machine) != 0) ||
	    (strcmp(target_machine, "mips-sgi-irix5") == 0) ||
	    (strcmp(target_machine, "mips-sgi-irix5.3") == 0) ||
 	    (strcmp(target_machine, "mips-sgi-irix6.2") == 0) ||
 	    (strcmp(target_machine, "mips-sgi-irix6.4") == 0) ||
	    (strcmp(target_machine, "sparc-sun-sunos4") == 0) ||
	    (strcmp(target_machine, "sparc-sun-solaris2.3") == 0) ||
	    (strcmp(target_machine, "i386-sun-solaris2.4") == 0) ||
	    (strcmp(target_machine, "alpha-dec-osf") == 0) ||
	    (strcmp(target_machine, "alpha-dec-osf3.2") == 0) ||
 	    (strcmp(target_machine, "mips-dec-ultrix") == 0) ||
	    (strcmp(target_machine, "i386-unknown-bsdos") == 0)) {
	    *p->flags[0] += "-T";
	    *p->flags[0] += target_machine;
	}
	if (no_warn_flag) *p->flags[0] += " -w"; )

PASS(	FIXFORTRAN,
        ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_NOT_SUIF,
	NULL,
	"fixfortran", "%p %i %o",
	sf2c_flag,
	; )

PASS(	ENTRY_TYPES,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_NOT_SUIF,
	NULL,
	"entry_types", "%p %i %o",
	sf2c_flag,
	; )

PASS(	PORKY_PRE_DEFAULTS,
        ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_NOT_SUIF,
	NULL,
	"porky", "-defaults %p %i %o",
	TRUE,
	; )

PASS(	PORKY_DEFAULTS,
        ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-defaults %p %i %o",
	TRUE,
	; )

PASS(	PORKY_LINE_FIX,
        ONE_IN_ONE_OUT,
	s_spd,
	OUTPUT_SUIF,
	NULL,
	"porky", "-kill-redundant-line-marks %p %i %o",
	TRUE,
	; )

PASS(	LINKSUIF,
	MANY_IN_MANY_OUT,
	s_sln,
	OUTPUT_SUIF,
	NULL,
	"linksuif", "%p %f %a",
	option_linksuif,
	; )

PASS(	PORKY_UCF_OPT,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-ucf-opt %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_DEAD_CODE1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-dead-code %p %i %o",
	opt_level >= 1,
	; )

PASS(	STRUCTURE,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"structure", "%p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_FOLD1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-fold %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_FIND_FORS,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-find-fors %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_CONST_PROP,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-const-prop %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_FOLD2,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-fold %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_COPY_PROP,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-copy-prop %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_DEAD_CODE2,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-dead-code %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_UNUSED1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-unused-syms -unused-types %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_EMPTY_TABLE1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-no-empty-table %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_EMPTY_FOR1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-no-empty-fors %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_CONTROL_SIMP1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-control-simp %p %i %o",
	opt_level >= 1,
	; )

PASS(	PORKY_FORWARD_PROP1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-forward-prop %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_FOLD3,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-fold %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_DEAD_CODE3,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-dead-code %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_LOOP_COND,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-loop-cond %p %i %o",
	opt_level >= 3,
	; )

PASS(	PORKY_FORWARD_PROP2,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-forward-prop %p %i %o",
	opt_level >= 3,
	; )

PASS(	PORKY_FOLD4,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-fold %p %i %o",
	opt_level >= 3,
	; )

PASS(	PORKY_DEAD_CODE4,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-dead-code %p %i %o",
	opt_level >= 3,
	; )

PASS(	PORKY_UNUSED2,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-unused-syms -unused-types %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_EMPTY_TABLE2,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-no-empty-table %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_EMPTY_FOR2,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-no-empty-fors %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_CONTROL_SIMP2,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-control-simp %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_LOOP_INVARIANTS1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-loop-invariants %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_FORWARD_PROP3,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-forward-prop %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_CSE1,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-cse %p %i %o",
	opt_level >= 2,
	; )

PASS(	PORKY_UNUSED,
	ONE_IN_ONE_OUT,
	s_tmp,
	OUTPUT_SUIF,
	NULL,
	"porky", "-unused-syms -unused-types %f %p %i %o",
	TRUE,
	; )

PASS(	S2C,
	ONE_IN_ONE_OUT,
	s_out_c,
	OUTPUT_NOT_SUIF,
	NULL,
	"s2c", "-annotes-named history %f %p %i %o",
	TRUE,
	; )

PASS(	BACKEND_CC,
	ONE_IN_ONE_OUT,
	s_o,
	OUTPUT_NOT_SUIF,
	alternate_cc ? NULL : ASLD_DIR,
	"cc", "-c %f %p %i -o %o",
	TRUE,
	p->flags[0] = new String("");
	if (g_flag)
	    *p->flags[0] += "-g";
	if (no_warn_flag)
	    *p->flags[0] += " -w";
	if (opt_level > 0) {
	    *p->flags[0] += " -O";
	    *p->flags[0] += opt_level + '0';
	} )

PASS(	LD,
        MANY_IN_ONE_OUT,
	s_out,
	OUTPUT_NOT_SUIF,
	alternate_cc ? NULL : ASLD_DIR,
	"ld", "-o %o %f %f %i %p %f -lc %f",
	TRUE,
	if (Gnum >= 0) {
	    char buf[20];
	    sprintf(buf, "-G %ld", Gnum);
	    p->flags[0] = new String(buf);
	}

	p->flags[2] = new String("");
	if (sf2c_flag) {
	    *p->flags[2] += "-L";
	    *p->flags[2] += suif_lib;

	    *p->flags[2] += " -lF77 -lI77 -lfortrun";
	    *p->flags[2] += " -lm";
        }

	if (strcmp(target_machine, "mips-sgi-irix5") == 0) {
	    p->flags[3] = new String("/usr/lib/crtn.o");
	}
)
