/* $Id$ */

#include <common.h>

#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)

#include <linux/ctype.h>
#include <bedbug/bedbug.h>
#include <bedbug/ppc.h>
#include <bedbug/regs.h>
#include <bedbug/tables.h>

#define Elf32_Word	unsigned long

/* USE_SOURCE_CODE enables some symbolic debugging functions of this
   code.  This is only useful if the program will have access to the
   source code for the binary being examined.
*/

/* #define USE_SOURCE_CODE 1 */

#ifdef USE_SOURCE_CODE
extern int line_info_from_addr __P ((Elf32_Word, char *, char *, int *));
extern struct symreflist *symByAddr;
extern char *symbol_name_from_addr __P ((Elf32_Word, int, int *));
#endif /* USE_SOURCE_CODE */

int print_operands __P ((struct ppc_ctx *));
int get_operand_value __P ((struct opcode *, unsigned long,
				enum OP_FIELD, unsigned long *));
struct opcode *find_opcode __P ((unsigned long));
struct opcode *find_opcode_by_name __P ((char *));
char *spr_name __P ((int));
int spr_value __P ((char *));
char *tbr_name __P ((int));
int tbr_value __P ((char *));
int parse_operand __P ((unsigned long, struct opcode *,
			struct operand *, char *, int *));
int get_word __P ((char **, char *));
long read_number __P ((char *));
int downstring __P ((char *));


/*======================================================================
 * Entry point for the PPC disassembler.
 *
 * Arguments:
 *	memaddr		The address to start disassembling from.
 *
 *	virtual		If this value is non-zero, then this will be
 *			used as the base address for the output and
 *			symbol lookups.  If this value is zero then
 *			memaddr is used as the absolute address.
 *
 *	num_instr	The number of instructions to disassemble.  Since
 *			each instruction is 32 bits long, this can be
 *			computed if you know the total size of the region.
 *
 *	pfunc		The address of a function that is called to print
 *			each line of output.  The function should take a
 *			single character pointer as its parameters a la puts.
 *
 *	flags		Sets options for the output.  This is a
 *			bitwise-inclusive-OR of the following
 *			values.  Note that only one of the radix
 *			options may be set.
 *
 *			F_RADOCTAL	- output radix is unsigned base 8.
 *			F_RADUDECIMAL	- output radix is unsigned base 10.
 *			F_RADSDECIMAL	- output radix is signed base 10.
 *			F_RADHEX	- output radix is unsigned base 16.
 *			F_SIMPLE	- use simplified mnemonics.
 *			F_SYMBOL	- lookup symbols for addresses.
 *			F_INSTR		- output raw instruction.
 *			F_LINENO	- show line # info if available.
 *
 * Returns TRUE if the area was successfully disassembled or FALSE if
 * a problem was encountered with accessing the memory.
 */

