static int print_insn()

in kernel/dis.c [424:486]


static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
{
	struct s390_insn *insn;
	const unsigned char *ops;
	const struct s390_operand *operand;
	unsigned int value;
	char separator;
	char *ptr;
	int i;

	ptr = buffer;
	insn = find_insn(code);
	if (insn) {
		if (insn->zero == 0)
			ptr += sprintf(ptr, "%.7s\t",
				       long_insn_name[insn->offset]);
		else
			ptr += sprintf(ptr, "%.5s\t", insn->name);
		/* Extract the operands. */
		separator = 0;
		for (ops = formats[insn->format], i = 0;
		     *ops != 0 && i < 6; ops++, i++) {
			operand = operands + *ops;
			value = extract_operand(code, operand);
			if ((operand->flags & OPERAND_INDEX)  && value == 0)
				continue;
			if ((operand->flags & OPERAND_BASE) &&
			    value == 0 && separator == '(') {
				separator = ',';
				continue;
			}
			if (separator)
				ptr += sprintf(ptr, "%c", separator);
			if (operand->flags & OPERAND_GPR)
				ptr += sprintf(ptr, "%%r%i", value);
			else if (operand->flags & OPERAND_FPR)
				ptr += sprintf(ptr, "%%f%i", value);
			else if (operand->flags & OPERAND_AR)
				ptr += sprintf(ptr, "%%a%i", value);
			else if (operand->flags & OPERAND_CR)
				ptr += sprintf(ptr, "%%c%i", value);
			else if (operand->flags & OPERAND_VR)
				ptr += sprintf(ptr, "%%v%i", value);
			else if (operand->flags & OPERAND_PCREL) {
				void *pcrel = (void *)((int)value + addr);

				ptr += sprintf(ptr, "%px", pcrel);
			} else if (operand->flags & OPERAND_SIGNED)
				ptr += sprintf(ptr, "%i", value);
			else
				ptr += sprintf(ptr, "%u", value);
			if (operand->flags & OPERAND_DISP)
				separator = '(';
			else if (operand->flags & OPERAND_BASE) {
				ptr += sprintf(ptr, ")");
				separator = ',';
			} else
				separator = ',';
		}
	} else
		ptr += sprintf(ptr, "unknown");
	return (int) (ptr - buffer);
}