11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds%{
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sub-parser for macro invocation in the Aic7xxx SCSI
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Host adapter sequencer assembler.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2001 Adaptec Inc.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All rights reserved.
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Redistribution and use in source and binary forms, with or without
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modification, are permitted provided that the following conditions
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are met:
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. Redistributions of source code must retain the above copyright
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    notice, this list of conditions, and the following disclaimer,
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    without modification.
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. Redistributions in binary form must reproduce at minimum a disclaimer
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    substantially similar to the "NO WARRANTY" disclaimer below
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    ("Disclaimer") and any redistribution must be conditioned upon
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    including a substantially similar Disclaimer requirement for further
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    binary redistribution.
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. Neither the names of the above-listed copyright holders nor the names
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    of any contributors may be used to endorse or promote products derived
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    from this software without specific prior written permission.
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Alternatively, this software may be distributed under the terms of the
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License ("GPL") version 2 as published by the Free
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Software Foundation.
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NO WARRANTY
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * POSSIBILITY OF SUCH DAMAGES.
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * $FreeBSD$
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/types.h>
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <inttypes.h>
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <regex.h>
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdio.h>
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdlib.h>
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <string.h>
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sysexits.h>
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __linux__
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "../queue.h"
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/queue.h>
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "aicasm.h"
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "aicasm_symbol.h"
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "aicasm_insformat.h"
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic symbol_t *macro_symbol;
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void add_macro_arg(const char *argtext, int position);
68f45ffaec2e51071ea0067849cbb84df9e0531b35James Bottomleyvoid mmerror(const char *string);
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds%}
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds%union {
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int		value;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char		*str;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	symbol_t	*sym;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds%token <str> T_ARG
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds%token <sym> T_SYMBOL
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds%type <value> macro_arglist
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds%%
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmacrocall:
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	T_SYMBOL '('
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macro_symbol = $1;
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	macro_arglist ')'
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (macro_symbol->info.macroinfo->narg != $4) {
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printf("Narg == %d", macro_symbol->info.macroinfo->narg);
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			stop("Too few arguments for macro invocation",
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     EX_DATAERR);
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* NOTREACHED */
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		macro_symbol = NULL;
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		YYACCEPT;
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmacro_arglist:
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Macros can take 0 arguments */
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		$$ = 0;
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds|	T_ARG
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		$$ = 1;
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		add_macro_arg($1, 1);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds|	macro_arglist ',' T_ARG
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ($1 == 0) {
11825985edcedea6396277003854657b5f3cb31a628Lucas De Marchi			stop("Comma without preceding argument in arg list",
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     EX_DATAERR);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* NOTREACHED */
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		$$ = $1 + 1;
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		add_macro_arg($3, $$);
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds%%
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsadd_macro_arg(const char *argtext, int argnum)
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct macro_arg *marg;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (macro_symbol == NULL || macro_symbol->type != MACRO) {
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stop("Invalid current symbol for adding macro arg",
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     EX_SOFTWARE);
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* NOTREACHED */
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Macro Invocation.  Find the appropriate argument and fill
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * in the replace ment text for this call.
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i = 0;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		i++;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (i == argnum)
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (marg == NULL) {
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stop("Too many arguments for macro invocation", EX_DATAERR);
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* NOTREACHED */
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	marg->replacement_text = strdup(argtext);
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (marg->replacement_text == NULL) {
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		stop("Unable to replicate replacement text", EX_SOFTWARE);
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* NOTREACHED */
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmmerror(const char *string)
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	stop(string, EX_DATAERR);
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
166