int disppc (unsigned char *memaddr, unsigned char *virtual, int num_instr,
			int (*pfunc) (const char *), unsigned long flags)
{
	int i;
	struct ppc_ctx ctx;

#ifdef USE_SOURCE_CODE
	int line_no = 0;
	int last_line_no = 0;
	char funcname[128] = { 0 };
	char filename[256] = { 0 };
	char last_funcname[128] = { 0 };
	int symoffset;
	char *symname;
	char *cursym = (char *) 0;
#endif /* USE_SOURCE_CODE */
  /*------------------------------------------------------------*/

	ctx.flags = flags;
	ctx.virtual = virtual;

	/* Figure out the output radix before we go any further */

	if (ctx.flags & F_RADOCTAL) {
		/* Unsigned octal output */
		strcpy (ctx.radix_fmt, "O%o");
	} else if (ctx.flags & F_RADUDECIMAL) {
		/* Unsigned decimal output */
		strcpy (ctx.radix_fmt, "%u");
	} else if (ctx.flags & F_RADSDECIMAL) {
		/* Signed decimal output */
		strcpy (ctx.radix_fmt, "%d");
	} else {
		/* Unsigned hex output */
		strcpy (ctx.radix_fmt, "0x%x");
	}

	if (ctx.virtual == 0) {
		ctx.virtual = memaddr;
	}
#ifdef USE_SOURCE_CODE
	if (ctx.flags & F_SYMBOL) {
		if (symByAddr == 0)		/* no symbols loaded */
			ctx.flags &= ~F_SYMBOL;
		else {
			cursym = (char *) 0;
			symoffset = 0;
		}
	}
#endif /* USE_SOURCE_CODE */

	/* format each line as "XXXXXXXX: <symbol> IIIIIIII  disassembly" where,
	   XXXXXXXX is the memory address in hex,
	   <symbol> is the symbolic location if F_SYMBOL is set.
	   IIIIIIII is the raw machine code in hex if F_INSTR is set,
	   and disassembly is the disassembled machine code with numbers
	   formatted according to the 'radix' parameter */

	for (i = 0; i < num_instr; ++i, memaddr += 4, ctx.virtual += 4) {
#ifdef USE_SOURCE_CODE
		if (ctx.flags & F_LINENO) {
			if ((line_info_from_addr ((Elf32_Word) ctx.virtual, filename,
									  funcname, &line_no) == TRUE) &&
				((line_no != last_line_no) ||
				 (strcmp (last_funcname, funcname) != 0))) {
				print_source_line (filename, funcname, line_no, pfunc);
			}
			last_line_no = line_no;
			strcpy (last_funcname, funcname);
		}
#endif /* USE_SOURCE_CODE */

		sprintf (ctx.data, "%08lx: ", (unsigned long) ctx.virtual);
		ctx.datalen = 10;

#ifdef USE_SOURCE_CODE
		if (ctx.flags & F_SYMBOL) {
			if ((symname =
				 symbol_name_from_addr ((Elf32_Word) ctx.virtual,
										TRUE, 0)) != 0) {
				cursym = symname;
				symoffset = 0;
			} else {
				if ((cursym == 0) &&
					((symname =
					  symbol_name_from_addr ((Elf32_Word) ctx.virtual,
											 FALSE, &symoffset)) != 0)) {
					cursym = symname;
				} else {
					symoffset += 4;
				}
			}

			if (cursym != 0) {
				sprintf (&ctx.data[ctx.datalen], "<%s+", cursym);
				ctx.datalen = strlen (ctx.data);
				sprintf (&ctx.data[ctx.datalen], ctx.radix_fmt, symoffset);
				strcat (ctx.data, ">");
				ctx.datalen = strlen (ctx.data);
			}
		}
#endif /* USE_SOURCE_CODE */

		ctx.instr = INSTRUCTION (memaddr);

		if (ctx.flags & F_INSTR) {
			/* Find the opcode structure for this opcode.  If one is not found
			   then it must be an illegal instruction */
			sprintf (&ctx.data[ctx.datalen],
					 "   %02lx %02lx %02lx %02lx    ",
					 ((ctx.instr >> 24) & 0xff),
					 ((ctx.instr >> 16) & 0xff), ((ctx.instr >> 8) & 0xff),
					 (ctx.instr & 0xff));
			ctx.datalen += 18;
		} else {
			strcat (ctx.data, "   ");
			ctx.datalen += 3;
		}

		if ((ctx.op = find_opcode (ctx.instr)) == 0) {
			/* Illegal Opcode */
			sprintf (&ctx.data[ctx.datalen], "        .long 0x%08lx",
					 ctx.instr);
			ctx.datalen += 24;
			(*pfunc) (ctx.data);
			continue;
		}

		if (((ctx.flags & F_SIMPLE) == 0) ||
			(ctx.op->hfunc == 0) || ((*ctx.op->hfunc) (&ctx) == FALSE)) {
			sprintf (&ctx.data[ctx.datalen], "%-7s ", ctx.op->name);
			ctx.datalen += 8;
			print_operands (&ctx);
		}

		(*pfunc) (ctx.data);
	}

	return TRUE;
}								/* disppc */



/*======================================================================
 * Called by the disassembler to print the operands for an instruction.
 *
 * Arguments:
 *	ctx		A pointer to the disassembler context record.
 *
 * always returns 0.
 */

