/* $Id$ */

#include <common.h>

#if defined(CONFIG_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
