brintos

brintos / linux-shallow public Read only

0
0
Text · 19.7 KiB · cd692a4 Raw
844 lines · c
1/*2 * Aic7xxx SCSI host adapter firmware assembler3 *4 * Copyright (c) 1997, 1998, 2000, 2001 Justin T. Gibbs.5 * Copyright (c) 2001, 2002 Adaptec Inc.6 * All rights reserved.7 *8 * Redistribution and use in source and binary forms, with or without9 * modification, are permitted provided that the following conditions10 * are met:11 * 1. Redistributions of source code must retain the above copyright12 *    notice, this list of conditions, and the following disclaimer,13 *    without modification.14 * 2. Redistributions in binary form must reproduce at minimum a disclaimer15 *    substantially similar to the "NO WARRANTY" disclaimer below16 *    ("Disclaimer") and any redistribution must be conditioned upon17 *    including a substantially similar Disclaimer requirement for further18 *    binary redistribution.19 * 3. Neither the names of the above-listed copyright holders nor the names20 *    of any contributors may be used to endorse or promote products derived21 *    from this software without specific prior written permission.22 *23 * Alternatively, this software may be distributed under the terms of the24 * GNU General Public License ("GPL") version 2 as published by the Free25 * Software Foundation.26 *27 * NO WARRANTY28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT32 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE38 * POSSIBILITY OF SUCH DAMAGES.39 *40 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm.c#23 $41 *42 * $FreeBSD$43 */44#include <sys/types.h>45#include <sys/mman.h>46 47#include <ctype.h>48#include <inttypes.h>49#include <regex.h>50#include <stdio.h>51#include <stdlib.h>52#include <string.h>53#include <sysexits.h>54#include <unistd.h>55 56#if linux57#include <endian.h>58#else59#include <machine/endian.h>60#endif61 62#include "aicasm.h"63#include "aicasm_symbol.h"64#include "aicasm_insformat.h"65 66typedef struct patch {67	STAILQ_ENTRY(patch) links;68	int		patch_func;69	u_int		begin;70	u_int		skip_instr;71	u_int		skip_patch;72} patch_t;73 74STAILQ_HEAD(patch_list, patch) patches;75 76static void usage(void);77static void back_patch(void);78static void output_code(void);79static void output_listing(char *ifilename);80static void dump_scope(scope_t *scope);81static void emit_patch(scope_t *scope, int patch);82static int check_patch(patch_t **start_patch, int start_instr,83		       int *skip_addr, int *func_vals);84 85struct path_list search_path;86int includes_search_curdir;87char *appname;88char *stock_include_file;89FILE *ofile;90char *ofilename;91char *regfilename;92FILE *regfile;93char *listfilename;94FILE *listfile;95char *regdiagfilename;96FILE *regdiagfile;97int   src_mode;98int   dst_mode;99 100static STAILQ_HEAD(,instruction) seq_program;101struct cs_tailq cs_tailq;102struct scope_list scope_stack;103symlist_t patch_functions;104 105#if DEBUG106extern int yy_flex_debug;107extern int mm_flex_debug;108extern int yydebug;109extern int mmdebug;110#endif111extern FILE *yyin;112extern int yyparse(void);113 114int main(int argc, char *argv[]);115 116int117main(int argc, char *argv[])118{119	extern char *optarg;120	extern int optind;121	int  ch;122	int  retval;123	char *inputfilename;124	scope_t *sentinal;125 126	STAILQ_INIT(&patches);127	SLIST_INIT(&search_path);128	STAILQ_INIT(&seq_program);129	TAILQ_INIT(&cs_tailq);130	SLIST_INIT(&scope_stack);131 132	/* Set Sentinal scope node */133	sentinal = scope_alloc();134	sentinal->type = SCOPE_ROOT;135	136	includes_search_curdir = 1;137	appname = *argv;138	regfile = NULL;139	listfile = NULL;140#if DEBUG141	yy_flex_debug = 0;142	mm_flex_debug = 0;143	yydebug = 0;144	mmdebug = 0;145#endif146	while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:")) != -1) {147		switch(ch) {148		case 'd':149#if DEBUG150			if (strcmp(optarg, "s") == 0) {151				yy_flex_debug = 1;152				mm_flex_debug = 1;153			} else if (strcmp(optarg, "p") == 0) {154				yydebug = 1;155				mmdebug = 1;156			} else {157				fprintf(stderr, "%s: -d Requires either an "158					"'s' or 'p' argument\n", appname);159				usage();160			}161#else162			stop("-d: Assembler not built with debugging "163			     "information", EX_SOFTWARE);164#endif165			break;166		case 'i':167			stock_include_file = optarg;168			break;169		case 'l':170			/* Create a program listing */171			if ((listfile = fopen(optarg, "w")) == NULL) {172				perror(optarg);173				stop(NULL, EX_CANTCREAT);174			}175			listfilename = optarg;176			break;177		case 'n':178			/* Don't complain about the -nostdinc directrive */179			if (strcmp(optarg, "ostdinc")) {180				fprintf(stderr, "%s: Unknown option -%c%s\n",181					appname, ch, optarg);182				usage();183				/* NOTREACHED */184			}185			break;186		case 'o':187			if ((ofile = fopen(optarg, "w")) == NULL) {188				perror(optarg);189				stop(NULL, EX_CANTCREAT);190			}191			ofilename = optarg;192			break;193		case 'p':194			/* Create Register Diagnostic "printing" Functions */195			if ((regdiagfile = fopen(optarg, "w")) == NULL) {196				perror(optarg);197				stop(NULL, EX_CANTCREAT);198			}199			regdiagfilename = optarg;200			break;201		case 'r':202			if ((regfile = fopen(optarg, "w")) == NULL) {203				perror(optarg);204				stop(NULL, EX_CANTCREAT);205			}206			regfilename = optarg;207			break;208		case 'I':209		{210			path_entry_t include_dir;211 212			if (strcmp(optarg, "-") == 0) {213				if (includes_search_curdir == 0) {214					fprintf(stderr, "%s: Warning - '-I-' "215							"specified multiple "216							"times\n", appname);217				}218				includes_search_curdir = 0;219				for (include_dir = SLIST_FIRST(&search_path);220				     include_dir != NULL;221				     include_dir = SLIST_NEXT(include_dir,222							      links))223					/*224					 * All entries before a '-I-' only225					 * apply to includes specified with226					 * quotes instead of "<>".227					 */228					include_dir->quoted_includes_only = 1;229			} else {230				include_dir =231				    (path_entry_t)malloc(sizeof(*include_dir));232				if (include_dir == NULL) {233					perror(optarg);234					stop(NULL, EX_OSERR);235				}236				include_dir->directory = strdup(optarg);237				if (include_dir->directory == NULL) {238					perror(optarg);239					stop(NULL, EX_OSERR);240				}241				include_dir->quoted_includes_only = 0;242				SLIST_INSERT_HEAD(&search_path, include_dir,243						  links);244			}245			break;246		}247		case '?':248		default:249			usage();250			/* NOTREACHED */251		}252	}253	argc -= optind;254	argv += optind;255 256	if (argc != 1) {257		fprintf(stderr, "%s: No input file specified\n", appname);258		usage();259		/* NOTREACHED */260	}261 262	if (regdiagfile != NULL263	 && (regfile == NULL || stock_include_file == NULL)) {264		fprintf(stderr,265			"%s: The -p option requires the -r and -i options.\n",266			appname);267		usage();268		/* NOTREACHED */269	}270	symtable_open();271	inputfilename = *argv;272	include_file(*argv, SOURCE_FILE);273	retval = yyparse();274	if (retval == 0) {275		if (SLIST_FIRST(&scope_stack) == NULL276		 || SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) {277			stop("Unterminated conditional expression", EX_DATAERR);278			/* NOTREACHED */279		}280 281		/* Process outmost scope */282		process_scope(SLIST_FIRST(&scope_stack));283		/*284		 * Decend the tree of scopes and insert/emit285		 * patches as appropriate.  We perform a depth first286		 * traversal, recursively handling each scope.287		 */288		/* start at the root scope */289		dump_scope(SLIST_FIRST(&scope_stack));290 291		/* Patch up forward jump addresses */292		back_patch();293 294		if (ofile != NULL)295			output_code();296		if (regfile != NULL)297			symtable_dump(regfile, regdiagfile);298		if (listfile != NULL)299			output_listing(inputfilename);300	}301 302	stop(NULL, 0);303	/* NOTREACHED */304	return (0);305}306 307static void308usage()309{310 311	(void)fprintf(stderr,312"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]\n"313"	[-r register_output_file [-p register_diag_file -i includefile]]\n"314"	[-l program_list_file]\n"315"	input_file\n", appname);316	exit(EX_USAGE);317}318 319static void320back_patch()321{322	struct instruction *cur_instr;323 324	for (cur_instr = STAILQ_FIRST(&seq_program);325	     cur_instr != NULL;326	     cur_instr = STAILQ_NEXT(cur_instr, links)) {327		if (cur_instr->patch_label != NULL) {328			struct ins_format3 *f3_instr;329			u_int address;330 331			if (cur_instr->patch_label->type != LABEL) {332				char buf[255];333 334				snprintf(buf, sizeof(buf),335					 "Undefined label %s",336					 cur_instr->patch_label->name);337				stop(buf, EX_DATAERR);338				/* NOTREACHED */339			}340			f3_instr = &cur_instr->format.format3;341			address = f3_instr->address;342			address += cur_instr->patch_label->info.linfo->address;343			f3_instr->address = address;344		}345	}346}347 348static void349output_code()350{351	struct instruction *cur_instr;352	patch_t *cur_patch;353	critical_section_t *cs;354	symbol_node_t *cur_node;355	int instrcount;356 357	instrcount = 0;358	fprintf(ofile,359"/*\n"360" * DO NOT EDIT - This file is automatically generated\n"361" *		 from the following source files:\n"362" *\n"363"%s */\n", versions);364 365	fprintf(ofile, "static const uint8_t seqprog[] = {\n");366	for (cur_instr = STAILQ_FIRST(&seq_program);367	     cur_instr != NULL;368	     cur_instr = STAILQ_NEXT(cur_instr, links)) {369 370		fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",371			cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n",372#ifdef __LITTLE_ENDIAN373			cur_instr->format.bytes[0],374			cur_instr->format.bytes[1],375			cur_instr->format.bytes[2],376			cur_instr->format.bytes[3]);377#else378			cur_instr->format.bytes[3],379			cur_instr->format.bytes[2],380			cur_instr->format.bytes[1],381			cur_instr->format.bytes[0]);382#endif383		instrcount++;384	}385	fprintf(ofile, "\n};\n\n");386 387	if (patch_arg_list == NULL)388		stop("Patch argument list not defined",389		     EX_DATAERR);390 391	/*392	 *  Output patch information.  Patch functions first.393	 */394	fprintf(ofile,395"typedef int %spatch_func_t (%s);\n", prefix, patch_arg_list);396 397	for (cur_node = SLIST_FIRST(&patch_functions);398	     cur_node != NULL;399	     cur_node = SLIST_NEXT(cur_node,links)) {400		fprintf(ofile,401"static %spatch_func_t %spatch%d_func;\n"402"\n"403"static int\n"404"%spatch%d_func(%s)\n"405"{\n"406"	return (%s);\n"407"}\n\n",408			prefix,409			prefix,410			cur_node->symbol->info.condinfo->func_num,411			prefix,412			cur_node->symbol->info.condinfo->func_num,413			patch_arg_list,414			cur_node->symbol->name);415	}416 417	fprintf(ofile,418"static const struct patch {\n"419"	%spatch_func_t		*patch_func;\n"420"	uint32_t		 begin		:10,\n"421"				 skip_instr	:10,\n"422"				 skip_patch	:12;\n"423"} patches[] = {\n", prefix);424 425	for (cur_patch = STAILQ_FIRST(&patches);426	     cur_patch != NULL;427	     cur_patch = STAILQ_NEXT(cur_patch,links)) {428		fprintf(ofile, "%s\t{ %spatch%d_func, %d, %d, %d }",429			cur_patch == STAILQ_FIRST(&patches) ? "" : ",\n",430			prefix,431			cur_patch->patch_func, cur_patch->begin,432			cur_patch->skip_instr, cur_patch->skip_patch);433	}434 435	fprintf(ofile, "\n};\n\n");436 437	fprintf(ofile,438"static const struct cs {\n"439"	uint16_t	begin;\n"440"	uint16_t	end;\n"441"} critical_sections[] = {\n");442 443	for (cs = TAILQ_FIRST(&cs_tailq);444	     cs != NULL;445	     cs = TAILQ_NEXT(cs, links)) {446		fprintf(ofile, "%s\t{ %d, %d }",447			cs == TAILQ_FIRST(&cs_tailq) ? "" : ",\n",448			cs->begin_addr, cs->end_addr);449	}450 451	fprintf(ofile, "\n};\n\n");452 453	fprintf(ofile,454	"#define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections)\n");455 456	fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);457}458 459static void460dump_scope(scope_t *scope)461{462	scope_t *cur_scope;463 464	/*465	 * Emit the first patch for this scope466	 */467	emit_patch(scope, 0);468 469	/*470	 * Dump each scope within this one.471	 */472	cur_scope = TAILQ_FIRST(&scope->inner_scope);473 474	while (cur_scope != NULL) {475 476		dump_scope(cur_scope);477 478		cur_scope = TAILQ_NEXT(cur_scope, scope_links);479	}480 481	/*482	 * Emit the second, closing, patch for this scope483	 */484	emit_patch(scope, 1);485}486 487void488emit_patch(scope_t *scope, int patch)489{490	patch_info_t *pinfo;491	patch_t *new_patch;492 493	pinfo = &scope->patches[patch];494 495	if (pinfo->skip_instr == 0)496		/* No-Op patch */497		return;498 499	new_patch = (patch_t *)malloc(sizeof(*new_patch));500 501	if (new_patch == NULL)502		stop("Could not malloc patch structure", EX_OSERR);503 504	memset(new_patch, 0, sizeof(*new_patch));505 506	if (patch == 0) {507		new_patch->patch_func = scope->func_num;508		new_patch->begin = scope->begin_addr;509	} else {510		new_patch->patch_func = 0;511		new_patch->begin = scope->end_addr;512	}513	new_patch->skip_instr = pinfo->skip_instr;514	new_patch->skip_patch = pinfo->skip_patch;515	STAILQ_INSERT_TAIL(&patches, new_patch, links);516}517 518void519output_listing(char *ifilename)520{521	char buf[1024];522	FILE *ifile;523	struct instruction *cur_instr;524	patch_t *cur_patch;525	symbol_node_t *cur_func;526	int *func_values;527	int instrcount;528	int instrptr;529	int line;530	int func_count;531	int skip_addr;532 533	instrcount = 0;534	instrptr = 0;535	line = 1;536	skip_addr = 0;537	if ((ifile = fopen(ifilename, "r")) == NULL) {538		perror(ifilename);539		stop(NULL, EX_DATAERR);540	}541 542	/*543	 * Determine which options to apply to this listing.544	 */545	for (func_count = 0, cur_func = SLIST_FIRST(&patch_functions);546	    cur_func != NULL;547	    cur_func = SLIST_NEXT(cur_func, links))548		func_count++;549 550	func_values = NULL;551	if (func_count != 0) {552		func_values = (int *)malloc(func_count * sizeof(int));553 554		if (func_values == NULL)555			stop("Could not malloc", EX_OSERR);556		557		func_values[0] = 0; /* FALSE func */558		func_count--;559 560		/*561		 * Ask the user to fill in the return values for562		 * the rest of the functions.563		 */564		565		566		for (cur_func = SLIST_FIRST(&patch_functions);567		     cur_func != NULL && SLIST_NEXT(cur_func, links) != NULL;568		     cur_func = SLIST_NEXT(cur_func, links), func_count--) {569			int input;570			571			fprintf(stdout, "\n(%s)\n", cur_func->symbol->name);572			fprintf(stdout,573				"Enter the return value for "574				"this expression[T/F]:");575 576			while (1) {577 578				input = getchar();579				input = toupper(input);580 581				if (input == 'T') {582					func_values[func_count] = 1;583					break;584				} else if (input == 'F') {585					func_values[func_count] = 0;586					break;587				}588			}589			if (isatty(fileno(stdin)) == 0)590				putchar(input);591		}592		fprintf(stdout, "\nThanks!\n");593	}594 595	/* Now output the listing */596	cur_patch = STAILQ_FIRST(&patches);597	for (cur_instr = STAILQ_FIRST(&seq_program);598	     cur_instr != NULL;599	     cur_instr = STAILQ_NEXT(cur_instr, links), instrcount++) {600 601		if (check_patch(&cur_patch, instrcount,602				&skip_addr, func_values) == 0) {603			/* Don't count this instruction as it is in a patch604			 * that was removed.605			 */606                        continue;607		}608 609		while (line < cur_instr->srcline) {610			fgets(buf, sizeof(buf), ifile);611				fprintf(listfile, "             \t%s", buf);612				line++;613		}614		fprintf(listfile, "%04x %02x%02x%02x%02x", instrptr,615#ifdef __LITTLE_ENDIAN616			cur_instr->format.bytes[0],617			cur_instr->format.bytes[1],618			cur_instr->format.bytes[2],619			cur_instr->format.bytes[3]);620#else621			cur_instr->format.bytes[3],622			cur_instr->format.bytes[2],623			cur_instr->format.bytes[1],624			cur_instr->format.bytes[0]);625#endif626		/*627		 * Macro expansions can cause several instructions628		 * to be output for a single source line.  Only629		 * advance the line once in these cases.630		 */631		if (line == cur_instr->srcline) {632			fgets(buf, sizeof(buf), ifile);633			fprintf(listfile, "\t%s", buf);634			line++;635		} else {636			fprintf(listfile, "\n");637		}638		instrptr++;639	}640	/* Dump the remainder of the file */641	while(fgets(buf, sizeof(buf), ifile) != NULL)642		fprintf(listfile, "             %s", buf);643 644	fclose(ifile);645}646 647static int648check_patch(patch_t **start_patch, int start_instr,649	    int *skip_addr, int *func_vals)650{651	patch_t *cur_patch;652 653	cur_patch = *start_patch;654 655	while (cur_patch != NULL && start_instr == cur_patch->begin) {656		if (func_vals[cur_patch->patch_func] == 0) {657			int skip;658 659			/* Start rejecting code */660			*skip_addr = start_instr + cur_patch->skip_instr;661			for (skip = cur_patch->skip_patch;662			     skip > 0 && cur_patch != NULL;663			     skip--)664				cur_patch = STAILQ_NEXT(cur_patch, links);665		} else {666			/* Accepted this patch.  Advance to the next667			 * one and wait for our intruction pointer to668			 * hit this point.669			 */670			cur_patch = STAILQ_NEXT(cur_patch, links);671		}672	}673 674	*start_patch = cur_patch;675	if (start_instr < *skip_addr)676		/* Still skipping */677		return (0);678 679	return (1);680}681 682/*683 * Print out error information if appropriate, and clean up before684 * terminating the program.685 */686void687stop(const char *string, int err_code)688{689	if (string != NULL) {690		fprintf(stderr, "%s: ", appname);691		if (yyfilename != NULL) {692			fprintf(stderr, "Stopped at file %s, line %d - ",693				yyfilename, yylineno);694		}695		fprintf(stderr, "%s\n", string);696	}697 698	if (ofile != NULL) {699		fclose(ofile);700		if (err_code != 0) {701			fprintf(stderr, "%s: Removing %s due to error\n",702				appname, ofilename);703			unlink(ofilename);704		}705	}706 707	if (regfile != NULL) {708		fclose(regfile);709		if (err_code != 0) {710			fprintf(stderr, "%s: Removing %s due to error\n",711				appname, regfilename);712			unlink(regfilename);713		}714	}715 716	if (listfile != NULL) {717		fclose(listfile);718		if (err_code != 0) {719			fprintf(stderr, "%s: Removing %s due to error\n",720				appname, listfilename);721			unlink(listfilename);722		}723	}724 725	symlist_free(&patch_functions);726	symtable_close();727 728	exit(err_code);729}730 731struct instruction *732seq_alloc()733{734	struct instruction *new_instr;735 736	new_instr = (struct instruction *)malloc(sizeof(struct instruction));737	if (new_instr == NULL)738		stop("Unable to malloc instruction object", EX_SOFTWARE);739	memset(new_instr, 0, sizeof(*new_instr));740	STAILQ_INSERT_TAIL(&seq_program, new_instr, links);741	new_instr->srcline = yylineno;742	return new_instr;743}744 745critical_section_t *746cs_alloc()747{748	critical_section_t *new_cs;749 750	new_cs= (critical_section_t *)malloc(sizeof(critical_section_t));751	if (new_cs == NULL)752		stop("Unable to malloc critical_section object", EX_SOFTWARE);753	memset(new_cs, 0, sizeof(*new_cs));754	755	TAILQ_INSERT_TAIL(&cs_tailq, new_cs, links);756	return new_cs;757}758 759scope_t *760scope_alloc()761{762	scope_t *new_scope;763 764	new_scope = (scope_t *)malloc(sizeof(scope_t));765	if (new_scope == NULL)766		stop("Unable to malloc scope object", EX_SOFTWARE);767	memset(new_scope, 0, sizeof(*new_scope));768	TAILQ_INIT(&new_scope->inner_scope);769	770	if (SLIST_FIRST(&scope_stack) != NULL) {771		TAILQ_INSERT_TAIL(&SLIST_FIRST(&scope_stack)->inner_scope,772				  new_scope, scope_links);773	}774	/* This patch is now the current scope */775	SLIST_INSERT_HEAD(&scope_stack, new_scope, scope_stack_links);776	return new_scope;777}778 779void780process_scope(scope_t *scope)781{782	/*783	 * We are "leaving" this scope.  We should now have784	 * enough information to process the lists of scopes785	 * we encapsulate.786	 */787	scope_t *cur_scope;788	u_int skip_patch_count;789	u_int skip_instr_count;790 791	cur_scope = TAILQ_LAST(&scope->inner_scope, scope_tailq);792	skip_patch_count = 0;793	skip_instr_count = 0;794	while (cur_scope != NULL) {795		u_int patch0_patch_skip;796 797		patch0_patch_skip = 0;798		switch (cur_scope->type) {799		case SCOPE_IF:800		case SCOPE_ELSE_IF:801			if (skip_instr_count != 0) {802				/* Create a tail patch */803				patch0_patch_skip++;804				cur_scope->patches[1].skip_patch =805				    skip_patch_count + 1;806				cur_scope->patches[1].skip_instr =807				    skip_instr_count;808			}809 810			/* Count Head patch */811			patch0_patch_skip++;812 813			/* Count any patches contained in our inner scope */814			patch0_patch_skip += cur_scope->inner_scope_patches;815 816			cur_scope->patches[0].skip_patch = patch0_patch_skip;817			cur_scope->patches[0].skip_instr =818			    cur_scope->end_addr - cur_scope->begin_addr;819 820			skip_instr_count += cur_scope->patches[0].skip_instr;821 822			skip_patch_count += patch0_patch_skip;823			if (cur_scope->type == SCOPE_IF) {824				scope->inner_scope_patches += skip_patch_count;825				skip_patch_count = 0;826			        skip_instr_count = 0;827			}828			break;829		case SCOPE_ELSE:830			/* Count any patches contained in our innter scope */831			skip_patch_count += cur_scope->inner_scope_patches;832 833			skip_instr_count += cur_scope->end_addr834					  - cur_scope->begin_addr;835			break;836		case SCOPE_ROOT:837			stop("Unexpected scope type encountered", EX_SOFTWARE);838			/* NOTREACHED */839		}840 841		cur_scope = TAILQ_PREV(cur_scope, scope_tailq, scope_links);842	}843}844