int print_operands (struct ppc_ctx *ctx)
{
	int open_parens = 0;
	int field;
	unsigned long operand;
	struct operand *opr;

#ifdef USE_SOURCE_CODE
	char *symname;
	int offset;
#endif /* USE_SOURCE_CODE */
  /*------------------------------------------------------------*/

	/* Walk through the operands and list each in order */
	for (field = 0; ctx->op->fields[field] != 0; ++field) {
		if (ctx->op->fields[field] > n_operands) {
			continue;			/* bad operand ?! */
		}

		opr = &operands[ctx->op->fields[field] - 1];

		if (opr->hint & OH_SILENT) {
			continue;
		}

		if ((field > 0) && !open_parens) {
			strcat (ctx->data, ",");
			ctx->datalen++;
		}

		operand = (ctx->instr >> opr->shift) & ((1 << opr->bits) - 1);

		if (opr->hint & OH_ADDR) {
			if ((operand & (1 << (opr->bits - 1))) != 0) {
				operand = operand - (1 << opr->bits);
			}

			if (ctx->op->hint & H_RELATIVE)
				operand = (operand << 2) + (unsigned long) ctx->virtual;
			else
				operand = (operand << 2);


			sprintf (&ctx->data[ctx->datalen], "0x%lx", operand);
			ctx->datalen = strlen (ctx->data);

#ifdef USE_SOURCE_CODE
			if ((ctx->flags & F_SYMBOL) &&
				((symname =
				  symbol_name_from_addr (operand, 0, &offset)) != 0)) {
				sprintf (&ctx->data[ctx->datalen], " <%s", symname);
				if (offset != 0) {
					strcat (ctx->data, "+");
					ctx->datalen = strlen (ctx->data);
					sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
							 offset);
				}
				strcat (ctx->data, ">");
			}
#endif /* USE_SOURCE_CODE */
		}

		else if (opr->hint & OH_REG) {
			if ((operand == 0) &&
				(opr->field == O_rA) && (ctx->op->hint & H_RA0_IS_0)) {
				strcat (ctx->data, "0");
			} else {
				sprintf (&ctx->data[ctx->datalen], "r%d", (short) operand);
			}

			if (open_parens) {
				strcat (ctx->data, ")");
				open_parens--;
			}
		}

		else if (opr->hint & OH_SPR) {
			strcat (ctx->data, spr_name (operand));
		}

		else if (opr->hint & OH_TBR) {
			strcat (ctx->data, tbr_name (operand));
		}

		else if (opr->hint & OH_LITERAL) {
			switch (opr->field) {
			case O_cr2:
				strcat (ctx->data, "cr2");
				ctx->datalen += 3;
				break;

			default:
				break;
			}
		}

		else {
			sprintf (&ctx->data[ctx->datalen], ctx->radix_fmt,
					 (unsigned short) operand);

			if (open_parens) {
				strcat (ctx->data, ")");
				open_parens--;
			}

			else if (opr->hint & OH_OFFSET) {
				strcat (ctx->data, "(");
				open_parens++;
			}
		}

		ctx->datalen = strlen (ctx->data);
	}

	return 0;
}								/* print_operands */



/*======================================================================
 * Called to get the value of an arbitrary operand with in an instruction.
 *
 * Arguments:
 *	op		The pointer to the opcode structure to which
 *			the operands belong.
 *
 *	instr		The instruction (32 bits) containing the opcode
 *			and the operands to print.  By the time that
 *			this routine is called the operand has already
 *			been added to the output.
 *
 *	field		The field (operand) to get the value of.
 *
 *	value		The address of an unsigned long to be filled in
 *			with the value of the operand if it is found.  This
 *			will only be filled in if the function returns
 *			TRUE.  This may be passed as 0 if the value is
 *			not required.
 *
 * Returns TRUE if the operand was found or FALSE if it was not.
 */

int get_operand_value (struct opcode *op, unsigned long instr,
					   enum OP_FIELD field, unsigned long *value)
{
	int i;
	struct operand *opr;

  /*------------------------------------------------------------*/

	if (field > n_operands) {
		return FALSE;			/* bad operand ?! */
	}

	/* Walk through the operands and list each in order */
	for (i = 0; op->fields[i] != 0; ++i) {
		if (op->fields[i] != field) {
			continue;
		}

		opr = &operands[op->fields[i] - 1];

		if (value) {
			*value = (instr >> opr->shift) & ((1 << opr->bits) - 1);
		}
		return TRUE;
	}

	return FALSE;
}								/* operand_value */



/*======================================================================
 * Called by the disassembler to match an opcode value to an opcode structure.
 *
 * Arguments:
 *	instr		The instruction (32 bits) to match.  This value
 *			may contain operand values as well as the opcode
 *			since they will be masked out anyway for this
 *			search.
 *
 * Returns the address of an opcode struct (from the opcode table) if the
 * operand successfully matched an entry, or 0 if no match was found.
 */

struct opcode *find_opcode (unsigned long instr)
{
	struct opcode *ptr;
	int top = 0;
	int bottom = n_opcodes - 1;
	int idx;

  /*------------------------------------------------------------*/

	while (top <= bottom) {
		idx = (top + bottom) >> 1;
		ptr = &opcodes[idx];

		if ((instr & ptr->mask) < ptr->opcode) {
			bottom = idx - 1;
		} else if ((instr & ptr->mask) > ptr->opcode) {
			top = idx + 1;
		} else {
			return ptr;
		}
	}

	return (struct opcode *) 0;
}								/* find_opcode */



/*======================================================================
 * Called by the assembler to match an opcode name to an opcode structure.
 *
 * Arguments:
 *	name		The text name of the opcode, e.g. "b", "mtspr", etc.
 *
 * The opcodes are sorted numerically by their instruction binary code
 * so a search for the name cannot use the binary search used by the
 * other find routine.
 *
 * Returns the address of an opcode struct (from the opcode table) if the
 * name successfully matched an entry, or 0 if no match was found.
 */

struct opcode *find_opcode_by_name (char *name)
{
	int idx;

  /*------------------------------------------------------------*/

	downstring (name);

	for (idx = 0; idx < n_opcodes; ++idx) {
		if (!strcmp (name, opcodes[idx].name))
			return &opcodes[idx];
	}

	return (struct opcode *) 0;
}								/* find_opcode_by_name */



/*======================================================================
 * Convert the 'spr' operand from its numeric value to its symbolic name.
 *
 * Arguments:
 *	value		The value of the 'spr' operand.  This value should
 *			be unmodified from its encoding in the instruction.
 *			the split-field computations will be performed
 *			here before the switch.
 *
 * Returns the address of a character array containing the name of the
 * special purpose register defined by the 'value' parameter, or the
 * address of a character array containing "???" if no match was found.
 */

char *spr_name (int value)
{
	unsigned short spr;
	static char other[10];
	int i;

  /*------------------------------------------------------------*/

	/* spr is a 10 bit field whose interpretation has the high and low
	   five-bit fields reversed from their encoding in the operand */

	spr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);

	for (i = 0; i < n_sprs; ++i) {
		if (spr == spr_map[i].spr_val)
			return spr_map[i].spr_name;
	}

	sprintf (other, "%d", spr);
	return other;
}								/* spr_name */



/*======================================================================
 * Convert the 'spr' operand from its symbolic name to its numeric value
 *
 * Arguments:
 *	name		The symbolic name of the 'spr' operand.  The
 *			split-field encoding will be done by this routine.
 *			NOTE: name can be a number.
 *
 * Returns the numeric value for the spr appropriate for encoding a machine
 * instruction.  Returns 0 if unable to find the SPR.
 */

int spr_value (char *name)
{
	struct spr_info *sprp;
	int spr;
	int i;

  /*------------------------------------------------------------*/

	if (!name || !*name)
		return 0;

	if (isdigit ((int) name[0])) {
		i = htonl (read_number (name));
		spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);
		return spr;
	}

	downstring (name);

	for (i = 0; i < n_sprs; ++i) {
		sprp = &spr_map[i];

		if (strcmp (name, sprp->spr_name) == 0) {
			/* spr is a 10 bit field whose interpretation has the high and low
			   five-bit fields reversed from their encoding in the operand */
			i = htonl (sprp->spr_val);
			spr = ((i >> 5) & 0x1f) | ((i & 0x1f) << 5);

			return spr;
		}
	}

	return 0;
}								/* spr_value */



/*======================================================================
 * Convert the 'tbr' operand from its numeric value to its symbolic name.
 *
 * Arguments:
 *	value		The value of the 'tbr' operand.  This value should
 *			be unmodified from its encoding in the instruction.
 *			the split-field computations will be performed
 *			here before the switch.
 *
 * Returns the address of a character array containing the name of the
 * time base register defined by the 'value' parameter, or the address
 * of a character array containing "???" if no match was found.
 */

char *tbr_name (int value)
{
	unsigned short tbr;

  /*------------------------------------------------------------*/

	/* tbr is a 10 bit field whose interpretation has the high and low
	   five-bit fields reversed from their encoding in the operand */

	tbr = ((value >> 5) & 0x1f) | ((value & 0x1f) << 5);

	if (tbr == 268)
		return "TBL";

	else if (tbr == 269)
		return "TBU";


	return "???";
}								/* tbr_name */



/*======================================================================
 * Convert the 'tbr' operand from its symbolic name to its numeric value.
 *
 * Arguments:
 *	name		The symbolic name of the 'tbr' operand.  The
 *			split-field encoding will be done by this routine.
 *
 * Returns the numeric value for the spr appropriate for encoding a machine
 * instruction.  Returns 0 if unable to find the TBR.
 */

int tbr_value (char *name)
{
	int tbr;
	int val;

  /*------------------------------------------------------------*/

	if (!name || !*name)
		return 0;

	downstring (name);

	if (isdigit ((int) name[0])) {
		val = read_number (name);

		if (val != 268 && val != 269)
			return 0;
	} else if (strcmp (name, "tbl") == 0)
		val = 268;
	else if (strcmp (name, "tbu") == 0)
		val = 269;
	else
		return 0;

	/* tbr is a 10 bit field whose interpretation has the high and low
	   five-bit fields reversed from their encoding in the operand */

	val = htonl (val);
	tbr = ((val >> 5) & 0x1f) | ((val & 0x1f) << 5);
	return tbr;
}								/* tbr_name */



/*======================================================================
 * The next several functions (handle_xxx) are the routines that handle
 * disassembling the opcodes with simplified mnemonics.
 *
 * Arguments:
 *	ctx		A pointer to the disassembler context record.
 *
 * Returns TRUE if the simpler form was printed or FALSE if it was not.
 */

int handle_bc (struct ppc_ctx *ctx)
{
	unsigned long bo;
	unsigned long bi;
	static struct opcode blt = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
	0, "blt", H_RELATIVE
	};
	static struct opcode bne =
			{ B_OPCODE (16, 0, 0), B_MASK, {O_cr2, O_BD, 0},
	0, "bne", H_RELATIVE
	};
	static struct opcode bdnz = { B_OPCODE (16, 0, 0), B_MASK, {O_BD, 0},
	0, "bdnz", H_RELATIVE
	};

  /*------------------------------------------------------------*/

	if (get_operand_value (ctx->op, ctx->instr, O_BO, &bo) == FALSE)
		return FALSE;

	if (get_operand_value (ctx->op, ctx->instr, O_BI, &bi) == FALSE)
		return FALSE;

	if ((bo == 12) && (bi == 0)) {
		ctx->op = &blt;
		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
		ctx->datalen += 8;
		print_operands (ctx);
		return TRUE;
	} else if ((bo == 4) && (bi == 10)) {
		ctx->op = &bne;
		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
		ctx->datalen += 8;
		print_operands (ctx);
		return TRUE;
	} else if ((bo == 16) && (bi == 0)) {
		ctx->op = &bdnz;
		sprintf (&ctx->data[ctx->datalen], "%-7s ", ctx->op->name);
		ctx->datalen += 8;
		print_operands (ctx);
		return TRUE;
	}

	return FALSE;
}								/* handle_blt */



/*======================================================================
 * Outputs source line information for the disassembler.  This should
 * be modified in the future to lookup the actual line of source code
 * from the file, but for now this will do.
 *
 * Arguments:
 *	filename	The address of a character array containing the
 *			absolute path and file name of the source file.
 *
 *	funcname	The address of a character array containing the
 *			name of the function (not C++ demangled (yet))
 *			to which this code belongs.
 *
 *	line_no		An integer specifying the source line number that
 *			generated this code.
 *
 *	pfunc		The address of a function to call to print the output.
 *
 *
 * Returns TRUE if it was able to output the line info, or false if it was
 * not.
 */

int print_source_line (char *filename, char *funcname,
					   int line_no, int (*pfunc) (const char *))
{
	char out_buf[256];

  /*------------------------------------------------------------*/

	(*pfunc) ("");				/* output a newline */
	sprintf (out_buf, "%s %s(): line %d", filename, funcname, line_no);
	(*pfunc) (out_buf);

	return TRUE;
}								/* print_source_line */



/*======================================================================
 * Entry point for the PPC assembler.
 *
 * Arguments:
 *	asm_buf		An array of characters containing the assembly opcode
 *			and operands to convert to a POWERPC machine
 *			instruction.
 *
 * Returns the machine instruction or zero.
 */

unsigned long asmppc (unsigned long memaddr, char *asm_buf, int *err)
{
	struct opcode *opc;
	struct operand *oper[MAX_OPERANDS];
	unsigned long instr;
	unsigned long param;
	char *ptr = asm_buf;
	char scratch[20];
	int i;
	int w_operands = 0;			/* wanted # of operands */
	int n_operands = 0;			/* # of operands read */
	int asm_debug = 0;

  /*------------------------------------------------------------*/

	if (err)
		*err = 0;

	if (get_word (&ptr, scratch) == 0)
		return 0;

	/* Lookup the opcode structure based on the opcode name */
	if ((opc = find_opcode_by_name (scratch)) == (struct opcode *) 0) {
		if (err)
			*err = E_ASM_BAD_OPCODE;
		return 0;
	}

	if (asm_debug) {
		printf ("asmppc: Opcode = \"%s\"\n", opc->name);
	}

	for (i = 0; i < 8; ++i) {
		if (opc->fields[i] == 0)
			break;
		++w_operands;
	}

	if (asm_debug) {
		printf ("asmppc: Expecting %d operands\n", w_operands);
	}

	instr = opc->opcode;

	/* read each operand */
	while (n_operands < w_operands) {

		oper[n_operands] = &operands[opc->fields[n_operands] - 1];

		if (oper[n_operands]->hint & OH_SILENT) {
			/* Skip silent operands, they are covered in opc->opcode */

			if (asm_debug) {
				printf ("asmppc: Operand %d \"%s\" SILENT\n", n_operands,
						oper[n_operands]->name);
			}

			++n_operands;
			continue;
		}

		if (get_word (&ptr, scratch) == 0)
			break;

		if (asm_debug) {
			printf ("asmppc: Operand %d \"%s\" : \"%s\"\n", n_operands,
					oper[n_operands]->name, scratch);
		}

		if ((param = parse_operand (memaddr, opc, oper[n_operands],
									scratch, err)) == -1)
			return 0;

		instr |= param;
		++n_operands;
	}

	if (n_operands < w_operands) {
		if (err)
			*err = E_ASM_NUM_OPERANDS;
		return 0;
	}

	if (asm_debug) {
		printf ("asmppc: Instruction = 0x%08lx\n", instr);
	}

	return instr;
}								/* asmppc */



/*======================================================================
 * Called by the assembler to interpret a single operand
 *
 * Arguments:
 *	ctx		A pointer to the disassembler context record.
 *
 * Returns 0 if the operand is ok, or -1 if it is bad.
 */

int parse_operand (unsigned long memaddr, struct opcode *opc,
				   struct operand *oper, char *txt, int *err)
{
	long data;
	long mask;
	int is_neg = 0;

  /*------------------------------------------------------------*/

	mask = (1 << oper->bits) - 1;

	if (oper->hint & OH_ADDR) {
		data = read_number (txt);

		if (opc->hint & H_RELATIVE)
			data = data - memaddr;

		if (data < 0)
			is_neg = 1;

		data >>= 2;
		data &= (mask >> 1);

		if (is_neg)
			data |= 1 << (oper->bits - 1);
	}

	else if (oper->hint & OH_REG) {
		if (txt[0] == 'r' || txt[0] == 'R')
			txt++;
		else if (txt[0] == '%' && (txt[1] == 'r' || txt[1] == 'R'))
			txt += 2;

		data = read_number (txt);
		if (data > 31) {
			if (err)
				*err = E_ASM_BAD_REGISTER;
			return -1;
		}

		data = htonl (data);
	}

	else if (oper->hint & OH_SPR) {
		if ((data = spr_value (txt)) == 0) {
			if (err)
				*err = E_ASM_BAD_SPR;
			return -1;
		}
	}

	else if (oper->hint & OH_TBR) {
		if ((data = tbr_value (txt)) == 0) {
			if (err)
				*err = E_ASM_BAD_TBR;
			return -1;
		}
	}

	else {
		data = htonl (read_number (txt));
	}

	return (data & mask) << oper->shift;
}								/* parse_operand */


char *asm_error_str (int err)
{
	switch (err) {
	case E_ASM_BAD_OPCODE:
		return "Bad opcode";
	case E_ASM_NUM_OPERANDS:
		return "Bad number of operands";
	case E_ASM_BAD_REGISTER:
		return "Bad register number";
	case E_ASM_BAD_SPR:
		return "Bad SPR name or number";
	case E_ASM_BAD_TBR:
		return "Bad TBR name or number";
	}

	return "";
}								/* asm_error_str */



/*======================================================================
 * Copy a word from one buffer to another, ignores leading white spaces.
 *
 * Arguments:
 *	src		The address of a character pointer to the
 *			source buffer.
 *	dest		A pointer to a character buffer to write the word
 *			into.
 *
 * Returns the number of non-white space characters copied, or zero.
 */

int get_word (char **src, char *dest)
{
	char *ptr = *src;
	int nchars = 0;

  /*------------------------------------------------------------*/

	/* Eat white spaces */
	while (*ptr && isblank (*ptr))
		ptr++;

	if (*ptr == 0) {
		*src = ptr;
		return 0;
	}

	/* Find the text of the word */
	while (*ptr && !isblank (*ptr) && (*ptr != ','))
		dest[nchars++] = *ptr++;
	ptr = (*ptr == ',') ? ptr + 1 : ptr;
	dest[nchars] = 0;

	*src = ptr;
	return nchars;
}								/* get_word */



/*======================================================================
 * Convert a numeric string to a number, be aware of base notations.
 *
 * Arguments:
 *	txt		The numeric string.
 *
 * Returns the converted numeric value.
 */

long read_number (char *txt)
{
	long val;
	int is_neg = 0;

  /*------------------------------------------------------------*/

	if (txt == 0 || *txt == 0)
		return 0;

	if (*txt == '-') {
		is_neg = 1;
		++txt;
	}

	if (txt[0] == '0' && (txt[1] == 'x' || txt[1] == 'X'))	/* hex */
		val = simple_strtoul (&txt[2], NULL, 16);
	else						/* decimal */
		val = simple_strtoul (txt, NULL, 10);

	if (is_neg)
		val = -val;

	return val;
}								/* read_number */


int downstring (char *s)
{
	if (!s || !*s)
		return 0;

	while (*s) {
		if (isupper (*s))
			*s = tolower (*s);
		s++;
	}

	return 0;
}								/* downstring */



/*======================================================================
 * Examines the instruction at the current address and determines the
 * next address to be executed.  This will take into account branches
 * of different types so that a "step" and "next" operations can be
 * supported.
 *
 * Arguments:
 *	nextaddr	The address (to be filled in) of the next
 *			instruction to execute.  This will only be a valid
 *			address if TRUE is returned.
 *
 *	step_over	A flag indicating how to compute addresses for
 *			branch statements:
 *			 TRUE  = Step over the branch (next)
 *			 FALSE = step into the branch (step)
 *
 * Returns TRUE if it was able to compute the address.  Returns FALSE if
 * it has a problem reading the current instruction or one of the registers.
 */

int find_next_address (unsigned char *nextaddr, int step_over,
					   struct pt_regs *regs)
{
	unsigned long pc;			/* SRR0 register from PPC */
	unsigned long ctr;			/* CTR register from PPC */
	unsigned long cr;			/* CR register from PPC */
	unsigned long lr;			/* LR register from PPC */
	unsigned long instr;		/* instruction at SRR0 */
	unsigned long next;			/* computed instruction for 'next' */
	unsigned long step;			/* computed instruction for 'step' */
	unsigned long addr = 0;		/* target address operand */
	unsigned long aa = 0;		/* AA operand */
	unsigned long lk = 0;		/* LK operand */
	unsigned long bo = 0;		/* BO operand */
	unsigned long bi = 0;		/* BI operand */
	struct opcode *op = 0;		/* opcode structure for 'instr' */
	int ctr_ok = 0;
	int cond_ok = 0;
	int conditional = 0;
	int branch = 0;

  /*------------------------------------------------------------*/

	if (nextaddr == 0 || regs == 0) {
		printf ("find_next_address: bad args");
		return FALSE;
	}

	pc = regs->nip & 0xfffffffc;
	instr = INSTRUCTION (pc);

	if ((op = find_opcode (instr)) == (struct opcode *) 0) {
		printf ("find_next_address: can't parse opcode 0x%lx", instr);
		return FALSE;
	}

	ctr = regs->ctr;
	cr = regs->ccr;
	lr = regs->link;

	switch (op->opcode) {
	case B_OPCODE (16, 0, 0):	/* bc */
	case B_OPCODE (16, 0, 1):	/* bcl */
	case B_OPCODE (16, 1, 0):	/* bca */
	case B_OPCODE (16, 1, 1):	/* bcla */
		if (!get_operand_value (op, instr, O_BD, &addr) ||
			!get_operand_value (op, instr, O_BO, &bo) ||
			!get_operand_value (op, instr, O_BI, &bi) ||
			!get_operand_value (op, instr, O_AA, &aa) ||
			!get_operand_value (op, instr, O_LK, &lk))
			return FALSE;

		if ((addr & (1 << 13)) != 0)
			addr = addr - (1 << 14);
		addr <<= 2;
		conditional = 1;
		branch = 1;
		break;

	case I_OPCODE (18, 0, 0):	/* b */
	case I_OPCODE (18, 0, 1):	/* bl */
	case I_OPCODE (18, 1, 0):	/* ba */
	case I_OPCODE (18, 1, 1):	/* bla */
		if (!get_operand_value (op, instr, O_LI, &addr) ||
			!get_operand_value (op, instr, O_AA, &aa) ||
			!get_operand_value (op, instr, O_LK, &lk))
			return FALSE;

		if ((addr & (1 << 23)) != 0)
			addr = addr - (1 << 24);
		addr <<= 2;
		conditional = 0;
		branch = 1;
		break;

	case XL_OPCODE (19, 528, 0):	/* bcctr */
	case XL_OPCODE (19, 528, 1):	/* bcctrl */
		if (!get_operand_value (op, instr, O_BO, &bo) ||
			!get_operand_value (op, instr, O_BI, &bi) ||
			!get_operand_value (op, instr, O_LK, &lk))
			return FALSE;

		addr = ctr;
		aa = 1;
		conditional = 1;
		branch = 1;
		break;

	case XL_OPCODE (19, 16, 0):	/* bclr */
	case XL_OPCODE (19, 16, 1):	/* bclrl */
		if (!get_operand_value (op, instr, O_BO, &bo) ||
			!get_operand_value (op, instr, O_BI, &bi) ||
			!get_operand_value (op, instr, O_LK, &lk))
			return FALSE;

		addr = lr;
		aa = 1;
		conditional = 1;
		branch = 1;
		break;

	default:
		conditional = 0;
		branch = 0;
		break;
	}

	if (conditional) {
		switch ((bo & 0x1e) >> 1) {
		case 0:				/* 0000y */
			if (--ctr != 0)
				ctr_ok = 1;

			cond_ok = !(cr & (1 << (31 - bi)));
			break;

		case 1:				/* 0001y */
			if (--ctr == 0)
				ctr_ok = 1;

			cond_ok = !(cr & (1 << (31 - bi)));
			break;

		case 2:				/* 001zy */
			ctr_ok = 1;
			cond_ok = !(cr & (1 << (31 - bi)));
			break;

		case 4:				/* 0100y */
			if (--ctr != 0)
				ctr_ok = 1;

			cond_ok = cr & (1 << (31 - bi));
			break;

		case 5:				/* 0101y */
			if (--ctr == 0)
				ctr_ok = 1;

			cond_ok = cr & (1 << (31 - bi));
			break;

		case 6:				/* 011zy */
			ctr_ok = 1;
			cond_ok = cr & (1 << (31 - bi));
			break;

		case 8:				/* 1z00y */
			if (--ctr != 0)
				ctr_ok = cond_ok = 1;
			break;

		case 9:				/* 1z01y */
			if (--ctr == 0)
				ctr_ok = cond_ok = 1;
			break;

		case 10:				/* 1z1zz */
			ctr_ok = cond_ok = 1;
			break;
		}
	}

	if (branch && (!conditional || (ctr_ok && cond_ok))) {
		if (aa)
			step = addr;
		else
			step = addr + pc;

		if (lk)
			next = pc + 4;
		else
			next = step;
	} else {
		step = next = pc + 4;
	}

	if (step_over == TRUE)
		*(unsigned long *) nextaddr = next;
	else
		*(unsigned long *) nextaddr = step;

	return TRUE;
}								/* find_next_address */


/*
 * Copyright (c) 2000 William L. Pitts and W. Gerald Hicks
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are freely
 * permitted provided that the above copyright notice and this
 * paragraph and the following disclaimer are duplicated in all
 * such forms.
 *
 * This software is provided "AS IS" and without any express or
 * implied warranties, including, without limitation, the implied
 * warranties of merchantability and fitness for a particular
 * purpose.
 */

#endif	/* CONFIG_COMMANDS & CFG_CMD_BEDBUG */
